From 94567721d3a0ecef039631d88e2cab366795e579 Mon Sep 17 00:00:00 2001 From: David Kirwan Date: Mar 29 2023 09:33:53 +0000 Subject: Move openshift secret retrieval into seperate task Renamed fasjson tasks/libs to ipa Enabled all the tasks in main.yaml Put library/fas2discourse_sync_group_membership module outline in place Signed-off-by: David Kirwan Signed-off-by: Lenka Segura --- diff --git a/Makefile b/Makefile index 97677e9..6df9c04 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # To re-generate a bundle for another specific version without changing the standard setup, you can: # - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) # - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.0.33 +VERSION ?= 0.0.42 # CHANNELS define the bundle channels used in the bundle. # Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 7285fdf..460b5f9 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -13,4 +13,4 @@ kind: Kustomization images: - name: controller newName: quay.io/fedora/fas2discourse-operator - newTag: v0.0.33 + newTag: v0.0.42 diff --git a/roles/fas2discourseconfig/library/fas2discourse_retrieve_discourse_groups.py b/roles/fas2discourseconfig/library/fas2discourse_retrieve_discourse_groups.py index 094604a..bb6d5fa 100644 --- a/roles/fas2discourseconfig/library/fas2discourse_retrieve_discourse_groups.py +++ b/roles/fas2discourseconfig/library/fas2discourse_retrieve_discourse_groups.py @@ -83,7 +83,7 @@ def run_module(): module_args = dict( discourse_api=dict(type="str", required=True), discourse_host=dict(type="str", required=True), - discourse_ignored_groups=dict(dict="str", required=True), + discourse_ignored_groups=dict(type="list", required=True), ) # seed the result dict in the object @@ -126,7 +126,7 @@ def run_module(): result["discourse_groups"] = discourse_groups result["changed"] = True - result["msg"] = "Successfully retrieved groups and their members from Discourse." + result["message"] = "Successfully retrieved groups and their members from Discourse." except Exception: raise diff --git a/roles/fas2discourseconfig/library/fas2discourse_retrieve_fasjson_data.py b/roles/fas2discourseconfig/library/fas2discourse_retrieve_fasjson_data.py deleted file mode 100644 index 45834d4..0000000 --- a/roles/fas2discourseconfig/library/fas2discourse_retrieve_fasjson_data.py +++ /dev/null @@ -1,191 +0,0 @@ -#!/usr/bin/python - -# Copyright: (c) 2018, Terry Jones -# GNU General Public License v3.0+ (see COPYING or -# https://www.gnu.org/licenses/gpl-3.0.txt) - -import json -import requests - -from ansible.module_utils.basic import AnsibleModule -from ansible.utils.display import Display -from requests_kerberos import HTTPKerberosAuth - -display = Display(verbosity=5) -__metaclass__ = type - -DOCUMENTATION = r""" ---- -module: fas2discourse_retrieve_fasjson_data - -short_description: Retrieve fasjson group and user data. - -version_added: "0.0.1" - -description: This module retrieves fasjson group and users data which match -the groups in discourse. - -options: - keytab_path: - description: This is the location on disk where the kerberos keytab is stored. - required: true - type: str - principal: - description: The is the kerberos principal. - required: true - type: str - discourse_groups: - description: These are the groups retrieved from the discourse. - required: true - type: str - -author: - - David Kirwan (dkirwan@redhat.com) - - Lenka Segura (lsegura@redhat.com) - - Patrik Polakovic (ppolakov@redhat.com) -""" - -EXAMPLES = r""" -- name: Retrieve fasjson group/user data based on the discourse groups - fas2discourse_retrieve_fasjson_data: - keytab_path: "{{ fas2discourse_keytab }}" - principal: "{{ fas2discourse_principal }}" - discourse_groups: "{{ discourse_groups }}" - register: fas2discourse_fasjson_response -""" - -RETURN = r""" -# These are examples of possible return values, and in general should use other names for return -# values. -matched_groups: - description: The groups and their users which match the discourse groups. - type: str - returned: always - sample: -[ - { - "group_name": "yyy", - "group_members": [ - "uuu", - "iii", - "eee", - "zqq" - ] - }, - { - "group_name": "abc", - "group_members": [ - "xyc", - "cyz", - "xxx", - "zzz" - ] - } -] - -msg: - description: The output message that the module generates. - type: str - returned: always - sample: 'Successfully retrieved groups and their users from fasjson.' -""" - - -# Helper function to create the http requests -def get_http_client(keytab_path, principal): - try: - kerberos_auth = HTTPKerberosAuth(principal=principal) - except Exception as e: - print("Error trying to authenticate with Kerberos", e) - raise - session = requests.Session() - session.auth = kerberos_auth - return session - - -# Helper function to retrieve fasjson groups -def get_groups(http_client): - response = http_client.get("https://fasjson.fedoraproject.org/v1/groups/") - display.debug(f"Response from get_groups: {response}, {response.json()}, {response.status_code}") - if response.ok: - return response.json() - - -# Helper function to retrieve fasjson group members -def get_group_members(http_client, groupname): - response = http_client.get( - "%sgroups/%s/members/" % ("https://fasjson.fedoraproject.org/v1/", groupname) - ) - if response.ok: - return response.json() - - -def run_module(): - # define available arguments/parameters a user can pass to the module - module_args = dict( - keytab_path=dict(type="str", required=True), - principal=dict(type="str", required=True), - discourse_groups=dict(type="str", required=True), - ) - - # seed the result dict in the object - # we primarily care about changed and state - # changed is if this module effectively modified the target - # state will include any data that you want your module to pass back - # for consumption, for example, in a subsequent task - result = dict(changed=False, original_message="", message="") - - # the AnsibleModule object will be our abstraction working with Ansible - # this includes instantiation, a couple of common attr would be the - # args/params passed to the execution, as well as if the module - # supports check mode - module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) - - # if the user is working with this module in only check mode we do not - # want to make any changes to the environment, just return the current - # state with no modifications - if module.check_mode: - module.exit_json(**result) - - # manipulate or modify the state as needed (this is going to be the - # part where your module will do what it needs to do) - keytab_path = module.params["keytab_path"] - principal = module.params["principal"] - discourse_groups = module.params["discourse_groups"] - - try: - http_client = get_http_client(keytab_path, principal) - groups_response = get_groups(http_client) - - fas2discourse_groups = [] - for v in groups_response["result"]: - if v["groupname"] in discourse_groups: - group = {"groupname": v["groupname"], "groupmembers": []} - - group_member_res = get_group_members(http_client, v["groupname"]) - # print(json.dumps(group_member_res)) - - for v in group_member_res["result"]: - group["groupmembers"].append(v["username"]) - fas2discourse_groups.append(group) - # print(v["groupname"]) - - # print(json.dumps(fas2discourse_groups)) - - result["matched_groups"] = json.dumps(fas2discourse_groups) - result["changed"] = True - result["msg"] = "Successfully retrieved groups and their users from fasjson." - except Exception: - raise - - # in the event of a successful module execution, you will want to - # simple AnsibleModule.exit_json(), passing the key/value results - module.exit_json(**result) - - -def main(): - run_module() - - -if __name__ == "__main__": - main() diff --git a/roles/fas2discourseconfig/library/fas2discourse_retrieve_ipa_groups.py b/roles/fas2discourseconfig/library/fas2discourse_retrieve_ipa_groups.py new file mode 100644 index 0000000..2d1dd17 --- /dev/null +++ b/roles/fas2discourseconfig/library/fas2discourse_retrieve_ipa_groups.py @@ -0,0 +1,191 @@ +#!/usr/bin/python + +# Copyright: (c) 2018, Terry Jones +# GNU General Public License v3.0+ (see COPYING or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +import json +import requests + +from ansible.module_utils.basic import AnsibleModule +from ansible.utils.display import Display +from requests_kerberos import HTTPKerberosAuth + +display = Display(verbosity=5) +__metaclass__ = type + +DOCUMENTATION = r""" +--- +module: fas2discourse_retrieve_ipa_groups + +short_description: Retrieve fasjson group and user data. + +version_added: "0.0.1" + +description: This module retrieves fasjson group and users data which match +the groups in discourse. + +options: + keytab_path: + description: This is the location on disk where the kerberos keytab is stored. + required: true + type: str + principal: + description: The is the kerberos principal. + required: true + type: str + discourse_groups: + description: These are the groups retrieved from the discourse. + required: true + type: str + +author: + - David Kirwan (dkirwan@redhat.com) + - Lenka Segura (lsegura@redhat.com) + - Patrik Polakovic (ppolakov@redhat.com) +""" + +EXAMPLES = r""" +- name: Retrieve fasjson group/user data based on the discourse groups + fas2discourse_retrieve_ipa_groups: + keytab_path: "{{ fas2discourse_keytab }}" + principal: "{{ fas2discourse_principal }}" + discourse_groups: "{{ discourse_groups }}" + register: fas2discourse_fasjson_response +""" + +RETURN = r""" +# These are examples of possible return values, and in general should use other names for return +# values. +ipa_groups: + description: The groups and their users which match the discourse groups. + type: str + returned: always + sample: +[ + { + "group_name": "yyy", + "group_members": [ + "uuu", + "iii", + "eee", + "zqq" + ] + }, + { + "group_name": "abc", + "group_members": [ + "xyc", + "cyz", + "xxx", + "zzz" + ] + } +] + +msg: + description: The output message that the module generates. + type: str + returned: always + sample: 'Successfully retrieved groups and their users from fasjson.' +""" + + +# Helper function to create the http requests +def get_http_client(keytab_path, principal): + try: + kerberos_auth = HTTPKerberosAuth(principal=principal) + except Exception as e: + print("Error trying to authenticate with Kerberos", e) + raise + session = requests.Session() + session.auth = kerberos_auth + return session + + +# Helper function to retrieve fasjson groups +def get_groups(http_client): + response = http_client.get("https://fasjson.fedoraproject.org/v1/groups/") + display.debug(f"Response from get_groups: {response}, {response.json()}, {response.status_code}") + if response.ok: + return response.json() + + +# Helper function to retrieve fasjson group members +def get_group_members(http_client, groupname): + response = http_client.get( + "%sgroups/%s/members/" % ("https://fasjson.fedoraproject.org/v1/", groupname) + ) + if response.ok: + return response.json() + + +def run_module(): + # define available arguments/parameters a user can pass to the module + module_args = dict( + keytab_path=dict(type="str", required=True), + principal=dict(type="str", required=True), + discourse_groups=dict(type="str", required=True), + ) + + # seed the result dict in the object + # we primarily care about changed and state + # changed is if this module effectively modified the target + # state will include any data that you want your module to pass back + # for consumption, for example, in a subsequent task + result = dict(changed=False, original_message="", message="") + + # the AnsibleModule object will be our abstraction working with Ansible + # this includes instantiation, a couple of common attr would be the + # args/params passed to the execution, as well as if the module + # supports check mode + module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) + + # if the user is working with this module in only check mode we do not + # want to make any changes to the environment, just return the current + # state with no modifications + if module.check_mode: + module.exit_json(**result) + + # manipulate or modify the state as needed (this is going to be the + # part where your module will do what it needs to do) + keytab_path = module.params["keytab_path"] + principal = module.params["principal"] + discourse_groups = module.params["discourse_groups"] + + try: + http_client = get_http_client(keytab_path, principal) + groups_response = get_groups(http_client) + + fas2discourse_groups = [] + for v in groups_response["result"]: + if v["groupname"] in discourse_groups: + group = {"groupname": v["groupname"], "groupmembers": []} + + group_member_res = get_group_members(http_client, v["groupname"]) + # print(json.dumps(group_member_res)) + + for v in group_member_res["result"]: + group["groupmembers"].append(v["username"]) + fas2discourse_groups.append(group) + # print(v["groupname"]) + + # print(json.dumps(fas2discourse_groups)) + + result["ipa_groups"] = fas2discourse_groups + result["changed"] = True + result["message"] = "Successfully retrieved groups and their users from fasjson." + except Exception: + raise + + # in the event of a successful module execution, you will want to + # simple AnsibleModule.exit_json(), passing the key/value results + module.exit_json(**result) + + +def main(): + run_module() + + +if __name__ == "__main__": + main() diff --git a/roles/fas2discourseconfig/library/fas2discourse_sync_group_membership.py b/roles/fas2discourseconfig/library/fas2discourse_sync_group_membership.py new file mode 100644 index 0000000..20dca76 --- /dev/null +++ b/roles/fas2discourseconfig/library/fas2discourse_sync_group_membership.py @@ -0,0 +1,176 @@ +#!/usr/bin/python + +# Copyright: (c) 2018, Terry Jones +# GNU General Public License v3.0+ (see COPYING or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +import json +import requests + +from ansible.module_utils.basic import AnsibleModule +from requests_kerberos import HTTPKerberosAuth + +__metaclass__ = type + +DOCUMENTATION = r""" +--- +module: fas2discourse_sync_group_membership + +short_description: Retrieve discourse groups. + +version_added: "0.0.1" + +description: This module retrieves discourse groups. + +options: + discourse_groups: + description: These are the groups retrieved from the discouse. + required: true + type: str + +author: + - David Kirwan (dkirwan@redhat.com) + - Lenka Segura (lsegura@redhat.com) + - Patrik Polakovic (ppolakov@redhat.com) +""" + +EXAMPLES = r""" +- name: Retrieve discourse groups. + fas2discourse_sync_group_membership: + discourse_api: "{{ discourse_api }}" + discourse_host: "{{ discourse_host }}" + register: fas2discourse_discourse_response +""" + +RETURN = r""" +# These are examples of possible return values, and in general should use other names for return +# values. + +discourse_groups: + description: The Discourse groups. + type: dict + returned: always + sample: '{"groups":[{"id":51,"automatic":false,"name":"community-blog","user_count":2,"mentionable_level":3,"messageable_level":0,"visibility_level":0,"primary_group":false,"title":"","grant_trust_level":1,"flair_url":"https://redhat.discourse-cdn.com/fedoraproject/original/2X/2/28d0975bef06287ee5f04d0a9e576de172103298.png","flair_bg_color":"","flair_color":"","bio_cooked":null,"bio_excerpt":null,"public_admission":false,"public_exit":false,"allow_membership_requests":false,"full_name":"Community Blog Editors","default_notification_level":3,"membership_request_template":null,"members_visibility_level":0,"can_see_members":true,"publish_read_state":false}]}' + +msg: + description: The output message that the module generates. + type: str + returned: always + sample: 'Successfully retrieved groups from Discourse.' +""" + + +def synchronise_group_membership_data(discourse_groups, ipa_groups): + processed_discourse_groups = {} + processed_ipa_groups = {} + add_users = {} + remove_users = {} + + try: + # reformat the data structure to make it easier to handle for set operations. + for i in discourse_groups: + groupname = i["groupname"] + processed_discourse_groups[groupname] = i["groupmembers"] + + for i in ipa_groups: + groupname = i["groupname"] + processed_ipa_groups[groupname] = i["groupmembers"] + + discourse_keys = processed_discourse_groups.keys() + ipa_keys = processed_ipa_groups.keys() + + for i in ipa_keys: + ipa_group_members = set(processed_ipa_groups[i]) + discourse_group_members = set(processed_discourse_groups[i]) + + users_to_remove = discourse_group_members.difference(ipa_group_members) + users_to_add = ipa_group_members.difference(discourse_group_members) + # print("Discourse: %s %s" % (i, discourse_group_members)) + # print("IPA: %s: %s" % (i, ipa_group_members)) + # print("Add to %s: %s " % (i, users_to_add)) + # print("Remove from %s: %s " % (i, users_to_remove)) + + if ipa_group_members == discourse_group_members: + # do nothing + continue + if users_to_add != set(): + # add these users to discourse group i + add_users[i] = list(users_to_add) + if users_to_remove != set(): + # remove these users from discourse group i + remove_users[i] = list(users_to_remove) + + # print("Discourse: ", processed_discourse_groups) + # print("IPA: ", processed_ipa_groups) + # print("Users to add: ", add_users) + # print("Users to remove: ", remove_users) + return add_users, remove_users + except Exception: + raise + + +def synchronise_group_membership_with_discourse(add_users, remove_users): + message = "Success" + + return message + + +def run_module(): + # define available arguments/parameters a user can pass to the module + module_args = dict( + discourse_api=dict(type="str", required=True), + discourse_host=dict(type="str", required=True), + discourse_groups=dict(type="list", required=True), + ipa_groups=dict(type="list", required=True), + ) + + # seed the result dict in the object + # we primarily care about changed and state + # changed is if this module effectively modified the target + # state will include any data that you want your module to pass back + # for consumption, for example, in a subsequent task + result = dict(changed=False, original_message="", message="") + + # the AnsibleModule object will be our abstraction working with Ansible + # this includes instantiation, a couple of common attr would be the + # args/params passed to the execution, as well as if the module + # supports check mode + module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) + + # if the user is working with this module in only check mode we do not + # want to make any changes to the environment, just return the current + # state with no modifications + if module.check_mode: + module.exit_json(**result) + + # manipulate or modify the state as needed (this is going to be the + # part where your module will do what it needs to do) + discourse_api = module.params["discourse_api"] + discourse_host = module.params["discourse_host"] + discourse_groups = module.params["discourse_groups"] + ipa_groups = module.params["ipa_groups"] + + try: + add_users, remove_users = synchronise_group_membership_data( + discourse_groups, ipa_groups + ) + message = synchronise_group_membership_with_discourse(add_users, remove_users) + print(f"BEHOLD! Printing discourse groups: {discourse_groups}") + + result["sync_response"] = {"add_users": add_users, "remove_users": remove_users} + result["changed"] = True + result["message"] = message + except Exception: + raise + + # in the event of a successful module execution, you will want to + # simple AnsibleModule.exit_json(), passing the key/value results + module.exit_json(**result) + + +def main(): + run_module() + + +if __name__ == "__main__": + main() diff --git a/roles/fas2discourseconfig/tasks/main.yml b/roles/fas2discourseconfig/tasks/main.yml index d771f84..abf8604 100644 --- a/roles/fas2discourseconfig/tasks/main.yml +++ b/roles/fas2discourseconfig/tasks/main.yml @@ -1,8 +1,9 @@ --- # tasks file for Fas2discourseConfig -- include_tasks: retrieve_discourse_groups.yml - include_tasks: kerberos_auth.yml +- include_tasks: retrieve_openshift_secrets.yml +- include_tasks: retrieve_discourse_groups.yml - include_tasks: retrieve_ipa_groups.yml -#- include_tasks: sync_group_membership.yml +- include_tasks: sync_group_membership.yml diff --git a/roles/fas2discourseconfig/tasks/retrieve_discourse_groups.yml b/roles/fas2discourseconfig/tasks/retrieve_discourse_groups.yml index 587ca7c..dd0b2d1 100644 --- a/roles/fas2discourseconfig/tasks/retrieve_discourse_groups.yml +++ b/roles/fas2discourseconfig/tasks/retrieve_discourse_groups.yml @@ -1,26 +1,6 @@ --- # tasks file for fas2discourse -- k8s_info: - api_version: v1 - kind: Secret - namespace: "{{ f2d_namespace }}" - name: "{{ f2d_discourse_secret }}" - register: f2d_discourse_secret_yaml - -- name: Prints the secret - ansible.builtin.debug: - msg: - - "{{ f2d_discourse_secret_yaml }}" - -- set_fact: - f2d_discourse_secret: "{{ f2d_discourse_secret_yaml.resources[0] | from_yaml }}" -- set_fact: - discourse_api: "{{ f2d_discourse_secret.data['fas2discourse-discourse-apikey'] | b64decode }}" -- set_fact: - discourse_host: "{{ f2d_discourse_secret.data['fas2discourse-host'] | b64decode }}" - - - name: Retrieve discourse groups fas2discourse_retrieve_discourse_groups: discourse_host: "{{ discourse_host }}" @@ -28,9 +8,6 @@ discourse_ignored_groups: "{{ discourse_ignored_groups }}" register: fas2discourse_retrieve_discourse_groups_response -- set_fact: - discourse_groups: "{{ fas2discourse_retrieve_discourse_groups_response['discourse_groups'] }}" - - name: Prints the groups ansible.builtin.debug: msg: @@ -40,3 +17,6 @@ ansible.builtin.debug: msg: - "{{ fas2discourse_retrieve_discourse_groups_response }}" + +- set_fact: + discourse_groups: "{{ fas2discourse_retrieve_discourse_groups_response['discourse_groups'] }}" diff --git a/roles/fas2discourseconfig/tasks/retrieve_ipa_groups.yml b/roles/fas2discourseconfig/tasks/retrieve_ipa_groups.yml index 9844cc0..a1a2f1e 100644 --- a/roles/fas2discourseconfig/tasks/retrieve_ipa_groups.yml +++ b/roles/fas2discourseconfig/tasks/retrieve_ipa_groups.yml @@ -1,20 +1,27 @@ --- # tasks file for fas2discourse -- name: Retrieve fasjson group/user data based on the discourse group - fas2discourse_retrieve_fasjson_data: +- name: Retrieve ipa group/user data based on the discourse group from fasjson + fas2discourse_retrieve_ipa_groups: keytab_path: "{{ fas2discourse_keytab_path }}" principal: "{{ fas2discourse_principal }}" discourse_groups: "{{ discourse_groups }}" - register: fasjson_response + register: fas2discourse_retrieve_ipa_groups_response environment: KRB5CCNAME: /tmp/ticket -- name: Set fact - set_fact: - fas2discourse_fasjson_response: "{{ fasjson_response }}" - name: Prints the groups ansible.builtin.debug: msg: - - "Groups found: {{ fas2discourse_fasjson_response }}" + - "{{ fas2discourse_retrieve_ipa_groups_response['ipa_groups'] }}" + + +- name: Prints the entire response + ansible.builtin.debug: + msg: + - "{{ fas2discourse_retrieve_ipa_groups_response }}" + +- set_fact: + ipa_groups: "{{ fas2discourse_retrieve_ipa_groups_response['ipa_groups'] }}" + diff --git a/roles/fas2discourseconfig/tasks/retrieve_openshift_secrets.yml b/roles/fas2discourseconfig/tasks/retrieve_openshift_secrets.yml new file mode 100644 index 0000000..e4ea188 --- /dev/null +++ b/roles/fas2discourseconfig/tasks/retrieve_openshift_secrets.yml @@ -0,0 +1,19 @@ +--- +- k8s_info: + api_version: v1 + kind: Secret + namespace: "{{ f2d_namespace }}" + name: "{{ f2d_discourse_secret }}" + register: f2d_discourse_secret_yaml + +- name: Prints the secret + ansible.builtin.debug: + msg: + - "{{ f2d_discourse_secret_yaml }}" + +- set_fact: + f2d_discourse_secret: "{{ f2d_discourse_secret_yaml.resources[0] | from_yaml }}" +- set_fact: + discourse_api: "{{ f2d_discourse_secret.data['fas2discourse-discourse-apikey'] | b64decode }}" +- set_fact: + discourse_host: "{{ f2d_discourse_secret.data['fas2discourse-host'] | b64decode }}" diff --git a/roles/fas2discourseconfig/tasks/sync_group_membership.yml b/roles/fas2discourseconfig/tasks/sync_group_membership.yml index bdc112e..f965516 100644 --- a/roles/fas2discourseconfig/tasks/sync_group_membership.yml +++ b/roles/fas2discourseconfig/tasks/sync_group_membership.yml @@ -1,30 +1,17 @@ --- # tasks file for Fas2Discourse -- k8s_info: - api_version: v1 - kind: Secret - namespace: "{{ f2d_namespace }}" - name: "{{ f2d_secret }}" - register: f2d_secret_yaml - -- set_fact: - cao_secret: "{{ f2d_secret_yaml.resources[0] | from_yaml }}" -- set_fact: - fas2discourse_ocp_api_token: "{{ f2d_secret.data['fas2discourse-ocp-api-token'] | b64decode }}" -- set_fact: - fas2discourse_ocp_api_host: "{{ f2d_secret.data['fas2discourse-ocp-api-host'] | b64decode }}" - - name: Sync user membership between IPA and Discourse Groups # figure out how to do this with discourse - community.okd.k8s: - api_key: "{{ fas2discourse_ocp_api_token }}" - host: "{{ fas2discourse_ocp_api_host }}" - state: present - definition: - apiVersion: user.openshift.io/v1 - kind: Group - metadata: - name: "{{ item['groupname'] }}" - users: "{{ item['groupmembers'] | default([]) }}" - with_items: "{{ fas2discourse_fasjson_response['matched_groups'] }}" + fas2discourse_sync_group_membership: + discourse_host: "{{ discourse_host }}" + discourse_api: "{{ discourse_api }}" + discourse_groups: "{{ discourse_groups }}" + ipa_groups: "{{ ipa_groups }}" + register: fas2discourse_sync_groups_response + + +- name: Prints the fas2discourse_sync_groups_response + ansible.builtin.debug: + msg: + - "{{ fas2discourse_sync_groups_response['sync_response'] }}"