From 99a427833b70164e974c0d17b093dfbce6952813 Mon Sep 17 00:00:00 2001 From: Steve Martinelli <stevemar@ca.ibm.com> Date: Fri, 11 Dec 2015 02:17:37 -0500 Subject: [PATCH] deprecate write support for identity LDAP At the previous summit, we decided to deprecate write support for idenity LPAP. It'll be removed in 2 releases. Several config options were affected, and those operations should now have deprecation warnings. implements bp: deprecated-as-of-mitaka Change-Id: I1e989d6c5e85ba303609c7bb36116a8bdedce9e4 --- keystone/common/config.py | 30 ++++++++++++++ keystone/identity/backends/ldap.py | 21 ++++++++++ keystone/tests/unit/test_backend_ldap.py | 41 ++++++++++++++++++- ...recated-as-of-mitaka-8534e43fa40c1d09.yaml | 7 ++++ 4 files changed, 97 insertions(+), 2 deletions(-) diff --git a/keystone/common/config.py b/keystone/common/config.py index 3663d58bfb..8a6d07a869 100644 --- a/keystone/common/config.py +++ b/keystone/common/config.py @@ -626,10 +626,25 @@ FILE_OPTIONS = { help='LDAP attribute mapped to default_project_id for ' 'users.'), cfg.BoolOpt('user_allow_create', default=True, + deprecated_for_removal=True, + deprecated_reason="Write support for Identity LDAP " + "backends has been deprecated in the M " + "release and will be removed in the O " + "release.", help='Allow user creation in LDAP backend.'), cfg.BoolOpt('user_allow_update', default=True, + deprecated_for_removal=True, + deprecated_reason="Write support for Identity LDAP " + "backends has been deprecated in the M " + "release and will be removed in the O " + "release.", help='Allow user updates in LDAP backend.'), cfg.BoolOpt('user_allow_delete', default=True, + deprecated_for_removal=True, + deprecated_reason="Write support for Identity LDAP " + "backends has been deprecated in the M " + "release and will be removed in the O " + "release.", help='Allow user deletion in LDAP backend.'), cfg.BoolOpt('user_enabled_emulation', default=False, help='If true, Keystone uses an alternative method to ' @@ -669,10 +684,25 @@ FILE_OPTIONS = { help='List of attributes stripped off the group on ' 'update.'), cfg.BoolOpt('group_allow_create', default=True, + deprecated_for_removal=True, + deprecated_reason="Write support for Identity LDAP " + "backends has been deprecated in the M " + "release and will be removed in the O " + "release.", help='Allow group creation in LDAP backend.'), cfg.BoolOpt('group_allow_update', default=True, + deprecated_for_removal=True, + deprecated_reason="Write support for Identity LDAP " + "backends has been deprecated in the M " + "release and will be removed in the O " + "release.", help='Allow group update in LDAP backend.'), cfg.BoolOpt('group_allow_delete', default=True, + deprecated_for_removal=True, + deprecated_reason="Write support for Identity LDAP " + "backends has been deprecated in the M " + "release and will be removed in the O " + "release.", help='Allow group deletion in LDAP backend.'), cfg.ListOpt('group_additional_attribute_mapping', default=[], diff --git a/keystone/identity/backends/ldap.py b/keystone/identity/backends/ldap.py index ce08b7dfc1..d458b20325 100644 --- a/keystone/identity/backends/ldap.py +++ b/keystone/identity/backends/ldap.py @@ -17,6 +17,7 @@ import uuid import ldap.filter from oslo_config import cfg from oslo_log import log +from oslo_log import versionutils import six from keystone.common import clean @@ -31,6 +32,10 @@ from keystone import identity CONF = cfg.CONF LOG = log.getLogger(__name__) +_DEPRECATION_MSG = _('%s for the LDAP identity backend has been deprecated in ' + 'the Mitaka release in favor of read-only identity LDAP ' + 'access. It will be removed in the "O" release.') + class Identity(identity.IdentityDriverV8): def __init__(self, conf=None): @@ -87,11 +92,15 @@ class Identity(identity.IdentityDriverV8): # CRUD def create_user(self, user_id, user): + msg = _DEPRECATION_MSG % "create_user" + versionutils.report_deprecated_feature(LOG, msg) self.user.check_allow_create() user_ref = self.user.create(user) return self.user.filter_attributes(user_ref) def update_user(self, user_id, user): + msg = _DEPRECATION_MSG % "update_user" + versionutils.report_deprecated_feature(LOG, msg) self.user.check_allow_update() old_obj = self.user.get(user_id) if 'name' in user and old_obj.get('name') != user['name']: @@ -110,6 +119,8 @@ class Identity(identity.IdentityDriverV8): return self.user.get_filtered(user_id) def delete_user(self, user_id): + msg = _DEPRECATION_MSG % "delete_user" + versionutils.report_deprecated_feature(LOG, msg) self.user.check_allow_delete() user = self.user.get(user_id) user_dn = user['dn'] @@ -122,6 +133,8 @@ class Identity(identity.IdentityDriverV8): self.user.delete(user_id) def create_group(self, group_id, group): + msg = _DEPRECATION_MSG % "create_group" + versionutils.report_deprecated_feature(LOG, msg) self.group.check_allow_create() group['name'] = clean.group_name(group['name']) return common_ldap.filter_entity(self.group.create(group)) @@ -135,21 +148,29 @@ class Identity(identity.IdentityDriverV8): return self.group.get_filtered_by_name(group_name) def update_group(self, group_id, group): + msg = _DEPRECATION_MSG % "update_group" + versionutils.report_deprecated_feature(LOG, msg) self.group.check_allow_update() if 'name' in group: group['name'] = clean.group_name(group['name']) return common_ldap.filter_entity(self.group.update(group_id, group)) def delete_group(self, group_id): + msg = _DEPRECATION_MSG % "delete_group" + versionutils.report_deprecated_feature(LOG, msg) self.group.check_allow_delete() return self.group.delete(group_id) def add_user_to_group(self, user_id, group_id): + msg = _DEPRECATION_MSG % "add_user_to_group" + versionutils.report_deprecated_feature(LOG, msg) user_ref = self._get_user(user_id) user_dn = user_ref['dn'] self.group.add_user(user_dn, group_id, user_id) def remove_user_from_group(self, user_id, group_id): + msg = _DEPRECATION_MSG % "remove_user_from_group" + versionutils.report_deprecated_feature(LOG, msg) user_ref = self._get_user(user_id) user_dn = user_ref['dn'] self.group.remove_user(user_dn, group_id, user_id) diff --git a/keystone/tests/unit/test_backend_ldap.py b/keystone/tests/unit/test_backend_ldap.py index 633436616a..b74ca4d439 100644 --- a/keystone/tests/unit/test_backend_ldap.py +++ b/keystone/tests/unit/test_backend_ldap.py @@ -20,6 +20,7 @@ import uuid import ldap import mock from oslo_config import cfg +from oslo_log import versionutils from oslotest import mockpatch import pkg_resources from six.moves import http_client @@ -669,21 +670,46 @@ class BaseLDAPIdentity(test_backend.IdentityTests): # do not yet support the update of either group or domain names with LDAP. # In the tests below, the update is demonstrated by updating description. # Refer to bug 1136403 for more detail. - def test_group_crud(self): + @mock.patch.object(versionutils, 'report_deprecated_feature') + def test_group_crud(self, mock_deprecator): + # NOTE(stevemar): As of the Mitaka release, we now check for calls that + # the LDAP write functionality has been deprecated. group = unit.new_group_ref(domain_id=CONF.identity.default_domain_id) group = self.identity_api.create_group(group) + args, _kwargs = mock_deprecator.call_args + self.assertIn("create_group for the LDAP identity backend", args[1]) + group_ref = self.identity_api.get_group(group['id']) self.assertDictEqual(group, group_ref) group['description'] = uuid.uuid4().hex self.identity_api.update_group(group['id'], group) + args, _kwargs = mock_deprecator.call_args + self.assertIn("update_group for the LDAP identity backend", args[1]) + group_ref = self.identity_api.get_group(group['id']) self.assertDictEqual(group, group_ref) self.identity_api.delete_group(group['id']) + args, _kwargs = mock_deprecator.call_args + self.assertIn("delete_group for the LDAP identity backend", args[1]) self.assertRaises(exception.GroupNotFound, self.identity_api.get_group, group['id']) + @mock.patch.object(versionutils, 'report_deprecated_feature') + def test_add_remove_user_group_deprecated(self, mock_deprecator): + group = unit.new_group_ref(domain_id=CONF.identity.default_domain_id) + group = self.identity_api.create_group(group) + user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) + user = self.identity_api.create_user(user) + self.identity_api.add_user_to_group(user['id'], group['id']) + args, _kwargs = mock_deprecator.call_args + self.assertIn("add_user_to_group for the LDAP identity", args[1]) + + self.identity_api.remove_user_from_group(user['id'], group['id']) + args, _kwargs = mock_deprecator.call_args + self.assertIn("remove_user_from_group for the LDAP identity", args[1]) + @unit.skip_if_cache_disabled('identity') def test_cache_layer_group_crud(self): group = unit.new_group_ref(domain_id=CONF.identity.default_domain_id) @@ -1852,10 +1878,16 @@ class LDAPIdentityEnabledEmulation(LDAPIdentity): self.resource_api.get_project, project['id']) - def test_user_crud(self): + @mock.patch.object(versionutils, 'report_deprecated_feature') + def test_user_crud(self, mock_deprecator): + # NOTE(stevemar): As of the Mitaka release, we now check for calls that + # the LDAP write functionality has been deprecated. user_dict = self.new_user_ref( domain_id=CONF.identity.default_domain_id) user = self.identity_api.create_user(user_dict) + args, _kwargs = mock_deprecator.call_args + self.assertIn("create_user for the LDAP identity backend", args[1]) + del user_dict['password'] user_ref = self.identity_api.get_user(user['id']) user_ref_dict = {x: user_ref[x] for x in user_ref} @@ -1863,12 +1895,17 @@ class LDAPIdentityEnabledEmulation(LDAPIdentity): user_dict['password'] = uuid.uuid4().hex self.identity_api.update_user(user['id'], user_dict) + args, _kwargs = mock_deprecator.call_args + self.assertIn("update_user for the LDAP identity backend", args[1]) + del user_dict['password'] user_ref = self.identity_api.get_user(user['id']) user_ref_dict = {x: user_ref[x] for x in user_ref} self.assertDictContainsSubset(user_dict, user_ref_dict) self.identity_api.delete_user(user['id']) + args, _kwargs = mock_deprecator.call_args + self.assertIn("delete_user for the LDAP identity backend", args[1]) self.assertRaises(exception.UserNotFound, self.identity_api.get_user, user['id']) diff --git a/releasenotes/notes/deprecated-as-of-mitaka-8534e43fa40c1d09.yaml b/releasenotes/notes/deprecated-as-of-mitaka-8534e43fa40c1d09.yaml index 9de697a826..11b0e21150 100644 --- a/releasenotes/notes/deprecated-as-of-mitaka-8534e43fa40c1d09.yaml +++ b/releasenotes/notes/deprecated-as-of-mitaka-8534e43fa40c1d09.yaml @@ -6,3 +6,10 @@ deprecations: deprecated. They will be removed in the 'O' release. Due to this change, the ``hash_algorithm`` option in the ``[token]`` section of the configuration file has also been deprecated. + - > + [`blueprint deprecated-as-of-mitaka <https://blueprints.launchpad.net/keystone/+spec/deprecated-as-of-mitaka>`_] + As of the Mitaka release, write support for the LDAP driver of the Identity + backend has been deprecated. This includes the following operations: create user, + create group, delete user, delete group, update user, update group, + add user to group, and remove user from group. These operations will be + removed in the 'O' release.