Remove need to include admin in credentials in base classes

This commit removes some excess code from the rbac_base classes,
including defining the auth_provider and setting credentials =
['primary', 'admin']. The credentials array should only be
populated with credentials needed by a test class -- but currently
admin is provided for rbac_utils, which is poor design.

This is accomplished by refactoring the constructor in RbacUtils
to instantiate an admin client manager using get_client_manager
which is available in the instance of tempest.test.BaseTestCase.
From there, it is easy to reference the admin roles client used
for switching roles. This is the only reason that admin was
provided in the credentials array above.

The following was changed:
  - refactored RbacUtils constructor to remove need to add
    'admin' to credentials array
  - refactored rbac_utils functions to avoid using auth_provider
    and to instead reference the auth_provider nested inside
    os_primary
  - adding doctring for RbacUtils
  - refactored unit tests as needed

Change-Id: Id5588f2bf8947c314d46bd3cc0ef8b5c93874fc8
diff --git a/patrole_tempest_plugin/rbac_rule_validation.py b/patrole_tempest_plugin/rbac_rule_validation.py
index c088ce7..0a101d7 100644
--- a/patrole_tempest_plugin/rbac_rule_validation.py
+++ b/patrole_tempest_plugin/rbac_rule_validation.py
@@ -149,11 +149,11 @@
         disabled and the ``rule_name`` does not exist in the system
     """
     try:
-        project_id = test_obj.auth_provider.credentials.project_id
-        user_id = test_obj.auth_provider.credentials.user_id
+        project_id = test_obj.os_primary.credentials.project_id
+        user_id = test_obj.os_primary.credentials.user_id
     except AttributeError as e:
-        msg = ("{0}: project_id/user_id not found in "
-               "cls.auth_provider.credentials".format(e))
+        msg = ("{0}: project_id or user_id not found in os_primary.credentials"
+               .format(e))
         LOG.error(msg)
         raise rbac_exceptions.RbacResourceSetupFailed(msg)
 
diff --git a/patrole_tempest_plugin/rbac_utils.py b/patrole_tempest_plugin/rbac_utils.py
index 00bfd24..9fd8aee 100644
--- a/patrole_tempest_plugin/rbac_utils.py
+++ b/patrole_tempest_plugin/rbac_utils.py
@@ -20,6 +20,7 @@
 
 from oslo_log import log as logging
 import oslo_utils.uuidutils as uuid_utils
+import testtools
 
 from tempest.common import credentials_factory as credentials
 from tempest import config
@@ -31,8 +32,38 @@
 
 
 class RbacUtils(object):
+    """Utility class responsible for switching os_primary role.
+
+    This class is responsible for overriding the value of the primary Tempest
+    credential's role (i.e. "os_primary" role). By doing so, it is possible to
+    seamlessly swap between admin credentials, needed for setup and clean up,
+    and primary credentials, needed to perform the API call which does
+    policy enforcement. The primary credentials always cycle between roles
+    defined by ``CONF.identity.admin_role`` and `CONF.rbac.rbac_test_role``.
+    """
 
     def __init__(self, test_obj):
+        """Constructor for ``RbacUtils``.
+
+        :param test_obj: A Tempest test instance.
+        :type test_obj: tempest.lib.base.BaseTestCase or
+            tempest.test.BaseTestCase
+        """
+        # Since we are going to instantiate a client manager with
+        # admin credentials, first check if admin is available.
+        if not credentials.is_admin_available(
+                identity_version=test_obj.get_identity_version()):
+            msg = "Missing Identity Admin API credentials in configuration."
+            raise testtools.TestCase.skipException(msg)
+
+        # Intialize the admin roles_client to perform role switching.
+        admin_creds = test_obj.get_client_manager(credential_type='admin')
+        if test_obj.get_identity_version() == 'v3':
+            admin_roles_client = admin_creds.roles_v3_client
+        else:
+            admin_roles_client = admin_creds.roles_client
+
+        self.admin_roles_client = admin_roles_client
         self.switch_role(test_obj, toggle_rbac_role=False)
 
     # References the last value of `toggle_rbac_role` that was passed to
@@ -45,20 +76,11 @@
     rbac_role_id = None
 
     def switch_role(self, test_obj, toggle_rbac_role=False):
-        self.user_id = test_obj.auth_provider.credentials.user_id
-        self.project_id = test_obj.auth_provider.credentials.tenant_id
-        self.token = test_obj.auth_provider.get_token()
-        self.identity_version = test_obj.get_identity_version()
+        self.user_id = test_obj.os_primary.credentials.user_id
+        self.project_id = test_obj.os_primary.credentials.tenant_id
+        self.token = test_obj.os_primary.auth_provider.get_token()
 
-        if not credentials.is_admin_available(
-                identity_version=self.identity_version):
-            msg = "Missing Identity Admin API credentials in configuration."
-            raise rbac_exceptions.RbacResourceSetupFailed(msg)
-
-        self.roles_client = test_obj.os_admin.roles_v3_client
-
-        LOG.debug('Switching role to: %s', toggle_rbac_role)
-
+        LOG.debug('Switching role to: %s.', toggle_rbac_role)
         try:
             if not self.admin_role_id or not self.rbac_role_id:
                 self._get_roles()
@@ -79,25 +101,25 @@
             # Reset auth again to verify the password restore does work.
             # Clear auth restores the original credentials and deletes
             # cached auth data.
-            test_obj.auth_provider.clear_auth()
+            test_obj.os_primary.auth_provider.clear_auth()
             # Fernet tokens are not subsecond aware and Keystone should only be
             # precise to the second. Sleep to ensure we are passing the second
             # boundary before attempting to authenticate. If token is of type
             # uuid, then do not sleep.
             if not uuid_utils.is_uuid_like(self.token):
                 time.sleep(1)
-            test_obj.auth_provider.set_auth()
+            test_obj.os_primary.auth_provider.set_auth()
 
     def _add_role_to_user(self, role_id):
         role_already_present = self._clear_user_roles(role_id)
         if role_already_present:
             return
 
-        self.roles_client.create_user_role_on_project(
+        self.admin_roles_client.create_user_role_on_project(
             self.project_id, self.user_id, role_id)
 
     def _clear_user_roles(self, role_id):
-        roles = self.roles_client.list_user_roles_on_project(
+        roles = self.admin_roles_client.list_user_roles_on_project(
             self.project_id, self.user_id)['roles']
 
         # If the user already has the role that is required, return early.
@@ -106,7 +128,7 @@
             return True
 
         for role in roles:
-            self.roles_client.delete_role_from_user_on_project(
+            self.admin_roles_client.delete_role_from_user_on_project(
                 self.project_id, self.user_id, role['id'])
 
         return False
@@ -147,7 +169,7 @@
             self.switch_role_history[key] = toggle_rbac_role
 
     def _get_roles(self):
-        available_roles = self.roles_client.list_roles()
+        available_roles = self.admin_roles_client.list_roles()
         admin_role_id = rbac_role_id = None
 
         for role in available_roles['roles']:
diff --git a/patrole_tempest_plugin/tests/api/compute/rbac_base.py b/patrole_tempest_plugin/tests/api/compute/rbac_base.py
index 0a3a1f5..aa148ea 100644
--- a/patrole_tempest_plugin/tests/api/compute/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/compute/rbac_base.py
@@ -23,8 +23,6 @@
 
 class BaseV2ComputeRbacTest(compute_base.BaseV2ComputeTest):
 
-    credentials = ['admin', 'primary']
-
     @classmethod
     def skip_checks(cls):
         super(BaseV2ComputeRbacTest, cls).skip_checks()
@@ -35,7 +33,6 @@
     @classmethod
     def setup_clients(cls):
         super(BaseV2ComputeRbacTest, cls).setup_clients()
-        cls.auth_provider = cls.os_primary.auth_provider
         cls.rbac_utils = rbac_utils.RbacUtils(cls)
 
         cls.hosts_client = cls.os_primary.hosts_client
diff --git a/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py
index b771d32..b196d93 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py
@@ -40,7 +40,7 @@
         super(FlavorAccessRbacTest, cls).resource_setup()
         cls.flavor_id = cls._create_flavor(is_public=False)['id']
         cls.public_flavor_id = CONF.compute.flavor_ref
-        cls.tenant_id = cls.auth_provider.credentials.tenant_id
+        cls.tenant_id = cls.os_primary.credentials.tenant_id
 
     @decorators.idempotent_id('a2bd3740-765d-4c95-ac98-9e027378c75e')
     @rbac_rule_validation.action(
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_actions_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_actions_rbac.py
index b115ab5..cb32eec 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_actions_rbac.py
@@ -33,6 +33,8 @@
 
 class ServerActionsRbacTest(rbac_base.BaseV2ComputeRbacTest):
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def resource_setup(cls):
         super(ServerActionsRbacTest, cls).resource_setup()
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py
index a7f16a1..1913159 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py
@@ -30,6 +30,8 @@
     max_microversion = 'latest'
     block_migration = 'auto'
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def skip_checks(cls):
         super(MigrateServerV225RbacTest, cls).skip_checks()
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py
index c1bf9f7..1866119 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py
@@ -44,6 +44,8 @@
       * small policy "families" -- i.e. containing one to three policies
     """
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def resource_setup(cls):
         super(MiscPolicyActionsRbacTest, cls).resource_setup()
@@ -262,7 +264,7 @@
     @decorators.idempotent_id('fe7eacda-15c4-4bf7-93ef-1091c4546a9d')
     def test_show_simple_tenant_usage(self):
         """Test show tenant usage, part of os-simple-tenant-usage."""
-        tenant_id = self.auth_provider.credentials.tenant_id
+        tenant_id = self.os_primary.credentials.tenant_id
 
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
         self.tenant_usages_client.show_tenant_usage(tenant_id=tenant_id)
@@ -308,6 +310,8 @@
       * tests that require network resources
     """
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def skip_checks(cls):
         super(MiscPolicyActionsNetworkRbacTest, cls).skip_checks()
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
index f5d9dc0..5539221 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
@@ -33,6 +33,8 @@
 
 class ComputeServersRbacTest(base.BaseV2ComputeRbacTest):
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def setup_clients(cls):
         super(ComputeServersRbacTest, cls).setup_clients()
diff --git a/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
index 0935c95..b2c8e79 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
@@ -33,6 +33,8 @@
     # https://developer.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
     max_microversion = '2.35'
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def setup_clients(cls):
         super(VolumeRbacTest, cls).setup_clients()
diff --git a/patrole_tempest_plugin/tests/api/identity/rbac_base.py b/patrole_tempest_plugin/tests/api/identity/rbac_base.py
index e8c402e..8ee80c6 100644
--- a/patrole_tempest_plugin/tests/api/identity/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/identity/rbac_base.py
@@ -26,26 +26,23 @@
 LOG = logging.getLogger(__name__)
 
 
-class BaseIdentityRbacTest(base.BaseIdentityTest):
-
-    credentials = ['admin', 'primary']
+class BaseIdentityV2RbacTest(base.BaseIdentityV2Test):
 
     @classmethod
     def skip_checks(cls):
-        super(BaseIdentityRbacTest, cls).skip_checks()
+        super(BaseIdentityV2RbacTest, cls).skip_checks()
         if not CONF.rbac.enable_rbac:
             raise cls.skipException(
                 "%s skipped as RBAC testing not enabled" % cls.__name__)
 
     @classmethod
     def setup_clients(cls):
-        super(BaseIdentityRbacTest, cls).setup_clients()
-        cls.auth_provider = cls.os_primary.auth_provider
+        super(BaseIdentityV2RbacTest, cls).setup_clients()
         cls.rbac_utils = rbac_utils.RbacUtils(cls)
 
     @classmethod
     def resource_setup(cls):
-        super(BaseIdentityRbacTest, cls).resource_setup()
+        super(BaseIdentityV2RbacTest, cls).resource_setup()
         cls.endpoints = []
         cls.roles = []
         cls.services = []
@@ -69,7 +66,7 @@
             test_utils.call_and_ignore_notfound_exc(
                 cls.users_client.delete_user, user['id'])
 
-        super(BaseIdentityRbacTest, cls).resource_cleanup()
+        super(BaseIdentityV2RbacTest, cls).resource_cleanup()
 
     @classmethod
     def setup_test_endpoint(cls, service=None):
@@ -150,7 +147,7 @@
         return user
 
 
-class BaseIdentityV2AdminRbacTest(BaseIdentityRbacTest):
+class BaseIdentityV2AdminRbacTest(BaseIdentityV2RbacTest):
     """Base test class for the Identity v2 admin API.
 
     Keystone's v2 API is split into two APIs: an admin and non-admin API. RBAC
@@ -160,8 +157,6 @@
     implementation of ``assert_admin`` in ``keystone.common.wsgi``.
     """
 
-    identity_version = 'v2'
-
     @classmethod
     def skip_checks(cls):
         super(BaseIdentityV2AdminRbacTest, cls).skip_checks()
@@ -218,7 +213,7 @@
         return token_id
 
 
-class BaseIdentityV3RbacTest(BaseIdentityRbacTest):
+class BaseIdentityV3RbacTest(BaseIdentityV2RbacTest):
 
     identity_version = 'v3'
 
diff --git a/patrole_tempest_plugin/tests/api/identity/v2/test_projects_rbac.py b/patrole_tempest_plugin/tests/api/identity/v2/test_projects_rbac.py
index 784045a..e733e26 100644
--- a/patrole_tempest_plugin/tests/api/identity/v2/test_projects_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v2/test_projects_rbac.py
@@ -113,8 +113,8 @@
         """
         tenants_client = self.os_admin.tenants_client if \
             self.rbac_utils.is_admin else self.os_primary.tenants_client
-        admin_tenant_id = self.os_admin.auth_provider.credentials.project_id
-        non_admin_tenant_id = self.auth_provider.credentials.project_id
+        admin_tenant_id = self.os_admin.credentials.project_id
+        non_admin_tenant_id = self.os_primary.credentials.project_id
 
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
         tenants = tenants_client.list_tenants()['tenants']
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_tokens_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_tokens_rbac.py
index 78ee78a..0853d12 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_tokens_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_tokens_rbac.py
@@ -34,8 +34,8 @@
         # credentials before switching roles. Populate role_ids with admin
         # role id.
         cls.role_ids = [cls.get_role_by_name(CONF.identity.admin_role)['id']]
-        cls.project_id = cls.auth_provider.credentials.project_id
-        cls.user_id = cls.auth_provider.credentials.user_id
+        cls.project_id = cls.os_primary.credentials.project_id
+        cls.user_id = cls.os_primary.credentials.user_id
 
     def _create_consumer(self):
         description = data_utils.rand_name(
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_negative_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_negative_rbac.py
index 1ab296a..7b3a658 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_negative_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_negative_rbac.py
@@ -26,7 +26,7 @@
 
 class IdentityTokenV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
 
-    credentials = ['primary', 'admin', 'alt']
+    credentials = ['primary', 'alt']
 
     @classmethod
     def skip_checks(cls):
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_trusts_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_trusts_rbac.py
index 0532b2d..82feff9 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_trusts_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_trusts_rbac.py
@@ -25,7 +25,7 @@
 
 class IdentityTrustV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
 
-    credentials = ['primary', 'admin', 'alt']
+    credentials = ['primary', 'alt']
 
     @classmethod
     def skip_checks(cls):
@@ -41,15 +41,15 @@
         # user_id:%(trust.trustor_user_id)s will thereby evaluate to
         # "primary user's user_id:primary user's user_id" which evaluates to
         # true.
-        cls.trustor_user_id = cls.auth_provider.credentials.user_id
-        cls.trustor_project_id = cls.auth_provider.credentials.project_id
+        cls.trustor_user_id = cls.os_primary.credentials.user_id
+        cls.trustor_project_id = cls.os_primary.credentials.project_id
         cls.trustee_user_id = cls.setup_test_user()['id']
 
         # The "unauthorized_user_id" does not have permissions to create a
         # trust because the user_id in "user_id:%(trust.trustor_user_id)s" (the
         # policy rule for creating a trust) corresponds to the primary user_id
         # not the alt user_id.
-        cls.unauthorized_user_id = cls.os_alt.auth_provider.credentials.user_id
+        cls.unauthorized_user_id = cls.os_alt.credentials.user_id
 
         # A role is guaranteed to exist (namely the admin role), because
         # "trustor_user_id" and "trustor_project_id" are the primary tempest
@@ -67,8 +67,7 @@
         service="keystone",
         rule="identity:create_trust",
         extra_target_data={
-            "trust.trustor_user_id":
-            "os_primary.auth_provider.credentials.user_id"
+            "trust.trustor_user_id": "os_primary.credentials.user_id"
         })
     def test_create_trust(self):
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
@@ -81,7 +80,7 @@
         service="keystone",
         rule="identity:create_trust",
         extra_target_data={
-            "trust.trustor_user_id": "os_alt.auth_provider.credentials.user_id"
+            "trust.trustor_user_id": "os_alt.credentials.user_id"
         })
     def test_create_trust_negative(self):
         # Explicit negative test for identity:create_trust policy action.
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_users_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_users_rbac.py
index 723455e..0c85240 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_users_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_users_rbac.py
@@ -25,7 +25,7 @@
     @classmethod
     def resource_setup(cls):
         super(IdentityUserV3AdminRbacTest, cls).resource_setup()
-        cls.default_user_id = cls.auth_provider.credentials.user_id
+        cls.default_user_id = cls.os_primary.credentials.user_id
 
     @rbac_rule_validation.action(service="keystone",
                                  rule="identity:create_user")
diff --git a/patrole_tempest_plugin/tests/api/image/rbac_base.py b/patrole_tempest_plugin/tests/api/image/rbac_base.py
index 7270560..e49e2f6 100644
--- a/patrole_tempest_plugin/tests/api/image/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/image/rbac_base.py
@@ -21,8 +21,6 @@
 
 class BaseV1ImageRbacTest(image_base.BaseV1ImageTest):
 
-    credentials = ['admin', 'primary']
-
     @classmethod
     def skip_checks(cls):
         super(BaseV1ImageRbacTest, cls).skip_checks()
@@ -33,14 +31,11 @@
     @classmethod
     def setup_clients(cls):
         super(BaseV1ImageRbacTest, cls).setup_clients()
-        cls.auth_provider = cls.os_primary.auth_provider
         cls.rbac_utils = rbac_utils.RbacUtils(cls)
 
 
 class BaseV2ImageRbacTest(image_base.BaseV2ImageTest):
 
-    credentials = ['admin', 'primary']
-
     @classmethod
     def skip_checks(cls):
         super(BaseV2ImageRbacTest, cls).skip_checks()
@@ -51,5 +46,4 @@
     @classmethod
     def setup_clients(cls):
         super(BaseV2ImageRbacTest, cls).setup_clients()
-        cls.auth_provider = cls.os_primary.auth_provider
         cls.rbac_utils = rbac_utils.RbacUtils(cls)
diff --git a/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py b/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py
index a7c59f5..59c4aaf 100644
--- a/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py
@@ -21,7 +21,7 @@
 
 class ImagesMemberRbacTest(base.BaseV2ImageRbacTest):
 
-    credentials = ['admin', 'primary', 'alt']
+    credentials = ['primary', 'alt']
 
     @classmethod
     def resource_setup(cls):
diff --git a/patrole_tempest_plugin/tests/api/image/test_images_rbac.py b/patrole_tempest_plugin/tests/api/image/test_images_rbac.py
index 340323e..b08f8bd 100644
--- a/patrole_tempest_plugin/tests/api/image/test_images_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/test_images_rbac.py
@@ -24,6 +24,8 @@
 
 class BasicOperationsImagesRbacTest(rbac_base.BaseV2ImageRbacTest):
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def setup_clients(cls):
         super(BasicOperationsImagesRbacTest, cls).setup_clients()
diff --git a/patrole_tempest_plugin/tests/api/network/rbac_base.py b/patrole_tempest_plugin/tests/api/network/rbac_base.py
index 3ee31b7..6cf0138 100644
--- a/patrole_tempest_plugin/tests/api/network/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/network/rbac_base.py
@@ -23,8 +23,6 @@
 
 class BaseNetworkRbacTest(network_base.BaseNetworkTest):
 
-    credentials = ['admin', 'primary']
-
     @classmethod
     def skip_checks(cls):
         super(BaseNetworkRbacTest, cls).skip_checks()
@@ -35,5 +33,4 @@
     @classmethod
     def setup_clients(cls):
         super(BaseNetworkRbacTest, cls).setup_clients()
-        cls.auth_provider = cls.os_primary.auth_provider
         cls.rbac_utils = rbac_utils.RbacUtils(cls)
diff --git a/patrole_tempest_plugin/tests/api/volume/rbac_base.py b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
index 953a834..4d3b612 100644
--- a/patrole_tempest_plugin/tests/api/volume/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
@@ -23,8 +23,6 @@
 
 class BaseVolumeRbacTest(vol_base.BaseVolumeTest):
 
-    credentials = ['admin', 'primary']
-
     @classmethod
     def skip_checks(cls):
         super(BaseVolumeRbacTest, cls).skip_checks()
@@ -35,8 +33,6 @@
     @classmethod
     def setup_clients(cls):
         super(BaseVolumeRbacTest, cls).setup_clients()
-        cls.auth_provider = cls.os_primary.auth_provider
-
         cls.rbac_utils = rbac_utils.RbacUtils(cls)
 
         version_checker = {
diff --git a/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
index c6703b0..7d9ec0f 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
@@ -23,10 +23,12 @@
 
 
 class VolumeQOSRbacTest(rbac_base.BaseVolumeRbacTest):
+
+    credentials = ['primary', 'admin']
+
     @classmethod
     def setup_clients(cls):
         super(VolumeQOSRbacTest, cls).setup_clients()
-        cls.auth_provider = cls.os_primary.auth_provider
         cls.qos_client = cls.os_primary.volume_qos_v2_client
         cls.admin_qos_client = cls.os_admin.volume_qos_v2_client
 
diff --git a/patrole_tempest_plugin/tests/api/volume/test_user_messages_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_user_messages_rbac.py
index d2a5452..fddaee4 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_user_messages_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_user_messages_rbac.py
@@ -29,6 +29,8 @@
     min_microversion = '3.3'
     max_microversion = 'latest'
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def setup_clients(cls):
         super(MessagesV3RbacTest, cls).setup_clients()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
index e8e3ef8..209821e 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
@@ -29,6 +29,8 @@
 
 class VolumesActionsRbacTest(rbac_base.BaseVolumeRbacTest):
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def setup_clients(cls):
         super(VolumesActionsRbacTest, cls).setup_clients()
@@ -218,6 +220,8 @@
     min_microversion = '3.10'
     max_microversion = 'latest'
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def setup_clients(cls):
         super(VolumesActionsV310RbacTest, cls).setup_clients()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
index 405d02b..656a2e6 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
@@ -23,6 +23,8 @@
 
 class VolumesTransfersRbacTest(rbac_base.BaseVolumeRbacTest):
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def setup_clients(cls):
         super(VolumesTransfersRbacTest, cls).setup_clients()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_types_access_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_types_access_rbac.py
index 8fd68a3..af9994c 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_types_access_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_types_access_rbac.py
@@ -36,7 +36,7 @@
         super(VolumeTypesAccessRbacTest, cls).resource_setup()
         cls.vol_type = cls.create_volume_type(
             **{'os-volume-type-access:is_public': False})
-        cls.project_id = cls.auth_provider.credentials.project_id
+        cls.project_id = cls.os_primary.credentials.project_id
 
     def _add_type_access(self, ignore_not_found=False):
         self.volume_types_client.add_type_access(
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volumes_backup_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volumes_backup_rbac.py
index 01c1b08..a734e58 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volumes_backup_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volumes_backup_rbac.py
@@ -30,6 +30,8 @@
 
 class VolumesBackupsRbacTest(rbac_base.BaseVolumeRbacTest):
 
+    credentials = ['primary', 'admin']
+
     def setUp(self):
         super(VolumesBackupsRbacTest, self).setUp()
         self.volume = self.create_volume()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volumes_extend_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volumes_extend_rbac.py
index 971e079..205be9e 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volumes_extend_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volumes_extend_rbac.py
@@ -25,6 +25,8 @@
 
 class VolumesExtendRbacTest(rbac_base.BaseVolumeRbacTest):
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def setup_clients(cls):
         super(VolumesExtendRbacTest, cls).setup_clients()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volumes_manage_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volumes_manage_rbac.py
index bea3a46..dab796d 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volumes_manage_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volumes_manage_rbac.py
@@ -27,6 +27,8 @@
 
 class VolumesManageRbacTest(rbac_base.BaseVolumeRbacTest):
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def skip_checks(cls):
         super(VolumesManageRbacTest, cls).skip_checks()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volumes_snapshots_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volumes_snapshots_rbac.py
index 13ced96..249b88b 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volumes_snapshots_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volumes_snapshots_rbac.py
@@ -25,6 +25,8 @@
 
 class VolumesSnapshotRbacTest(rbac_base.BaseVolumeRbacTest):
 
+    credentials = ['primary', 'admin']
+
     @classmethod
     def skip_checks(cls):
         super(VolumesSnapshotRbacTest, cls).skip_checks()
diff --git a/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py b/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
index a90ec2a..7ce5548 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
@@ -30,11 +30,11 @@
     def setUp(self):
         super(RBACRuleValidationTest, self).setUp()
         self.mock_args = mock.Mock(spec=test.BaseTestCase)
-        self.mock_args.auth_provider = mock.Mock()
+        self.mock_args.os_primary = mock.Mock()
         self.mock_args.rbac_utils = mock.Mock()
-        self.mock_args.auth_provider.credentials.project_id = \
+        self.mock_args.os_primary.credentials.project_id = \
             mock.sentinel.project_id
-        self.mock_args.auth_provider.credentials.user_id = \
+        self.mock_args.os_primary.credentials.user_id = \
             mock.sentinel.user_id
 
         CONF.set_override('rbac_test_role', 'Member', group='rbac')
diff --git a/patrole_tempest_plugin/tests/unit/test_rbac_utils.py b/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
index 85b1c39..3a26b00 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
@@ -44,13 +44,14 @@
         super(RBACUtilsTest, self).setUp()
 
         self.mock_test_obj = mock.Mock(spec=lib_base.BaseTestCase)
-        self.mock_test_obj.auth_provider = mock.Mock(
+        self.mock_test_obj.os_primary = mock.Mock(
             **{'credentials.user_id': mock.sentinel.user_id,
                'credentials.tenant_id': mock.sentinel.project_id})
-        self.mock_test_obj.os_admin = mock.Mock(
-            **{'roles_v3_client.list_roles.return_value': self.available_roles}
+        self.mock_test_obj.get_client_manager = mock.Mock(
+            **{'return_value.roles_v3_client.list_roles.return_value':
+                self.available_roles}
         )
-        self.mock_test_obj.get_identity_version = mock.Mock(return_value=3)
+        self.mock_test_obj.get_identity_version = mock.Mock(return_value='v3')
 
         with mock.patch.object(rbac_utils.RbacUtils, '_validate_switch_role'):
             self.rbac_utils = rbac_utils.RbacUtils(self.mock_test_obj)
@@ -62,9 +63,9 @@
         CONF.set_override('auth_version', 'v3', group='identity')
         CONF.set_override('rbac_test_role', 'Member', group='rbac')
 
-        roles_client = self.mock_test_obj.os_admin.roles_v3_client
+        roles_client = self.mock_test_obj.get_client_manager().roles_v3_client
         roles_client.create_user_role_on_project.reset_mock()
-        self.mock_test_obj.auth_provider.reset_mock()
+        self.mock_test_obj.os_primary.reset_mock()
 
         self.addCleanup(CONF.clear_override, 'rbac_test_role', group='rbac')
         self.addCleanup(CONF.clear_override, 'admin_role', group='identity')
@@ -79,11 +80,10 @@
     @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
                        autospec=True, return_value=False)
     def test_initialization_with_missing_admin_role(self, _):
-        self.mock_test_obj.os_admin = mock.Mock(
-            **{'roles_v3_client.list_roles.return_value':
-               {'roles': [{'name': 'Member', 'id': 'member_id'}]}})
         self.rbac_utils.admin_role_id = None
         self.rbac_utils.rbac_role_id = None
+        CONF.set_override('admin_role', None, group='identity')
+
         e = self.assertRaises(rbac_exceptions.RbacResourceSetupFailed,
                               self.rbac_utils.switch_role, self.mock_test_obj,
                               True)
@@ -93,11 +93,10 @@
     @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
                        autospec=True, return_value=False)
     def test_initialization_with_missing_rbac_role(self, _):
-        self.mock_test_obj.os_admin = mock.Mock(
-            **{'roles_v3_client.list_roles.return_value':
-               {'roles': [{'name': 'admin', 'id': 'admin_id'}]}})
         self.rbac_utils.admin_role_id = None
         self.rbac_utils.rbac_role_id = None
+        CONF.set_override('rbac_test_role', None, group='rbac')
+
         e = self.assertRaises(rbac_exceptions.RbacResourceSetupFailed,
                               self.rbac_utils.switch_role, self.mock_test_obj,
                               True)
@@ -105,7 +104,7 @@
                       "system.", e.__str__())
 
     def test_clear_user_roles(self):
-        roles_client = self.mock_test_obj.os_admin.roles_v3_client
+        roles_client = self.mock_test_obj.get_client_manager().roles_v3_client
         roles_client.list_user_roles_on_project.return_value = {
             'roles': [{'id': 'admin_id'}, {'id': 'member_id'}]
         }
@@ -133,14 +132,16 @@
     def test_rbac_utils_switch_role_to_admin_role(self, mock_time, _):
         self.rbac_utils.prev_switch_role = True
         self._mock_list_user_roles_on_project('admin_id')
-        roles_client = self.mock_test_obj.os_admin.roles_v3_client
+        roles_client = self.mock_test_obj.get_client_manager().roles_v3_client
 
         self.rbac_utils.switch_role(self.mock_test_obj, False)
 
         roles_client.create_user_role_on_project.assert_called_once_with(
             mock.sentinel.project_id, mock.sentinel.user_id, 'admin_id')
-        self.mock_test_obj.auth_provider.clear_auth.assert_called_once_with()
-        self.mock_test_obj.auth_provider.set_auth.assert_called_once_with()
+        self.mock_test_obj.os_primary.auth_provider.clear_auth\
+            .assert_called_once_with()
+        self.mock_test_obj.os_primary.auth_provider.set_auth\
+            .assert_called_once_with()
         mock_time.sleep.assert_called_once_with(1)
 
     @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
@@ -148,14 +149,16 @@
     @mock.patch.object(rbac_utils, 'time', autospec=True)
     def test_rbac_utils_switch_role_to_rbac_role(self, mock_time, _):
         self._mock_list_user_roles_on_project('member_id')
-        roles_client = self.mock_test_obj.os_admin.roles_v3_client
+        roles_client = self.mock_test_obj.get_client_manager().roles_v3_client
 
         self.rbac_utils.switch_role(self.mock_test_obj, True)
 
         roles_client.create_user_role_on_project.assert_called_once_with(
             mock.sentinel.project_id, mock.sentinel.user_id, 'member_id')
-        self.mock_test_obj.auth_provider.clear_auth.assert_called_once_with()
-        self.mock_test_obj.auth_provider.set_auth.assert_called_once_with()
+        self.mock_test_obj.os_primary.auth_provider.clear_auth\
+            .assert_called_once_with()
+        self.mock_test_obj.os_primary.auth_provider.set_auth\
+            .assert_called_once_with()
         mock_time.sleep.assert_called_once_with(1)
 
     def test_RBAC_utils_switch_roles_without_boolean_value(self):
@@ -233,7 +236,7 @@
                        autospec=True, return_value=False)
     def test_rbac_utils_switch_role_except_exception(self,
                                                      mock_clear_user_roles):
-        roles_client = self.mock_test_obj.os_admin.roles_v3_client
+        roles_client = self.mock_test_obj.get_client_manager().roles_v3_client
         roles_client.create_user_role_on_project.side_effect =\
             lib_exc.NotFound