diff --git a/README-role.md b/README-role.md index b8e3b655..9d51ec00 100644 --- a/README-role.md +++ b/README-role.md @@ -230,6 +230,8 @@ Example playbook to ensure that different members are not associated with a role - User Administrators service: - service01 + sysaccount: + - my-app action: member state: absent ``` @@ -253,6 +255,7 @@ Variable | Description | Required `host` | List of hosts to be assigned or not assigned to the role. | no `hostgroup` | List of hostgroups to be assigned or not assigned to the role. | no `service` | List of services to be assigned or not assigned to the role. | no +`sysaccount` | List of sysaccounts to be assigned or not assigned to the role. | no `action` | Work on role or member level. It can be on of `member` or `role` and defaults to `role`. | no `state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no @@ -261,3 +264,4 @@ Authors ======= Rafael Jeffman +Thomas Woerner diff --git a/plugins/modules/iparole.py b/plugins/modules/iparole.py index bf449839..09c407ab 100644 --- a/plugins/modules/iparole.py +++ b/plugins/modules/iparole.py @@ -85,6 +85,11 @@ options: type: list elements: str required: false + sysaccount: + description: List of sysaccounts. + type: list + elements: str + required: false action: description: Work on role or member level. type: str @@ -177,7 +182,7 @@ def check_parameters(module): "description", "user", "group", "host", "hostgroup", - "service", + "service", "sysaccount", "privilege", ] @@ -225,7 +230,7 @@ def ensure_absent_state(module, name, action, res_find): {"privilege": del_list}]) member_args = {} - for key in ['user', 'group', 'hostgroup']: + for key in ['user', 'group', 'hostgroup', 'sysaccount']: _members = module.params_get_lowercase(key) if _members: del_list = gen_intersection_list( @@ -335,7 +340,7 @@ def ensure_role_with_members_is_present(module, name, res_find, action): add_members = {} del_members = {} - for key in ["user", "group", "hostgroup"]: + for key in ["user", "group", "hostgroup", "sysaccount"]: _members = module.params_get_lowercase(key) if _members is not None: add_list, del_list = gen_add_del_lists( @@ -437,6 +442,8 @@ def create_module(): default=None), service=dict(required=False, type='list', elements="str", default=None), + sysaccount=dict(required=False, type='list', elements="str", + default=None), # state action=dict(type="str", default="role", @@ -467,8 +474,15 @@ def main(): state = ansible_module.params_get("state") action = ansible_module.params_get("action") names = ansible_module.params_get("name") + sysaccount = ansible_module.params_get("sysaccount") commands = [] + has_sysaccount_member = ansible_module.ipa_command_param_exists( + "role_add_member", "sysaccount") + if not has_sysaccount_member and sysaccount is not None: + ansible_module.fail_json( + msg="sysaccount members are not supported by your IPA version") + for name in names: cmds = role_commands_for_name(ansible_module, state, action, name) commands.extend(cmds) diff --git a/tests/role/test_role_sysaccount_member.yml b/tests/role/test_role_sysaccount_member.yml new file mode 100644 index 00000000..1b415cac --- /dev/null +++ b/tests/role/test_role_sysaccount_member.yml @@ -0,0 +1,161 @@ +--- +- name: Test sysaccount + hosts: "{{ ipa_test_host | default('ipaserver') }}" + # It is normally not needed to set "become" to "true" for a module test. + # Only set it to true if it is needed to execute commands as root. + become: false + # Enable "gather_facts" only if "ansible_facts" variable needs to be used. + gather_facts: false + module_defaults: + ipaprivilege: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + iparole: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + ipasysaccount: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + + tasks: + + - name: Verify if role sysaccount member tests are possible + ansible.builtin.shell: + cmd: | + echo SomeADMINpassword | kinit -c {{ krb5ccname }} admin > /dev/null + RESULT=$(KRB5CCNAME={{ krb5ccname }} ipa role-add-member --help) + kdestroy -A -c {{ krb5ccname }} > /dev/null + echo $RESULT + vars: + krb5ccname: "__check_ipa_role_add_member__" + register: check_role_add_member + + - name: Execute tests + when: '"sysaccounts" in check_role_add_member.stdout' + block: + + # CLEANUP TEST ITEMS + + - name: Ensure sysaccount my-app is absent + ipasysaccount: + name: my-app + state: absent + + - name: Ensure role "my-app role" is absent + iparole: + name: my-app role + state: absent + + - name: Ensure privilege "my-app password change privilege" is absent + ipaprivilege: + name: my-app password change privilege + state: absent + + # CREATE TEST ITEMS + + - name: Ensure privilege "my-app password change privilege" is present + ipaprivilege: + name: my-app password change privilege + permission: + - "System: Change User password" + register: result + failed_when: not result.changed or result.failed + + # TESTS + + - name: Ensure sysaccount my-app is present with random password + ipasysaccount: + name: my-app + random: true + register: result + failed_when: not result.changed or result.failed + + - name: Ensure role "my-app role" is present with sysaccount member my-app + iparole: + name: my-app role + sysaccount: my-app + privilege: my-app password change privilege + register: result + failed_when: not result.changed or result.failed + + - name: Ensure role "my-app role" is present with sysaccount member my-app, again + iparole: + name: my-app role + sysaccount: my-app + privilege: my-app password change privilege + register: result + failed_when: result.changed or result.failed + + - name: Ensure role my-app role does not have sysaccount member my-app + iparole: + name: my-app role + sysaccount: my-app + action: member + state: absent + register: result + failed_when: not result.changed or result.failed + + - name: Ensure role my-app role does not have sysaccount member my-app, again + iparole: + name: my-app role + sysaccount: my-app + action: member + state: absent + register: result + failed_when: result.changed or result.failed + + - name: Ensure role my-app role has sysaccount member my-app + iparole: + name: my-app role + sysaccount: my-app + action: member + register: result + failed_when: not result.changed or result.failed + + - name: Ensure role my-app role has sysaccount member my-app, again + iparole: + name: my-app role + sysaccount: my-app + action: member + register: result + failed_when: result.changed or result.failed + + - name: Ensure role my-app role has zero sysaccount members + iparole: + name: my-app role + sysaccount: [] + register: result + failed_when: not result.changed or result.failed + + - name: Ensure role my-app role has zero sysaccount members, again + iparole: + name: my-app role + sysaccount: [] + register: result + failed_when: result.changed or result.failed + + - name: Ensure role my-app role does not have sysaccount member my-app, again + iparole: + name: my-app role + sysaccount: my-app + action: member + state: absent + register: result + failed_when: result.changed or result.failed + + # CLEANUP TEST ITEMS + + - name: Ensure sysaccount my-app is absent + ipasysaccount: + name: my-app + state: absent + + - name: Ensure role my-app role is absent + iparole: + name: my-app role + state: absent + + - name: Ensure privilege "my-app password change privilege" is absent + ipaprivilege: + name: my-app password change privilege + state: absent