diff options
author | Pavel Zuna <pzuna@redhat.com> | 2010-10-01 12:35:27 -0400 |
---|---|---|
committer | Adam Young <ayoung@redhat.com> | 2010-10-01 10:00:01 -0400 |
commit | 838c1f2c943a4dd315b4da17a0951a6d53d31ad3 (patch) | |
tree | 5de0c4b8b28a800cbd6d2e97e05e36b9f1d063ef | |
parent | c53831037cbe388d961420e87b036b1caf6cf723 (diff) | |
download | freeipa-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.py | 98 |
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): |