Fix interface ordering for bridge interfaces in translation layer
[osm/SO.git] / rwcal / plugins / vala / rwcal_openstack / rift / rwcal / openstack / openstack_drv.py
index a720b8a..ae12b13 100644 (file)
@@ -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
@@ -263,7 +277,7 @@ 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):
         """
         Constructor for KeystoneDriverV3 class
         Arguments:
@@ -274,26 +288,41 @@ class KeystoneDriverV3(KeystoneDriver):
 
         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
         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
         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
@@ -340,6 +369,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):
@@ -529,7 +561,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
@@ -552,22 +585,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
@@ -836,6 +870,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
@@ -877,7 +931,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):
     """
@@ -1383,6 +1437,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:
@@ -1617,7 +1673,7 @@ 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):
         """
         OpenstackDriver Driver constructor
         Arguments:
@@ -1632,21 +1688,24 @@ class OpenstackDriver(object):
         """
         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)
             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.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
 
@@ -1724,10 +1783,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)
@@ -1793,6 +1861,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()
 
@@ -1999,3 +2070,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)
+