From f9cf2eb23cb1dc22fe9d680ac49c8ed4d2aa6eff Mon Sep 17 00:00:00 2001 From: spisarski Date: Thu, 24 May 2018 12:35:33 -0600 Subject: New functionality for snaps-oo application. 1. Utility for saving a dict to a YAML file 2. Added new hook that will create a file with the VMs created with the associated OpenStack credentials Change-Id: I124db00e4375603e9473cceab3e2846582d6cb22 Signed-off-by: spisarski --- snaps/file_utils.py | 16 +++++++- snaps/openstack/utils/launch_utils.py | 74 +++++++++++++++++++++++++++-------- 2 files changed, 73 insertions(+), 17 deletions(-) diff --git a/snaps/file_utils.py b/snaps/file_utils.py index 58ec55c..284ae15 100644 --- a/snaps/file_utils.py +++ b/snaps/file_utils.py @@ -183,7 +183,7 @@ def read_yaml(config_file_path): logger.debug('Attempting to load configuration file - ' + config_file_path) config_file = None try: - with open(config_file_path) as config_file: + with open(config_file_path, 'r') as config_file: config = yaml.safe_load(config_file) logger.info('Loaded configuration') return config @@ -193,6 +193,20 @@ def read_yaml(config_file_path): config_file.close() +def persist_dict_to_yaml(the_dict, file_name): + """ + Creates a YAML file from a dict + :param the_dict: the dictionary to store + :param conf_dir: the directory used to store the config file + :return: the file object + """ + logger.info('Persisting %s to [%s]', the_dict, file_name) + file_path = os.path.expanduser(file_name) + yaml_from_dict = yaml.dump( + the_dict, default_flow_style=False, default_style='') + return save_string_to_file(yaml_from_dict, file_path) + + def read_os_env_file(os_env_filename): """ Reads the OS environment source file and returns a map of each key/value diff --git a/snaps/openstack/utils/launch_utils.py b/snaps/openstack/utils/launch_utils.py index 49d41e7..6e8b94e 100644 --- a/snaps/openstack/utils/launch_utils.py +++ b/snaps/openstack/utils/launch_utils.py @@ -24,6 +24,7 @@ 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 @@ -49,6 +50,7 @@ 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 logger = logging.getLogger('lanuch_utils') @@ -417,10 +419,9 @@ def __apply_ansible_playbooks(ansible_configs, os_creds_dict, vm_dict, 'SSH requests') return False - os_creds = os_creds_dict.get('admin-creds') __apply_ansible_playbook( - ansible_config, os_creds, vm_dict, image_dict, flavor_dict, - networks_dict, routers_dict) + ansible_config, os_creds_dict, vm_dict, image_dict, + flavor_dict, networks_dict, routers_dict) # Return to original directory os.chdir(orig_cwd) @@ -428,12 +429,13 @@ def __apply_ansible_playbooks(ansible_configs, os_creds_dict, vm_dict, return True -def __apply_ansible_playbook(ansible_config, os_creds, vm_dict, image_dict, - flavor_dict, networks_dict, routers_dict): +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: the OpenStack admin credentials object + :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 @@ -459,8 +461,8 @@ def __apply_ansible_playbook(ansible_config, os_creds, vm_dict, image_dict, 'completed') variables = __get_variables( - ansible_config.get('variables'), os_creds, vm_dict, image_dict, - flavor_dict, networks_dict, routers_dict) + ansible_config.get('variables'), os_creds_dict, vm_dict, + image_dict, flavor_dict, networks_dict, routers_dict) retval = ansible_utils.apply_playbook( ansible_config['playbook_location'], floating_ips, remote_user, @@ -480,7 +482,7 @@ def __apply_ansible_playbook(ansible_config, os_creds, vm_dict, image_dict, 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() + vm_dict[vm_name].reboot(RebootType.hard) return retval @@ -528,13 +530,13 @@ def __get_connection_info(ansible_config, vm_dict): return None -def __get_variables(var_config, os_creds, vm_dict, image_dict, flavor_dict, +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: the OpenStack admin credentials object + :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 @@ -551,7 +553,7 @@ def __get_variables(var_config, os_creds, vm_dict, image_dict, flavor_dict, variables = dict() for key, value in var_config.items(): value = __get_variable_value( - value, os_creds, vm_dict, image_dict, flavor_dict, + value, os_creds_dict, vm_dict, image_dict, flavor_dict, networks_dict, routers_dict) if key and value: variables[key] = value @@ -566,13 +568,13 @@ def __get_variables(var_config, os_creds, vm_dict, image_dict, flavor_dict, return None -def __get_variable_value(var_config_values, os_creds, vm_dict, image_dict, +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: the OpenStack admin credentials object + :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 @@ -585,17 +587,18 @@ def __get_variable_value(var_config_values, os_creds, vm_dict, image_dict, the name is the key :return: """ + admin_creds = os_creds_dict.get('admin-creds') 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) + return __get_os_creds_variable_value(var_config_values, admin_creds) 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) + admin_creds) if var_config_values['type'] == 'port': return __get_vm_port_variable_value(var_config_values, vm_dict) if var_config_values['type'] == 'floating_ip': @@ -604,6 +607,8 @@ def __get_variable_value(var_config_values, os_creds, vm_dict, image_dict, 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'] == 'snaps-env-yaml': + return __create_snaps_env_yaml(var_config_values, vm_dict) return None @@ -813,6 +818,43 @@ def __get_flavor_variable_value(var_config_values, flavor_dict): return flavor_creator.get_flavor().id +def __create_snaps_env_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 os_creds: the admin credentials for accessing OpenStack + :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() + + for name, vm_creator in vm_dict.items(): + vm_inst = vm_creator.get_vm_inst() + inst_creds = vm_creator._os_creds + if vm_inst: + out_dict['vms'].append({ + 'name': str(vm_inst.name), + 'id': str(vm_inst.id), + 'os_creds': { + 'username': inst_creds.username, + 'password': inst_creds.password, + 'auth_url': inst_creds.auth_url, + 'project_name': inst_creds.project_name, + 'identity_api_version': inst_creds.identity_api_version, + } + }) + + 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 -- cgit 1.2.3-korg