Skip to content
Snippets Groups Projects
Commit 16f67ce9 authored by Rafael Guterres Jeffman's avatar Rafael Guterres Jeffman
Browse files

Add support for parameter `rename` on ipahostgroup.

FreeIPA 4.8.7 introduced an option to rename an existing hostgroup.
This patch adds support for renaming hostgroups if the option is
available on installed IPA version.

A new state `renamed` and a new option `rename` (alias: `new_name`)
was added to module `ipahostgroup` to allow renaming of host groups.

The implemented behavior is:
* Rename if `name` exists and `rename` doesn't.
* Do nothing if `name` does not exist and `rename` does, or if
  `name` equals to `rename`. (result.changed is False)
* Fail if neither or both `name` and `rename` exist.
parent 3487efcf
No related branches found
No related tags found
No related merge requests found
...@@ -19,6 +19,8 @@ Supported FreeIPA Versions ...@@ -19,6 +19,8 @@ Supported FreeIPA Versions
FreeIPA versions 4.4.0 and up are supported by the ipahostgroup module. FreeIPA versions 4.4.0 and up are supported by the ipahostgroup module.
Some variables are only supported on newer versions of FreeIPA. Check `Variables` section for details.
Requirements Requirements
------------ ------------
...@@ -105,6 +107,23 @@ Example playbook to make sure hosts and hostgroups are absent in databases hostg ...@@ -105,6 +107,23 @@ Example playbook to make sure hosts and hostgroups are absent in databases hostg
state: absent state: absent
``` ```
Example playbook to rename an existing playbook:
```yaml
---
- name: Playbook to handle hostgroups
hosts: ipaserver
become: true
tasks:
# Ensure host-group databases is absent
- ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: databases
rename: datalake
state: renamed
```
Example playbook to make sure host-group databases is absent: Example playbook to make sure host-group databases is absent:
```yaml ```yaml
...@@ -121,7 +140,6 @@ Example playbook to make sure host-group databases is absent: ...@@ -121,7 +140,6 @@ Example playbook to make sure host-group databases is absent:
state: absent state: absent
``` ```
Variables Variables
========= =========
...@@ -139,8 +157,9 @@ Variable | Description | Required ...@@ -139,8 +157,9 @@ Variable | Description | Required
`hostgroup` | List of hostgroup name strings assigned to this hostgroup. | no `hostgroup` | List of hostgroup name strings assigned to this hostgroup. | no
`membermanager_user` | List of member manager users assigned to this hostgroup. Only usable with IPA versions 4.8.4 and up. | no `membermanager_user` | List of member manager users assigned to this hostgroup. Only usable with IPA versions 4.8.4 and up. | no
`membermanager_group` | List of member manager groups assigned to this hostgroup. Only usable with IPA versions 4.8.4 and up. | no `membermanager_group` | List of member manager groups assigned to this hostgroup. Only usable with IPA versions 4.8.4 and up. | no
`rename` \| `new_name` | Rename hostgroup to the provided name. Only usable with IPA versions 4.8.7 and up. | no
`action` | Work on hostgroup or member level. It can be on of `member` or `hostgroup` and defaults to `hostgroup`. | no `action` | Work on hostgroup or member level. It can be on of `member` or `hostgroup` and defaults to `hostgroup`. | no
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | no `state` | The state to ensure. It can be one of `present`, `absent` or `renamed`, default: `present`. | no
Authors Authors
......
---
- name: Playbook to handle hostgroups
hosts: ipaserver
become: yes
tasks:
- name : Rename host-group from `databases` to `datalake`
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: databases
rename: datalake
state: renamed
...@@ -70,6 +70,12 @@ options: ...@@ -70,6 +70,12 @@ options:
- Only usable with IPA versions 4.8.4 and up. - Only usable with IPA versions 4.8.4 and up.
required: false required: false
type: list type: list
rename:
description:
- Rename hostgroup to the given name.
- Only usable with IPA versions 4.8.7 and up.
required: false
aliases: ["new_name"]
action: action:
description: Work on hostgroup or member level description: Work on hostgroup or member level
default: hostgroup default: hostgroup
...@@ -77,7 +83,7 @@ options: ...@@ -77,7 +83,7 @@ options:
state: state:
description: State to ensure description: State to ensure
default: present default: present
choices: ["present", "absent"] choices: ["present", "absent", "renamed"]
author: author:
- Thomas Woerner - Thomas Woerner
""" """
...@@ -116,6 +122,12 @@ EXAMPLES = """ ...@@ -116,6 +122,12 @@ EXAMPLES = """
action: member action: member
state: absent state: absent
# Rename hostgroup
- ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: databases
rename: datalake
# Ensure host-group databases is absent # Ensure host-group databases is absent
- ipahostgroup: - ipahostgroup:
ipaadmin_password: SomeADMINpassword ipaadmin_password: SomeADMINpassword
...@@ -129,7 +141,7 @@ RETURN = """ ...@@ -129,7 +141,7 @@ RETURN = """
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \ temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
module_params_get, gen_add_del_lists, api_check_command module_params_get, gen_add_del_lists, api_check_command, api_check_param
def find_hostgroup(module, name): def find_hostgroup(module, name):
...@@ -149,12 +161,14 @@ def find_hostgroup(module, name): ...@@ -149,12 +161,14 @@ def find_hostgroup(module, name):
return None return None
def gen_args(description, nomembers): def gen_args(description, nomembers, rename):
_args = {} _args = {}
if description is not None: if description is not None:
_args["description"] = description _args["description"] = description
if nomembers is not None: if nomembers is not None:
_args["nomembers"] = nomembers _args["nomembers"] = nomembers
if rename is not None:
_args["rename"] = rename
return _args return _args
...@@ -186,11 +200,13 @@ def main(): ...@@ -186,11 +200,13 @@ def main():
membermanager_user=dict(required=False, type='list', default=None), membermanager_user=dict(required=False, type='list', default=None),
membermanager_group=dict(required=False, type='list', membermanager_group=dict(required=False, type='list',
default=None), default=None),
rename=dict(required=False, type='str', default=None,
aliases=["new_name"]),
action=dict(type="str", default="hostgroup", action=dict(type="str", default="hostgroup",
choices=["member", "hostgroup"]), choices=["member", "hostgroup"]),
# state # state
state=dict(type="str", default="present", state=dict(type="str", default="present",
choices=["present", "absent"]), choices=["present", "absent", "renamed"]),
), ),
supports_check_mode=True, supports_check_mode=True,
) )
...@@ -215,6 +231,7 @@ def main(): ...@@ -215,6 +231,7 @@ def main():
"membermanager_user") "membermanager_user")
membermanager_group = module_params_get(ansible_module, membermanager_group = module_params_get(ansible_module,
"membermanager_group") "membermanager_group")
rename = module_params_get(ansible_module, "rename")
action = module_params_get(ansible_module, "action") action = module_params_get(ansible_module, "action")
# state # state
state = module_params_get(ansible_module, "state") state = module_params_get(ansible_module, "state")
...@@ -225,19 +242,38 @@ def main(): ...@@ -225,19 +242,38 @@ def main():
if len(names) != 1: if len(names) != 1:
ansible_module.fail_json( ansible_module.fail_json(
msg="Only one hostgroup can be added at a time.") msg="Only one hostgroup can be added at a time.")
invalid = ["rename"]
if action == "member": if action == "member":
invalid = ["description", "nomembers"] invalid.extend(["description", "nomembers"])
for x in invalid: for x in invalid:
if vars()[x] is not None: if vars()[x] is not None:
ansible_module.fail_json( ansible_module.fail_json(
msg="Argument '%s' can not be used with action " msg="Argument '%s' can not be used with action "
"'%s'" % (x, action)) "'%s'" % (x, action))
if state == "renamed":
if len(names) != 1:
ansible_module.fail_json(
msg="Only one hostgroup can be added at a time.")
if action == "member":
ansible_module.fail_json(
msg="Action '%s' can not be used with state '%s'" %
(action, state))
invalid = [
"description", "nomembers", "host", "hostgroup",
"membermanager_user", "membermanager_group"
]
for x in invalid:
if vars()[x] is not None:
ansible_module.fail_json(
msg="Argument '%s' can not be used with state '%s'" %
(x, state))
if state == "absent": if state == "absent":
if len(names) < 1: if len(names) < 1:
ansible_module.fail_json( ansible_module.fail_json(
msg="No name given.") msg="No name given.")
invalid = ["description", "nomembers"] invalid = ["description", "nomembers", "rename"]
if action == "hostgroup": if action == "hostgroup":
invalid.extend(["host", "hostgroup"]) invalid.extend(["host", "hostgroup"])
for x in invalid: for x in invalid:
...@@ -266,6 +302,10 @@ def main(): ...@@ -266,6 +302,10 @@ def main():
msg="Managing a membermanager user or group is not supported " msg="Managing a membermanager user or group is not supported "
"by your IPA version" "by your IPA version"
) )
has_mod_rename = api_check_param("hostgroup_mod", "rename")
if not has_mod_rename and rename is not None:
ansible_module.fail_json(
msg="Renaming hostgroups is not supported by your IPA version")
commands = [] commands = []
...@@ -276,7 +316,7 @@ def main(): ...@@ -276,7 +316,7 @@ def main():
# Create command # Create command
if state == "present": if state == "present":
# Generate args # Generate args
args = gen_args(description, nomembers) args = gen_args(description, nomembers, rename)
if action == "hostgroup": if action == "hostgroup":
# Found the hostgroup # Found the hostgroup
...@@ -375,6 +415,22 @@ def main(): ...@@ -375,6 +415,22 @@ def main():
}] }]
) )
elif state == "renamed":
if res_find is not None:
if rename != name:
commands.append(
[name, "hostgroup_mod", {"rename": rename}]
)
else:
# If a hostgroup with the desired name exists, do nothing.
new_find = find_hostgroup(ansible_module, rename)
if new_find is None:
# Fail only if the either hostsgroups do not exist.
ansible_module.fail_json(
msg="Attribute `rename` can not be used, unless "
"hostgroup exists."
)
elif state == "absent": elif state == "absent":
if action == "hostgroup": if action == "hostgroup":
if res_find is not None: if res_find is not None:
......
---
- name: Test hostgroup
hosts: ipaserver
become: true
gather_facts: false
tasks:
- name: Ensure testing host-group are absent
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name:
- databases
- datalake
- inexistenthostgroup
state: absent
- name: Ensure host-group databases is present
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: databases
state: present
register: result
failed_when: not result.changed
- name: Rename host-group from `databases` to `datalake`
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: databases
rename: datalake
state: renamed
register: result
failed_when: not result.changed
- name: Ensure host-group database was already absent
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: database
state: absent
register: result
failed_when: result.changed
- name: Rename host-group from `databases` to `datalake`, again
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: databases
rename: datalake
state: renamed
register: result
failed_when: result.changed or result.failed
- name: Rename host-group with same name.
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: datalake
rename: datalake
state: renamed
register: result
failed_when: result.changed
- name: Ensure testing hostgroups do not exist.
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: inexistenthostgroup,alsoinexistent
state: absent
- name: Rename inexistent host-group to an existing one.
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: inexistenthostgroup
rename: datalake
state: renamed
register: result
failed_when: result.changed or result.failed
- name: Rename inexistent host-group to a non-existing one.
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: inexistenthostgroup
rename: alsoinexistent
state: renamed
register: result
failed_when: not result.failed or "Attribute `rename` can not be used, unless hostgroup exists." not in result.msg
- name: Ensure host-group databases is present
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: databases
state: present
- name: Rename host-group to an existing one.
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name: databases
rename: datalake
state: renamed
register: result
failed_when: not result.failed or "This entry already exists" not in result.msg
- name: Ensure host-group databases and datalake are absent
ipahostgroup:
ipaadmin_password: SomeADMINpassword
name:
- databases
- datalake
state: absent
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment