-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
SUMMARY
This tasks enable the OpenLDAP memberof module:
- name: Enable memberof module
ldap_attrs:
dn: cn=module{0},cn=config
attributes:
olcModuleLoad: memberof.so
state: presentThe first time it is executed is OK, but the second time it is executed produce this error:
fatal: [myserver.mydomain.tld]: FAILED! => {"changed": false, "details": "{'info': u'modify/add: olcModuleLoad: value #0 already exists', 'desc': u'Type or value exists'}", "msg": "Attribute action failed."}
Type or value exists is something I expect with the state attribute set to present, so I am not sure why this is considered fatal.
Looking at the code, it seems that _is_value_present stays False, and no ldap.ALREADY_EXISTS exception is ever catched.
community.general/plugins/modules/net_tools/ldap/ldap_attrs.py
Lines 296 to 312 in 41cfdda
| if state == 'present': | |
| modlist = ldap.add() | |
| elif state == 'absent': | |
| modlist = ldap.delete() | |
| elif state == 'exact': | |
| modlist = ldap.exact() | |
| changed = False | |
| if len(modlist) > 0: | |
| changed = True | |
| if not module.check_mode: | |
| try: | |
| ldap.connection.modify_s(ldap.dn, modlist) | |
| except Exception as e: | |
| module.fail_json(msg="Attribute action failed.", details=to_native(e)) |
community.general/plugins/modules/net_tools/ldap/ldap_attrs.py
Lines 219 to 227 in 41cfdda
| def add(self): | |
| modlist = [] | |
| for name, values in self.module.params['attributes'].items(): | |
| norm_values = self._normalize_values(values) | |
| for value in norm_values: | |
| if self._is_value_absent(name, value): | |
| modlist.append((ldap.MOD_ADD, name, value)) | |
| return modlist |
community.general/plugins/modules/net_tools/ldap/ldap_attrs.py
Lines 261 to 269 in 41cfdda
| def _is_value_present(self, name, value): | |
| """ True if the target attribute has the given value. """ | |
| try: | |
| is_present = bool( | |
| self.connection.compare_s(self.dn, name, value)) | |
| except ldap.NO_SUCH_ATTRIBUTE: | |
| is_present = False | |
| return is_present |
If this is indeed a bug, I can try to provide a patch.
ISSUE TYPE
- Bug Report
COMPONENT NAME
ldap_attrs
ANSIBLE VERSION
ansible 2.10.1
config file = ~/dev/test/ansible.cfg
configured module search path = ['~/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.8/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.8.5 (default, Sep 5 2020, 10:50:12) [GCC 10.2.0]
CONFIGURATION
OS / ENVIRONMENT
Host: Archlinux - Target : Debian 10
STEPS TO REPRODUCE
Execute this task twice on a host that has OpenLDAP installed.
- name: Enable memberof module
ldap_attrs:
dn: cn=module{0},cn=config
attributes:
olcModuleLoad: memberof.so
state: presentEXPECTED RESULTS
The first time the task is executed, I expect a changed state.
The second time the task is executed, I expect a ok state.
ACTUAL RESULTS
The first time the task is executed, I get a changed state.
The second time the task is executed, I get a fatal state.
task path: ~/dev/test/roles/ldap/tasks/ldap.yml:129
redirecting (type: modules) ansible.builtin.ldap_attrs to community.general.ldap_attrs
Using module file /usr/lib/python3.8/site-packages/ansible_collections/community/general/plugins/modules/ldap_attrs.py
Pipelining is enabled.
<myserver.mydomain.tld> ESTABLISH SSH CONNECTION FOR USER: user<myserver.mydomain.tld> SSH: EXEC ssh -F ssh_config -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="user"' -o ConnectTimeout=10 myserver.mydomain.tld '/bin/sh -c '"'"'sudo -H -S -n -u root /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-bepsbegxtxjxhqjqqznwpvhyrvozoyyd ; /usr/bin/python'"'"'"'"'"'"'"'"' && sleep 0'"'"''
Escalation succeeded
<myserver.mydomain.tld> (1, b'\n{"msg": "Attribute action failed.", "failed": true, "exception": "WARNING: The below traceback may *not* be related to the actual failure.\\n File \\"/tmp/ansible_ldap_attrs_payload_2haQFB/ansible_ldap_attrs_payload.zip/ansible_collections/community/general/plugins/modules/ldap_attrs.py\\", line 310, in main\\n File \\"/usr/lib/python2.7/dist-packages/ldap/ldapobject.py\\", line 629, in modify_s\\n return self.modify_ext_s(dn,modlist,None,None)\\n File \\"/usr/lib/python2.7/dist-packages/ldap/ldapobject.py\\", line 602, in modify_ext_s\\n resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all=1,timeout=self.timeout)\\n File \\"/usr/lib/python2.7/dist-packages/ldap/ldapobject.py\\", line 749, in result3\\n resp_ctrl_classes=resp_ctrl_classes\\n File \\"/usr/lib/python2.7/dist-packages/ldap/ldapobject.py\\", line 756, in result4\\n ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)\\n File \\"/usr/lib/python2.7/dist-packages/ldap/ldapobject.py\\", line 329, in _ldap_call\\n reraise(exc_type, exc_value, exc_traceback)\\n File \\"/usr/lib/python2.7/dist-packages/ldap/ldapobject.py\\", line 313, in _ldap_call\\n result = func(*args,**kwargs)\\n", "details": "{\'info\': u\'modify/add: olcModuleLoad: value #0 already exists\', \'desc\': u\'Type or value exists\'}", "invocation": {"module_args": {"dn": "cn=module{0},cn=config", "ordered": false, "server_uri": "ldapi:///", "start_tls": false, "bind_dn": null, "state": "present", "bind_pw": "", "attributes": {"olcModuleLoad": "memberof.so"}, "validate_certs": true}}}\n', b'')
<myserver.mydomain.tld> Failed to connect to the host via ssh:
The full traceback is:
WARNING: The below traceback may *not* be related to the actual failure.
File "/tmp/ansible_ldap_attrs_payload_2haQFB/ansible_ldap_attrs_payload.zip/ansible_collections/community/general/plugins/modules/ldap_attrs.py", line 310, in main
File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 629, in modify_s
return self.modify_ext_s(dn,modlist,None,None)
File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 602, in modify_ext_s
resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all=1,timeout=self.timeout)
File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 749, in result3
resp_ctrl_classes=resp_ctrl_classes
File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 756, in result4
ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)
File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 329, in _ldap_call
reraise(exc_type, exc_value, exc_traceback)
File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 313, in _ldap_call
result = func(*args,**kwargs)
fatal: [myserver.mydomain.tld]: FAILED! => {
"changed": false,
"details": "{'info': u'modify/add: olcModuleLoad: value #0 already exists', 'desc': u'Type or value exists'}",
"invocation": {
"module_args": {
"attributes": {
"olcModuleLoad": "memberof.so"
},
"bind_dn": null,
"bind_pw": "",
"dn": "cn=module{0},cn=config",
"ordered": false,
"server_uri": "ldapi:///",
"start_tls": false,
"state": "present",
"validate_certs": true
}
},
"msg": "Attribute action failed."
}