From b4fdb83355e27c2e6f3d216cdc892f301391af6d Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mar 31 2020 15:55:35 +0000 Subject: Allow rename of a host group RN: host groups can now be renamed with IPA CLI: RN: 'ipa hostgroup-mod group-name --rename new-name'. RN: Protected hostgroups ('ipaservers') cannot be renamed. Fixes: https://pagure.io/freeipa/issue/6783 Signed-off-by: Alexander Bokovoy Reviewed-By: Rob Crittenden Reviewed-By: Florence Blanc-Renaud --- diff --git a/API.txt b/API.txt index 9459762..3e65883 100644 --- a/API.txt +++ b/API.txt @@ -2789,7 +2789,7 @@ output: ListOfEntries('result') output: Output('summary', type=[, ]) output: Output('truncated', type=[]) command: hostgroup_mod/1 -args: 1,9,3 +args: 1,10,3 arg: Str('cn', cli_name='hostgroup_name') option: Str('addattr*', cli_name='addattr') option: Flag('all', autofill=True, cli_name='all', default=False) @@ -2797,6 +2797,7 @@ option: Str('delattr*', cli_name='delattr') option: Str('description?', autofill=False, cli_name='desc') option: Flag('no_members', autofill=True, default=False) option: Flag('raw', autofill=True, cli_name='raw', default=False) +option: Str('rename?', cli_name='rename') option: Flag('rights', autofill=True, default=False) option: Str('setattr*', cli_name='setattr') option: Str('version?') diff --git a/VERSION.m4 b/VERSION.m4 index c826756..11707d5 100644 --- a/VERSION.m4 +++ b/VERSION.m4 @@ -86,8 +86,9 @@ define(IPA_DATA_VERSION, 20100614120000) # # ######################################################## define(IPA_API_VERSION_MAJOR, 2) -define(IPA_API_VERSION_MINOR, 236) -# Last change: Add trust_enable_agent. +define(IPA_API_VERSION_MINOR, 237) +# Last change: allow rename a hostgroup + ######################################################## # Following values are auto-generated from values above diff --git a/ipaserver/plugins/hostgroup.py b/ipaserver/plugins/hostgroup.py index 85e6e36..aa03fd4 100644 --- a/ipaserver/plugins/hostgroup.py +++ b/ipaserver/plugins/hostgroup.py @@ -113,6 +113,7 @@ class hostgroup(LDAPObject): 'memberofindirect', 'membermanager', ] uuid_attribute = 'ipauniqueid' + allow_rename = True attribute_members = { 'member': ['host', 'hostgroup'], 'membermanager': ['user', 'group'], @@ -276,6 +277,16 @@ class hostgroup_mod(LDAPUpdate): has_output_params = LDAPUpdate.has_output_params + hostgroup_output_params msg_summary = _('Modified hostgroup "%(value)s"') + def pre_callback(self, ldap, dn, entry_attrs, attrs_list, + *keys, **options): + assert isinstance(dn, DN) + if keys[0] in PROTECTED_HOSTGROUPS and 'rename' in options: + raise errors.ProtectedEntryError(label=_(u'hostgroup'), + key=keys[0], + reason=_(u'privileged hostgroup')) + + return dn + def post_callback(self, ldap, dn, entry_attrs, *keys, **options): assert isinstance(dn, DN) self.obj.suppress_netgroup_memberof(ldap, dn, entry_attrs) diff --git a/ipatests/test_xmlrpc/test_hostgroup_plugin.py b/ipatests/test_xmlrpc/test_hostgroup_plugin.py index 361fd9d..a94062d 100644 --- a/ipatests/test_xmlrpc/test_hostgroup_plugin.py +++ b/ipatests/test_xmlrpc/test_hostgroup_plugin.py @@ -29,6 +29,7 @@ from ipatests.test_xmlrpc.tracker.host_plugin import HostTracker from ipalib import errors import pytest +renamedhostgroup1 = u'renamedhostgroup1' @pytest.fixture(scope='class') def hostgroup(request, xmlrpc_setup): @@ -54,6 +55,20 @@ def host(request, xmlrpc_setup): return tracker.make_fixture(request) +@pytest.fixture(scope='class') +def ipaservers(request, xmlrpc_setup): + # Track the ipaservers hostgroup + # Since the hostgroup is protected, we cannot use 'make_fixture()' because + # it will try to delete the object when scope is destroyed and that will + # fail. Thus, we only create it here. + tracker = HostGroupTracker( + name=u'ipaservers', description=u'IPA server hosts' + ) + tracker.exists = True + tracker.track_create() + return tracker + + class TestNonexistentHostGroup(XMLRPC_test): def test_retrieve_nonexistent(self, hostgroup): """ Try to retrieve non-existent hostgroup """ @@ -105,6 +120,35 @@ class TestHostGroup(XMLRPC_test): hostgroup.cn)): command() + def test_rename_hostgroup(self, hostgroup): + """ Rename a hostgroup and than rename it back """ + origname = hostgroup.cn + + command = hostgroup.make_command( + 'hostgroup_mod', *[hostgroup.cn], + **dict(setattr=u'cn=%s' % renamedhostgroup1)) + result = command() + hostgroup.attrs.update(cn=[renamedhostgroup1]) + hostgroup.check_update(result) + hostgroup.cn = renamedhostgroup1 + + command = hostgroup.make_command( + 'hostgroup_mod', *[hostgroup.cn], + **dict(setattr=u'cn=%s' % origname)) + result = command() + hostgroup.attrs.update(cn=[origname]) + hostgroup.check_update(result) + hostgroup.cn = origname + + def test_rename_ipaservers(self, ipaservers): + """ Try to rename the protected ipaservers group """ + command = ipaservers.make_command('hostgroup_mod', *[ipaservers.cn], + **dict(rename=renamedhostgroup1)) + reason = u'privileged hostgroup' + with raises_exact(errors.ProtectedEntryError(label=u'hostgroup', + key=ipaservers.cn, reason=reason)): + command() + def test_create_host_add_to_hostgroup(self, hostgroup, host): """ Check that host can be added to hostgroup """ host.create()