Merge "Extend get_client_manager to support roles"
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 8bc9b12..0c7fa6b 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -15,8 +15,6 @@
 
 from tempest_lib import exceptions as lib_exc
 
-from tempest import clients
-from tempest.common import credentials
 from tempest.common import custom_matchers
 from tempest import config
 import tempest.test
@@ -38,19 +36,7 @@
         cls.set_network_resources()
         super(BaseObjectTest, cls).setup_credentials()
         operator_role = CONF.object_storage.operator_role
-        # There are no credentials by type used by object storage tests so
-        # isolated_creds must still be initialized
-        cls.isolated_creds = credentials.get_isolated_credentials(
-            cls.__name__, network_resources=cls.network_resources)
-        if not cls.isolated_creds.is_role_available(operator_role):
-            skip_msg = ("%s skipped because the configured credential provider"
-                        " is not able to provide credentials with the %s role "
-                        "assigned." % (cls.__name__, operator_role))
-            raise cls.skipException(skip_msg)
-        else:
-            # Get isolated creds for normal user
-            cls.os = clients.Manager(cls.isolated_creds.get_creds_by_roles(
-                [operator_role]))
+        cls.os = cls.get_client_manager(roles=[operator_role])
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index 364d6e1..04bfee4 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -15,7 +15,6 @@
 from tempest_lib.common.utils import data_utils
 
 from tempest.api.object_storage import base
-from tempest import clients
 from tempest import config
 from tempest import test
 
@@ -28,15 +27,8 @@
     def setup_credentials(cls):
         super(AccountQuotasTest, cls).setup_credentials()
         reseller_admin_role = CONF.object_storage.reseller_admin_role
-        if not cls.isolated_creds.is_role_available(reseller_admin_role):
-            skip_msg = ("%s skipped because the configured credential provider"
-                        " is not able to provide credentials with the %s role "
-                        "assigned." % (cls.__name__, reseller_admin_role))
-            raise cls.skipException(skip_msg)
-        else:
-            cls.os_reselleradmin = clients.Manager(
-                cls.isolated_creds.get_creds_by_roles(
-                    roles=[reseller_admin_role]))
+        cls.os_reselleradmin = cls.get_client_manager(
+            roles=[reseller_admin_role])
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/object_storage/test_account_quotas_negative.py b/tempest/api/object_storage/test_account_quotas_negative.py
index b32943c..a11b407 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -17,7 +17,6 @@
 from tempest_lib import exceptions as lib_exc
 
 from tempest.api.object_storage import base
-from tempest import clients
 from tempest import config
 from tempest import test
 
@@ -30,15 +29,8 @@
     def setup_credentials(cls):
         super(AccountQuotasNegativeTest, cls).setup_credentials()
         reseller_admin_role = CONF.object_storage.reseller_admin_role
-        if not cls.isolated_creds.is_role_available(reseller_admin_role):
-            skip_msg = ("%s skipped because the configured credential provider"
-                        " is not able to provide credentials with the %s role "
-                        "assigned." % (cls.__name__, reseller_admin_role))
-            raise cls.skipException(skip_msg)
-        else:
-            cls.os_reselleradmin = clients.Manager(
-                cls.isolated_creds.get_creds_by_roles(
-                    roles=[reseller_admin_role]))
+        cls.os_reselleradmin = cls.get_client_manager(
+            roles=[reseller_admin_role])
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index 918bd5a..c28a3e0 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -20,7 +20,6 @@
 import testtools
 
 from tempest.api.object_storage import base
-from tempest import clients
 from tempest.common import custom_matchers
 from tempest import config
 from tempest import test
@@ -35,9 +34,8 @@
     @classmethod
     def setup_credentials(cls):
         super(AccountTest, cls).setup_credentials()
-        cls.os_operator = clients.Manager(
-            cls.isolated_creds.get_creds_by_roles(
-                roles=[CONF.object_storage.operator_role], force_new=True))
+        cls.os_operator = cls.get_client_manager(
+            roles=[CONF.object_storage.operator_role], force_new=True)
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/object_storage/test_account_services_negative.py b/tempest/api/object_storage/test_account_services_negative.py
index feccf18..dfc5dfa 100644
--- a/tempest/api/object_storage/test_account_services_negative.py
+++ b/tempest/api/object_storage/test_account_services_negative.py
@@ -15,7 +15,6 @@
 from tempest_lib import exceptions as lib_exc
 
 from tempest.api.object_storage import base
-from tempest import clients
 from tempest import config
 from tempest import test
 
@@ -27,9 +26,8 @@
     @classmethod
     def setup_credentials(cls):
         super(AccountNegativeTest, cls).setup_credentials()
-        cls.os_operator = clients.Manager(
-            cls.isolated_creds.get_creds_by_roles(
-                roles=[CONF.object_storage.operator_role], force_new=True))
+        cls.os_operator = cls.get_client_manager(
+            roles=[CONF.object_storage.operator_role], force_new=True)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('070e6aca-6152-4867-868d-1118d68fb38c')
diff --git a/tempest/api/object_storage/test_container_acl.py b/tempest/api/object_storage/test_container_acl.py
index 1003f82..25dac6b 100644
--- a/tempest/api/object_storage/test_container_acl.py
+++ b/tempest/api/object_storage/test_container_acl.py
@@ -16,7 +16,6 @@
 from tempest_lib.common.utils import data_utils
 
 from tempest.api.object_storage import base
-from tempest import clients
 from tempest import config
 from tempest import test
 
@@ -28,9 +27,8 @@
     @classmethod
     def setup_credentials(cls):
         super(ObjectTestACLs, cls).setup_credentials()
-        cls.os_operator = clients.Manager(
-            cls.isolated_creds.get_creds_by_roles(
-                roles=[CONF.object_storage.operator_role], force_new=True))
+        cls.os_operator = cls.get_client_manager(
+            roles=[CONF.object_storage.operator_role], force_new=True)
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/object_storage/test_container_acl_negative.py b/tempest/api/object_storage/test_container_acl_negative.py
index 2c6d3cc..31c301a 100644
--- a/tempest/api/object_storage/test_container_acl_negative.py
+++ b/tempest/api/object_storage/test_container_acl_negative.py
@@ -16,7 +16,6 @@
 from tempest_lib import exceptions as lib_exc
 
 from tempest.api.object_storage import base
-from tempest import clients
 from tempest import config
 from tempest import test
 
@@ -28,9 +27,8 @@
     @classmethod
     def setup_credentials(cls):
         super(ObjectACLsNegativeTest, cls).setup_credentials()
-        cls.os_operator = clients.Manager(
-            cls.isolated_creds.get_creds_by_roles(
-                roles=[CONF.object_storage.operator_role], force_new=True))
+        cls.os_operator = cls.get_client_manager(
+            roles=[CONF.object_storage.operator_role], force_new=True)
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/object_storage/test_container_sync.py b/tempest/api/object_storage/test_container_sync.py
index 53bcfa6..4c0723d 100644
--- a/tempest/api/object_storage/test_container_sync.py
+++ b/tempest/api/object_storage/test_container_sync.py
@@ -22,7 +22,6 @@
 
 
 from tempest.api.object_storage import base
-from tempest import clients
 from tempest import config
 from tempest import test
 
@@ -41,8 +40,8 @@
     @classmethod
     def setup_credentials(cls):
         super(ContainerSyncTest, cls).setup_credentials()
-        cls.os_alt = clients.Manager(cls.isolated_creds.get_creds_by_roles(
-            [CONF.object_storage.operator_role], force_new=True))
+        cls.os_alt = cls.get_client_manager(
+            roles=[CONF.object_storage.operator_role], force_new=True)
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 8075e91..b02f178 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -24,7 +24,6 @@
 from tempest_lib.common.utils import data_utils
 
 from tempest.api.object_storage import base
-from tempest import clients
 from tempest.common import custom_matchers
 from tempest import config
 from tempest import test
@@ -993,9 +992,8 @@
     @classmethod
     def setup_credentials(cls):
         super(PublicObjectTest, cls).setup_credentials()
-        cls.os_alt = clients.Manager(
-            cls.isolated_creds.get_creds_by_roles(
-                roles=[CONF.object_storage.operator_role], force_new=True))
+        cls.os_alt = cls.get_client_manager(
+            roles=[CONF.object_storage.operator_role], force_new=True)
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py
index 35f51b9..af97794 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -17,7 +17,6 @@
 from tempest_lib import exceptions as lib_exc
 import yaml
 
-from tempest import clients
 from tempest import config
 import tempest.test
 
@@ -41,14 +40,7 @@
     def setup_credentials(cls):
         super(BaseOrchestrationTest, cls).setup_credentials()
         stack_owner_role = CONF.orchestration.stack_owner_role
-        if not cls.isolated_creds.is_role_available(stack_owner_role):
-            skip_msg = ("%s skipped because the configured credential provider"
-                        " is not able to provide credentials with the %s role "
-                        "assigned." % (cls.__name__, stack_owner_role))
-            raise cls.skipException(skip_msg)
-        else:
-            cls.os = clients.Manager(cls.isolated_creds.get_creds_by_roles(
-                [stack_owner_role]))
+        cls.os = cls.get_client_manager(roles=[stack_owner_role])
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 7e0c3b3..50aa261 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -22,7 +22,6 @@
 from tempest_lib.common.utils import data_utils
 from tempest_lib import exceptions as lib_exc
 
-from tempest import clients
 from tempest.common import fixed_network
 from tempest.common.utils.linux import remote_client
 from tempest import config
@@ -1341,15 +1340,7 @@
         cls.set_network_resources()
         super(SwiftScenarioTest, cls).setup_credentials()
         operator_role = CONF.object_storage.operator_role
-        if not cls.isolated_creds.is_role_available(operator_role):
-            skip_msg = ("%s skipped because the configured credential provider"
-                        " is not able to provide credentials with the %s role "
-                        "assigned." % (cls.__name__, operator_role))
-            raise cls.skipException(skip_msg)
-        else:
-            cls.os_operator = clients.Manager(
-                cls.isolated_creds.get_creds_by_roles(
-                    [operator_role]))
+        cls.os_operator = cls.get_client_manager(roles=[operator_role])
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/test.py b/tempest/test.py
index aa21c7a..6fe3aef 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -416,10 +416,25 @@
 
     @classmethod
     def get_client_manager(cls, identity_version=None,
-                           credential_type='primary'):
+                           credential_type=None, roles=None, force_new=None):
+        """Returns an OpenStack client manager
+
+        Returns an OpenStack client manager based on either credential_type
+        or a list of roles. If neither is specified, it defaults to
+        credential_type 'primary'
+        :param identity_version: string - v2 or v3
+        :param credential_type: string - primary, alt or admin
+        :param roles: list of roles
+
+        :returns the created client manager
+        :raises skipException: if the requested credentials are not available
         """
-        Returns an OpenStack client manager
-        """
+        if all([roles, credential_type]):
+            msg = "Cannot get credentials by type and roles at the same time"
+            raise ValueError(msg)
+        if not any([roles, credential_type]):
+            credential_type = 'primary'
+
         force_tenant_isolation = getattr(cls, 'force_tenant_isolation', None)
         identity_version = identity_version or CONF.identity.auth_version
 
@@ -431,14 +446,26 @@
                 identity_version=identity_version
             )
 
-        credentials_method = 'get_%s_creds' % credential_type
-        if hasattr(cls.isolated_creds, credentials_method):
-            creds = getattr(cls.isolated_creds, credentials_method)()
+        if roles:
+            for role in roles:
+                if not cls.isolated_creds.is_role_available(role):
+                    skip_msg = (
+                        "%s skipped because the configured credential provider"
+                        " is not able to provide credentials with the %s role "
+                        "assigned." % (cls.__name__, role))
+                    raise cls.skipException(skip_msg)
+            params = dict(roles=roles)
+            if force_new is not None:
+                params.update(force_new=force_new)
+            creds = cls.isolated_creds.get_creds_by_roles(**params)
         else:
-            raise exceptions.InvalidCredentials(
-                "Invalid credentials type %s" % credential_type)
-        os = clients.Manager(credentials=creds, service=cls._service)
-        return os
+            credentials_method = 'get_%s_creds' % credential_type
+            if hasattr(cls.isolated_creds, credentials_method):
+                creds = getattr(cls.isolated_creds, credentials_method)()
+            else:
+                raise exceptions.InvalidCredentials(
+                    "Invalid credentials type %s" % credential_type)
+        return clients.Manager(credentials=creds, service=cls._service)
 
     @classmethod
     def clear_isolated_creds(cls):