File: senlin_plugin.py

package info (click to toggle)
senlin 6.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 6,872 kB
  • sloc: python: 66,932; sh: 588; makefile: 196
file content (146 lines) | stat: -rw-r--r-- 6,604 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from oslo_config import cfg

from rally import consts
from rally.plugins.openstack import scenario
from rally.plugins.openstack.scenarios.senlin import utils as senlin_utils
from rally.task import atomic
from rally.task import utils
from rally.task import validation

CONF = cfg.CONF


class SenlinPlugin(senlin_utils.SenlinScenario):
    """Base class for Senlin scenarios with basic atomic actions."""

    def _get_action(self, action_id):
        """Get action details.

        :param action_id: ID of action to get

        :returns: object of action
        """
        return self.admin_clients("senlin").get_action(action_id)

    @atomic.action_timer("senlin.resize_cluster")
    def _resize_cluster(self, cluster, adj_type=None, number=None,
                        min_size=None, max_size=None, min_step=None,
                        strict=True):
        """Adjust cluster size.

        :param cluster: cluster object to resize.
        :param adj_type: type of adjustment. If specified, must be one of the
                         strings defined in `consts.ADJUSTMENT_TYPES`.
        :param number: number for adjustment. It is interpreted as the new
                       desired_capacity of the cluster if `adj_type` is set
                       to `EXACT_CAPACITY`; it is interpreted as the relative
                       number of nodes to add/remove when `adj_type` is set
                       to `CHANGE_IN_CAPACITY`; it is treated as a percentage
                       when `adj_type` is set to `CHANGE_IN_PERCENTAGE`.
        :param min_size: new lower bound of the cluster size, if specified.
        :param max_size: new upper bound of the cluster size, if specified.
                         A value of negative means no upper limit is imposed.
        :param min_step: the number of nodes to be added or removed when
                         `adj_type` is set to value `CHANGE_IN_PERCENTAGE`
                         and the number calculated is less than 1.
        :param strict: whether Senlin should try a best-effort style resizing
                       or just rejects the request when scaling beyond its
                       current size constraint.
        """
        kwargs = {}
        if adj_type:
            kwargs['adjustment_type'] = adj_type
        if number:
            kwargs['number'] = number
        if min_size:
            kwargs['min_size'] = min_size
        if max_size:
            kwargs['max_size'] = max_size
        if min_step:
            kwargs['min_step'] = min_step
        kwargs['strict'] = strict
        res = self.admin_clients("senlin").cluster_resize(cluster.id, **kwargs)
        action = self._get_action(res['action'])
        utils.wait_for_status(
            action,
            ready_statuses=["SUCCEEDED"],
            failure_statuses=["FAILED"],
            update_resource=self._get_action,
            timeout=senlin_utils.CONF.benchmark.senlin_action_timeout)

    @atomic.action_timer("senlin.cluster_scale_in")
    def _scale_in_cluster(self, cluster, count):
        """Cluster scale in.

        :param cluster: cluster object.
        :param count: number of nodes to be removed from the cluster.
        """
        res = self.admin_clients("senlin").cluster_scale_in(cluster.id, count)
        action = self._get_action(res["action"])
        utils.wait_for_status(
            action,
            ready_statuses=["SUCCEEDED"],
            failure_statuses=["FAILED"],
            update_resource=self._get_action,
            timeout=senlin_utils.CONF.benchmark.senlin_action_timeout)

    @validation.required_openstack(admin=True)
    @validation.required_services(consts.Service.SENLIN)
    @validation.required_contexts("profiles")
    @scenario.configure(context={"cleanup": ["senlin"]})
    def create_resize_delete_cluster(self, create_params,
                                     resize_params, timeout=3600):
        """Create a cluster, resize it and then delete it.

        Measure the `senlin cluster-create`, `senlin cluster-resize`
        and `senlin cluster-delete` commands performance.

        :param create_params: the dictionary provides the parameters for
                              cluster creation
        :param resize_params: the dictionary provides the parameters
                              for cluster resizing
        :param timeout: The timeout value in seconds for each cluster
                        action, including creation, deletion and resizing
        """
        profile_id = self.context["tenant"]["profile"]
        cluster = self._create_cluster(profile_id, timeout=timeout,
                                       **create_params)
        self._resize_cluster(cluster, **resize_params)
        self._delete_cluster(cluster)

    @validation.required_openstack(admin=True)
    @validation.required_services(consts.Service.SENLIN)
    @validation.required_contexts("profiles")
    @scenario.configure(context={"cleanup": ["senlin"]})
    def create_scale_in_delete_cluster(self, desired_capacity=1,
                                       min_size=0, max_size=-1,
                                       count=1):
        """Create a cluster, scale-in it and then delete it.

        Measure the `senlin cluster-create`, `senlin cluster-scale-in`
        and `senlin cluster-delete` commands performance.

        :param desired_capacity: The capacity or initial number of nodes
                                 owned by the cluster
        :param min_size: The minimum number of nodes owned by the cluster
        :param max_size: The maximum number of nodes owned by the cluster.
                         -1 means no limit
        :param count: The number of nodes will be removed from the cluster.
        """
        profile_id = self.context["tenant"]["profile"]
        cluster = self._create_cluster(profile_id, desired_capacity,
                                       min_size, max_size)
        self._scale_in_cluster(cluster, count)
        self._delete_cluster(cluster)