diff options
-rw-r--r-- | snaps/openstack/create_flavor.py | 118 | ||||
-rw-r--r-- | snaps/openstack/create_image.py | 210 | ||||
-rw-r--r-- | snaps/openstack/create_instance.py | 525 | ||||
-rw-r--r-- | snaps/openstack/create_keypairs.py | 66 | ||||
-rw-r--r-- | snaps/openstack/create_network.py | 383 | ||||
-rw-r--r-- | snaps/openstack/create_project.py | 62 | ||||
-rw-r--r-- | snaps/openstack/create_router.py | 145 | ||||
-rw-r--r-- | snaps/openstack/create_security_group.py | 249 | ||||
-rw-r--r-- | snaps/openstack/create_stack.py | 119 | ||||
-rw-r--r-- | snaps/openstack/tests/create_flavor_tests.py | 154 | ||||
-rw-r--r-- | snaps/openstack/tests/create_image_tests.py | 401 | ||||
-rw-r--r-- | snaps/openstack/tests/create_instance_tests.py | 1240 | ||||
-rw-r--r-- | snaps/openstack/tests/create_keypairs_tests.py | 77 | ||||
-rw-r--r-- | snaps/openstack/tests/create_network_tests.py | 203 | ||||
-rw-r--r-- | snaps/openstack/tests/create_project_tests.py | 94 | ||||
-rw-r--r-- | snaps/openstack/tests/create_router_tests.py | 179 | ||||
-rw-r--r-- | snaps/openstack/tests/create_security_group_tests.py | 340 | ||||
-rw-r--r-- | snaps/openstack/tests/create_stack_tests.py | 132 |
18 files changed, 2864 insertions, 1833 deletions
diff --git a/snaps/openstack/create_flavor.py b/snaps/openstack/create_flavor.py index 2d78be4..f1c7ee3 100644 --- a/snaps/openstack/create_flavor.py +++ b/snaps/openstack/create_flavor.py @@ -46,18 +46,23 @@ class OpenStackFlavor: def create(self, cleanup=False): """ Creates the image in OpenStack if it does not already exist - :param cleanup: Denotes whether or not this is being called for cleanup or not + :param cleanup: Denotes whether or not this is being called for cleanup + or not :return: The OpenStack flavor object """ self.__nova = nova_utils.nova_client(self.__os_creds) - self.__flavor = nova_utils.get_flavor_by_name(self.__nova, self.flavor_settings.name) + self.__flavor = nova_utils.get_flavor_by_name( + self.__nova, self.flavor_settings.name) if self.__flavor: - logger.info('Found flavor with name - ' + self.flavor_settings.name) + logger.info( + 'Found flavor with name - ' + self.flavor_settings.name) elif not cleanup: - self.__flavor = nova_utils.create_flavor(self.__nova, self.flavor_settings) + self.__flavor = nova_utils.create_flavor( + self.__nova, self.flavor_settings) if self.flavor_settings.metadata: self.__flavor.set_keys(self.flavor_settings.metadata) - self.__flavor = nova_utils.get_flavor_by_name(self.__nova, self.flavor_settings.name) + self.__flavor = nova_utils.get_flavor_by_name( + self.__nova, self.flavor_settings.name) else: logger.info('Did not create flavor due to cleanup mode') @@ -89,12 +94,12 @@ class FlavorSettings: Configuration settings for OpenStack flavor creation """ - def __init__(self, config=None, name=None, flavor_id='auto', ram=None, disk=None, vcpus=None, ephemeral=0, swap=0, - rxtx_factor=1.0, is_public=True, metadata=None): + def __init__(self, **kwargs): """ Constructor - :param config: dict() object containing the configuration settings using the attribute names below as each - member's the key and overrides any of the other parameters. + :param config: dict() object containing the configuration settings + using the attribute names below as each member's the + key and overrides any of the other parameters. :param name: the flavor's name (required) :param flavor_id: the string ID (default 'auto') :param ram: the required RAM in MB (required) @@ -102,62 +107,52 @@ class FlavorSettings: :param vcpus: the number of virtual CPUs (required) :param ephemeral: the size of the ephemeral disk in GB (default 0) :param swap: the size of the dedicated swap disk in GB (default 0) - :param rxtx_factor: the receive/transmit factor to be set on ports if backend supports - QoS extension (default 1.0) - :param is_public: denotes whether or not the flavor is public (default True) - :param metadata: freeform dict() for special metadata (default hw:mem_page_size=any) + :param rxtx_factor: the receive/transmit factor to be set on ports if + backend supports QoS extension (default 1.0) + :param is_public: denotes whether or not the flavor is public + (default True) + :param metadata: freeform dict() for special metadata """ + self.name = kwargs.get('name') - if config: - self.name = config.get('name') - - if config.get('flavor_id'): - self.flavor_id = config['flavor_id'] - else: - self.flavor_id = flavor_id - - self.ram = config.get('ram') - self.disk = config.get('disk') - self.vcpus = config.get('vcpus') - - if config.get('ephemeral'): - self.ephemeral = config['ephemeral'] - else: - self.ephemeral = ephemeral - - if config.get('swap'): - self.swap = config['swap'] - else: - self.swap = swap - - if config.get('rxtx_factor'): - self.rxtx_factor = config['rxtx_factor'] - else: - self.rxtx_factor = rxtx_factor - - if config.get('is_public') is not None: - self.is_public = config['is_public'] - else: - self.is_public = is_public - - if config.get('metadata'): - self.metadata = config['metadata'] - else: - self.metadata = metadata + if kwargs.get('flavor_id'): + self.flavor_id = kwargs['flavor_id'] else: - self.name = name - self.flavor_id = flavor_id - self.ram = ram - self.disk = disk - self.vcpus = vcpus - self.ephemeral = ephemeral - self.swap = swap - self.rxtx_factor = rxtx_factor - self.is_public = is_public - self.metadata = metadata + self.flavor_id = 'auto' + + self.ram = kwargs.get('ram') + self.disk = kwargs.get('disk') + self.vcpus = kwargs.get('vcpus') + + if kwargs.get('ephemeral'): + self.ephemeral = kwargs['ephemeral'] + else: + self.ephemeral = 0 + + if kwargs.get('swap'): + self.swap = kwargs['swap'] + else: + self.swap = 0 + + if kwargs.get('rxtx_factor'): + self.rxtx_factor = kwargs['rxtx_factor'] + else: + self.rxtx_factor = 1.0 + + if kwargs.get('is_public') is not None: + self.is_public = kwargs['is_public'] + else: + self.is_public = True + + if kwargs.get('metadata'): + self.metadata = kwargs['metadata'] + else: + self.metadata = None if not self.name or not self.ram or not self.disk or not self.vcpus: - raise Exception('The attributes name, ram, disk, and vcpus are required for FlavorSettings') + raise Exception( + 'The attributes name, ram, disk, and vcpus are required for' + 'FlavorSettings') if not isinstance(self.ram, int): raise Exception('The ram attribute must be a integer') @@ -175,7 +170,8 @@ class FlavorSettings: raise Exception('The swap attribute must be an integer') if self.rxtx_factor and not isinstance(self.rxtx_factor, (int, float)): - raise Exception('The is_public attribute must be an integer or float') + raise Exception( + 'The is_public attribute must be an integer or float') if self.is_public and not isinstance(self.is_public, bool): raise Exception('The is_public attribute must be a boolean') diff --git a/snaps/openstack/create_image.py b/snaps/openstack/create_image.py index 401e845..9ed813c 100644 --- a/snaps/openstack/create_image.py +++ b/snaps/openstack/create_image.py @@ -49,50 +49,68 @@ class OpenStackImage: def create(self, cleanup=False): """ - Creates the image in OpenStack if it does not already exist and returns the domain Image object - :param cleanup: Denotes whether or not this is being called for cleanup or not + Creates the image in OpenStack if it does not already exist and returns + the domain Image object + :param cleanup: Denotes whether or not this is being called for cleanup + or not :return: The OpenStack Image object """ self.__glance = glance_utils.glance_client(self.__os_creds) - self.__image = glance_utils.get_image(self.__glance, self.image_settings.name) + self.__image = glance_utils.get_image(self.__glance, + self.image_settings.name) if self.__image: logger.info('Found image with name - ' + self.image_settings.name) return self.__image - elif self.image_settings.exists and not self.image_settings.url and not self.image_settings.image_file: - raise ImageCreationError('Image with does not exist with name - ' + self.image_settings.name) + elif self.image_settings.exists and not self.image_settings.url \ + and not self.image_settings.image_file: + raise ImageCreationError( + 'Image with does not exist with name - ' + + self.image_settings.name) elif not cleanup: extra_properties = self.image_settings.extra_properties or dict() if self.image_settings.kernel_image_settings: self.__kernel_image = glance_utils.get_image( - self.__glance, self.image_settings.kernel_image_settings.name) + self.__glance, + self.image_settings.kernel_image_settings.name) if not self.__kernel_image and not cleanup: - logger.info('Creating associated kernel image with name - ' - + self.image_settings.kernel_image_settings.name) + logger.info( + 'Creating associated kernel image with name - %s', + self.image_settings.kernel_image_settings.name) self.__kernel_image = glance_utils.create_image( - self.__glance, self.image_settings.kernel_image_settings) + self.__glance, + self.image_settings.kernel_image_settings) extra_properties['kernel_id'] = self.__kernel_image.id if self.image_settings.ramdisk_image_settings: self.__ramdisk_image = glance_utils.get_image( - self.__glance, self.image_settings.ramdisk_image_settings.name) + self.__glance, + self.image_settings.ramdisk_image_settings.name) if not self.__ramdisk_image and not cleanup: - logger.info('Creating associated ramdisk image with name - ' - + self.image_settings.ramdisk_image_settings.name) + logger.info( + 'Creating associated ramdisk image with name - %s', + self.image_settings.ramdisk_image_settings.name) self.__ramdisk_image = glance_utils.create_image( - self.__glance, self.image_settings.ramdisk_image_settings) + self.__glance, + self.image_settings.ramdisk_image_settings) extra_properties['ramdisk_id'] = self.__ramdisk_image.id self.image_settings.extra_properties = extra_properties - self.__image = glance_utils.create_image(self.__glance, self.image_settings) + self.__image = glance_utils.create_image(self.__glance, + self.image_settings) - logger.info('Created image with name - ' + self.image_settings.name) + logger.info( + 'Created image with name - %s', self.image_settings.name) if self.__image and self.image_active(block=True): - logger.info('Image is now active with name - ' + self.image_settings.name) + logger.info( + 'Image is now active with name - %s', + self.image_settings.name) return self.__image else: - raise ImageCreationError('Image was not created or activated in the alloted amount of time') + raise ImageCreationError( + 'Image was not created or activated in the alloted amount' + 'of time') else: logger.info('Did not create image due to cleanup mode') @@ -116,40 +134,51 @@ class OpenStackImage: def get_image(self): """ - Returns the domain Image object as it was populated when create() was called + Returns the domain Image object as it was populated when create() was + called :return: the object """ return self.__image def get_kernel_image(self): """ - Returns the OpenStack kernel image object as it was populated when create() was called + Returns the OpenStack kernel image object as it was populated when + create() was called :return: the object """ return self.__kernel_image def get_ramdisk_image(self): """ - Returns the OpenStack ramdisk image object as it was populated when create() was called + Returns the OpenStack ramdisk image object as it was populated when + create() was called :return: the object """ return self.__ramdisk_image - def image_active(self, block=False, timeout=IMAGE_ACTIVE_TIMEOUT, poll_interval=POLL_INTERVAL): + def image_active(self, block=False, timeout=IMAGE_ACTIVE_TIMEOUT, + poll_interval=POLL_INTERVAL): """ - Returns true when the image status returns the value of expected_status_code - :param block: When true, thread will block until active or timeout value in seconds has been exceeded (False) + Returns true when the image status returns the value of + expected_status_code + :param block: When true, thread will block until active or timeout + value in seconds has been exceeded (False) :param timeout: The timeout value :param poll_interval: The polling interval in seconds :return: T/F """ - return self._image_status_check(STATUS_ACTIVE, block, timeout, poll_interval) + return self._image_status_check(STATUS_ACTIVE, block, timeout, + poll_interval) - def _image_status_check(self, expected_status_code, block, timeout, poll_interval): + def _image_status_check(self, expected_status_code, block, timeout, + poll_interval): """ - Returns true when the image status returns the value of expected_status_code - :param expected_status_code: instance status evaluated with this string value - :param block: When true, thread will block until active or timeout value in seconds has been exceeded (False) + Returns true when the image status returns the value of + expected_status_code + :param expected_status_code: instance status evaluated with this string + value + :param block: When true, thread will block until active or timeout + value in seconds has been exceeded (False) :param timeout: The timeout value :param poll_interval: The polling interval in seconds :return: T/F @@ -163,26 +192,31 @@ class OpenStackImage: while timeout > time.time() - start: status = self._status(expected_status_code) if status: - logger.debug('Image is active with name - ' + self.image_settings.name) + logger.debug( + 'Image is active with name - ' + self.image_settings.name) return True - logger.debug('Retry querying image status in ' + str(poll_interval) + ' seconds') + logger.debug('Retry querying image status in ' + str( + poll_interval) + ' seconds') time.sleep(poll_interval) - logger.debug('Image status query timeout in ' + str(timeout - (time.time() - start))) + logger.debug('Image status query timeout in ' + str( + timeout - (time.time() - start))) - logger.error('Timeout checking for image status for ' + expected_status_code) + logger.error( + 'Timeout checking for image status for ' + expected_status_code) return False def _status(self, expected_status_code): """ Returns True when active else False - :param expected_status_code: instance status evaluated with this string value + :param expected_status_code: instance status evaluated with this string + value :return: T/F """ - # TODO - Place this API call into glance_utils. status = glance_utils.get_image_status(self.__glance, self.__image) if not status: - logger.warning('Cannot image status for image with ID - ' + self.__image.id) + logger.warning( + 'Cannot image status for image with ID - ' + self.__image.id) return False if status == 'ERROR': @@ -192,87 +226,96 @@ class OpenStackImage: class ImageSettings: - def __init__(self, config=None, name=None, image_user=None, img_format=None, url=None, image_file=None, - extra_properties=None, nic_config_pb_loc=None, kernel_image_settings=None, - ramdisk_image_settings=None, exists=False, public=False): + def __init__(self, **kwargs): """ - - :param config: dict() object containing the configuration settings using the attribute names below as each - member's the key and overrides any of the other parameters. + Constructor :param name: the image's name (required) :param image_user: the image's default sudo user (required) - :param img_format: the image type (required) - :param url: the image download location (requires url or img_file) + :param format or img_format: the image type (required) + :param url or download_url: the image download location (requires url + or img_file) :param image_file: the image file location (requires url or img_file) - :param extra_properties: dict() object containing extra parameters to pass when loading the image; - can be ids of kernel and initramfs images for a 3-part image - :param nic_config_pb_loc: the file location to the Ansible Playbook that can configure multiple NICs + :param extra_properties: dict() object containing extra parameters to + pass when loading the image; + can be ids of kernel and initramfs images for + a 3-part image + :param nic_config_pb_loc: the file location to the Ansible Playbook + that can configure multiple NICs :param kernel_image_settings: the settings for a kernel image :param ramdisk_image_settings: the settings for a kernel image :param exists: When True, an image with the given name must exist - :param public: When True, an image will be created with public visibility + :param public: When True, an image will be created with public + visibility """ - if config: - self.name = config.get('name') - self.image_user = config.get('image_user') - self.format = config.get('format') - self.url = config.get('download_url') - self.image_file = config.get('image_file') - self.extra_properties = config.get('extra_properties') - self.nic_config_pb_loc = config.get('nic_config_pb_loc') - if config.get('kernel_image_settings'): - self.kernel_image_settings = ImageSettings(config=config['kernel_image_settings']) + self.name = kwargs.get('name') + self.image_user = kwargs.get('image_user') + self.format = kwargs.get('format') + if not self.format: + self.format = kwargs.get('img_format') + + self.url = kwargs.get('url') + if not self.url: + self.url = kwargs.get('download_url') + + self.image_file = kwargs.get('image_file') + self.extra_properties = kwargs.get('extra_properties') + self.nic_config_pb_loc = kwargs.get('nic_config_pb_loc') + + kernel_image_settings = kwargs.get('kernel_image_settings') + if kernel_image_settings: + if isinstance(kernel_image_settings, dict): + self.kernel_image_settings = ImageSettings( + **kernel_image_settings) else: - self.kernel_image_settings = None + self.kernel_image_settings = kernel_image_settings + else: + self.kernel_image_settings = None - if config.get('ramdisk_image_settings'): - self.ramdisk_image_settings = ImageSettings(config=config['ramdisk_image_settings']) + ramdisk_image_settings = kwargs.get('ramdisk_image_settings') + if ramdisk_image_settings: + if isinstance(ramdisk_image_settings, dict): + self.ramdisk_image_settings = ImageSettings( + **ramdisk_image_settings) else: - self.ramdisk_image_settings = None + self.ramdisk_image_settings = ramdisk_image_settings + else: + self.ramdisk_image_settings = None - if 'exists' in config and config['exists'] is True: - self.exists = True - else: - self.exists = False + if 'exists' in kwargs and kwargs['exists'] is True: + self.exists = True + else: + self.exists = False - if 'public' in config and config['public'] is True: - self.public = True - else: - self.public = False + if 'public' in kwargs and kwargs['public'] is True: + self.public = True else: - self.name = name - self.image_user = image_user - self.format = img_format - self.url = url - self.image_file = image_file - self.extra_properties = extra_properties - self.nic_config_pb_loc = nic_config_pb_loc - self.kernel_image_settings = kernel_image_settings - self.ramdisk_image_settings = ramdisk_image_settings - self.exists = exists - self.public = public + self.public = False if not self.name: raise ImageSettingsError("The attribute name is required") if not (self.url or self.image_file) and not self.exists: - raise ImageSettingsError('URL or image file must be set or image must already exist') + raise ImageSettingsError( + 'URL or image file must be set or image must already exist') if self.url and self.image_file: - raise ImageSettingsError('Please set either URL or image file, not both') + raise ImageSettingsError( + 'Please set either URL or image file, not both') if not self.image_user: raise ImageSettingsError('Image user is required') if not self.format and not self.exists: - raise ImageSettingsError('Format is required when the image should not already exist') + raise ImageSettingsError( + 'Format is required when the image should not already exist') class ImageSettingsError(Exception): """ Exception to be thrown when an image settings are incorrect """ + def __init__(self, message): Exception.__init__(self, message) @@ -281,5 +324,6 @@ class ImageCreationError(Exception): """ Exception to be thrown when an image cannot be created """ + def __init__(self, message): Exception.__init__(self, message) diff --git a/snaps/openstack/create_instance.py b/snaps/openstack/create_instance.py index 85e96a8..991aca5 100644 --- a/snaps/openstack/create_instance.py +++ b/snaps/openstack/create_instance.py @@ -18,11 +18,11 @@ import time from neutronclient.common.exceptions import PortNotFoundClient from novaclient.exceptions import NotFound +from snaps.openstack.create_network import PortSettings from snaps.openstack.utils import glance_utils from snaps.openstack.utils import neutron_utils -from snaps.openstack.create_network import PortSettings -from snaps.provisioning import ansible_utils from snaps.openstack.utils import nova_utils +from snaps.provisioning import ansible_utils __author__ = 'spisarski' @@ -38,7 +38,8 @@ class OpenStackVmInstance: Class responsible for creating a VM instance in OpenStack """ - def __init__(self, os_creds, instance_settings, image_settings, keypair_settings=None): + def __init__(self, os_creds, instance_settings, image_settings, + keypair_settings=None): """ Constructor :param os_creds: The connection credentials to the OpenStack API @@ -56,7 +57,8 @@ class OpenStackVmInstance: self.image_settings = image_settings self.keypair_settings = keypair_settings - # TODO - get rid of FIP list and only use the dict(). Need to fix populating this object when already exists + # TODO - get rid of FIP list and only use the dict(). Need to fix + # populating this object when already exists self.__floating_ips = list() self.__floating_ip_dict = dict() @@ -70,14 +72,17 @@ class OpenStackVmInstance: """ Creates a VM instance :param cleanup: When true, only perform lookups for OpenStack objects. - :param block: Thread will block until instance has either become active, error, or timeout waiting. - Additionally, when True, floating IPs will not be applied until VM is active. + :param block: Thread will block until instance has either become + active, error, or timeout waiting. + Additionally, when True, floating IPs will not be applied + until VM is active. :return: The VM reference object """ self.__nova = nova_utils.nova_client(self.__os_creds) self.__neutron = neutron_utils.neutron_client(self.__os_creds) - self.__ports = self.__setup_ports(self.instance_settings.port_settings, cleanup) + self.__ports = self.__setup_ports(self.instance_settings.port_settings, + cleanup) self.__lookup_existing_vm_by_name() if not self.__vm and not cleanup: self.__create_vm(block) @@ -85,25 +90,31 @@ class OpenStackVmInstance: def __lookup_existing_vm_by_name(self): """ - Populates the member variables 'self.vm' and 'self.floating_ips' if a VM with the same name already exists + Populates the member variables 'self.vm' and 'self.floating_ips' if a + VM with the same name already exists within the project """ - servers = nova_utils.get_servers_by_name(self.__nova, self.instance_settings.name) + servers = nova_utils.get_servers_by_name(self.__nova, + self.instance_settings.name) for server in servers: if server.name == self.instance_settings.name: self.__vm = server - logger.info('Found existing machine with name - ' + self.instance_settings.name) + logger.info( + 'Found existing machine with name - %s', + self.instance_settings.name) fips = self.__nova.floating_ips.list() for fip in fips: if fip.instance_id == server.id: self.__floating_ips.append(fip) - # TODO - Determine a means to associate to the FIP configuration and add to FIP map + # TODO - Determine a means to associate to the FIP + # configuration and add to FIP map def __create_vm(self, block=False): """ Responsible for creating the VM instance - :param block: Thread will block until instance has either become active, error, or timeout waiting. - Floating IPs will be assigned after active when block=True + :param block: Thread will block until instance has either become + active, error, or timeout waiting. Floating IPs will be + assigned after active when block=True """ nics = [] for key, port in self.__ports: @@ -116,12 +127,16 @@ class OpenStackVmInstance: if self.keypair_settings: keypair_name = self.keypair_settings.name - flavor = nova_utils.get_flavor_by_name(self.__nova, self.instance_settings.flavor) + flavor = nova_utils.get_flavor_by_name(self.__nova, + self.instance_settings.flavor) if not flavor: - raise Exception('Flavor not found with name - ' + self.instance_settings.flavor) + raise Exception( + 'Flavor not found with name - %s', + self.instance_settings.flavor) - image = glance_utils.get_image(glance_utils.glance_client(self.__os_creds), - self.image_settings.name) + image = glance_utils.get_image( + glance_utils.glance_client(self.__os_creds), + self.image_settings.name) if image: self.__vm = self.__nova.servers.create( name=self.instance_settings.name, @@ -134,22 +149,32 @@ class OpenStackVmInstance: availability_zone=self.instance_settings.availability_zone) else: - raise Exception('Cannot create instance, image cannot be located with name ' + self.image_settings.name) + raise Exception( + 'Cannot create instance, image cannot be located with name %s', + self.image_settings.name) - logger.info('Created instance with name - ' + self.instance_settings.name) + logger.info( + 'Created instance with name - %s', self.instance_settings.name) if block: if not self.vm_active(block=True): - raise Exception('Fatal error, VM did not become ACTIVE within the alloted time') + raise Exception( + 'Fatal error, VM did not become ACTIVE within the alloted ' + 'time') - # TODO - the call above should add security groups. The return object shows they exist but the association - # had never been made by OpenStack. This call is here to ensure they have been added + # TODO - the call above should add security groups. The return object + # shows they exist but the association had never been made by + # OpenStack. This call is here to ensure they have been added for sec_grp_name in self.instance_settings.security_group_names: if self.vm_active(block=True): - nova_utils.add_security_group(self.__nova, self.__vm, sec_grp_name) + nova_utils.add_security_group(self.__nova, self.__vm, + sec_grp_name) else: - raise Exception('Cannot applying security group with name ' + sec_grp_name + - ' to VM that did not activate with name - ' + self.instance_settings.name) + raise Exception( + 'Cannot applying security group with name ' + + sec_grp_name + + ' to VM that did not activate with name - ' + + self.instance_settings.name) self.__apply_floating_ips() @@ -166,33 +191,43 @@ class OpenStackVmInstance: port = port_dict.get(floating_ip_setting.port_name) if not port: - raise Exception('Cannot find port object with name - ' + floating_ip_setting.port_name) - - # Setup Floating IP only if there is a router with an external gateway - ext_gateway = self.__ext_gateway_by_router(floating_ip_setting.router_name) + raise Exception( + 'Cannot find port object with name - ' + + floating_ip_setting.port_name) + + # Setup Floating IP only if there is a router with an external + # gateway + ext_gateway = self.__ext_gateway_by_router( + floating_ip_setting.router_name) if ext_gateway: - subnet = neutron_utils.get_subnet_by_name(self.__neutron, floating_ip_setting.subnet_name) - floating_ip = nova_utils.create_floating_ip(self.__nova, ext_gateway) + subnet = neutron_utils.get_subnet_by_name( + self.__neutron, floating_ip_setting.subnet_name) + floating_ip = nova_utils.create_floating_ip(self.__nova, + ext_gateway) self.__floating_ips.append(floating_ip) self.__floating_ip_dict[floating_ip_setting.name] = floating_ip - logger.info('Created floating IP ' + floating_ip.ip + ' via router - ' + - floating_ip_setting.router_name) + logger.info( + 'Created floating IP %s via router - %s', floating_ip.ip, + floating_ip_setting.router_name) self.__add_floating_ip(floating_ip, port, subnet) else: - raise Exception('Unable to add floating IP to port,' + - ' cannot locate router with an external gateway ') + raise Exception('Unable to add floating IP to port,' + ' cannot locate router with an external ' + 'gateway ') def __ext_gateway_by_router(self, router_name): """ - Returns network name for the external network attached to a router or None if not found + Returns network name for the external network attached to a router or + None if not found :param router_name: The name of the router to lookup :return: the external network name or None """ router = neutron_utils.get_router_by_name(self.__neutron, router_name) if router and router['router'].get('external_gateway_info'): - network = neutron_utils.get_network_by_id(self.__neutron, - router['router']['external_gateway_info']['network_id']) + network = neutron_utils.get_network_by_id( + self.__neutron, + router['router']['external_gateway_info']['network_id']) if network: return network['network']['name'] return None @@ -218,48 +253,58 @@ class OpenStackVmInstance: try: neutron_utils.delete_port(self.__neutron, port) except PortNotFoundClient as e: - logger.warning('Unexpected error deleting port - ' + str(e)) + logger.warning('Unexpected error deleting port - %s', e) pass self.__ports = list() # Cleanup VM if self.__vm: try: - logger.info('Deleting VM instance - ' + self.instance_settings.name) + logger.info( + 'Deleting VM instance - ' + self.instance_settings.name) nova_utils.delete_vm_instance(self.__nova, self.__vm) except Exception as e: - logger.error('Error deleting VM - ' + str(e)) + logger.error('Error deleting VM - %s', e) - # Block until instance cannot be found or returns the status of DELETED + # Block until instance cannot be found or returns the status of + # DELETED logger.info('Checking deletion status') try: if self.vm_deleted(block=True): - logger.info('VM has been properly deleted VM with name - ' + self.instance_settings.name) + logger.info( + 'VM has been properly deleted VM with name - %s', + self.instance_settings.name) self.__vm = None else: - logger.error('VM not deleted within the timeout period of ' + - str(self.instance_settings.vm_delete_timeout) + ' seconds') + logger.error( + 'VM not deleted within the timeout period of %s ' + 'seconds', self.instance_settings.vm_delete_timeout) except Exception as e: - logger.error('Unexpected error while checking VM instance status - ' + str(e)) + logger.error( + 'Unexpected error while checking VM instance status - %s', + e) def __setup_ports(self, port_settings, cleanup): """ - Returns the previously configured ports or creates them if they do not exist + Returns the previously configured ports or creates them if they do not + exist :param port_settings: A list of PortSetting objects :param cleanup: When true, only perform lookups for OpenStack objects. - :return: a list of OpenStack port tuples where the first member is the port name and the second is the port - object + :return: a list of OpenStack port tuples where the first member is the + port name and the second is the port object """ ports = list() for port_setting in port_settings: # First check to see if network already has this port - # TODO/FIXME - this could potentially cause problems if another port with the same name exists + # TODO/FIXME - this could potentially cause problems if another + # port with the same name exists # VM has the same network/port name pair found = False - # TODO/FIXME - should we not be iterating on ports for the specific network in question as unique port names + # TODO/FIXME - should we not be iterating on ports for the specific + # network in question as unique port names # seem to only be important by network existing_ports = self.__neutron.list_ports()['ports'] for existing_port in existing_ports: @@ -269,12 +314,15 @@ class OpenStackVmInstance: break if not found and not cleanup: - ports.append((port_setting.name, neutron_utils.create_port(self.__neutron, self.__os_creds, - port_setting))) + ports.append((port_setting.name, + neutron_utils.create_port(self.__neutron, + self.__os_creds, + port_setting))) return ports - def __add_floating_ip(self, floating_ip, port, subnet, timeout=30, poll_interval=POLL_INTERVAL): + def __add_floating_ip(self, floating_ip, port, subnet, timeout=30, + poll_interval=POLL_INTERVAL): """ Returns True when active else False TODO - Make timeout and poll_interval configurable... @@ -282,7 +330,8 @@ class OpenStackVmInstance: ip = None if subnet: - # Take IP of subnet if there is one configured on which to place the floating IP + # Take IP of subnet if there is one configured on which to place + # the floating IP for fixed_ip in port['port']['fixed_ips']: if fixed_ip['subnet_id'] == subnet['subnet']['id']: ip = fixed_ip['ip_address'] @@ -297,16 +346,20 @@ class OpenStackVmInstance: logger.debug('Attempting to add floating IP to instance') try: self.__vm.add_floating_ip(floating_ip, ip) - logger.info('Added floating IP ' + floating_ip.ip + ' to port IP - ' + ip + - ' on instance - ' + self.instance_settings.name) + logger.info( + 'Added floating IP %s to port IP %s on instance %s', + floating_ip.ip, ip, self.instance_settings.name) return except Exception as e: - logger.debug('Retry adding floating IP to instance. Last attempt failed with - ' + str(e)) + logger.debug( + 'Retry adding floating IP to instance. Last attempt ' + 'failed with - %s', e) time.sleep(poll_interval) count -= 1 pass else: - raise Exception('Unable find IP address on which to place the floating IP') + raise Exception( + 'Unable find IP address on which to place the floating IP') logger.error('Timeout attempting to add the floating IP to instance.') raise Exception('Timeout while attempting add floating IP to instance') @@ -327,8 +380,9 @@ class OpenStackVmInstance: def get_port_ip(self, port_name, subnet_name=None): """ - Returns the first IP for the port corresponding with the port_name parameter when subnet_name is None - else returns the IP address that corresponds to the subnet_name parameter + Returns the first IP for the port corresponding with the port_name + parameter when subnet_name is None else returns the IP address that + corresponds to the subnet_name parameter :param port_name: the name of the port from which to return the IP :param subnet_name: the name of the subnet attached to this IP :return: the IP or None if not found @@ -337,9 +391,12 @@ class OpenStackVmInstance: if port: port_dict = port['port'] if subnet_name: - subnet = neutron_utils.get_subnet_by_name(self.__neutron, subnet_name) + subnet = neutron_utils.get_subnet_by_name(self.__neutron, + subnet_name) if not subnet: - logger.warning('Cannot retrieve port IP as subnet could not be located with name - ' + subnet_name) + logger.warning('Cannot retrieve port IP as subnet could ' + 'not be located with name - %s', + subnet_name) return None for fixed_ip in port_dict['fixed_ips']: if fixed_ip['subnet_id'] == subnet['subnet']['id']: @@ -352,8 +409,10 @@ class OpenStackVmInstance: def get_port_mac(self, port_name): """ - Returns the first IP for the port corresponding with the port_name parameter - TODO - Add in the subnet as an additional parameter as a port may have multiple fixed_ips + Returns the first IP for the port corresponding with the port_name + parameter + TODO - Add in the subnet as an additional parameter as a port may have + multiple fixed_ips :param port_name: the name of the port from which to return the IP :return: the IP or None if not found """ @@ -377,7 +436,8 @@ class OpenStackVmInstance: def config_nics(self): """ - Responsible for configuring NICs on RPM systems where the instance has more than one configured port + Responsible for configuring NICs on RPM systems where the instance has + more than one configured port :return: None """ if len(self.__ports) > 1 and len(self.__floating_ips) > 0: @@ -386,12 +446,16 @@ class OpenStackVmInstance: port_index = self.__ports.index((key, port)) if port_index > 0: nic_name = 'eth' + repr(port_index) - self.__config_nic(nic_name, port, self.__get_first_provisioning_floating_ip().ip) - logger.info('Configured NIC - ' + nic_name + ' on VM - ' + self.instance_settings.name) + self.__config_nic( + nic_name, port, + self.__get_first_provisioning_floating_ip().ip) + logger.info('Configured NIC - %s on VM - %s', + nic_name, self.instance_settings.name) def __get_first_provisioning_floating_ip(self): """ - Returns the first floating IP tagged with the Floating IP name if exists else the first one found + Returns the first floating IP tagged with the Floating IP name if + exists else the first one found :return: """ for floating_ip_setting in self.instance_settings.floating_ip_settings: @@ -404,10 +468,8 @@ class OpenStackVmInstance: def __config_nic(self, nic_name, port, floating_ip): """ - Although ports/NICs can contain multiple IPs, this code currently only supports the first. - - Your CWD at this point must be the <repo dir>/python directory. - TODO - fix this restriction. + Although ports/NICs can contain multiple IPs, this code currently only + supports the first. :param nic_name: Name of the interface :param port: The port information containing the expected IP values. @@ -422,27 +484,33 @@ class OpenStackVmInstance: } if self.image_settings.nic_config_pb_loc and self.keypair_settings: - return self.apply_ansible_playbook(self.image_settings.nic_config_pb_loc, variables) + return self.apply_ansible_playbook( + self.image_settings.nic_config_pb_loc, variables) else: - logger.warning('VM ' + self.instance_settings.name + ' cannot self configure NICs eth1++. ' + - 'No playbook or keypairs found.') + logger.warning( + 'VM %s cannot self configure NICs eth1++. No playbook or ' + 'keypairs found.', self.instance_settings.name) - def apply_ansible_playbook(self, pb_file_loc, variables=None, fip_name=None): + def apply_ansible_playbook(self, pb_file_loc, variables=None, + fip_name=None): """ Applies a playbook to a VM :param pb_file_loc: the file location of the playbook to be applied - :param variables: a dict() of substitution values required by the playbook - :param fip_name: the name of the floating IP to use for applying the playbook (default - will take the first) + :param variables: a dict() of substitution values required by the + playbook + :param fip_name: the name of the floating IP to use for applying the + playbook (default - will take the first) :return: the return value from ansible """ - return ansible_utils.apply_playbook(pb_file_loc, [self.get_floating_ip(fip_name=fip_name).ip], - self.get_image_user(), self.keypair_settings.private_filepath, - variables, self.__os_creds.proxy_settings) + return ansible_utils.apply_playbook( + pb_file_loc, [self.get_floating_ip(fip_name=fip_name).ip], + self.get_image_user(), self.keypair_settings.private_filepath, + variables, self.__os_creds.proxy_settings) def get_image_user(self): """ - Returns the instance sudo_user if it has been configured in the instance_settings else it returns the - image_settings.image_user value + Returns the instance sudo_user if it has been configured in the + instance_settings else it returns the image_settings.image_user value """ if self.instance_settings.sudo_user: return self.instance_settings.sudo_user @@ -451,33 +519,45 @@ class OpenStackVmInstance: def vm_deleted(self, block=False, poll_interval=POLL_INTERVAL): """ - Returns true when the VM status returns the value of expected_status_code or instance retrieval throws - a NotFound exception. - :param block: When true, thread will block until active or timeout value in seconds has been exceeded (False) + Returns true when the VM status returns the value of + expected_status_code or instance retrieval throws a NotFound exception. + :param block: When true, thread will block until active or timeout + value in seconds has been exceeded (False) :param poll_interval: The polling interval in seconds :return: T/F """ try: - return self.__vm_status_check(STATUS_DELETED, block, self.instance_settings.vm_delete_timeout, - poll_interval) + return self.__vm_status_check( + STATUS_DELETED, block, + self.instance_settings.vm_delete_timeout, poll_interval) except NotFound as e: - logger.debug("Instance not found when querying status for " + STATUS_DELETED + ' with message ' + str(e)) + logger.debug( + "Instance not found when querying status for %s with message " + "%s", STATUS_DELETED, e) return True def vm_active(self, block=False, poll_interval=POLL_INTERVAL): """ - Returns true when the VM status returns the value of expected_status_code - :param block: When true, thread will block until active or timeout value in seconds has been exceeded (False) + Returns true when the VM status returns the value of + expected_status_code + :param block: When true, thread will block until active or timeout + value in seconds has been exceeded (False) :param poll_interval: The polling interval in seconds :return: T/F """ - return self.__vm_status_check(STATUS_ACTIVE, block, self.instance_settings.vm_boot_timeout, poll_interval) + return self.__vm_status_check(STATUS_ACTIVE, block, + self.instance_settings.vm_boot_timeout, + poll_interval) - def __vm_status_check(self, expected_status_code, block, timeout, poll_interval): + def __vm_status_check(self, expected_status_code, block, timeout, + poll_interval): """ - Returns true when the VM status returns the value of expected_status_code - :param expected_status_code: instance status evaluated with this string value - :param block: When true, thread will block until active or timeout value in seconds has been exceeded (False) + Returns true when the VM status returns the value of + expected_status_code + :param expected_status_code: instance status evaluated with this + string value + :param block: When true, thread will block until active or timeout + value in seconds has been exceeded (False) :param timeout: The timeout value :param poll_interval: The polling interval in seconds :return: T/F @@ -494,17 +574,21 @@ class OpenStackVmInstance: logger.info('VM is - ' + expected_status_code) return True - logger.debug('Retry querying VM status in ' + str(poll_interval) + ' seconds') + logger.debug('Retry querying VM status in ' + str( + poll_interval) + ' seconds') time.sleep(poll_interval) - logger.debug('VM status query timeout in ' + str(timeout - (time.time() - start))) + logger.debug('VM status query timeout in ' + str( + timeout - (time.time() - start))) - logger.error('Timeout checking for VM status for ' + expected_status_code) + logger.error( + 'Timeout checking for VM status for ' + expected_status_code) return False def __status(self, expected_status_code): """ Returns True when active else False - :param expected_status_code: instance status evaluated with this string value + :param expected_status_code: instance status evaluated with this string + value :return: T/F """ if not self.__vm: @@ -517,13 +601,16 @@ class OpenStackVmInstance: if instance.status == 'ERROR': raise Exception('Instance had an error during deployment') - logger.debug('Instance status [' + self.instance_settings.name + '] is - ' + instance.status) + logger.debug( + 'Instance status [%s] is - %s', self.instance_settings.name, + instance.status) return instance.status == expected_status_code def vm_ssh_active(self, block=False, poll_interval=POLL_INTERVAL): """ Returns true when the VM can be accessed via SSH - :param block: When true, thread will block until active or timeout value in seconds has been exceeded (False) + :param block: When true, thread will block until active or timeout + value in seconds has been exceeded (False) :param poll_interval: The polling interval :return: T/F """ @@ -544,9 +631,11 @@ class OpenStackVmInstance: logger.info('SSH is active for VM instance') return True - logger.debug('Retry SSH connection in ' + str(poll_interval) + ' seconds') + logger.debug('Retry SSH connection in ' + str( + poll_interval) + ' seconds') time.sleep(poll_interval) - logger.debug('SSH connection timeout in ' + str(timeout - (time.time() - start))) + logger.debug('SSH connection timeout in ' + str( + timeout - (time.time() - start))) logger.error('Timeout attempting to connect with VM via SSH') return False @@ -564,7 +653,8 @@ class OpenStackVmInstance: def get_floating_ip(self, fip_name=None): """ - Returns the floating IP object byt name if found, else the first known, else None + Returns the floating IP object byt name if found, else the first known, + else None :param fip_name: the name of the floating IP to return :return: the SSH client or None """ @@ -577,17 +667,20 @@ class OpenStackVmInstance: def ssh_client(self, fip_name=None): """ - Returns an SSH client using the name or the first known floating IP if exists, else None + Returns an SSH client using the name or the first known floating IP if + exists, else None :param fip_name: the name of the floating IP to return :return: the SSH client or None """ fip = self.get_floating_ip(fip_name) if fip: - return ansible_utils.ssh_client(self.__floating_ips[0].ip, self.get_image_user(), - self.keypair_settings.private_filepath, - proxy_settings=self.__os_creds.proxy_settings) + return ansible_utils.ssh_client( + self.__floating_ips[0].ip, self.get_image_user(), + self.keypair_settings.private_filepath, + proxy_settings=self.__os_creds.proxy_settings) else: - logger.warning('Cannot return an SSH client. No Floating IP configured') + logger.warning( + 'Cannot return an SSH client. No Floating IP configured') def add_security_group(self, security_group): """ @@ -602,7 +695,9 @@ class OpenStackVmInstance: return False try: - nova_utils.add_security_group(self.__nova, self.get_vm_inst(), security_group['security_group']['name']) + nova_utils.add_security_group(self.__nova, self.get_vm_inst(), + security_group['security_group'][ + 'name']) return True except NotFound as e: logger.warning('Security group not added - ' + str(e)) @@ -610,7 +705,7 @@ class OpenStackVmInstance: def remove_security_group(self, security_group): """ - Removes a security group to this VM. Call will block until VM is active. + Removes a security group to this VM. Call will block until VM is active :param security_group: the OpenStack security group object :return True if successful else False """ @@ -621,7 +716,8 @@ class OpenStackVmInstance: return False try: - nova_utils.remove_security_group(self.__nova, self.get_vm_inst(), security_group) + nova_utils.remove_security_group(self.__nova, self.get_vm_inst(), + security_group) return True except NotFound as e: logger.warning('Security group not removed - ' + str(e)) @@ -632,134 +728,133 @@ class VmInstanceSettings: """ Class responsible for holding configuration setting for a VM Instance """ - def __init__(self, config=None, name=None, flavor=None, port_settings=list(), security_group_names=set(), - floating_ip_settings=list(), sudo_user=None, vm_boot_timeout=900, - vm_delete_timeout=300, ssh_connect_timeout=180, availability_zone=None, userdata=None): + + def __init__(self, **kwargs): """ Constructor - :param config: dict() object containing the configuration settings using the attribute names below as each - member's the key and overrides any of the other parameters. :param name: the name of the VM :param flavor: the VM's flavor :param port_settings: the port configuration settings (required) - :param security_group_names: a set of names of the security groups to add to the VM + :param security_group_names: a set of names of the security groups to + add to the VM :param floating_ip_settings: the floating IP configuration settings - :param sudo_user: the sudo user of the VM that will override the instance_settings.image_user when trying to + :param sudo_user: the sudo user of the VM that will override the + instance_settings.image_user when trying to connect to the VM - :param vm_boot_timeout: the amount of time a thread will sleep waiting for an instance to boot - :param vm_delete_timeout: the amount of time a thread will sleep waiting for an instance to be deleted - :param ssh_connect_timeout: the amount of time a thread will sleep waiting obtaining an SSH connection to a VM - :param availability_zone: the name of the compute server on which to deploy the VM (optional) - :param userdata: the cloud-init script to run after the VM has been started - """ - if config: - self.name = config.get('name') - self.flavor = config.get('flavor') - self.sudo_user = config.get('sudo_user') - self.userdata = config.get('userdata') - - self.port_settings = list() - if config.get('ports'): - for port_config in config['ports']: - if isinstance(port_config, PortSettings): - self.port_settings.append(port_config) - else: - self.port_settings.append(PortSettings(config=port_config['port'])) - - if config.get('security_group_names'): - if isinstance(config['security_group_names'], list): - self.security_group_names = set(config['security_group_names']) - elif isinstance(config['security_group_names'], set): - self.security_group_names = config['security_group_names'] - elif isinstance(config['security_group_names'], str): - self.security_group_names = [config['security_group_names']] - else: - raise Exception('Invalid data type for security_group_names attribute') + :param vm_boot_timeout: the amount of time a thread will sleep waiting + for an instance to boot + :param vm_delete_timeout: the amount of time a thread will sleep + waiting for an instance to be deleted + :param ssh_connect_timeout: the amount of time a thread will sleep + waiting obtaining an SSH connection to a VM + :param availability_zone: the name of the compute server on which to + deploy the VM (optional) + :param userdata: the cloud-init script to run after the VM has been + started + """ + self.name = kwargs.get('name') + self.flavor = kwargs.get('flavor') + self.sudo_user = kwargs.get('sudo_user') + self.userdata = kwargs.get('userdata') + + self.port_settings = list() + port_settings = kwargs.get('ports') + if not port_settings: + port_settings = kwargs.get('port_settings') + if port_settings: + for port_setting in port_settings: + if isinstance(port_setting, dict): + self.port_settings.append(PortSettings(**port_setting)) + elif isinstance(port_setting, PortSettings): + self.port_settings.append(port_setting) + + if kwargs.get('security_group_names'): + if isinstance(kwargs['security_group_names'], list): + self.security_group_names = kwargs['security_group_names'] + elif isinstance(kwargs['security_group_names'], set): + self.security_group_names = kwargs['security_group_names'] + elif isinstance(kwargs['security_group_names'], str): + self.security_group_names = [kwargs['security_group_names']] else: - self.security_group_names = set() - - self.floating_ip_settings = list() - if config.get('floating_ips'): - for floating_ip_config in config['floating_ips']: - if isinstance(floating_ip_config, FloatingIpSettings): - self.floating_ip_settings.append(floating_ip_config) - else: - self.floating_ip_settings.append(FloatingIpSettings(config=floating_ip_config['floating_ip'])) - - if config.get('vm_boot_timeout'): - self.vm_boot_timeout = config['vm_boot_timeout'] - else: - self.vm_boot_timeout = vm_boot_timeout + raise Exception( + 'Invalid data type for security_group_names attribute') + else: + self.security_group_names = set() + + self.floating_ip_settings = list() + floating_ip_settings = kwargs.get('floating_ips') + if not floating_ip_settings: + floating_ip_settings = kwargs.get('floating_ip_settings') + if floating_ip_settings: + for floating_ip_config in floating_ip_settings: + if isinstance(floating_ip_config, FloatingIpSettings): + self.floating_ip_settings.append(floating_ip_config) + else: + self.floating_ip_settings.append(FloatingIpSettings( + **floating_ip_config['floating_ip'])) - if config.get('vm_delete_timeout'): - self.vm_delete_timeout = config['vm_delete_timeout'] - else: - self.vm_delete_timeout = vm_delete_timeout + if kwargs.get('vm_boot_timeout'): + self.vm_boot_timeout = kwargs['vm_boot_timeout'] + else: + self.vm_boot_timeout = 900 - if config.get('ssh_connect_timeout'): - self.ssh_connect_timeout = config['ssh_connect_timeout'] - else: - self.ssh_connect_timeout = ssh_connect_timeout + if kwargs.get('vm_delete_timeout'): + self.vm_delete_timeout = kwargs['vm_delete_timeout'] + else: + self.vm_delete_timeout = 300 - if config.get('availability_zone'): - self.availability_zone = config['availability_zone'] - else: - self.availability_zone = None + if kwargs.get('ssh_connect_timeout'): + self.ssh_connect_timeout = kwargs['ssh_connect_timeout'] + else: + self.ssh_connect_timeout = 180 + + if kwargs.get('availability_zone'): + self.availability_zone = kwargs['availability_zone'] else: - self.name = name - self.flavor = flavor - self.port_settings = port_settings - self.security_group_names = security_group_names - self.floating_ip_settings = floating_ip_settings - self.sudo_user = sudo_user - self.vm_boot_timeout = vm_boot_timeout - self.vm_delete_timeout = vm_delete_timeout - self.ssh_connect_timeout = ssh_connect_timeout - self.availability_zone = availability_zone - self.userdata = userdata + self.availability_zone = None if not self.name or not self.flavor: - raise Exception('Instance configuration requires the attributes: name, flavor') + raise Exception( + 'Instance configuration requires the attributes: name, flavor') if len(self.port_settings) == 0: - raise Exception('Instance configuration requires port settings (aka. NICS)') + raise Exception( + 'Instance configuration requires port settings (aka. NICS)') class FloatingIpSettings: """ Class responsible for holding configuration settings for a floating IP """ - def __init__(self, config=None, name=None, port_name=None, router_name=None, subnet_name=None, provisioning=True): + + def __init__(self, **kwargs): """ Constructor - :param config: dict() object containing the configuration settings using the attribute names below as each - member's the key and overrides any of the other parameters. :param name: the name of the floating IP :param port_name: the name of the router to the external network :param router_name: the name of the router to the external network - :param subnet_name: the name of the subnet on which to attach the floating IP - :param provisioning: when true, this floating IP can be used for provisioning - - TODO - provisioning flag is a hack as I have only observed a single Floating IPs that actually works on - an instance. Multiple floating IPs placed on different subnets from the same port are especially troublesome - as you cannot predict which one will actually connect. For now, it is recommended not to setup multiple - floating IPs on an instance unless absolutely necessary. - """ - if config: - self.name = config.get('name') - self.port_name = config.get('port_name') - self.router_name = config.get('router_name') - self.subnet_name = config.get('subnet_name') - if config.get('provisioning') is not None: - self.provisioning = config['provisioning'] - else: - self.provisioning = provisioning + :param subnet_name: the name of the subnet on which to attach the + floating IP + :param provisioning: when true, this floating IP can be used for + provisioning + + TODO - provisioning flag is a hack as I have only observed a single + Floating IPs that actually works on an instance. Multiple floating IPs + placed on different subnets from the same port are especially + troublesome as you cannot predict which one will actually connect. + For now, it is recommended not to setup multiple floating IPs on an + instance unless absolutely necessary. + """ + self.name = kwargs.get('name') + self.port_name = kwargs.get('port_name') + self.router_name = kwargs.get('router_name') + self.subnet_name = kwargs.get('subnet_name') + if kwargs.get('provisioning') is not None: + self.provisioning = kwargs['provisioning'] else: - self.name = name - self.port_name = port_name - self.router_name = router_name - self.subnet_name = subnet_name - self.provisioning = provisioning + self.provisioning = True if not self.name or not self.port_name or not self.router_name: - raise Exception('The attributes name, port_name and router_name are required for FloatingIPSettings') + raise Exception( + 'The attributes name, port_name and router_name are required ' + 'for FloatingIPSettings') diff --git a/snaps/openstack/create_keypairs.py b/snaps/openstack/create_keypairs.py index 9b7b350..cf5a93d 100644 --- a/snaps/openstack/create_keypairs.py +++ b/snaps/openstack/create_keypairs.py @@ -13,10 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging -import os +import os from novaclient.exceptions import NotFound - from snaps.openstack.utils import nova_utils __author__ = 'spisarski' @@ -39,6 +38,7 @@ class OpenStackKeypair: self.__os_creds = os_creds self.keypair_settings = keypair_settings self.__nova = nova_utils.nova_client(os_creds) + self.__delete_keys_on_clean = True # Attributes instantiated on create() self.__keypair = None @@ -46,27 +46,35 @@ class OpenStackKeypair: def create(self, cleanup=False): """ Responsible for creating the keypair object. - :param cleanup: Denotes whether or not this is being called for cleanup or not + :param cleanup: Denotes whether or not this is being called for cleanup + or not """ self.__nova = nova_utils.nova_client(self.__os_creds) logger.info('Creating keypair %s...' % self.keypair_settings.name) - self.__keypair = nova_utils.get_keypair_by_name(self.__nova, self.keypair_settings.name) + self.__keypair = nova_utils.get_keypair_by_name( + self.__nova, self.keypair_settings.name) if not self.__keypair and not cleanup: - if self.keypair_settings.public_filepath and os.path.isfile(self.keypair_settings.public_filepath): + if self.keypair_settings.public_filepath and os.path.isfile( + self.keypair_settings.public_filepath): logger.info("Uploading existing keypair") - self.__keypair = nova_utils.upload_keypair_file(self.__nova, self.keypair_settings.name, - self.keypair_settings.public_filepath) + self.__keypair = nova_utils.upload_keypair_file( + self.__nova, self.keypair_settings.name, + self.keypair_settings.public_filepath) + self.__delete_keys_on_clean = False else: logger.info("Creating new keypair") # TODO - Make this value configurable keys = nova_utils.create_keys(1024) - self.__keypair = nova_utils.upload_keypair(self.__nova, self.keypair_settings.name, - nova_utils.public_key_openssh(keys)) - nova_utils.save_keys_to_files(keys, self.keypair_settings.public_filepath, - self.keypair_settings.private_filepath) + self.__keypair = nova_utils.upload_keypair( + self.__nova, self.keypair_settings.name, + nova_utils.public_key_openssh(keys)) + nova_utils.save_keys_to_files( + keys, self.keypair_settings.public_filepath, + self.keypair_settings.private_filepath) + self.__delete_keys_on_clean = True return self.__keypair @@ -81,12 +89,13 @@ class OpenStackKeypair: pass self.__keypair = None - if self.keypair_settings.public_filepath: - os.chmod(self.keypair_settings.public_filepath, 0o777) - os.remove(self.keypair_settings.public_filepath) - if self.keypair_settings.private_filepath: - os.chmod(self.keypair_settings.private_filepath, 0o777) - os.remove(self.keypair_settings.private_filepath) + if self.__delete_keys_on_clean: + if self.keypair_settings.public_filepath: + os.chmod(self.keypair_settings.public_filepath, 0o777) + os.remove(self.keypair_settings.public_filepath) + if self.keypair_settings.private_filepath: + os.chmod(self.keypair_settings.private_filepath, 0o777) + os.remove(self.keypair_settings.private_filepath) def get_keypair(self): """ @@ -101,25 +110,20 @@ class KeypairSettings: Class representing a keypair configuration """ - def __init__(self, config=None, name=None, public_filepath=None, private_filepath=None): + def __init__(self, **kwargs): """ Constructor - all parameters are optional - :param config: Should be a dict object containing the configuration settings using the attribute names below - as each member's the key and overrides any of the other parameters. :param name: The keypair name. - :param public_filepath: The path to/from the filesystem where the public key file is or will be stored - :param private_filepath: The path where the generated private key file will be stored + :param public_filepath: The path to/from the filesystem where the + public key file is or will be stored + :param private_filepath: The path where the generated private key file + will be stored :return: """ - if config: - self.name = config.get('name') - self.public_filepath = config.get('public_filepath') - self.private_filepath = config.get('private_filepath') - else: - self.name = name - self.public_filepath = public_filepath - self.private_filepath = private_filepath + self.name = kwargs.get('name') + self.public_filepath = kwargs.get('public_filepath') + self.private_filepath = kwargs.get('private_filepath') if not self.name: - raise Exception('The attributes name, public_filepath, and private_filepath are required') + raise Exception('Name is a required attribute') diff --git a/snaps/openstack/create_network.py b/snaps/openstack/create_network.py index 54f0b12..8357313 100644 --- a/snaps/openstack/create_network.py +++ b/snaps/openstack/create_network.py @@ -15,7 +15,6 @@ import logging from neutronclient.common.exceptions import NotFound - from snaps.openstack.utils import keystone_utils, neutron_utils __author__ = 'spisarski' @@ -44,36 +43,49 @@ class OpenStackNetwork: def create(self, cleanup=False): """ - Responsible for creating not only the network but then a private subnet, router, and an interface to the router. + Responsible for creating not only the network but then a private + subnet, router, and an interface to the router. :param cleanup: When true, only perform lookups for OpenStack objects. :return: the created network object or None """ self.__neutron = neutron_utils.neutron_client(self.__os_creds) - logger.info('Creating neutron network %s...' % self.network_settings.name) - net_inst = neutron_utils.get_network(self.__neutron, self.network_settings.name, - self.network_settings.get_project_id(self.__os_creds)) + logger.info( + 'Creating neutron network %s...' % self.network_settings.name) + net_inst = neutron_utils.get_network( + self.__neutron, self.network_settings.name, + self.network_settings.get_project_id(self.__os_creds)) if net_inst: self.__network = net_inst else: if not cleanup: - self.__network = neutron_utils.create_network(self.__neutron, self.__os_creds, - self.network_settings) + self.__network = neutron_utils.create_network( + self.__neutron, self.__os_creds, self.network_settings) else: - logger.info('Network does not exist and will not create as in cleanup mode') + logger.info( + 'Network does not exist and will not create as in cleanup' + ' mode') return - logger.debug("Network '%s' created successfully" % self.__network['network']['id']) + logger.debug( + "Network '%s' created successfully" % self.__network['network'][ + 'id']) logger.debug('Creating Subnets....') for subnet_setting in self.network_settings.subnet_settings: - sub_inst = neutron_utils.get_subnet_by_name(self.__neutron, subnet_setting.name) + sub_inst = neutron_utils.get_subnet_by_name(self.__neutron, + subnet_setting.name) if sub_inst: self.__subnets.append(sub_inst) - logger.debug("Subnet '%s' created successfully" % sub_inst['subnet']['id']) + logger.debug( + "Subnet '%s' created successfully" % sub_inst['subnet'][ + 'id']) else: if not cleanup: - self.__subnets.append(neutron_utils.create_subnet(self.__neutron, subnet_setting, - self.__os_creds, self.__network)) + self.__subnets.append( + neutron_utils.create_subnet(self.__neutron, + subnet_setting, + self.__os_creds, + self.__network)) return self.__network @@ -83,10 +95,12 @@ class OpenStackNetwork: """ for subnet in self.__subnets: try: - logger.info('Deleting subnet with name ' + subnet['subnet']['name']) + logger.info( + 'Deleting subnet with name ' + subnet['subnet']['name']) neutron_utils.delete_subnet(self.__neutron, subnet) except NotFound as e: - logger.warning('Error deleting subnet with message - ' + str(e)) + logger.warning( + 'Error deleting subnet with message - ' + str(e)) pass self.__subnets = list() @@ -118,65 +132,64 @@ class NetworkSettings: Class representing a network configuration """ - def __init__(self, config=None, name=None, admin_state_up=True, shared=None, project_name=None, - external=False, network_type=None, physical_network=None, subnet_settings=list()): + def __init__(self, **kwargs): """ Constructor - all parameters are optional - :param config: Should be a dict object containing the configuration settings using the attribute names below - as each member's the key and overrides any of the other parameters. :param name: The network name. - :param admin_state_up: The administrative status of the network. True = up / False = down (default True) - :param shared: Boolean value indicating whether this network is shared across all projects/tenants. By default, - only administrative users can change this value. - :param project_name: Admin-only. The name of the project that will own the network. This project can be - different from the project that makes the create network request. However, only - administrative users can specify a project ID other than their own. You cannot change this - value through authorization policies. - :param external: when true, will setup an external network (default False). + :param admin_state_up: The administrative status of the network. + True = up / False = down (default True) + :param shared: Boolean value indicating whether this network is shared + across all projects/tenants. By default, only + administrative users can change this value. + :param project_name: Admin-only. The name of the project that will own + the network. This project can be different from + the project that makes the create network request. + However, only administrative users can specify a + project ID other than their own. You cannot change + this value through authorization policies. + :param external: when true, will setup an external network + (default False). :param network_type: the type of network (i.e. vlan|flat). - :param physical_network: the name of the physical network (this is required when network_type is 'flat') - :param subnet_settings: List of SubnetSettings objects. + :param physical_network: the name of the physical network + (this is required when network_type is 'flat') + :param subnets or subnet_settings: List of SubnetSettings objects. :return: """ self.project_id = None - if config: - self.name = config.get('name') - if config.get('admin_state_up') is not None: - self.admin_state_up = bool(config['admin_state_up']) - else: - self.admin_state_up = admin_state_up - - if config.get('shared') is not None: - self.shared = bool(config['shared']) - else: - self.shared = None - - self.project_name = config.get('project_name') - - if config.get('external') is not None: - self.external = bool(config.get('external')) - else: - self.external = external + self.name = kwargs.get('name') + if kwargs.get('admin_state_up') is not None: + self.admin_state_up = bool(kwargs['admin_state_up']) + else: + self.admin_state_up = True - self.network_type = config.get('network_type') - self.physical_network = config.get('physical_network') + if kwargs.get('shared') is not None: + self.shared = bool(kwargs['shared']) + else: + self.shared = None - self.subnet_settings = list() - if config.get('subnets'): - for subnet_config in config['subnets']: - self.subnet_settings.append(SubnetSettings(config=subnet_config['subnet'])) + self.project_name = kwargs.get('project_name') + if kwargs.get('external') is not None: + self.external = bool(kwargs.get('external')) else: - self.name = name - self.admin_state_up = admin_state_up - self.shared = shared - self.project_name = project_name - self.external = external - self.network_type = network_type - self.physical_network = physical_network - self.subnet_settings = subnet_settings + self.external = False + + self.network_type = kwargs.get('network_type') + self.physical_network = kwargs.get('physical_network') + + self.subnet_settings = list() + subnet_settings = kwargs.get('subnets') + if not subnet_settings: + subnet_settings = kwargs.get('subnet_settings') + if subnet_settings: + for subnet_config in subnet_settings: + if isinstance(subnet_config, SubnetSettings): + self.subnet_settings.append(subnet_config) + else: + self.subnet_settings.append( + SubnetSettings(**subnet_config['subnet'])) if not self.name or len(self.name) < 1: raise Exception('Name required for networks') @@ -192,7 +205,8 @@ class NetworkSettings: else: if self.project_name: keystone = keystone_utils.keystone_client(os_creds) - project = keystone_utils.get_project(keystone, self.project_name) + project = keystone_utils.get_project(keystone, + self.project_name) if project: return project.id @@ -201,8 +215,8 @@ class NetworkSettings: def dict_for_neutron(self, os_creds): """ Returns a dictionary object representing this object. - This is meant to be converted into JSON designed for use by the Neutron API - + This is meant to be converted into JSON designed for use by the Neutron + API TODO - expand automated testing to exercise all parameters :param os_creds: the OpenStack credentials @@ -221,7 +235,9 @@ class NetworkSettings: if project_id: out['project_id'] = project_id else: - raise Exception('Could not find project ID for project named - ' + self.project_name) + raise Exception( + 'Could not find project ID for project named - ' + + self.project_name) if self.network_type: out['provider:network_type'] = self.network_type if self.physical_network: @@ -236,26 +252,27 @@ class SubnetSettings: Class representing a subnet configuration """ - def __init__(self, config=None, cidr=None, ip_version=4, name=None, project_name=None, start=None, - end=None, gateway_ip=None, enable_dhcp=None, dns_nameservers=None, host_routes=None, destination=None, - nexthop=None, ipv6_ra_mode=None, ipv6_address_mode=None): + def __init__(self, **kwargs): """ Constructor - all parameters are optional except cidr (subnet mask) - :param config: Should be a dict object containing the configuration settings using the attribute names below - as each member's the key and overrides any of the other parameters. :param cidr: The CIDR. REQUIRED if config parameter is None :param ip_version: The IP version, which is 4 or 6. :param name: The subnet name. - :param project_name: The name of the project who owns the network. Only administrative users can specify a - project ID other than their own. You cannot change this value through authorization - policies. + :param project_name: The name of the project who owns the network. + Only administrative users can specify a project ID + other than their own. You cannot change this value + through authorization policies. :param start: The start address for the allocation pools. :param end: The end address for the allocation pools. :param gateway_ip: The gateway IP address. - :param enable_dhcp: Set to true if DHCP is enabled and false if DHCP is disabled. - :param dns_nameservers: A list of DNS name servers for the subnet. Specify each name server as an IP address - and separate multiple entries with a space. For example [8.8.8.7 8.8.8.8]. - :param host_routes: A list of host route dictionaries for the subnet. For example: + :param enable_dhcp: Set to true if DHCP is enabled and false if DHCP is + disabled. + :param dns_nameservers: A list of DNS name servers for the subnet. + Specify each name server as an IP address + and separate multiple entries with a space. + For example [8.8.8.7 8.8.8.8]. + :param host_routes: A list of host route dictionaries for the subnet. + For example: "host_routes":[ { "destination":"0.0.0.0/0", @@ -268,56 +285,36 @@ class SubnetSettings: ] :param destination: The destination for static route :param nexthop: The next hop for the destination. - :param ipv6_ra_mode: A valid value is dhcpv6-stateful, dhcpv6-stateless, or slaac. - :param ipv6_address_mode: A valid value is dhcpv6-stateful, dhcpv6-stateless, or slaac. + :param ipv6_ra_mode: A valid value is dhcpv6-stateful, + dhcpv6-stateless, or slaac. + :param ipv6_address_mode: A valid value is dhcpv6-stateful, + dhcpv6-stateless, or slaac. :raise: Exception when config does not have or cidr values are None """ - if not dns_nameservers: - dns_nameservers = ['8.8.8.8'] - - if config: - self.cidr = config['cidr'] - if config.get('ip_version'): - self.ip_version = config['ip_version'] - else: - self.ip_version = ip_version - - # Optional attributes that can be set after instantiation - self.name = config.get('name') - self.project_name = config.get('project_name') - self.start = config.get('start') - self.end = config.get('end') - self.gateway_ip = config.get('gateway_ip') - self.enable_dhcp = config.get('enable_dhcp') - - if config.get('dns_nameservers'): - self.dns_nameservers = config.get('dns_nameservers') - else: - self.dns_nameservers = dns_nameservers - - self.host_routes = config.get('host_routes') - self.destination = config.get('destination') - self.nexthop = config.get('nexthop') - self.ipv6_ra_mode = config.get('ipv6_ra_mode') - self.ipv6_address_mode = config.get('ipv6_address_mode') + self.cidr = kwargs['cidr'] + if kwargs.get('ip_version'): + self.ip_version = kwargs['ip_version'] + else: + self.ip_version = 4 + + # Optional attributes that can be set after instantiation + self.name = kwargs.get('name') + self.project_name = kwargs.get('project_name') + self.start = kwargs.get('start') + self.end = kwargs.get('end') + self.gateway_ip = kwargs.get('gateway_ip') + self.enable_dhcp = kwargs.get('enable_dhcp') + + if kwargs.get('dns_nameservers'): + self.dns_nameservers = kwargs.get('dns_nameservers') else: - # Required attributes - self.cidr = cidr - self.ip_version = ip_version - - # Optional attributes that can be set after instantiation - self.name = name - self.project_name = project_name - self.start = start - self.end = end - self.gateway_ip = gateway_ip - self.enable_dhcp = enable_dhcp - self.dns_nameservers = dns_nameservers - self.host_routes = host_routes - self.destination = destination - self.nexthop = nexthop - self.ipv6_ra_mode = ipv6_ra_mode - self.ipv6_address_mode = ipv6_address_mode + self.dns_nameservers = ['8.8.8.8'] + + self.host_routes = kwargs.get('host_routes') + self.destination = kwargs.get('destination') + self.nexthop = kwargs.get('nexthop') + self.ipv6_ra_mode = kwargs.get('ipv6_ra_mode') + self.ipv6_address_mode = kwargs.get('ipv6_address_mode') if not self.name or not self.cidr: raise Exception('Name and cidr required for subnets') @@ -325,9 +322,11 @@ class SubnetSettings: def dict_for_neutron(self, os_creds, network=None): """ Returns a dictionary object representing this object. - This is meant to be converted into JSON designed for use by the Neutron API + This is meant to be converted into JSON designed for use by the Neutron + API :param os_creds: the OpenStack credentials - :param network: (Optional) the network object on which the subnet will be created + :param network: The network object on which the subnet will be created + (optional) :return: the dictionary object """ out = { @@ -348,7 +347,9 @@ class SubnetSettings: if project_id: out['project_id'] = project_id else: - raise Exception('Could not find project ID for project named - ' + self.project_name) + raise Exception( + 'Could not find project ID for project named - ' + + self.project_name) if self.start and self.end: out['allocation_pools'] = [{'start': self.start, 'end': self.end}] if self.gateway_ip: @@ -375,73 +376,68 @@ class PortSettings: Class representing a port configuration """ - def __init__(self, config=None, name=None, network_name=None, admin_state_up=True, project_name=None, - mac_address=None, ip_addrs=None, fixed_ips=None, security_groups=None, allowed_address_pairs=None, - opt_value=None, opt_name=None, device_owner=None, device_id=None): + def __init__(self, **kwargs): """ Constructor - all parameters are optional - :param config: Should be a dict object containing the configuration settings using the attribute names below - as each member's the key and overrides any of the other parameters. :param name: A symbolic name for the port. - :param network_name: The name of the network on which to create the port. - :param admin_state_up: A boolean value denoting the administrative status of the port. True = up / False = down - :param project_name: The name of the project who owns the network. Only administrative users can specify a - project ID other than their own. You cannot change this value through authorization - policies. - :param mac_address: The MAC address. If you specify an address that is not valid, a Bad Request (400) status - code is returned. If you do not specify a MAC address, OpenStack Networking tries to - allocate one. If a failure occurs, a Service Unavailable (503) status code is returned. - :param ip_addrs: A list of dict objects where each contains two keys 'subnet_name' and 'ip' values which will - get mapped to self.fixed_ips. - These values will be directly translated into the fixed_ips dict - :param fixed_ips: A dict where the key is the subnet IDs and value is the IP address to assign to the port + :param network_name: The name of the network on which to create the + port. + :param admin_state_up: A boolean value denoting the administrative + status of the port. True = up / False = down + :param project_name: The name of the project who owns the network. + Only administrative users can specify a project ID + other than their own. You cannot change this value + through authorization policies. + :param mac_address: The MAC address. If you specify an address that is + not valid, a Bad Request (400) status code is + returned. If you do not specify a MAC address, + OpenStack Networking tries to allocate one. If a + failure occurs, a Service Unavailable (503) status + code is returned. + :param ip_addrs: A list of dict objects where each contains two keys + 'subnet_name' and 'ip' values which will get mapped to + self.fixed_ips. These values will be directly + translated into the fixed_ips dict + :param fixed_ips: A dict where the key is the subnet IDs and value is + the IP address to assign to the port :param security_groups: One or more security group IDs. - :param allowed_address_pairs: A dictionary containing a set of zero or more allowed address pairs. An address - pair contains an IP address and MAC address. + :param allowed_address_pairs: A dictionary containing a set of zero or + more allowed address pairs. An address + pair contains an IP address and MAC + address. :param opt_value: The extra DHCP option value. :param opt_name: The extra DHCP option name. - :param device_owner: The ID of the entity that uses this port. For example, a DHCP agent. - :param device_id: The ID of the device that uses this port. For example, a virtual server. + :param device_owner: The ID of the entity that uses this port. + For example, a DHCP agent. + :param device_id: The ID of the device that uses this port. + For example, a virtual server. :return: """ self.network = None - if config: - self.name = config.get('name') - self.network_name = config.get('network_name') + self.name = kwargs.get('name') + self.network_name = kwargs.get('network_name') - if config.get('admin_state_up') is not None: - self.admin_state_up = bool(config['admin_state_up']) - else: - self.admin_state_up = admin_state_up - - self.project_name = config.get('project_name') - self.mac_address = config.get('mac_address') - self.ip_addrs = config.get('ip_addrs') - self.fixed_ips = config.get('fixed_ips') - self.security_groups = config.get('security_groups') - self.allowed_address_pairs = config.get('allowed_address_pairs') - self.opt_value = config.get('opt_value') - self.opt_name = config.get('opt_name') - self.device_owner = config.get('device_owner') - self.device_id = config.get('device_id') + if kwargs.get('admin_state_up') is not None: + self.admin_state_up = bool(kwargs['admin_state_up']) else: - self.name = name - self.network_name = network_name - self.admin_state_up = admin_state_up - self.project_name = project_name - self.mac_address = mac_address - self.ip_addrs = ip_addrs - self.fixed_ips = fixed_ips - self.security_groups = security_groups - self.allowed_address_pairs = allowed_address_pairs - self.opt_value = opt_value - self.opt_name = opt_name - self.device_owner = device_owner - self.device_id = device_id + self.admin_state_up = True + + self.project_name = kwargs.get('project_name') + self.mac_address = kwargs.get('mac_address') + self.ip_addrs = kwargs.get('ip_addrs') + self.fixed_ips = kwargs.get('fixed_ips') + self.security_groups = kwargs.get('security_groups') + self.allowed_address_pairs = kwargs.get('allowed_address_pairs') + self.opt_value = kwargs.get('opt_value') + self.opt_name = kwargs.get('opt_name') + self.device_owner = kwargs.get('device_owner') + self.device_id = kwargs.get('device_id') if not self.name or not self.network_name: - raise Exception('The attributes neutron, name, and network_name are required for PortSettings') + raise Exception( + 'The attributes neutron, name, and network_name are required ' + 'for PortSettings') def __set_fixed_ips(self, neutron): """ @@ -453,17 +449,23 @@ class PortSettings: self.fixed_ips = list() for ip_addr_dict in self.ip_addrs: - subnet = neutron_utils.get_subnet_by_name(neutron, ip_addr_dict['subnet_name']) + subnet = neutron_utils.get_subnet_by_name(neutron, + ip_addr_dict[ + 'subnet_name']) if subnet: - self.fixed_ips.append({'ip_address': ip_addr_dict['ip'], 'subnet_id': subnet['subnet']['id']}) + self.fixed_ips.append({'ip_address': ip_addr_dict['ip'], + 'subnet_id': subnet['subnet'][ + 'id']}) else: - raise Exception('Invalid port configuration, subnet does not exist with name - ' + - ip_addr_dict['subnet_name']) + raise Exception( + 'Invalid port configuration, subnet does not exist ' + 'with name - ' + ip_addr_dict['subnet_name']) def dict_for_neutron(self, neutron, os_creds): """ Returns a dictionary object representing this object. - This is meant to be converted into JSON designed for use by the Neutron API + This is meant to be converted into JSON designed for use by the Neutron + API TODO - expand automated testing to exercise all parameters :param neutron: the Neutron client @@ -482,9 +484,12 @@ class PortSettings: project_id = project.id if not self.network: - self.network = neutron_utils.get_network(neutron, self.network_name, project_id) + self.network = neutron_utils.get_network(neutron, + self.network_name, + project_id) if not self.network: - raise Exception('Cannot locate network with name - ' + self.network_name) + raise Exception( + 'Cannot locate network with name - ' + self.network_name) out['network_id'] = self.network['network']['id'] @@ -496,7 +501,9 @@ class PortSettings: if project_id: out['project_id'] = project_id else: - raise Exception('Could not find project ID for project named - ' + self.project_name) + raise Exception( + 'Could not find project ID for project named - ' + + self.project_name) if self.mac_address: out['mac_address'] = self.mac_address if self.fixed_ips and len(self.fixed_ips) > 0: diff --git a/snaps/openstack/create_project.py b/snaps/openstack/create_project.py index b60d396..8d72fdb 100644 --- a/snaps/openstack/create_project.py +++ b/snaps/openstack/create_project.py @@ -15,7 +15,6 @@ import logging from keystoneclient.exceptions import NotFound - from snaps.openstack.utils import keystone_utils __author__ = 'spisarski' @@ -44,16 +43,18 @@ class OpenStackProject: def create(self, cleanup=False): """ Creates the image in OpenStack if it does not already exist - :param cleanup: Denotes whether or not this is being called for cleanup or not + :param cleanup: Denotes whether or not this is being called for cleanup :return: The OpenStack Image object """ self.__keystone = keystone_utils.keystone_client(self.__os_creds) - self.__project = keystone_utils.get_project(keystone=self.__keystone, - project_name=self.project_settings.name) + self.__project = keystone_utils.get_project( + keystone=self.__keystone, project_name=self.project_settings.name) if self.__project: - logger.info('Found project with name - ' + self.project_settings.name) + logger.info( + 'Found project with name - ' + self.project_settings.name) elif not cleanup: - self.__project = keystone_utils.create_project(self.__keystone, self.project_settings) + self.__project = keystone_utils.create_project( + self.__keystone, self.project_settings) else: logger.info('Did not create image due to cleanup mode') @@ -92,44 +93,43 @@ class OpenStackProject: :return: """ if not self.__role: - self.__role = keystone_utils.create_role(self.__keystone, self.project_settings.name + '-role') + self.__role = keystone_utils.create_role( + self.__keystone, self.project_settings.name + '-role') - keystone_utils.assoc_user_to_project(self.__keystone, self.__role, user, self.__project) + keystone_utils.assoc_user_to_project(self.__keystone, self.__role, + user, self.__project) class ProjectSettings: """ - Class to hold the configuration settings required for creating OpenStack project objects + Class to hold the configuration settings required for creating OpenStack + project objects """ - def __init__(self, config=None, name=None, domain='default', description=None, enabled=True): + + def __init__(self, **kwargs): """ Constructor - :param config: dict() object containing the configuration settings using the attribute names below as each - member's the key and overrides any of the other parameters. :param name: the project's name (required) - :param domain: the project's domain name (default 'default'). Field is used for v3 clients + :param domain: the project's domain name (default 'default'). Field is + used for v3 clients :param description: the description (optional) - :param enabled: denotes whether or not the user is enabled (default True) + :param enabled: denotes whether or not the user is enabled + (default True) """ - if config: - self.name = config.get('name') - if config.get('domain'): - self.domain = config['domain'] - else: - self.domain = domain - - self.description = config.get('description') - if config.get('enabled') is not None: - self.enabled = config['enabled'] - else: - self.enabled = enabled + self.name = kwargs.get('name') + if kwargs.get('domain'): + self.domain = kwargs['domain'] + else: + self.domain = 'default' + + self.description = kwargs.get('description') + if kwargs.get('enabled') is not None: + self.enabled = kwargs['enabled'] else: - self.name = name - self.domain = domain - self.description = description - self.enabled = enabled + self.enabled = True if not self.name: - raise Exception("The attribute name is required for ProjectSettings") + raise Exception( + "The attribute name is required for ProjectSettings") diff --git a/snaps/openstack/create_router.py b/snaps/openstack/create_router.py index 0b56424..ffdf2e6 100644 --- a/snaps/openstack/create_router.py +++ b/snaps/openstack/create_router.py @@ -15,7 +15,6 @@ import logging from neutronclient.common.exceptions import NotFound - from snaps.openstack.create_network import PortSettings from snaps.openstack.utils import neutron_utils, keystone_utils @@ -33,8 +32,9 @@ class OpenStackRouter: """ Constructor - all parameters are required :param os_creds: The credentials to connect with OpenStack - :param router_settings: The settings used to create a router object (must be an instance of the - RouterSettings class) + :param router_settings: The settings used to create a router object + (must be an instance of the RouterSettings + class) """ self.__os_creds = os_creds @@ -49,7 +49,8 @@ class OpenStackRouter: self.__internal_subnets = list() self.__internal_router_interface = None - # Dict where the port object is the key and any newly created router interfaces are the value + # Dict where the port object is the key and any newly created router + # interfaces are the value self.__ports = list() def create(self, cleanup=False): @@ -60,18 +61,22 @@ class OpenStackRouter: """ self.__neutron = neutron_utils.neutron_client(self.__os_creds) - logger.debug('Creating Router with name - ' + self.router_settings.name) + logger.debug( + 'Creating Router with name - ' + self.router_settings.name) existing = False - router_inst = neutron_utils.get_router_by_name(self.__neutron, self.router_settings.name) + router_inst = neutron_utils.get_router_by_name( + self.__neutron, self.router_settings.name) if router_inst: self.__router = router_inst existing = True else: if not cleanup: - self.__router = neutron_utils.create_router(self.__neutron, self.__os_creds, self.router_settings) + self.__router = neutron_utils.create_router( + self.__neutron, self.__os_creds, self.router_settings) for internal_subnet_name in self.router_settings.internal_subnets: - internal_subnet = neutron_utils.get_subnet_by_name(self.__neutron, internal_subnet_name) + internal_subnet = neutron_utils.get_subnet_by_name( + self.__neutron, internal_subnet_name) if internal_subnet: self.__internal_subnets.append(internal_subnet) if internal_subnet and not cleanup and not existing: @@ -79,22 +84,32 @@ class OpenStackRouter: self.__internal_router_interface = neutron_utils.add_interface_router( self.__neutron, self.__router, subnet=internal_subnet) else: - raise Exception('Subnet not found with name ' + internal_subnet_name) + raise Exception( + 'Subnet not found with name ' + internal_subnet_name) for port_setting in self.router_settings.port_settings: - port = neutron_utils.get_port_by_name(self.__neutron, port_setting.name) - logger.info('Retrieved port ' + port_setting.name + ' for router - ' + self.router_settings.name) + port = neutron_utils.get_port_by_name(self.__neutron, + port_setting.name) + logger.info( + 'Retrieved port %s for router - %s', port_setting.name, + self.router_settings.name) if port: self.__ports.append(port) if not port and not cleanup and not existing: - port = neutron_utils.create_port(self.__neutron, self.__os_creds, port_setting) + port = neutron_utils.create_port(self.__neutron, + self.__os_creds, port_setting) if port: - logger.info('Created port ' + port_setting.name + ' for router - ' + self.router_settings.name) + logger.info( + 'Created port %s for router - %s', port_setting.name, + self.router_settings.name) self.__ports.append(port) - neutron_utils.add_interface_router(self.__neutron, self.__router, port=port) + neutron_utils.add_interface_router(self.__neutron, + self.__router, + port=port) else: - raise Exception('Error creating port with name - ' + port_setting.name) + raise Exception( + 'Error creating port with name - ' + port_setting.name) return self.__router @@ -103,19 +118,24 @@ class OpenStackRouter: Removes and deletes all items created in reverse order. """ for port in self.__ports: - logger.info('Removing router interface from router ' + self.router_settings.name + - ' and port ' + port['port']['name']) + logger.info( + 'Removing router interface from router %s and port %s', + self.router_settings.name, port['port']['name']) try: - neutron_utils.remove_interface_router(self.__neutron, self.__router, port=port) + neutron_utils.remove_interface_router(self.__neutron, + self.__router, port=port) except NotFound: pass self.__ports = list() for internal_subnet in self.__internal_subnets: - logger.info('Removing router interface from router ' + self.router_settings.name + - ' and subnet ' + internal_subnet['subnet']['name']) + logger.info( + 'Removing router interface from router %s and subnet %s', + self.router_settings.name, internal_subnet['subnet']['name']) try: - neutron_utils.remove_interface_router(self.__neutron, self.__router, subnet=internal_subnet) + neutron_utils.remove_interface_router(self.__neutron, + self.__router, + subnet=internal_subnet) except NotFound: pass self.__internal_subnets = list() @@ -148,51 +168,43 @@ class RouterSettings: Class representing a router configuration """ - def __init__(self, config=None, name=None, project_name=None, external_gateway=None, - admin_state_up=True, external_fixed_ips=None, internal_subnets=list(), - port_settings=list()): + def __init__(self, **kwargs): """ Constructor - all parameters are optional - :param config: Should be a dict object containing the configuration settings using the attribute names below - as each member's the key and overrides any of the other parameters. :param name: The router name. - :param project_name: The name of the project who owns the network. Only administrative users can specify a - project ID other than their own. You cannot change this value through authorization - policies. + :param project_name: The name of the project who owns the network. Only + administrative users can specify a project ID + other than their own. You cannot change this value + through authorization policies. :param external_gateway: Name of the external network to which to route - :param admin_state_up: The administrative status of the router. True = up / False = down (default True) - :param external_fixed_ips: Dictionary containing the IP address parameters. - :param internal_subnets: List of subnet names to which to connect this router for Floating IP purposes + :param admin_state_up: The administrative status of the router. + True = up / False = down (default True) + :param external_fixed_ips: Dictionary containing the IP address + parameters. + :param internal_subnets: List of subnet names to which to connect this + router for Floating IP purposes :param port_settings: List of PortSettings objects :return: """ - if config: - self.name = config.get('name') - self.project_name = config.get('project_name') - self.external_gateway = config.get('external_gateway') - - self.admin_state_up = config.get('admin_state_up') - self.enable_snat = config.get('enable_snat') - self.external_fixed_ips = config.get('external_fixed_ips') - if config.get('internal_subnets'): - self.internal_subnets = config['internal_subnets'] - else: - self.internal_subnets = internal_subnets - - self.port_settings = list() - if config.get('interfaces'): - interfaces = config['interfaces'] - for interface in interfaces: - if interface.get('port'): - self.port_settings.append(PortSettings(config=interface['port'])) + self.name = kwargs.get('name') + self.project_name = kwargs.get('project_name') + self.external_gateway = kwargs.get('external_gateway') + + self.admin_state_up = kwargs.get('admin_state_up') + self.enable_snat = kwargs.get('enable_snat') + self.external_fixed_ips = kwargs.get('external_fixed_ips') + if kwargs.get('internal_subnets'): + self.internal_subnets = kwargs['internal_subnets'] else: - self.name = name - self.project_name = project_name - self.external_gateway = external_gateway - self.admin_state_up = admin_state_up - self.external_fixed_ips = external_fixed_ips - self.internal_subnets = internal_subnets - self.port_settings = port_settings + self.internal_subnets = list() + + self.port_settings = list() + if kwargs.get('interfaces'): + interfaces = kwargs['interfaces'] + for interface in interfaces: + if interface.get('port'): + self.port_settings.append( + PortSettings(**interface['port'])) if not self.name: raise Exception('Name is required') @@ -200,10 +212,12 @@ class RouterSettings: def dict_for_neutron(self, neutron, os_creds): """ Returns a dictionary object representing this object. - This is meant to be converted into JSON designed for use by the Neutron API + This is meant to be converted into JSON designed for use by the Neutron + API TODO - expand automated testing to exercise all parameters - :param neutron: The neutron client to retrieve external network information if necessary + :param neutron: The neutron client to retrieve external network + information if necessary :param os_creds: The OpenStack credentials :return: the dictionary object """ @@ -223,16 +237,21 @@ class RouterSettings: if project_id: out['project_id'] = project_id else: - raise Exception('Could not find project ID for project named - ' + self.project_name) + raise Exception( + 'Could not find project ID for project named - ' + + self.project_name) if self.admin_state_up is not None: out['admin_state_up'] = self.admin_state_up if self.external_gateway: - ext_net = neutron_utils.get_network(neutron, self.external_gateway, project_id) + ext_net = neutron_utils.get_network(neutron, self.external_gateway, + project_id) if ext_net: ext_gw['network_id'] = ext_net['network']['id'] out['external_gateway_info'] = ext_gw else: - raise Exception('Could not find the external network named - ' + self.external_gateway) + raise Exception( + 'Could not find the external network named - ' + + self.external_gateway) # TODO: Enable SNAT option for Router # TODO: Add external_fixed_ips Tests diff --git a/snaps/openstack/create_security_group.py b/snaps/openstack/create_security_group.py index 4e98e82..49cc67b 100644 --- a/snaps/openstack/create_security_group.py +++ b/snaps/openstack/create_security_group.py @@ -16,8 +16,8 @@ import logging import enum from neutronclient.common.exceptions import NotFound -from snaps.openstack.utils import neutron_utils from snaps.openstack.utils import keystone_utils +from snaps.openstack.utils import neutron_utils __author__ = 'spisarski' @@ -49,22 +49,26 @@ class OpenStackSecurityGroup: def create(self, cleanup=False): """ Responsible for creating the security group. - :param cleanup: Denotes whether or not this is being called for cleanup or not + :param cleanup: Denotes whether or not this is being called for cleanup :return: the OpenStack security group object """ self.__neutron = neutron_utils.neutron_client(self.__os_creds) self.__keystone = keystone_utils.keystone_client(self.__os_creds) - logger.info('Creating security group %s...' % self.sec_grp_settings.name) + logger.info( + 'Creating security group %s...' % self.sec_grp_settings.name) - self.__security_group = neutron_utils.get_security_group(self.__neutron, self.sec_grp_settings.name) + self.__security_group = neutron_utils.get_security_group( + self.__neutron, self.sec_grp_settings.name) if not self.__security_group and not cleanup: # Create the security group - self.__security_group = neutron_utils.create_security_group(self.__neutron, self.__keystone, - self.sec_grp_settings) + self.__security_group = neutron_utils.create_security_group( + self.__neutron, self.__keystone, + self.sec_grp_settings) # Get the rules added for free - auto_rules = neutron_utils.get_rules_by_security_group(self.__neutron, self.__security_group) + auto_rules = neutron_utils.get_rules_by_security_group( + self.__neutron, self.__security_group) ctr = 0 for auto_rule in auto_rules: @@ -74,14 +78,17 @@ class OpenStackSecurityGroup: # Create the custom rules for sec_grp_rule_setting in self.sec_grp_settings.rule_settings: - custom_rule = neutron_utils.create_security_group_rule(self.__neutron, sec_grp_rule_setting) + custom_rule = neutron_utils.create_security_group_rule( + self.__neutron, sec_grp_rule_setting) self.__rules[sec_grp_rule_setting] = custom_rule - # Refresh security group object to reflect the new rules added to it - self.__security_group = neutron_utils.get_security_group(self.__neutron, self.sec_grp_settings.name) + # Refresh security group object to reflect the new rules added + self.__security_group = neutron_utils.get_security_group( + self.__neutron, self.sec_grp_settings.name) else: # Populate rules - existing_rules = neutron_utils.get_rules_by_security_group(self.__neutron, self.__security_group) + existing_rules = neutron_utils.get_rules_by_security_group( + self.__neutron, self.__security_group) for existing_rule in existing_rules: # For Custom Rules @@ -99,22 +106,27 @@ class OpenStackSecurityGroup: def __generate_rule_setting(self, rule): """ Creates a SecurityGroupRuleSettings object for a given rule - :param rule: the rule from which to create the SecurityGroupRuleSettings object + :param rule: the rule from which to create the + SecurityGroupRuleSettings object :return: the newly instantiated SecurityGroupRuleSettings object """ rule_dict = rule['security_group_rule'] sec_grp_name = None if rule_dict['security_group_id']: - sec_grp = neutron_utils.get_security_group_by_id(self.__neutron, rule_dict['security_group_id']) + sec_grp = neutron_utils.get_security_group_by_id( + self.__neutron, rule_dict['security_group_id']) if sec_grp: sec_grp_name = sec_grp['security_group']['name'] - setting = SecurityGroupRuleSettings(description=rule_dict['description'], - direction=rule_dict['direction'], ethertype=rule_dict['ethertype'], - port_range_min=rule_dict['port_range_min'], - port_range_max=rule_dict['port_range_max'], protocol=rule_dict['protocol'], - remote_group_id=rule_dict['remote_group_id'], - remote_ip_prefix=rule_dict['remote_ip_prefix'], sec_grp_name=sec_grp_name) + setting = SecurityGroupRuleSettings( + description=rule_dict['description'], + direction=rule_dict['direction'], ethertype=rule_dict['ethertype'], + port_range_min=rule_dict['port_range_min'], + port_range_max=rule_dict['port_range_max'], + protocol=rule_dict['protocol'], + remote_group_id=rule_dict['remote_group_id'], + remote_ip_prefix=rule_dict['remote_ip_prefix'], + sec_grp_name=sec_grp_name) return setting def clean(self): @@ -131,9 +143,11 @@ class OpenStackSecurityGroup: if self.__security_group: try: - neutron_utils.delete_security_group(self.__neutron, self.__security_group) + neutron_utils.delete_security_group(self.__neutron, + self.__security_group) except NotFound as e: - logger.warning('Security Group not found, cannot delete - ' + str(e)) + logger.warning( + 'Security Group not found, cannot delete - ' + str(e)) self.__security_group = None @@ -157,25 +171,29 @@ class OpenStackSecurityGroup: :param rule_setting: the rule configuration """ rule_setting.sec_grp_name = self.sec_grp_settings.name - new_rule = neutron_utils.create_security_group_rule(self.__neutron, rule_setting) + new_rule = neutron_utils.create_security_group_rule(self.__neutron, + rule_setting) self.__rules[rule_setting] = new_rule self.sec_grp_settings.rule_settings.append(rule_setting) def remove_rule(self, rule_id=None, rule_setting=None): """ - Removes a rule to this security group by id, name, or rule_setting object + Removes a rule to this security group by id, name, or rule_setting + object :param rule_id: the rule's id :param rule_setting: the rule's setting object """ rule_to_remove = None if rule_id or rule_setting: if rule_id: - rule_to_remove = neutron_utils.get_rule_by_id(self.__neutron, self.__security_group, rule_id) + rule_to_remove = neutron_utils.get_rule_by_id( + self.__neutron, self.__security_group, rule_id) elif rule_setting: rule_to_remove = self.__rules.get(rule_setting) if rule_to_remove: - neutron_utils.delete_security_group_rule(self.__neutron, rule_to_remove) + neutron_utils.delete_security_group_rule(self.__neutron, + rule_to_remove) rule_setting = self.__get_setting_from_rule(rule_to_remove) if rule_setting: self.__rules.pop(rule_setting) @@ -199,42 +217,46 @@ class SecurityGroupSettings: Class representing a keypair configuration """ - def __init__(self, config=None, name=None, description=None, project_name=None, - rule_settings=list()): + def __init__(self, **kwargs): """ Constructor - all parameters are optional - :param config: Should be a dict object containing the configuration settings using the attribute names below - as each member's the key and overrides any of the other parameters. :param name: The keypair name. :param description: The security group's description - :param project_name: The name of the project under which the security group will be created + :param project_name: The name of the project under which the security + group will be created :return: """ - if config: - self.name = config.get('name') - self.description = config.get('description') - self.project_name = config.get('project_name') - self.rule_settings = list() - if config.get('rules') and type(config['rules']) is list: - for config_rule in config['rules']: - self.rule_settings.append(SecurityGroupRuleSettings(config=config_rule)) - else: - self.name = name - self.description = description - self.project_name = project_name - self.rule_settings = rule_settings + self.name = kwargs.get('name') + self.description = kwargs.get('description') + self.project_name = kwargs.get('project_name') + self.rule_settings = list() + + rule_settings = kwargs.get('rules') + if not rule_settings: + rule_settings = kwargs.get('rule_settings') + + if rule_settings: + for rule_setting in rule_settings: + if isinstance(rule_setting, SecurityGroupRuleSettings): + self.rule_settings.append(rule_setting) + else: + self.rule_settings.append(SecurityGroupRuleSettings( + **rule_setting)) if not self.name: raise Exception('The attribute name is required') for rule_setting in self.rule_settings: if rule_setting.sec_grp_name is not self.name: - raise Exception('Rule settings must correspond with the name of this security group') + raise Exception( + 'Rule settings must correspond with the name of this ' + 'security group') def dict_for_neutron(self, keystone): """ Returns a dictionary object representing this object. - This is meant to be converted into JSON designed for use by the Neutron API + This is meant to be converted into JSON designed for use by the Neutron + API TODO - expand automated testing to exercise all parameters :param keystone: the Keystone client @@ -254,7 +276,9 @@ class SecurityGroupSettings: if project_id: out['project_id'] = project_id else: - raise Exception('Could not find project ID for project named - ' + self.project_name) + raise Exception( + 'Could not find project ID for project named - ' + + self.project_name) return {'security_group': out} @@ -290,67 +314,62 @@ class SecurityGroupRuleSettings: Class representing a keypair configuration """ - def __init__(self, config=None, sec_grp_name=None, description=None, direction=None, - remote_group_id=None, protocol=None, ethertype=None, port_range_min=None, port_range_max=None, - sec_grp_rule=None, remote_ip_prefix=None): + def __init__(self, **kwargs): """ Constructor - all parameters are optional - :param config: Should be a dict object containing the configuration settings using the attribute names below - as each member's the key and overrides any of the other parameters. - :param sec_grp_name: The security group's name on which to add the rule. (required) + :param sec_grp_name: The security group's name on which to add the + rule. (required) :param description: The rule's description - :param direction: An enumeration of type create_security_group.RULE_DIRECTION (required) - :param remote_group_id: The group ID to associate with this rule (this should be changed to group name - once snaps support Groups) (optional) - :param protocol: An enumeration of type create_security_group.RULE_PROTOCOL or a string value that will be - mapped accordingly (optional) - :param ethertype: An enumeration of type create_security_group.RULE_ETHERTYPE (optional) - :param port_range_min: The minimum port number in the range that is matched by the security group rule. When - the protocol is TCP or UDP, this value must be <= port_range_max. When the protocol is - ICMP, this value must be an ICMP type. - :param port_range_max: The maximum port number in the range that is matched by the security group rule. When - the protocol is TCP or UDP, this value must be <= port_range_max. When the protocol is - ICMP, this value must be an ICMP type. - :param sec_grp_rule: The OpenStack rule object to a security group rule object to associate - (note: Cannot be set using the config object nor can I see any real uses for this - parameter) - :param remote_ip_prefix: The remote IP prefix to associate with this metering rule packet (optional) + :param direction: An enumeration of type + create_security_group.RULE_DIRECTION (required) + :param remote_group_id: The group ID to associate with this rule + (this should be changed to group name once + snaps support Groups) (optional) + :param protocol: An enumeration of type + create_security_group.RULE_PROTOCOL or a string value + that will be mapped accordingly (optional) + :param ethertype: An enumeration of type + create_security_group.RULE_ETHERTYPE (optional) + :param port_range_min: The minimum port number in the range that is + matched by the security group rule. When the + protocol is TCP or UDP, this value must be <= + port_range_max. When the protocol is ICMP, this + value must be an ICMP type. + :param port_range_max: The maximum port number in the range that is + matched by the security group rule. When the + protocol is TCP or UDP, this value must be <= + port_range_max. When the protocol is ICMP, this + value must be an ICMP type. + :param sec_grp_rule: The OpenStack rule object to a security group rule + object to associate + (note: Cannot be set using the config object nor + can I see any real uses for this parameter) + :param remote_ip_prefix: The remote IP prefix to associate with this + metering rule packet (optional) TODO - Need to support the tenant... """ - if config: - self.description = config.get('description') - self.sec_grp_name = config.get('sec_grp_name') - self.remote_group_id = config.get('remote_group_id') - self.direction = None - if config.get('direction'): - self.direction = map_direction(config['direction']) - - self.protocol = None - if config.get('protocol'): - self.protocol = map_protocol(config['protocol']) - else: - self.protocol = Protocol.null + self.description = kwargs.get('description') + self.sec_grp_name = kwargs.get('sec_grp_name') + self.remote_group_id = kwargs.get('remote_group_id') + self.direction = None + if kwargs.get('direction'): + self.direction = map_direction(kwargs['direction']) - self.ethertype = None - if config.get('ethertype'): - self.ethertype = map_ethertype(config['ethertype']) - - self.port_range_min = config.get('port_range_min') - self.port_range_max = config.get('port_range_max') - self.remote_ip_prefix = config.get('remote_ip_prefix') + self.protocol = None + if kwargs.get('protocol'): + self.protocol = map_protocol(kwargs['protocol']) else: - self.description = description - self.sec_grp_name = sec_grp_name - self.remote_group_id = remote_group_id - self.direction = map_direction(direction) - self.protocol = map_protocol(protocol) - self.ethertype = map_ethertype(ethertype) - self.port_range_min = port_range_min - self.port_range_max = port_range_max - self.sec_grp_rule = sec_grp_rule - self.remote_ip_prefix = remote_ip_prefix + self.protocol = Protocol.null + + self.ethertype = None + if kwargs.get('ethertype'): + self.ethertype = map_ethertype(kwargs['ethertype']) + + self.port_range_min = kwargs.get('port_range_min') + self.port_range_max = kwargs.get('port_range_max') + self.remote_ip_prefix = kwargs.get('remote_ip_prefix') if not self.direction or not self.sec_grp_name: raise Exception('direction and sec_grp_name are required') @@ -358,7 +377,8 @@ class SecurityGroupRuleSettings: def dict_for_neutron(self, neutron): """ Returns a dictionary object representing this object. - This is meant to be converted into JSON designed for use by the Neutron API + This is meant to be converted into JSON designed for use by the Neutron + API :param neutron: the neutron client for performing lookups :return: the dictionary object @@ -375,18 +395,19 @@ class SecurityGroupRuleSettings: out['port_range_max'] = self.port_range_max if self.ethertype: out['ethertype'] = self.ethertype.name - if self.protocol: + if self.protocol and self.protocol.name != 'null': out['protocol'] = self.protocol.name if self.sec_grp_name: - sec_grp = neutron_utils.get_security_group(neutron, self.sec_grp_name) + sec_grp = neutron_utils.get_security_group( + neutron, self.sec_grp_name) if sec_grp: out['security_group_id'] = sec_grp['security_group']['id'] else: - raise Exception('Cannot locate security group with name - ' + self.sec_grp_name) + raise Exception( + 'Cannot locate security group with name - ' + + self.sec_grp_name) if self.remote_group_id: out['remote_group_id'] = self.remote_group_id - if self.sec_grp_rule: - out['security_group_rule'] = self.sec_grp_rule if self.remote_ip_prefix: out['remote_ip_prefix'] = self.remote_ip_prefix @@ -401,7 +422,8 @@ class SecurityGroupRuleSettings: rule_dict = rule['security_group_rule'] if self.description is not None: - if rule_dict['description'] is not None and rule_dict['description'] != '': + if rule_dict['description'] is not None and rule_dict[ + 'description'] != '': return False elif self.description != rule_dict['description']: if rule_dict['description'] != '': @@ -445,18 +467,19 @@ class SecurityGroupRuleSettings: self.protocol == other.protocol and \ self.sec_grp_name == other.sec_grp_name and \ self.remote_group_id == other.remote_group_id and \ - self.sec_grp_rule == other.sec_grp_rule and \ self.remote_ip_prefix == other.remote_ip_prefix def __hash__(self): - return hash((self.sec_grp_name, self.description, self.direction, self.remote_group_id, - self.protocol, self.ethertype, self.port_range_min, self.port_range_max, self.sec_grp_rule, - self.remote_ip_prefix)) + return hash((self.sec_grp_name, self.description, self.direction, + self.remote_group_id, + self.protocol, self.ethertype, self.port_range_min, + self.port_range_max, self.remote_ip_prefix)) def map_direction(direction): """ - Takes a the direction value maps it to the Direction enum. When None return None + Takes a the direction value maps it to the Direction enum. When None return + None :param direction: the direction value :return: the Direction enum object :raise: Exception if value is invalid @@ -477,7 +500,8 @@ def map_direction(direction): def map_protocol(protocol): """ - Takes a the protocol value maps it to the Protocol enum. When None return None + Takes a the protocol value maps it to the Protocol enum. When None return + None :param protocol: the protocol value :return: the Protocol enum object :raise: Exception if value is invalid @@ -502,7 +526,8 @@ def map_protocol(protocol): def map_ethertype(ethertype): """ - Takes a the ethertype value maps it to the Ethertype enum. When None return None + Takes a the ethertype value maps it to the Ethertype enum. When None return + None :param ethertype: the ethertype value :return: the Ethertype enum object :raise: Exception if value is invalid diff --git a/snaps/openstack/create_stack.py b/snaps/openstack/create_stack.py index 8dc5027..1492829 100644 --- a/snaps/openstack/create_stack.py +++ b/snaps/openstack/create_stack.py @@ -17,7 +17,6 @@ import logging import time from heatclient.exc import HTTPNotFound - from snaps.openstack.utils import heat_utils __author__ = 'spisarski' @@ -49,23 +48,31 @@ class OpenStackHeatStack: def create(self, cleanup=False): """ - Creates the heat stack in OpenStack if it does not already exist and returns the domain Stack object - :param cleanup: Denotes whether or not this is being called for cleanup or not + Creates the heat stack in OpenStack if it does not already exist and + returns the domain Stack object + :param cleanup: Denotes whether or not this is being called for cleanup :return: The OpenStack Stack object """ self.__heat_cli = heat_utils.heat_client(self.__os_creds) - self.__stack = heat_utils.get_stack_by_name(self.__heat_cli, self.stack_settings.name) + self.__stack = heat_utils.get_stack_by_name(self.__heat_cli, + self.stack_settings.name) if self.__stack: logger.info('Found stack with name - ' + self.stack_settings.name) return self.__stack elif not cleanup: - self.__stack = heat_utils.create_stack(self.__heat_cli, self.stack_settings) - logger.info('Created stack with name - ' + self.stack_settings.name) + self.__stack = heat_utils.create_stack(self.__heat_cli, + self.stack_settings) + logger.info( + 'Created stack with name - ' + self.stack_settings.name) if self.__stack and self.stack_complete(block=True): - logger.info('Stack is now active with name - ' + self.stack_settings.name) + logger.info( + 'Stack is now active with name - ' + + self.stack_settings.name) return self.__stack else: - raise StackCreationError('Stack was not created or activated in the alloted amount of time') + raise StackCreationError( + 'Stack was not created or activated in the alloted amount ' + 'of time') else: logger.info('Did not create stack due to cleanup mode') @@ -86,42 +93,53 @@ class OpenStackHeatStack: def get_stack(self): """ - Returns the domain Stack object as it was populated when create() was called + Returns the domain Stack object as it was populated when create() was + called :return: the object """ return self.__stack def get_outputs(self): """ - Returns the list of outputs as contained on the OpenStack Heat Stack object + Returns the list of outputs as contained on the OpenStack Heat Stack + object :return: """ return heat_utils.get_stack_outputs(self.__heat_cli, self.__stack.id) def get_status(self): """ - Returns the list of outputs as contained on the OpenStack Heat Stack object + Returns the list of outputs as contained on the OpenStack Heat Stack + object :return: """ return heat_utils.get_stack_status(self.__heat_cli, self.__stack.id) - def stack_complete(self, block=False, timeout=None, poll_interval=POLL_INTERVAL): + def stack_complete(self, block=False, timeout=None, + poll_interval=POLL_INTERVAL): """ - Returns true when the stack status returns the value of expected_status_code - :param block: When true, thread will block until active or timeout value in seconds has been exceeded (False) + Returns true when the stack status returns the value of + expected_status_code + :param block: When true, thread will block until active or timeout + value in seconds has been exceeded (False) :param timeout: The timeout value :param poll_interval: The polling interval in seconds :return: T/F """ if not timeout: timeout = self.stack_settings.stack_create_timeout - return self._stack_status_check(STATUS_CREATE_COMPLETE, block, timeout, poll_interval) - - def _stack_status_check(self, expected_status_code, block, timeout, poll_interval): - """ - Returns true when the stack status returns the value of expected_status_code - :param expected_status_code: stack status evaluated with this string value - :param block: When true, thread will block until active or timeout value in seconds has been exceeded (False) + return self._stack_status_check(STATUS_CREATE_COMPLETE, block, timeout, + poll_interval) + + def _stack_status_check(self, expected_status_code, block, timeout, + poll_interval): + """ + Returns true when the stack status returns the value of + expected_status_code + :param expected_status_code: stack status evaluated with this string + value + :param block: When true, thread will block until active or timeout + value in seconds has been exceeded (False) :param timeout: The timeout value :param poll_interval: The polling interval in seconds :return: T/F @@ -135,25 +153,31 @@ class OpenStackHeatStack: while timeout > time.time() - start: status = self._status(expected_status_code) if status: - logger.debug('Stack is active with name - ' + self.stack_settings.name) + logger.debug( + 'Stack is active with name - ' + self.stack_settings.name) return True - logger.debug('Retry querying stack status in ' + str(poll_interval) + ' seconds') + logger.debug('Retry querying stack status in ' + str( + poll_interval) + ' seconds') time.sleep(poll_interval) - logger.debug('Stack status query timeout in ' + str(timeout - (time.time() - start))) + logger.debug('Stack status query timeout in ' + str( + timeout - (time.time() - start))) - logger.error('Timeout checking for stack status for ' + expected_status_code) + logger.error( + 'Timeout checking for stack status for ' + expected_status_code) return False def _status(self, expected_status_code): """ Returns True when active else False - :param expected_status_code: stack status evaluated with this string value + :param expected_status_code: stack status evaluated with this string + value :return: T/F """ status = self.get_status() if not status: - logger.warning('Cannot stack status for stack with ID - ' + self.__stack.id) + logger.warning( + 'Cannot stack status for stack with ID - ' + self.__stack.id) return False if status == 'ERROR': @@ -163,33 +187,26 @@ class OpenStackHeatStack: class StackSettings: - def __init__(self, config=None, name=None, template=None, template_path=None, env_values=None, - stack_create_timeout=STACK_COMPLETE_TIMEOUT): + def __init__(self, **kwargs): """ Constructor - :param config: dict() object containing the configuration settings using the attribute names below as each - member's the key and overrides any of the other parameters. :param name: the stack's name (required) - :param template: the heat template in dict() format (required if template_path attribute is None) - :param template_path: the location of the heat template file (required if template attribute is None) - :param env_values: k/v pairs of strings for substitution of template default values (optional) - """ - - if config: - self.name = config.get('name') - self.template = config.get('template') - self.template_path = config.get('template_path') - self.env_values = config.get('env_values') - if 'stack_create_timeout' in config: - self.stack_create_timeout = config['stack_create_timeout'] - else: - self.stack_create_timeout = stack_create_timeout + :param template: the heat template in dict() format (required if + template_path attribute is None) + :param template_path: the location of the heat template file (required + if template attribute is None) + :param env_values: k/v pairs of strings for substitution of template + default values (optional) + """ + + self.name = kwargs.get('name') + self.template = kwargs.get('template') + self.template_path = kwargs.get('template_path') + self.env_values = kwargs.get('env_values') + if 'stack_create_timeout' in kwargs: + self.stack_create_timeout = kwargs['stack_create_timeout'] else: - self.name = name - self.template = template - self.template_path = template_path - self.env_values = env_values - self.stack_create_timeout = stack_create_timeout + self.stack_create_timeout = STACK_COMPLETE_TIMEOUT if not self.name: raise StackSettingsError('name is required') @@ -202,6 +219,7 @@ class StackSettingsError(Exception): """ Exception to be thrown when an stack settings are incorrect """ + def __init__(self, message): Exception.__init__(self, message) @@ -210,5 +228,6 @@ class StackCreationError(Exception): """ Exception to be thrown when an stack cannot be created """ + def __init__(self, message): Exception.__init__(self, message) diff --git a/snaps/openstack/tests/create_flavor_tests.py b/snaps/openstack/tests/create_flavor_tests.py index be7ac64..5d7e4c4 100644 --- a/snaps/openstack/tests/create_flavor_tests.py +++ b/snaps/openstack/tests/create_flavor_tests.py @@ -12,8 +12,8 @@ # 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. -import uuid import unittest +import uuid from snaps.openstack.create_flavor import FlavorSettings, OpenStackFlavor from snaps.openstack.tests.os_source_file_test import OSComponentTestCase @@ -61,107 +61,140 @@ class FlavorSettingsUnitTests(unittest.TestCase): def test_ram_string(self): with self.assertRaises(Exception): - FlavorSettings(name='foo', ram='bar', disk=2, vcpus=3, ephemeral=4, swap=5, rxtx_factor=6.0, + FlavorSettings(name='foo', ram='bar', disk=2, vcpus=3, ephemeral=4, + swap=5, rxtx_factor=6.0, is_public=False) def test_config_ram_string(self): with self.assertRaises(Exception): - FlavorSettings(config={'name': 'foo', 'ram': 'bar', 'disk': 2, 'vcpus': 3, 'ephemeral': 4, 'swap': 5, - 'rxtx_factor': 6.0, 'is_public': False}) + FlavorSettings( + config={'name': 'foo', 'ram': 'bar', 'disk': 2, 'vcpus': 3, + 'ephemeral': 4, 'swap': 5, + 'rxtx_factor': 6.0, 'is_public': False}) def test_ram_float(self): with self.assertRaises(Exception): - FlavorSettings(name='foo', ram=1.5, disk=2, vcpus=3, ephemeral=4, swap=5, rxtx_factor=6.0, is_public=False) + FlavorSettings(name='foo', ram=1.5, disk=2, vcpus=3, ephemeral=4, + swap=5, rxtx_factor=6.0, is_public=False) def test_config_ram_float(self): with self.assertRaises(Exception): - FlavorSettings(config={'name': 'foo', 'ram': 1.5, 'disk': 2, 'vcpus': 3, 'ephemeral': 4, 'swap': 5, - 'rxtx_factor': 6.0, 'is_public': False}) + FlavorSettings( + config={'name': 'foo', 'ram': 1.5, 'disk': 2, 'vcpus': 3, + 'ephemeral': 4, 'swap': 5, + 'rxtx_factor': 6.0, 'is_public': False}) def test_disk_string(self): with self.assertRaises(Exception): - FlavorSettings(name='foo', ram=1, disk='bar', vcpus=3, ephemeral=4, swap=5, rxtx_factor=6.0, + FlavorSettings(name='foo', ram=1, disk='bar', vcpus=3, ephemeral=4, + swap=5, rxtx_factor=6.0, is_public=False) def test_config_disk_string(self): with self.assertRaises(Exception): - FlavorSettings(config={'name': 'foo', 'ram': 1, 'disk': 'bar', 'vcpus': 3, 'ephemeral': 4, 'swap': 5, - 'rxtx_factor': 6.0, 'is_public': False}) + FlavorSettings( + config={'name': 'foo', 'ram': 1, 'disk': 'bar', 'vcpus': 3, + 'ephemeral': 4, 'swap': 5, + 'rxtx_factor': 6.0, 'is_public': False}) def test_disk_float(self): with self.assertRaises(Exception): - FlavorSettings(name='foo', ram=1, disk=2.5, vcpus=3, ephemeral=4, swap=5, rxtx_factor=6.0, is_public=False) + FlavorSettings(name='foo', ram=1, disk=2.5, vcpus=3, ephemeral=4, + swap=5, rxtx_factor=6.0, is_public=False) def test_config_disk_float(self): with self.assertRaises(Exception): - FlavorSettings(config={'name': 'foo', 'ram': 1, 'disk': 2.5, 'vcpus': 3, 'ephemeral': 4, 'swap': 5, - 'rxtx_factor': 6.0, 'is_public': False}) + FlavorSettings( + config={'name': 'foo', 'ram': 1, 'disk': 2.5, 'vcpus': 3, + 'ephemeral': 4, 'swap': 5, + 'rxtx_factor': 6.0, 'is_public': False}) def test_vcpus_string(self): with self.assertRaises(Exception): - FlavorSettings(name='foo', ram=1, disk=2, vcpus='bar', ephemeral=4, swap=5, rxtx_factor=6.0, + FlavorSettings(name='foo', ram=1, disk=2, vcpus='bar', ephemeral=4, + swap=5, rxtx_factor=6.0, is_public=False) def test_config_vcpus_string(self): with self.assertRaises(Exception): - FlavorSettings(config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 'bar', 'ephemeral': 4, 'swap': 5, - 'rxtx_factor': 6.0, 'is_public': False}) + FlavorSettings( + config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 'bar', + 'ephemeral': 4, 'swap': 5, + 'rxtx_factor': 6.0, 'is_public': False}) def test_ephemeral_string(self): with self.assertRaises(Exception): - FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral='bar', swap=5, rxtx_factor=6.0, + FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral='bar', + swap=5, rxtx_factor=6.0, is_public=False) def test_config_ephemeral_string(self): with self.assertRaises(Exception): - FlavorSettings(config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, 'ephemeral': 'bar', 'swap': 5, - 'rxtx_factor': 6.0, 'is_public': False}) + FlavorSettings( + config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, + 'ephemeral': 'bar', 'swap': 5, + 'rxtx_factor': 6.0, 'is_public': False}) def test_ephemeral_float(self): with self.assertRaises(Exception): - FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4.5, swap=5, rxtx_factor=6.0, is_public=False) + FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4.5, + swap=5, rxtx_factor=6.0, is_public=False) def test_config_ephemeral_float(self): with self.assertRaises(Exception): - FlavorSettings(config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, 'ephemeral': 4.5, 'swap': 5, - 'rxtx_factor': 6.0, 'is_public': False}) + FlavorSettings( + config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, + 'ephemeral': 4.5, 'swap': 5, + 'rxtx_factor': 6.0, 'is_public': False}) def test_swap_string(self): with self.assertRaises(Exception): - FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4, swap='bar', rxtx_factor=6.0, + FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4, + swap='bar', rxtx_factor=6.0, is_public=False) def test_config_swap_string(self): with self.assertRaises(Exception): - FlavorSettings(config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, 'ephemeral': 4, 'swap': 'bar', - 'rxtx_factor': 6.0, 'is_public': False}) + FlavorSettings( + config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, + 'ephemeral': 4, 'swap': 'bar', + 'rxtx_factor': 6.0, 'is_public': False}) def test_swap_float(self): with self.assertRaises(Exception): - FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4, swap=5.5, rxtx_factor=6.0, is_public=False) + FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4, + swap=5.5, rxtx_factor=6.0, is_public=False) def test_config_swap_float(self): with self.assertRaises(Exception): - FlavorSettings(config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, 'ephemeral': 4, 'swap': 5.5, - 'rxtx_factor': 6.0, 'is_public': False}) + FlavorSettings( + config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, + 'ephemeral': 4, 'swap': 5.5, + 'rxtx_factor': 6.0, 'is_public': False}) def test_rxtx_string(self): with self.assertRaises(Exception): - FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4, swap=5, rxtx_factor='bar', is_public=False) + FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4, + swap=5, rxtx_factor='bar', is_public=False) def test_config_rxtx_string(self): with self.assertRaises(Exception): - FlavorSettings(config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, 'ephemeral': 4, 'swap': 5, - 'rxtx_factor': 'bar', 'is_public': False}) + FlavorSettings( + config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, + 'ephemeral': 4, 'swap': 5, + 'rxtx_factor': 'bar', 'is_public': False}) def test_is_pub_string(self): with self.assertRaises(Exception): - FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4, swap=5, rxtx_factor=6.0, is_public='bar') + FlavorSettings(name='foo', ram=1, disk=2, vcpus=3, ephemeral=4, + swap=5, rxtx_factor=6.0, is_public='bar') def test_config_is_pub_string(self): with self.assertRaises(Exception): - FlavorSettings(config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, 'ephemeral': 4, 'swap': 5, - 'rxtx_factor': 6.0, 'is_public': 'bar'}) + FlavorSettings( + config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3, + 'ephemeral': 4, 'swap': 5, + 'rxtx_factor': 6.0, 'is_public': 'bar'}) def test_name_ram_disk_vcpus_only(self): settings = FlavorSettings(name='foo', ram=1, disk=2, vcpus=3) @@ -177,7 +210,8 @@ class FlavorSettingsUnitTests(unittest.TestCase): self.assertEqual(None, settings.metadata) def test_config_with_name_ram_disk_vcpus_only(self): - settings = FlavorSettings(config={'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3}) + settings = FlavorSettings( + **{'name': 'foo', 'ram': 1, 'disk': 2, 'vcpus': 3}) self.assertEqual('foo', settings.name) self.assertEqual('auto', settings.flavor_id) self.assertEqual(1, settings.ram) @@ -191,8 +225,9 @@ class FlavorSettingsUnitTests(unittest.TestCase): def test_all(self): metadata = {'foo': 'bar'} - settings = FlavorSettings(name='foo', flavor_id='bar', ram=1, disk=2, vcpus=3, ephemeral=4, swap=5, - rxtx_factor=6.0, is_public=False, metadata=metadata) + settings = FlavorSettings( + name='foo', flavor_id='bar', ram=1, disk=2, vcpus=3, ephemeral=4, + swap=5, rxtx_factor=6.0, is_public=False, metadata=metadata) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.flavor_id) self.assertEqual(1, settings.ram) @@ -206,9 +241,12 @@ class FlavorSettingsUnitTests(unittest.TestCase): def test_config_all(self): metadata = {'foo': 'bar'} - settings = FlavorSettings(config={'name': 'foo', 'flavor_id': 'bar', 'ram': 1, 'disk': 2, 'vcpus': 3, - 'ephemeral': 4, 'swap': 5, 'rxtx_factor': 6.0, 'is_public': False, - 'metadata': metadata}) + settings = FlavorSettings( + **{'name': 'foo', 'flavor_id': 'bar', 'ram': 1, 'disk': 2, + 'vcpus': 3, + 'ephemeral': 4, 'swap': 5, 'rxtx_factor': 6.0, + 'is_public': False, + 'metadata': metadata}) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.flavor_id) self.assertEqual(1, settings.ram) @@ -228,8 +266,8 @@ class CreateFlavorTests(OSComponentTestCase): def setUp(self): """ - Instantiates the CreateSecurityGroup object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateSecurityGroup object that is responsible for + downloading and creating an OS image file within OpenStack """ guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) self.flavor_name = guid + 'name' @@ -251,17 +289,20 @@ class CreateFlavorTests(OSComponentTestCase): Tests the creation of an OpenStack flavor. """ # Create Flavor - flavor_settings = FlavorSettings(name=self.flavor_name, ram=1, disk=1, vcpus=1) + flavor_settings = FlavorSettings(name=self.flavor_name, ram=1, disk=1, + vcpus=1) self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings) flavor = self.flavor_creator.create() self.assertTrue(validate_flavor(flavor_settings, flavor)) def test_create_flavor_existing(self): """ - Tests the creation of an OpenStack flavor then starts another creator to ensure it has not been done twice. + Tests the creation of an OpenStack flavor then starts another creator + to ensure it has not been done twice. """ # Create Flavor - flavor_settings = FlavorSettings(name=self.flavor_name, ram=1, disk=1, vcpus=1) + flavor_settings = FlavorSettings(name=self.flavor_name, ram=1, disk=1, + vcpus=1) self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings) flavor = self.flavor_creator.create() self.assertTrue(validate_flavor(flavor_settings, flavor)) @@ -276,7 +317,8 @@ class CreateFlavorTests(OSComponentTestCase): Tests the creation and cleanup of an OpenStack flavor. """ # Create Flavor - flavor_settings = FlavorSettings(name=self.flavor_name, ram=1, disk=1, vcpus=1) + flavor_settings = FlavorSettings(name=self.flavor_name, ram=1, disk=1, + vcpus=1) self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings) flavor = self.flavor_creator.create() self.assertTrue(validate_flavor(flavor_settings, flavor)) @@ -285,22 +327,26 @@ class CreateFlavorTests(OSComponentTestCase): self.flavor_creator.clean() self.assertIsNone(self.flavor_creator.get_flavor()) - self.assertIsNone(nova_utils.get_flavor_by_name(self.nova, flavor_settings.name)) + self.assertIsNone( + nova_utils.get_flavor_by_name(self.nova, flavor_settings.name)) def test_create_delete_flavor(self): """ - Tests the creation of an OpenStack Security Group, the deletion, then cleanup to ensure clean() does not + Tests the creation of an OpenStack Security Group, the deletion, then + cleanup to ensure clean() does not raise any exceptions. """ # Create Flavor - flavor_settings = FlavorSettings(name=self.flavor_name, ram=1, disk=1, vcpus=1) + flavor_settings = FlavorSettings(name=self.flavor_name, ram=1, disk=1, + vcpus=1) self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings) flavor = self.flavor_creator.create() self.assertTrue(validate_flavor(flavor_settings, flavor)) # Delete Flavor nova_utils.delete_flavor(self.nova, flavor) - self.assertIsNone(nova_utils.get_flavor_by_name(self.nova, flavor_settings.name)) + self.assertIsNone( + nova_utils.get_flavor_by_name(self.nova, flavor_settings.name)) # Attempt to cleanup self.flavor_creator.clean() @@ -317,7 +363,7 @@ def validate_flavor(flavor_settings, flavor): :param flavor: the OpenStack flavor object """ return flavor is not None \ - and flavor_settings.name == flavor.name \ - and flavor_settings.ram == flavor.ram \ - and flavor_settings.disk == flavor.disk \ - and flavor_settings.vcpus == flavor.vcpus + and flavor_settings.name == flavor.name \ + and flavor_settings.ram == flavor.ram \ + and flavor_settings.disk == flavor.disk \ + and flavor_settings.vcpus == flavor.vcpus diff --git a/snaps/openstack/tests/create_image_tests.py b/snaps/openstack/tests/create_image_tests.py index 7cb46e4..cadbe5c 100644 --- a/snaps/openstack/tests/create_image_tests.py +++ b/snaps/openstack/tests/create_image_tests.py @@ -19,18 +19,19 @@ except ImportError: from urllib2 import URLError import logging -import os import shutil -import uuid import unittest +import uuid -from snaps import file_utils -from snaps.openstack.create_image import ImageSettings, ImageCreationError, ImageSettingsError +import os -from snaps.openstack.tests import openstack_tests -from snaps.openstack.utils import glance_utils +from snaps import file_utils from snaps.openstack import create_image +from snaps.openstack.create_image import (ImageSettings, ImageCreationError, + ImageSettingsError) +from snaps.openstack.tests import openstack_tests from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase +from snaps.openstack.utils import glance_utils __author__ = 'spisarski' @@ -41,13 +42,14 @@ class ImageSettingsUnitTests(unittest.TestCase): """ Tests the construction of the ImageSettings class """ + def test_no_params(self): with self.assertRaises(ImageSettingsError): ImageSettings() def test_empty_config(self): with self.assertRaises(ImageSettingsError): - ImageSettings(config=dict()) + ImageSettings(**dict()) def test_name_only(self): with self.assertRaises(ImageSettingsError): @@ -55,7 +57,7 @@ class ImageSettingsUnitTests(unittest.TestCase): def test_config_with_name_only(self): with self.assertRaises(ImageSettingsError): - ImageSettings(config={'name': 'foo'}) + ImageSettings(**{'name': 'foo'}) def test_name_user_only(self): with self.assertRaises(ImageSettingsError): @@ -63,7 +65,7 @@ class ImageSettingsUnitTests(unittest.TestCase): def test_config_with_name_user_only(self): with self.assertRaises(ImageSettingsError): - ImageSettings(config={'name': 'foo', 'image_user': 'bar'}) + ImageSettings(**{'name': 'foo', 'image_user': 'bar'}) def test_name_user_format_only(self): with self.assertRaises(ImageSettingsError): @@ -71,20 +73,25 @@ class ImageSettingsUnitTests(unittest.TestCase): def test_config_with_name_user_format_only(self): with self.assertRaises(ImageSettingsError): - ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2'}) + ImageSettings( + **{'name': 'foo', 'image_user': 'bar', 'format': 'qcow2'}) def test_name_user_format_url_file_only(self): with self.assertRaises(ImageSettingsError): - ImageSettings(name='foo', image_user='bar', img_format='qcow2', url='http://foo.com', + ImageSettings(name='foo', image_user='bar', img_format='qcow2', + url='http://foo.com', image_file='/foo/bar.qcow') def test_config_with_name_user_format_url_file_only(self): with self.assertRaises(ImageSettingsError): - ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2', - 'download_url': 'http://foo.com', 'image_file': '/foo/bar.qcow'}) + ImageSettings( + **{'name': 'foo', 'image_user': 'bar', 'format': 'qcow2', + 'download_url': 'http://foo.com', + 'image_file': '/foo/bar.qcow'}) def test_name_user_format_url_only(self): - settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', url='http://foo.com') + settings = ImageSettings(name='foo', image_user='bar', + img_format='qcow2', url='http://foo.com') self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.image_user) self.assertEqual('qcow2', settings.format) @@ -96,7 +103,8 @@ class ImageSettingsUnitTests(unittest.TestCase): def test_name_user_format_url_only_properties(self): properties = {'hw_video_model': 'vga'} - settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', url='http://foo.com', + settings = ImageSettings(name='foo', image_user='bar', + img_format='qcow2', url='http://foo.com', extra_properties=properties) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.image_user) @@ -109,8 +117,9 @@ class ImageSettingsUnitTests(unittest.TestCase): self.assertIsNone(settings.nic_config_pb_loc) def test_config_with_name_user_format_url_only(self): - settings = ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2', - 'download_url': 'http://foo.com'}) + settings = ImageSettings( + **{'name': 'foo', 'image_user': 'bar', 'format': 'qcow2', + 'download_url': 'http://foo.com'}) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.image_user) self.assertEqual('qcow2', settings.format) @@ -121,7 +130,9 @@ class ImageSettingsUnitTests(unittest.TestCase): self.assertIsNone(settings.nic_config_pb_loc) def test_name_user_format_file_only(self): - settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', image_file='/foo/bar.qcow') + settings = ImageSettings(name='foo', image_user='bar', + img_format='qcow2', + image_file='/foo/bar.qcow') self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.image_user) self.assertEqual('qcow2', settings.format) @@ -132,8 +143,9 @@ class ImageSettingsUnitTests(unittest.TestCase): self.assertIsNone(settings.nic_config_pb_loc) def test_config_with_name_user_format_file_only(self): - settings = ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2', - 'image_file': '/foo/bar.qcow'}) + settings = ImageSettings( + **{'name': 'foo', 'image_user': 'bar', 'format': 'qcow2', + 'image_file': '/foo/bar.qcow'}) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.image_user) self.assertEqual('qcow2', settings.format) @@ -145,11 +157,17 @@ class ImageSettingsUnitTests(unittest.TestCase): def test_all_url(self): properties = {'hw_video_model': 'vga'} - kernel_settings = ImageSettings(name='kernel', url='http://kernel.com', image_user='bar', img_format='qcow2') - ramdisk_settings = ImageSettings(name='ramdisk', url='http://ramdisk.com', image_user='bar', img_format='qcow2') - settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', url='http://foo.com', - extra_properties=properties, nic_config_pb_loc='/foo/bar', - kernel_image_settings=kernel_settings, ramdisk_image_settings=ramdisk_settings, + kernel_settings = ImageSettings(name='kernel', url='http://kernel.com', + image_user='bar', img_format='qcow2') + ramdisk_settings = ImageSettings(name='ramdisk', + url='http://ramdisk.com', + image_user='bar', img_format='qcow2') + settings = ImageSettings(name='foo', image_user='bar', + img_format='qcow2', url='http://foo.com', + extra_properties=properties, + nic_config_pb_loc='/foo/bar', + kernel_image_settings=kernel_settings, + ramdisk_image_settings=ramdisk_settings, exists=True, public=True) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.image_user) @@ -159,11 +177,13 @@ class ImageSettingsUnitTests(unittest.TestCase): self.assertIsNone(settings.image_file) self.assertEqual('/foo/bar', settings.nic_config_pb_loc) self.assertEqual('kernel', settings.kernel_image_settings.name) - self.assertEqual('http://kernel.com', settings.kernel_image_settings.url) + self.assertEqual('http://kernel.com', + settings.kernel_image_settings.url) self.assertEqual('bar', settings.kernel_image_settings.image_user) self.assertEqual('qcow2', settings.kernel_image_settings.format) self.assertEqual('ramdisk', settings.ramdisk_image_settings.name) - self.assertEqual('http://ramdisk.com', settings.ramdisk_image_settings.url) + self.assertEqual('http://ramdisk.com', + settings.ramdisk_image_settings.url) self.assertEqual('bar', settings.ramdisk_image_settings.image_user) self.assertEqual('qcow2', settings.ramdisk_image_settings.format) self.assertTrue(settings.exists) @@ -171,33 +191,46 @@ class ImageSettingsUnitTests(unittest.TestCase): def test_config_all_url(self): settings = ImageSettings( - config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2', - 'download_url': 'http://foo.com', - 'extra_properties': '{\'hw_video_model\': \'vga\'}', - 'nic_config_pb_loc': '/foo/bar', - 'kernel_image_settings': {'name': 'kernel', 'download_url': 'http://kernel.com', - 'image_user': 'bar', 'format': 'qcow2'}, - 'ramdisk_image_settings': {'name': 'ramdisk', 'download_url': 'http://ramdisk.com', - 'image_user': 'bar', 'format': 'qcow2'}, - 'exists': True, 'public': True}) + **{'name': 'foo', 'image_user': 'bar', 'format': 'qcow2', + 'download_url': 'http://foo.com', + 'extra_properties': '{\'hw_video_model\': \'vga\'}', + 'nic_config_pb_loc': '/foo/bar', + 'kernel_image_settings': { + 'name': 'kernel', + 'download_url': 'http://kernel.com', + 'image_user': 'bar', + 'format': 'qcow2'}, + 'ramdisk_image_settings': { + 'name': 'ramdisk', + 'download_url': 'http://ramdisk.com', + 'image_user': 'bar', + 'format': 'qcow2'}, + 'exists': True, 'public': True}) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.image_user) self.assertEqual('qcow2', settings.format) self.assertEqual('http://foo.com', settings.url) - self.assertEqual('{\'hw_video_model\': \'vga\'}', settings.extra_properties) + self.assertEqual('{\'hw_video_model\': \'vga\'}', + settings.extra_properties) self.assertIsNone(settings.image_file) self.assertEqual('/foo/bar', settings.nic_config_pb_loc) self.assertEqual('kernel', settings.kernel_image_settings.name) - self.assertEqual('http://kernel.com', settings.kernel_image_settings.url) + self.assertEqual('http://kernel.com', + settings.kernel_image_settings.url) self.assertEqual('ramdisk', settings.ramdisk_image_settings.name) - self.assertEqual('http://ramdisk.com', settings.ramdisk_image_settings.url) + self.assertEqual('http://ramdisk.com', + settings.ramdisk_image_settings.url) self.assertTrue(settings.exists) self.assertTrue(settings.public) def test_all_file(self): properties = {'hw_video_model': 'vga'} - settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', image_file='/foo/bar.qcow', - extra_properties=properties, nic_config_pb_loc='/foo/bar', exists=True, public=True) + settings = ImageSettings(name='foo', image_user='bar', + img_format='qcow2', + image_file='/foo/bar.qcow', + extra_properties=properties, + nic_config_pb_loc='/foo/bar', exists=True, + public=True) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.image_user) self.assertEqual('qcow2', settings.format) @@ -209,16 +242,19 @@ class ImageSettingsUnitTests(unittest.TestCase): self.assertTrue(settings.public) def test_config_all_file(self): - settings = ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2', - 'image_file': '/foo/bar.qcow', - 'extra_properties': '{\'hw_video_model\' : \'vga\'}', - 'nic_config_pb_loc': '/foo/bar', 'exists': True, 'public': True}) + settings = ImageSettings( + **{'name': 'foo', 'image_user': 'bar', 'format': 'qcow2', + 'image_file': '/foo/bar.qcow', + 'extra_properties': '{\'hw_video_model\' : \'vga\'}', + 'nic_config_pb_loc': '/foo/bar', 'exists': True, + 'public': True}) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.image_user) self.assertEqual('qcow2', settings.format) self.assertIsNone(settings.url) self.assertEqual('/foo/bar.qcow', settings.image_file) - self.assertEqual('{\'hw_video_model\' : \'vga\'}', settings.extra_properties) + self.assertEqual('{\'hw_video_model\' : \'vga\'}', + settings.extra_properties) self.assertEqual('/foo/bar', settings.nic_config_pb_loc) self.assertTrue(settings.exists) self.assertTrue(settings.public) @@ -231,8 +267,8 @@ class CreateImageSuccessTests(OSIntegrationTestCase): def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ super(self.__class__, self).__start__() @@ -250,8 +286,9 @@ class CreateImageSuccessTests(OSIntegrationTestCase): if not os.path.exists(self.tmp_dir): os.makedirs(self.tmp_dir) - self.image_settings = openstack_tests.cirros_image_settings(name=self.image_name, - image_metadata=glance_test_meta) + self.image_settings = openstack_tests.cirros_image_settings( + name=self.image_name, + image_metadata=glance_test_meta) def tearDown(self): """ @@ -270,16 +307,20 @@ class CreateImageSuccessTests(OSIntegrationTestCase): Tests the creation of an OpenStack image from a URL. """ # Create Image - # Set the default image settings, then set any custom parameters sent from the app + # Set the default image settings, then set any custom parameters sent + # from the app - self.image_creator = create_image.OpenStackImage(self.os_creds, self.image_settings) + self.image_creator = create_image.OpenStackImage(self.os_creds, + self.image_settings) created_image = self.image_creator.create() self.assertIsNotNone(created_image) - retrieved_image = glance_utils.get_image(self.glance, self.image_settings.name) + retrieved_image = glance_utils.get_image(self.glance, + self.image_settings.name) self.assertIsNotNone(retrieved_image) self.assertEqual(created_image.size, retrieved_image.size) - self.assertEqual(get_image_size(self.image_settings), retrieved_image.size) + self.assertEqual(get_image_size(self.image_settings), + retrieved_image.size) self.assertEqual(created_image.name, retrieved_image.name) self.assertEqual(created_image.id, retrieved_image.id) @@ -288,15 +329,20 @@ class CreateImageSuccessTests(OSIntegrationTestCase): Tests the creation of an OpenStack image from a URL and set properties. """ # Create Image - # Set the default image settings, then set any custom parameters sent from the app - self.image_creator = create_image.OpenStackImage(self.os_creds, self.image_settings) + # Set the default image settings, then set any custom parameters sent + # from the app + self.image_creator = create_image.OpenStackImage(self.os_creds, + self.image_settings) created_image = self.image_creator.create() self.assertIsNotNone(created_image) - retrieved_image = glance_utils.get_image(self.glance, self.image_settings.name) + retrieved_image = glance_utils.get_image(self.glance, + self.image_settings.name) self.assertIsNotNone(retrieved_image) - self.assertEqual(self.image_creator.get_image().size, retrieved_image.size) - self.assertEqual(get_image_size(self.image_settings), retrieved_image.size) + self.assertEqual(self.image_creator.get_image().size, + retrieved_image.size) + self.assertEqual(get_image_size(self.image_settings), + retrieved_image.size) self.assertEqual(created_image.name, retrieved_image.name) self.assertEqual(created_image.id, retrieved_image.id) self.assertEqual(created_image.properties, retrieved_image.properties) @@ -307,7 +353,8 @@ class CreateImageSuccessTests(OSIntegrationTestCase): """ if not self.image_settings.image_file and self.image_settings.url: # Download the file of the image - image_file_name = file_utils.download(self.image_settings.url, self.tmp_dir).name + image_file_name = file_utils.download(self.image_settings.url, + self.tmp_dir).name else: image_file_name = self.image_settings.image_file @@ -315,41 +362,53 @@ class CreateImageSuccessTests(OSIntegrationTestCase): file_image_settings = openstack_tests.file_image_test_settings( name=self.image_name, file_path=image_file_name) - self.image_creator = create_image.OpenStackImage(self.os_creds, file_image_settings) + self.image_creator = create_image.OpenStackImage( + self.os_creds, file_image_settings) created_image = self.image_creator.create() self.assertIsNotNone(created_image) self.assertEqual(self.image_name, created_image.name) - retrieved_image = glance_utils.get_image(self.glance, file_image_settings.name) + retrieved_image = glance_utils.get_image( + self.glance, file_image_settings.name) self.assertIsNotNone(retrieved_image) - self.assertEqual(self.image_creator.get_image().size, retrieved_image.size) - self.assertEqual(get_image_size(file_image_settings), retrieved_image.size) + self.assertEqual(self.image_creator.get_image().size, + retrieved_image.size) + self.assertEqual(get_image_size(file_image_settings), + retrieved_image.size) self.assertEqual(created_image.name, retrieved_image.name) self.assertEqual(created_image.id, retrieved_image.id) else: - logger.warn('Test not executed as the image metadata requires image files') + logger.warn( + 'Test not executed as the image metadata requires image files') def test_create_delete_image(self): """ - Tests the creation then deletion of an OpenStack image to ensure clean() does not raise an Exception. + Tests the creation then deletion of an OpenStack image to ensure + clean() does not raise an Exception. """ # Create Image - self.image_creator = create_image.OpenStackImage(self.os_creds, self.image_settings) + self.image_creator = create_image.OpenStackImage(self.os_creds, + self.image_settings) created_image = self.image_creator.create() self.assertIsNotNone(created_image) - retrieved_image = glance_utils.get_image(self.glance, self.image_settings.name) + retrieved_image = glance_utils.get_image(self.glance, + self.image_settings.name) self.assertIsNotNone(retrieved_image) - self.assertEqual(self.image_creator.get_image().size, retrieved_image.size) - self.assertEqual(get_image_size(self.image_settings), retrieved_image.size) + self.assertEqual(self.image_creator.get_image().size, + retrieved_image.size) + self.assertEqual(get_image_size(self.image_settings), + retrieved_image.size) # Delete Image manually glance_utils.delete_image(self.glance, created_image) - self.assertIsNone(glance_utils.get_image(self.glance, self.image_creator.image_settings.name)) + self.assertIsNone(glance_utils.get_image( + self.glance, self.image_creator.image_settings.name)) - # Must not throw an exception when attempting to cleanup non-existent image + # Must not throw an exception when attempting to cleanup non-existent + # image self.image_creator.clean() self.assertIsNone(self.image_creator.get_image()) @@ -358,42 +417,53 @@ class CreateImageSuccessTests(OSIntegrationTestCase): Tests the creation of an OpenStack image when the image already exists. """ # Create Image - self.image_creator = create_image.OpenStackImage(self.os_creds, self.image_settings) + self.image_creator = create_image.OpenStackImage(self.os_creds, + self.image_settings) image1 = self.image_creator.create() - retrieved_image = glance_utils.get_image(self.glance, self.image_settings.name) + retrieved_image = glance_utils.get_image(self.glance, + self.image_settings.name) self.assertIsNotNone(retrieved_image) - self.assertEqual(self.image_creator.get_image().size, retrieved_image.size) - self.assertEqual(get_image_size(self.image_settings), retrieved_image.size) + self.assertEqual(self.image_creator.get_image().size, + retrieved_image.size) + self.assertEqual(get_image_size(self.image_settings), + retrieved_image.size) self.assertEqual(image1.name, retrieved_image.name) self.assertEqual(image1.id, retrieved_image.id) self.assertEqual(image1.properties, retrieved_image.properties) # Should be retrieving the instance data - os_image_2 = create_image.OpenStackImage(self.os_creds, self.image_settings) + os_image_2 = create_image.OpenStackImage(self.os_creds, + self.image_settings) image2 = os_image_2.create() self.assertEqual(image1.id, image2.id) def test_create_same_image_new_settings(self): """ - Tests the creation of an OpenStack image when the image already exists and the configuration only contains - the name. + Tests the creation of an OpenStack image when the image already exists + and the configuration only contains the name. """ # Create Image - self.image_creator = create_image.OpenStackImage(self.os_creds, self.image_settings) + self.image_creator = create_image.OpenStackImage(self.os_creds, + self.image_settings) image1 = self.image_creator.create() - retrieved_image = glance_utils.get_image(self.glance, self.image_settings.name) + retrieved_image = glance_utils.get_image(self.glance, + self.image_settings.name) self.assertIsNotNone(retrieved_image) - self.assertEqual(self.image_creator.get_image().size, retrieved_image.size) - self.assertEqual(get_image_size(self.image_settings), retrieved_image.size) + self.assertEqual(self.image_creator.get_image().size, + retrieved_image.size) + self.assertEqual(get_image_size(self.image_settings), + retrieved_image.size) self.assertEqual(image1.name, retrieved_image.name) self.assertEqual(image1.id, retrieved_image.id) self.assertEqual(image1.properties, retrieved_image.properties) # Should be retrieving the instance data - image_2_settings = ImageSettings(name=self.image_settings.name, image_user='foo', exists=True) - os_image_2 = create_image.OpenStackImage(self.os_creds, image_2_settings) + image_2_settings = ImageSettings(name=self.image_settings.name, + image_user='foo', exists=True) + os_image_2 = create_image.OpenStackImage(self.os_creds, + image_2_settings) image2 = os_image_2.create() self.assertEqual(image1.id, image2.id) @@ -417,24 +487,32 @@ class CreateImageNegativeTests(OSIntegrationTestCase): def test_bad_image_name(self): """ - Expect an ImageCreationError when the image name does not exist when a file or URL has not been configured + Expect an ImageCreationError when the image name does not exist when a + file or URL has not been configured """ - os_image_settings = ImageSettings(name='foo', image_user='bar', exists=True) - self.image_creator = create_image.OpenStackImage(self.os_creds, os_image_settings) + os_image_settings = ImageSettings(name='foo', image_user='bar', + exists=True) + self.image_creator = create_image.OpenStackImage(self.os_creds, + os_image_settings) with self.assertRaises(ImageCreationError): self.image_creator.create() - self.fail('ImageCreationError should have been raised prior to this line') + self.fail('ImageCreationError should have been raised prior to' + 'this line') def test_bad_image_url(self): """ Expect an ImageCreationError when the image download url is bad """ - os_image_settings = openstack_tests.cirros_image_settings(name=self.image_name) - self.image_creator = create_image.OpenStackImage(self.os_creds, create_image.ImageSettings( - name=os_image_settings.name, image_user=os_image_settings.image_user, - img_format=os_image_settings.format, url="http://foo.bar")) + os_image_settings = openstack_tests.cirros_image_settings( + name=self.image_name) + self.image_creator = create_image.OpenStackImage( + self.os_creds, + create_image.ImageSettings(name=os_image_settings.name, + image_user=os_image_settings.image_user, + img_format=os_image_settings.format, + url="http://foo.bar")) with self.assertRaises(URLError): self.image_creator.create() @@ -443,11 +521,14 @@ class CreateImageNegativeTests(OSIntegrationTestCase): """ Expect an ImageCreationError when the image file does not exist """ - os_image_settings = openstack_tests.cirros_image_settings(name=self.image_name) + os_image_settings = openstack_tests.cirros_image_settings( + name=self.image_name) self.image_creator = create_image.OpenStackImage( self.os_creds, - create_image.ImageSettings(name=os_image_settings.name, image_user=os_image_settings.image_user, - img_format=os_image_settings.format, image_file="/foo/bar.qcow")) + create_image.ImageSettings(name=os_image_settings.name, + image_user=os_image_settings.image_user, + img_format=os_image_settings.format, + image_file="/foo/bar.qcow")) with self.assertRaises(IOError): self.image_creator.create() @@ -456,6 +537,7 @@ class CreateMultiPartImageTests(OSIntegrationTestCase): """ Test different means for creating a 3-part images """ + def setUp(self): """ Instantiates the CreateImage object that is responsible for @@ -497,30 +579,41 @@ class CreateMultiPartImageTests(OSIntegrationTestCase): if 'disk_file' not in self.glance_test_meta: image_settings = openstack_tests.cirros_image_settings( name=self.image_name, - image_metadata={'disk_url': 'http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img', - 'kernel_url': 'http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel', - 'ramdisk_url': 'http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs'}) - - image_creator = create_image.OpenStackImage(self.os_creds, image_settings) + image_metadata={ + 'disk_url': + openstack_tests.CIRROS_DEFAULT_IMAGE_URL, + 'kernel_url': + openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, + 'ramdisk_url': + openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL}) + + image_creator = create_image.OpenStackImage(self.os_creds, + image_settings) self.image_creators.append(image_creator) image_creator.create() - main_image = glance_utils.get_image(self.glance, image_settings.name) + main_image = glance_utils.get_image(self.glance, + image_settings.name) self.assertIsNotNone(main_image) self.assertIsNotNone(image_creator.get_image()) self.assertEqual(image_creator.get_image().id, main_image.id) - kernel_image = glance_utils.get_image(self.glance, image_settings.kernel_image_settings.name) + kernel_image = glance_utils.get_image( + self.glance, image_settings.kernel_image_settings.name) self.assertIsNotNone(kernel_image) self.assertIsNotNone(image_creator.get_kernel_image()) - self.assertEqual(kernel_image.id, image_creator.get_kernel_image().id) + self.assertEqual(kernel_image.id, + image_creator.get_kernel_image().id) - ramdisk_image = glance_utils.get_image(self.glance, image_settings.ramdisk_image_settings.name) + ramdisk_image = glance_utils.get_image( + self.glance, image_settings.ramdisk_image_settings.name) self.assertIsNotNone(ramdisk_image) self.assertIsNotNone(image_creator.get_ramdisk_image()) - self.assertEqual(ramdisk_image.id, image_creator.get_ramdisk_image().id) + self.assertEqual(ramdisk_image.id, + image_creator.get_ramdisk_image().id) else: - logger.warn('Test not executed as the image metadata requires image files') + logger.warn( + 'Test not executed as the image metadata requires image files') def test_create_three_part_image_from_file_3_creators(self): """ @@ -540,18 +633,21 @@ class CreateMultiPartImageTests(OSIntegrationTestCase): elif 'kernel_url' in self.glance_test_meta: kernel_url = self.glance_test_meta['kernel_url'] else: - kernel_url = 'http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel' + kernel_url = openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL if not kernel_file_name: - kernel_file_name = file_utils.download(kernel_url, self.tmp_dir).name + kernel_file_name = file_utils.download(kernel_url, + self.tmp_dir).name kernel_file_image_settings = openstack_tests.file_image_test_settings( - name=self.image_name+'_kernel', file_path=kernel_file_name) + name=self.image_name + '_kernel', file_path=kernel_file_name) - self.image_creators.append(create_image.OpenStackImage(self.os_creds, kernel_file_image_settings)) + self.image_creators.append(create_image.OpenStackImage( + self.os_creds, kernel_file_image_settings)) kernel_image = self.image_creators[-1].create() self.assertIsNotNone(kernel_image) - self.assertEqual(get_image_size(kernel_file_image_settings), kernel_image.size) + self.assertEqual(get_image_size(kernel_file_image_settings), + kernel_image.size) # Create the ramdisk image ramdisk_file_name = None @@ -562,14 +658,17 @@ class CreateMultiPartImageTests(OSIntegrationTestCase): ramdisk_url = self.glance_test_meta['ramdisk_url'] if not ramdisk_file_name: - ramdisk_file_name = file_utils.download(ramdisk_url, self.tmp_dir).name + ramdisk_file_name = file_utils.download(ramdisk_url, + self.tmp_dir).name ramdisk_file_image_settings = openstack_tests.file_image_test_settings( - name=self.image_name+'_ramdisk', file_path=ramdisk_file_name) - self.image_creators.append(create_image.OpenStackImage(self.os_creds, ramdisk_file_image_settings)) + name=self.image_name + '_ramdisk', file_path=ramdisk_file_name) + self.image_creators.append(create_image.OpenStackImage( + self.os_creds, ramdisk_file_image_settings)) ramdisk_image = self.image_creators[-1].create() self.assertIsNotNone(ramdisk_image) - self.assertEqual(get_image_size(ramdisk_file_image_settings), ramdisk_image.size) + self.assertEqual(get_image_size(ramdisk_file_image_settings), + ramdisk_image.size) # Create the main disk image disk_file_name = None @@ -582,20 +681,25 @@ class CreateMultiPartImageTests(OSIntegrationTestCase): if not disk_file_name: disk_file_name = file_utils.download(disk_url, self.tmp_dir).name - file_image_settings = openstack_tests.file_image_test_settings(name=self.image_name, file_path=disk_file_name) + file_image_settings = openstack_tests.file_image_test_settings( + name=self.image_name, file_path=disk_file_name) properties['kernel_id'] = kernel_image.id properties['ramdisk_id'] = ramdisk_image.id file_image_settings.extra_properties = properties - self.image_creators.append(create_image.OpenStackImage(self.os_creds, file_image_settings)) + self.image_creators.append( + create_image.OpenStackImage(self.os_creds, file_image_settings)) created_image = self.image_creators[-1].create() self.assertIsNotNone(created_image) self.assertEqual(self.image_name, created_image.name) - retrieved_image = glance_utils.get_image(self.glance, file_image_settings.name) + retrieved_image = glance_utils.get_image(self.glance, + file_image_settings.name) self.assertIsNotNone(retrieved_image) - self.assertEqual(self.image_creators[-1].get_image().size, retrieved_image.size) - self.assertEqual(get_image_size(file_image_settings), retrieved_image.size) + self.assertEqual(self.image_creators[-1].get_image().size, + retrieved_image.size) + self.assertEqual(get_image_size(file_image_settings), + retrieved_image.size) self.assertEqual(created_image.name, retrieved_image.name) self.assertEqual(created_image.id, retrieved_image.id) self.assertEqual(created_image.properties, retrieved_image.properties) @@ -607,38 +711,47 @@ class CreateMultiPartImageTests(OSIntegrationTestCase): if 'disk_file' not in self.glance_test_meta: # Set properties properties = {} - if self.glance_test_meta and 'extra_properties' in self.glance_test_meta: + if self.glance_test_meta and \ + 'extra_properties' in self.glance_test_meta: properties = self.glance_test_meta['extra_properties'] # Create the kernel image kernel_image_settings = openstack_tests.cirros_image_settings( - name=self.image_name+'_kernel', - url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-kernel') + name=self.image_name + '_kernel', + url=openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL) if self.glance_test_meta: if 'kernel_url' in self.glance_test_meta: - kernel_image_settings.url = self.glance_test_meta['kernel_url'] - self.image_creators.append(create_image.OpenStackImage(self.os_creds, kernel_image_settings)) + kernel_image_settings.url = self.glance_test_meta[ + 'kernel_url'] + self.image_creators.append( + create_image.OpenStackImage(self.os_creds, + kernel_image_settings)) kernel_image = self.image_creators[-1].create() self.assertIsNotNone(kernel_image) - self.assertEqual(get_image_size(kernel_image_settings), kernel_image.size) + self.assertEqual(get_image_size(kernel_image_settings), + kernel_image.size) # Create the ramdisk image ramdisk_image_settings = openstack_tests.cirros_image_settings( - name=self.image_name+'_ramdisk', - url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-initramfs') + name=self.image_name + '_ramdisk', + url=openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL) if self.glance_test_meta: if 'ramdisk_url' in self.glance_test_meta: - ramdisk_image_settings.url = self.glance_test_meta['ramdisk_url'] - self.image_creators.append(create_image.OpenStackImage(self.os_creds, ramdisk_image_settings)) + ramdisk_image_settings.url = self.glance_test_meta[ + 'ramdisk_url'] + self.image_creators.append( + create_image.OpenStackImage(self.os_creds, + ramdisk_image_settings)) ramdisk_image = self.image_creators[-1].create() self.assertIsNotNone(ramdisk_image) - self.assertEqual(get_image_size(ramdisk_image_settings), ramdisk_image.size) + self.assertEqual(get_image_size(ramdisk_image_settings), + ramdisk_image.size) # Create the main image os_image_settings = openstack_tests.cirros_image_settings( name=self.image_name, - url='http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img') + url=openstack_tests.CIRROS_DEFAULT_IMAGE_URL) if self.glance_test_meta: if 'disk_url' in self.glance_test_meta: os_image_settings.url = self.glance_test_meta['disk_url'] @@ -647,22 +760,28 @@ class CreateMultiPartImageTests(OSIntegrationTestCase): properties['ramdisk_id'] = ramdisk_image.id os_image_settings.extra_properties = properties - self.image_creators.append(create_image.OpenStackImage(self.os_creds, os_image_settings)) + self.image_creators.append( + create_image.OpenStackImage(self.os_creds, os_image_settings)) created_image = self.image_creators[-1].create() self.assertIsNotNone(created_image) self.assertEqual(self.image_name, created_image.name) - retrieved_image = glance_utils.get_image(self.glance, os_image_settings.name) + retrieved_image = glance_utils.get_image(self.glance, + os_image_settings.name) self.assertIsNotNone(retrieved_image) - self.assertEqual(self.image_creators[-1].get_image().size, retrieved_image.size) - self.assertEqual(get_image_size(os_image_settings), retrieved_image.size) + self.assertEqual(self.image_creators[-1].get_image().size, + retrieved_image.size) + self.assertEqual(get_image_size(os_image_settings), + retrieved_image.size) self.assertEqual(created_image.name, retrieved_image.name) self.assertEqual(created_image.id, retrieved_image.id) - self.assertEqual(created_image.properties, retrieved_image.properties) + self.assertEqual(created_image.properties, + retrieved_image.properties) else: - logger.warn('Test not executed as the image metadata requires image files') + logger.warn( + 'Test not executed as the image metadata requires image files') def get_image_size(image_settings): @@ -675,4 +794,6 @@ def get_image_size(image_settings): elif image_settings.url: return int(file_utils.get_content_length(image_settings.url)) else: - raise Exception('Cannot retrieve expected image size. Image filename or URL has not been configured') + raise Exception( + 'Cannot retrieve expected image size. Image filename or URL has ' + 'not been configured') diff --git a/snaps/openstack/tests/create_instance_tests.py b/snaps/openstack/tests/create_instance_tests.py index 34cec98..998fe88 100644 --- a/snaps/openstack/tests/create_instance_tests.py +++ b/snaps/openstack/tests/create_instance_tests.py @@ -13,25 +13,29 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging -import os import re +import shutil import time import unittest import uuid -import shutil +import os + from snaps import file_utils -from snaps.openstack.create_instance import VmInstanceSettings, OpenStackVmInstance, FloatingIpSettings from snaps.openstack.create_flavor import OpenStackFlavor, FlavorSettings +from snaps.openstack.create_image import OpenStackImage, ImageSettings +from snaps.openstack.create_instance import ( + VmInstanceSettings, OpenStackVmInstance, FloatingIpSettings) from snaps.openstack.create_keypairs import OpenStackKeypair, KeypairSettings from snaps.openstack.create_network import OpenStackNetwork, PortSettings from snaps.openstack.create_router import OpenStackRouter -from snaps.openstack.create_image import OpenStackImage, ImageSettings -from snaps.openstack.create_security_group import SecurityGroupSettings, OpenStackSecurityGroup, \ - SecurityGroupRuleSettings, Direction, Protocol +from snaps.openstack.create_security_group import ( + SecurityGroupSettings, OpenStackSecurityGroup, SecurityGroupRuleSettings, + Direction, Protocol) from snaps.openstack.tests import openstack_tests, validation_utils +from snaps.openstack.tests.os_source_file_test import ( + OSIntegrationTestCase, OSComponentTestCase) from snaps.openstack.utils import nova_utils -from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase, OSComponentTestCase __author__ = 'spisarski' @@ -71,7 +75,8 @@ class VmInstanceSettingsUnitTests(unittest.TestCase): def test_name_flavor_port_only(self): port_settings = PortSettings(name='foo-port', network_name='bar-net') - settings = VmInstanceSettings(name='foo', flavor='bar', port_settings=[port_settings]) + settings = VmInstanceSettings(name='foo', flavor='bar', + port_settings=[port_settings]) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.flavor) self.assertEqual(1, len(settings.port_settings)) @@ -87,7 +92,8 @@ class VmInstanceSettingsUnitTests(unittest.TestCase): def test_config_with_name_flavor_port_only(self): port_settings = PortSettings(name='foo-port', network_name='bar-net') - settings = VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar', 'ports': [port_settings]}) + settings = VmInstanceSettings( + **{'name': 'foo', 'flavor': 'bar', 'ports': [port_settings]}) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.flavor) self.assertEqual(1, len(settings.port_settings)) @@ -103,12 +109,17 @@ class VmInstanceSettingsUnitTests(unittest.TestCase): def test_all(self): port_settings = PortSettings(name='foo-port', network_name='bar-net') - fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port', router_name='foo-bar-router') - - settings = VmInstanceSettings(name='foo', flavor='bar', port_settings=[port_settings], - security_group_names=['sec_grp_1'], floating_ip_settings=[fip_settings], - sudo_user='joe', vm_boot_timeout=999, vm_delete_timeout=333, - ssh_connect_timeout=111, availability_zone='server name') + fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port', + router_name='foo-bar-router') + + settings = VmInstanceSettings(name='foo', flavor='bar', + port_settings=[port_settings], + security_group_names=['sec_grp_1'], + floating_ip_settings=[fip_settings], + sudo_user='joe', vm_boot_timeout=999, + vm_delete_timeout=333, + ssh_connect_timeout=111, + availability_zone='server name') self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.flavor) self.assertEqual(1, len(settings.port_settings)) @@ -118,8 +129,10 @@ class VmInstanceSettingsUnitTests(unittest.TestCase): self.assertEqual('sec_grp_1', settings.security_group_names[0]) self.assertEqual(1, len(settings.floating_ip_settings)) self.assertEqual('foo-fip', settings.floating_ip_settings[0].name) - self.assertEqual('bar-port', settings.floating_ip_settings[0].port_name) - self.assertEqual('foo-bar-router', settings.floating_ip_settings[0].router_name) + self.assertEqual('bar-port', + settings.floating_ip_settings[0].port_name) + self.assertEqual('foo-bar-router', + settings.floating_ip_settings[0].router_name) self.assertEqual('joe', settings.sudo_user) self.assertEqual(999, settings.vm_boot_timeout) self.assertEqual(333, settings.vm_delete_timeout) @@ -128,13 +141,15 @@ class VmInstanceSettingsUnitTests(unittest.TestCase): def test_config_all(self): port_settings = PortSettings(name='foo-port', network_name='bar-net') - fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port', router_name='foo-bar-router') - - settings = VmInstanceSettings(config={'name': 'foo', 'flavor': 'bar', 'ports': [port_settings], - 'security_group_names': ['sec_grp_1'], - 'floating_ips': [fip_settings], 'sudo_user': 'joe', - 'vm_boot_timeout': 999, 'vm_delete_timeout': 333, - 'ssh_connect_timeout': 111, 'availability_zone': 'server name'}) + fip_settings = FloatingIpSettings(name='foo-fip', port_name='bar-port', + router_name='foo-bar-router') + + settings = VmInstanceSettings( + **{'name': 'foo', 'flavor': 'bar', 'ports': [port_settings], + 'security_group_names': ['sec_grp_1'], + 'floating_ips': [fip_settings], 'sudo_user': 'joe', + 'vm_boot_timeout': 999, 'vm_delete_timeout': 333, + 'ssh_connect_timeout': 111, 'availability_zone': 'server name'}) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.flavor) self.assertEqual(1, len(settings.port_settings)) @@ -143,8 +158,10 @@ class VmInstanceSettingsUnitTests(unittest.TestCase): self.assertEqual(1, len(settings.security_group_names)) self.assertEqual(1, len(settings.floating_ip_settings)) self.assertEqual('foo-fip', settings.floating_ip_settings[0].name) - self.assertEqual('bar-port', settings.floating_ip_settings[0].port_name) - self.assertEqual('foo-bar-router', settings.floating_ip_settings[0].router_name) + self.assertEqual('bar-port', + settings.floating_ip_settings[0].port_name) + self.assertEqual('foo-bar-router', + settings.floating_ip_settings[0].router_name) self.assertEqual('joe', settings.sudo_user) self.assertEqual(999, settings.vm_boot_timeout) self.assertEqual(333, settings.vm_delete_timeout) @@ -163,7 +180,7 @@ class FloatingIpSettingsUnitTests(unittest.TestCase): def test_empty_config(self): with self.assertRaises(Exception): - FloatingIpSettings(config=dict()) + FloatingIpSettings(**dict()) def test_name_only(self): with self.assertRaises(Exception): @@ -171,7 +188,7 @@ class FloatingIpSettingsUnitTests(unittest.TestCase): def test_config_with_name_only(self): with self.assertRaises(Exception): - FloatingIpSettings(config={'name': 'foo'}) + FloatingIpSettings(**{'name': 'foo'}) def test_name_port_only(self): with self.assertRaises(Exception): @@ -179,7 +196,7 @@ class FloatingIpSettingsUnitTests(unittest.TestCase): def test_config_with_name_port_only(self): with self.assertRaises(Exception): - FloatingIpSettings(config={'name': 'foo', 'port_name': 'bar'}) + FloatingIpSettings(**{'name': 'foo', 'port_name': 'bar'}) def test_name_router_only(self): with self.assertRaises(Exception): @@ -187,10 +204,11 @@ class FloatingIpSettingsUnitTests(unittest.TestCase): def test_config_with_name_router_only(self): with self.assertRaises(Exception): - FloatingIpSettings(config={'name': 'foo', 'router_name': 'bar'}) + FloatingIpSettings(**{'name': 'foo', 'router_name': 'bar'}) def test_name_port_router_only(self): - settings = FloatingIpSettings(name='foo', port_name='foo-port', router_name='bar-router') + settings = FloatingIpSettings(name='foo', port_name='foo-port', + router_name='bar-router') self.assertEqual('foo', settings.name) self.assertEqual('foo-port', settings.port_name) self.assertEqual('bar-router', settings.router_name) @@ -198,7 +216,9 @@ class FloatingIpSettingsUnitTests(unittest.TestCase): self.assertTrue(settings.provisioning) def test_config_with_name_port_router_only(self): - settings = FloatingIpSettings(config={'name': 'foo', 'port_name': 'foo-port', 'router_name': 'bar-router'}) + settings = FloatingIpSettings( + **{'name': 'foo', 'port_name': 'foo-port', + 'router_name': 'bar-router'}) self.assertEqual('foo', settings.name) self.assertEqual('foo-port', settings.port_name) self.assertEqual('bar-router', settings.router_name) @@ -206,8 +226,10 @@ class FloatingIpSettingsUnitTests(unittest.TestCase): self.assertTrue(settings.provisioning) def test_all(self): - settings = FloatingIpSettings(name='foo', port_name='foo-port', router_name='bar-router', - subnet_name='bar-subnet', provisioning=False) + settings = FloatingIpSettings(name='foo', port_name='foo-port', + router_name='bar-router', + subnet_name='bar-subnet', + provisioning=False) self.assertEqual('foo', settings.name) self.assertEqual('foo-port', settings.port_name) self.assertEqual('bar-router', settings.router_name) @@ -215,8 +237,10 @@ class FloatingIpSettingsUnitTests(unittest.TestCase): self.assertFalse(settings.provisioning) def test_config_all(self): - settings = FloatingIpSettings(config={'name': 'foo', 'port_name': 'foo-port', 'router_name': 'bar-router', - 'subnet_name': 'bar-subnet', 'provisioning': False}) + settings = FloatingIpSettings( + **{'name': 'foo', 'port_name': 'foo-port', + 'router_name': 'bar-router', 'subnet_name': 'bar-subnet', + 'provisioning': False}) self.assertEqual('foo', settings.name) self.assertEqual('foo-port', settings.port_name) self.assertEqual('bar-router', settings.router_name) @@ -231,7 +255,8 @@ class SimpleHealthCheck(OSIntegrationTestCase): def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ super(self.__class__, self).__start__() @@ -249,25 +274,30 @@ class SimpleHealthCheck(OSIntegrationTestCase): self.priv_net_config = openstack_tests.get_priv_net_config( net_name=guid + '-priv-net', subnet_name=guid + '-priv-subnet') self.port_settings = PortSettings( - name=self.port_1_name, network_name=self.priv_net_config.network_settings.name) + name=self.port_1_name, + network_name=self.priv_net_config.network_settings.name) # Create Image - # Set the default image settings, then set any custom parameters sent from the app + # Set the default image settings, then set any custom parameters sent + # from the app os_image_settings = openstack_tests.cirros_image_settings( name=guid + '-image', image_metadata=self.image_metadata) try: - self.image_creator = OpenStackImage(self.os_creds, os_image_settings) + self.image_creator = OpenStackImage(self.os_creds, + os_image_settings) self.image_creator.create() # Create Network - self.network_creator = OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings) + self.network_creator = OpenStackNetwork( + self.os_creds, self.priv_net_config.network_settings) self.network_creator.create() # Create Flavor self.flavor_creator = OpenStackFlavor( self.admin_os_creds, - FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=1, metadata=self.flavor_metadata)) + FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, + vcpus=1, metadata=self.flavor_metadata)) self.flavor_creator.create() except Exception as e: self.tearDown() @@ -281,38 +311,49 @@ class SimpleHealthCheck(OSIntegrationTestCase): try: self.inst_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning VM instance with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning VM instance with message' + ' - %s', e) if self.network_creator: try: self.network_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning network with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning network with message - %s', + e) if self.flavor_creator: try: self.flavor_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning flavor with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning flavor with message - %s', + e) if self.image_creator and not self.image_creator.image_settings.exists: try: self.image_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning image with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning image with message - %s', + e) super(self.__class__, self).__clean__() def test_check_vm_ip_dhcp(self): """ - Tests the creation of an OpenStack instance with a single port and ensures that it's assigned IP address is - the actual. + Tests the creation of an OpenStack instance with a single port and + ensures that it's assigned IP address is the actual. """ instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) vm = self.inst_creator.create() ip = self.inst_creator.get_port_ip(self.port_settings.name) @@ -327,9 +368,11 @@ class CreateInstanceSimpleTests(OSIntegrationTestCase): """ Simple instance creation tests without any other objects """ + def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ super(self.__class__, self).__start__() @@ -353,21 +396,25 @@ class CreateInstanceSimpleTests(OSIntegrationTestCase): try: # Create Image - self.image_creator = OpenStackImage(self.os_creds, os_image_settings) + self.image_creator = OpenStackImage(self.os_creds, + os_image_settings) self.image_creator.create() # Create Flavor self.flavor_creator = OpenStackFlavor( self.admin_os_creds, - FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata)) + FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, + vcpus=2, metadata=self.flavor_metadata)) self.flavor_creator.create() # Create Network - self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings) + self.network_creator = OpenStackNetwork( + self.os_creds, net_config.network_settings) self.network_creator.create() - self.port_settings = PortSettings(name=guid + '-port', - network_name=net_config.network_settings.name) + self.port_settings = PortSettings( + name=guid + '-port', + network_name=net_config.network_settings.name) except Exception as e: self.tearDown() @@ -381,46 +428,59 @@ class CreateInstanceSimpleTests(OSIntegrationTestCase): try: self.inst_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning VM instance with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning VM instance with message ' + '- %s', e) if self.flavor_creator: try: self.flavor_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning flavor with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning flavor with message - %s', + e) if self.network_creator: try: self.network_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning network with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning network with message - %s', + e) if self.image_creator and not self.image_creator.image_settings.exists: try: self.image_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning image with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning image with message - %s', e) super(self.__class__, self).__clean__() def test_create_delete_instance(self): """ - Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP. + Tests the creation of an OpenStack instance with a single port with a + static IP without a Floating IP. """ - instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, - port_settings=[self.port_settings]) + instance_settings = VmInstanceSettings( + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) self.inst_creator = OpenStackVmInstance( - self.os_creds, instance_settings, self.image_creator.image_settings) + self.os_creds, instance_settings, + self.image_creator.image_settings) vm_inst = self.inst_creator.create() - self.assertEqual(1, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name))) + self.assertEqual(1, len( + nova_utils.get_servers_by_name(self.nova, instance_settings.name))) # Delete instance nova_utils.delete_vm_instance(self.nova, vm_inst) self.assertTrue(self.inst_creator.vm_deleted(block=True)) - self.assertEqual(0, len(nova_utils.get_servers_by_name(self.nova, instance_settings.name))) + self.assertEqual(0, len( + nova_utils.get_servers_by_name(self.nova, instance_settings.name))) # Exception should not be thrown self.inst_creator.clean() @@ -433,8 +493,8 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase): def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ super(self.__class__, self).__start__() @@ -463,37 +523,47 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase): name=guid + '-image', image_metadata=self.image_metadata) try: # Create Image - self.image_creator = OpenStackImage(self.os_creds, os_image_settings) + self.image_creator = OpenStackImage(self.os_creds, + os_image_settings) self.image_creator.create() # Create Network - self.network_creator = OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings) + self.network_creator = OpenStackNetwork( + self.os_creds, self.pub_net_config.network_settings) self.network_creator.create() # Create Router - self.router_creator = OpenStackRouter(self.os_creds, self.pub_net_config.router_settings) + self.router_creator = OpenStackRouter( + self.os_creds, self.pub_net_config.router_settings) self.router_creator.create() # Create Flavor self.flavor_creator = OpenStackFlavor( self.admin_os_creds, - FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata)) + FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, + vcpus=2, metadata=self.flavor_metadata)) self.flavor_creator.create() self.keypair_creator = OpenStackKeypair( self.os_creds, KeypairSettings( - name=self.keypair_name, public_filepath=self.keypair_pub_filepath, + name=self.keypair_name, + public_filepath=self.keypair_pub_filepath, private_filepath=self.keypair_priv_filepath)) self.keypair_creator.create() sec_grp_name = guid + '-sec-grp' - rule1 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name, direction=Direction.ingress, + rule1 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name, + direction=Direction.ingress, protocol=Protocol.icmp) - rule2 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name, direction=Direction.ingress, - protocol=Protocol.tcp, port_range_min=22, port_range_max=22) + rule2 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name, + direction=Direction.ingress, + protocol=Protocol.tcp, + port_range_min=22, + port_range_max=22) self.sec_grp_creator = OpenStackSecurityGroup( self.os_creds, - SecurityGroupSettings(name=sec_grp_name, rule_settings=[rule1, rule2])) + SecurityGroupSettings(name=sec_grp_name, + rule_settings=[rule1, rule2])) self.sec_grp_creator.create() except Exception as e: self.tearDown() @@ -507,13 +577,17 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase): try: inst_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning VM instance with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning VM instance with message ' + '- %s', e) if self.keypair_creator: try: self.keypair_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning keypair with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning keypair with message - %s', + e) if os.path.isfile(self.keypair_pub_filepath): os.remove(self.keypair_pub_filepath) @@ -525,52 +599,67 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase): try: self.flavor_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning flavor with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning flavor with message - %s', + e) if self.sec_grp_creator: try: self.sec_grp_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning security group with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning security group with message' + ' - %s', e) if self.router_creator: try: self.router_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning router with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning router with message - %s', + e) if self.network_creator: try: self.network_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning network with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning network with message - %s', + e) if self.image_creator and not self.image_creator.image_settings.exists: try: self.image_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning image with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning image with message - %s', e) super(self.__class__, self).__clean__() def test_single_port_static(self): """ - Tests the creation of an OpenStack instance with a single port with a static IP without a Floating IP. + Tests the creation of an OpenStack instance with a single port with a + static IP without a Floating IP. """ ip_1 = '10.55.1.100' - + sub_settings = self.pub_net_config.network_settings.subnet_settings port_settings = PortSettings( - name=self.port_1_name, network_name=self.pub_net_config.network_settings.name, - ip_addrs=[{'subnet_name': self.pub_net_config.network_settings.subnet_settings[0].name, 'ip': ip_1}]) + name=self.port_1_name, + network_name=self.pub_net_config.network_settings.name, + ip_addrs=[ + {'subnet_name': sub_settings[0].name, 'ip': ip_1}]) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings], + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[port_settings], floating_ip_settings=[FloatingIpSettings( name=self.floating_ip_name, port_name=self.port_1_name, router_name=self.pub_net_config.router_settings.name)]) inst_creator = OpenStackVmInstance( - self.os_creds, instance_settings, self.image_creator.image_settings, + self.os_creds, instance_settings, + self.image_creator.image_settings, keypair_settings=self.keypair_creator.keypair_settings) self.inst_creators.append(inst_creator) vm_inst = inst_creator.create() @@ -581,19 +670,24 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase): def test_ssh_client_fip_before_active(self): """ - Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active. + Tests the ability to access a VM via SSH and a floating IP when it has + been assigned prior to being active. """ port_settings = PortSettings( - name=self.port_1_name, network_name=self.pub_net_config.network_settings.name) + name=self.port_1_name, + network_name=self.pub_net_config.network_settings.name) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings], + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[port_settings], floating_ip_settings=[FloatingIpSettings( name=self.floating_ip_name, port_name=self.port_1_name, router_name=self.pub_net_config.router_settings.name)]) inst_creator = OpenStackVmInstance( - self.os_creds, instance_settings, self.image_creator.image_settings, + self.os_creds, instance_settings, + self.image_creator.image_settings, keypair_settings=self.keypair_creator.keypair_settings) self.inst_creators.append(inst_creator) vm_inst = inst_creator.create() @@ -604,26 +698,32 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase): ip = inst_creator.get_port_ip(port_settings.name) self.assertTrue(check_dhcp_lease(vm_inst, ip)) - inst_creator.add_security_group(self.sec_grp_creator.get_security_group()) + inst_creator.add_security_group( + self.sec_grp_creator.get_security_group()) self.assertEqual(vm_inst, inst_creator.get_vm_inst()) self.assertTrue(validate_ssh_client(inst_creator)) def test_ssh_client_fip_after_active(self): """ - Tests the ability to access a VM via SSH and a floating IP when it has been assigned prior to being active. + Tests the ability to access a VM via SSH and a floating IP when it has + been assigned prior to being active. """ port_settings = PortSettings( - name=self.port_1_name, network_name=self.pub_net_config.network_settings.name) + name=self.port_1_name, + network_name=self.pub_net_config.network_settings.name) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings], + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[port_settings], floating_ip_settings=[FloatingIpSettings( name=self.floating_ip_name, port_name=self.port_1_name, router_name=self.pub_net_config.router_settings.name)]) inst_creator = OpenStackVmInstance( - self.os_creds, instance_settings, self.image_creator.image_settings, + self.os_creds, instance_settings, + self.image_creator.image_settings, keypair_settings=self.keypair_creator.keypair_settings) self.inst_creators.append(inst_creator) @@ -636,7 +736,8 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase): ip = inst_creator.get_port_ip(port_settings.name) self.assertTrue(check_dhcp_lease(vm_inst, ip)) - inst_creator.add_security_group(self.sec_grp_creator.get_security_group()) + inst_creator.add_security_group( + self.sec_grp_creator.get_security_group()) self.assertEqual(vm_inst, inst_creator.get_vm_inst()) self.assertTrue(validate_ssh_client(inst_creator)) @@ -644,13 +745,14 @@ class CreateInstanceSingleNetworkTests(OSIntegrationTestCase): class CreateInstancePortManipulationTests(OSIntegrationTestCase): """ - Test for the CreateInstance class with a single NIC/Port where mac and IP values are manually set + Test for the CreateInstance class with a single NIC/Port where mac and IP + values are manually set """ def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ super(self.__class__, self).__start__() @@ -674,17 +776,20 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase): try: # Create Image - self.image_creator = OpenStackImage(self.os_creds, os_image_settings) + self.image_creator = OpenStackImage(self.os_creds, + os_image_settings) self.image_creator.create() # Create Network - self.network_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings) + self.network_creator = OpenStackNetwork( + self.os_creds, self.net_config.network_settings) self.network_creator.create() # Create Flavor self.flavor_creator = OpenStackFlavor( self.admin_os_creds, - FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata)) + FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, + vcpus=2, metadata=self.flavor_metadata)) self.flavor_creator.create() except Exception as e: self.tearDown() @@ -698,147 +803,198 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase): try: self.inst_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning VM instance with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning VM instance with message ' + '- %s', e) if self.flavor_creator: try: self.flavor_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning flavor with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning flavor with message - %s', + e) if self.network_creator: try: self.network_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning network with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning network with message - %s', + e) if self.image_creator and not self.image_creator.image_settings.exists: try: self.image_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning image with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning image with message - %s', e) super(self.__class__, self).__clean__() def test_set_custom_valid_ip_one_subnet(self): """ - Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet. + Tests the creation of an OpenStack instance with a single port with a + static IP on a network with one subnet. """ ip = '10.55.0.101' + sub_settings = self.net_config.network_settings.subnet_settings port_settings = PortSettings( - name=self.port_1_name, network_name=self.net_config.network_settings.name, - ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}]) + name=self.port_1_name, + network_name=self.net_config.network_settings.name, + ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}]) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings]) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) self.inst_creator.create(block=True) self.assertEqual(ip, self.inst_creator.get_port_ip( - self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name)) + self.port_1_name, + subnet_name=self.net_config.network_settings.subnet_settings[ + 0].name)) def test_set_custom_invalid_ip_one_subnet(self): """ - Tests the creation of an OpenStack instance with a single port with a static IP on a network with one subnet. + Tests the creation of an OpenStack instance with a single port with a + static IP on a network with one subnet. """ ip = '10.66.0.101' + sub_settings = self.net_config.network_settings.subnet_settings port_settings = PortSettings( - name=self.port_1_name, network_name=self.net_config.network_settings.name, - ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}]) + name=self.port_1_name, + network_name=self.net_config.network_settings.name, + ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}]) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings]) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) with self.assertRaises(Exception): self.inst_creator.create() def test_set_custom_valid_mac(self): """ - Tests the creation of an OpenStack instance with a single port where the MAC address is assigned. + Tests the creation of an OpenStack instance with a single port where + the MAC address is assigned. """ mac_addr = '0a:1b:2c:3d:4e:5f' port_settings = PortSettings( - name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr) + name=self.port_1_name, + network_name=self.net_config.network_settings.name, + mac_address=mac_addr) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings]) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) self.inst_creator.create(block=True) - self.assertEqual(mac_addr, self.inst_creator.get_port_mac(self.port_1_name)) + self.assertEqual(mac_addr, + self.inst_creator.get_port_mac(self.port_1_name)) def test_set_custom_invalid_mac(self): """ - Tests the creation of an OpenStack instance with a single port where an invalid MAC address value is being + Tests the creation of an OpenStack instance with a single port where an + invalid MAC address value is being assigned. This should raise an Exception """ port_settings = PortSettings( - name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address='foo') + name=self.port_1_name, + network_name=self.net_config.network_settings.name, + mac_address='foo') instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings]) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[port_settings]) self.inst_creator = OpenStackVmInstance( - self.os_creds, instance_settings, self.image_creator.image_settings) + self.os_creds, instance_settings, + self.image_creator.image_settings) with self.assertRaises(Exception): self.inst_creator.create() def test_set_custom_mac_and_ip(self): """ - Tests the creation of an OpenStack instance with a single port where the IP and MAC address is assigned. + Tests the creation of an OpenStack instance with a single port where + the IP and MAC address is assigned. """ ip = '10.55.0.101' mac_addr = '0a:1b:2c:3d:4e:5f' + sub_settings = self.net_config.network_settings.subnet_settings port_settings = PortSettings( - name=self.port_1_name, network_name=self.net_config.network_settings.name, mac_address=mac_addr, - ip_addrs=[{'subnet_name': self.net_config.network_settings.subnet_settings[0].name, 'ip': ip}]) + name=self.port_1_name, + network_name=self.net_config.network_settings.name, + mac_address=mac_addr, + ip_addrs=[{'subnet_name': sub_settings[0].name, 'ip': ip}]) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings]) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) self.inst_creator.create(block=True) self.assertEqual(ip, self.inst_creator.get_port_ip( - self.port_1_name, subnet_name=self.net_config.network_settings.subnet_settings[0].name)) - self.assertEqual(mac_addr, self.inst_creator.get_port_mac(self.port_1_name)) + self.port_1_name, + subnet_name=self.net_config.network_settings.subnet_settings[ + 0].name)) + self.assertEqual(mac_addr, + self.inst_creator.get_port_mac(self.port_1_name)) def test_set_allowed_address_pairs(self): """ - Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set. + Tests the creation of an OpenStack instance with a single port where + max_allowed_address_pair is set. """ ip = '10.55.0.101' mac_addr = '0a:1b:2c:3d:4e:5f' pair = {'ip_address': ip, 'mac_address': mac_addr} port_settings = PortSettings( - name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair]) + name=self.port_1_name, + network_name=self.net_config.network_settings.name, + allowed_address_pairs=[pair]) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings]) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) self.inst_creator.create(block=True) port = self.inst_creator.get_port_by_name(port_settings.name) self.assertIsNotNone(port) self.assertIsNotNone(port['port'].get('allowed_address_pairs')) self.assertEqual(1, len(port['port']['allowed_address_pairs'])) - validation_utils.objects_equivalent(pair, port['port']['allowed_address_pairs'][0]) + validation_utils.objects_equivalent(pair, port['port'][ + 'allowed_address_pairs'][0]) def test_set_allowed_address_pairs_bad_mac(self): """ - Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an - invalid MAC address. + Tests the creation of an OpenStack instance with a single port where + max_allowed_address_pair is set with an invalid MAC address. """ ip = '10.55.0.101' mac_addr = 'foo' @@ -846,20 +1002,25 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase): pairs = set() pairs.add((ip, mac_addr)) port_settings = PortSettings( - name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair]) + name=self.port_1_name, + network_name=self.net_config.network_settings.name, + allowed_address_pairs=[pair]) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings]) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) with self.assertRaises(Exception): self.inst_creator.create() def test_set_allowed_address_pairs_bad_ip(self): """ - Tests the creation of an OpenStack instance with a single port where max_allowed_address_pair is set with an - invalid MAC address. + Tests the creation of an OpenStack instance with a single port where + max_allowed_address_pair is set with an invalid MAC address. """ ip = 'foo' mac_addr = '0a:1b:2c:3d:4e:5f' @@ -867,13 +1028,18 @@ class CreateInstancePortManipulationTests(OSIntegrationTestCase): pairs = set() pairs.add((ip, mac_addr)) port_settings = PortSettings( - name=self.port_1_name, network_name=self.net_config.network_settings.name, allowed_address_pairs=[pair]) + name=self.port_1_name, + network_name=self.net_config.network_settings.name, + allowed_address_pairs=[pair]) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[port_settings]) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) with self.assertRaises(Exception): self.inst_creator.create() @@ -885,8 +1051,8 @@ class CreateInstanceOnComputeHost(OSIntegrationTestCase): def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ super(self.__class__, self).__start__() @@ -908,17 +1074,20 @@ class CreateInstanceOnComputeHost(OSIntegrationTestCase): try: # Create Network - self.network_creator = OpenStackNetwork(self.admin_os_creds, self.priv_net_config.network_settings) + self.network_creator = OpenStackNetwork( + self.admin_os_creds, self.priv_net_config.network_settings) self.network_creator.create() # Create Flavor self.flavor_creator = OpenStackFlavor( self.admin_os_creds, - FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1, vcpus=1, metadata=self.flavor_metadata)) + FlavorSettings(name=guid + '-flavor-name', ram=512, disk=1, + vcpus=1, metadata=self.flavor_metadata)) self.flavor_creator.create() # Create Image - self.image_creator = OpenStackImage(self.os_creds, os_image_settings) + self.image_creator = OpenStackImage(self.os_creds, + os_image_settings) self.image_creator.create() except Exception as e: @@ -933,25 +1102,32 @@ class CreateInstanceOnComputeHost(OSIntegrationTestCase): try: inst_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning VM instance with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning VM instance with message ' + '- %s', e) if self.flavor_creator: try: self.flavor_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning flavor with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning flavor with message - %s', + e) if self.network_creator: try: self.network_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning network with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning network with message - %s', + e) if self.image_creator and not self.image_creator.image_settings.exists: try: self.image_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning image with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning image with message - %s', e) super(self.__class__, self).__clean__() @@ -968,18 +1144,23 @@ class CreateInstanceOnComputeHost(OSIntegrationTestCase): for zone in zones: inst_name = self.vm_inst_name + '-' + zone ctr += 1 - port_settings = PortSettings(name=self.port_base_name + '-' + str(ctr), - network_name=self.priv_net_config.network_settings.name) + port_settings = PortSettings( + name=self.port_base_name + '-' + str(ctr), + network_name=self.priv_net_config.network_settings.name) instance_settings = VmInstanceSettings( - name=inst_name, flavor=self.flavor_creator.flavor_settings.name, availability_zone=zone, + name=inst_name, + flavor=self.flavor_creator.flavor_settings.name, + availability_zone=zone, port_settings=[port_settings]) inst_creator = OpenStackVmInstance( - self.admin_os_creds, instance_settings, self.image_creator.image_settings) + self.admin_os_creds, instance_settings, + self.image_creator.image_settings) self.inst_creators.append(inst_creator) inst_creator.create() - # Validate instances to ensure they've been deployed to the correct server + # Validate instances to ensure they've been deployed to the correct + # server index = 0 for zone in zones: creator = self.inst_creators[index] @@ -993,14 +1174,15 @@ class CreateInstanceOnComputeHost(OSIntegrationTestCase): class CreateInstancePubPrivNetTests(OSIntegrationTestCase): """ - Test for the CreateInstance class with two NIC/Ports, eth0 with floating IP and eth1 w/o + Test for the CreateInstance class with two NIC/Ports, eth0 with floating IP + and eth1 w/o. These tests require a Centos image """ def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ super(self.__class__, self).__start__() @@ -1022,29 +1204,39 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase): self.port_2_name = self.guid + '-port-2' self.floating_ip_name = self.guid + 'fip1' self.priv_net_config = openstack_tests.get_priv_net_config( - net_name=self.guid + '-priv-net', subnet_name=self.guid + '-priv-subnet', - router_name=self.guid + '-priv-router', external_net=self.ext_net_name) + net_name=self.guid + '-priv-net', + subnet_name=self.guid + '-priv-subnet', + router_name=self.guid + '-priv-router', + external_net=self.ext_net_name) self.pub_net_config = openstack_tests.get_pub_net_config( - net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet', - router_name=self.guid + '-pub-router', external_net=self.ext_net_name) + net_name=self.guid + '-pub-net', + subnet_name=self.guid + '-pub-subnet', + router_name=self.guid + '-pub-router', + external_net=self.ext_net_name) image_name = self.__class__.__name__ + '-' + str(uuid.uuid4()) - os_image_settings = openstack_tests.centos_image_settings(name=image_name, image_metadata=self.image_metadata) + os_image_settings = openstack_tests.centos_image_settings( + name=image_name, image_metadata=self.image_metadata) try: # Create Image - self.image_creator = OpenStackImage(self.os_creds, os_image_settings) + self.image_creator = OpenStackImage(self.os_creds, + os_image_settings) self.image_creator.create() # First network is public - self.network_creators.append(OpenStackNetwork(self.os_creds, self.pub_net_config.network_settings)) + self.network_creators.append(OpenStackNetwork( + self.os_creds, self.pub_net_config.network_settings)) # Second network is private - self.network_creators.append(OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings)) + self.network_creators.append(OpenStackNetwork( + self.os_creds, self.priv_net_config.network_settings)) for network_creator in self.network_creators: network_creator.create() - self.router_creators.append(OpenStackRouter(self.os_creds, self.pub_net_config.router_settings)) - self.router_creators.append(OpenStackRouter(self.os_creds, self.priv_net_config.router_settings)) + self.router_creators.append(OpenStackRouter( + self.os_creds, self.pub_net_config.router_settings)) + self.router_creators.append(OpenStackRouter( + self.os_creds, self.priv_net_config.router_settings)) # Create Routers for router_creator in self.router_creators: @@ -1053,25 +1245,32 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase): # Create Flavor self.flavor_creator = OpenStackFlavor( self.admin_os_creds, - FlavorSettings(name=self.guid + '-flavor-name', ram=512, disk=10, vcpus=2, + FlavorSettings(name=self.guid + '-flavor-name', ram=512, + disk=10, vcpus=2, metadata=self.flavor_metadata)) self.flavor_creator.create() # Create Keypair self.keypair_creator = OpenStackKeypair( self.os_creds, KeypairSettings( - name=self.keypair_name, public_filepath=self.keypair_pub_filepath, + name=self.keypair_name, + public_filepath=self.keypair_pub_filepath, private_filepath=self.keypair_priv_filepath)) self.keypair_creator.create() sec_grp_name = self.guid + '-sec-grp' - rule1 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name, direction=Direction.ingress, + rule1 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name, + direction=Direction.ingress, protocol=Protocol.icmp) - rule2 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name, direction=Direction.ingress, - protocol=Protocol.tcp, port_range_min=22, port_range_max=22) + rule2 = SecurityGroupRuleSettings(sec_grp_name=sec_grp_name, + direction=Direction.ingress, + protocol=Protocol.tcp, + port_range_min=22, + port_range_max=22) self.sec_grp_creator = OpenStackSecurityGroup( self.os_creds, - SecurityGroupSettings(name=sec_grp_name, rule_settings=[rule1, rule2])) + SecurityGroupSettings(name=sec_grp_name, + rule_settings=[rule1, rule2])) self.sec_grp_creator.create() except Exception as e: self.tearDown() @@ -1085,13 +1284,17 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase): try: self.inst_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning VM instance with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning VM instance with message ' + '- %s', e) if self.keypair_creator: try: self.keypair_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning keypair with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning keypair with message - %s', + e) if os.path.isfile(self.keypair_pub_filepath): os.remove(self.keypair_pub_filepath) @@ -1103,42 +1306,55 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase): try: self.flavor_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning flavor with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning flavor with message - %s', + e) for router_creator in self.router_creators: try: router_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning router with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning router with message - %s', + e) for network_creator in self.network_creators: try: network_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning network with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning network with message - %s', + e) if self.sec_grp_creator: try: self.sec_grp_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning security group with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning security group with message' + ' - %s', e) if self.image_creator and not self.image_creator.image_settings.exists: try: self.image_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning image with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning image with message - %s', e) super(self.__class__, self).__clean__() def test_dual_ports_dhcp(self): """ - Tests the creation of an OpenStack instance with a dual ports/NICs with a DHCP assigned IP. - NOTE: This test and any others that call ansible will most likely fail unless you do one of - two things: - 1. Have a ~/.ansible.cfg (or alternate means) to set host_key_checking = False - 2. Set the following environment variable in your executing shell: ANSIBLE_HOST_KEY_CHECKING=False - Should this not be performed, the creation of the host ssh key will cause your ansible calls to fail. + Tests the creation of an OpenStack instance with a dual ports/NICs with + a DHCP assigned IP. + NOTE: This test and any others that call ansible will most likely fail + unless you do one of two things: + 1. Have a ~/.ansible.cfg (or alternate means) to + set host_key_checking = False + 2. Set the following environment variable in your executing shell: + ANSIBLE_HOST_KEY_CHECKING=False + Should this not be performed, the creation of the host ssh key will + cause your ansible calls to fail. """ # Create ports/NICs for instance ports_settings = [] @@ -1151,13 +1367,16 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase): # Create instance instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=ports_settings, + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=ports_settings, floating_ip_settings=[FloatingIpSettings( name=self.floating_ip_name, port_name=self.port_1_name, router_name=self.pub_net_config.router_settings.name)]) self.inst_creator = OpenStackVmInstance( - self.os_creds, instance_settings, self.image_creator.image_settings, + self.os_creds, instance_settings, + self.image_creator.image_settings, keypair_settings=self.keypair_creator.keypair_settings) vm_inst = self.inst_creator.create(block=True) @@ -1171,28 +1390,32 @@ class CreateInstancePubPrivNetTests(OSIntegrationTestCase): self.assertTrue(check_dhcp_lease(vm_inst, ip)) # Add security group to VM - self.inst_creator.add_security_group(self.sec_grp_creator.get_security_group()) + self.inst_creator.add_security_group( + self.sec_grp_creator.get_security_group()) # Effectively blocks until VM's ssh port has been opened self.assertTrue(self.inst_creator.vm_ssh_active(block=True)) - # TODO - Refactor config_nics() to return a status that can be validated here. + # TODO - Refactor config_nics() to return a status that can be + # validated here. self.inst_creator.config_nics() # TODO - *** ADD VALIDATION HERE *** # TODO - Add validation that both floating IPs work # TODO - Add tests where only one NIC has a floating IP - # TODO - Add tests where one attempts to place a floating IP on a network/router without an external gateway + # TODO - Add tests where one attempts to place a floating IP on a + # network/router without an external gateway class InstanceSecurityGroupTests(OSIntegrationTestCase): """ Tests that include, add, and remove security groups from VM instances """ + def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ super(self.__class__, self).__start__() @@ -1208,8 +1431,10 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase): self.floating_ip_name = self.guid + 'fip1' net_config = openstack_tests.get_priv_net_config( - net_name=self.guid + '-pub-net', subnet_name=self.guid + '-pub-subnet', - router_name=self.guid + '-pub-router', external_net=self.ext_net_name) + net_name=self.guid + '-pub-net', + subnet_name=self.guid + '-pub-subnet', + router_name=self.guid + '-pub-router', + external_net=self.ext_net_name) # Initialize for tearDown() self.image_creator = None @@ -1221,22 +1446,26 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase): try: # Create Image - self.image_creator = OpenStackImage(self.os_creds, os_image_settings) + self.image_creator = OpenStackImage(self.os_creds, + os_image_settings) self.image_creator.create() # Create Network - self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings) + self.network_creator = OpenStackNetwork( + self.os_creds, net_config.network_settings) self.network_creator.create() # Create Flavor self.flavor_creator = OpenStackFlavor( self.admin_os_creds, - FlavorSettings(name=self.guid + '-flavor-name', ram=128, disk=10, vcpus=2, + FlavorSettings(name=self.guid + '-flavor-name', ram=128, + disk=10, vcpus=2, metadata=self.flavor_metadata)) self.flavor_creator.create() - self.port_settings = PortSettings(name=self.guid + '-port', - network_name=net_config.network_settings.name) + self.port_settings = PortSettings( + name=self.guid + '-port', + network_name=net_config.network_settings.name) except Exception as e: self.tearDown() raise e @@ -1249,31 +1478,40 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase): try: self.inst_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning VM instance with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning VM instance with message -' + ' %s', e) for sec_grp_creator in self.sec_grp_creators: try: sec_grp_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning security group with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning security group with message' + ' - %s', e) if self.flavor_creator: try: self.flavor_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning flavor with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning flavor with message - %s', + e) if self.network_creator: try: self.network_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning network with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning network with message - %s', + e) if self.image_creator and not self.image_creator.image_settings.exists: try: self.image_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning image with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning image with message - %s', e) super(self.__class__, self).__clean__() @@ -1283,26 +1521,33 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase): """ # Create instance instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) vm_inst = self.inst_creator.create(block=True) self.assertIsNotNone(vm_inst) # Create security group object to add to instance - sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group') - sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', + description='hello group') + sec_grp_creator = OpenStackSecurityGroup(self.os_creds, + sec_grp_settings) sec_grp = sec_grp_creator.create() self.sec_grp_creators.append(sec_grp_creator) # Check that group has not been added - self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name)) + self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), + sec_grp_settings.name)) # Add security group to instance after activated self.inst_creator.add_security_group(sec_grp) # Validate that security group has been added - self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name)) + self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), + sec_grp_settings.name)) def test_add_invalid_security_group(self): """ @@ -1310,44 +1555,57 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase): """ # Create instance instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) vm_inst = self.inst_creator.create(block=True) self.assertIsNotNone(vm_inst) # Create security group object to add to instance - sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group') - sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', + description='hello group') + sec_grp_creator = OpenStackSecurityGroup(self.os_creds, + sec_grp_settings) sec_grp = sec_grp_creator.create() sec_grp_creator.clean() self.sec_grp_creators.append(sec_grp_creator) # Check that group has not been added - self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name)) + self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), + sec_grp_settings.name)) # Add security group to instance after activated self.assertFalse(self.inst_creator.add_security_group(sec_grp)) # Validate that security group has been added - self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name)) + self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), + sec_grp_settings.name)) def test_remove_security_group(self): """ - Tests the removal of a security group created before and added to the instance. + Tests the removal of a security group created before and added to the + instance. """ # Create security group object to add to instance - sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group') - sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', + description='hello group') + sec_grp_creator = OpenStackSecurityGroup(self.os_creds, + sec_grp_settings) sec_grp = sec_grp_creator.create() self.sec_grp_creators.append(sec_grp_creator) # Create instance instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, - security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + security_group_names=[sec_grp_settings.name], + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) vm_inst = self.inst_creator.create(block=True) self.assertIsNotNone(vm_inst) @@ -1358,62 +1616,79 @@ class InstanceSecurityGroupTests(OSIntegrationTestCase): self.assertTrue(self.inst_creator.remove_security_group(sec_grp)) # Validate that security group has been added - self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name)) + self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), + sec_grp_settings.name)) def test_remove_security_group_never_added(self): """ - Tests the removal of a security group that was never added in the first place. + Tests the removal of a security group that was never added in the first + place. """ # Create security group object to add to instance - sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group') - sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', + description='hello group') + sec_grp_creator = OpenStackSecurityGroup(self.os_creds, + sec_grp_settings) sec_grp = sec_grp_creator.create() self.sec_grp_creators.append(sec_grp_creator) # Create instance instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) vm_inst = self.inst_creator.create(block=True) self.assertIsNotNone(vm_inst) # Check that group has been added - self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name)) + self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), + sec_grp_settings.name)) # Add security group to instance after activated self.assertFalse(self.inst_creator.remove_security_group(sec_grp)) # Validate that security group has been added - self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name)) + self.assertFalse(inst_has_sec_grp(self.inst_creator.get_vm_inst(), + sec_grp_settings.name)) def test_add_same_security_group(self): """ - Tests the addition of a security group created before add added to the instance. + Tests the addition of a security group created before add added to the + instance. """ # Create security group object to add to instance - sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', description='hello group') - sec_grp_creator = OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_settings = SecurityGroupSettings(name=self.guid + '-name', + description='hello group') + sec_grp_creator = OpenStackSecurityGroup(self.os_creds, + sec_grp_settings) sec_grp = sec_grp_creator.create() self.sec_grp_creators.append(sec_grp_creator) # Create instance instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, - security_group_names=[sec_grp_settings.name], port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + security_group_names=[sec_grp_settings.name], + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) vm_inst = self.inst_creator.create(block=True) self.assertIsNotNone(vm_inst) # Check that group has been added - self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name)) + self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), + sec_grp_settings.name)) # Add security group to instance after activated self.assertTrue(self.inst_creator.add_security_group(sec_grp)) # Validate that security group has been added - self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), sec_grp_settings.name)) + self.assertTrue(inst_has_sec_grp(self.inst_creator.get_vm_inst(), + sec_grp_settings.name)) def inst_has_sec_grp(vm_inst, sec_grp_name): @@ -1435,7 +1710,8 @@ def inst_has_sec_grp(vm_inst, sec_grp_name): def validate_ssh_client(instance_creator): """ Returns True if instance_creator returns an SSH client that is valid - :param instance_creator: the object responsible for creating the VM instance + :param instance_creator: the object responsible for creating the VM + instance :return: T/F """ ssh_active = instance_creator.vm_ssh_active(block=True) @@ -1464,8 +1740,8 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase): def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ super(self.__class__, self).__start__() @@ -1491,16 +1767,22 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase): and 'disk_file' in self.image_metadata['cirros']: metadata = self.image_metadata['cirros'] else: - metadata = {'disk_url': openstack_tests.CIRROS_DEFAULT_IMAGE_URL, - 'kernel_url': openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, - 'ramdisk_url': openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL} + metadata = { + 'disk_url': openstack_tests.CIRROS_DEFAULT_IMAGE_URL, + 'kernel_url': + openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, + 'ramdisk_url': + openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL} image_settings = openstack_tests.cirros_image_settings( name=self.image_name, image_metadata=metadata) - if not image_settings.ramdisk_image_settings or not image_settings.kernel_image_settings: - logger.warn('3 Part image will not be tested. Image metadata has overridden this functionality') + if not image_settings.ramdisk_image_settings or not \ + image_settings.kernel_image_settings: + logger.warn( + '3 Part image will not be tested. Image metadata has ' + 'overridden this functionality') self.image_creator = OpenStackImage(self.os_creds, image_settings) self.image_creator.create() @@ -1508,15 +1790,18 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase): # Create Flavor self.flavor_creator = OpenStackFlavor( self.admin_os_creds, - FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, vcpus=2, metadata=self.flavor_metadata)) + FlavorSettings(name=guid + '-flavor-name', ram=128, disk=10, + vcpus=2, metadata=self.flavor_metadata)) self.flavor_creator.create() # Create Network - self.network_creator = OpenStackNetwork(self.os_creds, net_config.network_settings) + self.network_creator = OpenStackNetwork( + self.os_creds, net_config.network_settings) self.network_creator.create() - self.port_settings = PortSettings(name=guid + '-port', - network_name=net_config.network_settings.name) + self.port_settings = PortSettings( + name=guid + '-port', + network_name=net_config.network_settings.name) except Exception as e: self.tearDown() raise e @@ -1529,25 +1814,32 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase): try: self.inst_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning VM instance with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning VM instance with message -' + ' %s', e) if self.flavor_creator: try: self.flavor_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning flavor with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning flavor with message - %s', + e) if self.network_creator: try: self.network_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning network with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning network with message - %s', + e) if self.image_creator and not self.image_creator.image_settings.exists: try: self.image_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning image with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning image with message - %s', e) super(self.__class__, self).__clean__() @@ -1555,12 +1847,16 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase): """ Tests the creation of an OpenStack instance from a 3-part image. """ - instance_settings = VmInstanceSettings(name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, - port_settings=[self.port_settings]) + instance_settings = VmInstanceSettings( + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) - # The last created image is the main image from which we create the instance + # The last created image is the main image from which we create the + # instance self.inst_creator = OpenStackVmInstance( - self.os_creds, instance_settings, self.image_creator.image_settings) + self.os_creds, instance_settings, + self.image_creator.image_settings) vm_inst = self.inst_creator.create() self.assertIsNotNone(vm_inst) @@ -1569,14 +1865,15 @@ class CreateInstanceFromThreePartImage(OSIntegrationTestCase): class CreateInstanceMockOfflineTests(OSComponentTestCase): """ - Tests the custom image_metadata that can be set by clients for handling images differently than the - default behavior of the existing tests primarily for offline testing + Tests the custom image_metadata that can be set by clients for handling + images differently than the default behavior of the existing tests + primarily for offline testing """ def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) @@ -1595,23 +1892,28 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase): self.inst_creator = None self.priv_net_config = openstack_tests.get_priv_net_config( - net_name=self.guid + '-priv-net', subnet_name=self.guid + '-priv-subnet') + net_name=self.guid + '-priv-net', + subnet_name=self.guid + '-priv-subnet') self.port_settings = PortSettings( - name=self.port_1_name, network_name=self.priv_net_config.network_settings.name) + name=self.port_1_name, + network_name=self.priv_net_config.network_settings.name) try: # Download image file - self.image_file = file_utils.download(openstack_tests.CIRROS_DEFAULT_IMAGE_URL, self.tmpDir) + self.image_file = file_utils.download( + openstack_tests.CIRROS_DEFAULT_IMAGE_URL, self.tmpDir) # Create Network - self.network_creator = OpenStackNetwork(self.os_creds, self.priv_net_config.network_settings) + self.network_creator = OpenStackNetwork( + self.os_creds, self.priv_net_config.network_settings) self.network_creator.create() # Create Flavor self.flavor_creator = OpenStackFlavor( self.os_creds, FlavorSettings( - name=self.guid + '-flavor-name', ram=128, disk=10, vcpus=1)) + name=self.guid + '-flavor-name', ram=128, disk=10, + vcpus=1)) self.flavor_creator.create() except Exception as e: self.tearDown() @@ -1625,43 +1927,54 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase): try: self.inst_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning VM instance with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning VM instance with message - ' + '%s', e) if self.network_creator: try: self.network_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning network with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning network with message - %s', + e) if self.flavor_creator: try: self.flavor_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning flavor with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning flavor with message - %s', + e) if self.image_creator: try: self.image_creator.clean() except Exception as e: - logger.error('Unexpected exception cleaning image with message - ' + str(e)) + logger.error( + 'Unexpected exception cleaning image with message - %s', e) if os.path.exists(self.tmpDir) and os.path.isdir(self.tmpDir): shutil.rmtree(self.tmpDir) def test_inst_from_file_image_simple_flat(self): """ - Creates a VM instance from a locally sourced file image using simply the 'disk_file' attribute vs. - using the 'config' option which completely overrides all image settings + Creates a VM instance from a locally sourced file image using simply + the 'disk_file' attribute vs. using the 'config' option which + completely overrides all image settings :return: """ metadata = {'disk_file': self.image_file.name} - os_image_settings = openstack_tests.cirros_image_settings(name=self.image_name, image_metadata=metadata) + os_image_settings = openstack_tests.cirros_image_settings( + name=self.image_name, image_metadata=metadata) self.assertEqual(self.image_file.name, os_image_settings.image_file) - self.assertEqual(openstack_tests.CIRROS_USER, os_image_settings.image_user) + self.assertEqual(openstack_tests.CIRROS_USER, + os_image_settings.image_user) self.assertIsNone(os_image_settings.url) self.assertFalse(os_image_settings.exists) - self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, os_image_settings.format) + self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, + os_image_settings.format) self.assertIsNone(os_image_settings.kernel_image_settings) self.assertIsNone(os_image_settings.ramdisk_image_settings) @@ -1670,27 +1983,34 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase): self.image_creator.create() instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) self.inst_creator.create() self.assertTrue(self.inst_creator.vm_active(block=True)) def test_inst_from_file_image_simple_nested(self): """ - Creates a VM instance from a locally sourced file image using simply the 'disk_file' attribute under 'cirros' - vs. using the 'config' option which completely overrides all image settings + Creates a VM instance from a locally sourced file image using simply + the 'disk_file' attribute under 'cirros' vs. using the 'config' option + which completely overrides all image settings :return: """ metadata = {'cirros': {'disk_file': self.image_file.name}} - os_image_settings = openstack_tests.cirros_image_settings(name=self.image_name, image_metadata=metadata) + os_image_settings = openstack_tests.cirros_image_settings( + name=self.image_name, image_metadata=metadata) self.assertEqual(self.image_file.name, os_image_settings.image_file) - self.assertEqual(openstack_tests.CIRROS_USER, os_image_settings.image_user) + self.assertEqual(openstack_tests.CIRROS_USER, + os_image_settings.image_user) self.assertIsNone(os_image_settings.url) self.assertFalse(os_image_settings.exists) - self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, os_image_settings.format) + self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, + os_image_settings.format) self.assertIsNone(os_image_settings.kernel_image_settings) self.assertIsNone(os_image_settings.ramdisk_image_settings) @@ -1699,57 +2019,78 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase): self.image_creator.create() instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) self.inst_creator.create() self.assertTrue(self.inst_creator.vm_active(block=True)) def test_inst_from_existing(self): """ - Creates a VM instance from a image creator that has been configured to use an existing image + Creates a VM instance from a image creator that has been configured to + use an existing image :return: """ - os_image_settings = openstack_tests.cirros_image_settings(name=self.image_name) + os_image_settings = openstack_tests.cirros_image_settings( + name=self.image_name) self.image_creator = OpenStackImage(self.os_creds, os_image_settings) self.image_creator.create() + image_settings = self.image_creator.image_settings test_image_creator = OpenStackImage( - self.os_creds, ImageSettings(name=self.image_creator.image_settings.name, - image_user=self.image_creator.image_settings.image_user, exists=True)) + self.os_creds, + ImageSettings(name=image_settings.name, + image_user=image_settings.image_user, + exists=True)) test_image_creator.create() - self.assertEqual(self.image_creator.get_image().id, test_image_creator.get_image().id) + self.assertEqual(self.image_creator.get_image().id, + test_image_creator.get_image().id) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - test_image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + test_image_creator.image_settings) self.inst_creator.create() self.assertTrue(self.inst_creator.vm_active(block=True)) def test_inst_from_file_image_complex(self): """ - Creates a VM instance from a locally sourced file image by overriding the default settings by using a dict() - that can be read in by ImageSettings + Creates a VM instance from a locally sourced file image by overriding + the default settings by using a dict() that can be read in by + ImageSettings :return: """ - os_image_settings = openstack_tests.cirros_image_settings(name=self.image_name) + os_image_settings = openstack_tests.cirros_image_settings( + name=self.image_name) self.image_creator = OpenStackImage(self.os_creds, os_image_settings) self.image_creator.create() - metadata = {'cirros': {'config': - {'name': os_image_settings.name, 'image_user': os_image_settings.image_user, - 'exists': True}}} - test_image_settings = openstack_tests.cirros_image_settings(image_metadata=metadata) + metadata = { + 'cirros': + {'config': + {'name': os_image_settings.name, + 'image_user': os_image_settings.image_user, + 'exists': True}}} + test_image_settings = openstack_tests.cirros_image_settings( + image_metadata=metadata) test_image = OpenStackImage(self.os_creds, test_image_settings) test_image.create() instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance(self.os_creds, + instance_settings, test_image_settings) self.inst_creator.create() @@ -1757,102 +2098,136 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase): def test_inst_from_file_3part_image_complex(self): """ - Creates a VM instance from a locally sourced file image by overriding the default settings by using a dict() - that can be read in by ImageSettings + Creates a VM instance from a locally sourced file image by overriding + the default settings by using a dict() that can be read in by + ImageSettings :return: """ - kernel_file = file_utils.download(openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir) - ramdisk_file = file_utils.download(openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir) - - metadata = {'cirros': - {'config': - {'name': self.image_name, - 'image_user': openstack_tests.CIRROS_USER, - 'image_file': self.image_file.name, - 'format': openstack_tests.DEFAULT_IMAGE_FORMAT, - 'kernel_image_settings': - {'name': self.image_name + '-kernel', - 'image_user': openstack_tests.CIRROS_USER, - 'image_file': kernel_file.name, - 'format': openstack_tests.DEFAULT_IMAGE_FORMAT}, - 'ramdisk_image_settings': - {'name': self.image_name + '-ramdisk', - 'image_user': openstack_tests.CIRROS_USER, - 'image_file': ramdisk_file.name, - 'format': openstack_tests.DEFAULT_IMAGE_FORMAT}}}} - - os_image_settings = openstack_tests.cirros_image_settings(name=self.image_name, image_metadata=metadata) + kernel_file = file_utils.download( + openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir) + ramdisk_file = file_utils.download( + openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir) + + metadata = { + 'cirros': + {'config': + {'name': self.image_name, + 'image_user': openstack_tests.CIRROS_USER, + 'image_file': self.image_file.name, + 'format': openstack_tests.DEFAULT_IMAGE_FORMAT, + 'kernel_image_settings': + {'name': self.image_name + '-kernel', + 'image_user': openstack_tests.CIRROS_USER, + 'image_file': kernel_file.name, + 'format': openstack_tests.DEFAULT_IMAGE_FORMAT}, + 'ramdisk_image_settings': + {'name': self.image_name + '-ramdisk', + 'image_user': openstack_tests.CIRROS_USER, + 'image_file': ramdisk_file.name, + 'format': openstack_tests.DEFAULT_IMAGE_FORMAT}}}} + + os_image_settings = openstack_tests.cirros_image_settings( + name=self.image_name, image_metadata=metadata) self.assertEqual(self.image_name, os_image_settings.name) self.assertEqual(self.image_file.name, os_image_settings.image_file) - self.assertEqual(openstack_tests.CIRROS_USER, os_image_settings.image_user) + self.assertEqual(openstack_tests.CIRROS_USER, + os_image_settings.image_user) self.assertIsNone(os_image_settings.url) self.assertFalse(os_image_settings.exists) - self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, os_image_settings.format) + self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, + os_image_settings.format) self.assertIsNotNone(os_image_settings.kernel_image_settings) - self.assertEqual(self.image_name + '-kernel', os_image_settings.kernel_image_settings.name) - self.assertEqual(kernel_file.name, os_image_settings.kernel_image_settings.image_file) - self.assertEqual(openstack_tests.CIRROS_USER, os_image_settings.kernel_image_settings.image_user) + self.assertEqual(self.image_name + '-kernel', + os_image_settings.kernel_image_settings.name) + self.assertEqual(kernel_file.name, + os_image_settings.kernel_image_settings.image_file) + self.assertEqual(openstack_tests.CIRROS_USER, + os_image_settings.kernel_image_settings.image_user) self.assertIsNone(os_image_settings.kernel_image_settings.url) self.assertFalse(os_image_settings.kernel_image_settings.exists) - self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, os_image_settings.kernel_image_settings.format) + self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, + os_image_settings.kernel_image_settings.format) self.assertIsNotNone(os_image_settings.ramdisk_image_settings) - self.assertEqual(self.image_name + '-ramdisk', os_image_settings.ramdisk_image_settings.name) - self.assertEqual(ramdisk_file.name, os_image_settings.ramdisk_image_settings.image_file) - self.assertEqual(openstack_tests.CIRROS_USER, os_image_settings.ramdisk_image_settings.image_user) + self.assertEqual(self.image_name + '-ramdisk', + os_image_settings.ramdisk_image_settings.name) + self.assertEqual(ramdisk_file.name, + os_image_settings.ramdisk_image_settings.image_file) + self.assertEqual(openstack_tests.CIRROS_USER, + os_image_settings.ramdisk_image_settings.image_user) self.assertIsNone(os_image_settings.ramdisk_image_settings.url) self.assertFalse(os_image_settings.ramdisk_image_settings.exists) - self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, os_image_settings.ramdisk_image_settings.format) + self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, + os_image_settings.ramdisk_image_settings.format) self.image_creator = OpenStackImage(self.os_creds, os_image_settings) self.image_creator.create() instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, self.image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) self.inst_creator.create() self.assertTrue(self.inst_creator.vm_active(block=True)) def test_inst_from_file_3part_image_simple_flat(self): """ - Creates a VM instance from a 3-part image locally sourced from file images using simply the 'disk_file', - 'kernel_file', and 'ramdisk_file' attributes vs. using the 'config' option which completely overrides all + Creates a VM instance from a 3-part image locally sourced from file + images using simply the 'disk_file', 'kernel_file', and 'ramdisk_file' + attributes vs. using the 'config' option which completely overrides all image settings :return: """ - kernel_file = file_utils.download(openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir) - ramdisk_file = file_utils.download(openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir) + kernel_file = file_utils.download( + openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir) + ramdisk_file = file_utils.download( + openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir) - metadata = {'disk_file': self.image_file.name, 'kernel_file': kernel_file.name, + metadata = {'disk_file': self.image_file.name, + 'kernel_file': kernel_file.name, 'ramdisk_file': ramdisk_file.name} - os_image_settings = openstack_tests.cirros_image_settings(name=self.image_name, image_metadata=metadata) + os_image_settings = openstack_tests.cirros_image_settings( + name=self.image_name, image_metadata=metadata) self.assertEqual(self.image_name, os_image_settings.name) self.assertEqual(self.image_file.name, os_image_settings.image_file) - self.assertEqual(openstack_tests.CIRROS_USER, os_image_settings.image_user) + self.assertEqual(openstack_tests.CIRROS_USER, + os_image_settings.image_user) self.assertIsNone(os_image_settings.url) self.assertFalse(os_image_settings.exists) - self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, os_image_settings.format) + self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, + os_image_settings.format) self.assertIsNotNone(os_image_settings.kernel_image_settings) - self.assertEqual(self.image_name + '-kernel', os_image_settings.kernel_image_settings.name) - self.assertEqual(kernel_file.name, os_image_settings.kernel_image_settings.image_file) - self.assertEqual(openstack_tests.CIRROS_USER, os_image_settings.kernel_image_settings.image_user) + self.assertEqual(self.image_name + '-kernel', + os_image_settings.kernel_image_settings.name) + self.assertEqual(kernel_file.name, + os_image_settings.kernel_image_settings.image_file) + self.assertEqual(openstack_tests.CIRROS_USER, + os_image_settings.kernel_image_settings.image_user) self.assertIsNone(os_image_settings.kernel_image_settings.url) self.assertFalse(os_image_settings.kernel_image_settings.exists) - self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, os_image_settings.kernel_image_settings.format) + self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, + os_image_settings.kernel_image_settings.format) self.assertIsNotNone(os_image_settings.ramdisk_image_settings) - self.assertEqual(self.image_name + '-ramdisk', os_image_settings.ramdisk_image_settings.name) - self.assertEqual(ramdisk_file.name, os_image_settings.ramdisk_image_settings.image_file) - self.assertEqual(openstack_tests.CIRROS_USER, os_image_settings.ramdisk_image_settings.image_user) + self.assertEqual(self.image_name + '-ramdisk', + os_image_settings.ramdisk_image_settings.name) + self.assertEqual(ramdisk_file.name, + os_image_settings.ramdisk_image_settings.image_file) + self.assertEqual(openstack_tests.CIRROS_USER, + os_image_settings.ramdisk_image_settings.image_user) self.assertIsNone(os_image_settings.ramdisk_image_settings.url) self.assertFalse(os_image_settings.ramdisk_image_settings.exists) - self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, os_image_settings.ramdisk_image_settings.format) + self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, + os_image_settings.ramdisk_image_settings.format) self.image_creator = OpenStackImage(self.os_creds, os_image_settings) self.image_creator.create() @@ -1861,50 +2236,68 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase): self.assertIsNotNone(self.image_creator.get_ramdisk_image()) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) self.inst_creator.create() self.assertTrue(self.inst_creator.vm_active(block=True)) def test_inst_from_file_3part_image_simple_nested(self): """ - Creates a VM instance from a 3-part image locally sourced from file images using simply the 'disk_file', - 'kernel_file', and 'ramdisk_file' attributes under 'cirros' vs. using the 'config' option which completely - overrides all image settings + Creates a VM instance from a 3-part image locally sourced from file + images using simply the 'disk_file', 'kernel_file', and 'ramdisk_file' + attributes under 'cirros' vs. using the 'config' option which + completely overrides all image settings :return: """ - kernel_file = file_utils.download(openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir) - ramdisk_file = file_utils.download(openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir) + kernel_file = file_utils.download( + openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir) + ramdisk_file = file_utils.download( + openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir) - metadata = {'cirros': {'disk_file': self.image_file.name, 'kernel_file': kernel_file.name, + metadata = {'cirros': {'disk_file': self.image_file.name, + 'kernel_file': kernel_file.name, 'ramdisk_file': ramdisk_file.name}} - os_image_settings = openstack_tests.cirros_image_settings(name=self.image_name, image_metadata=metadata) + os_image_settings = openstack_tests.cirros_image_settings( + name=self.image_name, image_metadata=metadata) self.assertEqual(self.image_name, os_image_settings.name) self.assertEqual(self.image_file.name, os_image_settings.image_file) - self.assertEqual(openstack_tests.CIRROS_USER, os_image_settings.image_user) + self.assertEqual(openstack_tests.CIRROS_USER, + os_image_settings.image_user) self.assertIsNone(os_image_settings.url) self.assertFalse(os_image_settings.exists) - self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, os_image_settings.format) + self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, + os_image_settings.format) self.assertIsNotNone(os_image_settings.kernel_image_settings) - self.assertEqual(self.image_name + '-kernel', os_image_settings.kernel_image_settings.name) - self.assertEqual(kernel_file.name, os_image_settings.kernel_image_settings.image_file) - self.assertEqual(openstack_tests.CIRROS_USER, os_image_settings.kernel_image_settings.image_user) + self.assertEqual(self.image_name + '-kernel', + os_image_settings.kernel_image_settings.name) + self.assertEqual(kernel_file.name, + os_image_settings.kernel_image_settings.image_file) + self.assertEqual(openstack_tests.CIRROS_USER, + os_image_settings.kernel_image_settings.image_user) self.assertIsNone(os_image_settings.kernel_image_settings.url) self.assertFalse(os_image_settings.kernel_image_settings.exists) - self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, os_image_settings.kernel_image_settings.format) + self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, + os_image_settings.kernel_image_settings.format) self.assertIsNotNone(os_image_settings.ramdisk_image_settings) - self.assertEqual(self.image_name + '-ramdisk', os_image_settings.ramdisk_image_settings.name) - self.assertEqual(ramdisk_file.name, os_image_settings.ramdisk_image_settings.image_file) - self.assertEqual(openstack_tests.CIRROS_USER, os_image_settings.ramdisk_image_settings.image_user) + self.assertEqual(self.image_name + '-ramdisk', + os_image_settings.ramdisk_image_settings.name) + self.assertEqual(ramdisk_file.name, + os_image_settings.ramdisk_image_settings.image_file) + self.assertEqual(openstack_tests.CIRROS_USER, + os_image_settings.ramdisk_image_settings.image_user) self.assertIsNone(os_image_settings.ramdisk_image_settings.url) self.assertFalse(os_image_settings.ramdisk_image_settings.exists) - self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, os_image_settings.ramdisk_image_settings.format) + self.assertEqual(openstack_tests.DEFAULT_IMAGE_FORMAT, + os_image_settings.ramdisk_image_settings.format) self.image_creator = OpenStackImage(self.os_creds, os_image_settings) self.image_creator.create() @@ -1913,9 +2306,12 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase): self.assertIsNotNone(self.image_creator.get_ramdisk_image()) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - self.image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + self.image_creator.image_settings) self.inst_creator.create() self.assertTrue(self.inst_creator.vm_active(block=True)) @@ -1925,26 +2321,37 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase): Creates a VM instance from a 3-part image that is existing :return: """ - kernel_file = file_utils.download(openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir) - ramdisk_file = file_utils.download(openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir) + kernel_file = file_utils.download( + openstack_tests.CIRROS_DEFAULT_KERNEL_IMAGE_URL, self.tmpDir) + ramdisk_file = file_utils.download( + openstack_tests.CIRROS_DEFAULT_RAMDISK_IMAGE_URL, self.tmpDir) - metadata = {'cirros': {'disk_file': self.image_file.name, 'kernel_file': kernel_file.name, + metadata = {'cirros': {'disk_file': self.image_file.name, + 'kernel_file': kernel_file.name, 'ramdisk_file': ramdisk_file.name}} - os_image_settings = openstack_tests.cirros_image_settings(name=self.image_name, image_metadata=metadata) + os_image_settings = openstack_tests.cirros_image_settings( + name=self.image_name, image_metadata=metadata) self.image_creator = OpenStackImage(self.os_creds, os_image_settings) self.image_creator.create() + image_settings = self.image_creator.image_settings test_image_creator = OpenStackImage( - self.os_creds, ImageSettings(name=self.image_creator.image_settings.name, - image_user=self.image_creator.image_settings.image_user, exists=True)) + self.os_creds, + ImageSettings(name=image_settings.name, + image_user=image_settings.image_user, + exists=True)) test_image_creator.create() - self.assertEqual(self.image_creator.get_image().id, test_image_creator.get_image().id) + self.assertEqual(self.image_creator.get_image().id, + test_image_creator.get_image().id) instance_settings = VmInstanceSettings( - name=self.vm_inst_name, flavor=self.flavor_creator.flavor_settings.name, port_settings=[self.port_settings]) - self.inst_creator = OpenStackVmInstance(self.os_creds, instance_settings, - test_image_creator.image_settings) + name=self.vm_inst_name, + flavor=self.flavor_creator.flavor_settings.name, + port_settings=[self.port_settings]) + self.inst_creator = OpenStackVmInstance( + self.os_creds, instance_settings, + test_image_creator.image_settings) self.inst_creator.create() self.assertTrue(self.inst_creator.vm_active(block=True)) @@ -1953,8 +2360,9 @@ class CreateInstanceMockOfflineTests(OSComponentTestCase): def check_dhcp_lease(vm, ip, timeout=160): """ Returns true if the expected DHCP lease has been acquired - :param vm: - :param ip: + :param vm: the OpenStack VM instance object + :param ip: the IP address to look for + :param timeout: how long to query for IP address :return: """ found = False diff --git a/snaps/openstack/tests/create_keypairs_tests.py b/snaps/openstack/tests/create_keypairs_tests.py index b587a50..29fe843 100644 --- a/snaps/openstack/tests/create_keypairs_tests.py +++ b/snaps/openstack/tests/create_keypairs_tests.py @@ -12,13 +12,13 @@ # 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. -import os -import uuid import unittest +import uuid +import os from snaps.openstack.create_keypairs import KeypairSettings, OpenStackKeypair -from snaps.openstack.utils import nova_utils from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase +from snaps.openstack.utils import nova_utils __author__ = 'spisarski' @@ -34,7 +34,7 @@ class KeypairSettingsUnitTests(unittest.TestCase): def test_empty_config(self): with self.assertRaises(Exception): - KeypairSettings(config=dict()) + KeypairSettings(**dict()) def test_name_only(self): settings = KeypairSettings(name='foo') @@ -43,7 +43,7 @@ class KeypairSettingsUnitTests(unittest.TestCase): self.assertIsNone(settings.private_filepath) def test_config_with_name_only(self): - settings = KeypairSettings(config={'name': 'foo'}) + settings = KeypairSettings(**{'name': 'foo'}) self.assertEqual('foo', settings.name) self.assertIsNone(settings.public_filepath) self.assertIsNone(settings.private_filepath) @@ -55,7 +55,8 @@ class KeypairSettingsUnitTests(unittest.TestCase): self.assertIsNone(settings.private_filepath) def test_config_with_name_pub_only(self): - settings = KeypairSettings(config={'name': 'foo', 'public_filepath': '/foo/bar.pub'}) + settings = KeypairSettings( + **{'name': 'foo', 'public_filepath': '/foo/bar.pub'}) self.assertEqual('foo', settings.name) self.assertEqual('/foo/bar.pub', settings.public_filepath) self.assertIsNone(settings.private_filepath) @@ -67,20 +68,23 @@ class KeypairSettingsUnitTests(unittest.TestCase): self.assertEqual('/foo/bar', settings.private_filepath) def test_config_with_name_priv_only(self): - settings = KeypairSettings(config={'name': 'foo', 'private_filepath': '/foo/bar'}) + settings = KeypairSettings( + **{'name': 'foo', 'private_filepath': '/foo/bar'}) self.assertEqual('foo', settings.name) self.assertIsNone(settings.public_filepath) self.assertEqual('/foo/bar', settings.private_filepath) def test_all(self): - settings = KeypairSettings(name='foo', public_filepath='/foo/bar.pub', private_filepath='/foo/bar') + settings = KeypairSettings(name='foo', public_filepath='/foo/bar.pub', + private_filepath='/foo/bar') self.assertEqual('foo', settings.name) self.assertEqual('/foo/bar.pub', settings.public_filepath) self.assertEqual('/foo/bar', settings.private_filepath) def test_config_all(self): - settings = KeypairSettings(config={'name': 'foo', 'public_filepath': '/foo/bar.pub', - 'private_filepath': '/foo/bar'}) + settings = KeypairSettings( + **{'name': 'foo', 'public_filepath': '/foo/bar.pub', + 'private_filepath': '/foo/bar'}) self.assertEqual('foo', settings.name) self.assertEqual('/foo/bar.pub', settings.public_filepath) self.assertEqual('/foo/bar', settings.private_filepath) @@ -126,27 +130,33 @@ class CreateKeypairsTests(OSIntegrationTestCase): Tests the creation of a generated keypair without saving to file :return: """ - self.keypair_creator = OpenStackKeypair(self.os_creds, KeypairSettings(name=self.keypair_name)) + self.keypair_creator = OpenStackKeypair(self.os_creds, KeypairSettings( + name=self.keypair_name)) self.keypair_creator.create() - keypair = nova_utils.keypair_exists(self.nova, self.keypair_creator.get_keypair()) + keypair = nova_utils.keypair_exists(self.nova, + self.keypair_creator.get_keypair()) self.assertEqual(self.keypair_creator.get_keypair(), keypair) def test_create_delete_keypair(self): """ - Tests the creation then deletion of an OpenStack keypair to ensure clean() does not raise an Exception. + Tests the creation then deletion of an OpenStack keypair to ensure + clean() does not raise an Exception. """ # Create Image - self.keypair_creator = OpenStackKeypair(self.os_creds, KeypairSettings(name=self.keypair_name)) + self.keypair_creator = OpenStackKeypair(self.os_creds, KeypairSettings( + name=self.keypair_name)) created_keypair = self.keypair_creator.create() self.assertIsNotNone(created_keypair) # Delete Image manually nova_utils.delete_keypair(self.nova, created_keypair) - self.assertIsNone(nova_utils.get_keypair_by_name(self.nova, self.keypair_name)) + self.assertIsNone( + nova_utils.get_keypair_by_name(self.nova, self.keypair_name)) - # Must not throw an exception when attempting to cleanup non-existent image + # Must not throw an exception when attempting to cleanup non-existent + # image self.keypair_creator.clean() self.assertIsNone(self.keypair_creator.get_keypair()) @@ -156,30 +166,37 @@ class CreateKeypairsTests(OSIntegrationTestCase): :return: """ self.keypair_creator = OpenStackKeypair( - self.os_creds, KeypairSettings(name=self.keypair_name, public_filepath=self.pub_file_path)) + self.os_creds, KeypairSettings(name=self.keypair_name, + public_filepath=self.pub_file_path)) self.keypair_creator.create() - keypair = nova_utils.keypair_exists(self.nova, self.keypair_creator.get_keypair()) + keypair = nova_utils.keypair_exists(self.nova, + self.keypair_creator.get_keypair()) self.assertEqual(self.keypair_creator.get_keypair(), keypair) file_key = open(os.path.expanduser(self.pub_file_path)).read() - self.assertEqual(self.keypair_creator.get_keypair().public_key, file_key) + self.assertEqual(self.keypair_creator.get_keypair().public_key, + file_key) def test_create_keypair_save_both(self): """ - Tests the creation of a generated keypair and saves both private and public key files[ + Tests the creation of a generated keypair and saves both private and + public key files[ :return: """ self.keypair_creator = OpenStackKeypair( - self.os_creds, KeypairSettings(name=self.keypair_name, public_filepath=self.pub_file_path, - private_filepath=self.priv_file_path)) + self.os_creds, KeypairSettings( + name=self.keypair_name, public_filepath=self.pub_file_path, + private_filepath=self.priv_file_path)) self.keypair_creator.create() - keypair = nova_utils.keypair_exists(self.nova, self.keypair_creator.get_keypair()) + keypair = nova_utils.keypair_exists(self.nova, + self.keypair_creator.get_keypair()) self.assertEqual(self.keypair_creator.get_keypair(), keypair) file_key = open(os.path.expanduser(self.pub_file_path)).read() - self.assertEqual(self.keypair_creator.get_keypair().public_key, file_key) + self.assertEqual(self.keypair_creator.get_keypair().public_key, + file_key) self.assertTrue(os.path.isfile(self.priv_file_path)) @@ -189,13 +206,17 @@ class CreateKeypairsTests(OSIntegrationTestCase): :return: """ keys = nova_utils.create_keys() - nova_utils.save_keys_to_files(keys=keys, pub_file_path=self.pub_file_path) + nova_utils.save_keys_to_files(keys=keys, + pub_file_path=self.pub_file_path) self.keypair_creator = OpenStackKeypair( - self.os_creds, KeypairSettings(name=self.keypair_name, public_filepath=self.pub_file_path)) + self.os_creds, KeypairSettings(name=self.keypair_name, + public_filepath=self.pub_file_path)) self.keypair_creator.create() - keypair = nova_utils.keypair_exists(self.nova, self.keypair_creator.get_keypair()) + keypair = nova_utils.keypair_exists(self.nova, + self.keypair_creator.get_keypair()) self.assertEqual(self.keypair_creator.get_keypair(), keypair) file_key = open(os.path.expanduser(self.pub_file_path)).read() - self.assertEqual(self.keypair_creator.get_keypair().public_key, file_key) + self.assertEqual(self.keypair_creator.get_keypair().public_key, + file_key) diff --git a/snaps/openstack/tests/create_network_tests.py b/snaps/openstack/tests/create_network_tests.py index a7f21ad..bf6c629 100644 --- a/snaps/openstack/tests/create_network_tests.py +++ b/snaps/openstack/tests/create_network_tests.py @@ -12,13 +12,15 @@ # 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. -import uuid import unittest +import uuid -from snaps.openstack.create_network import OpenStackNetwork, NetworkSettings, SubnetSettings, PortSettings from snaps.openstack import create_router +from snaps.openstack.create_network import (OpenStackNetwork, NetworkSettings, + SubnetSettings, PortSettings) from snaps.openstack.tests import openstack_tests -from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase, OSComponentTestCase +from snaps.openstack.tests.os_source_file_test import (OSIntegrationTestCase, + OSComponentTestCase) from snaps.openstack.utils import neutron_utils from snaps.openstack.utils.tests import neutron_utils_tests @@ -36,7 +38,7 @@ class NetworkSettingsUnitTests(unittest.TestCase): def test_empty_config(self): with self.assertRaises(Exception): - NetworkSettings(config=dict()) + NetworkSettings(**dict()) def test_name_only(self): settings = NetworkSettings(name='foo') @@ -49,7 +51,7 @@ class NetworkSettingsUnitTests(unittest.TestCase): self.assertEqual(0, len(settings.subnet_settings)) def test_config_with_name_only(self): - settings = NetworkSettings(config={'name': 'foo'}) + settings = NetworkSettings(**{'name': 'foo'}) self.assertEqual('foo', settings.name) self.assertTrue(settings.admin_state_up) self.assertIsNone(settings.shared) @@ -60,8 +62,11 @@ class NetworkSettingsUnitTests(unittest.TestCase): def test_all(self): sub_settings = SubnetSettings(name='foo-subnet', cidr='10.0.0.0/24') - settings = NetworkSettings(name='foo', admin_state_up=False, shared=True, project_name='bar', external=True, - network_type='flat', physical_network='phy', subnet_settings=[sub_settings]) + settings = NetworkSettings(name='foo', admin_state_up=False, + shared=True, project_name='bar', + external=True, + network_type='flat', physical_network='phy', + subnet_settings=[sub_settings]) self.assertEqual('foo', settings.name) self.assertFalse(settings.admin_state_up) self.assertTrue(settings.shared) @@ -73,11 +78,13 @@ class NetworkSettingsUnitTests(unittest.TestCase): self.assertEqual('foo-subnet', settings.subnet_settings[0].name) def test_config_all(self): - settings = NetworkSettings(config={'name': 'foo', 'admin_state_up': False, 'shared': True, - 'project_name': 'bar', 'external': True, 'network_type': 'flat', - 'physical_network': 'phy', - 'subnets': - [{'subnet': {'name': 'foo-subnet', 'cidr': '10.0.0.0/24'}}]}) + settings = NetworkSettings( + **{'name': 'foo', 'admin_state_up': False, 'shared': True, + 'project_name': 'bar', 'external': True, 'network_type': 'flat', + 'physical_network': 'phy', + 'subnets': + [{'subnet': {'name': 'foo-subnet', + 'cidr': '10.0.0.0/24'}}]}) self.assertEqual('foo', settings.name) self.assertFalse(settings.admin_state_up) self.assertTrue(settings.shared) @@ -100,7 +107,7 @@ class SubnetSettingsUnitTests(unittest.TestCase): def test_empty_config(self): with self.assertRaises(Exception): - SubnetSettings(config=dict()) + SubnetSettings(**dict()) def test_name_only(self): with self.assertRaises(Exception): @@ -108,7 +115,7 @@ class SubnetSettingsUnitTests(unittest.TestCase): def test_config_with_name_only(self): with self.assertRaises(Exception): - SubnetSettings(config={'name': 'foo'}) + SubnetSettings(**{'name': 'foo'}) def test_name_cidr_only(self): settings = SubnetSettings(name='foo', cidr='10.0.0.0/24') @@ -128,7 +135,7 @@ class SubnetSettingsUnitTests(unittest.TestCase): self.assertIsNone(settings.ipv6_address_mode) def test_config_with_name_cidr_only(self): - settings = SubnetSettings(config={'name': 'foo', 'cidr': '10.0.0.0/24'}) + settings = SubnetSettings(**{'name': 'foo', 'cidr': '10.0.0.0/24'}) self.assertEqual('foo', settings.name) self.assertEqual('10.0.0.0/24', settings.cidr) self.assertEqual(4, settings.ip_version) @@ -147,10 +154,16 @@ class SubnetSettingsUnitTests(unittest.TestCase): def test_all(self): host_routes = {'destination': '0.0.0.0/0', 'nexthop': '123.456.78.9'} - settings = SubnetSettings(name='foo', cidr='10.0.0.0/24', ip_version=6, project_name='bar-project', - start='10.0.0.2', end='10.0.0.101', gateway_ip='10.0.0.1', enable_dhcp=False, - dns_nameservers=['8.8.8.8'], host_routes=[host_routes], destination='dest', - nexthop='hop', ipv6_ra_mode='dhcpv6-stateful', ipv6_address_mode='slaac') + settings = SubnetSettings(name='foo', cidr='10.0.0.0/24', ip_version=6, + project_name='bar-project', + start='10.0.0.2', end='10.0.0.101', + gateway_ip='10.0.0.1', enable_dhcp=False, + dns_nameservers=['8.8.8.8'], + host_routes=[host_routes], + destination='dest', + nexthop='hop', + ipv6_ra_mode='dhcpv6-stateful', + ipv6_address_mode='slaac') self.assertEqual('foo', settings.name) self.assertEqual('10.0.0.0/24', settings.cidr) self.assertEqual(6, settings.ip_version) @@ -170,12 +183,15 @@ class SubnetSettingsUnitTests(unittest.TestCase): def test_config_all(self): host_routes = {'destination': '0.0.0.0/0', 'nexthop': '123.456.78.9'} - settings = SubnetSettings(config={'name': 'foo', 'cidr': '10.0.0.0/24', 'ip_version': 6, - 'project_name': 'bar-project', 'start': '10.0.0.2', 'end': '10.0.0.101', - 'gateway_ip': '10.0.0.1', 'enable_dhcp': False, - 'dns_nameservers': ['8.8.8.8'], 'host_routes': [host_routes], - 'destination': 'dest', 'nexthop': 'hop', 'ipv6_ra_mode': 'dhcpv6-stateful', - 'ipv6_address_mode': 'slaac'}) + settings = SubnetSettings( + **{'name': 'foo', 'cidr': '10.0.0.0/24', 'ip_version': 6, + 'project_name': 'bar-project', 'start': '10.0.0.2', + 'end': '10.0.0.101', + 'gateway_ip': '10.0.0.1', 'enable_dhcp': False, + 'dns_nameservers': ['8.8.8.8'], 'host_routes': [host_routes], + 'destination': 'dest', 'nexthop': 'hop', + 'ipv6_ra_mode': 'dhcpv6-stateful', + 'ipv6_address_mode': 'slaac'}) self.assertEqual('foo', settings.name) self.assertEqual('10.0.0.0/24', settings.cidr) self.assertEqual(6, settings.ip_version) @@ -205,7 +221,7 @@ class PortSettingsUnitTests(unittest.TestCase): def test_empty_config(self): with self.assertRaises(Exception): - PortSettings(config=dict()) + PortSettings(**dict()) def test_name_only(self): with self.assertRaises(Exception): @@ -213,7 +229,7 @@ class PortSettingsUnitTests(unittest.TestCase): def test_config_name_only(self): with self.assertRaises(Exception): - PortSettings(config={'name': 'foo'}) + PortSettings(**{'name': 'foo'}) def test_name_netname_only(self): settings = PortSettings(name='foo', network_name='bar') @@ -232,7 +248,7 @@ class PortSettingsUnitTests(unittest.TestCase): self.assertIsNone(settings.device_id) def test_config_with_name_netname_only(self): - settings = PortSettings(config={'name': 'foo', 'network_name': 'bar'}) + settings = PortSettings(**{'name': 'foo', 'network_name': 'bar'}) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.network_name) self.assertTrue(settings.admin_state_up) @@ -252,10 +268,15 @@ class PortSettingsUnitTests(unittest.TestCase): fixed_ips = {'sub_id', '10.0.0.10'} allowed_address_pairs = {'10.0.0.101', '1234.5678'} - settings = PortSettings(name='foo', network_name='bar', admin_state_up=False, project_name='foo-project', - mac_address='1234', ip_addrs=ip_addrs, fixed_ips=fixed_ips, - security_groups=['foo_grp_id'], allowed_address_pairs=allowed_address_pairs, - opt_value='opt value', opt_name='opt name', device_owner='owner', + settings = PortSettings(name='foo', network_name='bar', + admin_state_up=False, + project_name='foo-project', + mac_address='1234', ip_addrs=ip_addrs, + fixed_ips=fixed_ips, + security_groups=['foo_grp_id'], + allowed_address_pairs=allowed_address_pairs, + opt_value='opt value', opt_name='opt name', + device_owner='owner', device_id='device number') self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.network_name) @@ -277,11 +298,15 @@ class PortSettingsUnitTests(unittest.TestCase): fixed_ips = {'sub_id', '10.0.0.10'} allowed_address_pairs = {'10.0.0.101', '1234.5678'} - settings = PortSettings(config={'name': 'foo', 'network_name': 'bar', 'admin_state_up': False, - 'project_name': 'foo-project', 'mac_address': '1234', 'ip_addrs': ip_addrs, - 'fixed_ips': fixed_ips, 'security_groups': ['foo_grp_id'], - 'allowed_address_pairs': allowed_address_pairs, 'opt_value': 'opt value', - 'opt_name': 'opt name', 'device_owner': 'owner', 'device_id': 'device number'}) + settings = PortSettings( + **{'name': 'foo', 'network_name': 'bar', 'admin_state_up': False, + 'project_name': 'foo-project', 'mac_address': '1234', + 'ip_addrs': ip_addrs, + 'fixed_ips': fixed_ips, 'security_groups': ['foo_grp_id'], + 'allowed_address_pairs': allowed_address_pairs, + 'opt_value': 'opt value', + 'opt_name': 'opt name', 'device_owner': 'owner', + 'device_id': 'device number'}) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.network_name) self.assertFalse(settings.admin_state_up) @@ -332,13 +357,16 @@ class CreateNetworkSuccessTests(OSIntegrationTestCase): if len(self.net_creator.get_subnets()) > 0: # Validate subnet has been deleted neutron_utils_tests.validate_subnet( - self.neutron, self.net_creator.network_settings.subnet_settings[0].name, - self.net_creator.network_settings.subnet_settings[0].cidr, False) + self.neutron, + self.net_creator.network_settings.subnet_settings[0].name, + self.net_creator.network_settings.subnet_settings[0].cidr, + False) if self.net_creator.get_network(): # Validate network has been deleted - neutron_utils_tests.validate_network(self.neutron, self.net_creator.network_settings.name, - False) + neutron_utils_tests.validate_network( + self.neutron, self.net_creator.network_settings.name, + False) self.net_creator.clean() super(self.__class__, self).__clean__() @@ -348,30 +376,37 @@ class CreateNetworkSuccessTests(OSIntegrationTestCase): Tests the creation of an OpenStack network without a router. """ # Create Nework - self.net_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings) + self.net_creator = OpenStackNetwork(self.os_creds, + self.net_config.network_settings) self.net_creator.create() # Validate network was created - neutron_utils_tests.validate_network(self.neutron, self.net_creator.network_settings.name, True) + neutron_utils_tests.validate_network( + self.neutron, self.net_creator.network_settings.name, True) # Validate subnets neutron_utils_tests.validate_subnet( - self.neutron, self.net_creator.network_settings.subnet_settings[0].name, + self.neutron, + self.net_creator.network_settings.subnet_settings[0].name, self.net_creator.network_settings.subnet_settings[0].cidr, True) def test_create_delete_network(self): """ - Tests the creation of an OpenStack network, it's deletion, then cleanup. + Tests the creation of an OpenStack network, it's deletion, then cleanup """ # Create Nework - self.net_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings) + self.net_creator = OpenStackNetwork(self.os_creds, + self.net_config.network_settings) self.net_creator.create() # Validate network was created - neutron_utils_tests.validate_network(self.neutron, self.net_creator.network_settings.name, True) + neutron_utils_tests.validate_network( + self.neutron, self.net_creator.network_settings.name, True) - neutron_utils.delete_network(self.neutron, self.net_creator.get_network()) - self.assertIsNone(neutron_utils.get_network(self.neutron, self.net_creator.network_settings.name)) + neutron_utils.delete_network(self.neutron, + self.net_creator.get_network()) + self.assertIsNone(neutron_utils.get_network( + self.neutron, self.net_creator.network_settings.name)) # This shall not throw an exception here self.net_creator.clean() @@ -381,38 +416,46 @@ class CreateNetworkSuccessTests(OSIntegrationTestCase): Tests the creation of an OpenStack network with a router. """ # Create Network - self.net_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings) + self.net_creator = OpenStackNetwork(self.os_creds, + self.net_config.network_settings) self.net_creator.create() # Create Router - self.router_creator = create_router.OpenStackRouter(self.os_creds, self.net_config.router_settings) + self.router_creator = create_router.OpenStackRouter( + self.os_creds, self.net_config.router_settings) self.router_creator.create() # Validate network was created - neutron_utils_tests.validate_network(self.neutron, self.net_creator.network_settings.name, True) + neutron_utils_tests.validate_network( + self.neutron, self.net_creator.network_settings.name, True) # Validate subnets neutron_utils_tests.validate_subnet( - self.neutron, self.net_creator.network_settings.subnet_settings[0].name, + self.neutron, + self.net_creator.network_settings.subnet_settings[0].name, self.net_creator.network_settings.subnet_settings[0].cidr, True) # Validate routers - neutron_utils_tests.validate_router(self.neutron, self.router_creator.router_settings.name, True) + neutron_utils_tests.validate_router( + self.neutron, self.router_creator.router_settings.name, True) - neutron_utils_tests.validate_interface_router(self.router_creator.get_internal_router_interface(), - self.router_creator.get_router(), - self.net_creator.get_subnets()[0]) + neutron_utils_tests.validate_interface_router( + self.router_creator.get_internal_router_interface(), + self.router_creator.get_router(), + self.net_creator.get_subnets()[0]) def test_create_networks_same_name(self): """ - Tests the creation of an OpenStack network and ensures that the OpenStackNetwork object will not create - a second. + Tests the creation of an OpenStack network and ensures that the + OpenStackNetwork object will not create a second. """ # Create Nework - self.net_creator = OpenStackNetwork(self.os_creds, self.net_config.network_settings) + self.net_creator = OpenStackNetwork(self.os_creds, + self.net_config.network_settings) self.net_creator.create() - self.net_creator2 = OpenStackNetwork(self.os_creds, self.net_config.network_settings) + self.net_creator2 = OpenStackNetwork(self.os_creds, + self.net_config.network_settings) self.net_creator2.create() self.assertEqual(self.net_creator.get_network()['network']['id'], @@ -421,7 +464,8 @@ class CreateNetworkSuccessTests(OSIntegrationTestCase): class CreateNetworkTypeTests(OSComponentTestCase): """ - Test for the CreateNework class defined in create_nework.py for testing creating networks of different types + Test for the CreateNework class defined in create_nework.py for testing + creating networks of different types """ def setUp(self): @@ -446,14 +490,18 @@ class CreateNetworkTypeTests(OSComponentTestCase): if len(self.net_creator.get_subnets()) > 0: # Validate subnet has been deleted neutron_utils_tests.validate_subnet( - self.neutron, self.net_creator.network_settings.subnet_settings[0].name, - self.net_creator.network_settings.subnet_settings[0].cidr, False) + self.neutron, + self.net_creator.network_settings.subnet_settings[0].name, + self.net_creator.network_settings.subnet_settings[0].cidr, + False) if self.net_creator.get_network(): # Validate network has been deleted - neutron_utils_tests.validate_network(self.neutron, self.net_creator.network_settings.name, - False) + neutron_utils_tests.validate_network( + self.neutron, self.net_creator.network_settings.name, + False) self.net_creator.clean() + # TODO - determine why this is not working on Newton # - Unable to create the network. No tenant network is available for allocation. # def test_create_network_type_vlan(self): @@ -481,18 +529,21 @@ class CreateNetworkTypeTests(OSComponentTestCase): """ # Create Network network_type = 'vxlan' - net_settings = NetworkSettings(name=self.net_config.network_settings.name, - subnet_settings=self.net_config.network_settings.subnet_settings, - network_type=network_type) + net_settings = NetworkSettings( + name=self.net_config.network_settings.name, + subnet_settings=self.net_config.network_settings.subnet_settings, + network_type=network_type) # When setting the network_type, creds must be admin self.net_creator = OpenStackNetwork(self.os_creds, net_settings) network = self.net_creator.create() # Validate network was created - neutron_utils_tests.validate_network(self.neutron, net_settings.name, True) + neutron_utils_tests.validate_network(self.neutron, net_settings.name, + True) - self.assertEqual(network_type, network['network']['provider:network_type']) + self.assertEqual(network_type, + network['network']['provider:network_type']) # TODO - determine what value we need to place into physical_network # - Do not know what vaule to place into the 'physical_network' setting. @@ -521,13 +572,15 @@ class CreateNetworkTypeTests(OSComponentTestCase): def test_create_network_type_foo(self): """ - Tests the creation of an OpenStack network of type foo which should raise an exception. + Tests the creation of an OpenStack network of type foo which should + raise an exception. """ # Create Network network_type = 'foo' - net_settings = NetworkSettings(name=self.net_config.network_settings.name, - subnet_settings=self.net_config.network_settings.subnet_settings, - network_type=network_type) + net_settings = NetworkSettings( + name=self.net_config.network_settings.name, + subnet_settings=self.net_config.network_settings.subnet_settings, + network_type=network_type) self.net_creator = OpenStackNetwork(self.os_creds, net_settings) with self.assertRaises(Exception): self.net_creator.create() diff --git a/snaps/openstack/tests/create_project_tests.py b/snaps/openstack/tests/create_project_tests.py index ede8b4b..068ab95 100644 --- a/snaps/openstack/tests/create_project_tests.py +++ b/snaps/openstack/tests/create_project_tests.py @@ -12,8 +12,8 @@ # 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. -import uuid import unittest +import uuid from snaps.openstack.create_project import OpenStackProject, ProjectSettings from snaps.openstack.create_security_group import OpenStackSecurityGroup @@ -37,7 +37,7 @@ class ProjectSettingsUnitTests(unittest.TestCase): def test_empty_config(self): with self.assertRaises(Exception): - ProjectSettings(config=dict()) + ProjectSettings(**dict()) def test_name_only(self): settings = ProjectSettings(name='foo') @@ -47,21 +47,24 @@ class ProjectSettingsUnitTests(unittest.TestCase): self.assertTrue(settings.enabled) def test_config_with_name_only(self): - settings = ProjectSettings(config={'name': 'foo'}) + settings = ProjectSettings(**{'name': 'foo'}) self.assertEqual('foo', settings.name) self.assertEqual('default', settings.domain) self.assertIsNone(settings.description) self.assertTrue(settings.enabled) def test_all(self): - settings = ProjectSettings(name='foo', domain='bar', description='foobar', enabled=False) + settings = ProjectSettings(name='foo', domain='bar', + description='foobar', enabled=False) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.domain) self.assertEqual('foobar', settings.description) self.assertFalse(settings.enabled) def test_config_all(self): - settings = ProjectSettings(config={'name': 'foo', 'domain': 'bar', 'description': 'foobar', 'enabled': False}) + settings = ProjectSettings( + **{'name': 'foo', 'domain': 'bar', 'description': 'foobar', + 'enabled': False}) self.assertEqual('foo', settings.name) self.assertEqual('bar', settings.domain) self.assertEqual('foobar', settings.description) @@ -75,8 +78,8 @@ class CreateProjectSuccessTests(OSComponentTestCase): def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ guid = str(uuid.uuid4())[:-19] guid = self.__class__.__name__ + '-' + guid @@ -98,35 +101,42 @@ class CreateProjectSuccessTests(OSComponentTestCase): """ Tests the creation of an OpenStack project. """ - self.project_creator = OpenStackProject(self.os_creds, self.project_settings) + self.project_creator = OpenStackProject(self.os_creds, + self.project_settings) created_project = self.project_creator.create() self.assertIsNotNone(created_project) - retrieved_project = keystone_utils.get_project(keystone=self.keystone, project_name=self.project_settings.name) + retrieved_project = keystone_utils.get_project( + keystone=self.keystone, project_name=self.project_settings.name) self.assertIsNotNone(retrieved_project) self.assertEqual(created_project, retrieved_project) def test_create_project_2x(self): """ - Tests the creation of an OpenStack project twice to ensure it only creates one. + Tests the creation of an OpenStack project twice to ensure it only + creates one. """ - self.project_creator = OpenStackProject(self.os_creds, self.project_settings) + self.project_creator = OpenStackProject(self.os_creds, + self.project_settings) created_project = self.project_creator.create() self.assertIsNotNone(created_project) - retrieved_project = keystone_utils.get_project(keystone=self.keystone, project_name=self.project_settings.name) + retrieved_project = keystone_utils.get_project( + keystone=self.keystone, project_name=self.project_settings.name) self.assertIsNotNone(retrieved_project) self.assertEqual(created_project, retrieved_project) - project2 = OpenStackProject(self.os_creds, self.project_settings).create() + project2 = OpenStackProject(self.os_creds, + self.project_settings).create() self.assertEqual(retrieved_project, project2) def test_create_delete_project(self): """ - Tests the creation of an OpenStack project, it's deletion, then cleanup. + Tests the creation of an OpenStack project, it's deletion, then cleanup """ # Create Image - self.project_creator = OpenStackProject(self.os_creds, self.project_settings) + self.project_creator = OpenStackProject(self.os_creds, + self.project_settings) created_project = self.project_creator.create() self.assertIsNotNone(created_project) @@ -146,8 +156,8 @@ class CreateProjectUserTests(OSComponentTestCase): def setUp(self): """ - Instantiates the CreateImage object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateImage object that is responsible for downloading + and creating an OS image file within OpenStack """ guid = str(uuid.uuid4())[:-19] self.guid = self.__class__.__name__ + '-' + guid @@ -176,61 +186,79 @@ class CreateProjectUserTests(OSComponentTestCase): def test_create_project_sec_grp_one_user(self): """ - Tests the creation of an OpenStack object to a project with a new users and to create a security group + Tests the creation of an OpenStack object to a project with a new users + and to create a security group """ - self.project_creator = OpenStackProject(self.os_creds, self.project_settings) + self.project_creator = OpenStackProject(self.os_creds, + self.project_settings) created_project = self.project_creator.create() self.assertIsNotNone(created_project) - user_creator = OpenStackUser(self.os_creds, UserSettings(name=self.guid + '-user', password=self.guid)) + user_creator = OpenStackUser(self.os_creds, + UserSettings(name=self.guid + '-user', + password=self.guid)) self.project_creator.assoc_user(user_creator.create()) self.user_creators.append(user_creator) - sec_grp_os_creds = user_creator.get_os_creds(self.project_creator.get_project().name) + sec_grp_os_creds = user_creator.get_os_creds( + self.project_creator.get_project().name) sec_grp_creator = OpenStackSecurityGroup( - sec_grp_os_creds, SecurityGroupSettings(name=self.guid + '-name', description='hello group')) + sec_grp_os_creds, SecurityGroupSettings(name=self.guid + '-name', + description='hello group')) sec_grp = sec_grp_creator.create() self.assertIsNotNone(sec_grp) self.sec_grp_creators.append(sec_grp_creator) if 'tenant_id' in sec_grp['security_group']: - self.assertEqual(self.project_creator.get_project().id, sec_grp['security_group']['tenant_id']) + self.assertEqual(self.project_creator.get_project().id, + sec_grp['security_group']['tenant_id']) elif 'project_id' in sec_grp['security_group']: - self.assertEqual(self.project_creator.get_project().id, sec_grp['security_group']['project_id']) + self.assertEqual(self.project_creator.get_project().id, + sec_grp['security_group']['project_id']) else: self.fail('Cannot locate the project or tenant ID') def test_create_project_sec_grp_two_users(self): """ - Tests the creation of an OpenStack object to a project with two new users and use each user to create a - security group + Tests the creation of an OpenStack object to a project with two new + users and use each user to create a security group """ - self.project_creator = OpenStackProject(self.os_creds, self.project_settings) + self.project_creator = OpenStackProject(self.os_creds, + self.project_settings) created_project = self.project_creator.create() self.assertIsNotNone(created_project) - user_creator_1 = OpenStackUser(self.os_creds, UserSettings(name=self.guid + '-user1', password=self.guid)) + user_creator_1 = OpenStackUser(self.os_creds, + UserSettings(name=self.guid + '-user1', + password=self.guid)) self.project_creator.assoc_user(user_creator_1.create()) self.user_creators.append(user_creator_1) - user_creator_2 = OpenStackUser(self.os_creds, UserSettings(name=self.guid + '-user2', password=self.guid)) + user_creator_2 = OpenStackUser(self.os_creds, + UserSettings(name=self.guid + '-user2', + password=self.guid)) self.project_creator.assoc_user(user_creator_2.create()) self.user_creators.append(user_creator_2) ctr = 0 for user_creator in self.user_creators: ctr += 1 - sec_grp_os_creds = user_creator.get_os_creds(self.project_creator.get_project().name) + sec_grp_os_creds = user_creator.get_os_creds( + self.project_creator.get_project().name) sec_grp_creator = OpenStackSecurityGroup( - sec_grp_os_creds, SecurityGroupSettings(name=self.guid + '-name', description='hello group')) + sec_grp_os_creds, + SecurityGroupSettings(name=self.guid + '-name', + description='hello group')) sec_grp = sec_grp_creator.create() self.assertIsNotNone(sec_grp) self.sec_grp_creators.append(sec_grp_creator) if 'tenant_id' in sec_grp['security_group']: - self.assertEqual(self.project_creator.get_project().id, sec_grp['security_group']['tenant_id']) + self.assertEqual(self.project_creator.get_project().id, + sec_grp['security_group']['tenant_id']) elif 'project_id' in sec_grp['security_group']: - self.assertEqual(self.project_creator.get_project().id, sec_grp['security_group']['project_id']) + self.assertEqual(self.project_creator.get_project().id, + sec_grp['security_group']['project_id']) else: self.fail('Cannot locate the project or tenant ID') diff --git a/snaps/openstack/tests/create_router_tests.py b/snaps/openstack/tests/create_router_tests.py index 3e22714..bd2588a 100644 --- a/snaps/openstack/tests/create_router_tests.py +++ b/snaps/openstack/tests/create_router_tests.py @@ -19,8 +19,8 @@ from snaps.openstack import create_network from snaps.openstack import create_router from snaps.openstack.create_network import NetworkSettings from snaps.openstack.create_network import OpenStackNetwork -from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase from snaps.openstack.create_router import RouterSettings +from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase from snaps.openstack.utils import neutron_utils __author__ = 'mmakati' @@ -33,7 +33,8 @@ static_gateway_ip2 = '10.200.202.1' class CreateRouterSuccessTests(OSIntegrationTestCase): """ - Class for testing routers with various positive scenarios expected to succeed + Class for testing routers with various positive scenarios expected to + succeed """ def setUp(self): @@ -67,31 +68,40 @@ class CreateRouterSuccessTests(OSIntegrationTestCase): """ Test creation of a most basic router with minimal options. """ - router_settings = RouterSettings(name=self.guid + '-pub-router', external_gateway=self.ext_net_name) + router_settings = RouterSettings(name=self.guid + '-pub-router', + external_gateway=self.ext_net_name) - self.router_creator = create_router.OpenStackRouter(self.os_creds, router_settings) + self.router_creator = create_router.OpenStackRouter(self.os_creds, + router_settings) self.router_creator.create() - router = neutron_utils.get_router_by_name(self.neutron, router_settings.name) + router = neutron_utils.get_router_by_name(self.neutron, + router_settings.name) self.assertIsNotNone(router) - self.assertTrue(verify_router_attributes(router, self.router_creator, ext_gateway=self.ext_net_name)) + self.assertTrue(verify_router_attributes( + router, self.router_creator, ext_gateway=self.ext_net_name)) def test_create_delete_router(self): """ - Test that clean() will not raise an exception if the router is deleted by another process. + Test that clean() will not raise an exception if the router is deleted + by another process. """ - self.router_settings = RouterSettings(name=self.guid + '-pub-router', external_gateway=self.ext_net_name) + self.router_settings = RouterSettings( + name=self.guid + '-pub-router', external_gateway=self.ext_net_name) - self.router_creator = create_router.OpenStackRouter(self.os_creds, self.router_settings) + self.router_creator = create_router.OpenStackRouter( + self.os_creds, self.router_settings) created_router = self.router_creator.create() self.assertIsNotNone(created_router) - retrieved_router = neutron_utils.get_router_by_name(self.neutron, self.router_settings.name) + retrieved_router = neutron_utils.get_router_by_name( + self.neutron, self.router_settings.name) self.assertIsNotNone(retrieved_router) neutron_utils.delete_router(self.neutron, created_router) - retrieved_router = neutron_utils.get_router_by_name(self.neutron, self.router_settings.name) + retrieved_router = neutron_utils.get_router_by_name( + self.neutron, self.router_settings.name) self.assertIsNone(retrieved_router) # Should not raise an exception @@ -101,90 +111,118 @@ class CreateRouterSuccessTests(OSIntegrationTestCase): """ Test creation of a basic router with admin state down. """ - router_settings = RouterSettings(name=self.guid + '-pub-router', admin_state_up=False) + router_settings = RouterSettings(name=self.guid + '-pub-router', + admin_state_up=False) - self.router_creator = create_router.OpenStackRouter(self.os_creds, router_settings) + self.router_creator = create_router.OpenStackRouter(self.os_creds, + router_settings) self.router_creator.create() - router = neutron_utils.get_router_by_name(self.neutron, router_settings.name) + router = neutron_utils.get_router_by_name(self.neutron, + router_settings.name) self.assertIsNotNone(router) - self.assertTrue(verify_router_attributes(router, self.router_creator, admin_state=False)) + self.assertTrue(verify_router_attributes(router, self.router_creator, + admin_state=False)) def test_create_router_admin_state_True(self): """ Test creation of a basic router with admin state Up. """ - router_settings = RouterSettings(name=self.guid + '-pub-router', admin_state_up=True) + router_settings = RouterSettings(name=self.guid + '-pub-router', + admin_state_up=True) - self.router_creator = create_router.OpenStackRouter(self.os_creds, router_settings) + self.router_creator = create_router.OpenStackRouter(self.os_creds, + router_settings) self.router_creator.create() - router = neutron_utils.get_router_by_name(self.neutron, router_settings.name) + router = neutron_utils.get_router_by_name(self.neutron, + router_settings.name) self.assertIsNotNone(router) - self.assertTrue(verify_router_attributes(router, self.router_creator, admin_state=True)) + self.assertTrue(verify_router_attributes(router, self.router_creator, + admin_state=True)) def test_create_router_private_network(self): """ - Test creation of a router connected with two private networks and no external gateway + Test creation of a router connected with two private networks and no + external gateway """ - network_settings1 = NetworkSettings(name=self.guid + '-pub-net1', - subnet_settings=[ - create_network.SubnetSettings(cidr=cidr1, - name=self.guid + '-pub-subnet1', - gateway_ip=static_gateway_ip1)]) - network_settings2 = NetworkSettings(name=self.guid + '-pub-net2', - subnet_settings=[ - create_network.SubnetSettings(cidr=cidr2, - name=self.guid + '-pub-subnet2', - gateway_ip=static_gateway_ip2)]) - - self.network_creator1 = OpenStackNetwork(self.os_creds, network_settings1) - self.network_creator2 = OpenStackNetwork(self.os_creds, network_settings2) + network_settings1 = NetworkSettings( + name=self.guid + '-pub-net1', + subnet_settings=[ + create_network.SubnetSettings( + cidr=cidr1, name=self.guid + '-pub-subnet1', + gateway_ip=static_gateway_ip1)]) + network_settings2 = NetworkSettings( + name=self.guid + '-pub-net2', + subnet_settings=[ + create_network.SubnetSettings( + cidr=cidr2, name=self.guid + '-pub-subnet2', + gateway_ip=static_gateway_ip2)]) + + self.network_creator1 = OpenStackNetwork(self.os_creds, + network_settings1) + self.network_creator2 = OpenStackNetwork(self.os_creds, + network_settings2) self.network_creator1.create() self.network_creator2.create() - port_settings = [create_network.PortSettings(name=self.guid + '-port1', ip_addrs=[ - {'subnet_name': network_settings1.subnet_settings[0].name, 'ip': static_gateway_ip1}], - network_name=network_settings1.name) - , create_network.PortSettings(name=self.guid + '-port2', ip_addrs=[ - {'subnet_name': network_settings2.subnet_settings[0].name, 'ip': static_gateway_ip2}], + port_settings = [ + create_network.PortSettings(name=self.guid + '-port1', ip_addrs=[ + {'subnet_name': network_settings1.subnet_settings[0].name, + 'ip': static_gateway_ip1}], + network_name=network_settings1.name), + create_network.PortSettings(name=self.guid + '-port2', ip_addrs=[ + {'subnet_name': network_settings2.subnet_settings[0].name, + 'ip': static_gateway_ip2}], network_name=network_settings2.name)] - router_settings = RouterSettings(name=self.guid + '-pub-router', port_settings=port_settings) - self.router_creator = create_router.OpenStackRouter(self.os_creds, router_settings) + router_settings = RouterSettings(name=self.guid + '-pub-router', + port_settings=port_settings) + self.router_creator = create_router.OpenStackRouter(self.os_creds, + router_settings) self.router_creator.create() - router = neutron_utils.get_router_by_name(self.neutron, router_settings.name) + router = neutron_utils.get_router_by_name(self.neutron, + router_settings.name) self.assertTrue(verify_router_attributes(router, self.router_creator)) def test_create_router_external_network(self): """ - Test creation of a router connected to an external network and a private network. + Test creation of a router connected to an external network and a + private network. """ - network_settings = NetworkSettings(name=self.guid + '-pub-net1', - subnet_settings=[ - create_network.SubnetSettings(cidr=cidr1, - name=self.guid + '-pub-subnet1', - gateway_ip=static_gateway_ip1)]) - self.network_creator1 = OpenStackNetwork(self.os_creds, network_settings) + network_settings = NetworkSettings( + name=self.guid + '-pub-net1', + subnet_settings=[ + create_network.SubnetSettings( + cidr=cidr1, name=self.guid + '-pub-subnet1', + gateway_ip=static_gateway_ip1)]) + self.network_creator1 = OpenStackNetwork(self.os_creds, + network_settings) self.network_creator1.create() - port_settings = [create_network.PortSettings(name=self.guid + '-port1', ip_addrs=[ - {'subnet_name': network_settings.subnet_settings[0].name, 'ip': static_gateway_ip1}], - network_name=network_settings.name)] + port_settings = [ + create_network.PortSettings(name=self.guid + '-port1', ip_addrs=[ + {'subnet_name': network_settings.subnet_settings[0].name, + 'ip': static_gateway_ip1}], + network_name=network_settings.name)] router_settings = RouterSettings(name=self.guid + '-pub-router', - external_gateway=self.ext_net_name, port_settings=port_settings) - self.router_creator = create_router.OpenStackRouter(self.os_creds, router_settings) + external_gateway=self.ext_net_name, + port_settings=port_settings) + self.router_creator = create_router.OpenStackRouter(self.os_creds, + router_settings) self.router_creator.create() - router = neutron_utils.get_router_by_name(self.neutron, router_settings.name) + router = neutron_utils.get_router_by_name(self.neutron, + router_settings.name) - self.assertTrue(verify_router_attributes(router, self.router_creator, ext_gateway=self.ext_net_name)) + self.assertTrue(verify_router_attributes( + router, self.router_creator, ext_gateway=self.ext_net_name)) class CreateRouterNegativeTests(OSIntegrationTestCase): @@ -215,8 +253,10 @@ class CreateRouterNegativeTests(OSIntegrationTestCase): Test creating a router without a name. """ with self.assertRaises(Exception): - router_settings = RouterSettings(name=None, external_gateway=self.ext_net_name) - self.router_creator = create_router.OpenStackRouter(self.os_creds, router_settings) + router_settings = RouterSettings( + name=None, external_gateway=self.ext_net_name) + self.router_creator = create_router.OpenStackRouter( + self.os_creds, router_settings) self.router_creator.create() def test_create_router_invalid_gateway_name(self): @@ -224,18 +264,23 @@ class CreateRouterNegativeTests(OSIntegrationTestCase): Test creating a router without a valid network gateway name. """ with self.assertRaises(Exception): - router_settings = RouterSettings(name=self.guid + '-pub-router', external_gateway="Invalid_name") - self.router_creator = create_router.OpenStackRouter(self.os_creds, router_settings) + router_settings = RouterSettings(name=self.guid + '-pub-router', + external_gateway="Invalid_name") + self.router_creator = create_router.OpenStackRouter( + self.os_creds, router_settings) self.router_creator.create() -def verify_router_attributes(router_operational, router_creator, admin_state=True, ext_gateway=None): +def verify_router_attributes(router_operational, router_creator, + admin_state=True, ext_gateway=None): """ - Helper function to validate the attributes of router created with the one operational - :param router_operational: Operational Router object returned from neutron utils - :param router_creator: router_creator object returned from creating a router in the router test functions + Helper function to validate the attributes of router created with the one + operational + :param router_operational: Operational Router object returned from neutron + utils + :param router_creator: router_creator object returned from creating a + router in the router test functions :param admin_state: True if router is expected to be Up, else False - :param snat: True is enable_snat is True, else False :param ext_gateway: None if router is not connected to external gateway :return: """ @@ -246,7 +291,8 @@ def verify_router_attributes(router_operational, router_creator, admin_state=Tru return False elif not router_creator: return False - elif not (router_operational['router']['name'] == router_creator.router_settings.name): + elif not (router_operational['router'][ + 'name'] == router_creator.router_settings.name): return False elif not (router_operational['router']['id'] == router['router']['id']): return False @@ -256,7 +302,8 @@ def verify_router_attributes(router_operational, router_creator, admin_state=Tru return False elif not (admin_state == router_operational['router']['admin_state_up']): return False - elif (ext_gateway is None) and (router_operational['router']['external_gateway_info'] is not None): + elif (ext_gateway is None) and \ + (router_operational['router']['external_gateway_info'] is not None): return False elif ext_gateway is not None: if router_operational['router']['external_gateway_info'] is None: diff --git a/snaps/openstack/tests/create_security_group_tests.py b/snaps/openstack/tests/create_security_group_tests.py index 6a3c0ef..8fd8a6a 100644 --- a/snaps/openstack/tests/create_security_group_tests.py +++ b/snaps/openstack/tests/create_security_group_tests.py @@ -12,12 +12,14 @@ # 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. -import uuid import unittest +import uuid from snaps.openstack import create_security_group -from snaps.openstack.create_security_group import SecurityGroupSettings, SecurityGroupRuleSettings, Direction, \ - Ethertype, Protocol +from snaps.openstack.create_security_group import (SecurityGroupSettings, + SecurityGroupRuleSettings, + Direction, Ethertype, + Protocol) from snaps.openstack.tests import validation_utils from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase from snaps.openstack.utils import neutron_utils @@ -36,7 +38,7 @@ class SecurityGroupRuleSettingsUnitTests(unittest.TestCase): def test_empty_config(self): with self.assertRaises(Exception): - SecurityGroupRuleSettings(config=dict()) + SecurityGroupRuleSettings(**dict()) def test_name_only(self): with self.assertRaises(Exception): @@ -44,22 +46,26 @@ class SecurityGroupRuleSettingsUnitTests(unittest.TestCase): def test_config_with_name_only(self): with self.assertRaises(Exception): - SecurityGroupRuleSettings(config={'sec_grp_name': 'foo'}) + SecurityGroupRuleSettings(**{'sec_grp_name': 'foo'}) def test_name_and_direction(self): - settings = SecurityGroupRuleSettings(sec_grp_name='foo', direction=Direction.ingress) + settings = SecurityGroupRuleSettings(sec_grp_name='foo', + direction=Direction.ingress) self.assertEqual('foo', settings.sec_grp_name) self.assertEqual(Direction.ingress, settings.direction) def test_config_name_and_direction(self): - settings = SecurityGroupRuleSettings(config={'sec_grp_name': 'foo', 'direction': 'ingress'}) + settings = SecurityGroupRuleSettings( + **{'sec_grp_name': 'foo', 'direction': 'ingress'}) self.assertEqual('foo', settings.sec_grp_name) self.assertEqual(Direction.ingress, settings.direction) def test_all(self): settings = SecurityGroupRuleSettings( - sec_grp_name='foo', description='fubar', direction=Direction.egress, remote_group_id='rgi', - protocol=Protocol.icmp, ethertype=Ethertype.IPv6, port_range_min=1, port_range_max=2, + sec_grp_name='foo', description='fubar', + direction=Direction.egress, remote_group_id='rgi', + protocol=Protocol.icmp, ethertype=Ethertype.IPv6, port_range_min=1, + port_range_max=2, remote_ip_prefix='prfx') self.assertEqual('foo', settings.sec_grp_name) self.assertEqual('fubar', settings.description) @@ -73,15 +79,15 @@ class SecurityGroupRuleSettingsUnitTests(unittest.TestCase): def test_config_all(self): settings = SecurityGroupRuleSettings( - config={'sec_grp_name': 'foo', - 'description': 'fubar', - 'direction': 'egress', - 'remote_group_id': 'rgi', - 'protocol': 'tcp', - 'ethertype': 'IPv6', - 'port_range_min': 1, - 'port_range_max': 2, - 'remote_ip_prefix': 'prfx'}) + **{'sec_grp_name': 'foo', + 'description': 'fubar', + 'direction': 'egress', + 'remote_group_id': 'rgi', + 'protocol': 'tcp', + 'ethertype': 'IPv6', + 'port_range_min': 1, + 'port_range_max': 2, + 'remote_ip_prefix': 'prfx'}) self.assertEqual('foo', settings.sec_grp_name) self.assertEqual('fubar', settings.description) self.assertEqual(Direction.egress, settings.direction) @@ -104,27 +110,31 @@ class SecurityGroupSettingsUnitTests(unittest.TestCase): def test_empty_config(self): with self.assertRaises(Exception): - SecurityGroupSettings(config=dict()) + SecurityGroupSettings(**dict()) def test_name_only(self): settings = SecurityGroupSettings(name='foo') self.assertEqual('foo', settings.name) def test_config_with_name_only(self): - settings = SecurityGroupSettings(config={'name': 'foo'}) + settings = SecurityGroupSettings(**{'name': 'foo'}) self.assertEqual('foo', settings.name) def test_invalid_rule(self): - rule_setting = SecurityGroupRuleSettings(sec_grp_name='bar', direction=Direction.ingress) + rule_setting = SecurityGroupRuleSettings(sec_grp_name='bar', + direction=Direction.ingress) with self.assertRaises(Exception): SecurityGroupSettings(name='foo', rule_settings=[rule_setting]) def test_all(self): rule_settings = list() - rule_settings.append(SecurityGroupRuleSettings(sec_grp_name='bar', direction=Direction.egress)) - rule_settings.append(SecurityGroupRuleSettings(sec_grp_name='bar', direction=Direction.ingress)) + rule_settings.append(SecurityGroupRuleSettings( + sec_grp_name='bar', direction=Direction.egress)) + rule_settings.append(SecurityGroupRuleSettings( + sec_grp_name='bar', direction=Direction.ingress)) settings = SecurityGroupSettings( - name='bar', description='fubar', project_name='foo', rule_settings=rule_settings) + name='bar', description='fubar', project_name='foo', + rule_settings=rule_settings) self.assertEqual('bar', settings.name) self.assertEqual('fubar', settings.description) @@ -134,17 +144,19 @@ class SecurityGroupSettingsUnitTests(unittest.TestCase): def test_config_all(self): settings = SecurityGroupSettings( - config={'name': 'bar', - 'description': 'fubar', - 'project_name': 'foo', - 'rules': [{'sec_grp_name': 'bar', 'direction': 'ingress'}]}) + **{'name': 'bar', + 'description': 'fubar', + 'project_name': 'foo', + 'rules': [ + {'sec_grp_name': 'bar', 'direction': 'ingress'}]}) self.assertEqual('bar', settings.name) self.assertEqual('fubar', settings.description) self.assertEqual('foo', settings.project_name) self.assertEqual(1, len(settings.rule_settings)) self.assertEqual('bar', settings.rule_settings[0].sec_grp_name) - self.assertEqual(Direction.ingress, settings.rule_settings[0].direction) + self.assertEqual(Direction.ingress, + settings.rule_settings[0].direction) class CreateSecurityGroupTests(OSIntegrationTestCase): @@ -154,8 +166,8 @@ class CreateSecurityGroupTests(OSIntegrationTestCase): def setUp(self): """ - Instantiates the CreateSecurityGroup object that is responsible for downloading and creating an OS image file - within OpenStack + Instantiates the CreateSecurityGroup object that is responsible for + downloading and creating an OS image file within OpenStack """ super(self.__class__, self).__start__() @@ -180,176 +192,232 @@ class CreateSecurityGroupTests(OSIntegrationTestCase): Tests the creation of an OpenStack Security Group without custom rules. """ # Create Image - sec_grp_settings = SecurityGroupSettings(name=self.sec_grp_name, description='hello group') - self.sec_grp_creator = create_security_group.OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_settings = SecurityGroupSettings(name=self.sec_grp_name, + description='hello group') + self.sec_grp_creator = create_security_group.OpenStackSecurityGroup( + self.os_creds, sec_grp_settings) self.sec_grp_creator.create() - sec_grp = neutron_utils.get_security_group(self.neutron, self.sec_grp_name) + sec_grp = neutron_utils.get_security_group(self.neutron, + self.sec_grp_name) self.assertIsNotNone(sec_grp) - validation_utils.objects_equivalent(self.sec_grp_creator.get_security_group(), sec_grp) - rules = neutron_utils.get_rules_by_security_group(self.neutron, self.sec_grp_creator.get_security_group()) + validation_utils.objects_equivalent( + self.sec_grp_creator.get_security_group(), sec_grp) + rules = neutron_utils.get_rules_by_security_group( + self.neutron, self.sec_grp_creator.get_security_group()) self.assertEqual(len(self.sec_grp_creator.get_rules()), len(rules)) - validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), rules) + validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), + rules) def test_create_delete_group(self): """ Tests the creation of an OpenStack Security Group without custom rules. """ # Create Image - sec_grp_settings = SecurityGroupSettings(name=self.sec_grp_name, description='hello group') - self.sec_grp_creator = create_security_group.OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_settings = SecurityGroupSettings(name=self.sec_grp_name, + description='hello group') + self.sec_grp_creator = create_security_group.OpenStackSecurityGroup( + self.os_creds, sec_grp_settings) created_sec_grp = self.sec_grp_creator.create() self.assertIsNotNone(created_sec_grp) neutron_utils.delete_security_group(self.neutron, created_sec_grp) - self.assertIsNone(neutron_utils.get_security_group(self.neutron, self.sec_grp_creator.sec_grp_settings.name)) + self.assertIsNone(neutron_utils.get_security_group( + self.neutron, self.sec_grp_creator.sec_grp_settings.name)) self.sec_grp_creator.clean() def test_create_group_with_one_simple_rule(self): """ - Tests the creation of an OpenStack Security Group with one simple custom rule. + Tests the creation of an OpenStack Security Group with one simple + custom rule. """ # Create Image sec_grp_rule_settings = list() - sec_grp_rule_settings.append(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, - direction=Direction.ingress)) - sec_grp_settings = SecurityGroupSettings(name=self.sec_grp_name, description='hello group', - rule_settings=sec_grp_rule_settings) - self.sec_grp_creator = create_security_group.OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_rule_settings.append( + SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, + direction=Direction.ingress)) + sec_grp_settings = SecurityGroupSettings( + name=self.sec_grp_name, description='hello group', + rule_settings=sec_grp_rule_settings) + self.sec_grp_creator = create_security_group.OpenStackSecurityGroup( + self.os_creds, sec_grp_settings) self.sec_grp_creator.create() - sec_grp = neutron_utils.get_security_group(self.neutron, self.sec_grp_name) - validation_utils.objects_equivalent(self.sec_grp_creator.get_security_group(), sec_grp) - rules = neutron_utils.get_rules_by_security_group(self.neutron, - self.sec_grp_creator.get_security_group()) + sec_grp = neutron_utils.get_security_group(self.neutron, + self.sec_grp_name) + validation_utils.objects_equivalent( + self.sec_grp_creator.get_security_group(), sec_grp) + rules = neutron_utils.get_rules_by_security_group( + self.neutron, self.sec_grp_creator.get_security_group()) self.assertEqual(len(self.sec_grp_creator.get_rules()), len(rules)) - validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), rules) + validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), + rules) def test_create_group_with_several_rules(self): """ - Tests the creation of an OpenStack Security Group with one simple custom rule. + Tests the creation of an OpenStack Security Group with one simple + custom rule. """ # Create Image sec_grp_rule_settings = list() - sec_grp_rule_settings.append(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, - direction=Direction.ingress)) - sec_grp_rule_settings.append(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, - direction=Direction.egress, - protocol=Protocol.udp, - ethertype=Ethertype.IPv6)) - sec_grp_rule_settings.append(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, - direction=Direction.egress, - protocol=Protocol.udp, - ethertype=Ethertype.IPv4, - port_range_min=10, - port_range_max=20)) - sec_grp_settings = SecurityGroupSettings(name=self.sec_grp_name, description='hello group', - rule_settings=sec_grp_rule_settings) - self.sec_grp_creator = create_security_group.OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_rule_settings.append( + SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, + direction=Direction.ingress)) + sec_grp_rule_settings.append( + SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, + direction=Direction.egress, + protocol=Protocol.udp, + ethertype=Ethertype.IPv6)) + sec_grp_rule_settings.append( + SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, + direction=Direction.egress, + protocol=Protocol.udp, + ethertype=Ethertype.IPv4, + port_range_min=10, + port_range_max=20)) + sec_grp_settings = SecurityGroupSettings( + name=self.sec_grp_name, description='hello group', + rule_settings=sec_grp_rule_settings) + self.sec_grp_creator = create_security_group.OpenStackSecurityGroup( + self.os_creds, sec_grp_settings) self.sec_grp_creator.create() - sec_grp = neutron_utils.get_security_group(self.neutron, self.sec_grp_name) - validation_utils.objects_equivalent(self.sec_grp_creator.get_security_group(), sec_grp) - rules = neutron_utils.get_rules_by_security_group(self.neutron, self.sec_grp_creator.get_security_group()) + sec_grp = neutron_utils.get_security_group(self.neutron, + self.sec_grp_name) + validation_utils.objects_equivalent( + self.sec_grp_creator.get_security_group(), sec_grp) + rules = neutron_utils.get_rules_by_security_group( + self.neutron, self.sec_grp_creator.get_security_group()) self.assertEqual(len(self.sec_grp_creator.get_rules()), len(rules)) - validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), rules) + validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), + rules) def test_add_rule(self): """ - Tests the creation of an OpenStack Security Group with one simple custom rule then adds one after creation. + Tests the creation of an OpenStack Security Group with one simple + custom rule then adds one after creation. """ # Create Image sec_grp_rule_settings = list() - sec_grp_rule_settings.append(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, - direction=Direction.ingress)) - sec_grp_settings = SecurityGroupSettings(name=self.sec_grp_name, description='hello group', - rule_settings=sec_grp_rule_settings) - self.sec_grp_creator = create_security_group.OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_rule_settings.append( + SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, + direction=Direction.ingress)) + sec_grp_settings = SecurityGroupSettings( + name=self.sec_grp_name, description='hello group', + rule_settings=sec_grp_rule_settings) + self.sec_grp_creator = create_security_group.OpenStackSecurityGroup( + self.os_creds, sec_grp_settings) self.sec_grp_creator.create() - sec_grp = neutron_utils.get_security_group(self.neutron, self.sec_grp_name) - validation_utils.objects_equivalent(self.sec_grp_creator.get_security_group(), sec_grp) - rules = neutron_utils.get_rules_by_security_group(self.neutron, - self.sec_grp_creator.get_security_group()) + sec_grp = neutron_utils.get_security_group(self.neutron, + self.sec_grp_name) + validation_utils.objects_equivalent( + self.sec_grp_creator.get_security_group(), sec_grp) + rules = neutron_utils.get_rules_by_security_group( + self.neutron, self.sec_grp_creator.get_security_group()) self.assertEqual(len(self.sec_grp_creator.get_rules()), len(rules)) - validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), rules) - - self.sec_grp_creator.add_rule(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_creator.sec_grp_settings.name, - direction=Direction.egress, protocol=Protocol.icmp)) - rules2 = neutron_utils.get_rules_by_security_group(self.neutron, self.sec_grp_creator.get_security_group()) + validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), + rules) + + self.sec_grp_creator.add_rule(SecurityGroupRuleSettings( + sec_grp_name=self.sec_grp_creator.sec_grp_settings.name, + direction=Direction.egress, protocol=Protocol.icmp)) + rules2 = neutron_utils.get_rules_by_security_group( + self.neutron, self.sec_grp_creator.get_security_group()) self.assertEqual(len(rules) + 1, len(rules2)) def test_remove_rule_by_id(self): """ - Tests the creation of an OpenStack Security Group with two simple custom rules then removes one by the rule ID. + Tests the creation of an OpenStack Security Group with two simple + custom rules then removes one by the rule ID. """ # Create Image sec_grp_rule_settings = list() - sec_grp_rule_settings.append(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, - direction=Direction.ingress)) - sec_grp_rule_settings.append(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, - direction=Direction.egress, - protocol=Protocol.udp, - ethertype=Ethertype.IPv6)) - sec_grp_rule_settings.append(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, - direction=Direction.egress, - protocol=Protocol.udp, - ethertype=Ethertype.IPv4, - port_range_min=10, - port_range_max=20)) - sec_grp_settings = SecurityGroupSettings(name=self.sec_grp_name, description='hello group', - rule_settings=sec_grp_rule_settings) - self.sec_grp_creator = create_security_group.OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_rule_settings.append( + SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, + direction=Direction.ingress)) + sec_grp_rule_settings.append( + SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, + direction=Direction.egress, + protocol=Protocol.udp, + ethertype=Ethertype.IPv6)) + sec_grp_rule_settings.append( + SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, + direction=Direction.egress, + protocol=Protocol.udp, + ethertype=Ethertype.IPv4, + port_range_min=10, + port_range_max=20)) + sec_grp_settings = SecurityGroupSettings( + name=self.sec_grp_name, description='hello group', + rule_settings=sec_grp_rule_settings) + self.sec_grp_creator = create_security_group.OpenStackSecurityGroup( + self.os_creds, sec_grp_settings) self.sec_grp_creator.create() - sec_grp = neutron_utils.get_security_group(self.neutron, self.sec_grp_name) - validation_utils.objects_equivalent(self.sec_grp_creator.get_security_group(), sec_grp) - rules = neutron_utils.get_rules_by_security_group(self.neutron, - self.sec_grp_creator.get_security_group()) + sec_grp = neutron_utils.get_security_group(self.neutron, + self.sec_grp_name) + validation_utils.objects_equivalent( + self.sec_grp_creator.get_security_group(), sec_grp) + rules = neutron_utils.get_rules_by_security_group( + self.neutron, self.sec_grp_creator.get_security_group()) self.assertEqual(len(self.sec_grp_creator.get_rules()), len(rules)) - validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), rules) - - self.sec_grp_creator.remove_rule(rule_id=rules[0]['security_group_rule']['id']) - rules_after_del = neutron_utils.get_rules_by_security_group(self.neutron, - self.sec_grp_creator.get_security_group()) + validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), + rules) + + self.sec_grp_creator.remove_rule( + rule_id=rules[0]['security_group_rule']['id']) + rules_after_del = neutron_utils.get_rules_by_security_group( + self.neutron, + self.sec_grp_creator.get_security_group()) self.assertEqual(len(rules) - 1, len(rules_after_del)) def test_remove_rule_by_setting(self): """ - Tests the creation of an OpenStack Security Group with two simple custom rules then removes one by the rule - setting object + Tests the creation of an OpenStack Security Group with two simple + custom rules then removes one by the rule setting object """ # Create Image sec_grp_rule_settings = list() - sec_grp_rule_settings.append(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, - direction=Direction.ingress)) - sec_grp_rule_settings.append(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, - direction=Direction.egress, - protocol=Protocol.udp, - ethertype=Ethertype.IPv6)) - sec_grp_rule_settings.append(SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, - direction=Direction.egress, - protocol=Protocol.udp, - ethertype=Ethertype.IPv4, - port_range_min=10, - port_range_max=20)) - sec_grp_settings = SecurityGroupSettings(name=self.sec_grp_name, description='hello group', - rule_settings=sec_grp_rule_settings) - self.sec_grp_creator = create_security_group.OpenStackSecurityGroup(self.os_creds, sec_grp_settings) + sec_grp_rule_settings.append( + SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, + direction=Direction.ingress)) + sec_grp_rule_settings.append( + SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, + direction=Direction.egress, + protocol=Protocol.udp, + ethertype=Ethertype.IPv6)) + sec_grp_rule_settings.append( + SecurityGroupRuleSettings(sec_grp_name=self.sec_grp_name, + direction=Direction.egress, + protocol=Protocol.udp, + ethertype=Ethertype.IPv4, + port_range_min=10, + port_range_max=20)) + sec_grp_settings = SecurityGroupSettings( + name=self.sec_grp_name, description='hello group', + rule_settings=sec_grp_rule_settings) + self.sec_grp_creator = create_security_group.OpenStackSecurityGroup( + self.os_creds, sec_grp_settings) self.sec_grp_creator.create() - sec_grp = neutron_utils.get_security_group(self.neutron, self.sec_grp_name) - validation_utils.objects_equivalent(self.sec_grp_creator.get_security_group(), sec_grp) - rules = neutron_utils.get_rules_by_security_group(self.neutron, - self.sec_grp_creator.get_security_group()) + sec_grp = neutron_utils.get_security_group(self.neutron, + self.sec_grp_name) + validation_utils.objects_equivalent( + self.sec_grp_creator.get_security_group(), sec_grp) + rules = neutron_utils.get_rules_by_security_group( + self.neutron, self.sec_grp_creator.get_security_group()) self.assertEqual(len(self.sec_grp_creator.get_rules()), len(rules)) - validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), rules) + validation_utils.objects_equivalent(self.sec_grp_creator.get_rules(), + rules) self.sec_grp_creator.remove_rule(rule_setting=sec_grp_rule_settings[0]) - rules_after_del = neutron_utils.get_rules_by_security_group(self.neutron, - self.sec_grp_creator.get_security_group()) + rules_after_del = neutron_utils.get_rules_by_security_group( + self.neutron, + self.sec_grp_creator.get_security_group()) self.assertEqual(len(rules) - 1, len(rules_after_del)) -# TODO - Add more tests with different rules. Rule creation parameters can be somewhat complex +# TODO - Add more tests with different rules. Rule creation parameters can be +# somewhat complex diff --git a/snaps/openstack/tests/create_stack_tests.py b/snaps/openstack/tests/create_stack_tests.py index e665f82..626fc97 100644 --- a/snaps/openstack/tests/create_stack_tests.py +++ b/snaps/openstack/tests/create_stack_tests.py @@ -12,14 +12,12 @@ # 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. -import pkg_resources import time +import pkg_resources from heatclient.exc import HTTPBadRequest from snaps import file_utils - from snaps.openstack.create_flavor import OpenStackFlavor, FlavorSettings - from snaps.openstack.create_image import OpenStackImage try: @@ -46,13 +44,14 @@ class StackSettingsUnitTests(unittest.TestCase): """ Tests the construction of the StackSettings class """ + def test_no_params(self): with self.assertRaises(StackSettingsError): StackSettings() def test_empty_config(self): with self.assertRaises(StackSettingsError): - StackSettings(config=dict()) + StackSettings(**dict()) def test_name_only(self): with self.assertRaises(StackSettingsError): @@ -60,23 +59,25 @@ class StackSettingsUnitTests(unittest.TestCase): def test_config_with_name_only(self): with self.assertRaises(StackSettingsError): - StackSettings(config={'name': 'foo'}) + StackSettings(**{'name': 'foo'}) def test_config_minimum_template(self): - settings = StackSettings(config={'name': 'stack', 'template': 'foo'}) + settings = StackSettings(**{'name': 'stack', 'template': 'foo'}) self.assertEqual('stack', settings.name) self.assertEqual('foo', settings.template) self.assertIsNone(settings.template_path) self.assertIsNone(settings.env_values) - self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, settings.stack_create_timeout) + self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, + settings.stack_create_timeout) def test_config_minimum_template_path(self): - settings = StackSettings(config={'name': 'stack', 'template_path': 'foo'}) + settings = StackSettings(**{'name': 'stack', 'template_path': 'foo'}) self.assertEqual('stack', settings.name) self.assertIsNone(settings.template) self.assertEqual('foo', settings.template_path) self.assertIsNone(settings.env_values) - self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, settings.stack_create_timeout) + self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, + settings.stack_create_timeout) def test_minimum_template(self): settings = StackSettings(name='stack', template='foo') @@ -84,7 +85,8 @@ class StackSettingsUnitTests(unittest.TestCase): self.assertEqual('foo', settings.template) self.assertIsNone(settings.template_path) self.assertIsNone(settings.env_values) - self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, settings.stack_create_timeout) + self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, + settings.stack_create_timeout) def test_minimum_template_path(self): settings = StackSettings(name='stack', template_path='foo') @@ -92,11 +94,13 @@ class StackSettingsUnitTests(unittest.TestCase): self.assertEqual('foo', settings.template_path) self.assertIsNone(settings.template) self.assertIsNone(settings.env_values) - self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, settings.stack_create_timeout) + self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, + settings.stack_create_timeout) def test_all(self): env_values = {'foo': 'bar'} - settings = StackSettings(name='stack', template='bar', template_path='foo', env_values=env_values, + settings = StackSettings(name='stack', template='bar', + template_path='foo', env_values=env_values, stack_create_timeout=999) self.assertEqual('stack', settings.name) self.assertEqual('bar', settings.template) @@ -107,8 +111,8 @@ class StackSettingsUnitTests(unittest.TestCase): def test_config_all(self): env_values = {'foo': 'bar'} settings = StackSettings( - config={'name': 'stack', 'template': 'bar', 'template_path': 'foo', - 'env_values': env_values, 'stack_create_timeout': 999}) + **{'name': 'stack', 'template': 'bar', 'template_path': 'foo', + 'env_values': env_values, 'stack_create_timeout': 999}) self.assertEqual('stack', settings.name) self.assertEqual('bar', settings.template) self.assertEqual('foo', settings.template_path) @@ -123,8 +127,8 @@ class CreateStackSuccessTests(OSIntegrationTestCase): def setUp(self): """ - Instantiates the CreateStack object that is responsible for downloading and creating an OS stack file - within OpenStack + Instantiates the CreateStack object that is responsible for downloading + and creating an OS stack file within OpenStack """ super(self.__class__, self).__start__() @@ -134,17 +138,20 @@ class CreateStackSuccessTests(OSIntegrationTestCase): self.image_creator = OpenStackImage( self.os_creds, openstack_tests.cirros_image_settings( - name=self.__class__.__name__ + '-' + str(self.guid) + '-image', image_metadata=self.image_metadata)) + name=self.__class__.__name__ + '-' + str(self.guid) + '-image', + image_metadata=self.image_metadata)) self.image_creator.create() # Create Flavor self.flavor_creator = OpenStackFlavor( self.admin_os_creds, - FlavorSettings(name=self.guid + '-flavor-name', ram=128, disk=10, vcpus=1)) + FlavorSettings(name=self.guid + '-flavor-name', ram=128, disk=10, + vcpus=1)) self.flavor_creator.create() - self.env_values = {'image_name': self.image_creator.image_settings.name, - 'flavor_name': self.flavor_creator.flavor_settings.name} + self.env_values = { + 'image_name': self.image_creator.image_settings.name, + 'flavor_name': self.flavor_creator.flavor_settings.name} self.heat_tmplt_path = pkg_resources.resource_filename( 'snaps.openstack.tests.heat', 'test_heat_template.yaml') @@ -178,15 +185,19 @@ class CreateStackSuccessTests(OSIntegrationTestCase): Tests the creation of an OpenStack stack from Heat template file. """ # Create Stack - # Set the default stack settings, then set any custom parameters sent from the app - stack_settings = StackSettings(name=self.__class__.__name__ + '-' + str(self.guid) + '-stack', - template_path=self.heat_tmplt_path, - env_values=self.env_values) - self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings) + # Set the default stack settings, then set any custom parameters sent + # from the app + stack_settings = StackSettings( + name=self.__class__.__name__ + '-' + str(self.guid) + '-stack', + template_path=self.heat_tmplt_path, + env_values=self.env_values) + self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, + stack_settings) created_stack = self.stack_creator.create() self.assertIsNotNone(created_stack) - retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, created_stack.id) + retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, + created_stack.id) self.assertIsNotNone(retrieved_stack) self.assertEqual(created_stack.name, retrieved_stack.name) self.assertEqual(created_stack.id, retrieved_stack.id) @@ -198,17 +209,21 @@ class CreateStackSuccessTests(OSIntegrationTestCase): Tests the creation of an OpenStack stack from a heat dict() object. """ # Create Stack - # Set the default stack settings, then set any custom parameters sent from the app + # Set the default stack settings, then set any custom parameters sent + # from the app template_dict = heat_utils.parse_heat_template_str( file_utils.read_file(self.heat_tmplt_path)) - stack_settings = StackSettings(name=self.__class__.__name__ + '-' + str(self.guid) + '-stack', - template=template_dict, - env_values=self.env_values) - self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings) + stack_settings = StackSettings( + name=self.__class__.__name__ + '-' + str(self.guid) + '-stack', + template=template_dict, + env_values=self.env_values) + self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, + stack_settings) created_stack = self.stack_creator.create() self.assertIsNotNone(created_stack) - retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, created_stack.id) + retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, + created_stack.id) self.assertIsNotNone(retrieved_stack) self.assertEqual(created_stack.name, retrieved_stack.name) self.assertEqual(created_stack.id, retrieved_stack.id) @@ -217,25 +232,30 @@ class CreateStackSuccessTests(OSIntegrationTestCase): def test_create_delete_stack(self): """ - Tests the creation then deletion of an OpenStack stack to ensure clean() does not raise an Exception. + Tests the creation then deletion of an OpenStack stack to ensure + clean() does not raise an Exception. """ # Create Stack template_dict = heat_utils.parse_heat_template_str( file_utils.read_file(self.heat_tmplt_path)) - stack_settings = StackSettings(name=self.__class__.__name__ + '-' + str(self.guid) + '-stack', - template=template_dict, - env_values=self.env_values) - self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings) + stack_settings = StackSettings( + name=self.__class__.__name__ + '-' + str(self.guid) + '-stack', + template=template_dict, + env_values=self.env_values) + self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, + stack_settings) created_stack = self.stack_creator.create() self.assertIsNotNone(created_stack) - retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, created_stack.id) + retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, + created_stack.id) self.assertIsNotNone(retrieved_stack) self.assertEqual(created_stack.name, retrieved_stack.name) self.assertEqual(created_stack.id, retrieved_stack.id) self.assertIsNotNone(self.stack_creator.get_outputs()) self.assertEquals(0, len(self.stack_creator.get_outputs())) - self.assertEqual(create_stack.STATUS_CREATE_COMPLETE, self.stack_creator.get_status()) + self.assertEqual(create_stack.STATUS_CREATE_COMPLETE, + self.stack_creator.get_status()) # Delete Stack manually heat_utils.delete_stack(self.heat_cli, created_stack) @@ -243,14 +263,16 @@ class CreateStackSuccessTests(OSIntegrationTestCase): end_time = time.time() + 90 deleted = False while time.time() < end_time: - status = heat_utils.get_stack_status(self.heat_cli, retrieved_stack.id) + status = heat_utils.get_stack_status(self.heat_cli, + retrieved_stack.id) if status == create_stack.STATUS_DELETE_COMPLETE: deleted = True break self.assertTrue(deleted) - # Must not throw an exception when attempting to cleanup non-existent stack + # Must not throw an exception when attempting to cleanup non-existent + # stack self.stack_creator.clean() self.assertIsNone(self.stack_creator.get_stack()) @@ -261,13 +283,16 @@ class CreateStackSuccessTests(OSIntegrationTestCase): # Create Stack template_dict = heat_utils.parse_heat_template_str( file_utils.read_file(self.heat_tmplt_path)) - stack_settings = StackSettings(name=self.__class__.__name__ + '-' + str(self.guid) + '-stack', - template=template_dict, - env_values=self.env_values) - self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings) + stack_settings = StackSettings( + name=self.__class__.__name__ + '-' + str(self.guid) + '-stack', + template=template_dict, + env_values=self.env_values) + self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, + stack_settings) created_stack1 = self.stack_creator.create() - retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, created_stack1.id) + retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, + created_stack1.id) self.assertIsNotNone(retrieved_stack) self.assertEqual(created_stack1.name, retrieved_stack.name) self.assertEqual(created_stack1.id, retrieved_stack.id) @@ -275,7 +300,8 @@ class CreateStackSuccessTests(OSIntegrationTestCase): self.assertEqual(0, len(self.stack_creator.get_outputs())) # Should be retrieving the instance data - stack_creator2 = create_stack.OpenStackHeatStack(self.os_creds, stack_settings) + stack_creator2 = create_stack.OpenStackHeatStack(self.os_creds, + stack_settings) stack2 = stack_creator2.create() self.assertEqual(created_stack1.id, stack2.id) @@ -302,8 +328,10 @@ class CreateStackNegativeTests(OSIntegrationTestCase): """ Expect an StackCreationError when the stack file does not exist """ - stack_settings = StackSettings(name=self.stack_name, template_path=self.heat_tmplt_path) - self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings) + stack_settings = StackSettings(name=self.stack_name, + template_path=self.heat_tmplt_path) + self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, + stack_settings) with self.assertRaises(HTTPBadRequest): self.stack_creator.create() @@ -311,7 +339,9 @@ class CreateStackNegativeTests(OSIntegrationTestCase): """ Expect an StackCreationError when the stack file does not exist """ - stack_settings = StackSettings(name=self.stack_name, template_path='foo') - self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings) + stack_settings = StackSettings(name=self.stack_name, + template_path='foo') + self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, + stack_settings) with self.assertRaises(IOError): self.stack_creator.create() |