Remove code supporting moving resources between domains

Code moving users, groups, and projects between domains has been
removed and errors consolidated at the manager level (instead of
the controller level).

Change-Id: I73e77cc6dd5081d25dcd85ff2d2a61555829066d
bp: removed-as-of-ocata
This commit is contained in:
Morgan Fainberg 2017-01-24 13:06:05 -08:00
parent 35deec22f8
commit 821a4ffafa
7 changed files with 39 additions and 109 deletions

View File

@ -664,28 +664,6 @@ class V3Controller(wsgi.Application):
if 'id' in ref and ref['id'] != value:
raise exception.ValidationError('Cannot change ID')
def _require_matching_domain_id(self, ref_id, ref, get_member):
"""Ensure the current domain ID matches the reference one, if any.
Provided we want domain IDs to be immutable, check whether any
domain_id specified in the ref dictionary matches the existing
domain_id for this entity.
:param ref_id: the ID of the entity
:param ref: the dictionary of new values proposed for this entity
:param get_member: The member function to call to get the current
entity
:raises: :class:`keystone.exception.ValidationError`
"""
# TODO(henry-nash): It might be safer and more efficient to do this
# check in the managers affected, so look to migrate this check to
# there in the future.
if 'domain_id' in ref:
existing_ref = get_member(ref_id)
if ref['domain_id'] != existing_ref['domain_id']:
raise exception.ValidationError(_('Cannot change Domain ID'))
def _assign_unique_id(self, ref):
"""Generate and assigns a unique identifier to a reference."""
ref = ref.copy()

View File

@ -243,8 +243,6 @@ class UserV3(controller.V3Controller):
def _update_user(self, request, user_id, user):
self._require_matching_id(user_id, user)
self._require_matching_domain_id(
user_id, user, self.identity_api.get_user)
ref = self.identity_api.update_user(
user_id, user, initiator=request.audit_initiator
)
@ -346,8 +344,6 @@ class GroupV3(controller.V3Controller):
def update_group(self, request, group_id, group):
validation.lazy_validate(schema.group_update, group)
self._require_matching_id(group_id, group)
self._require_matching_domain_id(
group_id, group, self.identity_api.get_group)
ref = self.identity_api.update_group(
group_id, group, initiator=request.audit_initiator
)

View File

@ -21,7 +21,6 @@ import uuid
from oslo_config import cfg
from oslo_log import log
from oslo_log import versionutils
from pycadf import reason
from keystone import assignment # TODO(lbragstad): Decouple this dependency
@ -983,29 +982,34 @@ class Manager(manager.Manager):
return self._set_domain_id_and_mapping(
ref_list, domain_scope, driver, mapping.EntityType.USER)
def _check_update_of_domain_id(self, new_domain, old_domain):
if new_domain != old_domain:
versionutils.report_deprecated_feature(
LOG,
_('update of domain_id is deprecated as of Mitaka '
'and will be removed in O.')
)
def _require_matching_domain_id(self, new_ref, orig_ref):
"""Ensure the current domain ID matches the reference one, if any.
Provided we want domain IDs to be immutable, check whether any
domain_id specified in the ref dictionary matches the existing
domain_id for this entity.
:param new_ref: the dictionary of new values proposed for this entity
:param orig_ref: the dictionary of original values proposed for this
entity
:raises: :class:`keystone.exception.ValidationError`
"""
if 'domain_id' in new_ref:
if new_ref['domain_id'] != orig_ref['domain_id']:
raise exception.ValidationError(_('Cannot change Domain ID'))
@domains_configured
@exception_translated('user')
def update_user(self, user_id, user_ref, initiator=None):
old_user_ref = self.get_user(user_id)
user = user_ref.copy()
self._require_matching_domain_id(user, old_user_ref)
if 'password' in user:
validators.validate_password(user['password'])
if 'name' in user:
user['name'] = clean.user_name(user['name'])
if 'enabled' in user:
user['enabled'] = clean.user_enabled(user['enabled'])
if 'domain_id' in user:
self._check_update_of_domain_id(user['domain_id'],
old_user_ref['domain_id'])
self.resource_api.get_domain(user['domain_id'])
if 'id' in user:
if user_id != user['id']:
raise exception.ValidationError(_('Cannot change user ID'))
@ -1101,11 +1105,8 @@ class Manager(manager.Manager):
@domains_configured
@exception_translated('group')
def update_group(self, group_id, group, initiator=None):
if 'domain_id' in group:
old_group_ref = self.get_group(group_id)
self._check_update_of_domain_id(group['domain_id'],
old_group_ref['domain_id'])
self.resource_api.get_domain(group['domain_id'])
old_group_ref = self.get_group(group_id)
self._require_matching_domain_id(group, old_group_ref)
domain_id, driver, entity_id = (
self._get_domain_driver_and_entity_id(group_id))
group = self._clear_domain_id_if_domain_unaware(driver, group)

View File

@ -336,8 +336,6 @@ class ProjectV3(controller.V3Controller):
def update_project(self, request, project_id, project):
validation.lazy_validate(schema.project_update, project)
self._require_matching_id(project_id, project)
self._require_matching_domain_id(
project_id, project, self.resource_api.get_project)
ref = self.resource_api.update_project(
project_id,
project,

View File

@ -280,6 +280,7 @@ class Manager(manager.Manager):
# Use the driver directly to prevent using old cached value.
original_project = self.driver.get_project(project_id)
project = project.copy()
self._require_matching_domain_id(project, original_project)
if original_project['is_domain']:
domain = self._get_domain_from_project(original_project)
@ -855,6 +856,22 @@ class Manager(manager.Manager):
LOG.error(_LE('Failed to create the default domain.'))
raise
def _require_matching_domain_id(self, new_ref, orig_ref):
"""Ensure the current domain ID matches the reference one, if any.
Provided we want domain IDs to be immutable, check whether any
domain_id specified in the ref dictionary matches the existing
domain_id for this entity.
:param new_ref: the dictionary of new values proposed for this entity
:param orig_ref: the dictionary of original values proposed for this
entity
:raises: :class:`keystone.exception.ValidationError`
"""
if 'domain_id' in new_ref:
if new_ref['domain_id'] != orig_ref['domain_id']:
raise exception.ValidationError(_('Cannot change Domain ID'))
MEMOIZE_CONFIG = cache.get_memoization_decorator(group='domain_config')

View File

@ -15,7 +15,6 @@
import datetime
import uuid
import mock
from six.moves import range
from testtools import matchers
@ -236,35 +235,8 @@ class IdentityTests(object):
user = unit.new_user_ref(domain_id=domain1['id'])
user = self.identity_api.create_user(user)
user['domain_id'] = domain2['id']
# Update the user asserting that a deprecation warning is emitted
with mock.patch(
'oslo_log.versionutils.report_deprecated_feature') as mock_dep:
self.identity_api.update_user(user['id'], user)
self.assertTrue(mock_dep.called)
updated_user_ref = self.identity_api.get_user(user['id'])
self.assertEqual(domain2['id'], updated_user_ref['domain_id'])
def test_move_user_between_domains_with_clashing_names_fails(self):
domain1 = unit.new_domain_ref()
self.resource_api.create_domain(domain1['id'], domain1)
domain2 = unit.new_domain_ref()
self.resource_api.create_domain(domain2['id'], domain2)
# First, create a user in domain1
user1 = unit.new_user_ref(domain_id=domain1['id'])
user1 = self.identity_api.create_user(user1)
# Now create a user in domain2 with a potentially clashing
# name - which should work since we have domain separation
user2 = unit.new_user_ref(name=user1['name'],
domain_id=domain2['id'])
user2 = self.identity_api.create_user(user2)
# Now try and move user1 into the 2nd domain - which should
# fail since the names clash
user1['domain_id'] = domain2['id']
self.assertRaises(exception.Conflict,
self.identity_api.update_user,
user1['id'],
user1)
self.assertRaises(exception.ValidationError,
self.identity_api.update_user, user['id'], user)
def test_rename_duplicate_user_name_fails(self):
user1 = unit.new_user_ref(domain_id=CONF.identity.default_domain_id)
@ -943,35 +915,9 @@ class IdentityTests(object):
group = unit.new_group_ref(domain_id=domain1['id'])
group = self.identity_api.create_group(group)
group['domain_id'] = domain2['id']
# Update the group asserting that a deprecation warning is emitted
with mock.patch(
'oslo_log.versionutils.report_deprecated_feature') as mock_dep:
self.identity_api.update_group(group['id'], group)
self.assertTrue(mock_dep.called)
updated_group_ref = self.identity_api.get_group(group['id'])
self.assertEqual(domain2['id'], updated_group_ref['domain_id'])
def test_move_group_between_domains_with_clashing_names_fails(self):
domain1 = unit.new_domain_ref()
self.resource_api.create_domain(domain1['id'], domain1)
domain2 = unit.new_domain_ref()
self.resource_api.create_domain(domain2['id'], domain2)
# First, create a group in domain1
group1 = unit.new_group_ref(domain_id=domain1['id'])
group1 = self.identity_api.create_group(group1)
# Now create a group in domain2 with a potentially clashing
# name - which should work since we have domain separation
group2 = unit.new_group_ref(name=group1['name'],
domain_id=domain2['id'])
group2 = self.identity_api.create_group(group2)
# Now try and move group1 into the 2nd domain - which should
# fail since the names clash
group1['domain_id'] = domain2['id']
self.assertRaises(exception.Conflict,
self.assertRaises(exception.ValidationError,
self.identity_api.update_group,
group1['id'],
group1)
group['id'], group)
def test_user_crud(self):
user_dict = unit.new_user_ref(

View File

@ -137,15 +137,9 @@ class IdentityTests(identity_tests.IdentityTests):
def test_move_user_between_domains(self):
self.skip_test_overrides('Domains are read-only against LDAP')
def test_move_user_between_domains_with_clashing_names_fails(self):
self.skip_test_overrides('Domains are read-only against LDAP')
def test_move_group_between_domains(self):
self.skip_test_overrides('N/A: LDAP does not support multiple domains')
def test_move_group_between_domains_with_clashing_names_fails(self):
self.skip_test_overrides('Domains are read-only against LDAP')
def test_arbitrary_attributes_are_returned_from_get_user(self):
self.skip_test_overrides(
"Using arbitrary attributes doesn't work under LDAP")