Bug 129 82/782/1
authorHashir Mohammed <hashir.mohammed@riftio.com>
Mon, 12 Dec 2016 09:00:52 +0000 (04:00 -0500)
committerHashir Mohammed <hashir.mohammed@riftio.com>
Mon, 12 Dec 2016 09:01:10 +0000 (04:01 -0500)
     RIFT-15122

    * Added support for domain in Opnestack for KeyStone API v3
      * Added two new YANG model object user-domain and project-domain
      *  user-domain and project domain default to the value 'default'
      * Changed the Nova service name from computev21 to compute
      * Added test cases to verify the new feature and backward compatability

     Reviewers: TBD Rajesh, Ravu, Aniruddha

Signed-off-by: Hashir Mohammed <hashir.mohammed@riftio.com>
rwcal/plugins/vala/rwcal_openstack/rift/rwcal/openstack/openstack_drv.py
rwcal/plugins/vala/rwcal_openstack/rwcal_openstack.py
rwcal/plugins/yang/rwcal.yang
rwcal/test/test_rwcal_openstack.py

index 943cdd5..90cefa1 100644 (file)
@@ -70,6 +70,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 +275,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 +286,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 +367,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):
@@ -899,7 +929,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):
     """
@@ -1639,7 +1669,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:
@@ -1654,7 +1684,7 @@ 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)
index 05dc498..d3c0b97 100644 (file)
@@ -75,7 +75,6 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud):
         self._rwlog_handler = None
         RwcalOpenstackPlugin.instance_num += 1
 
-
     @contextlib.contextmanager
     def _use_driver(self, account):
         if self._rwlog_handler is None:
@@ -83,12 +82,14 @@ class RwcalOpenstackPlugin(GObject.Object, RwCal.Cloud):
 
         with rwlogger.rwlog_root_handler(self._rwlog_handler):
             try:
-                drv = self._driver_class(username      = account.openstack.key,
-                                         password      = account.openstack.secret,
-                                         auth_url      = account.openstack.auth_url,
-                                         tenant_name   = account.openstack.tenant,
-                                         mgmt_network  = account.openstack.mgmt_network,
-                                         cert_validate = account.openstack.cert_validate )
+                drv = self._driver_class(username            = account.openstack.key,
+                                         password            = account.openstack.secret,
+                                         auth_url            = account.openstack.auth_url,
+                                         tenant_name         = account.openstack.tenant,
+                                         mgmt_network        = account.openstack.mgmt_network,
+                                         cert_validate       = account.openstack.cert_validate,
+                                         user_domain_name    = account.openstack.user_domain,
+                                         project_domain_name = account.openstack.project_domain)
             except (KeystoneExceptions.Unauthorized, KeystoneExceptions.AuthorizationFailure,
                         NeutronException.NotFound) as e:
                 raise
index 76bd38b..e038c47 100644 (file)
@@ -231,6 +231,17 @@ module rwcal
           mandatory true;
         }
 
+        leaf user-domain {
+          type string;
+          default "Default";
+          description "Domain of the OpenStack user";
+        }
+        leaf project-domain {
+          type string;
+          default "Default";
+          description "Domain of the OpenStack project";
+        }
+
         leaf tenant {
           type string;
           mandatory true;
index 960beb9..d0d7d62 100644 (file)
@@ -20,7 +20,6 @@ import logging
 import time
 import unittest
 import hashlib
-
 import novaclient.exceptions as nova_exception
 import paramiko
 import rw_peas
@@ -29,7 +28,7 @@ from keystoneclient import v3 as ksclient
 
 from gi.repository import RwcalYang
 from gi.repository.RwTypes import RwStatus
-from rift.rwcal.openstack.openstack_drv import KeystoneDriver, NovaDriver
+from rift.rwcal.openstack.openstack_drv import KeystoneDriver, NovaDriver, KeystoneDriverV3, KeystoneDriverV2
 
 logger = logging.getLogger('rwcal-openstack')
 
@@ -46,7 +45,22 @@ openstack_info = {
     'reserved_image'     : 'Fedora-x86_64-20-20131211.1-sda-ping.qcow2',
     'physical_network'   : None,
     'network_type'       : None,
-    'segmentation_id'    : None
+    'segmentation_id'    : None,
+    'user_domain_name'   : 'default',
+    'project_domain_name': 'default'
+    }
+
+openstack_V3_info = {
+    'username'           : 'riftdev_admin',
+    'password'           : 'mypasswd',
+    'auth_url'           : 'http://10.68.0.11:5000/v3/',
+    'project_name'       : 'demov3',
+    'mgmt_network'       : 'center',
+    'physical_network'   : None,
+    'network_type'       : None,
+    'segmentation_id'    : None,
+    'user_domain_name'   : 'riftdev',
+    'project_domain_name': 'riftdev'
     }
 
 
@@ -54,14 +68,16 @@ def get_cal_account():
     """
     Creates an object for class RwcalYang.CloudAccount()
     """
-    account                        = RwcalYang.CloudAccount()
-    account.name                   = "Gruntxx"
-    account.account_type           = "openstack"
-    account.openstack.key          = openstack_info['username']
-    account.openstack.secret       = openstack_info['password']
-    account.openstack.auth_url     = openstack_info['auth_url']
-    account.openstack.tenant       = openstack_info['project_name']
-    account.openstack.mgmt_network = openstack_info['mgmt_network']
+    account                          = RwcalYang.CloudAccount()
+    account.name                     = "Gruntxx"
+    account.account_type             = "openstack"
+    account.openstack.key            = openstack_info['username']
+    account.openstack.secret         = openstack_info['password']
+    account.openstack.auth_url       = openstack_info['auth_url']
+    account.openstack.tenant         = openstack_info['project_name']
+    account.openstack.mgmt_network   = openstack_info['mgmt_network']
+    account.openstack.user_domain    = openstack_info['user_domain_name']
+    account.openstack.project_domain = openstack_info['project_domain_name']
     return account
 
 def get_cal_plugin():
@@ -531,6 +547,7 @@ class OpenStackTest(unittest.TestCase):
                 openstack_info['username'],
                 openstack_info['password'],
                 openstack_info['auth_url'],
+                None,
                 openstack_info['project_name'])
         # Get hold of the client instance need for Token Manager
         client = drv._get_keystone_connection()
@@ -566,6 +583,81 @@ class OpenStackTest(unittest.TestCase):
         flavors = nova.flavor_list()
         self.assertTrue(len(flavors) > 1)
 
+    def test_v3_Keystone(self):
+        # Keystone v3 authentication
+        auth_exp = False
+        try:
+            drv = KeystoneDriverV3(openstack_V3_info['username'],
+                    openstack_V3_info['password'],
+                    openstack_V3_info['auth_url'],
+                    openstack_V3_info['project_name'],
+                    None,
+                    openstack_V3_info['user_domain_name'],
+                    openstack_V3_info['project_domain_name'])
+            client = drv._get_keystone_connection()
+        except Exception:
+            auth_exp = True
+        self.assertFalse(auth_exp)
+
+        # Incorrect domain being to passed to v3 Keystone API
+        auth_exp = False
+        try:
+            drv = KeystoneDriverV3(openstack_V3_info['username'],
+                    openstack_V3_info['password'],
+                    openstack_V3_info['auth_url'],
+                    openstack_V3_info['project_name'],
+                    None,
+                    "DummyDom",
+                    openstack_V3_info['project_domain_name'])
+            client = drv._get_keystone_connection()
+        except Exception:
+            auth_exp = True
+        self.assertTrue(auth_exp)
+
+        # Keystone v3 authentication-Backward compatabilty test
+        auth_exp = False
+        try:
+            drv = KeystoneDriverV3(openstack_info['username'],
+                    openstack_info['password'],
+                    openstack_info['auth_url'],
+                    openstack_info['project_name'],
+                    None,
+                    openstack_info['user_domain_name'],
+                    openstack_info['project_domain_name'])
+            client = drv._get_keystone_connection()
+        except Exception:
+            auth_exp = True
+        self.assertFalse(auth_exp)
+
+        # Keystone v3 authentication-Backward compatabilty
+        auth_exp = False
+        try:
+            drv = KeystoneDriverV3(openstack_info['username'],
+                    openstack_info['password'],
+                    openstack_info['auth_url'],
+                    openstack_info['project_name'],
+                    None,
+                    None,
+                    None)
+            client = drv._get_keystone_connection()
+        except Exception:
+            auth_exp = True
+        self.assertFalse(auth_exp)
+
+        # Keystone v2 authentication
+        auth_exp = False
+        try:
+            drv2 = KeystoneDriverV2(
+                    openstack_info['username'],
+                    openstack_info['password'],
+                    'http://10.66.4.17:5000/v2.0',
+                    openstack_info['project_name'],
+                    None)
+            client = drv2._get_keystone_connection()
+        except Exception: 
+            auth_exp = True
+        self.assertFalse(auth_exp)
+
     @unittest.skip("Skipping test_vm_operations")
     def test_vm_operations(self):
         """