[python-ldap] LDAP Sync (RFC 4533) support
Chris Mikkelson
cmikk at qwest.net
Wed Aug 3 17:24:52 CEST 2011
On Tue, Aug 02, 2011 at 09:24:04AM -0500, Chris Mikkelson wrote:
> OK. I've made the following API changes to my local copy. The
> methods are now:
>
> syncrepl_present(self, uuids, refreshDeletes=False)
> syncrepl_delete(self, uuids)
>
> and the uuids parameters are either a list of uuid strings
> or None. I'll test my changes while writing a demo script,
> and send out the patch along with the demo script.
One more API change:
* syncrepl_search() now returns a msgid which can
be passed to syncrepl_poll(msgid=...). This makes
it possible to interleave ldapsync and non-ldapsync
operations on the same connection.
Patch attached.
Demo script also attached. It "mirrors" the DNs of entries
matching a search into a dbm, and prints out its updates.
--
Chris Mikkelson | For example, I could be a sentient PERL script. That
cmikk at qwest.net | pretty much assumes that someone brilliant enough to
| write me was also stupid enough to program in PERL.
| Not a likely explanation. -- Terry Lambert
-------------- next part --------------
diff --git a/Lib/ldap/syncrepl.py b/Lib/ldap/syncrepl.py
index cc92c7d..6c3960d 100644
--- a/Lib/ldap/syncrepl.py
+++ b/Lib/ldap/syncrepl.py
@@ -264,15 +264,15 @@ class SyncInfoMessage:
if attr.startswith('refresh'):
val['refreshDone'] = bool(comp.getComponentByName('refreshDone'))
elif attr == 'syncIdSet':
- uuids = set()
+ uuids = []
ids = comp.getComponentByName('syncUUIDs')
for i in range(len(ids)):
uuid = UUID(bytes=str(ids.getComponentByPosition(i)))
- uuids |= { str(uuid) }
+ uuids.append(str(uuid))
val['syncUUIDs'] = uuids
val['refreshDeletes'] = bool(comp.getComponentByName('refreshDeletes'))
- self.__dict__[attr] = val
+ setattr(self,attr,val)
return
@@ -312,11 +312,11 @@ class LDAPSyncObject(ldap.ldapobject.LDAPObject):
else:
search_args['serverctrls'] = [syncreq]
- self.__msgid = self.search_ext(base, scope, **search_args)
self.__refreshDone = False
+ return self.search_ext(base, scope, **search_args)
- def syncrepl_poll(self, timeout=None, all=0):
+ def syncrepl_poll(self, msgid=-1, timeout=None, all=0):
"""
polls for and processes responses to the syncrepl_search() operation.
Returns False when operation finishes, True if it is in progress, or
@@ -330,7 +330,7 @@ class LDAPSyncObject(ldap.ldapobject.LDAPObject):
"""
while True:
type, msg, mid, ctrls, n, v = self.result4(
- msgid=self.__msgid, timeout=timeout,
+ msgid=msgid, timeout=timeout,
add_intermediates=1, add_ctrls=1, all = 0
)
@@ -341,7 +341,7 @@ class LDAPSyncObject(ldap.ldapobject.LDAPObject):
for c in ctrls:
if c.__class__.__name__ != 'SyncDoneControl':
continue
- self.syncrepl_present(refreshDeletes=c.refreshDeletes)
+ self.syncrepl_present(None,refreshDeletes=c.refreshDeletes)
if c.cookie is not None:
self.syncrepl_set_cookie(c.cookie)
@@ -355,13 +355,13 @@ class LDAPSyncObject(ldap.ldapobject.LDAPObject):
if c.__class__.__name__ != 'SyncStateControl':
continue
if c.state == 'present':
- self.syncrepl_present(uuids={c.entryUUID})
+ self.syncrepl_present([c.entryUUID])
elif c.state == 'delete':
- self.syncrepl_delete(uuids={c.entryUUID})
+ self.syncrepl_delete([c.entryUUID])
else:
self.syncrepl_entry(dn, attrs, c.entryUUID)
if self.__refreshDone is False:
- self.syncrepl_present(uuids={c.entryUUID})
+ self.syncrepl_present([c.entryUUID])
if c.cookie is not None:
self.syncrepl_set_cookie(c.cookie)
break
@@ -376,20 +376,20 @@ class LDAPSyncObject(ldap.ldapobject.LDAPObject):
if sim.newcookie is not None:
self.syncrepl_set_cookie(sim.newcookie)
elif sim.refreshPresent is not None:
- self.syncrepl_present(refreshDeletes=False)
+ self.syncrepl_present(None, refreshDeletes=False)
if 'cookie' in sim.refreshPresent:
self.syncrepl_set_cookie(sim.refreshPresent['cookie'])
self.__refreshDone=sim.refreshPresent['refreshDone']
elif sim.refreshDelete is not None:
- self.syncrepl_present(refreshDeletes=True)
+ self.syncrepl_present(None, refreshDeletes=True)
if 'cookie' in sim.refreshDelete:
self.syncrepl_set_cookie(sim.refreshDelete['cookie'])
self.__refreshDone=sim.refreshDelete['refreshDone']
elif sim.syncIdSet is not None:
if sim.syncIdSet['refreshDeletes'] is True:
- self.syncrepl_delete(uuids=sim.syncIdSet['syncUUIDs'])
+ self.syncrepl_delete(sim.syncIdSet['syncUUIDs'])
else:
- self.syncrepl_present(uuids=sim.syncIdSet['syncUUIDs'])
+ self.syncrepl_present(sim.syncIdSet['syncUUIDs'])
if 'cookie' in sim.syncIdSet:
self.syncrepl_set_cookie(sim.syncIdSet['cookie'])
pass
@@ -412,31 +412,32 @@ class LDAPSyncObject(ldap.ldapobject.LDAPObject):
"""
pass
- def syncrepl_present(self, uuids={}, refreshDeletes=False):
+ def syncrepl_present(self, uuids, refreshDeletes=False):
"""
Called by syncrepl_poll() whenever entry UUIDs are presented to the client.
syncrepl_present() is given a list of entry UUIDs (uuids) and a flag
(refreshDeletes) which indicates whether the server explicitly deleted
non-present entries during the refresh operation.
- If called with a nonempty set of uuids, the syncrepl_present() implementation
+ If called with a list of uuids, the syncrepl_present() implementation
should record those uuids as present in the directory.
- If called with an empty set of uuids and refreshDeletes set to False,
+ If called with uuids set to None and refreshDeletes set to False,
syncrepl_present() should delete all non-present entries from the local
mirror, and reset the list of recorded uuids.
- If called with an empty set of uuids and refreshDeletes set to True,
+ If called with uuids set to None and refreshDeletes set to True,
syncrepl_present() should reset the list of recorded uuids, without
deleting any entries.
"""
pass
- def syncrepl_delete(self, uuids={}):
+ def syncrepl_delete(self, uuids):
"""
- Called by syncrepl_poll() to delete entries. It is given a list
- of UUIDs (uuids) of the entries to be deleted.
+ Called by syncrepl_poll() to delete entries. A list
+ of UUIDs of the entries to be deleted is given in the
+ uuids parameter.
"""
pass
-------------- next part --------------
A non-text attachment was scrubbed...
Name: syncrepl-demo.py
Type: text/x-python
Size: 2114 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-ldap/attachments/20110803/e1eee0c9/attachment.py>
More information about the python-ldap
mailing list