Extend credentials to support roles

Test can request credentials to be allocated by specifying
the required credential types at class level.
Extending that mechanism to support credentials by roles as
well.

Change-Id: I2f026e553f8c2c2a4cf2cb319bcd67e7d82e0479
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 0c7fa6b..41a7d65 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -24,6 +24,8 @@
 
 class BaseObjectTest(tempest.test.BaseTestCase):
 
+    credentials = [['operator', CONF.object_storage.operator_role]]
+
     @classmethod
     def skip_checks(cls):
         super(BaseObjectTest, cls).skip_checks()
@@ -35,8 +37,9 @@
     def setup_credentials(cls):
         cls.set_network_resources()
         super(BaseObjectTest, cls).setup_credentials()
-        operator_role = CONF.object_storage.operator_role
-        cls.os = cls.get_client_manager(roles=[operator_role])
+        # credentials may be overwritten by children classes
+        if hasattr(cls, 'os_roles_operator'):
+            cls.os = cls.os_roles_operator
 
     @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 04bfee4..bbdf367 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -23,12 +23,14 @@
 
 class AccountQuotasTest(base.BaseObjectTest):
 
+    credentials = [['operator', CONF.object_storage.operator_role],
+                   ['reseller', CONF.object_storage.reseller_admin_role]]
+
     @classmethod
     def setup_credentials(cls):
         super(AccountQuotasTest, cls).setup_credentials()
-        reseller_admin_role = CONF.object_storage.reseller_admin_role
-        cls.os_reselleradmin = cls.get_client_manager(
-            roles=[reseller_admin_role])
+        cls.os = cls.os_roles_operator
+        cls.os_reselleradmin = cls.os_roles_reseller
 
     @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 524454e..1f6b978 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -25,12 +25,14 @@
 
 class AccountQuotasNegativeTest(base.BaseObjectTest):
 
+    credentials = [['operator', CONF.object_storage.operator_role],
+                   ['reseller', CONF.object_storage.reseller_admin_role]]
+
     @classmethod
     def setup_credentials(cls):
         super(AccountQuotasNegativeTest, cls).setup_credentials()
-        reseller_admin_role = CONF.object_storage.reseller_admin_role
-        cls.os_reselleradmin = cls.get_client_manager(
-            roles=[reseller_admin_role])
+        cls.os = cls.os_roles_operator
+        cls.os_reselleradmin = cls.os_roles_reseller
 
     @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 44b24d5..41963a6 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -29,13 +29,15 @@
 
 class AccountTest(base.BaseObjectTest):
 
+    credentials = [['operator', CONF.object_storage.operator_role],
+                   ['operator_alt', CONF.object_storage.operator_role]]
     containers = []
 
     @classmethod
     def setup_credentials(cls):
         super(AccountTest, cls).setup_credentials()
-        cls.os_operator = cls.get_client_manager(
-            roles=[CONF.object_storage.operator_role], force_new=True)
+        cls.os = cls.os_roles_operator
+        cls.os_operator = cls.os_roles_operator_alt
 
     @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 dfc5dfa..998c2bd 100644
--- a/tempest/api/object_storage/test_account_services_negative.py
+++ b/tempest/api/object_storage/test_account_services_negative.py
@@ -23,11 +23,14 @@
 
 class AccountNegativeTest(base.BaseObjectTest):
 
+    credentials = [['operator', CONF.object_storage.operator_role],
+                   ['operator_alt', CONF.object_storage.operator_role]]
+
     @classmethod
     def setup_credentials(cls):
         super(AccountNegativeTest, cls).setup_credentials()
-        cls.os_operator = cls.get_client_manager(
-            roles=[CONF.object_storage.operator_role], force_new=True)
+        cls.os = cls.os_roles_operator
+        cls.os_operator = cls.os_roles_operator_alt
 
     @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 eaf5bf0..b873063 100644
--- a/tempest/api/object_storage/test_container_acl.py
+++ b/tempest/api/object_storage/test_container_acl.py
@@ -24,11 +24,14 @@
 
 class ObjectTestACLs(base.BaseObjectTest):
 
+    credentials = [['operator', CONF.object_storage.operator_role],
+                   ['operator_alt', CONF.object_storage.operator_role]]
+
     @classmethod
     def setup_credentials(cls):
         super(ObjectTestACLs, cls).setup_credentials()
-        cls.os_operator = cls.get_client_manager(
-            roles=[CONF.object_storage.operator_role], force_new=True)
+        cls.os = cls.os_roles_operator
+        cls.os_operator = cls.os_roles_operator_alt
 
     @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 2d43b74..8c6e6eb 100644
--- a/tempest/api/object_storage/test_container_acl_negative.py
+++ b/tempest/api/object_storage/test_container_acl_negative.py
@@ -24,11 +24,14 @@
 
 class ObjectACLsNegativeTest(base.BaseObjectTest):
 
+    credentials = [['operator', CONF.object_storage.operator_role],
+                   ['operator_alt', CONF.object_storage.operator_role]]
+
     @classmethod
     def setup_credentials(cls):
         super(ObjectACLsNegativeTest, cls).setup_credentials()
-        cls.os_operator = cls.get_client_manager(
-            roles=[CONF.object_storage.operator_role], force_new=True)
+        cls.os = cls.os_roles_operator
+        cls.os_operator = cls.os_roles_operator_alt
 
     @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 4c0723d..06e700b 100644
--- a/tempest/api/object_storage/test_container_sync.py
+++ b/tempest/api/object_storage/test_container_sync.py
@@ -37,11 +37,14 @@
 class ContainerSyncTest(base.BaseObjectTest):
     clients = {}
 
+    credentials = [['operator', CONF.object_storage.operator_role],
+                   ['operator_alt', CONF.object_storage.operator_role]]
+
     @classmethod
     def setup_credentials(cls):
         super(ContainerSyncTest, cls).setup_credentials()
-        cls.os_alt = cls.get_client_manager(
-            roles=[CONF.object_storage.operator_role], force_new=True)
+        cls.os = cls.os_roles_operator
+        cls.os_alt = cls.os_roles_operator_alt
 
     @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 6a524ca..7149399 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -1007,11 +1007,14 @@
 
 class PublicObjectTest(base.BaseObjectTest):
 
+    credentials = [['operator', CONF.object_storage.operator_role],
+                   ['operator_alt', CONF.object_storage.operator_role]]
+
     @classmethod
     def setup_credentials(cls):
         super(PublicObjectTest, cls).setup_credentials()
-        cls.os_alt = cls.get_client_manager(
-            roles=[CONF.object_storage.operator_role], force_new=True)
+        cls.os = cls.os_roles_operator
+        cls.os_alt = cls.os_roles_operator_alt
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/test.py b/tempest/test.py
index ed8d12c..e1babc1 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -229,7 +229,9 @@
     _service = None
 
     # NOTE(andreaf) credentials holds a list of the credentials to be allocated
-    # at class setup time. Credential types can be 'primary', 'alt' or 'admin'
+    # at class setup time. Credential types can be 'primary', 'alt', 'admin' or
+    # a list of roles - the first element of the list being a label, and the
+    # rest the actual roles
     credentials = []
     network_resources = {}
 
@@ -341,19 +343,24 @@
             # This may raise an exception in case credentials are not available
             # In that case we want to let the exception through and the test
             # fail accordingly
-            manager = cls.get_client_manager(
-                credential_type=credentials_type)
-            setattr(cls, 'os_%s' % credentials_type, manager)
-            # Setup some common aliases
-            # TODO(andreaf) The aliases below are a temporary hack
-            # to avoid changing too much code in one patch. They should
-            # be removed eventually
-            if credentials_type == 'primary':
-                cls.os = cls.manager = cls.os_primary
-            if credentials_type == 'admin':
-                cls.os_adm = cls.admin_manager = cls.os_admin
-            if credentials_type == 'alt':
-                cls.alt_manager = cls.os_alt
+            if isinstance(credentials_type, six.string_types):
+                manager = cls.get_client_manager(
+                    credential_type=credentials_type)
+                setattr(cls, 'os_%s' % credentials_type, manager)
+                # Setup some common aliases
+                # TODO(andreaf) The aliases below are a temporary hack
+                # to avoid changing too much code in one patch. They should
+                # be removed eventually
+                if credentials_type == 'primary':
+                    cls.os = cls.manager = cls.os_primary
+                if credentials_type == 'admin':
+                    cls.os_adm = cls.admin_manager = cls.os_admin
+                if credentials_type == 'alt':
+                    cls.alt_manager = cls.os_alt
+            elif isinstance(credentials_type, list):
+                manager = cls.get_client_manager(roles=credentials_type[1:],
+                                                 force_new=True)
+                setattr(cls, 'os_roles_%s' % credentials_type[0], manager)
 
     @classmethod
     def setup_clients(cls):