On 09/19/2013 03:29 PM, Ana Krivokapic wrote: > Hello, > > This patch set adds automember rebuild membership functionality to IPA CLI. > > Design: http://www.freeipa.org/page/V3/Automember_rebuild_membership > Ticket: https://fedorahosted.org/freeipa/ticket/3752 > > > > _______________________________________________ > Freeipa-devel mailing list > Freeipa-devel@redhat.com > https://www.redhat.com/mailman/listinfo/freeipa-devel
This updated patch set introduces only one automember-rebuild command, instead of three. The changes are covered in the design document: http://www.freeipa.org/page/V3/Automember_rebuild_membership#CLI. Also, while working on these patches, I hit this bug again: https://fedorahosted.org/freeipa/ticket/2708. Since the fix is pretty straightforward, and the bug is related to automember feature, I included a fix for it in this patch set (patch 0071). -- Regards, Ana Krivokapic Associate Software Engineer FreeIPA team Red Hat Inc.
From 9ceeec11494ddb11dc95d15e0a89597e3423ff38 Mon Sep 17 00:00:00 2001 From: Ana Krivokapic <akriv...@redhat.com> Date: Thu, 19 Sep 2013 14:01:58 +0200 Subject: [PATCH] Add automember rebuild command Add a new command to IPA CLI: ipa automember-rebuild The command integrates the automember rebuild membership task functionality into IPA CLI. It makes it possible to rebuild automember membership for groups/hostgroups. Design: http://www.freeipa.org/page/V3/Automember_rebuild_membership https://fedorahosted.org/freeipa/ticket/3752 --- API.txt | 9 +++ VERSION | 2 +- ipalib/plugins/automember.py | 129 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 129 insertions(+), 11 deletions(-) diff --git a/API.txt b/API.txt index 761d1d175b5ce48bb6e27ce60e404f89790bfe6b..bd51634c4f564d7043fb86398b7cabbe1af745bf 100644 --- a/API.txt +++ b/API.txt @@ -199,6 +199,15 @@ command: automember_mod output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None)) output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) output: Output('value', <type 'unicode'>, None) +command: automember_rebuild +args: 0,4,3 +option: Str('hosts', multivalue=True, required=False) +option: StrEnum('type', required=False, values=(u'group', u'hostgroup')) +option: Str('users', multivalue=True, required=False) +option: Str('version?', exclude='webui') +output: Output('result', <type 'bool'>, None) +output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) +output: Output('value', <type 'unicode'>, None) command: automember_remove_condition args: 1,8,5 arg: Str('cn', cli_name='automember_rule') diff --git a/VERSION b/VERSION index c3c6d5a4c28991839a1917f18d2804475a16bcb7..32f6efbc4d4768c77c514a3367cb9feb039205e5 100644 --- a/VERSION +++ b/VERSION @@ -89,4 +89,4 @@ IPA_DATA_VERSION=20100614120000 # # ######################################################## IPA_API_VERSION_MAJOR=2 -IPA_API_VERSION_MINOR=65 +IPA_API_VERSION_MINOR=66 diff --git a/ipalib/plugins/automember.py b/ipalib/plugins/automember.py index 4f563f11953dafac0d5bfd00f0309aca2f346f81..308f3cdcba5aae8af018aea2f77e09da7541e3e6 100644 --- a/ipalib/plugins/automember.py +++ b/ipalib/plugins/automember.py @@ -16,14 +16,13 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. - -from ipalib import api, errors -from ipalib import Str, StrEnum +import uuid +import ldap as _ldap +from ipalib import api, errors, Str, StrEnum, _, ngettext from ipalib.plugins.baseldap import * -from ipalib import _, ngettext from ipalib.request import context -import ldap as _ldap from ipapython.dn import DN +from ipapython.ipautil import realm_to_suffix __doc__ = _(""" Auto Membership Rule. @@ -184,14 +183,17 @@ class automember(LDAPObject): ), ) - def dn_exists(self, grouptype, groupname, *keys): + def dn_exists(self, otype, oname): ldap = self.api.Backend.ldap2 - dn = self.api.Object[grouptype].get_dn(groupname) + dn = self.api.Object[otype].get_dn(oname) try: - (gdn, entry_attrs) = ldap.get_entry(dn, []) + (odn, entry_attrs) = ldap.get_entry(dn, []) except errors.NotFound: - raise errors.NotFound(reason=_(u'Group: %s not found!') % groupname) - return gdn + raise errors.NotFound( + reason=_(u'%(otype)s: %(oname)s not found!') % + dict(otype=otype, oname=oname) + ) + return odn def get_dn(self, *keys, **options): if self.parent_object: @@ -587,3 +589,110 @@ def execute(self, *keys, **options): return result api.register(automember_default_group_show) + + +class automember_rebuild(LDAPQuery): + __doc__ = _('Rebuild auto membership for specified entries.') + # TODO: Add a --dry-run option: + # https://fedorahosted.org/freeipa/ticket/3936 + takes_options = ( + StrEnum( + 'type', + label=_('Grouping Type'), + doc=_('Grouping to which the rule applies'), + values=(u'group', u'hostgroup', ), + required=False, + ), + Str( + 'users', + label=_('Users'), + doc=_('Users for which the rebuild task will be run'), + required=False, + multivalue=True, + ), + Str( + 'hosts', + label=_('Hosts'), + doc=_('Hosts for which the rebuild task will be run'), + required=False, + multivalue=True, + ), + ) + has_output = output.standard_value + msg_summary = _('Automember rebuild membership task completed') + + def validate(self, **kw): + """ + Validation rules: + - at least one of 'type', 'users', 'hosts' is required + - 'users' and 'hosts' cannot be combined together + - if 'users' and 'type' are specified, 'type' must be 'group' + - if 'hosts' and 'type' are specified, 'type' must be 'hostgroup' + """ + super(automember_rebuild, self).validate(**kw) + users, hosts, gtype = kw.get('users'), kw.get('hosts'), kw.get('type') + + if not (gtype or users or hosts): + raise errors.ValidationError( + name='options', + error=_('At least one of options: type, users, hosts must be' + 'specified') + ) + + if users and hosts: + raise errors.ValidationError( + name='options', + error=_('Options users and hosts cannot be used together') + ) + + if gtype: + if users and gtype != 'group': + raise errors.ValidationError( + name='options', + error=_('Type must be "group" if option "users" is ' + 'specified') + ) + if hosts and gtype != 'hostgroup': + raise errors.ValidationError( + name='options', + error=_('Type must be "hostgroup" if option "hosts" is ' + 'specified') + ) + + def execute(self, *keys, **options): + ldap = self.obj.backend + cn = str(uuid.uuid4()) + basedn = realm_to_suffix(api.env.realm) + users = options.get('users', []) + hosts = options.get('hosts', []) + group_type = options.get('type') + + if users or hosts: + filters = [] + for u in users: + self.obj.dn_exists('user', u) + filters.append(ldap.make_filter_from_attr('uid', u)) + for h in hosts: + self.obj.dn_exists('host', h) + filters.append(ldap.make_filter_from_attr('fqdn', h)) + search_filter = ldap.combine_filters(filters, ldap.MATCH_ANY) + else: + search_filter = '(uid=*)' if group_type == 'group' else '(fqdn=*)' + + entry = ldap.make_entry( + DN( + ('cn', cn), + ('cn', 'automember rebuild membership'), + ('cn', 'tasks'), + ('cn', 'config'), + ), + objectclass=['top', 'extensibleObject'], + cn=[cn], + basedn=[basedn], + filter=[search_filter], + scope=['sub'] + ) + ldap.add_entry(entry) + return dict(result=True, value=u'') + +api.register(automember_rebuild) -- 1.8.3.1
From af969cd1541f066502c5202e8ad757b5a5dc84e8 Mon Sep 17 00:00:00 2001 From: Ana Krivokapic <akriv...@redhat.com> Date: Mon, 23 Sep 2013 13:56:14 +0200 Subject: [PATCH] Fix error message when adding duplicate automember rule Also fix object_name and object_name_plural for automember rules. https://fedorahosted.org/freeipa/ticket/2708 --- install/ui/test/data/ipa_init_objects.json | 4 ++-- ipalib/plugins/automember.py | 4 ++-- ipalib/plugins/baseldap.py | 5 +++-- ipatests/test_xmlrpc/test_automember_plugin.py | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/install/ui/test/data/ipa_init_objects.json b/install/ui/test/data/ipa_init_objects.json index bef3cc65d45a8473f7fed3b67124bbc892213ca5..c6a252b973775dd5210c67c105949616e586bd91 100644 --- a/install/ui/test/data/ipa_init_objects.json +++ b/install/ui/test/data/ipa_init_objects.json @@ -52,8 +52,8 @@ "automemberregexrule" ], "object_class_config": null, - "object_name": "auto_member_rule", - "object_name_plural": "auto_member_rules", + "object_name": "Automember rule", + "object_name_plural": "Automember rules", "parent_object": "", "rdn_attribute": "", "relationships": { diff --git a/ipalib/plugins/automember.py b/ipalib/plugins/automember.py index 9473dd4d11a88e96e4d02e0de6fddb9ffb7a42bd..4ae32f8688be179b266664f95e6b0951cfcf385e 100644 --- a/ipalib/plugins/automember.py +++ b/ipalib/plugins/automember.py @@ -159,8 +159,8 @@ class automember(LDAPObject): container_dn = api.env.container_automember - object_name = 'auto_member_rule' - object_name_plural = 'auto_member_rules' + object_name = 'Automember rule' + object_name_plural = 'Automember rules' object_class = ['top', 'automemberregexrule'] default_attributes = [ 'automemberinclusiveregex', 'automemberexclusiveregex', diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py index 4a79502708c358dd20ede017037b16f691b76766..f0d667dd444c548f704a914c3c5f41dc36895068 100644 --- a/ipalib/plugins/baseldap.py +++ b/ipalib/plugins/baseldap.py @@ -582,9 +582,10 @@ def handle_not_found(self, *keys): ) def handle_duplicate_entry(self, *keys): - pkey = '' - if self.primary_key: + try: pkey = keys[-1] + except KeyError: + pkey = '' raise errors.DuplicateEntry( message=self.already_exists_msg % { 'pkey': pkey, 'oname': self.object_name, diff --git a/ipatests/test_xmlrpc/test_automember_plugin.py b/ipatests/test_xmlrpc/test_automember_plugin.py index cb4d7e3f837af83786d52fe0c5ddf3f100e27083..9442420f48b39be76c14e31a7d20fe5c537b2734 100644 --- a/ipatests/test_xmlrpc/test_automember_plugin.py +++ b/ipatests/test_xmlrpc/test_automember_plugin.py @@ -96,7 +96,7 @@ class test_automember(Declarative): dict( desc='Try to delete non-existent group rule %r' % group1, command=('automember_del', [group1], dict(type=u'group')), - expected=errors.NotFound(reason=u': auto_member_rule not found'), + expected=errors.NotFound(reason=u': Automember rule not found'), ), @@ -118,7 +118,7 @@ class test_automember(Declarative): dict( desc='Try to delete non-existent hostgroup rule %r' % hostgroup1, command=('automember_del', [hostgroup1], dict(type=u'hostgroup')), - expected=errors.NotFound(reason=u': auto_member_rule not found'), + expected=errors.NotFound(reason=u': Automember rule not found'), ), # Automember rebuild membership tests -- 1.8.3.1
From 8893bc9ab1c5fe62b05956b4fad3bcb02e41d6cb Mon Sep 17 00:00:00 2001 From: Ana Krivokapic <akriv...@redhat.com> Date: Thu, 19 Sep 2013 14:10:32 +0200 Subject: [PATCH] Add permissions for automember rebuild command Design: http://www.freeipa.org/page/V3/Automember_rebuild_membership https://fedorahosted.org/freeipa/ticket/3752 --- install/updates/40-delegation.update | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/install/updates/40-delegation.update b/install/updates/40-delegation.update index 64a6432acc8605f3164d267d16609f51ce02a7ef..3a0e7f70e4bfda21bf1011c92562d565fb4d32cb 100644 --- a/install/updates/40-delegation.update +++ b/install/updates/40-delegation.update @@ -373,3 +373,29 @@ dn: cn=Retrieve Certificates from the CA,cn=permissions,cn=pbac,$SUFFIX dn: cn=Revoke Certificate,cn=permissions,cn=pbac,$SUFFIX add: member: 'cn=Host Administrators,cn=privileges,cn=pbac,$SUFFIX' + +# Automember tasks +dn: cn=Automember Task Administrator,cn=privileges,cn=pbac,$SUFFIX +default:objectClass: nestedgroup +default:objectClass: groupofnames +default:objectClass: top +default:cn: Automember Task Administrator +default:description: Automember Task Administrator + +dn: cn=Add Automember Rebuild Membership Task,cn=permissions,cn=pbac,$SUFFIX +default:objectClass: groupofnames +default:objectClass: ipapermission +default:objectClass: top +default:cn: Add Automember Rebuild Membership Task +default:member: cn=Automember Task Administrator,cn=privileges,cn=pbac,$SUFFIX + +dn: cn=Add Automember Export Updates Task,cn=permissions,cn=pbac,$SUFFIX +default:objectClass: groupofnames +default:objectClass: ipapermission +default:objectClass: top +default:cn: Add Automember Export Updates Task +default:member: cn=Automember Task Administrator,cn=privileges,cn=pbac,$SUFFIX + +dn: cn=config +add:aci: '(target = "ldap:///cn=automember rebuild membership,cn=tasks,cn=config")(targetattr=*)(version 3.0;acl "permission:Add Automember Rebuild Membership Task";allow (add) groupdn = "ldap:///cn=Add Automember Rebuild Membership Task,cn=permissions,cn=pbac,$SUFFIX";)' +add:aci: '(target = "ldap:///cn=automember export updates,cn=tasks,cn=config")(targetattr=*)(version 3.0;acl "permission:Add Automember Export Updates Task";allow (add) groupdn = "ldap:///cn=Add Automember Export Updates Task,cn=permissions,cn=pbac,$SUFFIX";)' -- 1.8.3.1
From f2a88f8d3e94aabec61a1371230dcb3d0ae352b6 Mon Sep 17 00:00:00 2001 From: Ana Krivokapic <akriv...@redhat.com> Date: Thu, 19 Sep 2013 14:12:44 +0200 Subject: [PATCH] Add unit tests for automember rebuild command Design: http://www.freeipa.org/page/V3/Automember_rebuild_membership https://fedorahosted.org/freeipa/ticket/3752 --- ipatests/test_xmlrpc/test_automember_plugin.py | 616 ++++++++++++++++++++++++- 1 file changed, 603 insertions(+), 13 deletions(-) diff --git a/ipatests/test_xmlrpc/test_automember_plugin.py b/ipatests/test_xmlrpc/test_automember_plugin.py index 2c38b6463bfc684dbe23904f54b7107bb4ce3ff2..cb4d7e3f837af83786d52fe0c5ddf3f100e27083 100644 --- a/ipatests/test_xmlrpc/test_automember_plugin.py +++ b/ipatests/test_xmlrpc/test_automember_plugin.py @@ -27,8 +27,8 @@ from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid, add_sid, add_oc -user1=u'tuser1' -manager1=u'mscott' +user1 = u'tuser1' +manager1 = u'mscott' fqdn1 = u'web1.%s' % api.env.domain short1 = u'web1' fqdn2 = u'dev1.%s' % api.env.domain @@ -40,13 +40,17 @@ fqdn5 = u'webserver5.%s' % api.env.domain short5 = u'webserver5' -group1=u'group1' -defaultgroup1=u'defaultgroup1' -hostgroup1=u'hostgroup1' -hostgroup2=u'hostgroup2' -hostgroup3=u'hostgroup3' -hostgroup4=u'hostgroup4' -defaulthostgroup1=u'defaulthostgroup1' +group1 = u'group1' +group1_dn = DN(('cn', group1), ('cn', 'groups'), + ('cn', 'accounts'), api.env.basedn) +defaultgroup1 = u'defaultgroup1' +hostgroup1 = u'hostgroup1' +hostgroup1_dn = DN(('cn', hostgroup1), ('cn', 'hostgroups'), + ('cn', 'accounts'), api.env.basedn) +hostgroup2 = u'hostgroup2' +hostgroup3 = u'hostgroup3' +hostgroup4 = u'hostgroup4' +defaulthostgroup1 = u'defaulthostgroup1' group_include_regex = u'mscott' hostgroup_include_regex = u'^web[1-9]' @@ -80,13 +84,13 @@ class test_automember(Declarative): desc='Try to retrieve non-existent group rule %r' % group1, command=('automember_add', [group1], dict(description=u'Test desc', type=u'group')), - expected=errors.NotFound(reason=u'Group: %s not found!' % group1), + expected=errors.NotFound(reason=u'group: %s not found!' % group1), ), dict( desc='Try to update non-existent group rule %r' % group1, command=('automember_add', [group1], dict(type=u'group')), - expected=errors.NotFound(reason=u'Group: %s not found!' % group1), + expected=errors.NotFound(reason=u'group: %s not found!' % group1), ), dict( @@ -101,14 +105,14 @@ class test_automember(Declarative): command=('automember_add', [hostgroup1], dict(description=u'Test desc', type=u'hostgroup')), expected=errors.NotFound( - reason=u'Group: %s not found!' % hostgroup1), + reason=u'hostgroup: %s not found!' % hostgroup1), ), dict( desc='Try to update non-existent hostgroup rule %r' % hostgroup1, command=('automember_add', [hostgroup1], dict(type=u'hostgroup')), expected=errors.NotFound( - reason=u'Group: %s not found!' % hostgroup1), + reason=u'hostgroup: %s not found!' % hostgroup1), ), dict( @@ -117,7 +121,593 @@ class test_automember(Declarative): expected=errors.NotFound(reason=u': auto_member_rule not found'), ), + # Automember rebuild membership tests + dict( + desc='Create hostgroup: %r' % hostgroup1, + command=( + 'hostgroup_add', [hostgroup1], dict(description=u'Test desc') + ), + expected=dict( + value=hostgroup1, + summary=u'Added hostgroup "%s"' % hostgroup1, + result=dict( + cn=[hostgroup1], + description=[u'Test desc'], + objectclass=objectclasses.hostgroup, + ipauniqueid=[fuzzy_uuid], + mepmanagedentry=[DN(('cn', hostgroup1), ('cn', 'ng'), + ('cn', 'alt'), api.env.basedn)], + dn=hostgroup1_dn + ), + ), + ), + dict( + desc='Create host: %r' % fqdn1, + command=( + 'host_add', + [fqdn1], + dict( + description=u'Test host 1', + l=u'Undisclosed location 1', + force=True, + ), + ), + expected=dict( + value=fqdn1, + summary=u'Added host "%s"' % fqdn1, + result=dict( + dn=DN(('fqdn', fqdn1), ('cn', 'computers'), + ('cn', 'accounts'), api.env.basedn), + fqdn=[fqdn1], + description=[u'Test host 1'], + l=[u'Undisclosed location 1'], + krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], + has_keytab=False, + has_password=False, + objectclass=objectclasses.host, + ipauniqueid=[fuzzy_uuid], + managedby_host=[fqdn1], + ), + ), + ), + + dict( + desc='Create automember rule: %r' % hostgroup1, + command=( + 'automember_add', [hostgroup1], dict( + description=u'Test desc', type=u'hostgroup', + ) + ), + expected=dict( + value=hostgroup1, + summary=u'Added automember rule "%s"' % hostgroup1, + result=dict( + cn=[hostgroup1], + description=[u'Test desc'], + automembertargetgroup=[hostgroup1_dn], + objectclass=objectclasses.automember, + dn=DN(('cn', hostgroup1), ('cn', 'hostgroup'), + ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), + ), + ), + ), + + dict( + desc='Create automember condition: %r' % hostgroup1, + command=( + 'automember_add_condition', [hostgroup1], dict( + key=u'fqdn', type=u'hostgroup', + automemberinclusiveregex=[hostgroup_include_regex], + ) + ), + expected=dict( + value=hostgroup1, + summary=u'Added condition(s) to "%s"' % hostgroup1, + completed=1, + failed=dict( + failed=dict( + automemberinclusiveregex=tuple(), + automemberexclusiveregex=tuple(), + ) + ), + result=dict( + cn=[hostgroup1], + description=[u'Test desc'], + automemberinclusiveregex=[ + u'fqdn=%s' % hostgroup_include_regex + ], + automembertargetgroup=[hostgroup1_dn], + ), + ), + ), + + dict( + desc='Retrieve hostgroup: %r' % hostgroup1, + command=('hostgroup_show', [hostgroup1], dict()), + expected=dict( + value=hostgroup1, + summary=None, + result=dict( + dn=hostgroup1_dn, + cn=[hostgroup1], + description=[u'Test desc'], + ), + ), + ), + + dict( + desc='Rebuild membership for hostgroups', + command=('automember_rebuild', [], dict(type=u'hostgroup')), + expected=dict( + value=u'', + summary=u'Automember rebuild membership task completed', + result=True + ), + ), + + dict( + desc='Retrieve hostgroup: %r' % hostgroup1, + command=('hostgroup_show', [hostgroup1], dict()), + expected=dict( + value=hostgroup1, + summary=None, + result=dict( + dn=hostgroup1_dn, + member_host=[u'%s' % fqdn1], + cn=[hostgroup1], + description=[u'Test desc'], + ), + ), + ), + + dict( + desc='Remove host %r from hostgroup %r' % (fqdn1, hostgroup1), + command=( + 'hostgroup_remove_member', + [hostgroup1], + dict(host=fqdn1) + ), + expected=dict( + failed=dict( + member=dict( + host=tuple(), + hostgroup=tuple(), + ), + ), + completed=1, + result=dict( + dn=hostgroup1_dn, + cn=[hostgroup1], + description=[u'Test desc'], + ), + ), + ), + + dict( + desc='Retrieve hostgroup: %r' % hostgroup1, + command=('hostgroup_show', [hostgroup1], dict()), + expected=dict( + value=hostgroup1, + summary=None, + result=dict( + dn=hostgroup1_dn, + cn=[hostgroup1], + description=[u'Test desc'], + ), + ), + ), + + dict( + desc='Try to rebuild membership (no options)', + command=('automember_rebuild', [], dict()), + expected=errors.ValidationError( + name='options', + error=(u'At least one of options: type, users, hosts must be' + 'specified') + ) + ), + + dict( + desc='Try to rebuild membership (--users and --hosts together)', + command=( + 'automember_rebuild', + [], + dict(users=user1, hosts=fqdn1) + ), + expected=errors.ValidationError( + name='options', + error=(u'Options users and hosts cannot be used together') + ) + ), + + dict( + desc='Try to rebuild membership (--users and --type=hostgroup)', + command=( + 'automember_rebuild', + [], + dict(users=user1, type=u'hostgroup') + ), + expected=errors.ValidationError( + name='options', + error=('Type must be "group" if option "users" is ' + 'specified') + ) + ), + + dict( + desc='Try to rebuild membership (--hosts and --type=group)', + command=( + 'automember_rebuild', + [], + dict(hosts=fqdn1, type=u'group') + ), + expected=errors.ValidationError( + name='options', + error=('Type must be "hostgroup" if option "hosts" is ' + 'specified') + ) + ), + + dict( + desc='Rebuild membership for host: %s' % fqdn1, + command=('automember_rebuild', [], dict(hosts=fqdn1)), + expected=dict( + value=u'', + summary=u'Automember rebuild membership task completed', + result=True + ), + ), + + dict( + desc='Retrieve hostgroup: %r' % hostgroup1, + command=('hostgroup_show', [hostgroup1], dict()), + expected=dict( + value=hostgroup1, + summary=None, + result=dict( + dn=hostgroup1_dn, + member_host=[u'%s' % fqdn1], + cn=[hostgroup1], + description=[u'Test desc'], + ), + ), + ), + + dict( + desc='Delete host: %r' % fqdn1, + command=('host_del', [fqdn1], dict()), + expected=dict( + value=fqdn1, + summary=u'Deleted host "%s"' % fqdn1, + result=dict(failed=u''), + ), + ), + + dict( + desc='Delete hostgroup: %r' % hostgroup1, + command=('hostgroup_del', [hostgroup1], dict()), + expected=dict( + value=hostgroup1, + summary=u'Deleted hostgroup "%s"' % hostgroup1, + result=dict(failed=u''), + ), + ), + + dict( + desc='Delete automember rule: %r' % hostgroup1, + command=('automember_del', [hostgroup1], dict(type=u'hostgroup')), + expected=dict( + value=hostgroup1, + summary=u'Deleted automember rule "%s"' % hostgroup1, + result=dict(failed=u''), + ), + ), + + dict( + desc='Create group: %r' % group1, + command=( + 'group_add', [group1], dict(description=u'Test desc') + ), + expected=dict( + value=group1, + summary=u'Added group "%s"' % group1, + result=dict( + cn=[group1], + description=[u'Test desc'], + objectclass=objectclasses.group + [u'posixgroup'], + ipauniqueid=[fuzzy_uuid], + gidnumber=[fuzzy_digits], + dn=group1_dn + ), + ), + ), + + dict( + desc='Create user: %r' % manager1, + command=( + 'user_add', [manager1], dict(givenname=u'Michael', sn=u'Scott') + ), + expected=dict( + value=manager1, + summary=u'Added user "mscott"', + result=add_sid(dict( + gecos=[u'Michael Scott'], + givenname=[u'Michael'], + homedirectory=[u'/home/mscott'], + krbprincipalname=[u'mscott@' + api.env.realm], + has_keytab=False, + has_password=False, + loginshell=[u'/bin/sh'], + objectclass=add_oc(objectclasses.user, u'ipantuserattrs'), + sn=[u'Scott'], + uid=[manager1], + uidnumber=[fuzzy_digits], + gidnumber=[fuzzy_digits], + mail=[u'%s@%s' % (manager1, api.env.domain)], + displayname=[u'Michael Scott'], + cn=[u'Michael Scott'], + initials=[u'MS'], + ipauniqueid=[fuzzy_uuid], + krbpwdpolicyreference=[ + DN(('cn', 'global_policy'), ('cn', api.env.realm), + ('cn', 'kerberos'), api.env.basedn) + ], + mepmanagedentry=[ + DN(('cn', manager1), ('cn', 'groups'), + ('cn', 'accounts'), api.env.basedn) + ], + memberof_group=[u'ipausers'], + dn=DN(('uid', 'mscott'), ('cn', 'users'), + ('cn', 'accounts'), api.env.basedn), + )), + ), + ), + + dict( + desc='Create user: %r' % user1, + command=( + 'user_add', + [user1], + dict(givenname=u'Test', sn=u'User1', manager=manager1) + ), + expected=dict( + value=user1, + summary=u'Added user "tuser1"', + result=add_sid(dict( + gecos=[u'Test User1'], + givenname=[u'Test'], + homedirectory=[u'/home/tuser1'], + krbprincipalname=[u'tuser1@' + api.env.realm], + has_keytab=False, + has_password=False, + loginshell=[u'/bin/sh'], + objectclass=add_oc(objectclasses.user, u'ipantuserattrs'), + sn=[u'User1'], + uid=[user1], + uidnumber=[fuzzy_digits], + gidnumber=[fuzzy_digits], + mail=[u'%s@%s' % (user1, api.env.domain)], + manager=[ + DN(('uid', 'mscott'), ('cn', 'users'), + ('cn', 'accounts'), api.env.basedn) + ], + displayname=[u'Test User1'], + cn=[u'Test User1'], + initials=[u'TU'], + ipauniqueid=[fuzzy_uuid], + krbpwdpolicyreference=[ + DN(('cn', 'global_policy'), ('cn', api.env.realm), + ('cn', 'kerberos'), api.env.basedn)], + mepmanagedentry=[ + DN(('cn', user1), ('cn', 'groups'), + ('cn', 'accounts'), api.env.basedn) + ], + memberof_group=[u'ipausers'], + dn=DN(('uid', 'tuser1'), ('cn', 'users'), + ('cn', 'accounts'), api.env.basedn), + )), + ), + ), + + + dict( + desc='Create automember rule: %r' % group1, + command=( + 'automember_add', [group1], dict( + description=u'Test desc', type=u'group', + ) + ), + expected=dict( + value=group1, + summary=u'Added automember rule "%s"' % group1, + result=dict( + cn=[group1], + description=[u'Test desc'], + automembertargetgroup=[group1_dn], + objectclass=objectclasses.automember, + dn=DN(('cn', group1), ('cn', 'group'), + ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), + ), + ), + ), + + dict( + desc='Create automember condition: %r' % group1, + command=( + 'automember_add_condition', [group1], dict( + key=u'manager', type=u'group', + automemberinclusiveregex=[group_include_regex], + ) + ), + expected=dict( + value=group1, + summary=u'Added condition(s) to "%s"' % group1, + completed=1, + failed=dict( + failed=dict( + automemberinclusiveregex=tuple(), + automemberexclusiveregex=tuple(), + ) + ), + result=dict( + cn=[group1], + description=[u'Test desc'], + automemberinclusiveregex=[ + u'manager=%s' % group_include_regex + ], + automembertargetgroup=[group1_dn], + ), + ), + ), + + dict( + desc='Retrieve group: %r' % group1, + command=('group_show', [group1], dict()), + expected=dict( + value=group1, + summary=None, + result=dict( + dn=group1_dn, + cn=[group1], + description=[u'Test desc'], + gidnumber=[fuzzy_digits], + ), + ), + ), + + dict( + desc='Rebuild membership for groups', + command=('automember_rebuild', [], dict(type=u'group')), + expected=dict( + value=u'', + summary=u'Automember rebuild membership task completed', + result=True + ), + ), + + dict( + desc='Retrieve group: %r' % group1, + command=('group_show', [group1], dict()), + expected=dict( + value=group1, + summary=None, + result=dict( + dn=group1_dn, + member_user=[u'%s' % user1], + cn=[group1], + description=[u'Test desc'], + gidnumber=[fuzzy_digits], + ), + ), + ), + + dict( + desc='Remove user %r from group %r' % (fqdn1, hostgroup1), + command=( + 'group_remove_member', + [group1], + dict(user=user1) + ), + expected=dict( + failed=dict( + member=dict( + user=tuple(), + group=tuple(), + ), + ), + completed=1, + result=dict( + dn=group1_dn, + cn=[group1], + description=[u'Test desc'], + gidnumber=[fuzzy_digits], + ), + ), + ), + + dict( + desc='Retrieve group: %r' % group1, + command=('group_show', [group1], dict()), + expected=dict( + value=group1, + summary=None, + result=dict( + dn=group1_dn, + cn=[group1], + description=[u'Test desc'], + gidnumber=[fuzzy_digits], + ), + ), + ), + + dict( + desc='Rebuild membership for user: %s' % user1, + command=('automember_rebuild', [], dict(users=user1)), + expected=dict( + value=u'', + summary=u'Automember rebuild membership task completed', + result=True + ), + ), + + dict( + desc='Retrieve group: %r' % group1, + command=('group_show', [group1], dict()), + expected=dict( + value=group1, + summary=None, + result=dict( + dn=group1_dn, + member_user=[u'%s' % user1], + cn=[group1], + description=[u'Test desc'], + gidnumber=[fuzzy_digits], + ), + ), + ), + + dict( + desc='Delete user: %r' % user1, + command=('user_del', [user1], dict()), + expected=dict( + value=user1, + summary=u'Deleted user "%s"' % user1, + result=dict(failed=u''), + ), + ), + + dict( + desc='Delete user: %r' % manager1, + command=('user_del', [manager1], dict()), + expected=dict( + value=manager1, + summary=u'Deleted user "%s"' % manager1, + result=dict(failed=u''), + ), + ), + + dict( + desc='Delete group: %r' % group1, + command=('group_del', [group1], dict()), + expected=dict( + value=group1, + summary=u'Deleted group "%s"' % group1, + result=dict(failed=u''), + ), + ), + + dict( + desc='Delete automember rule: %r' % group1, + command=('automember_del', [group1], dict(type=u'group')), + expected=dict( + value=group1, + summary=u'Deleted automember rule "%s"' % group1, + result=dict(failed=u''), + ), + ), + + # End of automember rebuild membership tests dict( desc='Create %r' % group1, -- 1.8.3.1
_______________________________________________ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel