diff options
author | Guilhem Moulin <guilhem@fripost.org> | 2014-07-07 23:02:45 +0200 |
---|---|---|
committer | Guilhem Moulin <guilhem@fripost.org> | 2015-06-07 02:52:41 +0200 |
commit | 9198e7f8096e9f1b0d5f474cf2345913a357f864 (patch) | |
tree | 940cafc428e311b8ea82d9dad7a59c8bfb9251ac /lib | |
parent | 3e38718677b10faca8970d9b1cc8edc215cce798 (diff) |
Make the Ansible LDAP plugin able to delete entries and attributes.
Use it to delete cn=admin,dc=fripost,dc=org, and to remove the rootDN on
the 'config' database.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/action_plugins/openldap.py | 3 | ||||
-rw-r--r-- | lib/modules/openldap | 37 |
2 files changed, 35 insertions, 5 deletions
diff --git a/lib/action_plugins/openldap.py b/lib/action_plugins/openldap.py index ee8a991..5dbf59f 100644 --- a/lib/action_plugins/openldap.py +++ b/lib/action_plugins/openldap.py @@ -14,40 +14,43 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import os import pipes import tempfile from ansible.utils import template from ansible import utils from ansible.runner.return_data import ReturnData class ActionModule(object): TRANSFERS_FILES = True def __init__(self, runner): self.runner = runner def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): ''' handler for file transfer operations ''' + if self.runner.noop_on_check(inject): + return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True)) + # load up options options = {} if complex_args: options.update(complex_args) options.update(utils.parse_kv(module_args)) target = options.get('target', None) local = options.get('local', 'no') if local not in [ 'no', 'file', 'template' ]: result = dict(failed=True, msg="local must be in ['no','file','template']") return ReturnData(conn=conn, comm_ok=False, result=result) if local != 'no' and target is None: result = dict(failed=True, msg="target is required in local mode") return ReturnData(conn=conn, comm_ok=False, result=result) if local == 'no': # run the module remotely return self.runner._execute_module(conn, tmp, 'openldap', module_args, inject=inject, complex_args=complex_args) diff --git a/lib/modules/openldap b/lib/modules/openldap index 1e84c32..69ee4df 100644 --- a/lib/modules/openldap +++ b/lib/modules/openldap @@ -248,65 +248,92 @@ def slapd_to_ldif(src, name): m2 = re2.match(line) m3 = re3.match(line) if m1 is not None: line = 'olcObjectIdentifier: %s' % m1.group(1) elif m2 is not None: line = 'olcObjectClasses: %s' % m2.group(1) elif m3 is not None: line = 'olcAttributeTypes: %s' % m3.group(1) d.write( reSp.sub(line, ' ') ) s.close() d.close() return d.name def main(): module = AnsibleModule( argument_spec = dict( - state = dict( default="present", choices=["absent","present"]), target = dict( default=None ), module = dict( default=None ), suffix = dict( default=None ), format = dict( default="ldif", choices=["ldif","slapd.conf"] ), name = dict( default=None ), local = dict( default="no", choices=["no","file","template"] ), + delete = dict( default=None ), ), supports_check_mode=True ) params = module.params - state = params['state'] target = params['target'] mod = params['module'] suffix = params['suffix'] form = params['format'] name = params['name'] + delete = params['delete'] changed = False try: - if state == "absent": - module.fail_json(msg="OpenLDAP's ansible: unsupported feature") + if delete is not None: + if name is None: + module.fail_json(msg="missing name") + l = ldap.initialize( 'ldapi://' ) + l.sasl_interactive_bind_s('', ldap.sasl.external()) + if delete == 'entry': + filterStr = '(objectClass=*)' + else: + filterStr = [ '(%s=*)' % x for x in delete.split(',') ] + if len(filterStr) > 1: + filterStr = '(|' + ''.join(filterStr) + ')' + else: + filterStr = filterStr[0] + + try: + r = l.search_s( name, ldap.SCOPE_BASE, filterStr, attrsonly=1 ) + except ldap.LDAPError, ldap.NO_SUCH_OBJECT: + r = None - elif state == "present": + if r: + changed = True + if module.check_mode: + module.exit_json(changed=changed) + if delete == 'entry': + l.delete_s(r[0][0]) + else: + attrlist = list(set(r[0][1].keys()) & set(delete.split(','))) + l.modify_s(r[0][0], [ (ldap.MOD_DELETE, x, None) for x in attrlist ]) + l.unbind_s() + + else: if form == 'slapd.conf': if name is None: module.fail_json(msg="missing name") target = slapd_to_ldif(target, name) if target is None and mod is None: module.fail_json(msg="missing target or module") # bind only once per LDIF file for performance l = ldap.initialize( 'ldapi://' ) l.sasl_interactive_bind_s('', ldap.sasl.external()) if mod is None: callback = partial(processEntry,module,l) else: changed |= loadModule (module, l, '%s.la' % mod) if target is None and suffix is None: l.unbind_s() module.exit_json(changed=changed) if target is None or suffix is None: module.fail_json(msg="missing target or suffix") |