diff --git a/README-permission.md b/README-permission.md index c1cc539ad1c431b7f038f131a2112f2d1a2ea92b..950e6ff06809cea4e441556a3a1414b91c55196e 100644 --- a/README-permission.md +++ b/README-permission.md @@ -161,6 +161,7 @@ Variable | Description | Required -------- | ----------- | -------- `ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no `ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no +`ipaapi_context` | The context in which the module will execute. Executing in a server context is preferred. If not provided context will be determined by the execution environment. Valid values are `server` and `client`. | no `name` \| `cn` | The permission name string. | yes `right` \| `ipapermright` | Rights to grant. It can be a list of one or more of `read`, `search`, `compare`, `write`, `add`, `delete`, and `all` default: `all` | no `attrs` | All attributes to which the permission applies. | no diff --git a/plugins/modules/ipapermission.py b/plugins/modules/ipapermission.py index 2dc6ab1cea590e791aec8669ddb63e6b818da73c..657d934ff7ff1f8f922c806e8f5aed7d77a79273 100644 --- a/plugins/modules/ipapermission.py +++ b/plugins/modules/ipapermission.py @@ -371,6 +371,10 @@ def main(): for _member, _member_change in check_members.items(): if _member_change is not None: _res_list = res_find[_member] + # if running in a client context, data may be + # returned as a tuple instead of a list. + if isinstance(_res_list, tuple): + _res_list = list(_res_list) _new_set = set(_res_list + _member_change) if _new_set != set(_res_list): member_attrs[_member] = list(_new_set) diff --git a/tests/permission/test_permission.yml b/tests/permission/test_permission.yml index b4c04fcdf2e47ba2ff42dab3e015caaff4453e46..d7edc102c0def2e0c99d69ac4a95e022b067e128 100644 --- a/tests/permission/test_permission.yml +++ b/tests/permission/test_permission.yml @@ -1,6 +1,6 @@ --- - name: Test permission - hosts: ipaserver + hosts: "{{ ipa_test_host | default('ipaserver') }}" become: true tasks: @@ -9,6 +9,7 @@ - name: Ensure testing groups are present. ipagroup: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: "{{ item }}" state: present with_items: @@ -20,6 +21,7 @@ - name: Ensure permission perm-test-1 is absent ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: - perm-test-1 - perm-test-bindtype-test @@ -31,6 +33,7 @@ - name: Ensure permission perm-test-1 is present ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 object_type: host memberof: rbacgroup1 @@ -42,6 +45,7 @@ - name: Ensure permission perm-test-1 is present again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 object_type: host memberof: rbacgroup1 @@ -53,6 +57,7 @@ - name: Ensure permission perm-test-1 has an extra filter '(cn=*.internal.*)' ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 filter: '(cn=*.internal.*)' action: member @@ -62,6 +67,7 @@ - name: Ensure permission perm-test-1 has an extra filter '(cn=*.internal.*)', again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 filter: '(cn=*.internal.*)' action: member @@ -71,6 +77,7 @@ - name: Ensure permission perm-test-1 `right` has `write` ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 right: write action: member @@ -80,6 +87,7 @@ - name: Ensure permission perm-test-1 `right` has `write`, again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 right: write action: member @@ -89,6 +97,7 @@ - name: Ensure permission perm-test-1 `right` has no `write` ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 right: write action: member @@ -99,6 +108,7 @@ - name: Ensure permission perm-test-1 `right` has no `write`, again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 right: write action: member @@ -109,6 +119,7 @@ - name: Ensure permission perm-test-1 `memberof` has `rbackgroup2` ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 memberof: rbacgroup2 action: member @@ -118,6 +129,7 @@ - name: Ensure permission perm-test-1 `memberof` has `rbackgroup2`, again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 memberof: rbacgroup2 action: member @@ -127,6 +139,7 @@ - name: Ensure permission perm-test-1 `memberof` item `rbackgroup1` is absent ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 memberof: rbacgroup1 action: member @@ -137,6 +150,7 @@ - name: Ensure permission perm-test-1 `memberof` item `rbackgroup1` is absent, again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 memberof: rbacgroup1 action: member @@ -147,6 +161,7 @@ - name: Ensure permission perm-test-1 is present with attr carlicense ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 attrs: - carlicense @@ -156,6 +171,7 @@ - name: Ensure permission perm-test-1 is present with attr carlicense again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 attrs: - carlicense @@ -165,6 +181,7 @@ - name: Ensure permission perm-test-1 is present with attr carlicense and displayname ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 attrs: - carlicense @@ -175,6 +192,7 @@ - name: Ensure permission perm-test-1 is present with attr carlicense and displayname again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 attrs: - carlicense @@ -185,6 +203,7 @@ - name: Ensure attr gecos is present in permission perm-test-1 ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 attrs: - gecos @@ -195,6 +214,7 @@ - name: Ensure attr gecos is present in permission perm-test-1 again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 attrs: - gecos @@ -205,6 +225,7 @@ - name: Ensure attr gecos is absent in permission perm-test-1 ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 attrs: - gecos @@ -216,6 +237,7 @@ - name: Ensure attr gecos is absent in permission perm-test-1 again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 attrs: - gecos @@ -227,6 +249,7 @@ - name: Ensure attributes carlicense and displayname are present in permission "System{{':'}} Update DNS Entries" ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: "System: Update DNS Entries" attrs: - carlicense @@ -238,6 +261,7 @@ - name: Ensure attributes carlicense and displayname are present in permission "System{{':'}} Update DNS Entries" again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: "System: Update DNS Entries" attrs: - carlicense @@ -249,6 +273,7 @@ - name: Ensure attributes carlicense and displayname are present in permission "System{{':'}} Update DNS Entries" ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: "System: Update DNS Entries" attrs: - carlicense @@ -261,6 +286,7 @@ - name: Ensure attributes carlicense and displayname are present in permission "System{{':'}} Update DNS Entries" again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: "System: Update DNS Entries" attrs: - carlicense @@ -273,6 +299,7 @@ - name: Ensure permission perm-test-1 has rawfilter '(objectclass=ipagroup)' ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 rawfilter: '(objectclass=ipagroup)' action: member @@ -282,6 +309,7 @@ - name: Ensure permission perm-test-1 has rawfilter '(objectclass=ipagroup)', again ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 rawfilter: '(objectclass=ipagroup)' action: member @@ -291,6 +319,7 @@ - name: Ensure filter and rawfilter cannot be used together. ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 rawfilter: '(objectclass=ipagroup)' filter: '(cn=*.internal.*)' @@ -301,6 +330,7 @@ - name: Rename permission perm-test-1 to perm-test-renamed ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 rename: perm-test-renamed state: renamed @@ -310,6 +340,7 @@ - name: Ensure permission perm-test-1 is absent ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-1 state: absent register: result @@ -318,6 +349,7 @@ - name: Ensure permission perm-test-renamed is present ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-renamed object_type: host right: all @@ -327,6 +359,7 @@ - name: Ensure permission with bindtype 'self' is present, if IPA version >= 4.8.7 ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-bindtype-test bindtype: self object_type: host @@ -338,6 +371,7 @@ - name: Fail to set permission perm-test-renamed bindtype to 'self', if IPA version < 4.8.7 ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: perm-test-bindtype-test bindtype: self object_type: host @@ -351,6 +385,7 @@ - name: Ensure testing permissions are absent ipapermission: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: - perm-test-1 - perm-test-bindtype-test @@ -360,6 +395,7 @@ - name: Ensure testing groups are absent. ipagroup: ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" name: "{{ item }}" state: absent with_items: diff --git a/tests/permission/test_permission_client_context.yml b/tests/permission/test_permission_client_context.yml new file mode 100644 index 0000000000000000000000000000000000000000..b351c08651f2edbcdb4ed707d2c8b67d610229c9 --- /dev/null +++ b/tests/permission/test_permission_client_context.yml @@ -0,0 +1,37 @@ +--- +- name: Test permission + hosts: ipaclients, ipaserver + become: no + gather_facts: no + + tasks: + - name: Include FreeIPA facts. + include_tasks: ../env_freeipa_facts.yml + + # Test will only be executed if host is not a server. + - name: Execute with server context in the client. + ipapermission: + ipaadmin_password: SomeADMINpassword + ipaapi_context: server + name: ThisShouldNotWork + register: result + failed_when: not (result.failed and result.msg is regex("No module named '*ipaserver'*")) + when: ipa_host_is_client + +# Import basic module tests, and execute with ipa_context set to 'client'. +# If ipaclients is set, it will be executed using the client, if not, +# ipaserver will be used. +# +# With this setup, tests can be executed against an IPA client, against +# an IPA server using "client" context, and ensure that tests are executed +# in upstream CI. + +- name: Test permission using client context, in client host. + import_playbook: test_permission.yml + when: groups['ipaclients'] + vars: + ipa_test_host: ipaclients + +- name: Test permission using client context, in server host. + import_playbook: test_permission.yml + when: groups['ipaclients'] is not defined or not groups['ipaclients']