diff --git a/keystone/common/resource_options/options/immutable.py b/keystone/common/resource_options/options/immutable.py index 8f0c44f209..2a0d8eb1a4 100644 --- a/keystone/common/resource_options/options/immutable.py +++ b/keystone/common/resource_options/options/immutable.py @@ -54,6 +54,20 @@ def check_immutable_update( immutable = check_resource_immutable(original_resource_ref) if immutable: new_options = new_resource_ref.get('options', {}) + if type == "domain": + if ( + new_resource_ref.get("is_domain", False) == True + and not new_resource_ref.get("domain_id") + and not new_resource_ref.get("parent_id") + ): + # To keep next check happy - reject certain props for the domain set by default in + # `get_project_from_domain` if those ARE default + new_resource_ref.pop("is_domain") + new_resource_ref.pop("domain_id") + new_resource_ref.pop("parent_id") + # If resource is currently immutable - raise error in attempt to + # update more then 1 property while making resource mutable + # (first make mutable then update rest) if ( (len(new_resource_ref.keys()) > 1) or (IMMUTABLE_OPT.option_name not in new_options) diff --git a/keystone/tests/unit/resource/test_backends.py b/keystone/tests/unit/resource/test_backends.py index 811a5d5d42..6c505ddc65 100644 --- a/keystone/tests/unit/resource/test_backends.py +++ b/keystone/tests/unit/resource/test_backends.py @@ -2184,13 +2184,18 @@ class ResourceTests: # domains are projects, this should be the same as the project version domain_id = uuid.uuid4().hex - domain = {'name': uuid.uuid4().hex, 'id': domain_id, 'is_domain': True} + domain = { + 'name': uuid.uuid4().hex, + 'id': domain_id, + 'is_domain': True, + 'options': {ro_opt.IMMUTABLE_OPT.option_name: True}, + } PROVIDERS.resource_api.create_domain(domain_id, domain) domain_via_manager = PROVIDERS.resource_api.get_domain(domain_id) self.assertTrue('options' in domain_via_manager) - self.assertFalse( - ro_opt.IMMUTABLE_OPT.option_name in domain_via_manager['options'] + self.assertTrue( + domain_via_manager['options'][ro_opt.IMMUTABLE_OPT.option_name] ) update_domain = {'options': {ro_opt.IMMUTABLE_OPT.option_name: False}}