Merge "Remove need to include admin in credentials in base classes"
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 4a5dcbf..7e9a402 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