+ if not session:
+ session = keystone_utils.keystone_session(os_creds)
+
+ return Client(os_creds.compute_api_version,
+ session=session,
+ region_name=os_creds.region_name)
+
+
+def create_server(nova, keystone, neutron, glance, instance_config,
+ image_config, project_name, keypair_config=None):
+ """
+ Creates a VM instance
+ :param nova: the nova client (required)
+ :param keystone: the keystone client for retrieving projects (required)
+ :param neutron: the neutron client for retrieving ports (required)
+ :param glance: the glance client (required)
+ :param instance_config: the VMInstConfig object (required)
+ :param image_config: the VM's ImageConfig object (required)
+ :param project_name: the associated project name (required)
+ :param keypair_config: the VM's KeypairConfig object (optional)
+ :return: a snaps.domain.VmInst object
+ """
+
+ ports = list()
+
+ for port_setting in instance_config.port_settings:
+ port = neutron_utils.get_port(
+ neutron, keystone, port_settings=port_setting,
+ project_name=project_name)
+ if port:
+ ports.append(port)
+ else:
+ raise Exception('Cannot find port named - ' + port_setting.name)
+ nics = []
+ for port in ports:
+ kv = dict()
+ kv['port-id'] = port.id
+ nics.append(kv)
+
+ logger.info('Creating VM with name - ' + instance_config.name)
+ keypair_name = None
+ if keypair_config:
+ keypair_name = keypair_config.name
+
+ flavor = get_flavor_by_name(nova, instance_config.flavor)
+ if not flavor:
+ raise NovaException(
+ 'Flavor not found with name - %s', instance_config.flavor)
+
+ image = glance_utils.get_image(glance, image_settings=image_config)
+ if image:
+ userdata = None
+ if instance_config.userdata:
+ if isinstance(instance_config.userdata, str):
+ userdata = instance_config.userdata + '\n'
+ elif (isinstance(instance_config.userdata, dict) and
+ 'script_file' in instance_config.userdata):
+ try:
+ userdata = file_utils.read_file(
+ instance_config.userdata['script_file'])
+ except Exception as e:
+ logger.warn('error reading userdata file %s - %s',
+ instance_config.userdata, e)
+ args = {'name': instance_config.name,
+ 'flavor': flavor,
+ 'image': image,
+ 'nics': nics,
+ 'key_name': keypair_name,
+ 'security_groups':
+ instance_config.security_group_names,
+ 'userdata': userdata}
+
+ if instance_config.availability_zone:
+ args['availability_zone'] = instance_config.availability_zone
+
+ server = nova.servers.create(**args)
+
+ return __map_os_server_obj_to_vm_inst(
+ neutron, keystone, server, project_name)
+ else:
+ raise NovaException(
+ 'Cannot create instance, image cannot be located with name %s',
+ image_config.name)
+
+
+def get_server(nova, neutron, keystone, vm_inst_settings=None,
+ server_name=None, project_id=None):
+ """
+ Returns a VmInst object for the first server instance found.
+ :param nova: the Nova client
+ :param neutron: the Neutron client
+ :param keystone: the Keystone client
+ :param vm_inst_settings: the VmInstanceConfig object from which to build
+ the query if not None
+ :param server_name: the server with this name to return if vm_inst_settings
+ is not None
+ :param project_id: the assocaited project ID
+ :return: a snaps.domain.VmInst object or None if not found
+ """
+ search_opts = dict()
+ if vm_inst_settings:
+ search_opts['name'] = vm_inst_settings.name
+ elif server_name:
+ search_opts['name'] = server_name
+
+ servers = nova.servers.list(search_opts=search_opts)
+ for server in servers:
+ return __map_os_server_obj_to_vm_inst(
+ neutron, keystone, server, project_id)
+
+
+def get_server_connection(nova, vm_inst_settings=None, server_name=None):
+ """
+ Returns a VmInst object for the first server instance found.
+ :param nova: the Nova client
+ :param vm_inst_settings: the VmInstanceConfig object from which to build
+ the query if not None
+ :param server_name: the server with this name to return if vm_inst_settings
+ is not None
+ :return: a snaps.domain.VmInst object or None if not found
+ """
+ search_opts = dict()
+ if vm_inst_settings:
+ search_opts['name'] = vm_inst_settings.name
+ elif server_name:
+ search_opts['name'] = server_name
+
+ servers = nova.servers.list(search_opts=search_opts)
+ for server in servers:
+ return server.links[0]
+
+
+def __map_os_server_obj_to_vm_inst(neutron, keystone, os_server,
+ project_name=None):
+ """
+ Returns a VmInst object for an OpenStack Server object
+ :param neutron: the Neutron client
+ :param keystone: the Keystone client
+ :param os_server: the OpenStack server object
+ :param project_name: the associated project name
+ :return: an equivalent SNAPS-OO VmInst domain object
+ """
+ sec_grp_names = list()
+ # VM must be active for 'security_groups' attr to be initialized
+ if hasattr(os_server, 'security_groups'):
+ for sec_group in os_server.security_groups:
+ if sec_group.get('name'):
+ sec_grp_names.append(sec_group.get('name'))
+
+ out_ports = list()
+ if len(os_server.networks) > 0:
+ for net_name, ips in os_server.networks.items():
+ network = neutron_utils.get_network(
+ neutron, keystone, network_name=net_name,
+ project_name=project_name)
+ ports = neutron_utils.get_ports(neutron, network, ips)
+ for port in ports:
+ out_ports.append(port)
+
+ volumes = None
+ if hasattr(os_server, 'os-extended-volumes:volumes_attached'):
+ volumes = getattr(os_server, 'os-extended-volumes:volumes_attached')
+
+ return VmInst(
+ name=os_server.name, inst_id=os_server.id,
+ image_id=os_server.image['id'], flavor_id=os_server.flavor['id'],
+ ports=out_ports, keypair_name=os_server.key_name,
+ sec_grp_names=sec_grp_names, volume_ids=volumes,
+ compute_host=os_server._info.get('OS-EXT-SRV-ATTR:host'),
+ availability_zone=os_server._info.get('OS-EXT-AZ:availability_zone'))
+
+
+def __get_latest_server_os_object(nova, server):
+ """
+ Returns a server with a given id
+ :param nova: the Nova client
+ :param server: the domain VmInst object
+ :return: the list of servers or None if not found
+ """
+ return __get_latest_server_os_object_by_id(nova, server.id)
+
+
+def __get_latest_server_os_object_by_id(nova, server_id):
+ """
+ Returns a server with a given id
+ :param nova: the Nova client
+ :param server_id: the server's ID
+ :return: the list of servers or None if not found
+ """
+ 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