1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

ldap_entry - Recursive deletion (#4355) (#4360)

* ldap_entry - Recursive deletion

  * Recursive deletion can be enabled with the `recursive` option. It is
    disabled by default.
  * When enabled, deletion is attempted by sending a single delete
    request with the Subtree Delete control. If that request fails with
    the `NOT_ALLOWED_ON_NONLEAF` error, try deleting the whole branch in
    reverse order using individual delete requests.

* ldap_entry recursive deletion - Changelog fragment

* ldap_entry - Refactored to avoid lint message

* Update changelogs/fragments/4355-ldap-recursive-delete.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* ldap_entry - Add version_added to the recursive flag

Co-authored-by: Felix Fontein <felix@fontein.de>

* ldap_entry - Moved member assignment to a more suitable location

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 0b71d123d2)

Co-authored-by: Emmanuel Benoît <tseeker@nocternity.net>
This commit is contained in:
patchback[bot] 2022-03-15 06:05:07 +01:00 committed by GitHub
parent 7fcb21e044
commit 89663a0688
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 2 deletions

View file

@ -0,0 +1,4 @@
---
minor_changes:
- ldap_entry - add support for recursive deletion
(https://github.com/ansible-collections/community.general/issues/3613).

View file

@ -49,6 +49,13 @@ options:
choices: [present, absent]
default: present
type: str
recursive:
description:
- If I(state=delete), a flag indicating whether a single entry or the
whole branch must be deleted.
type: bool
default: false
version_added: 4.6.0
extends_documentation_fragment:
- community.general.ldap.documentation
@ -110,6 +117,7 @@ from ansible_collections.community.general.plugins.module_utils.ldap import Ldap
LDAP_IMP_ERR = None
try:
import ldap.modlist
import ldap.controls
HAS_LDAP = True
except ImportError:
@ -123,6 +131,7 @@ class LdapEntry(LdapGeneric):
# Shortcuts
self.state = self.module.params['state']
self.recursive = self.module.params['recursive']
# Add the objectClass into the list of attributes
self.module.params['attributes']['objectClass'] = (
@ -158,12 +167,29 @@ class LdapEntry(LdapGeneric):
return action
def delete(self):
""" If self.dn exists, returns a callable that will delete it. """
""" If self.dn exists, returns a callable that will delete either
the item itself if the recursive option is not set or the whole branch
if it is. """
def _delete():
self.connection.delete_s(self.dn)
def _delete_recursive():
""" Attempt recurive deletion using the subtree-delete control.
If that fails, do it manually. """
try:
subtree_delete = ldap.controls.ValueLessRequestControl('1.2.840.113556.1.4.805')
self.connection.delete_ext_s(self.dn, serverctrls=[subtree_delete])
except ldap.NOT_ALLOWED_ON_NONLEAF:
search = self.connection.search_s(self.dn, ldap.SCOPE_SUBTREE, attrlist=('dn',))
search.reverse()
for entry in search:
self.connection.delete_s(entry[0])
if self._is_entry_present():
action = _delete
if self.recursive:
action = _delete_recursive
else:
action = _delete
else:
action = None
@ -186,6 +212,7 @@ def main():
attributes=dict(default={}, type='dict'),
objectClass=dict(type='list', elements='str'),
state=dict(default='present', choices=['present', 'absent']),
recursive=dict(default=False, type='bool'),
),
required_if=[('state', 'present', ['objectClass'])],
supports_check_mode=True,