From 0acf576d99405cdbc05be194afb2f42aadff3514 Mon Sep 17 00:00:00 2001 From: Thomas Woerner <twoerner@redhat.com> Date: Mon, 8 Jun 2020 16:01:04 +0200 Subject: [PATCH] ipagroup: Add support for group membership management A group membership manager is a user or a group that can add members to a group or remove members from a group. This is related to https://pagure.io/freeipa/issue/8114 New parameters have been added to the module: - `membermanager_user`: List of member manager users assigned to this group. Only usable with IPA versions 4.8.4 and up. - `membermanager_group`: List of member manager groups assigned to this group. Only usable with IPA versions 4.8.4 and up. These parameters behave like member parameters. A new test has been added: - tests/group/test_group_membermanager.yml --- README-group.md | 2 + plugins/modules/ipagroup.py | 88 +++++++++- tests/group/test_group_membermanager.yml | 194 +++++++++++++++++++++++ 3 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 tests/group/test_group_membermanager.yml diff --git a/README-group.md b/README-group.md index 4a278560..4ffdb291 100644 --- a/README-group.md +++ b/README-group.md @@ -143,6 +143,8 @@ Variable | Description | Required `user` | List of user name strings assigned to this group. | no `group` | List of group name strings assigned to this group. | no `service` | List of service name strings assigned to this group. Only usable with IPA versions 4.7 and up. | no +`membermanager_user` | List of member manager users assigned to this group. Only usable with IPA versions 4.8.4 and up. | no +`membermanager_group` | List of member manager groups assigned to this group. Only usable with IPA versions 4.8.4 and up. | no `action` | Work on group or member level. It can be on of `member` or `group` and defaults to `group`. | no `state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | yes diff --git a/plugins/modules/ipagroup.py b/plugins/modules/ipagroup.py index 1e6522c6..915bc499 100644 --- a/plugins/modules/ipagroup.py +++ b/plugins/modules/ipagroup.py @@ -75,6 +75,18 @@ options: - Only usable with IPA versions 4.7 and up. required: false type: list + membermanager_user: + description: + - List of member manager users assigned to this group. + - Only usable with IPA versions 4.8.4 and up. + required: false + type: list + membermanager_group: + description: + - List of member manager groups assigned to this group. + - Only usable with IPA versions 4.8.4 and up. + required: false + type: list action: description: Work on group or member level default: group @@ -141,7 +153,7 @@ RETURN = """ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \ - api_check_param, module_params_get, gen_add_del_lists + api_check_param, module_params_get, gen_add_del_lists, api_check_command def find_group(module, name): @@ -207,6 +219,9 @@ def main(): user=dict(required=False, type='list', default=None), group=dict(required=False, type='list', default=None), service=dict(required=False, type='list', default=None), + membermanager_user=dict(required=False, type='list', default=None), + membermanager_group=dict(required=False, type='list', + default=None), action=dict(type="str", default="group", choices=["member", "group"]), # state @@ -237,6 +252,10 @@ def main(): user = module_params_get(ansible_module, "user") group = module_params_get(ansible_module, "group") service = module_params_get(ansible_module, "service") + membermanager_user = module_params_get(ansible_module, + "membermanager_user") + membermanager_group = module_params_get(ansible_module, + "membermanager_group") action = module_params_get(ansible_module, "action") # state state = module_params_get(ansible_module, "state") @@ -287,6 +306,14 @@ def main(): msg="Managing a service as part of a group is not supported " "by your IPA version") + has_add_membermanager = api_check_command("group_add_member_manager") + if ((membermanager_user is not None or + membermanager_group is not None) and not has_add_membermanager): + ansible_module.fail_json( + msg="Managing a membermanager user or group is not supported " + "by your IPA version" + ) + commands = [] for name in names: @@ -360,6 +387,41 @@ def main(): "user": user_del, "group": group_del, }]) + + membermanager_user_add, membermanager_user_del = \ + gen_add_del_lists( + membermanager_user, + res_find.get("membermanager_user") + ) + + membermanager_group_add, membermanager_group_del = \ + gen_add_del_lists( + membermanager_group, + res_find.get("membermanager_group") + ) + + if has_add_membermanager: + # Add membermanager users and groups + if len(membermanager_user_add) > 0 or \ + len(membermanager_group_add) > 0: + commands.append( + [name, "group_add_member_manager", + { + "user": membermanager_user_add, + "group": membermanager_group_add, + }] + ) + # Remove member manager + if len(membermanager_user_del) > 0 or \ + len(membermanager_group_del) > 0: + commands.append( + [name, "group_remove_member_manager", + { + "user": membermanager_user_del, + "group": membermanager_group_del, + }] + ) + elif action == "member": if res_find is None: ansible_module.fail_json(msg="No group '%s'" % name) @@ -377,6 +439,18 @@ def main(): "group": group, }]) + if has_add_membermanager: + # Add membermanager users and groups + if membermanager_user is not None or \ + membermanager_group is not None: + commands.append( + [name, "group_add_member_manager", + { + "user": membermanager_user, + "group": membermanager_group, + }] + ) + elif state == "absent": if action == "group": if res_find is not None: @@ -400,6 +474,18 @@ def main(): "group": group, }]) + if has_add_membermanager: + # Remove membermanager users and groups + if membermanager_user is not None or \ + membermanager_group is not None: + commands.append( + [name, "group_remove_member_manager", + { + "user": membermanager_user, + "group": membermanager_group, + }] + ) + else: ansible_module.fail_json(msg="Unkown state '%s'" % state) diff --git a/tests/group/test_group_membermanager.yml b/tests/group/test_group_membermanager.yml new file mode 100644 index 00000000..1d38654f --- /dev/null +++ b/tests/group/test_group_membermanager.yml @@ -0,0 +1,194 @@ +--- +- name: Test group membermanagers + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: Ensure user manangeruser1 and manageruser2 is absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: manageruser1,manageruser2 + state: absent + + - name: Ensure group testgroup, managergroup1 and managergroup2 are absent + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup,managergroup1,managergroup2 + state: absent + + - name: Ensure user manageruser1 and manageruser2 are present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: manageruser1 + first: manageruser1 + last: Last1 + - name: manageruser2 + first: manageruser2 + last: Last2 + register: result + failed_when: not result.changed + + - name: Ensure testgroup is present + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + register: result + failed_when: not result.changed + + - name: Ensure managergroup1 is present + ipagroup: + ipaadmin_password: SomeADMINpassword + name: managergroup1 + register: result + failed_when: not result.changed + + - name: Ensure managergroup2 is present + ipagroup: + ipaadmin_password: SomeADMINpassword + name: managergroup2 + register: result + failed_when: not result.changed + + - name: Ensure membermanager user1 is present for testgroup + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_user: manageruser1 + register: result + failed_when: not result.changed + + - name: Ensure membermanager user1 is present for testgroup again + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_user: manageruser1 + register: result + failed_when: result.changed + + - name: Ensure membermanager group1 is present for testgroup + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_group: managergroup1 + register: result + failed_when: not result.changed + + - name: Ensure membermanager group1 is present for testgroup again + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_group: managergroup1 + register: result + failed_when: result.changed + + - name: Ensure membermanager user2 and group2 members are present for testgroup + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_user: manageruser2 + membermanager_group: managergroup2 + action: member + register: result + failed_when: not result.changed + + - name: Ensure membermanager user2 and group2 members are present for testgroup again + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_user: manageruser2 + membermanager_group: managergroup2 + action: member + register: result + failed_when: result.changed + + - name: Ensure membermanager user and group members are present for testgroup again + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_user: manageruser1,manageruser2 + membermanager_group: managergroup1,managergroup2 + action: member + register: result + failed_when: result.changed + + - name: Ensure membermanager user1 and group1 members are absent for testgroup + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_user: manageruser1 + membermanager_group: managergroup1 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Ensure membermanager user1 and group1 members are absent for testgroup again + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_user: manageruser1 + membermanager_group: managergroup1 + action: member + state: absent + register: result + failed_when: result.changed + + - name: Ensure membermanager user1 and group1 members are present for testgroup + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_user: manageruser1 + membermanager_group: managergroup1 + action: member + register: result + failed_when: not result.changed + + - name: Ensure membermanager user1 and group1 members are present for testgroup again + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_user: manageruser1 + membermanager_group: managergroup1 + action: member + register: result + failed_when: result.changed + + - name: Ensure membermanager user and group members are absent for testgroup + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_user: manageruser1,manageruser2 + membermanager_group: managergroup1,managergroup2 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Ensure membermanager user and group members are absent for testgroup again + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup + membermanager_user: manageruser1,manageruser2 + membermanager_group: managergroup1,managergroup2 + action: member + state: absent + register: result + failed_when: result.changed + + - name: Ensure user manangeruser1 and manageruser2 is absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: manageruser1,manageruser2 + state: absent + register: result + failed_when: not result.changed + + - name: Ensure group testgroup, managergroup1 and managergroup2 are absent + ipagroup: + ipaadmin_password: SomeADMINpassword + name: testgroup,managergroup1,managergroup2 + state: absent + register: result + failed_when: not result.changed -- GitLab