From 27f671f1a2588601358391f027d9ab28fda225b5 Mon Sep 17 00:00:00 2001 From: Lingxian Kong Date: Wed, 30 Dec 2020 21:23:03 +1300 Subject: [PATCH] Reuse tempest to create admin client manager The previous code doesn't support PreProvisionedCredentialProvider, it was getting admin credentials from tempest config file which are not set when using test_accounts_file. Change-Id: Ia34d08ad659b095a114c27d6d596507f7922149a --- patrole_tempest_plugin/policy_authority.py | 11 +++--- .../rbac_rule_validation.py | 2 ++ patrole_tempest_plugin/rbac_utils.py | 8 ++--- .../tests/api/identity/rbac_base.py | 1 - .../identity/v3/test_tokens_negative_rbac.py | 2 +- .../tests/api/identity/v3/test_trusts_rbac.py | 2 +- .../api/image/test_images_member_rbac.py | 2 +- patrole_tempest_plugin/tests/unit/fixtures.py | 35 +++++++++---------- .../tests/unit/test_policy_authority.py | 24 +++++++------ 9 files changed, 40 insertions(+), 47 deletions(-) diff --git a/patrole_tempest_plugin/policy_authority.py b/patrole_tempest_plugin/policy_authority.py index afa358a0..0a50d612 100644 --- a/patrole_tempest_plugin/policy_authority.py +++ b/patrole_tempest_plugin/policy_authority.py @@ -21,8 +21,6 @@ import os from oslo_log import log as logging from oslo_policy import policy import stevedore -from tempest import clients -from tempest.common import credentials_factory as credentials from tempest import config from patrole_tempest_plugin.rbac_authority import RbacAuthority @@ -34,6 +32,7 @@ LOG = logging.getLogger(__name__) class PolicyAuthority(RbacAuthority): """A class that uses ``oslo.policy`` for validating RBAC.""" + os_admin = None def __init__(self, project_id, user_id, service, extra_target_data=None): """Initialization of Policy Authority class. @@ -123,12 +122,10 @@ class PolicyAuthority(RbacAuthority): # Cache the list of available services in memory to avoid needlessly # doing an API call every time. - if not hasattr(cls, 'available_services'): - admin_mgr = clients.Manager( - credentials.get_configured_admin_credentials()) - services_client = (admin_mgr.identity_services_v3_client + if not hasattr(cls, 'available_services') and cls.os_admin: + services_client = (cls.os_admin.identity_services_v3_client if CONF.identity_feature_enabled.api_v3 - else admin_mgr.identity_services_client) + else cls.os_admin.identity_services_client) services = services_client.list_services()['services'] cls.available_services = [s['name'] for s in services] diff --git a/patrole_tempest_plugin/rbac_rule_validation.py b/patrole_tempest_plugin/rbac_rule_validation.py index 93c9a1d8..9334702d 100644 --- a/patrole_tempest_plugin/rbac_rule_validation.py +++ b/patrole_tempest_plugin/rbac_rule_validation.py @@ -356,9 +356,11 @@ def _is_authorized(test_obj, service, rule, extra_target_data): else: formatted_target_data = _format_extra_target_data( test_obj, extra_target_data) + policy_authority.PolicyAuthority.os_admin = test_obj.os_admin authority = policy_authority.PolicyAuthority( project_id, user_id, service, extra_target_data=formatted_target_data) + is_allowed = authority.allowed(rule, roles) if is_allowed: diff --git a/patrole_tempest_plugin/rbac_utils.py b/patrole_tempest_plugin/rbac_utils.py index 7a1c33fb..ed65a740 100644 --- a/patrole_tempest_plugin/rbac_utils.py +++ b/patrole_tempest_plugin/rbac_utils.py @@ -20,8 +20,6 @@ import time from oslo_log import log as logging from oslo_utils import excutils -from tempest import clients -from tempest.common import credentials_factory as credentials from tempest import config from tempest.lib import exceptions as lib_exc @@ -128,6 +126,7 @@ class RbacUtilsMixin(object): defined by ``CONF.identity.admin_role`` and ``CONF.patrole.rbac_test_roles``. """ + credentials = ['primary', 'admin'] def __init__(self, *args, **kwargs): super(RbacUtilsMixin, self).__init__(*args, **kwargs) @@ -159,11 +158,8 @@ class RbacUtilsMixin(object): @classmethod def setup_clients(cls): - # Intialize the admin roles_client to perform role switching. - admin_mgr = clients.Manager( - credentials.get_configured_admin_credentials()) if CONF.identity_feature_enabled.api_v3: - admin_roles_client = admin_mgr.roles_v3_client + admin_roles_client = cls.os_admin.roles_v3_client else: raise lib_exc.InvalidConfiguration( "Patrole role overriding only supports v3 identity API.") diff --git a/patrole_tempest_plugin/tests/api/identity/rbac_base.py b/patrole_tempest_plugin/tests/api/identity/rbac_base.py index 4321c604..aa5cd4bd 100644 --- a/patrole_tempest_plugin/tests/api/identity/rbac_base.py +++ b/patrole_tempest_plugin/tests/api/identity/rbac_base.py @@ -77,7 +77,6 @@ class BaseIdentityRbacTest(rbac_utils.RbacUtilsMixin, class BaseIdentityV3RbacTest(BaseIdentityRbacTest): identity_version = 'v3' - credentials = ['primary'] @classmethod def setup_clients(cls): 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 16a7893f..45eb601e 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 @@ -23,7 +23,7 @@ from patrole_tempest_plugin.tests.api.identity import rbac_base class IdentityTokenV3RbacTest(rbac_base.BaseIdentityV3RbacTest): - credentials = ['primary', 'alt'] + credentials = ['primary', 'alt', 'admin'] @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 23c75c61..da29433c 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 @@ -27,7 +27,7 @@ CONF = config.CONF class IdentityTrustV3RbacTest(rbac_base.BaseIdentityV3RbacTest): - credentials = ['primary', 'alt'] + credentials = ['primary', 'alt', 'admin'] @classmethod def skip_checks(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 43a5e573..94506762 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 @@ from patrole_tempest_plugin.tests.api.image import rbac_base as base class ImagesMemberRbacTest(base.BaseV2ImageRbacTest): - credentials = ['primary', 'alt'] + credentials = ['primary', 'alt', 'admin'] @classmethod def resource_setup(cls): diff --git a/patrole_tempest_plugin/tests/unit/fixtures.py b/patrole_tempest_plugin/tests/unit/fixtures.py index 98eb66c9..01b99db3 100644 --- a/patrole_tempest_plugin/tests/unit/fixtures.py +++ b/patrole_tempest_plugin/tests/unit/fixtures.py @@ -19,7 +19,6 @@ from unittest import mock import fixtures import time -from tempest.common import credentials_factory as credentials from tempest import config from tempest import test @@ -55,6 +54,7 @@ class ConfPatcher(fixtures.Fixture): class FakeBaseRbacTest(rbac_utils.RbacUtilsMixin, test.BaseTestCase): + credentials = [] os_primary = None def runTest(self): @@ -91,13 +91,20 @@ class RbacUtilsMixinFixture(fixtures.Fixture): # time.sleep is a test optimization. self.mock_time = self.patchobject(rbac_utils, 'time', __name__='mock_time', spec=time) - self.patchobject(credentials, 'get_configured_admin_credentials', - spec=object) - mock_admin_mgr = self.patchobject(rbac_utils.clients, 'Manager', - spec=rbac_utils.clients.Manager, - roles_v3_client=mock.Mock(), - roles_client=mock.Mock()) - self.admin_roles_client = mock_admin_mgr.return_value.roles_v3_client + + test_obj_kwargs = { + 'credentials.user_id': self.USER_ID, + 'credentials.tenant_id': self.PROJECT_ID, + 'credentials.project_id': self.PROJECT_ID, + } + + class FakeRbacTest(FakeBaseRbacTest): + os_primary = mock.Mock() + os_admin = mock.Mock() + + FakeRbacTest.os_primary.configure_mock(**test_obj_kwargs) + + self.admin_roles_client = FakeRbacTest.os_admin.roles_v3_client self.admin_roles_client.list_all_role_inference_rules.return_value = { "role_inferences": [ { @@ -115,22 +122,12 @@ class RbacUtilsMixinFixture(fixtures.Fixture): set(self._rbac_test_roles)) self.set_roles(list(default_roles), []) - test_obj_kwargs = { - 'credentials.user_id': self.USER_ID, - 'credentials.tenant_id': self.PROJECT_ID, - 'credentials.project_id': self.PROJECT_ID, - } - - class FakeRbacTest(FakeBaseRbacTest): - os_primary = mock.Mock() - - FakeRbacTest.os_primary.configure_mock(**test_obj_kwargs) - FakeRbacTest.setUpClass() self.test_obj = FakeRbacTest() if self._do_reset_mocks: self.admin_roles_client.reset_mock() self.test_obj.os_primary.reset_mock() + self.test_obj.os_admin.reset_mock() self.mock_time.reset_mock() def set_roles(self, roles, roles_on_project=None): diff --git a/patrole_tempest_plugin/tests/unit/test_policy_authority.py b/patrole_tempest_plugin/tests/unit/test_policy_authority.py index cdc9e155..fc7cafb7 100644 --- a/patrole_tempest_plugin/tests/unit/test_policy_authority.py +++ b/patrole_tempest_plugin/tests/unit/test_policy_authority.py @@ -40,11 +40,12 @@ class PolicyAuthorityTest(base.TestCase): def setUp(self): super(PolicyAuthorityTest, self).setUp() - self.patchobject(policy_authority, 'credentials') - m_creds = self.patchobject(policy_authority, 'clients') - m_creds.Manager().identity_services_client.list_services.\ + + mock_admin = self.patchobject(policy_authority.PolicyAuthority, + 'os_admin') + mock_admin.identity_services_client.list_services.\ return_value = self.services - m_creds.Manager().identity_services_v3_client.list_services.\ + mock_admin.identity_services_v3_client.list_services.\ return_value = self.services current_directory = os.path.dirname(os.path.realpath(__file__)) @@ -492,11 +493,12 @@ class PolicyAuthorityTest(base.TestCase): @mock.patch.object(policy_authority, 'policy', autospec=True) @mock.patch.object(policy_authority.PolicyAuthority, 'get_rules', autospec=True) - @mock.patch.object(policy_authority, 'clients', autospec=True) + @mock.patch.object(policy_authority.PolicyAuthority, 'os_admin', + autospec=True) @mock.patch.object(policy_authority, 'os', autospec=True) @mock.patch.object(policy_authority, 'glob', autospec=True) def test_discover_policy_files_with_many_invalid_one_valid(self, m_glob, - m_os, m_creds, + m_os, m_admin, *args): service = 'test_service' custom_policy_files = ['foo/%s', 'bar/%s', 'baz/%s'] @@ -506,7 +508,7 @@ class PolicyAuthorityTest(base.TestCase): m_os.path.isfile.side_effect = [False, False, True] # Ensure the outer for loop runs only once in `discover_policy_files`. - m_creds.Manager().identity_services_v3_client.\ + m_admin.identity_services_v3_client.\ list_services.return_value = { 'services': [{'name': service}]} @@ -545,11 +547,11 @@ class PolicyAuthorityTest(base.TestCase): def _test_validate_service(self, v2_services, v3_services, expected_failure=False, expected_services=None): - with mock.patch.object( - policy_authority, 'clients', autospec=True) as m_creds: - m_creds.Manager().identity_services_client.list_services.\ + with mock.patch.object(policy_authority.PolicyAuthority, 'os_admin', + autospec=True) as m_admin: + m_admin.identity_services_client.list_services.\ return_value = v2_services - m_creds.Manager().identity_services_v3_client.list_services.\ + m_admin.identity_services_v3_client.list_services.\ return_value = v3_services test_tenant_id = mock.sentinel.tenant_id