summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2011-07-01 15:32:31 -0400
committerMartin Kosek <mkosek@redhat.com>2011-07-19 13:06:16 +0200
commit1dd9e1407361bdd6ed337c70dcb1d209ce034cb6 (patch)
tree1b81a20a3835de965f40f35195ea22fbbe731afc
parentc09f116f4331175b3fb01f0bd62e78ef47fab716 (diff)
downloadfreeipa-1dd9e1407361bdd6ed337c70dcb1d209ce034cb6.tar.gz
freeipa-1dd9e1407361bdd6ed337c70dcb1d209ce034cb6.tar.xz
freeipa-1dd9e1407361bdd6ed337c70dcb1d209ce034cb6.zip
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
-rw-r--r--ipalib/constants.py1
-rw-r--r--ipalib/plugins/baseldap.py53
-rw-r--r--ipalib/plugins/hostgroup.py8
-rw-r--r--ipalib/plugins/user.py5
-rw-r--r--tests/test_xmlrpc/objectclasses.py4
-rw-r--r--tests/test_xmlrpc/test_attr.py3
-rw-r--r--tests/test_xmlrpc/test_group_plugin.py5
-rw-r--r--tests/test_xmlrpc/test_hostgroup_plugin.py2
-rw-r--r--tests/test_xmlrpc/test_krbtpolicy.py3
-rw-r--r--tests/test_xmlrpc/test_nesting.py14
-rw-r--r--tests/test_xmlrpc/test_netgroup_plugin.py8
-rw-r--r--tests/test_xmlrpc/test_replace.py3
-rw-r--r--tests/test_xmlrpc/test_user_plugin.py14
13 files changed, 120 insertions, 3 deletions
diff --git a/ipalib/constants.py b/ipalib/constants.py
index 23e80257d..026e07354 100644
--- a/ipalib/constants.py
+++ b/ipalib/constants.py
@@ -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),
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 8d58422bd..1ff7a2a6d 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -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.
diff --git a/ipalib/plugins/hostgroup.py b/ipalib/plugins/hostgroup.py
index 11ed66376..ef44a8b9b 100644
--- a/ipalib/plugins/hostgroup.py
+++ b/ipalib/plugins/hostgroup.py
@@ -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)
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index e6060c0f3..3068c6291 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -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)
diff --git a/tests/test_xmlrpc/objectclasses.py b/tests/test_xmlrpc/objectclasses.py
index 41350f0bc..29cd6af51 100644
--- a/tests/test_xmlrpc/objectclasses.py
+++ b/tests/test_xmlrpc/objectclasses.py
@@ -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',
diff --git a/tests/test_xmlrpc/test_attr.py b/tests/test_xmlrpc/test_attr.py
index 9f1b1c51d..1ea6a880f 100644
--- a/tests/test_xmlrpc/test_attr.py
+++ b/tests/test_xmlrpc/test_attr.py
@@ -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,
),
),
diff --git a/tests/test_xmlrpc/test_group_plugin.py b/tests/test_xmlrpc/test_group_plugin.py
index 97349e895..d4f6cd480 100644
--- a/tests/test_xmlrpc/test_group_plugin.py
+++ b/tests/test_xmlrpc/test_group_plugin.py
@@ -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],
diff --git a/tests/test_xmlrpc/test_hostgroup_plugin.py b/tests/test_xmlrpc/test_hostgroup_plugin.py
index 99ca9226c..803b8a793 100644
--- a/tests/test_xmlrpc/test_hostgroup_plugin.py
+++ b/tests/test_xmlrpc/test_hostgroup_plugin.py
@@ -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)],
),
),
),
diff --git a/tests/test_xmlrpc/test_krbtpolicy.py b/tests/test_xmlrpc/test_krbtpolicy.py
index bbfadb3f6..4d2443e79 100644
--- a/tests/test_xmlrpc/test_krbtpolicy.py
+++ b/tests/test_xmlrpc/test_krbtpolicy.py
@@ -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)
),
),
diff --git a/tests/test_xmlrpc/test_nesting.py b/tests/test_xmlrpc/test_nesting.py
index 541862826..0d1c78596 100644
--- a/tests/test_xmlrpc/test_nesting.py
+++ b/tests/test_xmlrpc/test_nesting.py
@@ -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)],
),
),
),
diff --git a/tests/test_xmlrpc/test_netgroup_plugin.py b/tests/test_xmlrpc/test_netgroup_plugin.py
index 47256e486..fcb3b06ac 100644
--- a/tests/test_xmlrpc/test_netgroup_plugin.py
+++ b/tests/test_xmlrpc/test_netgroup_plugin.py
@@ -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),
),
),
diff --git a/tests/test_xmlrpc/test_replace.py b/tests/test_xmlrpc/test_replace.py
index 668177844..4209e7064 100644
--- a/tests/test_xmlrpc/test_replace.py
+++ b/tests/test_xmlrpc/test_replace.py
@@ -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,
),
),
diff --git a/tests/test_xmlrpc/test_user_plugin.py b/tests/test_xmlrpc/test_user_plugin.py
index 36e19defc..e0f2d7fce 100644
--- a/tests/test_xmlrpc/test_user_plugin.py
+++ b/tests/test_xmlrpc/test_user_plugin.py
@@ -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,
),
),