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 <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
Alexander Bokovoy 2019-08-01 17:19:23 +03:00
parent 01b207bcd5
commit 6472a107d6
4 changed files with 60 additions and 3 deletions

View File

@ -2789,7 +2789,7 @@ output: ListOfEntries('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>]) output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: Output('truncated', type=[<type 'bool'>]) output: Output('truncated', type=[<type 'bool'>])
command: hostgroup_mod/1 command: hostgroup_mod/1
args: 1,9,3 args: 1,10,3
arg: Str('cn', cli_name='hostgroup_name') arg: Str('cn', cli_name='hostgroup_name')
option: Str('addattr*', cli_name='addattr') option: Str('addattr*', cli_name='addattr')
option: Flag('all', autofill=True, cli_name='all', default=False) 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: Str('description?', autofill=False, cli_name='desc')
option: Flag('no_members', autofill=True, default=False) option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', 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: Flag('rights', autofill=True, default=False)
option: Str('setattr*', cli_name='setattr') option: Str('setattr*', cli_name='setattr')
option: Str('version?') option: Str('version?')

View File

@ -86,8 +86,9 @@ define(IPA_DATA_VERSION, 20100614120000)
# # # #
######################################################## ########################################################
define(IPA_API_VERSION_MAJOR, 2) define(IPA_API_VERSION_MAJOR, 2)
define(IPA_API_VERSION_MINOR, 236) define(IPA_API_VERSION_MINOR, 237)
# Last change: Add trust_enable_agent. # Last change: allow rename a hostgroup
######################################################## ########################################################
# Following values are auto-generated from values above # Following values are auto-generated from values above

View File

@ -113,6 +113,7 @@ class hostgroup(LDAPObject):
'memberofindirect', 'membermanager', 'memberofindirect', 'membermanager',
] ]
uuid_attribute = 'ipauniqueid' uuid_attribute = 'ipauniqueid'
allow_rename = True
attribute_members = { attribute_members = {
'member': ['host', 'hostgroup'], 'member': ['host', 'hostgroup'],
'membermanager': ['user', 'group'], 'membermanager': ['user', 'group'],
@ -276,6 +277,16 @@ class hostgroup_mod(LDAPUpdate):
has_output_params = LDAPUpdate.has_output_params + hostgroup_output_params has_output_params = LDAPUpdate.has_output_params + hostgroup_output_params
msg_summary = _('Modified hostgroup "%(value)s"') 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): def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
assert isinstance(dn, DN) assert isinstance(dn, DN)
self.obj.suppress_netgroup_memberof(ldap, dn, entry_attrs) self.obj.suppress_netgroup_memberof(ldap, dn, entry_attrs)

View File

@ -29,6 +29,7 @@ from ipatests.test_xmlrpc.tracker.host_plugin import HostTracker
from ipalib import errors from ipalib import errors
import pytest import pytest
renamedhostgroup1 = u'renamedhostgroup1'
@pytest.fixture(scope='class') @pytest.fixture(scope='class')
def hostgroup(request, xmlrpc_setup): def hostgroup(request, xmlrpc_setup):
@ -54,6 +55,20 @@ def host(request, xmlrpc_setup):
return tracker.make_fixture(request) 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): class TestNonexistentHostGroup(XMLRPC_test):
def test_retrieve_nonexistent(self, hostgroup): def test_retrieve_nonexistent(self, hostgroup):
""" Try to retrieve non-existent hostgroup """ """ Try to retrieve non-existent hostgroup """
@ -105,6 +120,35 @@ class TestHostGroup(XMLRPC_test):
hostgroup.cn)): hostgroup.cn)):
command() 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): def test_create_host_add_to_hostgroup(self, hostgroup, host):
""" Check that host can be added to hostgroup """ """ Check that host can be added to hostgroup """
host.create() host.create()