diff --git a/README-host.md b/README-host.md index 5f540cac10255ec7af0cce6c2b46496bb7a06b70..4ee4cbe45abf3ee8c1af0c98bc0a2a7f76fdad65 100644 --- a/README-host.md +++ b/README-host.md @@ -173,14 +173,14 @@ Example playbook to ensure host presence with a random password: name: host01.example.com random: yes force: yes + update_password: on_create register: ipahost - name: Print generated random password debug: var: ipahost.host.randompassword ``` -Please remember that the `force` tag will also force the generation of a new random password even if the host already exists and if `update_password` is limited to `on_create`. - +Please remember that a new random password will be generated for an existing but not enrolled host if `update_password` is not limited to `on_create`. For an already enrolled host the task will fail with `update_password` default setting `always`. Example playbook to ensure presence of several hosts with a random password: @@ -198,9 +198,11 @@ Example playbook to ensure presence of several hosts with a random password: - name: host01.example.com random: yes force: yes + update_password: on_create - name: host02.example.com random: yes force: yes + update_password: on_create register: ipahost - name: Print generated random password for host01.example.com @@ -211,7 +213,7 @@ Example playbook to ensure presence of several hosts with a random password: debug: var: ipahost.host["host02.example.com"].randompassword ``` -Please remember that the `force` tag will also force the generation of a new random password even if the host alreay exists and if `update_password` is limited to `on_create`. +Please remember that a new random password will be generated for an existing but not enrolled host if `update_password` is not limited to `on_create`. For an already enrolled host the task will fail with `update_password` default setting `always`. Example playbook to ensure presence of host member principal: @@ -337,8 +339,8 @@ Variable | Description | Required `location` \| `ns_host_location` | Host location (e.g. "Lab 2"). | no `platform` \| `ns_hardware_platform` | Host hardware platform (e.g. "Lenovo T61"). | no `os` \| `ns_os_version` | Host operating system and version (e.g. "Fedora 9"). | no -`password` \| `user_password` \| `userpassword` | Password used in bulk enrollment. | no -`random` \| `random_password` | Initiate the generation of a random password to be used in bulk enrollment. | no +`password` \| `user_password` \| `userpassword` | Password used in bulk enrollment for absent or not enrolled hosts. | no +`random` \| `random_password` | Initiate the generation of a random password to be used in bulk enrollment for absent or not enrolled hosts. | no `certificate` \| `usercertificate` | List of base-64 encoded host certificates | no `managedby` \| `principalname` \| `krbprincipalname` | List of hosts that can manage this host | no `principal` \| `principalname` \| `krbprincipalname` | List of principal aliases for this host | no diff --git a/plugins/modules/ipahost.py b/plugins/modules/ipahost.py index 42bd7e1faf6fbb1f6f246ae72a4c623839e88ee9..4778386cfd237f235897287b9bfe8bb46073ce6c 100644 --- a/plugins/modules/ipahost.py +++ b/plugins/modules/ipahost.py @@ -420,23 +420,22 @@ if six.PY3: def find_host(module, name): _args = { "all": True, - "fqdn": to_text(name), } - _result = api_command(module, "host_find", to_text(name), _args) + try: + _result = api_command(module, "host_show", to_text(name), _args) + except ipalib_errors.NotFound as e: + msg = str(e) + if "host not found" in msg: + return None + module.fail_json(msg="host_show failed: %s" % msg) - if len(_result["result"]) > 1: - module.fail_json( - msg="There is more than one host '%s'" % (name)) - elif len(_result["result"]) == 1: - _res = _result["result"][0] - certs = _res.get("usercertificate") - if certs is not None: - _res["usercertificate"] = [encode_certificate(cert) for - cert in certs] - return _res - else: - return None + _res = _result["result"] + certs = _res.get("usercertificate") + if certs is not None: + _res["usercertificate"] = [encode_certificate(cert) for + cert in certs] + return _res def find_dnsrecord(module, name): @@ -903,9 +902,25 @@ def main(): # Found the host if res_find is not None: # Ignore password with update_password == on_create - if update_password == "on_create" and \ - "userpassword" in args: - del args["userpassword"] + if update_password == "on_create": + # Ignore userpassword and random for existing + # host if update_password is "on_create" + if "userpassword" in args: + del args["userpassword"] + if "random" in args: + del args["random"] + elif "userpassword" in args or "random" in args: + # Allow an existing OTP to be reset but don't + # allow a OTP or to be added to an enrolled host. + # Also do not allow to change the password for an + # enrolled host. + + if not res_find["has_password"] and \ + res_find["has_keytab"]: + ansible_module.fail_json( + msg="%s: Password cannot be set on " + "enrolled host." % host + ) # Ignore force, ip_address and no_reverse for mod for x in ["force", "ip_address", "no_reverse"]: @@ -953,7 +968,7 @@ def main(): principal_add, principal_del = gen_add_del_lists( principal, res_find.get("principal")) # Principals are not returned as utf8 for IPA using - # python2 using host_find, therefore we need to + # python2 using host_show, therefore we need to # convert the principals that we should remove. principal_del = [to_text(x) for x in principal_del] diff --git a/tests/host/test_host_random.yml b/tests/host/test_host_random.yml index 4d1b2545e6ae94d71e0adf5a5643b2fdac7e4757..376740c736ae421bd0b8e72dd27768824f4f2983 100644 --- a/tests/host/test_host_random.yml +++ b/tests/host/test_host_random.yml @@ -77,6 +77,22 @@ debug: var: ipahost.host["{{host2_fqdn }}"].randompassword + - name: Enrolled host "{{ groups.ipaserver[0] }}" fails to set random password with update_password always + ipahost: + ipaadmin_password: SomeADMINpassword + hosts: + - name: "{{ groups.ipaserver[0] }}" + random: yes + update_password: always + register: ipahost + failed_when: ipahost.changed + + - assert: + that: + - ipahost.host["{{ groups.ipaserver[0] }}"].randompassword is + not defined + - "'Password cannot be set on enrolled host' in ipahost.msg" + - name: Hosts "{{ host1_fqdn }}" and "{{ host2_fqdn }}" absent ipahost: ipaadmin_password: SomeADMINpassword