browbeat/rally/rally-plugins/nova/rally_az_context.py

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)