From c4ef216ad5cedc06815e38934a9180ba9f6a205f Mon Sep 17 00:00:00 2001 From: Przemyslaw Kalitowski Date: Sun, 6 Oct 2024 11:47:26 +0200 Subject: [PATCH] feat: support of exporting access list of objects --- .../fiiletree_export_access_list.yml | 4 ++ roles/filetree_create/README.md | 2 + .../tasks/team_access_list.yml | 52 +++++++++++++++ .../tasks/user_access_list.yml | 63 +++++++++++++++++++ .../templates/current_team_access_list.j2 | 29 +++++++++ .../templates/current_user_access_list.j2 | 29 +++++++++ 6 files changed, 179 insertions(+) create mode 100644 changelogs/fragments/fiiletree_export_access_list.yml create mode 100644 roles/filetree_create/tasks/team_access_list.yml create mode 100644 roles/filetree_create/tasks/user_access_list.yml create mode 100644 roles/filetree_create/templates/current_team_access_list.j2 create mode 100644 roles/filetree_create/templates/current_user_access_list.j2 diff --git a/changelogs/fragments/fiiletree_export_access_list.yml b/changelogs/fragments/fiiletree_export_access_list.yml new file mode 100644 index 00000000..84ff6126 --- /dev/null +++ b/changelogs/fragments/fiiletree_export_access_list.yml @@ -0,0 +1,4 @@ +--- +feature_change: + - filetree_create is able to export access list of given object +... diff --git a/roles/filetree_create/README.md b/roles/filetree_create/README.md index 9bca0885..90f673f4 100644 --- a/roles/filetree_create/README.md +++ b/roles/filetree_create/README.md @@ -27,6 +27,8 @@ The following variables are required for that role to work properly: | `organization`| N/A | no | str | Default organization for all objects that have not been set in the source controller.| | `export_related_objects` | False | no | bool | Whether to export related objects (job templates related to certain workflows and the projects associated with these job templates) when a single JT or a single WFJT are being exported. | | `update_project_state` | False | no | bool | Whether the project should be updated after import to the target controller. | +| `object_id` | N/A | no | int | Specifying object id with object type exports the access list of object | +| `object_type` | N/A | no | str | Specifying object type with object id exports the access list of object | ## Dependencies diff --git a/roles/filetree_create/tasks/team_access_list.yml b/roles/filetree_create/tasks/team_access_list.yml new file mode 100644 index 00000000..a38edc20 --- /dev/null +++ b/roles/filetree_create/tasks/team_access_list.yml @@ -0,0 +1,52 @@ +--- +- name: "Get access list for object from the API" + ansible.builtin.set_fact: + access_lookvar: "{{ query(controller_api_plugin, 'api/v2/{{ object_type }}/{{ object_id }}/access_list', + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) + }}" + no_log: "{{ controller_configuration_filetree_create_secure_logging }}" + +- name: "Set team direct access fact" + ansible.builtin.set_fact: + team_direct_access_fact: "{{ access_lookvar | map(attribute='summary_fields.direct_access') | flatten | map(attribute='role') | selectattr('team_name', 'defined') }}" + +- name: "Set roles and object lists" + ansible.builtin.set_fact: + team_roles: "{{ team_direct_access_fact | map(attribute='name') | unique }}" + team_objects: "{{ team_direct_access_fact | map(attribute='resource_name') | unique }}" + +- name: "Set team roles matrix" + ansible.builtin.set_fact: + team_roles_matrix: >- + {{ team_roles_matrix | default([]) + [{ 'role': item.0, + 'team': team_direct_access_fact | selectattr('name','equalto', item.0) | + selectattr('resource_name','equalto', item.1) | + map(attribute='team_name') | unique, + 'resource_type': team_direct_access_fact | selectattr('name','equalto', item.0) | + selectattr('resource_name','equalto', item.1) | + map(attribute='resource_type') | unique, + 'resource_name': item.1 + }] + }} + when: team_direct_access_fact | selectattr('name','equalto', item.0) | selectattr('resource_name','equalto', item.1) | map(attribute='team_name') | length > 0 + loop: "{{ team_roles | product(team_objects) | list }}" + +- name: "Create the output directory for team roles" + ansible.builtin.file: + path: "{{ output_path }}/team_roles" + state: directory + mode: '0755' + loop: "{{ team_roles_matrix }}" + loop_control: + loop_var: team_role + +- name: "Add current roles to the output yaml file" + ansible.builtin.template: + src: "templates/current_team_access_list.j2" + dest: "{{ output_path }}/team_roles/{{ team_role.resource_name | default('current') }}_roles_{{ team_role.role | regex_replace('/', '_') }}.yaml" + mode: '0644' + loop: "{{ team_roles_matrix }}" + loop_control: + loop_var: team_role +... diff --git a/roles/filetree_create/tasks/user_access_list.yml b/roles/filetree_create/tasks/user_access_list.yml new file mode 100644 index 00000000..fa3e94b5 --- /dev/null +++ b/roles/filetree_create/tasks/user_access_list.yml @@ -0,0 +1,63 @@ +--- +- name: "Get access list for object from the API" + ansible.builtin.set_fact: + access_lookvar: "{{ query(controller_api_plugin, 'api/v2/{{ object_type }}/{{ object_id }}/access_list', + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) + }}" + no_log: "{{ controller_configuration_filetree_create_secure_logging }}" + +- name: "Get user list" + ansible.builtin.set_fact: + user_list: "{{ access_lookvar | selectattr('username', 'defined') | map(attribute='username') | unique }}" + +- name: "Set direct user access fact" + ansible.builtin.set_fact: + user_direct_access_fact: >- + {{ user_direct_access_fact | default([]) + access_lookvar | selectattr('username', 'equalto', item) | + rejectattr('summary_fields.direct_access', 'equalto', []) | + map(attribute='summary_fields.direct_access') | flatten | + map(attribute='role') | + rejectattr('team_name', 'defined') | + map('combine', {'username': item}) + }} + loop: "{{ user_list }}" + +- name: "Set roles and object lists" + ansible.builtin.set_fact: + user_roles: "{{ user_direct_access_fact | map(attribute='name') | unique }}" + user_objects: "{{ user_direct_access_fact | map(attribute='resource_name') | unique }}" + +- name: "Set user roles matrix" + ansible.builtin.set_fact: + user_roles_matrix: >- + {{ user_roles_matrix | default([]) + [{ 'role': item.0, + 'user': user_direct_access_fact | selectattr('name','equalto', item.0) | selectattr('resource_name','equalto', item.1) | + map(attribute='username') | unique, + 'resource_type': user_direct_access_fact | selectattr('username', 'defined') | + selectattr('name','equalto', item.0) | selectattr('resource_name','equalto', item.1) | + map(attribute='resource_type') | unique, + 'resource_name': item.1 + }] + }} + when: user_direct_access_fact | selectattr('name','equalto', item.0) | selectattr('resource_name','equalto', item.1) | map(attribute='username') | length > 0 + loop: "{{ user_roles | product(user_objects) | list }}" + +- name: "Create the output directory for user roles" + ansible.builtin.file: + path: "{{ output_path }}/user_roles" + state: directory + mode: '0755' + loop: "{{ user_roles_matrix }}" + loop_control: + loop_var: user_role + +- name: "Add current roles to the output yaml file" + ansible.builtin.template: + src: "templates/current_user_access_list.j2" + dest: "{{ output_path }}/user_roles/{{ user_role.resource_name | default('current') }}_roles_{{ user_role.role | regex_replace('/', '_') }}.yaml" + mode: '0644' + loop: "{{ user_roles_matrix }}" + loop_control: + loop_var: user_role +... diff --git a/roles/filetree_create/templates/current_team_access_list.j2 b/roles/filetree_create/templates/current_team_access_list.j2 new file mode 100644 index 00000000..905f5c5a --- /dev/null +++ b/roles/filetree_create/templates/current_team_access_list.j2 @@ -0,0 +1,29 @@ +{% if first_team_role | default(true) | bool %} +--- +controller_roles: +{% endif %} + teams: +{% for team in team_role.team %} + - "{{ team }}" +{% endfor %} +{% if team_role.resource_type[0] is match('organization') %} + organizations: + - "{{ team_role.resource_name }}" +{% elif team_role.resource_type[0] is match('team') %} + target_teams: + - "{{ team_role.resource_name }}" +{% elif team_role.resource_type[0] is match('job_template') %} + job_template: "{{ team_role.resource_name }}" +{% elif team_role.resource_type[0] is match('inventory') %} + inventory: "{{ team_role.resource_name }}" +{% elif team_role.resource_type[0] is match('workflow_job_template') %} + workflow: "{{ team_role.resource_name }}" +{% elif team_role.resource_type[0] is match('project') %} + project: "{{ team_role.resource_name }}" +{% elif team_role.resource_type[0] is match('credential') %} + credential: "{{ team_role.resource_name }}" +{% endif %} + role: "{% if team_role.role | lower == 'approve' %}approval{% else %}{{ team_role.role | lower | regex_replace(' ', '_') }}{% endif %}" +{% if last_team_role | default(true) | bool %} +... +{% endif %} diff --git a/roles/filetree_create/templates/current_user_access_list.j2 b/roles/filetree_create/templates/current_user_access_list.j2 new file mode 100644 index 00000000..61eaf89f --- /dev/null +++ b/roles/filetree_create/templates/current_user_access_list.j2 @@ -0,0 +1,29 @@ +{% if first_user_role | default(true) | bool %} +--- +controller_roles: +{% endif %} + users: +{% for user in user_role.user %} + - "{{ user }}" +{% endfor %} +{% if user_role.resource_type[0] is match('organization') %} + organizations: + - "{{ user_role.resource_name }}" +{% elif user_role.resource_type[0] is match('user') %} + target_users: + - "{{ user_role.resource_name }}" +{% elif user_role.resource_type[0] is match('job_template') %} + job_template: "{{ user_role.resource_name }}" +{% elif user_role.resource_type[0] is match('inventory') %} + inventory: "{{ user_role.resource_name }}" +{% elif user_role.resource_type[0] is match('workflow_job_template') %} + workflow: "{{ user_role.resource_name }}" +{% elif user_role.resource_type[0] is match('project') %} + project: "{{ user_role.resource_name }}" +{% elif user_role.resource_type[0] is match('credential') %} + credential: "{{ user_role.resource_name }}" +{% endif %} + role: "{% if user_role.role | lower == 'approve' %}approval{% else %}{{ user_role.role | lower | regex_replace(' ', '_') }}{% endif %}" +{% if last_user_role | default(true) | bool %} +... +{% endif %}