Accommodate v2 and v3 auth for integration tests

devstack has moved default Keystone API version to v3[1].

[1] https://github.com/openstack-dev/devstack/commit/f4ce44bf3fbf06e53c2ae3ec6aa4996831cf4605

Though the above patch has been reverted, this would help
if devstack removes v2 support in the future.

Change-Id: I393750d00b3712a015e48a3cf38ab5f95bb61dae
Closes-Bug: #1539692
diff --git a/common/clients.py b/common/clients.py
index 9718d03..0ba7131 100644
--- a/common/clients.py
+++ b/common/clients.py
@@ -15,13 +15,49 @@
 import ceilometerclient.client
 import cinderclient.client
 import heatclient.client
+from keystoneclient.auth.identity.generic import password
+import keystoneclient.client
 import keystoneclient.exceptions
-import keystoneclient.v2_0.client
+from keystoneclient import session
 import neutronclient.v2_0.client
 import novaclient.client
 import swiftclient
 
 
+class KeystoneWrapperClient(object):
+    """Wrapper object for keystone client
+
+    This Wraps keystone client,so we can encpasulate certain
+    added properties like auth_token, project_id etc.
+    """
+    def __init__(self, auth_plugin, verify=True):
+        self.auth_plugin = auth_plugin
+        self.session = session.Session(
+            auth=auth_plugin,
+            verify=verify)
+
+    @property
+    def auth_token(self):
+        return self.auth_plugin.get_token(self.session)
+
+    @property
+    def auth_ref(self):
+        return self.auth_plugin.get_access(self.session)
+
+    @property
+    def project_id(self):
+        return self.auth_plugin.get_project_id(self.session)
+
+    def get_endpoint_url(self, service_type, region=None):
+        kwargs = {
+            'service_type': service_type,
+            'endpoint_type': 'publicURL'}
+        if region:
+            kwargs.update({'attr': 'region',
+                           'filter_value': region})
+        return self.auth_ref.service_catalog.url_for(**kwargs)
+
+
 class ClientManager(object):
     """Provides access to the official python clients for calling various APIs.
 
@@ -36,6 +72,8 @@
 
     def __init__(self, conf):
         self.conf = conf
+        self.v2_auth_url = self.conf.auth_url.replace('/v3', '/v2.0')
+        self.auth_version = self.conf.auth_url.split('/v')[1]
         self.identity_client = self._get_identity_client()
         self.orchestration_client = self._get_orchestration_client()
         self.compute_client = self._get_compute_client()
@@ -45,20 +83,15 @@
         self.metering_client = self._get_metering_client()
 
     def _get_orchestration_client(self):
-        region = self.conf.region
         endpoint = os.environ.get('HEAT_URL')
         if os.environ.get('OS_NO_CLIENT_AUTH') == 'True':
             token = None
         else:
-            keystone = self._get_identity_client()
-            token = keystone.auth_token
+            token = self.identity_client.auth_token
         try:
             if endpoint is None:
-                endpoint = keystone.service_catalog.url_for(
-                    attr='region',
-                    filter_value=region,
-                    service_type='orchestration',
-                    endpoint_type='publicURL')
+                endpoint = self.identity_client.get_endpoint_url(
+                    'orchestration', self.conf.region)
         except keystoneclient.exceptions.EndpointNotFound:
             return None
         else:
@@ -70,12 +103,22 @@
                 password=self.conf.password)
 
     def _get_identity_client(self):
-        return keystoneclient.v2_0.client.Client(
-            username=self.conf.username,
-            password=self.conf.password,
-            tenant_name=self.conf.tenant_name,
-            auth_url=self.conf.auth_url,
-            insecure=self.conf.disable_ssl_certificate_validation)
+        domain = self.conf.domain_name
+        kwargs = {
+            'username': self.conf.username,
+            'password': self.conf.password,
+            'tenant_name': self.conf.tenant_name,
+            'auth_url': self.conf.auth_url
+        }
+        # keystone v2 can't ignore domain details
+        if self.auth_version == '3':
+            kwargs.update({
+                'project_domain_name': domain,
+                'user_domain_name': domain})
+        auth = password.Password(**kwargs)
+        return KeystoneWrapperClient(
+            auth,
+            not self.conf.disable_ssl_certificate_validation)
 
     def _get_compute_client(self):
 
@@ -86,7 +129,8 @@
             self.conf.username,
             self.conf.password,
             self.conf.tenant_name,
-            self.conf.auth_url
+            # novaclient can not use v3 url
+            self.v2_auth_url
         )
 
         # Create our default Nova client to use in testing
@@ -101,7 +145,6 @@
             http_log_debug=True)
 
     def _get_network_client(self):
-        auth_url = self.conf.auth_url
         dscv = self.conf.disable_ssl_certificate_validation
 
         return neutronclient.v2_0.client.Client(
@@ -109,11 +152,11 @@
             password=self.conf.password,
             tenant_name=self.conf.tenant_name,
             endpoint_type='publicURL',
-            auth_url=auth_url,
+            # neutronclient can not use v3 url
+            auth_url=self.v2_auth_url,
             insecure=dscv)
 
     def _get_volume_client(self):
-        auth_url = self.conf.auth_url
         region = self.conf.region
         endpoint_type = 'publicURL'
         dscv = self.conf.disable_ssl_certificate_validation
@@ -122,7 +165,8 @@
             self.conf.username,
             self.conf.password,
             self.conf.tenant_name,
-            auth_url,
+            # cinderclient can not use v3 url
+            self.v2_auth_url,
             region_name=region,
             endpoint_type=endpoint_type,
             insecure=dscv,
@@ -131,7 +175,7 @@
     def _get_object_client(self):
         dscv = self.conf.disable_ssl_certificate_validation
         args = {
-            'auth_version': '2.0',
+            'auth_version': self.auth_version,
             'tenant_name': self.conf.tenant_name,
             'user': self.conf.username,
             'key': self.conf.password,
@@ -143,15 +187,10 @@
 
     def _get_metering_client(self):
         dscv = self.conf.disable_ssl_certificate_validation
-
-        keystone = self._get_identity_client()
+        domain = self.conf.domain_name
         try:
-            endpoint = keystone.service_catalog.url_for(
-                attr='region',
-                filter_value=self.conf.region,
-                service_type='metering',
-                endpoint_type='publicURL')
-
+            endpoint = self.identity_client.get_endpoint_url('metering',
+                                                             self.conf.region)
         except keystoneclient.exceptions.EndpointNotFound:
             return None
         else:
@@ -165,6 +204,12 @@
                 'endpoint_type': 'publicURL',
                 'service_type': 'metering',
             }
+            # ceilometerclient can't ignore domain details for
+            # v2 auth_url
+            if self.auth_version == '3':
+                args.update(
+                    {'user_domain_name': domain,
+                     'project_domain_name': domain})
 
             return ceilometerclient.client.Client(self.CEILOMETER_VERSION,
                                                   endpoint, **args)