diff --git a/README-host.md b/README-host.md
index 80dcf251..7ff7afa7 100644
--- a/README-host.md
+++ b/README-host.md
@@ -101,6 +101,11 @@ Example playbook to initiate the generation of a random password to be used in b
description: Example host
ip_address: 192.168.0.123
random: yes
+ register: ipahost
+
+ - name: Print generated random password
+ debug:
+ var: ipahost.host.randompassword
```
@@ -167,6 +172,21 @@ Variable | Description | Required
`state` | The state to ensure. It can be one of `present`, `absent` or `disabled`, default: `present`. | yes
+Return Values
+=============
+
+ipahost
+-------
+
+There are only return values if one or more random passwords have been generated.
+
+Variable | Description | Returned When
+-------- | ----------- | -------------
+`host` | Host dict with random password. (dict)
Options: | If random is yes and host did not exist or update_password is yes
+ | `randompassword` - The generated random password | If only one host is handled by the module
+ | `name` - The host name of the host that got a new random password. (dict)
Options:
`randompassword` - The generated random password | If several hosts are handled by the module
+
+
Authors
=======
diff --git a/README-user.md b/README-user.md
index 88d04b28..56772a77 100644
--- a/README-user.md
+++ b/README-user.md
@@ -142,6 +142,64 @@ And ensure the presence of the users with this example playbook:
users: "{{ users }}"
```
+Ensure user pinky is present with a generated random password and print the random password:
+
+```yaml
+---
+- name: Playbook to handle users
+ hosts: ipaserver
+ become: true
+
+ tasks:
+ # Ensure user pinky is present with a random password
+ - ipauser:
+ ipaadmin_password: MyPassword123
+ name: brain
+ first: brain
+ last: Acme
+ random: yes
+ register: ipauser
+
+ - name: Print generated random password
+ debug:
+ var: ipauser.user.randompassword
+```
+
+Ensure users pinky and brain are present with a generated random password and print the random passwords:
+
+```yaml
+---
+- name: Playbook to handle users
+ hosts: ipaserver
+ become: true
+
+ tasks:
+ # Ensure users pinky and brain are present with random password
+ - ipauser:
+ ipaadmin_password: MyPassword123
+ users:
+ - name: pinky
+ first: pinky
+ last: Acme
+ uid: 10001
+ gid: 100
+ phone: "+555123457"
+ email: pinky@acme.com
+ passwordexpiration: "2023-01-19 23:59:59"
+ password: "no-brain"
+ - name: brain
+ first: brain
+ last: Acme
+ register: ipauser
+
+ - name: Print generated random password of pinky
+ debug:
+ var: ipauser.user.pinky.randompassword
+
+ - name: Print generated random password of brain
+ debug:
+ var: ipauser.user.brain.randompassword
+```
Example playbook to delete a user, but preserve it:
@@ -367,6 +425,22 @@ Variable | Description | Required
`nomembers` | Suppress processing of membership attributes. (bool) | no
+
+Return Values
+=============
+
+ipauser
+-------
+
+There are only return values if one or more random passwords have been generated.
+
+Variable | Description | Returned When
+-------- | ----------- | -------------
+`host` | Host dict with random password. (dict)
Options: | If random is yes and user did not exist or update_password is yes
+ | `randompassword` - The generated random password | If only one user is handled by the module
+ | `name` - The user name of the user that got a new random password. (dict)
Options:
`randompassword` - The generated random password | If several users are handled by the module
+
+
Authors
=======
diff --git a/playbooks/host/ensure_host_with_randompassword.yml b/playbooks/host/ensure_host_with_randompassword.yml
new file mode 100644
index 00000000..cd1a1331
--- /dev/null
+++ b/playbooks/host/ensure_host_with_randompassword.yml
@@ -0,0 +1,18 @@
+---
+- name: Ensure host with random password
+ hosts: ipaserver
+ become: true
+
+ tasks:
+ - name: Host "{{ 'host1.' + ipaserver_domain }}" present with random password
+ ipahost:
+ ipaadmin_password: MyPassword123
+ name: "{{ 'host1.' + ipaserver_domain }}"
+ random: yes
+ force: yes
+ update_password: on_create
+ register: ipahost
+
+ - name: Print generated random password
+ debug:
+ var: ipahost.host.randompassword
diff --git a/playbooks/user/ensure_user_with_randompassword.yml b/playbooks/user/ensure_user_with_randompassword.yml
new file mode 100644
index 00000000..4ca9f214
--- /dev/null
+++ b/playbooks/user/ensure_user_with_randompassword.yml
@@ -0,0 +1,19 @@
+---
+- name: Ensure user with random password
+ hosts: ipaserver
+ become: true
+
+ tasks:
+ - name: User user1 present with random password
+ ipauser:
+ ipaadmin_password: MyPassword123
+ name: user1
+ first: first1
+ last: last1
+ random: yes
+ update_password: on_create
+ register: ipauser
+
+ - name: Print generated random password
+ debug:
+ var: ipauser.user.randompassword
diff --git a/playbooks/user/ensure_users_with_randompasswords.yml b/playbooks/user/ensure_users_with_randompasswords.yml
new file mode 100644
index 00000000..06f50c71
--- /dev/null
+++ b/playbooks/user/ensure_users_with_randompasswords.yml
@@ -0,0 +1,28 @@
+---
+- name: Tests
+ hosts: ipaserver
+ become: true
+
+ tasks:
+ - name: Users user1 and user1 present with random password
+ ipauser:
+ ipaadmin_password: MyPassword123
+ users:
+ - name: user1
+ first: first1
+ last: last1
+ random: yes
+ - name: user2
+ first: first2
+ last: last2
+ random: yes
+ update_password: on_create
+ register: ipauser
+
+ - name: Print generated random password for user1
+ debug:
+ var: ipauser.user.user1.randompassword
+
+ - name: Print generated random password for user2
+ debug:
+ var: ipauser.user.user2.randompassword
diff --git a/plugins/modules/ipahost.py b/plugins/modules/ipahost.py
index 952e5442..4a240bdb 100644
--- a/plugins/modules/ipahost.py
+++ b/plugins/modules/ipahost.py
@@ -149,6 +149,22 @@ EXAMPLES = """
"""
RETURN = """
+host:
+ description: Host dict with random password
+ returned: If random is yes and user did not exist or update_password is yes
+ type: dict
+ options:
+ randompassword:
+ description: The generated random password
+ returned: If only one user is handled by the module
+ name:
+ description: The user name of the user that got a new random password
+ returned: If several users are handled by the module
+ type: dict
+ options:
+ randompassword:
+ description: The generated random password
+ returned: always
"""
from ansible.module_utils.basic import AnsibleModule
@@ -344,9 +360,11 @@ 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":
+ if "userpassword" in args:
+ del args["userpassword"]
+ if "random" in args:
+ del args["random"]
# Ignore force, ip_address and no_reverse for mod
for x in ["force", "ip_address", "no_reverse"]:
@@ -379,8 +397,19 @@ def main():
# Execute commands
for name, command, args in commands:
try:
- api_command(ansible_module, command, to_text(name), args)
+ result = api_command(ansible_module, command, to_text(name),
+ args)
changed = True
+
+ if "random" in args and command in ["host_add", "host_mod"] \
+ and "randompassword" in result["result"]:
+ if len(names) == 1:
+ exit_args["randompassword"] = \
+ result["result"]["randompassword"]
+ else:
+ exit_args.setdefault(name, {})["randompassword"] = \
+ result["result"]["randompassword"]
+
except Exception as e:
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
str(e)))
@@ -393,7 +422,7 @@ def main():
# Done
- ansible_module.exit_json(changed=changed, **exit_args)
+ ansible_module.exit_json(changed=changed, host=exit_args)
if __name__ == "__main__":
diff --git a/plugins/modules/ipauser.py b/plugins/modules/ipauser.py
index 19bf7a18..ac452958 100644
--- a/plugins/modules/ipauser.py
+++ b/plugins/modules/ipauser.py
@@ -438,6 +438,22 @@ EXAMPLES = """
"""
RETURN = """
+user:
+ description: User dict with random password
+ returned: If random is yes and user did not exist or update_password is yes
+ type: dict
+ options:
+ randompassword:
+ description: The generated random password
+ returned: If only one user is handled by the module
+ name:
+ description: The user name of the user that got a new random password
+ returned: If several users are handled by the module
+ type: dict
+ options:
+ randompassword:
+ description: The generated random password
+ returned: always
"""
from ansible.module_utils.basic import AnsibleModule
@@ -1005,7 +1021,8 @@ def main():
else:
commands.append([name, "user_add", args])
- # Handle members: principal, manager
+ # Handle members: principal, manager, certificate and
+ # certmapdata
if res_find is not None:
# Generate addition and removal lists
manager_add = list(
@@ -1276,6 +1293,16 @@ def main():
changed = True
else:
changed = True
+
+ if "random" in args and command in ["user_add", "user_mod"] \
+ and "randompassword" in result["result"]:
+ if len(names) == 1:
+ exit_args["randompassword"] = \
+ result["result"]["randompassword"]
+ else:
+ exit_args.setdefault(name, {})["randompassword"] = \
+ result["result"]["randompassword"]
+
except Exception as e:
msg = str(e)
if "already contains" in msg \
@@ -1312,7 +1339,7 @@ def main():
# Done
- ansible_module.exit_json(changed=changed, **exit_args)
+ ansible_module.exit_json(changed=changed, user=exit_args)
if __name__ == "__main__":
diff --git a/tests/host/test_host_random.yml b/tests/host/test_host_random.yml
new file mode 100644
index 00000000..0856ddc0
--- /dev/null
+++ b/tests/host/test_host_random.yml
@@ -0,0 +1,41 @@
+---
+- name: Test ipahost random password generation
+ hosts: ipaserver
+ become: true
+
+ tasks:
+ - name: Get Domain from server name
+ set_fact:
+ ipaserver_domain: "{{ groups.ipaserver[0].split('.')[1:] | join ('.') }}"
+ when: ipaserver_domain is not defined
+
+ - name: Test hosts absent
+ ipahost:
+ ipaadmin_password: MyPassword123
+ name:
+ - "{{ 'host1.' + ipaserver_domain }}"
+ - "{{ 'host2.' + ipaserver_domain }}"
+ update_dns: yes
+ state: absent
+
+ - name: Host "{{ 'host1.' + ipaserver_domain }}" present with random password
+ ipahost:
+ ipaadmin_password: MyPassword123
+ name: "{{ 'host1.' + ipaserver_domain }}"
+ random: yes
+ force: yes
+ update_password: on_create
+ register: ipahost
+ failed_when: not ipahost.changed or
+ ipahost.host.randompassword is not defined
+
+ - name: Print generated random password
+ debug:
+ var: ipahost.host.randompassword
+
+ - name: Host "{{ 'host1.' + ipaserver_domain }}" absent
+ ipahost:
+ ipaadmin_password: MyPassword123
+ name:
+ - "{{ 'host1.' + ipaserver_domain }}"
+ state: absent
diff --git a/tests/user/test_user_random.yml b/tests/user/test_user_random.yml
new file mode 100644
index 00000000..47e4a350
--- /dev/null
+++ b/tests/user/test_user_random.yml
@@ -0,0 +1,70 @@
+---
+- name: Test ipauser random password generation
+ hosts: ipaserver
+ become: true
+
+ tasks:
+ - name: Users user1 and user2 absent
+ ipauser:
+ ipaadmin_password: MyPassword123
+ name:
+ - user1
+ - user2
+ state: absent
+
+ - name: User user1 present with random password
+ ipauser:
+ ipaadmin_password: MyPassword123
+ name: user1
+ first: first1
+ last: last1
+ random: yes
+ update_password: on_create
+ register: ipauser
+ failed_when: not ipauser.changed or
+ ipauser.user.randompassword is not defined
+
+ - name: Print generated random password
+ debug:
+ var: ipauser.user.randompassword
+
+ - name: User user1 absent
+ ipauser:
+ ipaadmin_password: MyPassword123
+ name:
+ - user1
+ state: absent
+
+ - name: Users user1 and user1 present with random password
+ ipauser:
+ ipaadmin_password: MyPassword123
+ users:
+ - name: user1
+ first: first1
+ last: last1
+ random: yes
+ - name: user2
+ first: first2
+ last: last2
+ random: yes
+ update_password: on_create
+ register: ipauser
+ failed_when: not ipauser.changed or
+ ipauser.user.user1.randompassword is not defined or
+ ipauser.user.user2.randompassword is not defined
+
+ - name: Print generated random password for user1
+ debug:
+ var: ipauser.user.user1.randompassword
+
+ - name: Print generated random password for user2
+ debug:
+ var: ipauser.user.user2.randompassword
+
+ - name: Users user1 and user2 absent
+ ipauser:
+ ipaadmin_password: MyPassword123
+ name:
+ - user1
+ - user2
+ state: absent