diff --git a/keystone_tempest_plugin/clients.py b/keystone_tempest_plugin/clients.py index 1a85bce..a72c9f5 100644 --- a/keystone_tempest_plugin/clients.py +++ b/keystone_tempest_plugin/clients.py @@ -14,6 +14,8 @@ from keystone_tempest_plugin.services.identity.v3 import ( identity_providers_client) +from keystone_tempest_plugin.services.identity.v3 import ( + mapping_rules_client) from keystone_tempest_plugin.services.identity.v3 import ( service_providers_client) @@ -28,6 +30,9 @@ class Manager(clients.Manager): self.identity_providers_client = ( identity_providers_client.IdentityProvidersClient( self.auth_provider)) + self.mapping_rules_client = ( + mapping_rules_client.MappingRulesClient( + self.auth_provider)) self.service_providers_client = ( service_providers_client.ServiceProvidersClient( self.auth_provider)) diff --git a/keystone_tempest_plugin/services/identity/v3/mapping_rules_client.py b/keystone_tempest_plugin/services/identity/v3/mapping_rules_client.py new file mode 100644 index 0000000..5554756 --- /dev/null +++ b/keystone_tempest_plugin/services/identity/v3/mapping_rules_client.py @@ -0,0 +1,60 @@ +# Copyright 2016 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_serialization import jsonutils + +from tempest.lib.common import rest_client + +from keystone_tempest_plugin.services.identity import clients + + +class MappingRulesClient(clients.Federation): + + subpath_suffix = 'mappings' + + def create_mapping_rule(self, mapping_id, rules): + """Create a mapping rule.""" + put_body = jsonutils.dumps({'mapping': rules}) + resp, body = self._put(mapping_id, put_body) + self.expected_success(201, resp.status) + body = jsonutils.loads(body) + return rest_client.ResponseBody(resp, body) + + def list_mapping_rules(self): + """List the mapping rules.""" + resp, body = self._get() + self.expected_success(200, resp.status) + body = jsonutils.loads(body) + return rest_client.ResponseBody(resp, body) + + def show_mapping_rule(self, mapping_id): + """Get a mapping rule.""" + resp, body = self._get(mapping_id) + self.expected_success(200, resp.status) + body = jsonutils.loads(body) + return rest_client.ResponseBody(resp, body) + + def delete_mapping_rule(self, mapping_id): + """Delete a mapping rule.""" + resp, body = self._delete(mapping_id) + self.expected_success(204, resp.status) + return rest_client.ResponseBody(resp, body) + + def update_mapping_rule(self, mapping_id, rules): + """Update a mapping rule.""" + patch_body = jsonutils.dumps({'mapping': rules}) + resp, body = self._patch(mapping_id, patch_body) + self.expected_success(200, resp.status) + body = jsonutils.loads(body) + return rest_client.ResponseBody(resp, body) diff --git a/keystone_tempest_plugin/tests/api/identity/base.py b/keystone_tempest_plugin/tests/api/identity/base.py index d8924c4..8fa3c79 100644 --- a/keystone_tempest_plugin/tests/api/identity/base.py +++ b/keystone_tempest_plugin/tests/api/identity/base.py @@ -34,4 +34,5 @@ class BaseIdentityTest(test.BaseTestCase): cls.credential_type, identity_version=cls.identity_version) cls.keystone_manager = clients.Manager(credentials=credentials) cls.idps_client = cls.keystone_manager.identity_providers_client + cls.mappings_client = cls.keystone_manager.mapping_rules_client cls.sps_client = cls.keystone_manager.service_providers_client diff --git a/keystone_tempest_plugin/tests/api/identity/v3/fixtures.py b/keystone_tempest_plugin/tests/api/identity/v3/fixtures.py index 434ade7..4e5899c 100644 --- a/keystone_tempest_plugin/tests/api/identity/v3/fixtures.py +++ b/keystone_tempest_plugin/tests/api/identity/v3/fixtures.py @@ -28,6 +28,30 @@ def idp_ref(enabled=None, remote_ids=None): return ref +def mapping_ref(): + rules = [{ + 'local': [ + { + 'user': {'name': '{0}'} + }, + { + 'group_ids': '{1}' + } + ], + 'remote': [ + { + 'type': 'openstack_username' + }, + { + 'type': 'group_ids', + 'whitelist': ['abc', '123'] + } + + ] + }] + return {'rules': rules} + + def sp_ref(enabled=None, relay_state_prefix=None): ref = { 'auth_url': data_utils.rand_url(), diff --git a/keystone_tempest_plugin/tests/api/identity/v3/test_mapping_rules.py b/keystone_tempest_plugin/tests/api/identity/v3/test_mapping_rules.py new file mode 100644 index 0000000..f544671 --- /dev/null +++ b/keystone_tempest_plugin/tests/api/identity/v3/test_mapping_rules.py @@ -0,0 +1,98 @@ +# Copyright 2016 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from tempest.lib.common.utils import data_utils +from tempest.lib import decorators +from tempest.lib import exceptions as lib_exc +from tempest import test + +from keystone_tempest_plugin.tests.api.identity import base +from keystone_tempest_plugin.tests.api.identity.v3 import fixtures + + +class MappingRulesTest(base.BaseIdentityTest): + + _MAPPING_REF = fixtures.mapping_ref() + + def _assert_mapping_rules_attributes(self, mapping, mapping_id, + mapping_ref=None): + self.assertIn('id', mapping) + self.assertEqual(mapping_id, mapping['id']) + + self.assertIn('rules', mapping) + + if mapping_ref: + self.assertItemsEqual(mapping_ref['rules'], mapping['rules']) + + def _create_mapping_rule(self, mapping_id, mapping_ref): + mapping = self.mappings_client.create_mapping_rule( + mapping_id, mapping_ref)['mapping'] + self.addCleanup(self.mappings_client.delete_mapping_rule, mapping_id) + return mapping + + @decorators.idempotent_id('4ca48c01-b6da-4759-acb6-007e15ad712a') + def test_mapping_rules_create(self): + mapping_id = data_utils.rand_uuid_hex() + mapping = self._create_mapping_rule(mapping_id, self._MAPPING_REF) + self._assert_mapping_rules_attributes( + mapping, mapping_id, self._MAPPING_REF) + + @test.attr(type=['negative']) + @decorators.idempotent_id('341dac45-ce1f-4f15-afdc-1f9a7d7d7c40') + def test_mapping_rules_create_without_mandatory_attributes(self): + mapping_id = data_utils.rand_uuid_hex() + self.assertRaises( + lib_exc.BadRequest, + self.mappings_client.create_mapping_rule, + mapping_id, + {}) + + @decorators.idempotent_id('8db213e3-1db0-48c6-863c-7a3ed23577ec') + def test_mapping_rules_get(self): + mapping_id = data_utils.rand_uuid_hex() + mapping_create = self._create_mapping_rule( + mapping_id, self._MAPPING_REF) + + mapping_get = self.mappings_client.show_mapping_rule(mapping_id)[ + 'mapping'] + self._assert_mapping_rules_attributes( + mapping_get, mapping_id, mapping_create) + + @decorators.idempotent_id('bb80b242-2a6a-4d29-b45f-4035be574a6e') + def test_mapping_rules_list(self): + mapping_ids = [] + for _ in range(3): + mapping_id = data_utils.rand_uuid_hex() + self._create_mapping_rule(mapping_id, self._MAPPING_REF) + mapping_ids.append(mapping_id) + + mappings_list = self.mappings_client.list_mapping_rules()['mappings'] + fetched_ids = [mapping['id'] for mapping in mappings_list] + + for mapping_id in mapping_ids: + self.assertIn(mapping_id, fetched_ids) + + @decorators.idempotent_id('1fc5d104-faf5-4809-8c89-29b5c1666a96') + def test_mapping_rule_update(self): + mapping_id = data_utils.rand_uuid_hex() + mapping_ref = fixtures.mapping_ref() + mapping = self._create_mapping_rule(mapping_id, mapping_ref) + + new_local = [{'group': {'id': data_utils.rand_uuid_hex()}}] + mapping_ref['rules'][0]['local'] = new_local + + mapping = self.mappings_client.update_mapping_rule( + mapping_id, mapping_ref)['mapping'] + self._assert_mapping_rules_attributes( + mapping, mapping_id, mapping_ref)