X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=rwcal%2Fplugins%2Fvala%2Frwcal_openstack%2Frift%2Frwcal%2Fopenstack%2Fopenstack_drv.py;h=191a06f42011d308814ded0e2c449ca5b0075969;hb=1e7e312528ebeedf478aefd0e7317b56c119cc1c;hp=2505da3de7b8266febdb0f4da8d068566ca666a8;hpb=255ff03a528a3090ce7f46f0a63b65da3e6f9bcf;p=osm%2FSO.git diff --git a/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py b/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py index 2505da3d..191a06f4 100644 --- a/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py +++ b/rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py @@ -26,12 +26,14 @@ from novaclient import client as nova_client from neutronclient.neutron import client as ntclient from glanceclient.v2 import client as glclient from ceilometerclient import client as ceilo_client +from cinderclient.v2 import client as cinder_client # Exceptions import novaclient.exceptions as NovaException import keystoneclient.exceptions as KeystoneExceptions import neutronclient.common.exceptions as NeutronException import glanceclient.exc as GlanceException +import cinderclient.exceptions as CinderException logger = logging.getLogger('rwcal.openstack.drv') logger.setLevel(logging.DEBUG) @@ -70,6 +72,18 @@ class KeystoneDriver(object): """ return self._tenant_name + def get_user_domain_name(self): + """ + Returns None as this field does not exist for v2. + """ + return None; + + def get_project_domain_name(self): + """ + Returns None as this field does not exist for v2. + """ + return None; + def _get_keystone_connection(self): """ Returns object of class python-keystoneclient class @@ -123,6 +137,8 @@ class KeystoneDriver(object): try: ksconn = self._get_keystone_connection() service_endpoint = ksconn.service_catalog.url_for(**endpoint_kwargs) + except (KeystoneExceptions.Unauthorized, KeystoneExceptions.AuthorizationFailure) as e: + raise except Exception as e: logger.error("OpenstackDriver: Service Catalog discovery operation failed for service_type: %s, endpoint_type: %s. Exception: %s" %(service_type, endpoint_type, str(e))) raise @@ -203,7 +219,7 @@ class KeystoneDriverV2(KeystoneDriver): """ Driver class for keystoneclient V2 APIs """ - def __init__(self, username, password, auth_url,tenant_name, insecure): + def __init__(self, username, password, auth_url,tenant_name, insecure, region): """ Constructor for KeystoneDriverV3 class Arguments: @@ -211,7 +227,7 @@ class KeystoneDriverV2(KeystoneDriver): password (string) : Password auth_url (string) : Authentication URL tenant_name(string): Tenant Name - + region (string) : Region name Returns: None """ self._username = username @@ -219,6 +235,7 @@ class KeystoneDriverV2(KeystoneDriver): self._auth_url = auth_url self._tenant_name = tenant_name self._insecure = insecure + self._region = region super(KeystoneDriverV2, self).__init__(ksclientv2.Client) def _get_keystone_credentials(self): @@ -232,6 +249,7 @@ class KeystoneDriverV2(KeystoneDriver): creds['auth_url'] = self._auth_url creds['tenant_name'] = self._tenant_name creds['insecure'] = self.get_security_mode() + creds['region_name'] = self._region return creds def get_auth_token(self): @@ -261,7 +279,14 @@ class KeystoneDriverV3(KeystoneDriver): """ Driver class for keystoneclient V3 APIs """ - def __init__(self, username, password, auth_url,tenant_name, insecure): + def __init__(self, username, + password, + auth_url, + tenant_name, + insecure, + user_domain_name = None, + project_domain_name = None, + region = None): """ Constructor for KeystoneDriverV3 class Arguments: @@ -269,29 +294,48 @@ class KeystoneDriverV3(KeystoneDriver): password (string) : Password auth_url (string) : Authentication URL tenant_name(string): Tenant Name - + user_domain_name (string) : User domain name + project_domain_name (string): Project domain name + region (string) : Region name Returns: None """ - self._username = username - self._password = password - self._auth_url = auth_url - self._tenant_name = tenant_name - self._insecure = insecure + self._username = username + self._password = password + self._auth_url = auth_url + self._tenant_name = tenant_name + self._insecure = insecure + self._user_domain_name = user_domain_name + self._project_domain_name = project_domain_name + self._region = region super(KeystoneDriverV3, self).__init__(ksclientv3.Client) def _get_keystone_credentials(self): """ Returns the dictionary of kwargs required to instantiate python-keystoneclient class """ - creds = {} - #creds['user_domain'] = self._domain_name - creds['username'] = self._username - creds['password'] = self._password - creds['auth_url'] = self._auth_url - creds['project_name'] = self._tenant_name - creds['insecure'] = self._insecure + creds = {} + creds['username'] = self._username + creds['password'] = self._password + creds['auth_url'] = self._auth_url + creds['project_name'] = self._tenant_name + creds['insecure'] = self._insecure + creds['user_domain_name'] = self._user_domain_name + creds['project_domain_name'] = self._project_domain_name + creds['region_name'] = self._region return creds + def get_user_domain_name(self): + """ + Returns the domain_name of the associated OpenStack user account + """ + return self._user_domain_name; + + def get_project_domain_name(self): + """ + Returns the domain_name of the associated OpenStack project + """ + return self._project_domain_name; + def get_auth_token(self): """ Returns a valid auth_token @@ -338,6 +382,9 @@ class NovaDriver(object): creds['project_id'] = self.ks_drv.get_tenant_name() creds['auth_token'] = self.ks_drv.get_auth_token() creds['insecure'] = self.ks_drv.get_security_mode() + #creds['user_domain_name'] = self.ks_drv.get_user_domain_name() + #creds['project_domain_name'] = self.ks_drv.get_project_domain_name() + return creds def _get_nova_connection(self): @@ -527,7 +574,8 @@ class NovaDriver(object): { server_name(string) : Name of the VM/Server flavor_id (string) : UUID of the flavor to be used for VM - image_id (string) : UUID of the image to be used VM/Server instance + image_id (string) : UUID of the image to be used VM/Server instance, + This could be None if volumes (with images) are being used network_list(List) : A List of network_ids. A port will be created in these networks port_list (List) : A List of port-ids. These ports will be added to VM. metadata (dict) : A dictionary of arbitrary key-value pairs associated with VM/server @@ -550,22 +598,23 @@ class NovaDriver(object): nvconn = self._get_nova_connection() + try: server = nvconn.servers.create(kwargs['name'], kwargs['image_id'], kwargs['flavor_id'], meta = kwargs['metadata'], - files = None, + files = kwargs['files'], reservation_id = None, min_count = None, max_count = None, userdata = kwargs['userdata'], security_groups = kwargs['security_groups'], availability_zone = kwargs['availability_zone'], - block_device_mapping = None, + block_device_mapping_v2 = kwargs['block_device_mapping_v2'], nics = nics, scheduler_hints = kwargs['scheduler_hints'], - config_drive = None) + config_drive = kwargs['config_drive']) except Exception as e: logger.info("OpenstackDriver: Create Server operation failed. Exception: %s" %(str(e))) raise @@ -834,6 +883,26 @@ class NovaDriver(object): logger.error("OpenstackDriver: Release Floating IP operation failed. Exception: %s" %str(e)) raise + def volume_list(self, server_id): + """ + List of volumes attached to the server + + Arguments: + None + Returns: + List of dictionary objects where dictionary is representation of class (novaclient.v2.volumes.Volume) + """ + nvconn = self._get_nova_connection() + try: + volumes = nvconn.volumes.get_server_volumes(server_id=server_id) + except Exception as e: + logger.error("OpenstackDriver: Get volume information failed. Exception: %s" %str(e)) + raise + + volume_info = [v.to_dict() for v in volumes] + return volume_info + + def group_list(self): """ List of Server Affinity and Anti-Affinity Groups @@ -875,7 +944,7 @@ class NovaDriverV21(NovaDriver): Constructor for NovaDriver Arguments: KeystoneDriver class object """ - super(NovaDriverV21, self).__init__(ks_drv, 'computev21', '2.1') + super(NovaDriverV21, self).__init__(ks_drv, 'compute', '2.1') class GlanceDriver(object): """ @@ -1381,6 +1450,8 @@ class NeutronDriver(object): "network_id" : kwargs['network_id'], "fixed_ips" : [ {"subnet_id": kwargs['subnet_id']}], "binding:vnic_type" : kwargs['port_type']}} + if 'port_security_enabled' in kwargs: + params["port"]["port_security_enabled"] = kwargs['port_security_enabled'] ntconn = self._get_neutron_connection() try: @@ -1615,7 +1686,15 @@ class OpenstackDriver(object): """ Driver for openstack nova, neutron, glance, keystone, swift, cinder services """ - def __init__(self, username, password, auth_url, tenant_name, mgmt_network = None, cert_validate = False): + def __init__(self, username, + password, + auth_url, + tenant_name, + mgmt_network = None, + cert_validate = False, + user_domain_name = None, + project_domain_name = None, + region = None): """ OpenstackDriver Driver constructor Arguments: @@ -1626,25 +1705,43 @@ class OpenstackDriver(object): mgmt_network(string, optional) : Management network name. Each VM created with this cloud-account will have a default interface into management network. cert_validate (boolean, optional) : In case of SSL/TLS connection if certificate validation is required or not. - + user_domain_name : Domain name for user + project_domain_name : Domain name for project + region : Region name """ insecure = not cert_validate if auth_url.find('/v3') != -1: - self.ks_drv = KeystoneDriverV3(username, password, auth_url, tenant_name, insecure) + self.ks_drv = KeystoneDriverV3(username, + password, + auth_url, + tenant_name, + insecure, + user_domain_name, + project_domain_name, + region) self.glance_drv = GlanceDriverV2(self.ks_drv) self.nova_drv = NovaDriverV21(self.ks_drv) self.neutron_drv = NeutronDriverV2(self.ks_drv) self.ceilo_drv = CeilometerDriverV2(self.ks_drv) + self.cinder_drv = CinderDriverV2(self.ks_drv) elif auth_url.find('/v2') != -1: - self.ks_drv = KeystoneDriverV2(username, password, auth_url, tenant_name, insecure) + + self.ks_drv = KeystoneDriverV2(username, + password, + auth_url, + tenant_name, + insecure, + region) self.glance_drv = GlanceDriverV2(self.ks_drv) self.nova_drv = NovaDriverV2(self.ks_drv) self.neutron_drv = NeutronDriverV2(self.ks_drv) self.ceilo_drv = CeilometerDriverV2(self.ks_drv) + self.cinder_drv = CinderDriverV2(self.ks_drv) else: logger.error("Could not identity the version information for openstack service endpoints. Auth_URL should contain \"/v2\" or \"/v3\" string in it") raise NotImplementedError("Auth URL is wrong or invalid. Only Keystone v2 & v3 supported") + self._mgmt_network_id = None if mgmt_network != None: self._mgmt_network = mgmt_network @@ -1652,6 +1749,8 @@ class OpenstackDriver(object): try: ntconn = self.neutron_drv._get_neutron_connection() networks = ntconn.list_networks() + except (KeystoneExceptions.Unauthorized, KeystoneExceptions.AuthorizationFailure) as e: + raise except Exception as e: logger.error("OpenstackDriver: List Network operation failed. Exception: %s" %(str(e))) raise @@ -1720,10 +1819,19 @@ class OpenstackDriver(object): return self.nova_drv.flavor_get(flavor_id) def nova_server_create(self, **kwargs): + def _verify_image(image_id): + image = self.glance_drv.image_get(image_id) + if image['status'] != 'active': + raise GlanceException.NotFound("Image with image_id: %s not found in active state. Current State: %s" %(image['id'], image['status'])) + assert kwargs['flavor_id'] == self.nova_drv.flavor_get(kwargs['flavor_id'])['id'] - image = self.glance_drv.image_get(kwargs['image_id']) - if image['status'] != 'active': - raise GlanceException.NotFound("Image with image_id: %s not found in active state. Current State: %s" %(image['id'], image['status'])) + + if kwargs['block_device_mapping_v2'] is not None: + for block_map in kwargs['block_device_mapping_v2']: + if 'uuid' in block_map: + _verify_image(block_map['uuid']) + else: + _verify_image(kwargs['image_id']) # if 'network_list' in kwargs: # kwargs['network_list'].append(self._mgmt_network_id) @@ -1789,6 +1897,9 @@ class OpenstackDriver(object): def nova_server_group_list(self): return self.nova_drv.group_list() + def nova_volume_list(self, server_id): + return self.nova_drv.volume_list(server_id) + def neutron_network_list(self): return self.neutron_drv.network_list() @@ -1995,3 +2106,136 @@ class OpenstackDriver(object): def ceilo_alarm_delete(self, alarm_id): self.ceilo_drv.client.alarms.delete(alarm_id) + + def cinder_volume_list(self): + return self.cinder_drv.volume_list() + + def cinder_volume_get(self,vol_id): + return self.cinder_drv.volume_get(vol_id) + + def cinder_volume_set_metadata(self, volumeid, metadata): + return self.cinder_drv.volume_set_metadata(volumeid, metadata) + + def cinder_volume_delete_metadata(self, volumeid, metadata): + return self.cinder_drv.volume_delete_metadata(volumeid, metadata) + + + +class CinderDriver(object): + """ + Driver for openstack cinder-client + """ + def __init__(self, ks_drv, service_name, version): + """ + Constructor for CinderDriver + Arguments: KeystoneDriver class object + """ + self.ks_drv = ks_drv + self._service_name = service_name + self._version = version + + def _get_cinder_credentials(self): + """ + Returns a dictionary of kwargs required to instantiate python-cinderclient class + + Arguments: None + + Returns: + A dictionary object of arguments + """ + creds = {} + creds['version'] = self._version + creds['username'] = self.ks_drv.get_username() + creds['api_key'] = self.ks_drv.get_password() + creds['auth_url'] = self.ks_drv.get_service_endpoint("identity", "publicURL") + creds['project_id'] = self.ks_drv.get_tenant_name() + creds['insecure'] = self.ks_drv.get_security_mode() + + return creds + + def _get_cinder_connection(self): + """ + Returns a object of class python-cinderclient + """ + if not hasattr(self, '_cinder_connection'): + self._cinder_connection = cinder_client.Client(**self._get_cinder_credentials()) + else: + # Reinitialize if auth_token is no longer valid + if not self.ks_drv.is_auth_token_valid(): + self._cinder_connection = cinder_client.Client(**self._get_cinder_credentials()) + return self._cinder_connection + + def volume_list(self): + """ + Returns list of dictionaries. Each dictionary contains attributes associated with + volumes + + Arguments: None + + Returns: List of dictionaries. + """ + cinderconn = self._get_cinder_connection() + volumes = [] + try: + volume_info = cinderconn.volumes.list() + except Exception as e: + logger.error("OpenstackDriver: List volumes operation failed. Exception: %s" %(str(e))) + raise + volumes = [ volume for volume in volume_info ] + return volumes + + def volume_get(self, volume_id): + """ + Get details volume + + Arguments: None + + Returns: List of dictionaries. + """ + cinderconn = self._get_cinder_connection() + try: + vol = cinderconn.volumes.get(volume_id) + except Exception as e: + logger.error("OpenstackDriver: Get volume operation failed. Exception: %s" %(str(e))) + raise + return vol + + def volume_set_metadata(self, volume_id, metadata): + """ + Set metadata for volume + Metadata is a dictionary of key-value pairs + + Arguments: None + + Returns: List of dictionaries. + """ + cinderconn = self._get_cinder_connection() + try: + cinderconn.volumes.set_metadata(volume_id, metadata) + except Exception as e: + logger.error("OpenstackDriver: Set metadata operation failed. Exception: %s" %(str(e))) + raise + + def volume_delete_metadata(self, volume_id, metadata): + """ + Delete metadata for volume + Metadata is a dictionary of key-value pairs + + Arguments: None + + Returns: List of dictionaries. + """ + cinderconn = self._get_cinder_connection() + try: + cinderconn.volumes.delete_metadata(volume_id, metadata) + except Exception as e: + logger.error("OpenstackDriver: Delete metadata operation failed. Exception: %s" %(str(e))) + raise + +class CinderDriverV2(CinderDriver): + """ + Driver for openstack cinder-client V2 + """ + def __init__(self, ks_drv): + super(CinderDriverV2, self).__init__(ks_drv, 'volumev2', 2) +