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)
"""
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
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
"""
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:
password (string) : Password
auth_url (string) : Authentication URL
tenant_name(string): Tenant Name
-
+ region (string) : Region name
Returns: None
"""
self._username = username
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):
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):
"""
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:
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
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):
{
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
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
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
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):
"""
"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:
"""
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:
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
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
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)
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()
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)
+