X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=yardstick%2Fcommon%2Fopenstack_utils.py;h=53f0ccc34b3c78a741a120231e41f51b356c93d0;hb=c47c33e6071a14485929bb58ee6e1d2aaeff7243;hp=e542a1d07e1b35c5407aef70f1932ff392184b49;hpb=05f97c4e4ce1e8c7c97cda16f12215e663a13c23;p=yardstick.git diff --git a/yardstick/common/openstack_utils.py b/yardstick/common/openstack_utils.py index e542a1d07..53f0ccc34 100644 --- a/yardstick/common/openstack_utils.py +++ b/yardstick/common/openstack_utils.py @@ -7,20 +7,21 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## +import copy +import logging import os -import time import sys -import logging +from cinderclient import client as cinderclient +from novaclient import client as novaclient +from glanceclient import client as glanceclient from keystoneauth1 import loading from keystoneauth1 import session +from neutronclient.neutron import client as neutronclient import shade from shade import exc -from cinderclient import client as cinderclient -from novaclient import client as novaclient -from glanceclient import client as glanceclient -from neutronclient.neutron import client as neutronclient +from yardstick.common import constants log = logging.getLogger(__name__) @@ -156,99 +157,39 @@ def get_glance_client(): # pragma: no cover return glanceclient.Client(get_glance_client_version(), session=sess) -def get_shade_client(): - return shade.openstack_cloud() +def get_shade_client(**os_cloud_config): + """Get Shade OpenStack cloud client + + By default, the input parameters given to "shade.openstack_cloud" method + are stored in "constants.OS_CLOUD_DEFAULT_CONFIG". The input parameters + passed in this function, "os_cloud_config", will overwrite the default + ones. + + :param os_cloud_config: (kwargs) input arguments for + "shade.openstack_cloud" method. + :return: ``shade.OpenStackCloud`` object. + """ + params = copy.deepcopy(constants.OS_CLOUD_DEFAULT_CONFIG) + params.update(os_cloud_config) + return shade.openstack_cloud(**params) # ********************************************* # NOVA # ********************************************* -def get_aggregates(nova_client): # pragma: no cover - try: - return nova_client.aggregates.list() - except Exception: # pylint: disable=broad-except - log.exception("Error [get_aggregates(nova_client)]") - - -def get_availability_zones(nova_client): # pragma: no cover - try: - return nova_client.availability_zones.list() - except Exception: # pylint: disable=broad-except - log.exception("Error [get_availability_zones(nova_client)]") - - -def get_availability_zone_names(nova_client): # pragma: no cover - try: - return [az.zoneName for az in get_availability_zones(nova_client)] - except Exception: # pylint: disable=broad-except - log.exception("Error [get_availability_zone_names(nova_client)]") - - -def create_aggregate(nova_client, aggregate_name, av_zone): # pragma: no cover - try: - nova_client.aggregates.create(aggregate_name, av_zone) - except Exception: # pylint: disable=broad-except - log.exception("Error [create_aggregate(nova_client, %s, %s)]", - aggregate_name, av_zone) - return False - else: - return True - - -def get_aggregate_id(nova_client, aggregate_name): # pragma: no cover - try: - aggregates = get_aggregates(nova_client) - _id = next((ag.id for ag in aggregates if ag.name == aggregate_name)) - except Exception: # pylint: disable=broad-except - log.exception("Error [get_aggregate_id(nova_client, %s)]", - aggregate_name) - else: - return _id - - -def add_host_to_aggregate(nova_client, aggregate_name, - compute_host): # pragma: no cover - try: - aggregate_id = get_aggregate_id(nova_client, aggregate_name) - nova_client.aggregates.add_host(aggregate_id, compute_host) - except Exception: # pylint: disable=broad-except - log.exception("Error [add_host_to_aggregate(nova_client, %s, %s)]", - aggregate_name, compute_host) - return False - else: - return True - +def create_keypair(shade_client, name, public_key=None): + """Create a new keypair. -def create_aggregate_with_host(nova_client, aggregate_name, av_zone, - compute_host): # pragma: no cover - try: - create_aggregate(nova_client, aggregate_name, av_zone) - add_host_to_aggregate(nova_client, aggregate_name, compute_host) - except Exception: # pylint: disable=broad-except - log.exception("Error [create_aggregate_with_host(" - "nova_client, %s, %s, %s)]", - aggregate_name, av_zone, compute_host) - return False - else: - return True - - -def create_keypair(name, key_path=None): # pragma: no cover - try: - with open(key_path) as fpubkey: - keypair = get_nova_client().keypairs.create( - name=name, public_key=fpubkey.read()) - return keypair - except Exception: # pylint: disable=broad-except - log.exception("Error [create_keypair(nova_client)]") + :param name: Name of the keypair being created. + :param public_key: Public key for the new keypair. - -def create_instance(json_body): # pragma: no cover + :return: Created keypair. + """ try: - return get_nova_client().servers.create(**json_body) - except Exception: # pylint: disable=broad-except - log.exception("Error create instance failed") - return None + return shade_client.create_keypair(name, public_key=public_key) + except exc.OpenStackCloudException as o_exc: + log.error("Error [create_keypair(shade_client)]. " + "Exception message, '%s'", o_exc.orig_message) def create_instance_and_wait_for_active(shade_client, name, image, @@ -338,17 +279,36 @@ def create_instance_and_wait_for_active(shade_client, name, image, "Exception message, '%s'", o_exc.orig_message) -def attach_server_volume(server_id, volume_id, - device=None): # pragma: no cover +def attach_volume_to_server(shade_client, server_name_or_id, volume_name_or_id, + device=None, wait=True, timeout=None): + """Attach a volume to a server. + + This will attach a volume, described by the passed in volume + dict, to the server described by the passed in server dict on the named + device on the server. + + If the volume is already attached to the server, or generally not + available, then an exception is raised. To re-attach to a server, + but under a different device, the user must detach it first. + + :param server_name_or_id:(string) The server name or id to attach to. + :param volume_name_or_id:(string) The volume name or id to attach. + :param device:(string) The device name where the volume will attach. + :param wait:(bool) If true, waits for volume to be attached. + :param timeout: Seconds to wait for volume attachment. None is forever. + + :returns: True if attached successful, False otherwise. + """ try: - get_nova_client().volumes.create_server_volume(server_id, - volume_id, device) - except Exception: # pylint: disable=broad-except - log.exception("Error [attach_server_volume(nova_client, '%s', '%s')]", - server_id, volume_id) - return False - else: + server = shade_client.get_server(name_or_id=server_name_or_id) + volume = shade_client.get_volume(volume_name_or_id) + shade_client.attach_volume( + server, volume, device=device, wait=wait, timeout=timeout) return True + except exc.OpenStackCloudException as o_exc: + log.error("Error [attach_volume_to_server(shade_client)]. " + "Exception message: %s", o_exc.orig_message) + return False def delete_instance(shade_client, name_or_id, wait=False, timeout=180, @@ -376,46 +336,26 @@ def delete_instance(shade_client, name_or_id, wait=False, timeout=180, return False -def remove_host_from_aggregate(nova_client, aggregate_name, - compute_host): # pragma: no cover - try: - aggregate_id = get_aggregate_id(nova_client, aggregate_name) - nova_client.aggregates.remove_host(aggregate_id, compute_host) - except Exception: # pylint: disable=broad-except - log.exception("Error remove_host_from_aggregate(nova_client, %s, %s)", - aggregate_name, compute_host) - return False - else: - return True +def get_server(shade_client, name_or_id=None, filters=None, detailed=False, + bare=False): + """Get a server by name or ID. + :param name_or_id: Name or ID of the server. + :param filters:(dict) A dictionary of meta data to use for further + filtering. + :param detailed:(bool) Whether or not to add detailed additional + information. + :param bare:(bool) Whether to skip adding any additional information to the + server record. -def remove_hosts_from_aggregate(nova_client, - aggregate_name): # pragma: no cover - aggregate_id = get_aggregate_id(nova_client, aggregate_name) - hosts = nova_client.aggregates.get(aggregate_id).hosts - assert( - all(remove_host_from_aggregate(nova_client, aggregate_name, host) - for host in hosts)) - - -def delete_aggregate(nova_client, aggregate_name): # pragma: no cover - try: - remove_hosts_from_aggregate(nova_client, aggregate_name) - nova_client.aggregates.delete(aggregate_name) - except Exception: # pylint: disable=broad-except - log.exception("Error [delete_aggregate(nova_client, %s)]", - aggregate_name) - return False - else: - return True - - -def get_server_by_name(name): # pragma: no cover + :returns: A server ``munch.Munch`` or None if no matching server is found. + """ try: - return get_nova_client().servers.list(search_opts={'name': name})[0] - except IndexError: - log.exception('Failed to get nova client') - raise + return shade_client.get_server(name_or_id=name_or_id, filters=filters, + detailed=detailed, bare=bare) + except exc.OpenStackCloudException as o_exc: + log.error("Error [get_server(shade_client, '%s')]. " + "Exception message: %s", name_or_id, o_exc.orig_message) def create_flavor(name, ram, vcpus, disk, **kwargs): # pragma: no cover @@ -428,14 +368,6 @@ def create_flavor(name, ram, vcpus, disk, **kwargs): # pragma: no cover return None -def get_image_by_name(name): # pragma: no cover - images = get_nova_client().images.list() - try: - return next((a for a in images if a.name == name)) - except StopIteration: - log.exception('No image matched') - - def get_flavor_id(nova_client, flavor_name): # pragma: no cover flavors = nova_client.flavors.list(detailed=True) flavor_id = '' @@ -446,27 +378,22 @@ def get_flavor_id(nova_client, flavor_name): # pragma: no cover return flavor_id -def get_flavor_by_name(name): # pragma: no cover - flavors = get_nova_client().flavors.list() - try: - return next((a for a in flavors if a.name == name)) - except StopIteration: - log.exception('No flavor matched') - +def get_flavor(shade_client, name_or_id, filters=None, get_extra=True): + """Get a flavor by name or ID. -def check_status(status, name, iterations, interval): # pragma: no cover - for _ in range(iterations): - try: - server = get_server_by_name(name) - except IndexError: - log.error('Cannot found %s server', name) - raise + :param name_or_id: Name or ID of the flavor. + :param filters: A dictionary of meta data to use for further filtering. + :param get_extra: Whether or not the list_flavors call should get the extra + flavor specs. - if server.status == status: - return True - - time.sleep(interval) - return False + :returns: A flavor ``munch.Munch`` or None if no matching flavor is found. + """ + try: + return shade_client.get_flavor(name_or_id, filters=filters, + get_extra=get_extra) + except exc.OpenStackCloudException as o_exc: + log.error("Error [get_flavor(shade_client, '%s')]. " + "Exception message: %s", name_or_id, o_exc.orig_message) def delete_flavor(flavor_id): # pragma: no cover @@ -479,12 +406,18 @@ def delete_flavor(flavor_id): # pragma: no cover return True -def delete_keypair(nova_client, key): # pragma: no cover +def delete_keypair(shade_client, name): + """Delete a keypair. + + :param name: Name of the keypair to delete. + + :returns: True if delete succeeded, False otherwise. + """ try: - nova_client.keypairs.delete(key=key) - return True - except Exception: # pylint: disable=broad-except - log.exception("Error [delete_keypair(nova_client)]") + return shade_client.delete_keypair(name) + except exc.OpenStackCloudException as o_exc: + log.error("Error [delete_neutron_router(shade_client, '%s')]. " + "Exception message: %s", name, o_exc.orig_message) return False