Expand OpenStackSecurityGroup class tests.
[snaps.git] / snaps / openstack / utils / nova_utils.py
index db9a666..ab434f1 100644 (file)
@@ -45,7 +45,8 @@ def nova_client(os_creds):
     """
     logger.debug('Retrieving Nova Client')
     return Client(os_creds.compute_api_version,
-                  session=keystone_utils.keystone_session(os_creds))
+                  session=keystone_utils.keystone_session(os_creds),
+                  region_name=os_creds.region_name)
 
 
 def create_server(nova, neutron, glance, instance_settings, image_settings,
@@ -69,7 +70,7 @@ def create_server(nova, neutron, glance, instance_settings, image_settings,
     nics = []
     for port in ports:
         kv = dict()
-        kv['port-id'] = port['port']['id']
+        kv['port-id'] = port.id
         nics.append(kv)
 
     logger.info('Creating VM with name - ' + instance_settings.name)
@@ -79,9 +80,8 @@ def create_server(nova, neutron, glance, instance_settings, image_settings,
 
     flavor = get_flavor_by_name(nova, instance_settings.flavor)
     if not flavor:
-        raise Exception(
-            'Flavor not found with name - %s',
-            instance_settings.flavor)
+        raise NovaException(
+            'Flavor not found with name - %s', instance_settings.flavor)
 
     image = glance_utils.get_image(glance, image_settings.name)
     if image:
@@ -92,14 +92,16 @@ def create_server(nova, neutron, glance, instance_settings, image_settings,
                 'key_name': keypair_name,
                 'security_groups':
                     instance_settings.security_group_names,
-                'userdata': instance_settings.userdata,
-                'availability_zone':
-                    instance_settings.availability_zone}
+                'userdata': instance_settings.userdata}
+
+        if instance_settings.availability_zone:
+            args['availability_zone'] = instance_settings.availability_zone
+
         server = nova.servers.create(**args)
         return VmInst(name=server.name, inst_id=server.id,
                       networks=server.networks)
     else:
-        raise Exception(
+        raise NovaException(
             'Cannot create instance, image cannot be located with name %s',
             image_settings.name)
 
@@ -109,7 +111,7 @@ def get_servers_by_name(nova, name):
     Returns a list of servers with a given name
     :param nova: the Nova client
     :param name: the server name
-    :return: the list of servers
+    :return: the list of snaps.domain.VmInst objects
     """
     out = list()
     servers = nova.servers.list(search_opts={'name': name})
@@ -119,7 +121,7 @@ def get_servers_by_name(nova, name):
     return out
 
 
-def get_latest_server_os_object(nova, server):
+def __get_latest_server_os_object(nova, server):
     """
     Returns a server with a given id
     :param nova: the Nova client
@@ -129,6 +131,32 @@ def get_latest_server_os_object(nova, server):
     return nova.servers.get(server.id)
 
 
+def get_server_status(nova, server):
+    """
+    Returns the a VM instance's status from OpenStack
+    :param nova: the Nova client
+    :param server: the domain VmInst object
+    :return: the VM's string status or None if not founc
+    """
+    server = __get_latest_server_os_object(nova, server)
+    if server:
+        return server.status
+    return None
+
+
+def get_server_console_output(nova, server):
+    """
+    Returns the console object for parsing VM activity
+    :param nova: the Nova client
+    :param server: the domain VmInst object
+    :return: the console output object or None if server object is not found
+    """
+    server = __get_latest_server_os_object(nova, server)
+    if server:
+        return server.get_console_output()
+    return None
+
+
 def get_latest_server_object(nova, server):
     """
     Returns a server with a given id
@@ -136,11 +164,38 @@ def get_latest_server_object(nova, server):
     :param server: the old server object
     :return: the list of servers or None if not found
     """
-    server = get_latest_server_os_object(nova, server)
+    server = __get_latest_server_os_object(nova, server)
     return VmInst(name=server.name, inst_id=server.id,
                   networks=server.networks)
 
 
+def get_server_security_group_names(nova, server):
+    """
+    Returns a server with a given id
+    :param nova: the Nova client
+    :param server: the old server object
+    :return: the list of security groups associated with a VM
+    """
+    out = list()
+    os_vm_inst = __get_latest_server_os_object(nova, server)
+    for sec_grp_dict in os_vm_inst.security_groups:
+        out.append(sec_grp_dict['name'])
+    return out
+
+
+def get_server_info(nova, server):
+    """
+    Returns a dictionary of a VMs info as returned by OpenStack
+    :param nova: the Nova client
+    :param server: the old server object
+    :return: a dict of the info if VM exists else None
+    """
+    vm = __get_latest_server_os_object(nova, server)
+    if vm:
+        return vm._info
+    return None
+
+
 def create_keys(key_size=2048):
     """
     Generates public and private keys
@@ -168,7 +223,6 @@ def save_keys_to_files(keys=None, pub_file_path=None, priv_file_path=None):
     :param keys: the keys to save generated by cryptography
     :param pub_file_path: the path to the public keys
     :param priv_file_path: the path to the private keys
-    :return: None
     """
     if keys:
         if pub_file_path:
@@ -238,7 +292,8 @@ def keypair_exists(nova, keypair_obj):
     """
     try:
         os_kp = nova.keypairs.get(keypair_obj)
-        return Keypair(name=os_kp.name, id=os_kp.id, public_key=os_kp.public_key)
+        return Keypair(name=os_kp.name, id=os_kp.id,
+                       public_key=os_kp.public_key)
     except:
         return None
 
@@ -270,16 +325,17 @@ def delete_keypair(nova, key):
     nova.keypairs.delete(key.id)
 
 
-def get_nova_availability_zones(nova):
+def get_availability_zone_hosts(nova, zone_name='nova'):
     """
     Returns the names of all nova active compute servers
     :param nova: the Nova client
+    :param zone_name: the Nova client
     :return: a list of compute server names
     """
     out = list()
     zones = nova.availability_zones.list()
     for zone in zones:
-        if zone.zoneName == 'nova':
+        if zone.zoneName == zone_name and zone.hosts:
             for key, host in zone.hosts.items():
                 if host['nova-compute']['available']:
                     out.append(zone.zoneName + ':' + key)
@@ -296,7 +352,7 @@ def delete_vm_instance(nova, vm_inst):
     nova.servers.delete(vm_inst.id)
 
 
-def get_os_flavor(nova, flavor):
+def __get_os_flavor(nova, flavor):
     """
     Returns to OpenStack flavor object by name
     :param nova: the Nova client
@@ -316,7 +372,7 @@ def get_flavor(nova, flavor):
     :param flavor: the SNAPS flavor domain object
     :return: the SNAPS Flavor domain object
     """
-    os_flavor = get_os_flavor(nova, flavor)
+    os_flavor = __get_os_flavor(nova, flavor)
     if os_flavor:
         return Flavor(
             name=os_flavor.name, id=os_flavor.id, ram=os_flavor.ram,
@@ -329,7 +385,7 @@ def get_flavor(nova, flavor):
         return None
 
 
-def get_os_flavor_by_name(nova, name):
+def __get_os_flavor_by_name(nova, name):
     """
     Returns to OpenStack flavor object by name
     :param nova: the Nova client
@@ -349,7 +405,7 @@ def get_flavor_by_name(nova, name):
     :param name: the flavor name to return
     :return: the SNAPS flavor domain object or None if not exists
     """
-    os_flavor = get_os_flavor_by_name(nova, name)
+    os_flavor = __get_os_flavor_by_name(nova, name)
     if os_flavor:
         return Flavor(
             name=os_flavor.name, id=os_flavor.id, ram=os_flavor.ram,
@@ -394,11 +450,22 @@ def set_flavor_keys(nova, flavor, metadata):
     :param flavor: the SNAPS flavor domain object
     :param metadata: the metadata to set
     """
-    os_flavor = get_os_flavor(nova, flavor)
+    os_flavor = __get_os_flavor(nova, flavor)
     if os_flavor:
         os_flavor.set_keys(metadata)
 
 
+def get_flavor_keys(nova, flavor):
+    """
+    Sets metadata on the flavor
+    :param nova: the Nova client
+    :param flavor: the SNAPS flavor domain object
+    """
+    os_flavor = __get_os_flavor(nova, flavor)
+    if os_flavor:
+        return os_flavor.get_keys()
+
+
 def add_security_group(nova, vm, security_group_name):
     """
     Adds a security group to an existing VM
@@ -414,10 +481,9 @@ def remove_security_group(nova, vm, security_group):
     Removes a security group from an existing VM
     :param nova: the nova client
     :param vm: the OpenStack server object (VM) to alter
-    :param security_group: the OpenStack security group object to add
+    :param security_group: the SNAPS SecurityGroup domain object to add
     """
-    nova.servers.remove_security_group(
-        str(vm.id), security_group['security_group']['name'])
+    nova.servers.remove_security_group(str(vm.id), security_group.name)
 
 
 def add_floating_ip_to_server(nova, vm, floating_ip, ip_addr):
@@ -428,5 +494,11 @@ def add_floating_ip_to_server(nova, vm, floating_ip, ip_addr):
     :param floating_ip: FloatingIp domain object
     :param ip_addr: the IP to which to bind the floating IP to
     """
-    vm = get_latest_server_os_object(nova, vm)
+    vm = __get_latest_server_os_object(nova, vm)
     vm.add_floating_ip(floating_ip.ip, ip_addr)
+
+
+class NovaException(Exception):
+    """
+    Exception when calls to the Keystone client cannot be served properly
+    """