##############################################################################
import os
-import time
-import sys
import logging
from keystoneauth1 import loading
# *********************************************
# 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 create_keypair(shade_client, name, public_key=None):
+ """Create a new keypair.
-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
+ :param name: Name of the keypair being created.
+ :param public_key: Public key for the 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)]")
-
-
-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,
"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,
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 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 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 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
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 = ''
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 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
+def get_flavor(shade_client, name_or_id, filters=None, get_extra=True):
+ """Get a flavor by name or ID.
- if server.status == status:
- return True
+ :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.
- 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
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
# *********************************************
# CINDER
# *********************************************
-def get_volume_id(volume_name): # pragma: no cover
- volumes = get_cinder_client().volumes.list()
- return next((v.id for v in volumes if v.name == volume_name), None)
+def get_volume_id(shade_client, volume_name):
+ return shade_client.get_volume_id(volume_name)
+
+
+def get_volume(shade_client, name_or_id, filters=None):
+ """Get a volume by name or ID.
+
+ :param name_or_id: Name or ID of the volume.
+ :param filters: A dictionary of meta data to use for further filtering.
+
+ :returns: A volume ``munch.Munch`` or None if no matching volume is found.
+ """
+ return shade_client.get_volume(name_or_id, filters=filters)
+
+def create_volume(shade_client, size, wait=True, timeout=None,
+ image=None, **kwargs):
+ """Create a volume.
-def create_volume(cinder_client, volume_name, volume_size,
- volume_image=False): # pragma: no cover
+ :param size: Size, in GB of the volume to create.
+ :param name: (optional) Name for the volume.
+ :param description: (optional) Name for the volume.
+ :param wait: If true, waits for volume to be created.
+ :param timeout: Seconds to wait for volume creation. None is forever.
+ :param image: (optional) Image name, ID or object from which to create
+ the volume.
+
+ :returns: The created volume object.
+
+ """
try:
- if volume_image:
- volume = cinder_client.volumes.create(name=volume_name,
- size=volume_size,
- imageRef=volume_image)
- else:
- volume = cinder_client.volumes.create(name=volume_name,
- size=volume_size)
- return volume
- except Exception: # pylint: disable=broad-except
- log.exception("Error [create_volume(cinder_client, %s)]",
- (volume_name, volume_size))
- return None
+ return shade_client.create_volume(size, wait=wait, timeout=timeout,
+ image=image, **kwargs)
+ except (exc.OpenStackCloudException, exc.OpenStackCloudTimeout) as op_exc:
+ log.error("Failed to create_volume(shade_client). "
+ "Exception message: %s", op_exc.orig_message)
-def delete_volume(cinder_client, volume_id,
- forced=False): # pragma: no cover
+def delete_volume(shade_client, name_or_id=None, wait=True, timeout=None):
+ """Delete a volume.
+
+ :param name_or_id:(string) Name or unique ID of the volume.
+ :param wait:(bool) If true, waits for volume to be deleted.
+ :param timeout:(string) Seconds to wait for volume deletion. None is forever.
+
+ :return: True on success, False otherwise.
+ """
try:
- if forced:
- try:
- cinder_client.volumes.detach(volume_id)
- except Exception: # pylint: disable=broad-except
- log.error(sys.exc_info()[0])
- cinder_client.volumes.force_delete(volume_id)
- else:
- while True:
- volume = get_cinder_client().volumes.get(volume_id)
- if volume.status.lower() == 'available':
- break
- cinder_client.volumes.delete(volume_id)
- return True
- except Exception: # pylint: disable=broad-except
- log.exception("Error [delete_volume(cinder_client, '%s')]", volume_id)
+ return shade_client.delete_volume(name_or_id=name_or_id,
+ wait=wait, timeout=timeout)
+ except (exc.OpenStackCloudException, exc.OpenStackCloudTimeout) as o_exc:
+ log.error("Error [delete_volume(shade_client,'%s')]. "
+ "Exception message: %s", name_or_id, o_exc.orig_message)
return False