summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Zuna <pzuna@redhat.com>2010-10-01 12:35:27 -0400
committerAdam Young <ayoung@redhat.com>2010-10-01 10:00:01 -0400
commit838c1f2c943a4dd315b4da17a0951a6d53d31ad3 (patch)
tree5de0c4b8b28a800cbd6d2e97e05e36b9f1d063ef
parentc53831037cbe388d961420e87b036b1caf6cf723 (diff)
downloadfreeipa-838c1f2c943a4dd315b4da17a0951a6d53d31ad3.tar.gz
freeipa-838c1f2c943a4dd315b4da17a0951a6d53d31ad3.tar.xz
freeipa-838c1f2c943a4dd315b4da17a0951a6d53d31ad3.zip
Add LDAPMultiQuery base class and make it the base of LDAPDelete.
In other words: make *-del commands accept 1 or more primary keys of entries to be deleted. Ticket #20
-rw-r--r--ipalib/plugins/baseldap.py98
1 files changed, 65 insertions, 33 deletions
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 1757a452e..f6b98e247 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -345,6 +345,19 @@ class LDAPQuery(CallbackInterface, crud.PKQuery):
yield self.obj.primary_key.clone(attribute=True, query=True)
+class LDAPMultiQuery(LDAPQuery):
+ """
+ Base class for commands that need to retrieve one or more existing entries.
+ """
+ def get_args(self):
+ for key in self.obj.get_ancestor_primary_keys():
+ yield key
+ if self.obj.primary_key:
+ yield self.obj.primary_key.clone(
+ attribute=True, query=True, multivalue=True
+ )
+
+
class LDAPRetrieve(LDAPQuery):
"""
Retrieve an LDAP entry.
@@ -512,7 +525,7 @@ class LDAPUpdate(LDAPQuery, crud.Update):
raise exc
-class LDAPDelete(LDAPQuery):
+class LDAPDelete(LDAPMultiQuery):
"""
Delete an LDAP entry and all of its direct subentries.
"""
@@ -521,47 +534,66 @@ class LDAPDelete(LDAPQuery):
def execute(self, *keys, **options):
ldap = self.obj.backend
- dn = self.obj.get_dn(*keys, **options)
+ def delete_entry(pkey):
+ nkeys = keys[:-1] + (pkey, )
+ dn = self.obj.get_dn(*nkeys, **options)
- for callback in self.PRE_CALLBACKS:
- if hasattr(callback, 'im_self'):
- dn = callback(ldap, dn, *keys, **options)
- else:
- dn = callback(self, ldap, dn, *keys, **options)
+ for callback in self.PRE_CALLBACKS:
+ if hasattr(callback, 'im_self'):
+ dn = callback(ldap, dn, *nkeys, **options)
+ else:
+ dn = callback(self, ldap, dn, *nkeys, **options)
- def delete_subtree(base_dn):
- truncated = True
- while truncated:
+ def delete_subtree(base_dn):
+ truncated = True
+ while truncated:
+ try:
+ (subentries, truncated) = ldap.find_entries(
+ None, [''], base_dn, ldap.SCOPE_ONELEVEL
+ )
+ except errors.NotFound:
+ break
+ else:
+ for (dn_, entry_attrs) in subentries:
+ delete_subtree(dn_)
try:
- (subentries, truncated) = ldap.find_entries(
- None, [''], base_dn, ldap.SCOPE_ONELEVEL
- )
- except errors.NotFound:
- break
+ ldap.delete_entry(base_dn, normalize=self.obj.normalize_dn)
+ except errors.ExecutionError, e:
+ try:
+ self._call_exc_callbacks(
+ nkeys, options, e, ldap.delete_entry, base_dn,
+ normalize=self.obj.normalize_dn
+ )
+ except errors.NotFound:
+ self.obj.handle_not_found(*nkeys)
+
+ delete_subtree(dn)
+
+ for callback in self.POST_CALLBACKS:
+ if hasattr(callback, 'im_self'):
+ result = callback(ldap, dn, *nkeys, **options)
else:
- for (dn_, entry_attrs) in subentries:
- delete_subtree(dn_)
- try:
- ldap.delete_entry(base_dn, normalize=self.obj.normalize_dn)
- except errors.ExecutionError, e:
- try:
- self._call_exc_callbacks(
- keys, options, e, ldap.delete_entry, base_dn,
- normalize=self.obj.normalize_dn
- )
- except errors.NotFound:
- self.obj.handle_not_found(*keys)
+ result = callback(self, ldap, dn, *nkeys, **options)
- delete_subtree(dn)
+ return result
- for callback in self.POST_CALLBACKS:
- if hasattr(callback, 'im_self'):
- result = callback(ldap, dn, *keys, **options)
+ if not self.obj.primary_key or not isinstance(keys[-1], (list, tuple)):
+ keys = keys[:-1] + (keys[-1], )
+
+ deleted = []
+ failed = []
+ result = True
+ for pkey in keys[-1]:
+ try:
+ if not delete_entry(pkey):
+ result = False
+ except errors.ExecutionError:
+ failed.append(pkey)
else:
- result = callback(self, ldap, dn, *keys, **options)
+ deleted.append(pkey)
if self.obj.primary_key and keys[-1] is not None:
- return dict(result=result, value=keys[-1])
+ return dict(result=result, value=u','.join(deleted))
return dict(result=result, value=u'')
def pre_callback(self, ldap, dn, *keys, **options):