diff --git a/README-automember.md b/README-automember.md index 42fc4aca3758a7fb26d871a099ccc2ffa3111c30..1e1f1d3a46c2444fbf9784baa6c5b2cfed06f7d6 100644 --- a/README-automember.md +++ b/README-automember.md @@ -104,13 +104,160 @@ Example playbook to add an inclusive condition to an existing rule ipaadmin_password: SomeADMINpassword name: "My domain hosts" description: "my automember condition" - automember_tye: hostgroup + automember_type: hostgroup action: member inclusive: - key: fqdn expression: ".*.mydomain.com" ``` +Example playbook to ensure group membership for all users has been rebuilt + +```yaml +- name: Playbook to ensure group membership for all users has been rebuilt + hosts: ipaserver + become: yes + gather_facts: no + tasks: + - ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: group + state: rebuilt +``` + +Example playbook to ensure group membership for given users has been rebuilt + + +```yaml +- name: Playbook to ensure group membership for given users has been rebuilt + hosts: ipaserver + become: yes + gather_facts: no + tasks: + - ipaautomember: + ipaadmin_password: SomeADMINpassword + users: + - user1 + - user2 + state: rebuilt +``` + +Example playbook to ensure hostgroup membership for all hosts has been rebuilt + +```yaml +- name: Playbook to ensure hostgroup membership for all hosts has been rebuilt + hosts: ipaserver + become: yes + gather_facts: no + tasks: + - ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + state: rebuilt +``` + +Example playbook to ensure hostgroup membership for given hosts has been rebuilt + +```yaml +- name: Playbook to ensure hostgroup membership for given hosts has been rebuilt + hosts: ipaserver + become: yes + gather_facts: no + tasks: + - ipaautomember: + ipaadmin_password: SomeADMINpassword + hosts: + - host1.mydomain.com + - host2.mydomain.com + state: rebuilt +``` + +Example playbook to ensure default group fallback_group for all unmatched group entries is set + +```yaml +- name: Playbook to ensure default group fallback_group for all unmatched group entries is set + hosts: ipaserver + become: yes + gather_facts: no + tasks: + - ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: group + default_group: fallback_group +``` + +Example playbook to ensure default group for all unmatched group entries is not set + +```yaml +- name: Playbook to ensure default group for all unmatched group entries is not set + hosts: ipaserver + become: yes + gather_facts: no + tasks: + - ipaautomember: + ipaadmin_password: SomeADMINpassword + default_group: "" + automember_type: group + state: absent +``` + +Example playbook to ensure default hostgroup fallback_hostgroup for all unmatched group entries + +```yaml +- name: Playbook to ensure default hostgroup fallback_hostgroup for all unmatched group entries + hosts: ipaserver + become: yes + gather_facts: no + tasks: + - ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + default_group: fallback_hostgroup +``` + +Example playbook to ensure default hostgroup for all unmatched group entries is not set + +```yaml +- name: Playbook to ensure default hostgroup for all unmatched group entries is not set + hosts: ipaserver + become: yes + gather_facts: no + tasks: + - ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + default_group: "" + state: absent +``` + +Example playbook to ensure all orphan automember group rules are removed: + +```yaml +- name: Playbook to ensure all orphan automember group rules are removed + hosts: ipaserver + become: yes + gather_facts: no + tasks: + - ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: group + state: orphans_removed +``` + +Example playbook to ensure all orphan automember hostgroup rules are removed: + +```yaml +- name: Playbook to ensure all orphan automember hostgroup rules are removed + hosts: ipaserver + become: yes + gather_facts: no + tasks: + - ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + state: orphans_removed +``` + Variables --------- @@ -129,11 +276,16 @@ Variable | Description | Required `automember_type` | Grouping to which the rule applies. It can be one of `group`, `hostgroup`. | yes `inclusive` | List of dictionaries in the format of `{'key': attribute, 'expression': inclusive_regex}` | no `exclusive` | List of dictionaries in the format of `{'key': attribute, 'expression': exclusive_regex}` | no +`users` | Users to rebuild membership for. | no +`hosts` | Hosts to rebuild membership for. | no +`no_wait` | Don't wait for rebuilding membership. | no +`default_group` | Default (fallback) group for all unmatched entries. Use the empty string "" for ensuring the default group is not set. | no `action` | Work on automember or member level. It can be one of `member` or `automember` and defaults to `automember`. | no -`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no +`state` | The state to ensure. It can be one of `present`, `absent`, 'rebuilt'. 'orphans_removed' default: `present`. | no Authors ======= Mark Hahl +Thomas Woerner diff --git a/playbooks/automember/automember-default-group-not-set.yml b/playbooks/automember/automember-default-group-not-set.yml new file mode 100644 index 0000000000000000000000000000000000000000..7c85bfb4068da523c98e9390c71a981f74353faa --- /dev/null +++ b/playbooks/automember/automember-default-group-not-set.yml @@ -0,0 +1,10 @@ +--- +- name: Automember default group not set + hosts: ipaserver + become: true + tasks: + - name: Ensure automember default group is not set + ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: group + default_group: "" diff --git a/playbooks/automember/automember-default-group-set.yml b/playbooks/automember/automember-default-group-set.yml new file mode 100644 index 0000000000000000000000000000000000000000..41ce1185039fe82eada6f449074d188e344d3fac --- /dev/null +++ b/playbooks/automember/automember-default-group-set.yml @@ -0,0 +1,10 @@ +--- +- name: Automember default group set + hosts: ipaserver + become: true + tasks: + - name: Ensure automember default group is set + ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: group + default_group: fallback_group diff --git a/playbooks/automember/automember-default-hostgroup-not-set.yml b/playbooks/automember/automember-default-hostgroup-not-set.yml new file mode 100644 index 0000000000000000000000000000000000000000..c37a875741131b5e59fc8e3bf6b01d021de47a32 --- /dev/null +++ b/playbooks/automember/automember-default-hostgroup-not-set.yml @@ -0,0 +1,10 @@ +--- +- name: Automember default hostgroup not set + hosts: ipaserver + become: true + tasks: + - name: Ensure automember default hostgroup is not set + ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + default_group: "" diff --git a/playbooks/automember/automember-default-hostgroup-set.yml b/playbooks/automember/automember-default-hostgroup-set.yml new file mode 100644 index 0000000000000000000000000000000000000000..ac3b8d6d025d5f0ad6bf580937fc6c981fd46139 --- /dev/null +++ b/playbooks/automember/automember-default-hostgroup-set.yml @@ -0,0 +1,10 @@ +--- +- name: Automember default hostgroup set + hosts: ipaserver + become: true + tasks: + - name: Ensure automember default hostgroup is set + ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + default_group: fallback_hostgroup diff --git a/playbooks/automember/automember-group-membership-all-users-rebuilt.yml b/playbooks/automember/automember-group-membership-all-users-rebuilt.yml new file mode 100644 index 0000000000000000000000000000000000000000..5cfd14379a5f2e16773fc647820f44fffb42547c --- /dev/null +++ b/playbooks/automember/automember-group-membership-all-users-rebuilt.yml @@ -0,0 +1,10 @@ +--- +- name: Automember group membership for all users rebuilt example + hosts: ipaserver + become: true + tasks: + - name: Ensure group automember rule admins is present + ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: group + state: rebuilt diff --git a/playbooks/automember/automember-group-membership-users-rebuilt.yml b/playbooks/automember/automember-group-membership-users-rebuilt.yml new file mode 100644 index 0000000000000000000000000000000000000000..df9e54a657a2feba6f15aa3f2dfe12ee09c11701 --- /dev/null +++ b/playbooks/automember/automember-group-membership-users-rebuilt.yml @@ -0,0 +1,12 @@ +--- +- name: Automember group membership for given users rebuilt example + hosts: ipaserver + become: true + tasks: + - name: Ensure group membership for given users has been rebuilt + ipaautomember: + ipaadmin_password: SomeADMINpassword + users: + - user1 + - user2 + state: rebuilt diff --git a/playbooks/automember/automember-group-orphans-removed.yml b/playbooks/automember/automember-group-orphans-removed.yml new file mode 100644 index 0000000000000000000000000000000000000000..46121101f8053390f19a5748fce2378c48f5afa6 --- /dev/null +++ b/playbooks/automember/automember-group-orphans-removed.yml @@ -0,0 +1,10 @@ +--- +- name: Automember orphan group rules are removed example + hosts: ipaserver + become: true + tasks: + - name: Ensure orphan group rules are removed + ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: group + state: orphans_removed diff --git a/playbooks/automember/automember-hostgroup-membership-all-hosts-rebuilt.yml b/playbooks/automember/automember-hostgroup-membership-all-hosts-rebuilt.yml new file mode 100644 index 0000000000000000000000000000000000000000..f2ad5a49c9ee4ef943b41cd4b3656dc12a77ba50 --- /dev/null +++ b/playbooks/automember/automember-hostgroup-membership-all-hosts-rebuilt.yml @@ -0,0 +1,10 @@ +--- +- name: Automember hostgroup membership for all hosts rebuilt example + hosts: ipaserver + become: true + tasks: + - name: Ensure hostgroup membership for all hosts has been rebuilt + ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + state: rebuilt diff --git a/playbooks/automember/automember-hostgroup-membership-hosts-rebuilt.yml b/playbooks/automember/automember-hostgroup-membership-hosts-rebuilt.yml new file mode 100644 index 0000000000000000000000000000000000000000..82e6c7f8f7d96056609db19b8121a0ba94eb8479 --- /dev/null +++ b/playbooks/automember/automember-hostgroup-membership-hosts-rebuilt.yml @@ -0,0 +1,12 @@ +--- +- name: Automember hostgroup membership for given hosts rebuilt example + hosts: ipaserver + become: true + tasks: + - name: Ensure hostgroup membership for given hosts has been rebuilt + ipaautomember: + ipaadmin_password: SomeADMINpassword + hosts: + - host1.mydomain.com + - host2.mydomain.com + state: rebuilt diff --git a/playbooks/automember/automember-hostgroup-orphans-removed.yml b/playbooks/automember/automember-hostgroup-orphans-removed.yml new file mode 100644 index 0000000000000000000000000000000000000000..62d7e93defbcb800db4f28c948a86d5992082a3b --- /dev/null +++ b/playbooks/automember/automember-hostgroup-orphans-removed.yml @@ -0,0 +1,10 @@ +--- +- name: Automember orphan hostgroup rules are removed example + hosts: ipaserver + become: true + tasks: + - name: Ensure orphan hostgroup rules are removed + ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + state: orphans_removed diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py index 728af00ac31f924fc90166d5a7d0a32e894c2944..b4cdf613f9fdd458261460d4d39d153a83ed64c1 100644 --- a/plugins/module_utils/ansible_freeipa_module.py +++ b/plugins/module_utils/ansible_freeipa_module.py @@ -419,6 +419,9 @@ else: def api_get_realm(): return api.env.realm + def api_get_basedn(): + return api.env.basedn + def gen_add_del_lists(user_list, res_list): """ Generate the lists for the addition and removal of members. @@ -882,6 +885,11 @@ else: """Retrieve IPA API realm.""" return api_get_realm() + @staticmethod + def ipa_get_basedn(): + """Retrieve IPA API basedn.""" + return api_get_basedn() + @staticmethod def ipa_command_exists(command): """ diff --git a/plugins/modules/ipaautomember.py b/plugins/modules/ipaautomember.py index c3b8e1a9048bc2cf289df627d4d32e3d91730fac..cfd6d192dfb1acdaeffb5a8ece10e70692673cc4 100644 --- a/plugins/modules/ipaautomember.py +++ b/plugins/modules/ipaautomember.py @@ -79,6 +79,20 @@ options: description: The expression of the regex type: str required: true + users: + description: Users to rebuild membership for. + type: list + required: false + hosts: + description: Hosts to rebuild membership for. + type: list + required: false + no_wait: + description: Don't wait for rebuilding membership. + type: bool + default_group: + description: Default (fallback) group for all unmatched entries. + type: str action: description: Work on automember or member level default: automember @@ -86,10 +100,11 @@ options: state: description: State to ensure default: present - choices: ["present", "absent"] + choices: ["present", "absent", "rebuilt", "orphans_removed"] author: - Mark Hahl - Jake Reynolds + - Thomas Woerner """ EXAMPLES = """ @@ -116,12 +131,78 @@ EXAMPLES = """ - ipaautomember: ipaadmin_password: SomeADMINpassword name: "My domain hosts" - automember_tye: hostgroup + automember_type: hostgroup action: member inclusive: - key: fqdn expression: ".*.mydomain.com" +# Ensure group membership for all users has been rebuilt +- ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: group + state: rebuilt + +# Ensure group membership for given users has been rebuilt +- ipaautomember: + ipaadmin_password: SomeADMINpassword + users: + - user1 + - user2 + state: rebuilt + +# Ensure hostgroup membership for all hosts has been rebuilt +- ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + state: rebuilt + +# Ensure hostgroup membership for given hosts has been rebuilt +- ipaautomember: + ipaadmin_password: SomeADMINpassword + hosts: + - host1.mydomain.com + - host2.mydomain.com + state: rebuilt + +# Ensure default group fallback_group for all unmatched group entries is set +- ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: group + default_group: fallback_group + +# Ensure default group for all unmatched group entries is not set +- ipaautomember: + ipaadmin_password: SomeADMINpassword + default_group: "" + automember_type: group + state: absent + +# Ensure default hostgroup fallback_hostgroup for all unmatched group entries +# is set +- ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + default_group: fallback_hostgroup + +# Ensure default hostgroup for all unmatched group entries is not set +- ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + default_group: "" + state: absent + +# Example playbook to ensure all orphan automember group rules are removed: +- ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: group + state: orphans_removed + +# Example playbook to ensure all orphan automember hostgroup rules are removed: +- ipaautomember: + ipaadmin_password: SomeADMINpassword + automember_type: hostgroup + state: orphans_removed """ RETURN = """ @@ -129,14 +210,14 @@ RETURN = """ from ansible.module_utils.ansible_freeipa_module import ( - IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, ipalib_errors + IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, ipalib_errors, DN ) -def find_automember(module, name, grouping): +def find_automember(module, name, automember_type): _args = { "all": True, - "type": grouping + "type": automember_type } try: @@ -146,13 +227,40 @@ def find_automember(module, name, grouping): return _result["result"] -def gen_condition_args(grouping, +def find_automember_orphans(module, automember_type): + _args = { + "all": True, + "type": automember_type + } + + try: + _result = module.ipa_command_no_name("automember_find_orphans", _args) + except ipalib_errors.NotFound: + return None + return _result + + +def find_automember_default_group(module, automember_type): + _args = { + "all": True, + "type": automember_type + } + + try: + _result = module.ipa_command_no_name("automember_default_group_show", + _args) + except ipalib_errors.NotFound: + return None + return _result["result"] + + +def gen_condition_args(automember_type, key, inclusiveregex=None, exclusiveregex=None): _args = {} - if grouping is not None: - _args['type'] = grouping + if automember_type is not None: + _args['type'] = automember_type if key is not None: _args['key'] = key if inclusiveregex is not None: @@ -163,13 +271,23 @@ def gen_condition_args(grouping, return _args -def gen_args(description, grouping): +def gen_rebuild_args(automember_type, rebuild_users, rebuild_hosts, no_wait): + _args = {"no_wait": no_wait} + if automember_type is not None: + _args['type'] = automember_type + if rebuild_users is not None: + _args["users"] = rebuild_users + if rebuild_hosts is not None: + _args["hosts"] = rebuild_hosts + return _args + + +def gen_args(description, automember_type): _args = {} if description is not None: _args["description"] = description - if grouping is not None: - _args['type'] = grouping - + if automember_type is not None: + _args['type'] = automember_type return _args @@ -212,14 +330,17 @@ def main(): elements="dict", required=False), name=dict(type="list", aliases=["cn"], - default=None, required=True), + default=None, required=False), description=dict(type="str", default=None), automember_type=dict(type='str', required=False, choices=['group', 'hostgroup']), + no_wait=dict(type="bool", default=None), + default_group=dict(type="str", default=None), action=dict(type="str", default="automember", choices=["member", "automember"]), state=dict(type="str", default="present", - choices=["present", "absent", "rebuild"]), + choices=["present", "absent", "rebuilt", + "orphans_removed"]), users=dict(type="list", default=None), hosts=dict(type="list", default=None), ), @@ -232,6 +353,8 @@ def main(): # general names = ansible_module.params_get("name") + if names is None: + names = [] # present description = ansible_module.params_get("description") @@ -240,6 +363,12 @@ def main(): inclusive = ansible_module.params_get("inclusive") exclusive = ansible_module.params_get("exclusive") + # no_wait for rebuilt + no_wait = ansible_module.params_get("no_wait") + + # default_group + default_group = ansible_module.params_get("default_group") + # action action = ansible_module.params_get("action") # state @@ -254,12 +383,51 @@ def main(): # Check parameters invalid = [] - if state != "rebuild": - invalid = ["rebuild_hosts", "rebuild_users"] + if state in ["rebuilt", "orphans_removed"]: + invalid = ["name", "description", "exclusive", "inclusive", + "default_group"] - if not automember_type and state != "rebuild": + if action == "member": ansible_module.fail_json( - msg="'automember_type' is required unless state: rebuild") + msg="'action=member' is not usable with state '%s'" % state) + + if state == "rebuilt": + if automember_type == "group" and rebuild_hosts is not None: + ansible_module.fail_json( + msg="state %s: hosts can not be set when type is '%s'" % + (state, automember_type)) + if automember_type == "hostgroup" and rebuild_users is not None: + ansible_module.fail_json( + msg="state %s: users can not be set when type is '%s'" % + (state, automember_type)) + + elif state == "orphans_removed": + invalid.extend(["users", "hosts"]) + + if not automember_type: + ansible_module.fail_json( + msg="'automember_type' is required unless state: rebuilt") + + else: + if default_group is not None: + for param in ["name", "exclusive", "inclusive", "users", "hosts" + "no_wait"]: + if ansible_module.params.get(param) is not None: + msg = "Cannot use {0} together with default_group" + ansible_module.fail_json(msg=msg.format(param)) + if action == "member": + ansible_module.fail_json( + msg="Cannot use default_group with action:member") + if state == "absent": + ansible_module.fail_json( + msg="Cannot use default_group with state:absent") + + else: + invalid = ["users", "hosts", "no_wait"] + + if not automember_type: + ansible_module.fail_json( + msg="'automember_type' is required.") ansible_module.params_fail_used_invalid(invalid, state, action) @@ -396,16 +564,45 @@ def main(): 'automember_remove_condition', condition_args]) - elif state == "rebuild": - if automember_type: - commands.append([None, 'automember_rebuild', - {"type": automember_type}]) - if rebuild_users: - commands.append([None, 'automember_rebuild', - {"users": rebuild_users}]) - if rebuild_hosts: - commands.append([None, 'automember_rebuild', - {"hosts": rebuild_hosts}]) + if len(names) == 0: + if state == "rebuilt": + args = gen_rebuild_args(automember_type, rebuild_users, + rebuild_hosts, no_wait) + commands.append([None, 'automember_rebuild', args]) + + elif state == "orphans_removed": + res_find = find_automember_orphans(ansible_module, + automember_type) + if res_find["count"] > 0: + commands.append([None, 'automember_find_orphans', + {'type': automember_type, + 'remove': True}]) + + elif default_group is not None and state == "present": + res_find = find_automember_default_group(ansible_module, + automember_type) + + if default_group == "": + if isinstance(res_find["automemberdefaultgroup"], list): + commands.append([None, + 'automember_default_group_remove', + {'type': automember_type}]) + ansible_module.warn("commands: %s" % repr(commands)) + + else: + dn_default_group = [DN(('cn', default_group), + ('cn', '%ss' % automember_type), + ('cn', 'accounts'), + ansible_module.ipa_get_basedn())] + if repr(res_find["automemberdefaultgroup"]) != \ + repr(dn_default_group): + commands.append( + [None, 'automember_default_group_set', + {'type': automember_type, + 'automemberdefaultgroup': default_group}]) + + else: + ansible_module.fail_json(msg="Invalid operation") # Execute commands diff --git a/tests/automember/test_automember_client_context.yml b/tests/automember/test_automember_client_context.yml index d8c5658dd1f82bdec1e5ef75fac85ae9ddf39127..5e03302c7ddb444eea310ed0f769f66fb258ff0a 100644 --- a/tests/automember/test_automember_client_context.yml +++ b/tests/automember/test_automember_client_context.yml @@ -13,8 +13,8 @@ ipaautomember: ipaadmin_password: SomeADMINpassword ipaapi_context: server - name: ThisShouldNotWork - state: rebuild + automember_type: group + state: rebuilt register: result failed_when: not (result.failed and result.msg is regex("No module named '*ipaserver'*")) when: ipa_host_is_client diff --git a/tests/automember/test_automember_default_group.yml b/tests/automember/test_automember_default_group.yml new file mode 100644 index 0000000000000000000000000000000000000000..9b082127459938cd86ed806fe665ce933937da6e --- /dev/null +++ b/tests/automember/test_automember_default_group.yml @@ -0,0 +1,166 @@ +--- +- name: Test automember default groups + hosts: "{{ ipa_test_host | default('ipaserver') }}" + become: true + + tasks: + + # SET FACTS + + # CLEANUP TEST ITEMS + + - name: Ensure group testgroup is absent + ipagroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testgroup + state: absent + + - name: Ensure hostgroup testhostgroup is absent + ipahostgroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testhostgroup + state: absent + + - name: Ensure automember default group is unset + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: "" + automember_type: group + + - name: Ensure automember default hostgroup is unset + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: "" + automember_type: hostgroup + + # CREATE TEST ITEMS + + - name: Ensure group testgroup is present + ipagroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testgroup + state: present + register: result + failed_when: not result.changed or result.failed + + - name: Ensure hostgroup testhostgroup is present + ipahostgroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testhostgroup + state: present + register: result + failed_when: not result.changed or result.failed + + # TESTS + + # GROUP TEST + + - name: Ensure automember default group is set to testgroup + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: testgroup + automember_type: group + register: result + failed_when: not result.changed or result.failed + + - name: Ensure automember default group is set to testgroup, again + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: testgroup + automember_type: group + register: result + failed_when: result.changed or result.failed + + - name: Ensure automember default group is unset + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: "" + automember_type: group + register: result + failed_when: not result.changed or result.failed + + - name: Ensure automember default group is unset, again + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: "" + automember_type: group + register: result + failed_when: result.changed or result.failed + + # HOSTGROUP TEST + + - name: Ensure automember default hostgroup is set to testhostgroup + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: testhostgroup + automember_type: hostgroup + register: result + failed_when: not result.changed or result.failed + + - name: Ensure automember default hostgroup is set to testhostgroup, again + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: testhostgroup + automember_type: hostgroup + register: result + failed_when: result.changed or result.failed + + - name: Ensure automember default hostgroup is unset + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: "" + automember_type: hostgroup + register: result + failed_when: not result.changed or result.failed + + - name: Ensure automember default hostgroup is unset, again + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: "" + automember_type: hostgroup + register: result + failed_when: result.changed or result.failed + + # CLEANUP TEST ITEMS + + - name: Ensure group testgroup is absent + ipagroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testgroup + state: absent + + - name: Ensure hostgroup testhostgroup is absent + ipahostgroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testhostgroup + state: absent + + - name: Ensure automember default group is unset + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: "" + automember_type: group + + - name: Ensure automember default hostgroup is unset + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + default_group: "" + automember_type: hostgroup diff --git a/tests/automember/test_automember_orphans_removed.yml b/tests/automember/test_automember_orphans_removed.yml new file mode 100644 index 0000000000000000000000000000000000000000..0b9bcd3a32dd375364268ee22c9b2dc5dc790406 --- /dev/null +++ b/tests/automember/test_automember_orphans_removed.yml @@ -0,0 +1,250 @@ +--- +- name: Test automember orphans_removed + hosts: "{{ ipa_test_host | default('ipaserver') }}" + become: true + + tasks: + + # SET FACTS + + - name: Get Domain from server name + set_fact: + ipaserver_domain: "{{ ansible_facts['fqdn'].split('.')[1:] | + join ('.') }}" + when: ipaserver_domain is not defined + + # CLEANUP TEST ITEMS + + - name: Ensure user testuser is absent + ipauser: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testuser + state: absent + + - name: Ensure group testgroup is absent + ipagroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testgroup + state: absent + + - name: Ensure host testhost is absent + ipahost: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ 'testhost.' + ipaserver_domain }}" + state: absent + + - name: Ensure hostgroup testhostgroup is absent + ipahostgroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testhostgroup + state: absent + + - name: Ensure automember group testgroup is absent + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testgroup + automember_type: group + state: absent + + - name: Ensure automember hostgroup testhostgroup is absent + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testhostgroup + automember_type: hostgroup + state: absent + + # CREATE TEST ITEMS + + - name: Ensure user testuser is present + ipauser: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testuser + first: Test + last: User + register: result + failed_when: not result.changed or result.failed + + - name: Ensure host testhost is present + ipahost: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ 'testhost.' + ipaserver_domain }}" + force: yes + reverse: no + register: result + failed_when: not result.changed or result.failed + + - name: Ensure group testgroup is present + ipagroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testgroup + state: present + register: result + failed_when: not result.changed or result.failed + + - name: Ensure hostgroup testhostgroup is present + ipahostgroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testhostgroup + state: present + register: result + failed_when: not result.changed or result.failed + + # TESTS + + # GROUP TEST + + - name: Ensure automember group testgroup exists + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testgroup + automember_type: group + register: result + failed_when: not result.changed or result.failed + + - name: Ensure automember group condition exits for users + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testgroup + automember_type: group + action: member + inclusive: + - key: uid + expression: uid + register: result + failed_when: not result.changed or result.failed + + - name: Ensure group testgroup is absent + ipagroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testgroup + state: absent + register: result + failed_when: not result.changed or result.failed + + - name: Ensure group orphans have been removed + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + automember_type: group + state: orphans_removed + register: result + failed_when: not result.changed or result.failed + + - name: Ensure group orphans have been removed again + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + automember_type: group + state: orphans_removed + register: result + failed_when: result.changed or result.failed + + # HOSTGROUP TEST + + - name: Ensure automember hostgroup testhostgroup exists + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testhostgroup + automember_type: hostgroup + register: result + failed_when: not result.changed or result.failed + + - name: Ensure automember hostgroup condition exits for hosts + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testhostgroup + automember_type: hostgroup + action: member + inclusive: + - key: fqdn + expression: "{{ '.*.' + ipaserver_domain }}" + register: result + failed_when: not result.changed or result.failed + + - name: Ensure hostgroup testhostgroup is absent + ipahostgroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testhostgroup + state: absent + register: result + failed_when: not result.changed or result.failed + + - name: Ensure hostgroup orphans have been removed + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + automember_type: hostgroup + state: orphans_removed + register: result + failed_when: not result.changed or result.failed + + - name: Ensure hostgroup orphans have been removed again + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + automember_type: hostgroup + state: orphans_removed + register: result + failed_when: result.changed or result.failed + + # CLEANUP TEST ITEMS + + - name: Ensure user testuser is absent + ipauser: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testuser + state: absent + + - name: Ensure group testgroup is absent + ipagroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testgroup + state: absent + + - name: Ensure host testhost is absent + ipahost: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ 'testhost.' + ipaserver_domain }}" + state: absent + + - name: Ensure hostgroup testhostgroup is absent + ipahostgroup: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testhostgroup + state: absent + + - name: Ensure automember group testgroup is absent + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testgroup + automember_type: group + state: absent + + - name: Ensure automember hostgroup testhostgroup is absent + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testhostgroup + automember_type: hostgroup + state: absent diff --git a/tests/automember/test_automember_rebuilt.yml b/tests/automember/test_automember_rebuilt.yml new file mode 100644 index 0000000000000000000000000000000000000000..4458e202766f736bc500401eacb8c3eaebfbee4d --- /dev/null +++ b/tests/automember/test_automember_rebuilt.yml @@ -0,0 +1,155 @@ +--- +- name: Test automember rebuilt + hosts: "{{ ipa_test_host | default('ipaserver') }}" + become: true + + tasks: + + # SET FACTS + + - name: Get Domain from server name + set_fact: + ipaserver_domain: "{{ ansible_facts['fqdn'].split('.')[1:] | + join ('.') }}" + when: ipaserver_domain is not defined + + # CLEANUP TEST ITEMS + + - name: Ensure user testuser is absent + ipauser: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testuser + state: absent + + - name: Ensure host testhost is absent + ipahost: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ 'testhost.' + ipaserver_domain }}" + state: absent + + # CREATE TEST ITEMS + + - name: Ensure user testuser is present + ipauser: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testuser + first: Test + last: User + register: result + failed_when: not result.changed or result.failed + + - name: Ensure host testhost is present + ipahost: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ 'testhost.' + ipaserver_domain }}" + force: yes + reverse: no + register: result + failed_when: not result.changed or result.failed + + # TESTS + + - name: Ensure group membership has been rebuilt + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + automember_type: group + state: rebuilt + register: result + failed_when: not result.changed or result.failed + + - name: Ensure group membership has been rebuilt no_wait + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + automember_type: group + no_wait: yes + state: rebuilt + register: result + failed_when: not result.changed or result.failed + + - name: Ensure group membership for given users has been rebuilt + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + users: + - testuser + state: rebuilt + register: result + failed_when: not result.changed or result.failed + + - name: Ensure hostgroup membership for given hosts has been rebuilt + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + hosts: + - "{{ 'testhost.' + ipaserver_domain }}" + state: rebuilt + register: result + failed_when: not result.changed or result.failed + + - name: Ensure group membership for given users has been rebuilt with type group + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + automember_type: group + users: + - testuser + state: rebuilt + register: result + failed_when: not result.changed or result.failed + + - name: Ensure hostgroup membership for given hosts has been rebuilt with type hostgroup + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + automember_type: hostgroup + hosts: + - "{{ 'testhost.' + ipaserver_domain }}" + state: rebuilt + register: result + failed_when: not result.changed or result.failed + + - name: Ensure group membership rebuild fails with hosts + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + automember_type: group + hosts: + - "{{ 'testhost.' + ipaserver_domain }}" + state: rebuilt + register: result + failed_when: not result.failed or + "hosts can not be set when type is 'group'" not in result.msg + + - name: Ensure hostgroup membership rebuild fails with users + ipaautomember: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + automember_type: hostgroup + users: + - testuser + state: rebuilt + register: result + failed_when: not result.failed or + "users can not be set when type is 'hostgroup'" not in result.msg + + # CLEANUP TEST ITEMS + + - name: Ensure user testuser is absent + ipauser: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: testuser + state: absent + + - name: Ensure host testhost is absent + ipahost: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ 'testhost.' + ipaserver_domain }}" + state: absent