Deprecating launch app and ansible support.
[snaps.git] / snaps / openstack / utils / launch_utils.py
index abf04b5..ddaad12 100644 (file)
@@ -21,8 +21,10 @@ 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
@@ -47,9 +49,14 @@ 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
+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'
 
@@ -117,7 +124,7 @@ def launch_config(config, tmplt_file, deploy, clean, clean_image):
             users_dict)
         creators.append(vol_type_dict)
 
-        # Create volume types
+        # Create volumes
         vol_dict = __create_instances(
             os_creds_dict, OpenStackVolume, VolumeConfig,
             os_config.get('volumes'), 'volume', clean, users_dict)
@@ -306,6 +313,8 @@ def __create_instances(os_creds_dict, creator_class, config_class, config,
                             creator.create()
 
                         out[inst_config['name']] = creator
+                    else:
+                        raise Exception('Unable to instantiate creator')
 
         logger.info('Initialized configured %ss', config_key)
 
@@ -414,10 +423,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)
@@ -425,12 +433,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
@@ -456,20 +465,24 @@ 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_utils.apply_playbook(
                 ansible_config['playbook_location'], floating_ips, remote_user,
-                private_key_filepath,
+                ssh_priv_key_file_path=private_key_filepath,
                 variables=variables,
                 proxy_setting=proxy_settings)
-            if retval != 0:
-                # Not a fatal type of event
-                logger.warning(
-                    'Unable to apply playbook found at location - %s',
-                    ansible_config.get('playbook_location'))
-            return retval
+
+            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):
@@ -515,13 +528,13 @@ def __get_connection_info(ansible_config, vm_dict):
     return None
 
 
-def __get_variables(var_config, os_creds, vm_dict, image_dict, flavor_dict,
-                    networks_dict, routers_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
@@ -538,7 +551,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
@@ -553,13 +566,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
@@ -577,12 +590,14 @@ def __get_variable_value(var_config_values, os_creds, vm_dict, image_dict,
     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, 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)
+                                           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':
@@ -591,6 +606,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'] == 'vm-yaml':
+        return __create_yaml(var_config_values, vm_dict)
     return None
 
 
@@ -619,13 +636,19 @@ def __get_vm_attr_variable_value(var_config_values, vm_dict):
             return vm.get_image_user()
 
 
-def __get_os_creds_variable_value(var_config_values, os_creds):
+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: the admin OpenStack OSCreds object
+    :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")
@@ -641,6 +664,21 @@ def __get_os_creds_variable_value(var_config_values, os_creds):
             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
@@ -664,6 +702,12 @@ def __get_network_variable_value(var_config_values, networks_dict):
                                 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]
@@ -682,32 +726,43 @@ def __get_network_variable_value(var_config_values, networks_dict):
                                 return broadcast_ip
 
 
-def __get_router_variable_value(var_config_values, routers_dict, os_creds):
+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: the admin OpenStack credentials
+    :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'):
-            neutron = neutron_utils.neutron_client(os_creds)
-            ext_nets = neutron_utils.get_external_networks(neutron)
+            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')
+                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']
+                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):
@@ -790,6 +845,36 @@ def __get_flavor_variable_value(var_config_values, flavor_dict):
                     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