diff --git a/releasenotes/notes/add-alt-project-dynamic-creds-1a3bc543e65d9433.yaml b/releasenotes/notes/add-alt-project-dynamic-creds-1a3bc543e65d9433.yaml new file mode 100644 index 0000000000..de81b2b53e --- /dev/null +++ b/releasenotes/notes/add-alt-project-dynamic-creds-1a3bc543e65d9433.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Add project alternate admin, member and reader role for dynamic credentials. diff --git a/tempest/lib/common/cred_provider.py b/tempest/lib/common/cred_provider.py index 35bca1dd9f..5af5a5ea47 100644 --- a/tempest/lib/common/cred_provider.py +++ b/tempest/lib/common/cred_provider.py @@ -85,14 +85,26 @@ class CredentialProvider(object, metaclass=abc.ABCMeta): def get_project_admin_creds(self): return + @abc.abstractmethod + def get_project_alt_admin_creds(self): + return + @abc.abstractmethod def get_project_member_creds(self): return + @abc.abstractmethod + def get_project_alt_member_creds(self): + return + @abc.abstractmethod def get_project_reader_creds(self): return + @abc.abstractmethod + def get_project_alt_reader_creds(self): + return + @abc.abstractmethod def clear_creds(self): return diff --git a/tempest/lib/common/dynamic_creds.py b/tempest/lib/common/dynamic_creds.py index 95f7e0bd55..5e2308ee18 100644 --- a/tempest/lib/common/dynamic_creds.py +++ b/tempest/lib/common/dynamic_creds.py @@ -379,12 +379,15 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): credentials = self._creds["%s_%s" % (scope, credential_type[0])] else: if scope: - if credential_type == 'admin': + if credential_type in [['admin'], ['alt_admin']]: credentials = self._create_creds( admin=True, scope=scope) else: + cred_type = credential_type + if credential_type in [['alt_member'], ['alt_reader']]: + cred_type = credential_type[0][4:] credentials = self._create_creds( - roles=credential_type, scope=scope) + roles=[cred_type], scope=scope) elif credential_type in ['primary', 'alt', 'admin']: is_admin = (credential_type == 'admin') credentials = self._create_creds(admin=is_admin) @@ -443,12 +446,21 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): def get_project_admin_creds(self): return self.get_credentials(['admin'], scope='project') + def get_project_alt_admin_creds(self): + return self.get_credentials(['alt_admin'], scope='project') + def get_project_member_creds(self): return self.get_credentials(['member'], scope='project') + def get_project_alt_member_creds(self): + return self.get_credentials(['alt_member'], scope='project') + def get_project_reader_creds(self): return self.get_credentials(['reader'], scope='project') + def get_project_alt_reader_creds(self): + return self.get_credentials(['alt_reader'], scope='project') + def get_creds_by_roles(self, roles, force_new=False): roles = list(set(roles)) # The roles list as a str will become the index as the dict key for diff --git a/tempest/lib/common/preprov_creds.py b/tempest/lib/common/preprov_creds.py index 313d3ebf90..a41f0bbe47 100644 --- a/tempest/lib/common/preprov_creds.py +++ b/tempest/lib/common/preprov_creds.py @@ -374,6 +374,10 @@ class PreProvisionedCredentialProvider(cred_provider.CredentialProvider): self._creds['project_admin'] = project_admin return project_admin + def get_project_alt_admin_creds(self): + # TODO(gmann): Implement alt admin hash. + return + def get_project_member_creds(self): if self._creds.get('project_member'): return self._creds.get('project_member') @@ -381,6 +385,10 @@ class PreProvisionedCredentialProvider(cred_provider.CredentialProvider): self._creds['project_member'] = project_member return project_member + def get_project_alt_member_creds(self): + # TODO(gmann): Implement alt member hash. + return + def get_project_reader_creds(self): if self._creds.get('project_reader'): return self._creds.get('project_reader') @@ -388,6 +396,10 @@ class PreProvisionedCredentialProvider(cred_provider.CredentialProvider): self._creds['project_reader'] = project_reader return project_reader + def get_project_alt_reader_creds(self): + # TODO(gmann): Implement alt reader hash. + return + def get_creds_by_roles(self, roles, force_new=False): roles = list(set(roles)) exist_creds = self._creds.get(str(roles).encode( diff --git a/tempest/test.py b/tempest/test.py index 68602d652d..2dfedeb3a4 100644 --- a/tempest/test.py +++ b/tempest/test.py @@ -296,6 +296,7 @@ class BaseTestCase(testtools.testcase.WithAttributes, identity_version = cls.get_identity_version() # setting force_tenant_isolation to True also needs admin credentials. if ('admin' in cls.credentials or + 'alt_admin' in cls.credentials or getattr(cls, 'force_tenant_isolation', False)): if not credentials.is_admin_available( identity_version=identity_version): diff --git a/tempest/tests/lib/common/test_dynamic_creds.py b/tempest/tests/lib/common/test_dynamic_creds.py index e9073ccf75..4bb6440733 100644 --- a/tempest/tests/lib/common/test_dynamic_creds.py +++ b/tempest/tests/lib/common/test_dynamic_creds.py @@ -213,6 +213,56 @@ class TestDynamicCredentialProvider(base.TestCase): self.assertEqual(admin_creds.tenant_id, '1234') self.assertEqual(admin_creds.user_id, '1234') + @mock.patch('tempest.lib.common.rest_client.RestClient') + def test_project_alt_admin_creds(self, MockRestClient): + creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params) + self._mock_list_roles('1234', 'admin') + self._mock_user_create('1234', 'fake_alt_admin_user') + self._mock_tenant_create('1234', 'fake_alt_admin') + + user_mock = mock.patch.object(self.roles_client.RolesClient, + 'create_user_role_on_project') + user_mock.start() + self.addCleanup(user_mock.stop) + with mock.patch.object(self.roles_client.RolesClient, + 'create_user_role_on_project') as user_mock: + alt_admin_creds = creds.get_project_alt_admin_creds() + user_mock.assert_has_calls([ + mock.call('1234', '1234', '1234')]) + self.assertEqual(alt_admin_creds.username, 'fake_alt_admin_user') + self.assertEqual(alt_admin_creds.project_name, 'fake_alt_admin') + # Verify IDs + self.assertEqual(alt_admin_creds.project_id, '1234') + self.assertEqual(alt_admin_creds.user_id, '1234') + + @mock.patch('tempest.lib.common.rest_client.RestClient') + def test_project_alt_member_creds(self, MockRestClient): + creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params) + self._mock_assign_user_role() + self._mock_list_role() + self._mock_tenant_create('1234', 'fake_alt_member') + self._mock_user_create('1234', 'fake_alt_user') + alt_member_creds = creds.get_project_alt_member_creds() + self.assertEqual(alt_member_creds.username, 'fake_alt_user') + self.assertEqual(alt_member_creds.project_name, 'fake_alt_member') + # Verify IDs + self.assertEqual(alt_member_creds.project_id, '1234') + self.assertEqual(alt_member_creds.user_id, '1234') + + @mock.patch('tempest.lib.common.rest_client.RestClient') + def test_project_alt_reader_creds(self, MockRestClient): + creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params) + self._mock_assign_user_role() + self._mock_list_roles('1234', 'reader') + self._mock_tenant_create('1234', 'fake_alt_reader') + self._mock_user_create('1234', 'fake_alt_user') + alt_reader_creds = creds.get_project_alt_reader_creds() + self.assertEqual(alt_reader_creds.username, 'fake_alt_user') + self.assertEqual(alt_reader_creds.project_name, 'fake_alt_reader') + # Verify IDs + self.assertEqual(alt_reader_creds.project_id, '1234') + self.assertEqual(alt_reader_creds.user_id, '1234') + @mock.patch('tempest.lib.common.rest_client.RestClient') def test_role_creds(self, MockRestClient): creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)