101 lines
4.0 KiB
Python
101 lines
4.0 KiB
Python
# 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 rally import exceptions
|
|
from rally.task import context
|
|
from rally.common import logging
|
|
from rally import consts
|
|
from rally_openstack.common import osclients
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
@context.configure(name="create_availability_zones", order=1000)
|
|
class CreateAvailabilityZonesContext(context.Context):
|
|
"""This plugin creates specified number of availability zones to boot servers."""
|
|
|
|
CONFIG_SCHEMA = {
|
|
"type": "object",
|
|
"$schema": consts.JSON_SCHEMA,
|
|
"additionalProperties": False,
|
|
"properties": {
|
|
"num_availability_zones": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
},
|
|
"requested_availability_zones":{
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"default": []
|
|
}
|
|
}
|
|
}
|
|
|
|
def get_nova_client(self):
|
|
return osclients.Clients(self.context["admin"]["credential"]).nova()
|
|
|
|
def setup(self):
|
|
"""This method is called before the task starts."""
|
|
num_availability_zones = self.config.get("num_availability_zones", 1)
|
|
requested_availability_zones = self.config.get("requested_availability_zones", [])
|
|
existing_availability_zones = self.get_nova_client().availability_zones.list(detailed=True)
|
|
self.available_hypervisors = []
|
|
self.context["availability_zones"] = list(requested_availability_zones)
|
|
|
|
for az in existing_availability_zones:
|
|
if az.zoneName == 'nova':
|
|
self.available_hypervisors = list(az.hosts.keys())
|
|
break
|
|
|
|
self.num_azs_to_be_created = (
|
|
num_availability_zones - len(requested_availability_zones)
|
|
)
|
|
if self.num_azs_to_be_created < 0:
|
|
err_msg = ("Invalid input passed. Make sure to pass correct"
|
|
" value for num_availability_zones")
|
|
raise exceptions.RallyException(err_msg)
|
|
|
|
if self.num_azs_to_be_created == 0:
|
|
return
|
|
|
|
if len(self.available_hypervisors)/self.num_azs_to_be_created < 1:
|
|
err_msg = ("Could not create availability zones as there are"
|
|
" no sufficient available hypervisors")
|
|
raise exceptions.RallyException(err_msg)
|
|
|
|
self.host_aggregates = []
|
|
for i in range(self.num_azs_to_be_created):
|
|
availability_zone = "crally_az" + str(i + 1)
|
|
aggregate_name = "crally_agg" + str(i + 1)
|
|
aggregate = self.get_nova_client().aggregates.create(aggregate_name, availability_zone)
|
|
self.host_aggregates.append(aggregate)
|
|
self.context["availability_zones"].append(availability_zone)
|
|
|
|
for counter, hypervisor in enumerate(self.available_hypervisors):
|
|
index = counter % self.num_azs_to_be_created
|
|
self.get_nova_client().aggregates.add_host(self.host_aggregates[index].id, hypervisor)
|
|
|
|
def cleanup(self):
|
|
"""This method is called after the task finishes."""
|
|
if self.num_azs_to_be_created <= 0:
|
|
return
|
|
|
|
for counter, hypervisor in enumerate(self.available_hypervisors):
|
|
index = counter % self.num_azs_to_be_created
|
|
self.get_nova_client().aggregates.remove_host(self.host_aggregates[index].id,
|
|
hypervisor)
|
|
|
|
for aggregate in self.host_aggregates:
|
|
self.get_nova_client().aggregates.delete(aggregate.id)
|