summaryrefslogtreecommitdiffstats
path: root/snaps/openstack/utils/launch_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'snaps/openstack/utils/launch_utils.py')
-rw-r--r--snaps/openstack/utils/launch_utils.py889
1 files changed, 889 insertions, 0 deletions
diff --git a/snaps/openstack/utils/launch_utils.py b/snaps/openstack/utils/launch_utils.py
new file mode 100644
index 0000000..ddaad12
--- /dev/null
+++ b/snaps/openstack/utils/launch_utils.py
@@ -0,0 +1,889 @@
+#
+# Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
+# and others. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This utility makes it easy to create OpenStack objects
+import logging
+import re
+import socket
+import struct
+
+import os
+import time
+from keystoneauth1.exceptions import Unauthorized
+
+from snaps import file_utils
+from snaps.config.flavor import FlavorConfig
+from snaps.config.image import ImageConfig
+from snaps.config.keypair import KeypairConfig
+from snaps.config.network import PortConfig, NetworkConfig
+from snaps.config.project import ProjectConfig
+from snaps.config.qos import QoSConfig
+from snaps.config.router import RouterConfig
+from snaps.config.security_group import SecurityGroupConfig
+from snaps.config.user import UserConfig
+from snaps.config.vm_inst import VmInstanceConfig
+from snaps.config.volume import VolumeConfig
+from snaps.config.volume_type import VolumeTypeConfig
+from snaps.openstack.create_flavor import OpenStackFlavor
+from snaps.openstack.create_image import OpenStackImage
+from snaps.openstack.create_keypairs import OpenStackKeypair
+from snaps.openstack.create_network import OpenStackNetwork
+from snaps.openstack.create_project import OpenStackProject
+from snaps.openstack.create_qos import OpenStackQoS
+from snaps.openstack.create_router import OpenStackRouter
+from snaps.openstack.create_security_group import OpenStackSecurityGroup
+from snaps.openstack.create_user import OpenStackUser
+from snaps.openstack.create_volume import OpenStackVolume
+from snaps.openstack.create_volume_type import OpenStackVolumeType
+from snaps.openstack.os_credentials import OSCreds, ProxySettings
+from snaps.openstack.utils import deploy_utils, neutron_utils, keystone_utils
+from snaps.openstack.utils.nova_utils import RebootType
+from snaps.provisioning import ansible_utils
+
+from warnings import warn
+warn('This utility will be removed in a subsequent release',
+ DeprecationWarning)
+
+logger = logging.getLogger('lanuch_utils')
+DEFAULT_CREDS_KEY = 'admin'
+
+
+def launch_config(config, tmplt_file, deploy, clean, clean_image):
+ """
+ Launches all objects and applies any configured ansible playbooks
+ :param config: the environment configuration dict object
+ :param tmplt_file: the path to the SNAPS-OO template file
+ :param deploy: when True deploy
+ :param clean: when True clean
+ :param clean_image: when True clean the image when clean is True
+ """
+ os_config = config.get('openstack')
+
+ creators = list()
+ vm_dict = dict()
+ images_dict = dict()
+ flavors_dict = dict()
+ networks_dict = dict()
+ routers_dict = dict()
+ os_creds_dict = dict()
+
+ if os_config:
+ os_creds_dict = __get_creds_dict(os_config)
+
+ # Create projects
+ projects_dict = __create_instances(
+ os_creds_dict, OpenStackProject, ProjectConfig,
+ os_config.get('projects'), 'project', clean)
+ creators.append(projects_dict)
+
+ # Create users
+ users_dict = __create_instances(
+ os_creds_dict, OpenStackUser, UserConfig,
+ os_config.get('users'), 'user', clean)
+ creators.append(users_dict)
+
+ # Associate new users to projects
+ if not clean:
+ for project_creator in projects_dict.values():
+ users = project_creator.project_settings.users
+ for user_name in users:
+ user_creator = users_dict.get(user_name)
+ if user_creator:
+ project_creator.assoc_user(
+ user_creator.get_user())
+
+ # Create flavors
+ flavors_dict = __create_instances(
+ os_creds_dict, OpenStackFlavor, FlavorConfig,
+ os_config.get('flavors'), 'flavor', clean, users_dict)
+ creators.append(flavors_dict)
+
+ # Create QoS specs
+ qos_dict = __create_instances(
+ os_creds_dict, OpenStackQoS, QoSConfig,
+ os_config.get('qos_specs'), 'qos_spec', clean, users_dict)
+ creators.append(qos_dict)
+
+ # Create volume types
+ vol_type_dict = __create_instances(
+ os_creds_dict, OpenStackVolumeType, VolumeTypeConfig,
+ os_config.get('volume_types'), 'volume_type', clean,
+ users_dict)
+ creators.append(vol_type_dict)
+
+ # Create volumes
+ vol_dict = __create_instances(
+ os_creds_dict, OpenStackVolume, VolumeConfig,
+ os_config.get('volumes'), 'volume', clean, users_dict)
+ creators.append(vol_dict)
+
+ # Create images
+ images_dict = __create_instances(
+ os_creds_dict, OpenStackImage, ImageConfig,
+ os_config.get('images'), 'image', clean, users_dict)
+ creators.append(images_dict)
+
+ # Create networks
+ networks_dict = __create_instances(
+ os_creds_dict, OpenStackNetwork, NetworkConfig,
+ os_config.get('networks'), 'network', clean, users_dict)
+ creators.append(networks_dict)
+
+ # Create routers
+ routers_dict = __create_instances(
+ os_creds_dict, OpenStackRouter, RouterConfig,
+ os_config.get('routers'), 'router', clean, users_dict)
+ creators.append(routers_dict)
+
+ # Create keypairs
+ keypairs_dict = __create_instances(
+ os_creds_dict, OpenStackKeypair, KeypairConfig,
+ os_config.get('keypairs'), 'keypair', clean, users_dict)
+ creators.append(keypairs_dict)
+
+ # Create security groups
+ creators.append(__create_instances(
+ os_creds_dict, OpenStackSecurityGroup,
+ SecurityGroupConfig,
+ os_config.get('security_groups'), 'security_group', clean,
+ users_dict))
+
+ # Create instance
+ vm_dict = __create_vm_instances(
+ os_creds_dict, users_dict, os_config.get('instances'),
+ images_dict, keypairs_dict, clean)
+ creators.append(vm_dict)
+ logger.info(
+ 'Completed creating/retrieving all configured instances')
+
+ # Must enter either block
+ if clean:
+ # Cleanup Environment
+ __cleanup(creators, clean_image)
+ elif deploy:
+ # Provision VMs
+ ansible_config = config.get('ansible')
+ if ansible_config and vm_dict:
+ if not __apply_ansible_playbooks(
+ ansible_config, os_creds_dict, vm_dict, images_dict,
+ flavors_dict, networks_dict, routers_dict, tmplt_file):
+ logger.error("Problem applying ansible playbooks")
+
+
+def __get_creds_dict(os_conn_config):
+ """
+ Returns a dict of OSCreds where the key is the creds name.
+ For backwards compatibility, credentials not contained in a list (only
+ one) will be returned with the key of None
+ :param os_conn_config: the credential configuration
+ :return: a dict of OSCreds objects
+ """
+ if 'connection' in os_conn_config:
+ return {DEFAULT_CREDS_KEY: __get_os_credentials(os_conn_config)}
+ elif 'connections' in os_conn_config:
+ out = dict()
+ for os_conn_dict in os_conn_config['connections']:
+ config = os_conn_dict.get('connection')
+ if not config:
+ raise Exception('Invalid connection format')
+
+ name = config.get('name')
+ if not name:
+ raise Exception('Connection config requires a name field')
+
+ out[name] = __get_os_credentials(os_conn_dict)
+ return out
+
+
+def __get_creds(os_creds_dict, os_user_dict, inst_config):
+ """
+ Returns the appropriate credentials
+ :param os_creds_dict: a dictionary of OSCreds objects where the name is the
+ key
+ :param os_user_dict: a dictionary of OpenStackUser objects where the name
+ is the key
+ :param inst_config:
+ :return: an OSCreds instance or None
+ """
+ os_creds = os_creds_dict.get(DEFAULT_CREDS_KEY)
+ if 'os_user' in inst_config:
+ os_user_conf = inst_config['os_user']
+ if 'name' in os_user_conf:
+ user_creator = os_user_dict.get(os_user_conf['name'])
+ if user_creator:
+ return user_creator.get_os_creds(
+ project_name=os_user_conf.get('project_name'))
+ elif 'os_creds_name' in inst_config:
+ if 'os_creds_name' in inst_config:
+ os_creds = os_creds_dict[inst_config['os_creds_name']]
+ return os_creds
+
+
+def __get_os_credentials(os_conn_config):
+ """
+ Returns an object containing all of the information required to access
+ OpenStack APIs
+ :param os_conn_config: The configuration holding the credentials
+ :return: an OSCreds instance
+ """
+ config = os_conn_config.get('connection')
+ if not config:
+ raise Exception('Invalid connection configuration')
+
+ proxy_settings = None
+ http_proxy = config.get('http_proxy')
+ if http_proxy:
+ tokens = re.split(':', http_proxy)
+ ssh_proxy_cmd = config.get('ssh_proxy_cmd')
+ proxy_settings = ProxySettings(host=tokens[0], port=tokens[1],
+ ssh_proxy_cmd=ssh_proxy_cmd)
+ else:
+ if 'proxy_settings' in config:
+ host = config['proxy_settings'].get('host')
+ port = config['proxy_settings'].get('port')
+ if host and host != 'None' and port and port != 'None':
+ proxy_settings = ProxySettings(**config['proxy_settings'])
+
+ if proxy_settings:
+ config['proxy_settings'] = proxy_settings
+ else:
+ if config.get('proxy_settings'):
+ del config['proxy_settings']
+
+ return OSCreds(**config)
+
+
+def __parse_ports_config(config):
+ """
+ Parses the "ports" configuration
+ :param config: The dictionary to parse
+ :return: a list of PortConfig objects
+ """
+ out = list()
+ for port_config in config:
+ out.append(PortConfig(**port_config.get('port')))
+ return out
+
+
+def __create_instances(os_creds_dict, creator_class, config_class, config,
+ config_key, cleanup=False, os_users_dict=None):
+ """
+ Returns a dictionary of SNAPS creator objects where the key is the name
+ :param os_creds_dict: Dictionary of OSCreds objects where the key is the
+ name
+ :param config: The list of configurations for the same type
+ :param config_key: The list of configurations for the same type
+ :param cleanup: Denotes whether or not this is being called for cleanup
+ :return: dictionary
+ """
+ out = {}
+
+ if config:
+ for config_dict in config:
+ inst_config = config_dict.get(config_key)
+ if inst_config:
+ creds = __get_creds(os_creds_dict, os_users_dict, inst_config)
+ if creds:
+ creator = creator_class(
+ creds,
+ config_class(**inst_config))
+
+ if creator:
+ if cleanup:
+ try:
+ creator.initialize()
+ except Unauthorized as e:
+ logger.warn(
+ 'Unable to initialize creator [%s] - %s',
+ creator, e)
+ else:
+ creator.create()
+
+ out[inst_config['name']] = creator
+ else:
+ raise Exception('Unable to instantiate creator')
+
+ logger.info('Initialized configured %ss', config_key)
+
+ return out
+
+
+def __create_vm_instances(os_creds_dict, os_users_dict, instances_config,
+ image_dict, keypairs_dict, cleanup=False):
+ """
+ Returns a dictionary of OpenStackVmInstance objects where the key is the
+ instance name
+ :param os_creds_dict: Dictionary of OSCreds objects where the key is the
+ name
+ :param os_users_dict: Dictionary of OpenStackUser objects where the key is
+ the username
+ :param instances_config: The list of VM instance configurations
+ :param image_dict: A dictionary of images that will probably be used to
+ instantiate the VM instance
+ :param keypairs_dict: A dictionary of keypairs that will probably be used
+ to instantiate the VM instance
+ :param cleanup: Denotes whether or not this is being called for cleanup
+ :return: dictionary
+ """
+ vm_dict = {}
+
+ if instances_config:
+ for instance_config in instances_config:
+ conf = instance_config.get('instance')
+ if conf:
+ if image_dict:
+ image_creator = image_dict.get(conf.get('imageName'))
+ if image_creator:
+ instance_settings = VmInstanceConfig(
+ **instance_config['instance'])
+ kp_creator = keypairs_dict.get(
+ conf.get('keypair_name'))
+
+ try:
+ vm_dict[conf[
+ 'name']] = deploy_utils.create_vm_instance(
+ __get_creds(
+ os_creds_dict, os_users_dict, conf),
+ instance_settings,
+ image_creator.image_settings,
+ keypair_creator=kp_creator,
+ init_only=cleanup)
+ except Unauthorized as e:
+ if not cleanup:
+ logger.warn('Unable to initialize VM - %s', e)
+ raise
+ else:
+ raise Exception('Image creator instance not found.'
+ ' Cannot instantiate')
+ else:
+ if not cleanup:
+ raise Exception('Image dictionary is None. Cannot '
+ 'instantiate')
+ else:
+ raise Exception('Instance configuration is None. Cannot '
+ 'instantiate')
+ logger.info('Created configured instances')
+
+ return vm_dict
+
+
+def __apply_ansible_playbooks(ansible_configs, os_creds_dict, vm_dict,
+ image_dict, flavor_dict, networks_dict,
+ routers_dict, tmplt_file):
+ """
+ Applies ansible playbooks to running VMs with floating IPs
+ :param ansible_configs: a list of Ansible configurations
+ :param os_creds_dict: Dictionary of OSCreds objects where the key is the
+ name
+ :param vm_dict: the dictionary of newly instantiated VMs where the name is
+ the key
+ :param image_dict: the dictionary of newly instantiated images where the
+ name is the key
+ :param flavor_dict: the dictionary of newly instantiated flavors where the
+ name is the key
+ :param networks_dict: the dictionary of newly instantiated networks where
+ the name is the key
+ :param routers_dict: the dictionary of newly instantiated routers where
+ the name is the key
+ :param tmplt_file: the path of the SNAPS-OO template file for setting the
+ CWD so playbook location is relative to the deployment
+ file
+ :return: t/f - true if successful
+ """
+ logger.info("Applying Ansible Playbooks")
+ if ansible_configs:
+ # Set CWD so the deployment file's playbook location can leverage
+ # relative paths
+ orig_cwd = os.getcwd()
+ env_dir = os.path.dirname(tmplt_file)
+ os.chdir(env_dir)
+
+ # Apply playbooks
+ for ansible_config in ansible_configs:
+ # Ensure all hosts are accepting SSH session requests
+ for vm_name in ansible_config['hosts']:
+ vm_inst = vm_dict.get(vm_name)
+ if vm_inst:
+ if not vm_inst.vm_ssh_active(block=True):
+ logger.warning(
+ 'Timeout waiting for instance to respond to '
+ 'SSH requests')
+ return False
+
+ __apply_ansible_playbook(
+ ansible_config, os_creds_dict, vm_dict, image_dict,
+ flavor_dict, networks_dict, routers_dict)
+
+ # Return to original directory
+ os.chdir(orig_cwd)
+
+ return True
+
+
+def __apply_ansible_playbook(ansible_config, os_creds_dict, vm_dict,
+ image_dict, flavor_dict, networks_dict,
+ routers_dict):
+ """
+ Applies an Ansible configuration setting
+ :param ansible_config: the configuration settings
+ :param os_creds_dict: dict where the key is the name and value is OSCreds
+ :param vm_dict: the dictionary of newly instantiated VMs where the name is
+ the key
+ :param image_dict: the dictionary of newly instantiated images where the
+ name is the key
+ :param flavor_dict: the dictionary of newly instantiated flavors where the
+ name is the key
+ :param networks_dict: the dictionary of newly instantiated networks where
+ the name is the key
+ :param routers_dict: the dictionary of newly instantiated routers where
+ the name is the key
+ """
+ if ansible_config:
+ (remote_user, floating_ips, private_key_filepath,
+ proxy_settings) = __get_connection_info(
+ ansible_config, vm_dict)
+ if floating_ips:
+ for key, vm_creator in vm_dict.items():
+ fip = vm_creator.get_floating_ip()
+ if fip and fip.ip in floating_ips:
+ if not vm_creator.cloud_init_complete(block=True):
+ raise Exception(
+ 'Cannot apply playbooks as cloud-init has not '
+ 'completed')
+
+ variables = __get_variables(
+ ansible_config.get('variables'), os_creds_dict, vm_dict,
+ image_dict, flavor_dict, networks_dict, routers_dict)
+
+ ansible_utils.apply_playbook(
+ ansible_config['playbook_location'], floating_ips, remote_user,
+ ssh_priv_key_file_path=private_key_filepath,
+ variables=variables,
+ proxy_setting=proxy_settings)
+
+ if 'post_processing' in ansible_config:
+ post_proc_config = ansible_config['post_processing']
+ if 'sleep' in post_proc_config:
+ time.sleep(post_proc_config['sleep'])
+ if 'reboot' in post_proc_config:
+ for vm_name in post_proc_config['reboot']:
+ if vm_name in vm_dict:
+ logger.info('Rebooting VM - %s', vm_name)
+ vm_dict[vm_name].reboot(RebootType.hard)
+
+
+def __get_connection_info(ansible_config, vm_dict):
+ """
+ Returns a tuple of data required for connecting to the running VMs
+ (remote_user, [floating_ips], private_key_filepath, proxy_settings)
+ :param ansible_config: the configuration settings
+ :param vm_dict: the dictionary of VMs where the VM name is the key
+ :return: tuple where the first element is the user and the second is a list
+ of floating IPs and the third is the
+ private key file location and the fourth is an instance of the
+ snaps.ProxySettings class
+ (note: in order to work, each of the hosts need to have the same sudo_user
+ and private key file location values)
+ """
+ if ansible_config.get('hosts'):
+ hosts = ansible_config['hosts']
+ if len(hosts) > 0:
+ floating_ips = list()
+ remote_user = None
+ pk_file = None
+ proxy_settings = None
+ for host in hosts:
+ vm = vm_dict.get(host)
+ if vm:
+ fip = vm.get_floating_ip()
+ if fip:
+ remote_user = vm.get_image_user()
+
+ if fip:
+ floating_ips.append(fip.ip)
+ else:
+ raise Exception(
+ 'Could not find floating IP for VM - ' +
+ vm.name)
+
+ pk_file = vm.keypair_settings.private_filepath
+ proxy_settings = vm.get_os_creds().proxy_settings
+ else:
+ logger.error('Could not locate VM with name - ' + host)
+
+ return remote_user, floating_ips, pk_file, proxy_settings
+ return None
+
+
+def __get_variables(var_config, os_creds_dict, vm_dict, image_dict,
+ flavor_dict, networks_dict, routers_dict):
+ """
+ Returns a dictionary of substitution variables to be used for Ansible
+ templates
+ :param var_config: the variable configuration settings
+ :param os_creds_dict: dict where the key is the name and value is OSCreds
+ :param vm_dict: the dictionary of newly instantiated VMs where the name is
+ the key
+ :param image_dict: the dictionary of newly instantiated images where the
+ name is the key
+ :param flavor_dict: the dictionary of newly instantiated flavors where the
+ name is the key
+ :param networks_dict: the dictionary of newly instantiated networks where
+ the name is the key
+ :param routers_dict: the dictionary of newly instantiated routers where
+ the name is the key
+ :return: dictionary or None
+ """
+ if var_config and vm_dict and len(vm_dict) > 0:
+ variables = dict()
+ for key, value in var_config.items():
+ value = __get_variable_value(
+ value, os_creds_dict, vm_dict, image_dict, flavor_dict,
+ networks_dict, routers_dict)
+ if key and value:
+ variables[key] = value
+ logger.info(
+ "Set Jinga2 variable with key [%s] the value [%s]",
+ key, value)
+ else:
+ raise Exception(
+ 'Key - [' + str(key) + '] or Value [' + str(value)
+ + '] must not be None')
+ return variables
+ return None
+
+
+def __get_variable_value(var_config_values, os_creds_dict, vm_dict, image_dict,
+ flavor_dict, networks_dict, routers_dict):
+ """
+ Returns the associated variable value for use by Ansible for substitution
+ purposes
+ :param var_config_values: the configuration dictionary
+ :param os_creds_dict: dict where the key is the name and value is OSCreds
+ :param vm_dict: the dictionary of newly instantiated VMs where the name is
+ the key
+ :param image_dict: the dictionary of newly instantiated images where the
+ name is the key
+ :param flavor_dict: the dictionary of newly instantiated flavors where the
+ name is the key
+ :param networks_dict: the dictionary of newly instantiated networks where
+ the name is the key
+ :param routers_dict: the dictionary of newly instantiated routers where
+ the name is the key
+ :return:
+ """
+ if var_config_values['type'] == 'string':
+ return __get_string_variable_value(var_config_values)
+ if var_config_values['type'] == 'vm-attr':
+ return __get_vm_attr_variable_value(var_config_values, vm_dict)
+ if var_config_values['type'] == 'os_creds':
+ return __get_os_creds_variable_value(var_config_values, os_creds_dict)
+ if var_config_values['type'] == 'os_creds_dict':
+ return str(__get_os_creds_dict(var_config_values, os_creds_dict))
+ if var_config_values['type'] == 'network':
+ return __get_network_variable_value(var_config_values, networks_dict)
+ if var_config_values['type'] == 'router':
+ return __get_router_variable_value(var_config_values, routers_dict,
+ os_creds_dict)
+ if var_config_values['type'] == 'port':
+ return __get_vm_port_variable_value(var_config_values, vm_dict)
+ if var_config_values['type'] == 'floating_ip':
+ return __get_vm_fip_variable_value(var_config_values, vm_dict)
+ if var_config_values['type'] == 'image':
+ return __get_image_variable_value(var_config_values, image_dict)
+ if var_config_values['type'] == 'flavor':
+ return __get_flavor_variable_value(var_config_values, flavor_dict)
+ if var_config_values['type'] == 'vm-yaml':
+ return __create_yaml(var_config_values, vm_dict)
+ return None
+
+
+def __get_string_variable_value(var_config_values):
+ """
+ Returns the associated string value
+ :param var_config_values: the configuration dictionary
+ :return: the value contained in the dictionary with the key 'value'
+ """
+ return var_config_values['value']
+
+
+def __get_vm_attr_variable_value(var_config_values, vm_dict):
+ """
+ Returns the associated value contained on a VM instance
+ :param var_config_values: the configuration dictionary
+ :param vm_dict: the dictionary containing all VMs where the key is the VM's
+ name
+ :return: the value
+ """
+ vm = vm_dict.get(var_config_values['vm_name'])
+ if vm:
+ if var_config_values['value'] == 'floating_ip':
+ return vm.get_floating_ip().ip
+ if var_config_values['value'] == 'image_user':
+ return vm.get_image_user()
+
+
+def __get_os_creds_variable_value(var_config_values, os_creds_dict):
+ """
+ Returns the associated OS credentials value
+ :param var_config_values: the configuration dictionary
+ :param os_creds_dict: dict of OpenStack credentials where the key is the
+ name
+ :return: the value
+ """
+ if 'creds_name' in var_config_values:
+ os_creds = os_creds_dict.get[var_config_values['creds_name']]
+ else:
+ os_creds = os_creds_dict.get('admin-creds')
+
+ if os_creds:
+ if var_config_values['value'] == 'username':
+ logger.info("Returning OS username")
+ return os_creds.username
+ elif var_config_values['value'] == 'password':
+ logger.info("Returning OS password")
+ return os_creds.password
+ elif var_config_values['value'] == 'auth_url':
+ logger.info("Returning OS auth_url")
+ return os_creds.auth_url
+ elif var_config_values['value'] == 'project_name':
+ logger.info("Returning OS project_name")
+ return os_creds.project_name
+
+
+def __get_os_creds_dict(var_config_values, os_creds_dict):
+ """
+ Returns the associated OS credentials as a dict
+ :param var_config_values: the configuration dictionary
+ :param os_creds_dict: dict of creds where the key is the username
+ :return: the value dict
+ """
+ if 'creds_name' in var_config_values:
+ os_creds = os_creds_dict.get[var_config_values['creds_name']]
+ else:
+ os_creds = os_creds_dict.get('admin-creds')
+ if os_creds:
+ return os_creds.to_dict()
+
+
+def __get_network_variable_value(var_config_values, networks_dict):
+ """
+ Returns the associated network value
+ :param var_config_values: the configuration dictionary
+ :param networks_dict: the dictionary containing all networks where the key
+ is the network name
+ :return: the value
+ """
+ net_name = var_config_values.get('network_name')
+
+ if net_name and networks_dict.get(net_name):
+ network_creator = networks_dict[net_name]
+
+ if 'subnet_name' in var_config_values:
+ subnet_name = var_config_values.get('subnet_name')
+ if subnet_name:
+ for subnet in network_creator.get_network().subnets:
+ if subnet_name == subnet.name:
+ if 'value' in var_config_values:
+ if 'gateway_ip' == var_config_values['value']:
+ return subnet.gateway_ip
+ if 'ip_range' == var_config_values['value']:
+ return subnet.start + ' ' + subnet.end
+ if 'ip_range_start' == var_config_values['value']:
+ return subnet.start
+ if 'ip_range_end' == var_config_values['value']:
+ return subnet.end
+ if 'cidr' == var_config_values['value']:
+ return subnet.cidr
+ if 'cidr_ip' == var_config_values['value']:
+ cidr_split = subnet.cidr.split('/')
+ return cidr_split[0]
+ if 'netmask' == var_config_values['value']:
+ cidr_split = subnet.cidr.split('/')
+ cidr_bits = 32 - int(cidr_split[1])
+ netmask = socket.inet_ntoa(
+ struct.pack(
+ '!I', (1 << 32) - (1 << cidr_bits)))
+ return netmask
+ if 'broadcast_ip' == var_config_values['value']:
+ end_split = subnet.end.split('.')
+ broadcast_ip = (
+ end_split[0] + '.' + end_split[1] + '.'
+ + end_split[2] + '.255')
+ return broadcast_ip
+
+
+def __get_router_variable_value(var_config_values, routers_dict,
+ os_creds_dict):
+ """
+ Returns the associated network value
+ :param var_config_values: the configuration dictionary
+ :param routers_dict: the dictionary containing all networks where the key
+ is the network name
+ :param os_creds_dict: dict of OpenStack credentials where the key is the
+ name
+ :return: the value
+ """
+ if 'creds_name' in var_config_values:
+ os_creds = os_creds_dict.get[var_config_values['creds_name']]
+ else:
+ os_creds = os_creds_dict.get('admin-creds')
+
+ router_name = var_config_values.get('router_name')
+ router_creator = routers_dict[router_name]
+
+ if router_creator:
+ if 'external_fixed_ip' == var_config_values.get('attr'):
+ session = keystone_utils.keystone_session(os_creds)
+ neutron = neutron_utils.neutron_client(os_creds, session)
+ try:
+ ext_nets = neutron_utils.get_external_networks(neutron)
+
+ subnet_name = var_config_values.get('subnet_name')
+
+ for ext_net in ext_nets:
+ for subnet in ext_net.subnets:
+ if subnet_name == subnet.name:
+ router = router_creator.get_router()
+ for fixed_ips in router.external_fixed_ips:
+ if subnet.id == fixed_ips['subnet_id']:
+ return fixed_ips['ip_address']
+ finally:
+ keystone_utils.close_session(session)
+
+
+def __get_vm_port_variable_value(var_config_values, vm_dict):
+ """
+ Returns the associated OS credentials value
+ :param var_config_values: the configuration dictionary
+ :param vm_dict: the dictionary containing all VMs where the key is the VM's
+ name
+ :return: the value
+ """
+ port_name = var_config_values.get('port_name')
+ vm_name = var_config_values.get('vm_name')
+
+ if port_name and vm_name:
+ vm = vm_dict.get(vm_name)
+ if vm:
+ for vm_port in vm.get_vm_inst().ports:
+ if vm_port.name == port_name:
+ port_value_id = var_config_values.get('port_value')
+ if port_value_id:
+ if port_value_id == 'mac_address':
+ return vm_port.mac_address
+ if port_value_id == 'ip_address':
+ return vm_port.ips[0]['ip_address']
+
+
+def __get_vm_fip_variable_value(var_config_values, vm_dict):
+ """
+ Returns the floating IP value if found
+ :param var_config_values: the configuration dictionary
+ :param vm_dict: the dictionary containing all VMs where the key is the VM's
+ name
+ :return: the floating IP string value or None
+ """
+ fip_name = var_config_values.get('fip_name')
+ vm_name = var_config_values.get('vm_name')
+
+ if vm_name:
+ vm = vm_dict.get(vm_name)
+ if vm:
+ fip = vm.get_floating_ip(fip_name)
+ if fip:
+ return fip.ip
+
+
+def __get_image_variable_value(var_config_values, image_dict):
+ """
+ Returns the associated image value
+ :param var_config_values: the configuration dictionary
+ :param image_dict: the dictionary containing all images where the key is
+ the name
+ :return: the value
+ """
+ if image_dict:
+ if var_config_values.get('image_name'):
+ image_creator = image_dict.get(var_config_values['image_name'])
+ if image_creator:
+ if (var_config_values.get('value')
+ and var_config_values['value'] == 'id'):
+ return image_creator.get_image().id
+ if (var_config_values.get('value')
+ and var_config_values['value'] == 'user'):
+ return image_creator.image_settings.image_user
+
+
+def __get_flavor_variable_value(var_config_values, flavor_dict):
+ """
+ Returns the associated flavor value
+ :param var_config_values: the configuration dictionary
+ :param flavor_dict: the dictionary containing all flavor creators where the
+ key is the name
+ :return: the value or None
+ """
+ if flavor_dict:
+ if var_config_values.get('flavor_name'):
+ flavor_creator = flavor_dict.get(var_config_values['flavor_name'])
+ if flavor_creator:
+ if (var_config_values.get('value')
+ and var_config_values['value'] == 'id'):
+ return flavor_creator.get_flavor().id
+
+
+def __create_yaml(var_config_values, vm_dict):
+ """
+ Creates a yaml file containing an OpenStack pod's credentials with a list
+ of server IDs that can be used for obtaining SNAPS-OO instances for
+ manipulation such as rebooting
+ :param var_config_values: the configuration dictionary
+ :param vm_dict: the dictionary containing all vm creators where the
+ key is the name
+ :return: the name of the generated file
+ """
+ out_dict = dict()
+ out_dict['vms'] = list()
+ req_vm_names = var_config_values.get('vms')
+
+ for name, vm_creator in vm_dict.items():
+ vm_inst = vm_creator.get_vm_inst()
+ if vm_inst and vm_inst.name in req_vm_names:
+ out_dict['vms'].append({
+ 'name': str(vm_inst.name),
+ 'id': str(vm_inst.id),
+ 'os_creds': vm_creator.get_os_creds().to_dict()
+ })
+
+ out_file = file_utils.persist_dict_to_yaml(
+ out_dict, var_config_values.get('file_name'))
+
+ if out_file:
+ return out_file.name
+
+
+def __cleanup(creators, clean_image=False):
+ """
+ Cleans up environment
+ :param creators: the list of creators by type
+ :param clean_image: when true
+ :return:
+ """
+ for creator_dict in reversed(creators):
+ for key, creator in creator_dict.items():
+ if ((isinstance(creator, OpenStackImage) and clean_image)
+ or not isinstance(creator, OpenStackImage)):
+ creator.clean()