mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Optionally wait for 389-ds postop plugins to complete
Add a new command that lets you wait for an attribute to appear in a value. Using this you can do things like wait for a managed entry to be created, adding a new objectclass to the parent entry. This is controlled by a new booleon option, wait_for_attr, defaulting to False. https://fedorahosted.org/freeipa/ticket/1144
This commit is contained in:
parent
c09f116f43
commit
1dd9e14073
@ -148,6 +148,7 @@ DEFAULT_CONFIG = (
|
||||
# Enable certain optional plugins:
|
||||
('enable_ra', False),
|
||||
('ra_plugin', 'selfsign'),
|
||||
('wait_for_attr', False),
|
||||
|
||||
# Used when verifying that the API hasn't changed. Not for production.
|
||||
('validate_api', False),
|
||||
|
@ -194,6 +194,25 @@ def get_effective_rights(ldap, dn, attrs=None):
|
||||
|
||||
return rdict
|
||||
|
||||
def entry_from_entry(entry, newentry):
|
||||
"""
|
||||
Python is more or less pass-by-value except for immutable objects. So if
|
||||
you pass in a dict to a function you are free to change members of that
|
||||
dict but you can't create a new dict in the function and expect to replace
|
||||
what was passed in.
|
||||
|
||||
In some post-op plugins that is exactly what we want to do, so here is a
|
||||
clumsy way around the problem.
|
||||
"""
|
||||
|
||||
# Wipe out the current data
|
||||
for e in entry.keys():
|
||||
del entry[e]
|
||||
|
||||
# Re-populate it with new wentry
|
||||
for e in newentry:
|
||||
entry[e] = newentry[e]
|
||||
|
||||
def wait_for_memberof(keys, entry_start, completed, show_command, adding=True):
|
||||
"""
|
||||
When adding or removing reverse members we are faking an update to
|
||||
@ -238,6 +257,40 @@ def wait_for_memberof(keys, entry_start, completed, show_command, adding=True):
|
||||
|
||||
return entry_attrs
|
||||
|
||||
def wait_for_value(ldap, dn, attr, value):
|
||||
"""
|
||||
389-ds postoperation plugins are executed after the data has been
|
||||
returned to a client. This means that plugins that add data in a
|
||||
postop are not included in data returned to the user.
|
||||
|
||||
The downside of waiting is that this increases the time of the
|
||||
command.
|
||||
|
||||
The updated entry is returned.
|
||||
"""
|
||||
# Loop a few times to give the postop-plugin a chance to complete
|
||||
# Don't sleep for more than 6 seconds.
|
||||
x = 0
|
||||
while x < 20:
|
||||
# sleep first because the first search, even on a quiet system,
|
||||
# almost always fails.
|
||||
time.sleep(.3)
|
||||
x = x + 1
|
||||
|
||||
# FIXME: put a try/except around here? I think it is probably better
|
||||
# to just let the exception filter up to the caller.
|
||||
(dn, entry_attrs) = ldap.get_entry( dn, ['*'])
|
||||
if attr in entry_attrs:
|
||||
if isinstance(entry_attrs[attr], (list, tuple)):
|
||||
values = map(lambda y:y.lower(), entry_attrs[attr])
|
||||
if value.lower() in values:
|
||||
break
|
||||
else:
|
||||
if value.lower() == entry_attrs[attr].lower():
|
||||
break
|
||||
|
||||
return entry_attrs
|
||||
|
||||
class LDAPObject(Object):
|
||||
"""
|
||||
Object representing a LDAP entry.
|
||||
|
@ -98,6 +98,14 @@ class hostgroup_add(LDAPCreate):
|
||||
|
||||
msg_summary = _('Added hostgroup "%(value)s"')
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
if self.api.env.wait_for_attr:
|
||||
newentry = wait_for_value(ldap, dn, 'objectclass', 'mepOriginEntry')
|
||||
entry_from_entry(entry_attrs, newentry)
|
||||
|
||||
return dn
|
||||
|
||||
|
||||
api.register(hostgroup_add)
|
||||
|
||||
|
||||
|
@ -402,6 +402,11 @@ class user_add(LDAPCreate):
|
||||
self.api.Command['user_mod'](keys[-1], **kw)
|
||||
except (errors.EmptyModlist, errors.NotFound):
|
||||
pass
|
||||
else:
|
||||
if self.api.env.wait_for_attr:
|
||||
newentry = wait_for_value(ldap, dn, 'objectclass', 'mepOriginEntry')
|
||||
entry_from_entry(entry_attrs, newentry)
|
||||
|
||||
return dn
|
||||
|
||||
api.register(user_add)
|
||||
|
@ -21,7 +21,7 @@
|
||||
Defines the expected objectclass for various entries.
|
||||
"""
|
||||
|
||||
user = [
|
||||
user_base = [
|
||||
u'top',
|
||||
u'person',
|
||||
u'organizationalperson',
|
||||
@ -33,6 +33,8 @@ user = [
|
||||
u'ipaobject',
|
||||
]
|
||||
|
||||
user = user_base + [u'mepOriginEntry']
|
||||
|
||||
group = [
|
||||
u'top',
|
||||
u'groupofnames',
|
||||
|
@ -61,6 +61,9 @@ class test_attr(Declarative):
|
||||
cn=[u'Test User1'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=tuser1,cn=users,cn=accounts,' + api.env.basedn,
|
||||
),
|
||||
),
|
||||
|
@ -590,6 +590,9 @@ class test_group(Declarative):
|
||||
cn=[u'Test User1'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=%s,cn=users,cn=accounts,%s' % (user1, api.env.basedn),
|
||||
),
|
||||
),
|
||||
@ -691,7 +694,7 @@ class test_group(Declarative):
|
||||
homedirectory=[u'/home/tuser1'],
|
||||
krbprincipalname=[u'tuser1@' + api.env.realm],
|
||||
loginshell=[u'/bin/sh'],
|
||||
objectclass=objectclasses.user,
|
||||
objectclass=objectclasses.user_base,
|
||||
sn=[u'User1'],
|
||||
uid=[user1],
|
||||
uidnumber=[fuzzy_digits],
|
||||
|
@ -23,6 +23,7 @@ Test the `ipalib.plugins.hostgroup` module.
|
||||
"""
|
||||
|
||||
from ipalib import api, errors
|
||||
from ipalib.dn import DN
|
||||
from tests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_uuid
|
||||
from tests.test_xmlrpc import objectclasses
|
||||
|
||||
@ -79,6 +80,7 @@ class test_hostgroup(Declarative):
|
||||
objectclass=objectclasses.hostgroup,
|
||||
description=[u'Test hostgroup 1'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
mepmanagedentry=['cn=%s,cn=ng,cn=alt,%s' % (hostgroup1, api.env.basedn)],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -106,6 +106,9 @@ class test_krbtpolicy(Declarative):
|
||||
cn=[u'Test User1'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=%s,cn=users,cn=accounts,%s' % (user1, api.env.basedn)
|
||||
),
|
||||
),
|
||||
|
@ -167,6 +167,9 @@ class test_nesting(Declarative):
|
||||
cn=[u'Test User1'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=%s,cn=users,cn=accounts,%s' % (user1, api.env.basedn)
|
||||
),
|
||||
),
|
||||
@ -196,6 +199,9 @@ class test_nesting(Declarative):
|
||||
cn=[u'Test User2'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user2, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=%s,cn=users,cn=accounts,%s' % (user2, api.env.basedn)
|
||||
),
|
||||
),
|
||||
@ -225,6 +231,9 @@ class test_nesting(Declarative):
|
||||
cn=[u'Test User3'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user3, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=%s,cn=users,cn=accounts,%s' % (user3, api.env.basedn)
|
||||
),
|
||||
),
|
||||
@ -254,6 +263,9 @@ class test_nesting(Declarative):
|
||||
cn=[u'Test User4'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user4, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=%s,cn=users,cn=accounts,%s' % (user4, api.env.basedn)
|
||||
),
|
||||
),
|
||||
@ -623,6 +635,7 @@ class test_nesting(Declarative):
|
||||
objectclass=objectclasses.hostgroup,
|
||||
description=[u'Test hostgroup 1'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
mepmanagedentry=[u'cn=%s,cn=ng,cn=alt,%s' % (hostgroup1, api.env.basedn)],
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -642,6 +655,7 @@ class test_nesting(Declarative):
|
||||
objectclass=objectclasses.hostgroup,
|
||||
description=[u'Test hostgroup 2'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
mepmanagedentry=[u'cn=%s,cn=ng,cn=alt,%s' % (hostgroup2, api.env.basedn)],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -183,6 +183,8 @@ class test_netgroup(Declarative):
|
||||
cn=[hostgroup1],
|
||||
objectclass=objectclasses.hostgroup,
|
||||
description=[u'Test hostgroup 1'],
|
||||
mepmanagedentry=['cn=%s,cn=ng,cn=alt,%s' % (hostgroup1, api
|
||||
.env.basedn)],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
),
|
||||
),
|
||||
@ -212,6 +214,9 @@ class test_netgroup(Declarative):
|
||||
cn=[u'Test User1'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=%s,cn=users,cn=accounts,%s' % (user1, api.env.basedn),
|
||||
),
|
||||
),
|
||||
@ -240,6 +245,9 @@ class test_netgroup(Declarative):
|
||||
cn=[u'Test User2'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user2, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=%s,cn=users,cn=accounts,%s' % (user2, api.env.basedn),
|
||||
),
|
||||
),
|
||||
|
@ -67,6 +67,9 @@ class test_replace(Declarative):
|
||||
initials=[u'TU'],
|
||||
mail=[u'test1@example.com', u'test2@example.com'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=tuser1,cn=users,cn=accounts,' + api.env.basedn,
|
||||
),
|
||||
),
|
||||
|
@ -98,6 +98,9 @@ class test_user(Declarative):
|
||||
cn=[u'Test User1'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=tuser1,cn=users,cn=accounts,' + api.env.basedn,
|
||||
),
|
||||
),
|
||||
@ -153,7 +156,7 @@ class test_user(Declarative):
|
||||
'krbprincipalname': [u'tuser1@' + api.env.realm],
|
||||
'loginshell': [u'/bin/sh'],
|
||||
'memberof_group': [u'ipausers'],
|
||||
'objectclass': objectclasses.user + [u'mepOriginEntry'],
|
||||
'objectclass': objectclasses.user,
|
||||
'sn': [u'User1'],
|
||||
'uid': [user1],
|
||||
'uidnumber': [fuzzy_digits],
|
||||
@ -442,6 +445,9 @@ class test_user(Declarative):
|
||||
cn=[u'Test User1'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=tuser1,cn=users,cn=accounts,' + api.env.basedn,
|
||||
),
|
||||
),
|
||||
@ -471,6 +477,9 @@ class test_user(Declarative):
|
||||
cn=[u'Test User2'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user2, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=tuser2,cn=users,cn=accounts,' + api.env.basedn,
|
||||
),
|
||||
),
|
||||
@ -602,6 +611,9 @@ class test_user(Declarative):
|
||||
postalcode=[u'01234-5678'],
|
||||
telephonenumber=[u'410-555-1212'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=u'uid=tuser1,cn=users,cn=accounts,' + api.env.basedn,
|
||||
),
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user