From 0a838919c57ac6d9ebd34de2ec0e1b3534940e49 Mon Sep 17 00:00:00 2001 From: ivarmu <26822043+ivarmu@users.noreply.github.com> Date: Mon, 6 Nov 2023 17:46:51 +0100 Subject: [PATCH 1/8] playbook to convert from filetree_create to flat files. job_templates, teams and team_roles to direct flat output --- playbooks/flatten_filetree_create_output.yaml | 85 +++++++++++++ roles/filetree_create/tasks/job_templates.yml | 120 ++++++++++++------ roles/filetree_create/tasks/team_roles.yml | 52 ++++++-- roles/filetree_create/tasks/teams.yml | 85 +++++++++---- .../templates/current_job_templates.j2 | 13 +- .../templates/current_team_roles.j2 | 4 + .../templates/current_teams.j2 | 4 + 7 files changed, 281 insertions(+), 82 deletions(-) create mode 100644 playbooks/flatten_filetree_create_output.yaml diff --git a/playbooks/flatten_filetree_create_output.yaml b/playbooks/flatten_filetree_create_output.yaml new file mode 100644 index 000000000..a72fb663f --- /dev/null +++ b/playbooks/flatten_filetree_create_output.yaml @@ -0,0 +1,85 @@ +- name: "Flatten the filetree_create output into unique files per each object type" + hosts: localhost + connection: local + gather_facts: false + vars: + filetree_controller_settings: &filetree_create_output_dir "{{ filetree_create_output_dir }}" + filetree_controller_organizations: *filetree_create_output_dir + filetree_controller_labels: *filetree_create_output_dir + filetree_controller_user_accounts: *filetree_create_output_dir + filetree_controller_teams: *filetree_create_output_dir + filetree_controller_credential_types: *filetree_create_output_dir + filetree_controller_credentials: *filetree_create_output_dir + filetree_controller_credential_input_sources: *filetree_create_output_dir + filetree_controller_notifications: *filetree_create_output_dir + filetree_controller_projects: *filetree_create_output_dir + filetree_controller_execution_environments: *filetree_create_output_dir + filetree_controller_applications: *filetree_create_output_dir + filetree_controller_inventories: *filetree_create_output_dir + filetree_controller_inventory_sources: *filetree_create_output_dir + filetree_controller_instance_groups: *filetree_create_output_dir + filetree_controller_hosts: *filetree_create_output_dir + filetree_controller_groups: *filetree_create_output_dir + filetree_controller_templates: *filetree_create_output_dir + filetree_controller_workflow_job_templates: *filetree_create_output_dir + filetree_controller_schedules: *filetree_create_output_dir + filetree_controller_roles: *filetree_create_output_dir + roles: + - infra.controller_configuration.filetree_read + post_tasks: + - name: "Create the output flatten dir" + ansible.builtin.file: + path: "{{ filetree_create_output_dir }}_flatten" + state: directory + + - name: "Write all the objects to the corresponding file" + ansible.builtin.copy: + dest: "{{ filetree_create_output_dir }}_flatten/{{ item.name }}.yaml" + content: | + --- + {{ item.value | to_nice_yaml(indent=2) }} + ... + loop: + - name: controller_settings + value: "{{ controller_settings }}" + - name: controller_organizations + value: "{{ controller_organizations }}" + - name: controller_labels + value: "{{ controller_labels }}" + - name: controller_user_accounts + value: "{{ controller_user_accounts }}" + - name: controller_teams + value: "{{ controller_teams }}" + - name: controller_credential_types + value: "{{ controller_credential_types }}" + - name: controller_credentials + value: "{{ controller_credentials }}" + - name: controller_credential_input_sources + value: "{{ controller_credential_input_sources }}" + - name: controller_notifications + value: "{{ controller_notifications }}" + - name: controller_projects + value: "{{ controller_projects }}" + - name: controller_execution_environments + value: "{{ controller_execution_environments }}" + - name: controller_applications + value: "{{ controller_applications }}" + - name: controller_inventories + value: "{{ controller_inventories }}" + - name: controller_inventory_sources + value: "{{ controller_inventory_sources }}" + - name: controller_instance_groups + value: "{{ controller_instance_groups }}" + - name: controller_hosts + value: "{{ controller_hosts }}" + - name: controller_groups + value: "{{ controller_groups }}" + - name: controller_templates + value: "{{ controller_templates }}" + - name: controller_workflow_job_templates + value: "{{ controller_workflow_job_templates | default([]) }}" + - name: controller_schedules + value: "{{ controller_schedules }}" + - name: controller_roles + value: "{{ controller_roles }}" +... diff --git a/roles/filetree_create/tasks/job_templates.yml b/roles/filetree_create/tasks/job_templates.yml index 3a5125052..191c37f8a 100644 --- a/roles/filetree_create/tasks/job_templates.yml +++ b/roles/filetree_create/tasks/job_templates.yml @@ -11,45 +11,85 @@ order_by: 'organization,id' no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the output directories for job templates in {{ output_path }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' - vars: - __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/job_templates" - loop: "{{ (job_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) - + (['ORGANIZATIONLESS'] if ((job_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) - }}" - loop_control: - loop_var: needed_path - label: "{{ __path }}" +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool + block: + - name: "Add current job_templates to the job_templates flat file" + blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_job_templates.j2') }}" + vars: + job_template_organization: "{{ current_job_templates_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + job_template_id: "{{ current_job_templates_asset_value.id }}" + job_template_name: "{{ current_job_templates_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/job_templates.yaml" + query_labels: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.labels, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_error: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.notification_templates_error, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_started: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.notification_templates_started, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_success: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.notification_templates_success, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + last_job_template: "{{ current_job_template_index == ((job_templates_lookvar | length) - 1) }}" + loop: "{{ job_templates_lookvar }}" + loop_control: + index_var: current_job_template_index + loop_var: current_job_templates_asset_value + label: "{{ __dest }}" + no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Add current job_templates to the /job_templates output file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_job_templates.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - job_template_organization: "{{ current_job_templates_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" - job_template_id: "{{ current_job_templates_asset_value.id }}" - job_template_name: "{{ current_job_templates_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/{{ job_template_organization | regex_replace('/', '_') }}/job_templates/{{ job_template_id }}_{{ job_template_name | regex_replace('/', '_') }}.yaml" - query_labels: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.labels, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_error: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.notification_templates_error, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_started: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.notification_templates_started, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_success: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.notification_templates_success, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - loop: "{{ job_templates_lookvar }}" - loop_control: - loop_var: current_job_templates_asset_value - label: "{{ __dest }}" - no_log: "{{ controller_configuration_filetree_create_secure_logging }}" +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the output directories for job templates in {{ output_path }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/job_templates" + loop: "{{ (job_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) + + (['ORGANIZATIONLESS'] if ((job_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) + }}" + loop_control: + loop_var: needed_path + label: "{{ __path }}" + + - name: "Add current job_templates to the /job_templates output file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_job_templates.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + job_template_organization: "{{ current_job_templates_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + job_template_id: "{{ current_job_templates_asset_value.id }}" + job_template_name: "{{ current_job_templates_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/{{ job_template_organization | regex_replace('/', '_') }}/job_templates/{{ job_template_id }}_{{ job_template_name | regex_replace('/', '_') }}.yaml" + query_labels: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.labels, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_error: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.notification_templates_error, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_started: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.notification_templates_started, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_success: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.notification_templates_success, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + loop: "{{ job_templates_lookvar }}" + loop_control: + loop_var: current_job_templates_asset_value + label: "{{ __dest }}" + no_log: "{{ controller_configuration_filetree_create_secure_logging }}" ... diff --git a/roles/filetree_create/tasks/team_roles.yml b/roles/filetree_create/tasks/team_roles.yml index 1db22c86d..afb5764b6 100644 --- a/roles/filetree_create/tasks/team_roles.yml +++ b/roles/filetree_create/tasks/team_roles.yml @@ -7,18 +7,44 @@ }}" no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the output directory for team roles: {{ output_path }}" - ansible.builtin.file: - path: "{{ output_path }}/team_roles" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool + block: + - name: "Stat if the output file exists" + ansible.builtin.stat: + path: "{{ output_path }}/team_roles.yaml" + register: team_roles_file -- name: "Add current roles to the output yaml file" - ansible.builtin.template: - src: "templates/current_team_roles.j2" - dest: "{{ output_path }}/team_roles/current_roles_{{ teamname | regex_replace('/', '_') }}.yaml" - mode: '0644' - vars: - current_team_roles_asset_value: "{{ team_roles_lookvar }}" - when: team_roles_lookvar | length > 0 + - name: "Add current team roles to the team roles flat file" + blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_team_roles.j2') }}" + vars: + current_team_roles_asset_value: "{{ team_roles_lookvar }}" + __dest: "{{ output_path }}/team_roles.yaml" + first_team_role: "{{ not team_roles_file.stat.exists }}" + when: team_roles_lookvar | length > 0 + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the output directory for team roles: {{ output_path }}" + ansible.builtin.file: + path: "{{ output_path }}/team_roles" + state: directory + mode: '0755' + + - name: "Add current roles to the output yaml file" + ansible.builtin.template: + src: "templates/current_team_roles.j2" + dest: "{{ output_path }}/team_roles/current_roles_{{ teamname | regex_replace('/', '_') }}.yaml" + mode: '0644' + vars: + current_team_roles_asset_value: "{{ team_roles_lookvar }}" + when: team_roles_lookvar | length > 0 ... diff --git a/roles/filetree_create/tasks/teams.yml b/roles/filetree_create/tasks/teams.yml index 4435aa571..fb7324d88 100644 --- a/roles/filetree_create/tasks/teams.yml +++ b/roles/filetree_create/tasks/teams.yml @@ -11,42 +11,71 @@ order_by: 'organization,id' no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the /teams output directory for teams in {{ output_path }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' - vars: - __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/teams" - loop: "{{ (teams_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) - + (['ORGANIZATIONLESS'] if ((teams_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) - }}" - loop_control: - loop_var: needed_path - label: "{{ __path }}" +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool + block: + - name: "Add current teams to the teams flat file" + blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_teams.j2') }}" + vars: + team_organization: "{{ (current_teams_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true)) | regex_replace('/', '_') }}" + team_id: "{{ current_teams_asset_value.id }}" + team_name: "{{ current_teams_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/teams.yaml" + last_team: "{{ current_team_index == ((teams_lookvar | length) - 1) }}" + loop: "{{ teams_lookvar }}" + loop_control: + index_var: current_team_index + loop_var: current_teams_asset_value + label: "{{ __dest }}" -- name: "Add current teams to the /teams output file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_teams.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - team_organization: "{{ (current_teams_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true)) | regex_replace('/', '_') }}" - team_id: "{{ current_teams_asset_value.id }}" - team_name: "{{ current_teams_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/{{ team_organization | regex_replace('/', '_') }}/teams/{{ team_id }}_{{ team_name | regex_replace('/', '_') }}.yaml" - loop: "{{ teams_lookvar }}" - loop_control: - loop_var: current_teams_asset_value - label: "{{ __dest }}" +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the /teams output directory for teams in {{ output_path }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/teams" + loop: "{{ (teams_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) + + (['ORGANIZATIONLESS'] if ((teams_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) + }}" + loop_control: + loop_var: needed_path + label: "{{ __path }}" + + - name: "Add current teams to the /teams output file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_teams.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + team_organization: "{{ (current_teams_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true)) | regex_replace('/', '_') }}" + team_id: "{{ current_teams_asset_value.id }}" + team_name: "{{ current_teams_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/{{ team_organization | regex_replace('/', '_') }}/teams/{{ team_id }}_{{ team_name | regex_replace('/', '_') }}.yaml" + loop: "{{ teams_lookvar }}" + loop_control: + loop_var: current_teams_asset_value + label: "{{ __dest }}" - name: "Set the team's roles" ansible.builtin.include_tasks: "team_roles.yml" vars: - team_organization: "{{ (current_teams_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true)) | regex_replace('/', '_') }}" + team_organization: "{{ (current_team.summary_fields.organization.name | default('ORGANIZATIONLESS', true)) | regex_replace('/', '_') }}" teamname: "{{ current_team.name }}" teamid: "{{ current_team.id }}" + last_team_role: "{{ current_team_index_for_roles == ((teams_lookvar | length) - 1) }}" loop: "{{ teams_lookvar }}" loop_control: + index_var: current_team_index_for_roles loop_var: current_team ... diff --git a/roles/filetree_create/templates/current_job_templates.j2 b/roles/filetree_create/templates/current_job_templates.j2 index a5e848b41..031eb5b41 100644 --- a/roles/filetree_create/templates/current_job_templates.j2 +++ b/roles/filetree_create/templates/current_job_templates.j2 @@ -1,5 +1,7 @@ +{%- if current_job_template_index == 0 -%} --- controller_templates: +{% endif %} - name: "{{ current_job_templates_asset_value.name }}" description: "{{ current_job_templates_asset_value.description }}" organization: "{{ current_job_templates_asset_value.summary_fields.organization.name | default('ToDo: The job template \'' + current_job_templates_asset_value.name + '\' must belong to an organization') }}" @@ -91,7 +93,14 @@ controller_templates: {% endfor %} {% endif %} survey_enabled: {{ current_job_templates_asset_value.survey_enabled | bool }} - survey_spec: {{ query(controller_api_plugin, current_job_templates_asset_value.related.survey_spec, host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs)[0] }} +{% set survey_spec_contents = query(controller_api_plugin, current_job_templates_asset_value.related.survey_spec, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs)[0] | + from_yaml | to_nice_yaml(indent=2,width=500) | regex_replace("\n\n[ ]*", "\\\\n") | indent(width=6, first=False) | replace("'{{", "!unsafe \'{{") | replace("^$", "") +-%} +{% if current_job_templates_asset_value.related.survey_spec is defined and survey_spec_contents | length > 3 %} + survey_spec: + {{ survey_spec_contents }} +{% endif %} become_enabled: {{ current_job_templates_asset_value.become_enabled | bool }} diff_mode: {{ current_job_templates_asset_value.diff_mode | bool }} webhook_service: "{{ current_job_templates_asset_value.webhook_service }}" @@ -101,4 +110,6 @@ controller_templates: {% if current_job_templates_asset_value.prevent_instance_group_fallback is defined %} prevent_instance_group_fallback: {{ current_job_templates_asset_value.prevent_instance_group_fallback | bool }} {% endif %} +{% if last_job_template | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_team_roles.j2 b/roles/filetree_create/templates/current_team_roles.j2 index 61dda0ae9..1ba33d0c0 100644 --- a/roles/filetree_create/templates/current_team_roles.j2 +++ b/roles/filetree_create/templates/current_team_roles.j2 @@ -1,5 +1,7 @@ +{% if first_team_role | bool %} --- controller_roles: +{% endif %} {% for role in team_roles_lookvar %} {% if role.summary_fields.resource_type is defined %} - team: "{{ teamname }}" @@ -23,4 +25,6 @@ controller_roles: role: "{{ role.name | lower }}" {% endif %} {% endfor %} +{% if last_team_role | bool %} ... +{%- endif -%} diff --git a/roles/filetree_create/templates/current_teams.j2 b/roles/filetree_create/templates/current_teams.j2 index d8f471e24..eafa0f076 100644 --- a/roles/filetree_create/templates/current_teams.j2 +++ b/roles/filetree_create/templates/current_teams.j2 @@ -1,6 +1,10 @@ +{%- if current_team_index == 0 -%} --- controller_teams: +{% endif %} - name: "{{ current_teams_asset_value.name }}" description: "{{ current_teams_asset_value.description }}" organization: "{{ current_teams_asset_value.summary_fields.organization.name }}" +{% if last_team | bool %} ... +{% endif %} From 2f79c153bcdfb18071aecdad1e5fe3c0a42f943b Mon Sep 17 00:00:00 2001 From: ivarmu <26822043+ivarmu@users.noreply.github.com> Date: Tue, 7 Nov 2023 17:22:19 +0100 Subject: [PATCH 2/8] all the objects has been updated to let flatten output --- .../filtree_create_flatten_output.yml | 4 + roles/filetree_create/README.md | 1 + roles/filetree_create/tasks/applications.yml | 86 +++++++---- .../tasks/constructed_inventory.yml | 98 +++++++++---- roles/filetree_create/tasks/credentials.yml | 86 +++++++---- roles/filetree_create/tasks/groups.yml | 46 ++++-- roles/filetree_create/tasks/hosts.yml | 46 ++++-- roles/filetree_create/tasks/inventory.yml | 125 ++++++++++++---- .../tasks/inventory_sources.yml | 48 +++++-- roles/filetree_create/tasks/job_templates.yml | 11 +- roles/filetree_create/tasks/labels.yml | 86 +++++++---- .../tasks/notification_templates.yml | 77 +++++++--- roles/filetree_create/tasks/organizations.yml | 112 ++++++++++----- roles/filetree_create/tasks/projects.yml | 116 ++++++++++----- roles/filetree_create/tasks/schedules.yml | 96 +++++++++---- roles/filetree_create/tasks/team_roles.yml | 13 +- roles/filetree_create/tasks/teams.yml | 11 +- roles/filetree_create/tasks/user_roles.yml | 59 ++++++-- roles/filetree_create/tasks/users.yml | 83 +++++++---- .../tasks/workflow_job_templates.yml | 134 ++++++++++++------ .../templates/current_applications.j2 | 4 + .../templates/current_credentials.j2 | 6 + .../templates/current_groups.j2 | 4 + .../templates/current_hosts.j2 | 4 + .../templates/current_inventories.j2 | 4 + .../templates/current_inventory_sources.j2 | 4 + .../templates/current_job_templates.j2 | 6 +- .../templates/current_labels.j2 | 4 + .../current_notification_templates.j2 | 4 + .../templates/current_organizations.j2 | 4 + .../templates/current_projects.j2 | 4 + .../templates/current_schedules.j2 | 4 + .../templates/current_team_roles.j2 | 6 +- .../templates/current_teams.j2 | 4 +- .../templates/current_user_roles.j2 | 4 + .../templates/current_users.j2 | 4 + .../current_workflow_job_templates.j2 | 16 ++- 37 files changed, 1038 insertions(+), 386 deletions(-) create mode 100644 changelogs/fragments/filtree_create_flatten_output.yml diff --git a/changelogs/fragments/filtree_create_flatten_output.yml b/changelogs/fragments/filtree_create_flatten_output.yml new file mode 100644 index 000000000..99529272f --- /dev/null +++ b/changelogs/fragments/filtree_create_flatten_output.yml @@ -0,0 +1,4 @@ +--- +minor_changes: + - The role 'filetree_create' will now allow to export all the objects of one kind into a single file, so it can be loaded by both ansible `group_vars` syntax and `filetree_read` tool. +... diff --git a/roles/filetree_create/README.md b/roles/filetree_create/README.md index cfc66f5e9..98e3f2199 100644 --- a/roles/filetree_create/README.md +++ b/roles/filetree_create/README.md @@ -19,6 +19,7 @@ The following variables are required for that role to work properly: | `organization_id` | N/A | no | int | Alternative to `organization_filter`, but specifiying the current organization's ID to filter by. Exports only the objects belonging to the specified organization (applies to all the objects that can be assigned to an organization). | | `output_path` | `/tmp/filetree_output` | yes | str | The path to the output directory where all the generated `yaml` files with the corresponding Objects as code will be written to. | | `input_tag` | `['all']` | no | List of Strings | The tags which are applied to the 'sub-roles'. If 'all' is in the list (the default value) then all roles will be called. | +| `flatten_output` | N/A | no | bool | Whether to flatten the output in single files per each object type instead of the normal exportation structure | ## Dependencies diff --git a/roles/filetree_create/tasks/applications.yml b/roles/filetree_create/tasks/applications.yml index 5fbcaf85d..df7eb9cbd 100644 --- a/roles/filetree_create/tasks/applications.yml +++ b/roles/filetree_create/tasks/applications.yml @@ -11,32 +11,66 @@ order_by: 'organization,id' no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the /applications output directory for applications in {{ output_path }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/applications" - loop: "{{ (applications_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) - + (['ORGANIZATIONLESS'] if ((applications_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) - }}" - loop_control: - loop_var: needed_path - label: "{{ __path }}" + __dest: "{{ output_path }}/applications.yaml" + block: + - name: "Add current applications to the applications flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_applications.j2') }}" + vars: + application_organization: "{{ current_applications_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true) }}" + application_id: "{{ current_applications_asset_value.id }}" + application_name: "{{ current_applications_asset_value.name | regex_replace('/', '_') }}" + last_application: "{{ current_application_index == ((applications_lookvar | length) - 1) }}" + loop: "{{ applications_lookvar }}" + loop_control: + index_var: current_application_index + loop_var: current_applications_asset_value + label: "{{ __dest }}" -- name: "Add current applications to the /applications output file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_applications.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - application_organization: "{{ current_applications_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true) }}" - application_id: "{{ current_applications_asset_value.id }}" - application_name: "{{ current_applications_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/{{ application_organization | regex_replace('/', '_') }}/applications/{{ application_id }}_{{ application_name | regex_replace('/', '_') }}.yaml" - loop: "{{ applications_lookvar }}" - loop_control: - loop_var: current_applications_asset_value - label: "{{ __dest }}" + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the /applications output directory for applications in {{ output_path }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/applications" + loop: "{{ (applications_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) + + (['ORGANIZATIONLESS'] if ((applications_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) + }}" + loop_control: + loop_var: needed_path + label: "{{ __path }}" + + - name: "Add current applications to the /applications output file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_applications.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + application_organization: "{{ current_applications_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true) }}" + application_id: "{{ current_applications_asset_value.id }}" + application_name: "{{ current_applications_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/{{ application_organization | regex_replace('/', '_') }}/applications/{{ application_id }}_{{ application_name | regex_replace('/', '_') }}.yaml" + loop: "{{ applications_lookvar }}" + loop_control: + loop_var: current_applications_asset_value + label: "{{ __dest }}" ... diff --git a/roles/filetree_create/tasks/constructed_inventory.yml b/roles/filetree_create/tasks/constructed_inventory.yml index 1b35fa374..dc1a2fbaf 100644 --- a/roles/filetree_create/tasks/constructed_inventory.yml +++ b/roles/filetree_create/tasks/constructed_inventory.yml @@ -1,5 +1,5 @@ --- -- name: "Get the inventories from the API" +- name: "Get the constructed inventories from the API" ansible.builtin.set_fact: constructed_inventory_lookvar: "{{ query(controller_api_plugin, 'api/v2/constructed_inventories/', query_params=(query_params | combine({'organization': organization_id})) if organization_id is defined else query_params, @@ -11,31 +11,77 @@ order_by: 'organization,id' no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the /inventories output directory for inventories in {{ output_path }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - inventory_organization: "{{ needed_path.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" - inventory_name: "{{ needed_path.name | regex_replace('/', '_') }}" - __path: "{{ output_path }}/{{ inventory_organization | regex_replace('/', '_') }}/inventories/{{ inventory_name | regex_replace('/', '_') }}" - loop: "{{ constructed_inventory_lookvar }}" - loop_control: - loop_var: needed_path - label: "{{ __path }}" + __dest: "{{ output_path }}/inventories.yaml" + block: + - name: "Stat if the output file exists" + ansible.builtin.stat: + path: "{{ __dest }}" + register: __constructed_inventories_file -- name: "Add current constructed_inventories to the /inventories output yaml file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_inventories.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - inventory_organization: "{{ current_inventories_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" - inventory_name: "{{ current_inventories_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/{{ inventory_organization | regex_replace('/', '_') }}/inventories/{{ inventory_name | regex_replace('/', '_') }}/{{ current_inventories_asset_value.id }}_{{ inventory_name | regex_replace('/', '_') }}.yaml" - loop: "{{ constructed_inventory_lookvar }}" - loop_control: - loop_var: current_inventories_asset_value - label: "{{ __dest }}" + - name: "Remove the yaml finalizer if it's already present" + lineinfile: + path: "{{ __dest }}" + line: "..." + state: absent + when: __constructed_inventories_file.stat.exists | bool + + - name: "Add current constructed inventory to the inventories flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_inventories.j2') }}" + vars: + inventory_organization: "{{ current_inventories_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + inventory_name: "{{ current_inventories_asset_value.name | regex_replace('/', '_') }}" + first_inventory: "{{ not (__constructed_inventories_file.stat.exists | bool) }}" + last_inventory: "{{ current_inventory_index == ((constructed_inventory_lookvar | length) - 1) }}" + loop: "{{ constructed_inventory_lookvar }}" + loop_control: + index_var: current_inventory_index + loop_var: current_inventories_asset_value + label: "{{ __dest }}" + + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the /inventories output directory for inventories in {{ output_path }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + inventory_organization: "{{ needed_path.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + inventory_name: "{{ needed_path.name | regex_replace('/', '_') }}" + __path: "{{ output_path }}/{{ inventory_organization | regex_replace('/', '_') }}/inventories/{{ inventory_name | regex_replace('/', '_') }}" + loop: "{{ constructed_inventory_lookvar }}" + loop_control: + loop_var: needed_path + label: "{{ __path }}" + + - name: "Add current constructed_inventories to the /inventories output yaml file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_inventories.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + inventory_organization: "{{ current_inventories_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + inventory_name: "{{ current_inventories_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/{{ inventory_organization | regex_replace('/', '_') }}/inventories/{{ inventory_name | regex_replace('/', '_') }}/{{ current_inventories_asset_value.id }}_{{ inventory_name | regex_replace('/', '_') }}.yaml" + loop: "{{ constructed_inventory_lookvar }}" + loop_control: + loop_var: current_inventories_asset_value + label: "{{ __dest }}" ... diff --git a/roles/filetree_create/tasks/credentials.yml b/roles/filetree_create/tasks/credentials.yml index 5647b312b..defb91b04 100644 --- a/roles/filetree_create/tasks/credentials.yml +++ b/roles/filetree_create/tasks/credentials.yml @@ -11,32 +11,66 @@ order_by: 'organization,id' no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the /credentials output directory for credentials in {{ output_path }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - __path: "{{ output_path }}/{{ needed_path }}/credentials" - loop: "{{ (credentials_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) - + (['ORGANIZATIONLESS'] if ((credentials_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) - }}" - loop_control: - loop_var: needed_path - label: "{{ __path }}" + __dest: "{{ output_path }}/credentials.yaml" + block: + - name: "Add current credentials to the credentials flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_credentials.j2') }}" + vars: + credentials_organization: "{{ current_credentials_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + credentials_id: "{{ current_credentials_asset_value.id }}" + credentials_name: "{{ current_credentials_asset_value.name | regex_replace('/', '_') }}" + last_credential: "{{ current_credential_index == ((credentials_lookvar | length) - 1) }}" + loop: "{{ credentials_lookvar }}" + loop_control: + index_var: current_credential_index + loop_var: current_credentials_asset_value + label: "{{ __dest }}" -- name: "Add current credentials to the /credentials output yaml file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_credentials.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - credentials_organization: "{{ current_credentials_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" - credentials_id: "{{ current_credentials_asset_value.id }}" - credentials_name: "{{ current_credentials_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/{{ credentials_organization | regex_replace('/', '_') }}/credentials/{{ credentials_id }}_{{ credentials_name | regex_replace('/', '_') }}.yaml" - loop: "{{ credentials_lookvar }}" - loop_control: - loop_var: current_credentials_asset_value - label: "{{ __dest }}" + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the /credentials output directory for credentials in {{ output_path }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + __path: "{{ output_path }}/{{ needed_path }}/credentials" + loop: "{{ (credentials_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) + + (['ORGANIZATIONLESS'] if ((credentials_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) + }}" + loop_control: + loop_var: needed_path + label: "{{ __path }}" + + - name: "Add current credentials to the /credentials output yaml file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_credentials.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + credentials_organization: "{{ current_credentials_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + credentials_id: "{{ current_credentials_asset_value.id }}" + credentials_name: "{{ current_credentials_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/{{ credentials_organization | regex_replace('/', '_') }}/credentials/{{ credentials_id }}_{{ credentials_name | regex_replace('/', '_') }}.yaml" + loop: "{{ credentials_lookvar }}" + loop_control: + loop_var: current_credentials_asset_value + label: "{{ __dest }}" ... diff --git a/roles/filetree_create/tasks/groups.yml b/roles/filetree_create/tasks/groups.yml index 529e605b3..e868ac5a7 100644 --- a/roles/filetree_create/tasks/groups.yml +++ b/roles/filetree_create/tasks/groups.yml @@ -1,14 +1,38 @@ --- -- name: "Create the output directory for groups: {{ groups_output_path }}" - ansible.builtin.file: - path: "{{ groups_output_path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool + vars: + __dest: "{{ groups_output_path }}" + block: + - name: "Add current groups to the groups flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_groups.j2') }}" -- name: "Add current groups to the current_groups.yaml output file in {{ groups_output_path }}" - ansible.builtin.template: - src: "templates/current_groups.j2" - dest: "{{ groups_output_path }}/current_groups.yaml" - mode: '0644' - when: current_groups_asset_value | length > 0 + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the output directory for groups: {{ groups_output_path }}" + ansible.builtin.file: + path: "{{ groups_output_path }}" + state: directory + mode: '0755' + + - name: "Add current groups to the current_groups.yaml output file in {{ groups_output_path }}" + ansible.builtin.template: + src: "templates/current_groups.j2" + dest: "{{ groups_output_path }}/current_groups.yaml" + mode: '0644' + when: current_groups_asset_value | length > 0 ... diff --git a/roles/filetree_create/tasks/hosts.yml b/roles/filetree_create/tasks/hosts.yml index 8ef5a38f5..aac7b35a7 100644 --- a/roles/filetree_create/tasks/hosts.yml +++ b/roles/filetree_create/tasks/hosts.yml @@ -1,14 +1,38 @@ --- -- name: "Create the output directory for hosts: {{ hosts_output_path }}" - ansible.builtin.file: - path: "{{ hosts_output_path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool + vars: + __dest: "{{ hosts_output_path }}" + block: + - name: "Add current hosts to the hosts flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_hosts.j2') }}" -- name: "Add current hosts to the current_hosts.yaml output file in {{ hosts_output_path }}" - ansible.builtin.template: - src: "templates/current_hosts.j2" - dest: "{{ hosts_output_path }}/current_hosts.yaml" - mode: '0644' - when: current_hosts_asset_value | length > 0 + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the output directory for hosts: {{ hosts_output_path }}" + ansible.builtin.file: + path: "{{ hosts_output_path }}" + state: directory + mode: '0755' + + - name: "Add current hosts to the current_hosts.yaml output file in {{ hosts_output_path }}" + ansible.builtin.template: + src: "templates/current_hosts.j2" + dest: "{{ hosts_output_path }}/current_hosts.yaml" + mode: '0644' + when: current_hosts_asset_value | length > 0 ... diff --git a/roles/filetree_create/tasks/inventory.yml b/roles/filetree_create/tasks/inventory.yml index 93f5e0d86..e0708dd39 100644 --- a/roles/filetree_create/tasks/inventory.yml +++ b/roles/filetree_create/tasks/inventory.yml @@ -12,47 +12,98 @@ order_by: 'organization,id' no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the /inventories output directory for inventories in {{ output_path }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - inventory_organization: "{{ needed_path.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" - inventory_name: "{{ needed_path.name | regex_replace('/', '_') }}" - __path: "{{ output_path }}/{{ inventory_organization | regex_replace('/', '_') }}/inventories/{{ inventory_name | regex_replace('/', '_') }}" - loop: "{{ inventory_lookvar }}" - loop_control: - loop_var: needed_path - label: "{{ __path }}" + __dest: "{{ output_path }}/inventories.yaml" + block: + - name: "Stat if the output file exists" + ansible.builtin.stat: + path: "{{ __dest }}" + register: __inventories_file -- name: "Add current inventories to the /inventories output yaml file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_inventories.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - inventory_organization: "{{ current_inventories_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" - inventory_name: "{{ current_inventories_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/{{ inventory_organization | regex_replace('/', '_') }}/inventories/{{ inventory_name | regex_replace('/', '_') }}/{{ current_inventories_asset_value.id }}_{{ inventory_name | regex_replace('/', '_') }}.yaml" - loop: "{{ inventory_lookvar }}" - loop_control: - loop_var: current_inventories_asset_value - label: "{{ __dest }}" + - name: "Remove the yaml finalizer if it's already present" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: "..." + state: absent + when: __inventories_file.stat.exists | bool + + - name: "Add current inventories to the inventories flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: '' + block: "{{ lookup('template', 'templates/current_inventories.j2') }}" + vars: + inventory_organization: "{{ current_inventories_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + inventory_name: "{{ current_inventories_asset_value.name | regex_replace('/', '_') }}" + first_inventory: "{{ not (__inventories_file.stat.exists | bool) }}" + last_inventory: "{{ current_inventory_index == ((inventory_lookvar | length) - 1) }}" + loop: "{{ inventory_lookvar }}" + loop_control: + index_var: current_inventory_index + loop_var: current_inventories_asset_value + label: "{{ __dest }}" + + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the /inventories output directory for inventories in {{ output_path }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + inventory_organization: "{{ needed_path.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + inventory_name: "{{ needed_path.name | regex_replace('/', '_') }}" + __path: "{{ output_path }}/{{ inventory_organization | regex_replace('/', '_') }}/inventories/{{ inventory_name | regex_replace('/', '_') }}" + loop: "{{ inventory_lookvar }}" + loop_control: + loop_var: needed_path + label: "{{ __path }}" + + - name: "Add current inventories to the /inventories output yaml file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_inventories.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + inventory_organization: "{{ current_inventories_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + inventory_name: "{{ current_inventories_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/{{ inventory_organization | regex_replace('/', '_') }}/inventories/{{ inventory_name | regex_replace('/', '_') }}/{{ current_inventories_asset_value.id }}_{{ inventory_name | regex_replace('/', '_') }}.yaml" + loop: "{{ inventory_lookvar }}" + loop_control: + loop_var: current_inventories_asset_value + label: "{{ __dest }}" - name: "Set the inventory's inventory sources" ansible.builtin.include_tasks: "inventory_sources.yml" vars: inventory_organization: "{{ current_inventory_sources.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" inventory_name: "{{ current_inventory_sources.name | regex_replace('/', '_') }}" - inventory_sources_output_path: "{{ output_path }}/{{ inventory_organization | regex_replace('/', '_') }}/inventories/{{ inventory_name | regex_replace('/', '_') }}" + inventory_sources_output_path: "{{ (output_path + '/' + inventory_organization | regex_replace('/', '_') + '/inventories/' + inventory_name | regex_replace('/', '_')) + if (flatten_output is not defined or (flatten_output | bool) == false) + else + output_path + '/inventory_sources.yaml' }}" current_inventory_sources_asset_value: "{{ query(controller_api_plugin, current_inventory_sources.related.inventory_sources, host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, return_all=true, max_objects=query_controller_api_max_objects) if current_inventory_sources.has_inventory_sources else [] }}" + last_inventory: "{{ current_inventory_index == ((inventory_lookvar | length) - 1) }}" loop: "{{ inventory_lookvar }}" loop_control: + index_var: current_inventory_index loop_var: current_inventory_sources label: "{{ inventory_sources_output_path }}" no_log: "{{ controller_configuration_filetree_create_secure_logging }}" @@ -62,14 +113,20 @@ vars: inventory_organization: "{{ current_inventory_hosts.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" inventory_name: "{{ current_inventory_hosts.name | regex_replace('/', '_') }}" - hosts_output_path: "{{ output_path }}/{{ inventory_organization | regex_replace('/', '_') }}/inventories/{{ inventory_name | regex_replace('/', '_') }}" + hosts_output_path: "{{ (output_path + '/' + inventory_organization | regex_replace('/', '_') + '/inventories/' + inventory_name | regex_replace('/', '_')) + if (flatten_output is not defined or (flatten_output | bool) == false) + else + output_path + '/hosts.yaml' }}" current_hosts_asset_value: "{{ query(controller_api_plugin, current_inventory_hosts.related.hosts, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) - if not current_inventory_hosts.has_inventory_sources else [] + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) + if not current_inventory_hosts.has_inventory_sources else [] }}" + first_inventory: "{{ not (__inventories_file.stat.exists | bool) }}" + last_inventory: "{{ current_inventory_index == ((inventory_lookvar | length) - 1) }}" loop: "{{ inventory_lookvar }}" loop_control: + index_var: current_inventory_index loop_var: current_inventory_hosts label: "{{ hosts_output_path }}" no_log: "{{ controller_configuration_filetree_create_secure_logging }}" @@ -80,14 +137,20 @@ vars: inventory_organization: "{{ current_inventory_groups.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" inventory_name: "{{ current_inventory_groups.name | regex_replace('/', '_') }}" - groups_output_path: "{{ output_path }}/{{ inventory_organization | regex_replace('/', '_') }}/inventories/{{ inventory_name | regex_replace('/', '_') }}" + groups_output_path: "{{ (output_path + '/' + inventory_organization | regex_replace('/', '_') + '/inventories/' + inventory_name | regex_replace('/', '_')) + if (flatten_output is not defined or (flatten_output | bool) == false) + else + output_path + '/groups.yaml' }}" current_groups_asset_value: "{{ query(controller_api_plugin, current_inventory_groups.related.groups, host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, return_all=true, max_objects=query_controller_api_max_objects) if (not current_inventory_groups.has_inventory_sources or current_inventory_groups.kind is match('smart')) else [] }}" + first_inventory: "{{ not (__inventories_file.stat.exists | bool) }}" + last_inventory: "{{ current_inventory_index == ((inventory_lookvar | length) - 1) }}" loop: "{{ inventory_lookvar }}" loop_control: + index_var: current_inventory_index loop_var: current_inventory_groups label: "{{ groups_output_path }}" no_log: "{{ controller_configuration_filetree_create_secure_logging }}" diff --git a/roles/filetree_create/tasks/inventory_sources.yml b/roles/filetree_create/tasks/inventory_sources.yml index 5092d2ee6..aae7d80ae 100644 --- a/roles/filetree_create/tasks/inventory_sources.yml +++ b/roles/filetree_create/tasks/inventory_sources.yml @@ -1,15 +1,39 @@ --- -- name: "Create the output directory for inventory sources: {{ inventory_sources_output_path }}" - ansible.builtin.file: - path: "{{ inventory_sources_output_path }}" - state: directory - mode: '0755' - -- name: "Add current inventory source to the current_inventory_sources.yaml output file in {{ inventory_sources_output_path }}" - ansible.builtin.template: - src: "templates/current_inventory_sources.j2" - dest: "{{ inventory_sources_output_path }}/current_inventory_sources.yaml" - mode: '0644' +- name: "Block for to generate flatten output" when: - - current_inventory_sources_asset_value | length > 0 + - flatten_output is defined + - flatten_output | bool + block: + - name: "Add current inventory source to the inventory sources flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ inventory_sources_output_path }}" + marker: "" + block: "{{ lookup('template', 'templates/current_inventory_sources.j2') }}" + vars: + last_inventory: "{{ current_inventory_for_sources_index == ((inventory_lookvar | length) - 1) }}" + + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ inventory_sources_output_path }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the output directory for inventory sources: {{ inventory_sources_output_path }}" + ansible.builtin.file: + path: "{{ inventory_sources_output_path }}" + state: directory + mode: '0755' + + - name: "Add current inventory source to the current_inventory_sources.yaml output file in {{ inventory_sources_output_path }}" + ansible.builtin.template: + src: "templates/current_inventory_sources.j2" + dest: "{{ inventory_sources_output_path }}/current_inventory_sources.yaml" + mode: '0644' + when: + - current_inventory_sources_asset_value | length > 0 ... diff --git a/roles/filetree_create/tasks/job_templates.yml b/roles/filetree_create/tasks/job_templates.yml index 191c37f8a..c49b34b5f 100644 --- a/roles/filetree_create/tasks/job_templates.yml +++ b/roles/filetree_create/tasks/job_templates.yml @@ -15,9 +15,11 @@ when: - flatten_output is defined - flatten_output | bool + vars: + __dest: "{{ output_path }}/job_templates.yaml" block: - name: "Add current job_templates to the job_templates flat file" - blockinfile: + ansible.builtin.blockinfile: create: true insertafter: EOF path: "{{ __dest }}" @@ -27,7 +29,6 @@ job_template_organization: "{{ current_job_templates_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" job_template_id: "{{ current_job_templates_asset_value.id }}" job_template_name: "{{ current_job_templates_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/job_templates.yaml" query_labels: "{{ query(controller_api_plugin, current_job_templates_asset_value.related.labels, host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, return_all=true, max_objects=query_controller_api_max_objects) }}" @@ -48,6 +49,12 @@ label: "{{ __dest }}" no_log: "{{ controller_configuration_filetree_create_secure_logging }}" + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + - name: "Block for to generate the filetre_create normal output" when: flatten_output is not defined or (flatten_output | bool) == false block: diff --git a/roles/filetree_create/tasks/labels.yml b/roles/filetree_create/tasks/labels.yml index db9f44fcc..b8976eced 100644 --- a/roles/filetree_create/tasks/labels.yml +++ b/roles/filetree_create/tasks/labels.yml @@ -11,32 +11,66 @@ order_by: 'organization,id' no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the /labels output directory for labels in {{ output_path }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/labels" - loop: "{{ (labels_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) - + (['ORGANIZATIONLESS'] if ((labels_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) - }}" - loop_control: - loop_var: needed_path - label: "{{ __path }}" + __dest: "{{ output_path }}/labels.yaml" + block: + - name: "Add current labels to the labels flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_labels.j2') }}" + vars: + label_organization: "{{ current_labels_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true) }}" + label_id: "{{ current_labels_asset_value.id }}" + label_name: "{{ current_labels_asset_value.name | regex_replace('/', '_') }}" + last_label: "{{ current_label_index == ((labels_lookvar | length) - 1) }}" + loop: "{{ labels_lookvar }}" + loop_control: + index_var: current_label_index + loop_var: current_labels_asset_value + label: "{{ __dest }}" -- name: "Add current labels to the /labels output file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_labels.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - label_organization: "{{ current_labels_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true) }}" - label_id: "{{ current_labels_asset_value.id }}" - label_name: "{{ current_labels_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/{{ label_organization | regex_replace('/', '_') }}/labels/{{ label_id }}_{{ label_name | regex_replace('/', '_') }}.yaml" - loop: "{{ labels_lookvar }}" - loop_control: - loop_var: current_labels_asset_value - label: "{{ __dest }}" + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the /labels output directory for labels in {{ output_path }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/labels" + loop: "{{ (labels_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) + + (['ORGANIZATIONLESS'] if ((labels_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) + }}" + loop_control: + loop_var: needed_path + label: "{{ __path }}" + + - name: "Add current labels to the /labels output file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_labels.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + label_organization: "{{ current_labels_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true) }}" + label_id: "{{ current_labels_asset_value.id }}" + label_name: "{{ current_labels_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/{{ label_organization | regex_replace('/', '_') }}/labels/{{ label_id }}_{{ label_name | regex_replace('/', '_') }}.yaml" + loop: "{{ labels_lookvar }}" + loop_control: + loop_var: current_labels_asset_value + label: "{{ __dest }}" ... diff --git a/roles/filetree_create/tasks/notification_templates.yml b/roles/filetree_create/tasks/notification_templates.yml index 20e87e11b..2a6edd8a0 100644 --- a/roles/filetree_create/tasks/notification_templates.yml +++ b/roles/filetree_create/tasks/notification_templates.yml @@ -11,29 +11,60 @@ order_by: 'organization,id' no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the /notification_templates output directory for notification templates in {{ output_path }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/notification_templates" - loop: "{{ (notification_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) - + (['ORGANIZATIONLESS'] if ((notification_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) - }}" - loop_control: - loop_var: needed_path - label: "{{ __path }}" + __dest: "{{ output_path }}/notification_templates.yaml" + block: + - name: "Add current notification_templates to the notification_templates flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_notification_templates.j2') }}" + vars: + last_notification_template: "{{ current_notification_template_index == ((notification_templates_lookvar | length) - 1) }}" + loop: "{{ notification_templates_lookvar }}" + loop_control: + index_var: current_notification_template_index + loop_var: current_notification_templates_asset_value + label: "{{ __dest }}" -- name: "Add current notification templates to the /current_notification_templates.yaml output file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_notification_templates.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - __dest: "{{ output_path }}/{{ (current_notification_templates_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true)) | regex_replace('/', '_') }}/notification_templates/{{ current_notification_templates_asset_value.name | regex_replace('/', '_') }}.yaml" - loop: "{{ notification_templates_lookvar }}" - loop_control: - loop_var: current_notification_templates_asset_value - label: "{{ __dest }}" + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the /notification_templates output directory for notification templates in {{ output_path }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/notification_templates" + loop: "{{ (notification_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) + + (['ORGANIZATIONLESS'] if ((notification_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) + }}" + loop_control: + loop_var: needed_path + label: "{{ __path }}" + + - name: "Add current notification templates to the /current_notification_templates.yaml output file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_notification_templates.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + __dest: "{{ output_path }}/{{ (current_notification_templates_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true)) | regex_replace('/', '_') }}/notification_templates/{{ current_notification_templates_asset_value.name | regex_replace('/', '_') }}.yaml" + loop: "{{ notification_templates_lookvar }}" + loop_control: + loop_var: current_notification_templates_asset_value + label: "{{ __dest }}" ... diff --git a/roles/filetree_create/tasks/organizations.yml b/roles/filetree_create/tasks/organizations.yml index 54c2f0266..c34c119c0 100644 --- a/roles/filetree_create/tasks/organizations.yml +++ b/roles/filetree_create/tasks/organizations.yml @@ -11,40 +11,84 @@ order_by: 'id' no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the output directory for organizations: {{ output_path + '/' + current_organization_dir.name }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - __path: "{{ output_path }}/{{ current_organization_dir.name | regex_replace('/', '_') }}" - loop: "{{ orgs_lookvar }}" - loop_control: - loop_var: current_organization_dir - label: "{{ __path }}" + __dest: "{{ output_path }}/organizations.yaml" + block: + - name: "Add current organizations to the organizations flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_organizations.j2') }}" + vars: + query_notification_error: "{{ query(controller_api_plugin, current_organization.related.notification_templates_error, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_started: "{{ query(controller_api_plugin, current_organization.related.notification_templates_started, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_success: "{{ query(controller_api_plugin, current_organization.related.notification_templates_success, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_approvals: "{{ query(controller_api_plugin, current_organization.related.notification_templates_approvals, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + last_organization: "{{ current_organization_index == ((orgs_lookvar | length) - 1) }}" + loop: "{{ orgs_lookvar }}" + loop_control: + index_var: current_organization_index + loop_var: current_organization + label: "{{ __dest }}" + no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Add current organizations to the output yaml file" - ansible.builtin.template: - src: "templates/current_organizations.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - __dest: "{{ output_path }}/{{ current_organization.name | regex_replace('/', '_') }}/current_organization.yaml" - query_notification_error: "{{ query(controller_api_plugin, current_organization.related.notification_templates_error, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_started: "{{ query(controller_api_plugin, current_organization.related.notification_templates_started, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_success: "{{ query(controller_api_plugin, current_organization.related.notification_templates_success, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_approvals: "{{ query(controller_api_plugin, current_organization.related.notification_templates_approvals, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - loop: "{{ orgs_lookvar }}" - loop_control: - loop_var: current_organization - label: "{{ __dest }}" - no_log: "{{ controller_configuration_filetree_create_secure_logging }}" + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the output directory for organizations: {{ output_path + '/' + current_organization_dir.name }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + __path: "{{ output_path }}/{{ current_organization_dir.name | regex_replace('/', '_') }}" + loop: "{{ orgs_lookvar }}" + loop_control: + loop_var: current_organization_dir + label: "{{ __path }}" + + - name: "Add current organizations to the output yaml file" + ansible.builtin.template: + src: "templates/current_organizations.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + __dest: "{{ output_path }}/{{ current_organization.name | regex_replace('/', '_') }}/current_organization.yaml" + query_notification_error: "{{ query(controller_api_plugin, current_organization.related.notification_templates_error, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_started: "{{ query(controller_api_plugin, current_organization.related.notification_templates_started, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_success: "{{ query(controller_api_plugin, current_organization.related.notification_templates_success, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_approvals: "{{ query(controller_api_plugin, current_organization.related.notification_templates_approvals, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + loop: "{{ orgs_lookvar }}" + loop_control: + loop_var: current_organization + label: "{{ __dest }}" + no_log: "{{ controller_configuration_filetree_create_secure_logging }}" ... diff --git a/roles/filetree_create/tasks/projects.yml b/roles/filetree_create/tasks/projects.yml index 5bbcfeca6..69710f79a 100644 --- a/roles/filetree_create/tasks/projects.yml +++ b/roles/filetree_create/tasks/projects.yml @@ -11,42 +11,86 @@ order_by: 'organization,id' no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the /projects output directory for projects in {{ output_path }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/projects" - loop: "{{ (projects_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) - + (['ORGANIZATIONLESS'] if ((projects_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) - }}" - loop_control: - loop_var: needed_path - label: "{{ __path }}" + __dest: "{{ output_path }}/projects.yaml" + block: + - name: "Add current projects to the projects flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_projects.j2') }}" + vars: + project_organization: "{{ current_projects_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true) }}" + project_id: "{{ current_projects_asset_value.id }}" + project_name: "{{ current_projects_asset_value.name | regex_replace('/', '_') }}" + query_notification_error: "{{ query(controller_api_plugin, current_projects_asset_value.related.notification_templates_error, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_started: "{{ query(controller_api_plugin, current_projects_asset_value.related.notification_templates_started, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_success: "{{ query(controller_api_plugin, current_projects_asset_value.related.notification_templates_success, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + last_project: "{{ current_project_index == ((projects_lookvar | length) - 1) }}" + loop: "{{ projects_lookvar }}" + loop_control: + index_var: current_project_index + loop_var: current_projects_asset_value + label: "{{ __dest }}" + no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Add current projects to the /projects output file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_projects.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - project_organization: "{{ current_projects_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true) }}" - project_id: "{{ current_projects_asset_value.id }}" - project_name: "{{ current_projects_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/{{ project_organization | regex_replace('/', '_') }}/projects/{{ project_id }}_{{ project_name | regex_replace('/', '_') }}.yaml" - query_notification_error: "{{ query(controller_api_plugin, current_projects_asset_value.related.notification_templates_error, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_started: "{{ query(controller_api_plugin, current_projects_asset_value.related.notification_templates_started, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_success: "{{ query(controller_api_plugin, current_projects_asset_value.related.notification_templates_success, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - loop: "{{ projects_lookvar }}" - loop_control: - loop_var: current_projects_asset_value - label: "{{ __dest }}" - no_log: "{{ controller_configuration_filetree_create_secure_logging }}" + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the /projects output directory for projects in {{ output_path }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/projects" + loop: "{{ (projects_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) + + (['ORGANIZATIONLESS'] if ((projects_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) + }}" + loop_control: + loop_var: needed_path + label: "{{ __path }}" + + - name: "Add current projects to the /projects output file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_projects.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + project_organization: "{{ current_projects_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true) }}" + project_id: "{{ current_projects_asset_value.id }}" + project_name: "{{ current_projects_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/{{ project_organization | regex_replace('/', '_') }}/projects/{{ project_id }}_{{ project_name | regex_replace('/', '_') }}.yaml" + query_notification_error: "{{ query(controller_api_plugin, current_projects_asset_value.related.notification_templates_error, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_started: "{{ query(controller_api_plugin, current_projects_asset_value.related.notification_templates_started, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_success: "{{ query(controller_api_plugin, current_projects_asset_value.related.notification_templates_success, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + loop: "{{ projects_lookvar }}" + loop_control: + loop_var: current_projects_asset_value + label: "{{ __dest }}" + no_log: "{{ controller_configuration_filetree_create_secure_logging }}" ... diff --git a/roles/filetree_create/tasks/schedules.yml b/roles/filetree_create/tasks/schedules.yml index 83a110e05..f1dc8f921 100644 --- a/roles/filetree_create/tasks/schedules.yml +++ b/roles/filetree_create/tasks/schedules.yml @@ -7,32 +7,74 @@ }}" no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the schedules output directory for schedules in {{ output_path }}" - ansible.builtin.file: - path: "{{ output_path }}/schedules" - state: directory - mode: '0755' - -- name: "Add current schedules to the schedules output file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_schedules.j2" - dest: "{{ __dest }}" - mode: '0644' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - label_id: "{{ current_schedules_asset_value.id }}" - label_name: "{{ current_schedules_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/schedules/{{ label_id }}_{{ label_name | regex_replace('/', '_') }}.yaml" - query_credentials: "{{ query(controller_api_plugin, current_schedules_asset_value.related.credentials, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) if current_schedules_asset_value.related.credentials is defined else [] }}" - query_instance_groups: "{{ query(controller_api_plugin, current_schedules_asset_value.related.instance_groups, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) if current_schedules_asset_value.related.instance_groups is defined else [] }}" - query_labels: "{{ query(controller_api_plugin, current_schedules_asset_value.related.labels, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) if current_schedules_asset_value.related.labels is defined else [] }}" - loop: "{{ schedules_lookvar }}" - loop_control: - loop_var: current_schedules_asset_value - label: "{{ __dest }}" + __dest: "{{ output_path }}/schedules.yaml" + block: + - name: "Add current schedules to the schedules flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_schedules.j2') }}" + vars: + label_id: "{{ current_schedules_asset_value.id }}" + label_name: "{{ current_schedules_asset_value.name | regex_replace('/', '_') }}" + query_credentials: "{{ query(controller_api_plugin, current_schedules_asset_value.related.credentials, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) if current_schedules_asset_value.related.credentials is defined else [] }}" + query_instance_groups: "{{ query(controller_api_plugin, current_schedules_asset_value.related.instance_groups, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) if current_schedules_asset_value.related.instance_groups is defined else [] }}" + query_labels: "{{ query(controller_api_plugin, current_schedules_asset_value.related.labels, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) if current_schedules_asset_value.related.labels is defined else [] }}" + last_schedule: "{{ current_schedule_index == ((schedules_lookvar | length) - 1) }}" + loop: "{{ schedules_lookvar }}" + loop_control: + index_var: current_schedule_index + loop_var: current_schedules_asset_value + label: "{{ __dest }}" + + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the schedules output directory for schedules in {{ output_path }}" + ansible.builtin.file: + path: "{{ output_path }}/schedules" + state: directory + mode: '0755' + + - name: "Add current schedules to the schedules output file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_schedules.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + label_id: "{{ current_schedules_asset_value.id }}" + label_name: "{{ current_schedules_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/schedules/{{ label_id }}_{{ label_name | regex_replace('/', '_') }}.yaml" + query_credentials: "{{ query(controller_api_plugin, current_schedules_asset_value.related.credentials, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) if current_schedules_asset_value.related.credentials is defined else [] }}" + query_instance_groups: "{{ query(controller_api_plugin, current_schedules_asset_value.related.instance_groups, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) if current_schedules_asset_value.related.instance_groups is defined else [] }}" + query_labels: "{{ query(controller_api_plugin, current_schedules_asset_value.related.labels, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) if current_schedules_asset_value.related.labels is defined else [] }}" + loop: "{{ schedules_lookvar }}" + loop_control: + loop_var: current_schedules_asset_value + label: "{{ __dest }}" ... diff --git a/roles/filetree_create/tasks/team_roles.yml b/roles/filetree_create/tasks/team_roles.yml index afb5764b6..760d7c106 100644 --- a/roles/filetree_create/tasks/team_roles.yml +++ b/roles/filetree_create/tasks/team_roles.yml @@ -11,14 +11,16 @@ when: - flatten_output is defined - flatten_output | bool + vars: + __dest: "{{ output_path }}/team_roles.yaml" block: - name: "Stat if the output file exists" ansible.builtin.stat: - path: "{{ output_path }}/team_roles.yaml" + path: "{{ __dest }}" register: team_roles_file - name: "Add current team roles to the team roles flat file" - blockinfile: + ansible.builtin.blockinfile: create: true insertafter: EOF path: "{{ __dest }}" @@ -26,10 +28,15 @@ block: "{{ lookup('template', 'templates/current_team_roles.j2') }}" vars: current_team_roles_asset_value: "{{ team_roles_lookvar }}" - __dest: "{{ output_path }}/team_roles.yaml" first_team_role: "{{ not team_roles_file.stat.exists }}" when: team_roles_lookvar | length > 0 + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + - name: "Block for to generate the filetre_create normal output" when: flatten_output is not defined or (flatten_output | bool) == false block: diff --git a/roles/filetree_create/tasks/teams.yml b/roles/filetree_create/tasks/teams.yml index fb7324d88..bfbe25896 100644 --- a/roles/filetree_create/tasks/teams.yml +++ b/roles/filetree_create/tasks/teams.yml @@ -15,9 +15,11 @@ when: - flatten_output is defined - flatten_output | bool + vars: + __dest: "{{ output_path }}/teams.yaml" block: - name: "Add current teams to the teams flat file" - blockinfile: + ansible.builtin.blockinfile: create: true insertafter: EOF path: "{{ __dest }}" @@ -27,7 +29,6 @@ team_organization: "{{ (current_teams_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS', true)) | regex_replace('/', '_') }}" team_id: "{{ current_teams_asset_value.id }}" team_name: "{{ current_teams_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/teams.yaml" last_team: "{{ current_team_index == ((teams_lookvar | length) - 1) }}" loop: "{{ teams_lookvar }}" loop_control: @@ -35,6 +36,12 @@ loop_var: current_teams_asset_value label: "{{ __dest }}" + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + - name: "Block for to generate the filetre_create normal output" when: flatten_output is not defined or (flatten_output | bool) == false block: diff --git a/roles/filetree_create/tasks/user_roles.yml b/roles/filetree_create/tasks/user_roles.yml index cd4335327..018d3053d 100644 --- a/roles/filetree_create/tasks/user_roles.yml +++ b/roles/filetree_create/tasks/user_roles.yml @@ -7,18 +7,51 @@ }}" no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the output directory for user roles: {{ output_path }}" - ansible.builtin.file: - path: "{{ output_path }}/user_roles" - state: directory - mode: '0755' - -- name: "Add current roles to the output yaml file" - ansible.builtin.template: - src: "templates/current_user_roles.j2" - dest: "{{ output_path }}/user_roles/current_roles_{{ username | regex_replace('/', '_') }}.yaml" - mode: '0644' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - current_user_roles_asset_value: "{{ user_roles_lookvar }}" - when: user_roles_lookvar | length > 0 + __dest: "{{ output_path }}/user_roles.yaml" + block: + - name: "Stat if the output file exists" + ansible.builtin.stat: + path: "{{ __dest }}" + register: user_roles_file + + - name: "Add current user roles to the user roles flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_user_roles.j2') }}" + vars: + current_user_roles_asset_value: "{{ user_roles_lookvar }}" + first_user_role: "{{ not user_roles_file.stat.exists }}" + when: user_roles_lookvar | length > 0 + + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the output directory for user roles: {{ output_path }}" + ansible.builtin.file: + path: "{{ output_path }}/user_roles" + state: directory + mode: '0755' + + - name: "Add current roles to the output yaml file" + ansible.builtin.template: + src: "templates/current_user_roles.j2" + dest: "{{ output_path }}/user_roles/current_roles_{{ username | regex_replace('/', '_') }}.yaml" + mode: '0644' + vars: + current_user_roles_asset_value: "{{ user_roles_lookvar }}" + when: user_roles_lookvar | length > 0 ... diff --git a/roles/filetree_create/tasks/users.yml b/roles/filetree_create/tasks/users.yml index 79fbbe938..f78c95a21 100644 --- a/roles/filetree_create/tasks/users.yml +++ b/roles/filetree_create/tasks/users.yml @@ -22,41 +22,76 @@ label: "User {{ user_lookvar_item.username }}" no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the output directory for users in {{ output_path }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - __path: "{{ output_path }}/{{ current_user_dir | regex_replace('/', '_') }}/users" - when: organization_filter is not defined or (current_user_dir is match(organization_filter)) - loop: "{{ current_users | selectattr('organizations', 'defined') | map(attribute='organizations') | flatten | unique }}" - loop_control: - loop_var: current_user_dir - label: "{{ __path }}" + __dest: "{{ output_path }}/users.yaml" + block: + - name: "Add current users to the users flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_users.j2') }}" + vars: + current_users_asset_value: "{{ current_user_dir.0 }}" + last_user: "{{ current_user_index == ((users_lookvar | length) - 1) }}" + when: organization_filter is not defined or (current_user_dir.1 is match(organization_filter)) + loop: "{{ current_users | default([]) | subelements('organizations', skip_missing=true) }}" + loop_control: + index_var: current_user_index + loop_var: current_user_dir + label: "{{ __dest }}" -- name: "Add current users to the /.yaml output file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_users.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - current_users_asset_value: "{{ current_user_dir.0 }}" - __dest: "{{ output_path }}/{{ current_user_dir.1 | regex_replace('/', '_') }}/users/{{ current_user_dir.0.username | regex_replace('/', '_') }}.yaml" - when: organization_filter is not defined or (current_user_dir.1 is match(organization_filter)) - loop: "{{ current_users | default([]) | subelements('organizations', skip_missing=true) }}" - loop_control: - loop_var: current_user_dir - label: "{{ __dest }}" + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the output directory for users in {{ output_path }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + __path: "{{ output_path }}/{{ current_user_dir | regex_replace('/', '_') }}/users" + when: organization_filter is not defined or (current_user_dir is match(organization_filter)) + loop: "{{ current_users | selectattr('organizations', 'defined') | map(attribute='organizations') | flatten | unique }}" + loop_control: + loop_var: current_user_dir + label: "{{ __path }}" + + - name: "Add current users to the /.yaml output file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_users.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + current_users_asset_value: "{{ current_user_dir.0 }}" + __dest: "{{ output_path }}/{{ current_user_dir.1 | regex_replace('/', '_') }}/users/{{ current_user_dir.0.username | regex_replace('/', '_') }}.yaml" + when: organization_filter is not defined or (current_user_dir.1 is match(organization_filter)) + loop: "{{ current_users | default([]) | subelements('organizations', skip_missing=true) }}" + loop_control: + loop_var: current_user_dir + label: "{{ __dest }}" - name: "Set the user's roles" ansible.builtin.include_tasks: "user_roles.yml" vars: username: "{{ current_user.0.username }}" + last_user_role: "{{ current_user_index_for_roles == ((current_users | default([]) | subelements('organizations', skip_missing=true) | length) - 1) }}" when: - not current_user.0.is_superuser - organization_filter is not defined or (current_user.1 is match(organization_filter)) loop: "{{ current_users | default([]) | subelements('organizations', skip_missing=true) }}" loop_control: + index_var: current_user_index_for_roles loop_var: current_user ... diff --git a/roles/filetree_create/tasks/workflow_job_templates.yml b/roles/filetree_create/tasks/workflow_job_templates.yml index c66d3a156..87901364d 100644 --- a/roles/filetree_create/tasks/workflow_job_templates.yml +++ b/roles/filetree_create/tasks/workflow_job_templates.yml @@ -11,48 +11,98 @@ order_by: 'organization,id' no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Create the /workflow_job_templates output directory for workflow job templates in {{ output_path }}" - ansible.builtin.file: - path: "{{ __path }}" - state: directory - mode: '0755' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/workflow_job_templates/" - loop: "{{ (workflow_job_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) - + (['ORGANIZATIONLESS'] if ((workflow_job_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) - }}" - loop_control: - loop_var: needed_path - label: "{{ __path }}" + __dest: "{{ output_path }}/workflow_job_templates.yaml" + block: + - name: "Add current workflow_job_templates to the workflow_job_templates flat file" + ansible.builtin.blockinfile: + create: true + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_workflow_job_templates.j2') }}" + vars: + workflow_job_template_organization: "{{ current_workflow_job_templates_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + workflow_job_template_id: "{{ current_workflow_job_templates_asset_value.id }}" + workflow_job_template_name: "{{ current_workflow_job_templates_asset_value.name | regex_replace('/', '_') }}" + query_labels: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.labels, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_error: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_error, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_started: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_started, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_success: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_success, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_approvals: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_approvals, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + last_workflow_job_template: "{{ current_workflow_job_template_index == ((workflow_job_templates_lookvar | length) - 1) }}" + loop: "{{ workflow_job_templates_lookvar }}" + loop_control: + index_var: current_workflow_job_template_index + loop_var: current_workflow_job_templates_asset_value + label: "{{ __dest }}" + no_log: "{{ controller_configuration_filetree_create_secure_logging }}" -- name: "Add current workflow job templates to the /workflow_job_templates output file in {{ output_path }}" - ansible.builtin.template: - src: "templates/current_workflow_job_templates.j2" - dest: "{{ __dest }}" - mode: '0644' - vars: - workflow_job_template_organization: "{{ current_workflow_job_templates_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" - workflow_job_template_id: "{{ current_workflow_job_templates_asset_value.id }}" - workflow_job_template_name: "{{ current_workflow_job_templates_asset_value.name | regex_replace('/', '_') }}" - __dest: "{{ output_path }}/{{ workflow_job_template_organization | regex_replace('/', '_') }}/workflow_job_templates/{{ workflow_job_template_id }}_{{ workflow_job_template_name | regex_replace('/', '_') }}.yaml" - query_labels: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.labels, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_error: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_error, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_started: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_started, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_success: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_success, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - query_notification_approvals: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_approvals, - host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, - return_all=true, max_objects=query_controller_api_max_objects) }}" - loop: "{{ workflow_job_templates_lookvar }}" - loop_control: - loop_var: current_workflow_job_templates_asset_value - label: "{{ __dest }}" - no_log: "{{ controller_configuration_filetree_create_secure_logging }}" + - name: "Remove all the blank lines introduced by the last task" + ansible.builtin.lineinfile: + path: "{{ __dest }}" + line: '' + state: absent + +- name: "Block for to generate the filetre_create normal output" + when: flatten_output is not defined or (flatten_output | bool) == false + block: + - name: "Create the /workflow_job_templates output directory for workflow job templates in {{ output_path }}" + ansible.builtin.file: + path: "{{ __path }}" + state: directory + mode: '0755' + vars: + __path: "{{ output_path }}/{{ needed_path | regex_replace('/', '_') }}/workflow_job_templates/" + loop: "{{ (workflow_job_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'defined') | map(attribute='organization') | map(attribute='name') | list | flatten | unique) + + (['ORGANIZATIONLESS'] if ((workflow_job_templates_lookvar | map(attribute='summary_fields') | selectattr('organization', 'undefined') | list | flatten) | length > 0) else []) + }}" + loop_control: + loop_var: needed_path + label: "{{ __path }}" + + - name: "Add current workflow job templates to the /workflow_job_templates output file in {{ output_path }}" + ansible.builtin.template: + src: "templates/current_workflow_job_templates.j2" + dest: "{{ __dest }}" + mode: '0644' + vars: + workflow_job_template_organization: "{{ current_workflow_job_templates_asset_value.summary_fields.organization.name | default('ORGANIZATIONLESS') }}" + workflow_job_template_id: "{{ current_workflow_job_templates_asset_value.id }}" + workflow_job_template_name: "{{ current_workflow_job_templates_asset_value.name | regex_replace('/', '_') }}" + __dest: "{{ output_path }}/{{ workflow_job_template_organization | regex_replace('/', '_') }}/workflow_job_templates/{{ workflow_job_template_id }}_{{ workflow_job_template_name | regex_replace('/', '_') }}.yaml" + query_labels: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.labels, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_error: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_error, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_started: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_started, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_success: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_success, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + query_notification_approvals: "{{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.notification_templates_approvals, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs, + return_all=true, max_objects=query_controller_api_max_objects) }}" + loop: "{{ workflow_job_templates_lookvar }}" + loop_control: + loop_var: current_workflow_job_templates_asset_value + label: "{{ __dest }}" + no_log: "{{ controller_configuration_filetree_create_secure_logging }}" ... diff --git a/roles/filetree_create/templates/current_applications.j2 b/roles/filetree_create/templates/current_applications.j2 index c27915117..246ba3ed4 100644 --- a/roles/filetree_create/templates/current_applications.j2 +++ b/roles/filetree_create/templates/current_applications.j2 @@ -1,5 +1,7 @@ +{% if (current_application_index | default(0)) == 0 %} --- controller_applications: +{% endif %} - name: "{{ current_applications_asset_value.name }}" description: "{{ current_applications_asset_value.description }}" organization: "{{ current_applications_asset_value.summary_fields.organization.name | default('ToDo: The application \'' + current_applications_asset_value.name + '\' must have an organization') }}" @@ -8,4 +10,6 @@ controller_applications: skip_authorization: "{{ current_applications_asset_value.skip_authorization }}" client_id: "{{ current_applications_asset_value.client_id }}" client_type: "{{ current_applications_asset_value.client_type }}" +{% if last_application | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_credentials.j2 b/roles/filetree_create/templates/current_credentials.j2 index 1eed4841c..d208a5d4e 100644 --- a/roles/filetree_create/templates/current_credentials.j2 +++ b/roles/filetree_create/templates/current_credentials.j2 @@ -1,5 +1,7 @@ +{% if (current_credential_index | default(0)) == 0 %} --- controller_credentials: +{% endif %} - name: "{{ current_credentials_asset_value.name }}" description: "{{ current_credentials_asset_value.description }}" credential_type: "{{ current_credentials_asset_value.summary_fields.credential_type.name }}" @@ -8,6 +10,10 @@ controller_credentials: {% else %} organization: "ORGANIZATIONLESS" {% endif %} +{% if current_credentials_asset_value.inputs is defined and current_credentials_asset_value.inputs is not match('{}') %} inputs: {{ current_credentials_asset_value.inputs | to_nice_yaml(indent=2) | indent(width=6, first=True) | replace("$encrypted$", "\'\'") }} +{% endif %} +{% if last_credential | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_groups.j2 b/roles/filetree_create/templates/current_groups.j2 index de8858bb5..a043e645e 100644 --- a/roles/filetree_create/templates/current_groups.j2 +++ b/roles/filetree_create/templates/current_groups.j2 @@ -1,5 +1,7 @@ +{% if ((first_inventory | default(true) | bool) and ((current_inventory_index | default(0)) == 0)) %} --- controller_groups: +{% endif %} {% for group in current_groups_asset_value %} - name: "{{ group.name }}" description: "{{ group.description }}" @@ -15,4 +17,6 @@ controller_groups: ) | selectattr("name", "defined") | map(attribute="name") | to_nice_yaml(indent=2) | indent(width=6, first=True) }} {%- endfor -%} +{% if last_inventory | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_hosts.j2 b/roles/filetree_create/templates/current_hosts.j2 index 3a3d4abef..7ef807915 100644 --- a/roles/filetree_create/templates/current_hosts.j2 +++ b/roles/filetree_create/templates/current_hosts.j2 @@ -1,5 +1,7 @@ +{% if ((first_inventory | default(true) | bool) and ((current_inventory_index | default(0)) == 0)) %} --- controller_hosts: +{% endif %} {% for host in current_hosts_asset_value if not host.has_inventory_sources %} - name: "{{ host.name }}" description: "{{ host.description }}" @@ -9,4 +11,6 @@ controller_hosts: {{ host.variables | from_yaml | to_nice_yaml(indent=2) | indent(width=6, first=False) | replace("'{{", "!unsafe \'{{") }} {%- endif %} {% endfor %} +{% if last_inventory | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_inventories.j2 b/roles/filetree_create/templates/current_inventories.j2 index e82330541..91c243bc3 100644 --- a/roles/filetree_create/templates/current_inventories.j2 +++ b/roles/filetree_create/templates/current_inventories.j2 @@ -1,5 +1,7 @@ +{% if (first_inventory | default(true) | bool) and (current_inventory_index | default(0) == 0) %} --- controller_inventories: +{% endif %} - name: "{{ current_inventories_asset_value.name }}" description: "{{ current_inventories_asset_value.description }}" organization: "{{ inventory_organization }}" @@ -29,4 +31,6 @@ controller_inventories: variables: {{ current_inventories_asset_value.variables | from_yaml | to_nice_yaml(indent=2) | indent(width=6, first=False) | replace("'{{", "!unsafe \'{{") }} {%- endif %} +{% if last_inventory | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_inventory_sources.j2 b/roles/filetree_create/templates/current_inventory_sources.j2 index 5c7887148..ab1c93936 100644 --- a/roles/filetree_create/templates/current_inventory_sources.j2 +++ b/roles/filetree_create/templates/current_inventory_sources.j2 @@ -1,5 +1,7 @@ +{% if (current_inventory_index | default(0)) == 0 %} --- controller_inventory_sources: +{% endif %} {% for inventory_source in current_inventory_sources_asset_value %} - name: "{{ inventory_source.name }}" description: "{{ inventory_source.description }}" @@ -51,4 +53,6 @@ controller_inventory_sources: {% endfor %} {% endif %} {% endfor %} +{% if last_inventory | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_job_templates.j2 b/roles/filetree_create/templates/current_job_templates.j2 index 031eb5b41..c9c160cbc 100644 --- a/roles/filetree_create/templates/current_job_templates.j2 +++ b/roles/filetree_create/templates/current_job_templates.j2 @@ -1,4 +1,4 @@ -{%- if current_job_template_index == 0 -%} +{% if (current_job_template_index | default(0)) == 0 %} --- controller_templates: {% endif %} @@ -52,7 +52,7 @@ controller_templates: {% if current_job_templates_asset_value.ask_instance_groups_on_launch is defined %} ask_instance_groups_on_launch: {{ current_job_templates_asset_value.ask_instance_groups_on_launch | bool }} {% endif %} -{% if current_job_templates_asset_value.extra_vars and current_job_templates_asset_value.extra_vars != '---' and current_job_templates_asset_value.extra_vars != '' %} +{% if current_job_templates_asset_value.extra_vars and current_job_templates_asset_value.extra_vars | length > 3 %} extra_vars: {{ current_job_templates_asset_value.extra_vars | from_yaml | to_nice_yaml(indent=2) | indent(width=6, first=False) | replace("'{{", "!unsafe \'{{") }} {%- endif %} @@ -110,6 +110,6 @@ controller_templates: {% if current_job_templates_asset_value.prevent_instance_group_fallback is defined %} prevent_instance_group_fallback: {{ current_job_templates_asset_value.prevent_instance_group_fallback | bool }} {% endif %} -{% if last_job_template | bool %} +{% if last_job_template | default(true) | bool %} ... {% endif %} diff --git a/roles/filetree_create/templates/current_labels.j2 b/roles/filetree_create/templates/current_labels.j2 index 727cf90d8..fff70f1a6 100644 --- a/roles/filetree_create/templates/current_labels.j2 +++ b/roles/filetree_create/templates/current_labels.j2 @@ -1,5 +1,9 @@ +{% if (current_label_index | default(0)) == 0 %} --- controller_labels: +{% endif %} - name: "{{ current_labels_asset_value.name }}" organization: "{{ current_labels_asset_value.summary_fields.organization.name | default('ToDo: The label \'' + current_labels_asset_value.name + '\' must have an organization') }}" +{% if last_label | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_notification_templates.j2 b/roles/filetree_create/templates/current_notification_templates.j2 index c98d04497..ad60cb4cc 100644 --- a/roles/filetree_create/templates/current_notification_templates.j2 +++ b/roles/filetree_create/templates/current_notification_templates.j2 @@ -1,5 +1,7 @@ +{% if (current_notification_template_index | default(0)) == 0 %} --- controller_notifications: +{% endif %} - name: "{{ current_notification_templates_asset_value.name }}" organization: "{{ current_notification_templates_asset_value.summary_fields.organization.name }}" notification_type: "{{ current_notification_templates_asset_value.notification_type }}" @@ -19,4 +21,6 @@ controller_notifications: messages: {{ current_notification_templates_asset_value.messages | to_nice_yaml(indent=2) | indent(width=6, first=True) | replace("'{{", "!unsafe \'{{") }} {% endif %} +{% if last_notification_template | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_organizations.j2 b/roles/filetree_create/templates/current_organizations.j2 index 3836f6ced..ea103a9cc 100644 --- a/roles/filetree_create/templates/current_organizations.j2 +++ b/roles/filetree_create/templates/current_organizations.j2 @@ -1,5 +1,7 @@ +{% if (current_organization_index | default(0)) == 0 %} --- controller_organizations: +{% endif %} - name: "{{ current_organization.name }}" description: "{{ current_organization.description }}" {% if query_notification_error | length > 0 %} @@ -26,4 +28,6 @@ controller_organizations: - "{{ notification_approval.name }}" {% endfor %} {% endif %} +{% if last_organization | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_projects.j2 b/roles/filetree_create/templates/current_projects.j2 index 5e9554006..9526f3356 100644 --- a/roles/filetree_create/templates/current_projects.j2 +++ b/roles/filetree_create/templates/current_projects.j2 @@ -1,5 +1,7 @@ +{% if (current_project_index | default(0)) == 0 %} --- controller_projects: +{% endif %} - name: "{{ current_projects_asset_value.name }}" description: "{{ current_projects_asset_value.description }}" organization: "{{ current_projects_asset_value.summary_fields.organization.name | default('ToDo: The project \'' + current_projects_asset_value.name + '\' must have an organization') }}" @@ -35,4 +37,6 @@ controller_projects: - "{{ notification_success.name }}" {% endfor %} {% endif %} +{% if last_project | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_schedules.j2 b/roles/filetree_create/templates/current_schedules.j2 index 367af3851..8c7506815 100644 --- a/roles/filetree_create/templates/current_schedules.j2 +++ b/roles/filetree_create/templates/current_schedules.j2 @@ -1,5 +1,7 @@ +{% if (current_schedule_index | default(0)) == 0 %} --- controller_schedules: +{% endif %} - name: "{{ current_schedules_asset_value.name }}" {% if current_schedules_asset_value.description is defined %} description: "{{ current_schedules_asset_value.description }}" @@ -76,4 +78,6 @@ controller_schedules: {% if current_schedules_asset_value.verbosity is defined %} verbosity: {{ current_schedules_asset_value.verbosity | int }} {% endif %} +{% if last_schedule | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_team_roles.j2 b/roles/filetree_create/templates/current_team_roles.j2 index 1ba33d0c0..d70d0a080 100644 --- a/roles/filetree_create/templates/current_team_roles.j2 +++ b/roles/filetree_create/templates/current_team_roles.j2 @@ -1,4 +1,4 @@ -{% if first_team_role | bool %} +{% if first_team_role | default(true) | bool %} --- controller_roles: {% endif %} @@ -25,6 +25,6 @@ controller_roles: role: "{{ role.name | lower }}" {% endif %} {% endfor %} -{% if last_team_role | bool %} +{% if last_team_role | default(true) | bool %} ... -{%- endif -%} +{% endif %} diff --git a/roles/filetree_create/templates/current_teams.j2 b/roles/filetree_create/templates/current_teams.j2 index eafa0f076..259c47df8 100644 --- a/roles/filetree_create/templates/current_teams.j2 +++ b/roles/filetree_create/templates/current_teams.j2 @@ -1,10 +1,10 @@ -{%- if current_team_index == 0 -%} +{% if (current_team_index | default(0)) == 0 %} --- controller_teams: {% endif %} - name: "{{ current_teams_asset_value.name }}" description: "{{ current_teams_asset_value.description }}" organization: "{{ current_teams_asset_value.summary_fields.organization.name }}" -{% if last_team | bool %} +{% if last_team | default(true) | bool %} ... {% endif %} diff --git a/roles/filetree_create/templates/current_user_roles.j2 b/roles/filetree_create/templates/current_user_roles.j2 index 2a037a5a7..2170e99d6 100644 --- a/roles/filetree_create/templates/current_user_roles.j2 +++ b/roles/filetree_create/templates/current_user_roles.j2 @@ -1,5 +1,7 @@ +{% if first_user_role | default(true) | bool %} --- controller_roles: +{% endif %} {% for role in user_roles_lookvar %} {% if role.summary_fields.resource_type is defined %} - user: "{{ username }}" @@ -23,4 +25,6 @@ controller_roles: role: "{{ role.name | lower }}" {% endif %} {% endfor %} +{% if last_user_role | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_users.j2 b/roles/filetree_create/templates/current_users.j2 index fe98ce709..59f766c2f 100644 --- a/roles/filetree_create/templates/current_users.j2 +++ b/roles/filetree_create/templates/current_users.j2 @@ -1,5 +1,7 @@ +{% if (current_user_index | default(0)) == 0 %} --- controller_user_accounts: +{% endif %} - username: "{{ current_users_asset_value.username }}" password: "INITIAL" email: "{{ current_users_asset_value.email }}" @@ -8,4 +10,6 @@ controller_user_accounts: auditor: "{{ current_users_asset_value.is_system_auditor }}" superuser: "{{ current_users_asset_value.is_superuser }}" update_secrets: false +{% if last_user | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_workflow_job_templates.j2 b/roles/filetree_create/templates/current_workflow_job_templates.j2 index 90fdb512f..6800a4215 100644 --- a/roles/filetree_create/templates/current_workflow_job_templates.j2 +++ b/roles/filetree_create/templates/current_workflow_job_templates.j2 @@ -1,5 +1,7 @@ +{% if (current_workflow_job_template_index | default(0)) == 0 %} --- controller_workflows: +{% endif %} - name: "{{ current_workflow_job_templates_asset_value.name }}" description: "{{ current_workflow_job_templates_asset_value.description }}" organization: "{{ current_workflow_job_templates_asset_value.summary_fields.organization.name | default('ToDo: The WF \'' + current_workflow_job_templates_asset_value.name + '\' must belong to an organization') }}" @@ -36,12 +38,11 @@ controller_workflows: {% endfor %} {% endif %} {% endfor %} - survey_enabled: "{{ current_workflow_job_templates_asset_value.survey_enabled }}" ask_variables_on_launch: "{{ current_workflow_job_templates_asset_value.ask_variables_on_launch }}" allow_simultaneous: "{{ current_workflow_job_templates_asset_value.allow_simultaneous }}" scm_branch: "{{ current_workflow_job_templates_asset_value.scm_branch }}" webhook_service: "{{ current_workflow_job_templates_asset_value.webhook_service }}" -{% if current_workflow_job_templates_asset_value.extra_vars and current_workflow_job_templates_asset_value.extra_vars != '---' and current_workflow_job_templates_asset_value.extra_vars != '' %} +{% if current_workflow_job_templates_asset_value.extra_vars and current_workflow_job_templates_asset_value.extra_vars | length > 3 %} extra_vars: {{ current_workflow_job_templates_asset_value.extra_vars | from_yaml | to_nice_yaml(indent=2) | indent(width=6, first=False) | replace("'{{", "!unsafe \'{{") }} {%- endif %} @@ -76,5 +77,14 @@ controller_workflows: {% endfor %} {% endif %} survey_enabled: {{ current_workflow_job_templates_asset_value.survey_enabled }} - survey_spec: {{ query(controller_api_plugin, current_workflow_job_templates_asset_value.related.survey_spec, host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs)[0] }} +{% set survey_spec_contents = query(controller_api_plugin, current_workflow_job_templates_asset_value.related.survey_spec, + host=controller_hostname, oauth_token=controller_oauthtoken, verify_ssl=controller_validate_certs)[0] | + from_yaml | to_nice_yaml(indent=2,width=500) | regex_replace("\n\n[ ]*", "\\\\n") | indent(width=6, first=False) | replace("'{{", "!unsafe \'{{") | replace("^$", "") +-%} +{% if current_workflow_job_templates_asset_value.related.survey_spec is defined and survey_spec_contents | length > 3 %} + survey_spec: + {{ survey_spec_contents }} +{% endif %} +{% if last_workflow_job_template | default(true) | bool %} ... +{% endif %} From 23c5431671e7212ec9ca935811d1e0bb66f2b8b8 Mon Sep 17 00:00:00 2001 From: ivarmu <26822043+ivarmu@users.noreply.github.com> Date: Tue, 7 Nov 2023 17:49:20 +0100 Subject: [PATCH 3/8] fix lintering issues --- playbooks/flatten_filetree_create_output.yaml | 3 +++ roles/filetree_create/tasks/applications.yml | 3 ++- roles/filetree_create/tasks/constructed_inventory.yml | 5 +++-- roles/filetree_create/tasks/credentials.yml | 3 ++- roles/filetree_create/tasks/groups.yml | 3 ++- roles/filetree_create/tasks/hosts.yml | 3 ++- roles/filetree_create/tasks/inventory.yml | 3 ++- roles/filetree_create/tasks/inventory_sources.yml | 3 ++- roles/filetree_create/tasks/job_templates.yml | 3 ++- roles/filetree_create/tasks/labels.yml | 3 ++- roles/filetree_create/tasks/notification_templates.yml | 3 ++- roles/filetree_create/tasks/organizations.yml | 3 ++- roles/filetree_create/tasks/projects.yml | 3 ++- roles/filetree_create/tasks/schedules.yml | 3 ++- roles/filetree_create/tasks/team_roles.yml | 3 ++- roles/filetree_create/tasks/teams.yml | 3 ++- roles/filetree_create/tasks/user_roles.yml | 3 ++- roles/filetree_create/tasks/users.yml | 3 ++- roles/filetree_create/tasks/workflow_job_templates.yml | 3 ++- roles/object_diff/tasks/roles.yml | 1 + 20 files changed, 41 insertions(+), 19 deletions(-) diff --git a/playbooks/flatten_filetree_create_output.yaml b/playbooks/flatten_filetree_create_output.yaml index a72fb663f..cdaacec4e 100644 --- a/playbooks/flatten_filetree_create_output.yaml +++ b/playbooks/flatten_filetree_create_output.yaml @@ -1,3 +1,4 @@ +--- - name: "Flatten the filetree_create output into unique files per each object type" hosts: localhost connection: local @@ -31,10 +32,12 @@ ansible.builtin.file: path: "{{ filetree_create_output_dir }}_flatten" state: directory + mode: "0755" - name: "Write all the objects to the corresponding file" ansible.builtin.copy: dest: "{{ filetree_create_output_dir }}_flatten/{{ item.name }}.yaml" + mode: "0644" content: | --- {{ item.value | to_nice_yaml(indent=2) }} diff --git a/roles/filetree_create/tasks/applications.yml b/roles/filetree_create/tasks/applications.yml index df7eb9cbd..1d8b7a9c9 100644 --- a/roles/filetree_create/tasks/applications.yml +++ b/roles/filetree_create/tasks/applications.yml @@ -21,6 +21,7 @@ - name: "Add current applications to the applications flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -43,7 +44,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the /applications output directory for applications in {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/constructed_inventory.yml b/roles/filetree_create/tasks/constructed_inventory.yml index dc1a2fbaf..fdee02e91 100644 --- a/roles/filetree_create/tasks/constructed_inventory.yml +++ b/roles/filetree_create/tasks/constructed_inventory.yml @@ -24,7 +24,7 @@ register: __constructed_inventories_file - name: "Remove the yaml finalizer if it's already present" - lineinfile: + ansible.builtin.lineinfile: path: "{{ __dest }}" line: "..." state: absent @@ -33,6 +33,7 @@ - name: "Add current constructed inventory to the inventories flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -55,7 +56,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the /inventories output directory for inventories in {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/credentials.yml b/roles/filetree_create/tasks/credentials.yml index defb91b04..97e27b956 100644 --- a/roles/filetree_create/tasks/credentials.yml +++ b/roles/filetree_create/tasks/credentials.yml @@ -21,6 +21,7 @@ - name: "Add current credentials to the credentials flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -43,7 +44,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the /credentials output directory for credentials in {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/groups.yml b/roles/filetree_create/tasks/groups.yml index e868ac5a7..cec0dbfb7 100644 --- a/roles/filetree_create/tasks/groups.yml +++ b/roles/filetree_create/tasks/groups.yml @@ -9,6 +9,7 @@ - name: "Add current groups to the groups flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -21,7 +22,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the output directory for groups: {{ groups_output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/hosts.yml b/roles/filetree_create/tasks/hosts.yml index aac7b35a7..514929fcf 100644 --- a/roles/filetree_create/tasks/hosts.yml +++ b/roles/filetree_create/tasks/hosts.yml @@ -9,6 +9,7 @@ - name: "Add current hosts to the hosts flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -21,7 +22,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the output directory for hosts: {{ hosts_output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/inventory.yml b/roles/filetree_create/tasks/inventory.yml index e0708dd39..fd05db1f9 100644 --- a/roles/filetree_create/tasks/inventory.yml +++ b/roles/filetree_create/tasks/inventory.yml @@ -34,6 +34,7 @@ - name: "Add current inventories to the inventories flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: '' @@ -56,7 +57,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the /inventories output directory for inventories in {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/inventory_sources.yml b/roles/filetree_create/tasks/inventory_sources.yml index aae7d80ae..0c67ca6cf 100644 --- a/roles/filetree_create/tasks/inventory_sources.yml +++ b/roles/filetree_create/tasks/inventory_sources.yml @@ -7,6 +7,7 @@ - name: "Add current inventory source to the inventory sources flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ inventory_sources_output_path }}" marker: "" @@ -21,7 +22,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the output directory for inventory sources: {{ inventory_sources_output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/job_templates.yml b/roles/filetree_create/tasks/job_templates.yml index c49b34b5f..90f7076bf 100644 --- a/roles/filetree_create/tasks/job_templates.yml +++ b/roles/filetree_create/tasks/job_templates.yml @@ -21,6 +21,7 @@ - name: "Add current job_templates to the job_templates flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -56,7 +57,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the output directories for job templates in {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/labels.yml b/roles/filetree_create/tasks/labels.yml index b8976eced..d54144e74 100644 --- a/roles/filetree_create/tasks/labels.yml +++ b/roles/filetree_create/tasks/labels.yml @@ -21,6 +21,7 @@ - name: "Add current labels to the labels flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -43,7 +44,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the /labels output directory for labels in {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/notification_templates.yml b/roles/filetree_create/tasks/notification_templates.yml index 2a6edd8a0..5aa2da2d9 100644 --- a/roles/filetree_create/tasks/notification_templates.yml +++ b/roles/filetree_create/tasks/notification_templates.yml @@ -21,6 +21,7 @@ - name: "Add current notification_templates to the notification_templates flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -40,7 +41,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the /notification_templates output directory for notification templates in {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/organizations.yml b/roles/filetree_create/tasks/organizations.yml index c34c119c0..f2de44b6f 100644 --- a/roles/filetree_create/tasks/organizations.yml +++ b/roles/filetree_create/tasks/organizations.yml @@ -21,6 +21,7 @@ - name: "Add current organizations to the organizations flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -53,7 +54,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the output directory for organizations: {{ output_path + '/' + current_organization_dir.name }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/projects.yml b/roles/filetree_create/tasks/projects.yml index 69710f79a..4cf7a838b 100644 --- a/roles/filetree_create/tasks/projects.yml +++ b/roles/filetree_create/tasks/projects.yml @@ -21,6 +21,7 @@ - name: "Add current projects to the projects flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -53,7 +54,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the /projects output directory for projects in {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/schedules.yml b/roles/filetree_create/tasks/schedules.yml index f1dc8f921..0fc38b364 100644 --- a/roles/filetree_create/tasks/schedules.yml +++ b/roles/filetree_create/tasks/schedules.yml @@ -17,6 +17,7 @@ - name: "Add current schedules to the schedules flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -47,7 +48,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the schedules output directory for schedules in {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/team_roles.yml b/roles/filetree_create/tasks/team_roles.yml index 760d7c106..19a003d6f 100644 --- a/roles/filetree_create/tasks/team_roles.yml +++ b/roles/filetree_create/tasks/team_roles.yml @@ -22,6 +22,7 @@ - name: "Add current team roles to the team roles flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -38,7 +39,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the output directory for team roles: {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/teams.yml b/roles/filetree_create/tasks/teams.yml index bfbe25896..e84807768 100644 --- a/roles/filetree_create/tasks/teams.yml +++ b/roles/filetree_create/tasks/teams.yml @@ -21,6 +21,7 @@ - name: "Add current teams to the teams flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -43,7 +44,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the /teams output directory for teams in {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/user_roles.yml b/roles/filetree_create/tasks/user_roles.yml index 018d3053d..24eab4c86 100644 --- a/roles/filetree_create/tasks/user_roles.yml +++ b/roles/filetree_create/tasks/user_roles.yml @@ -22,6 +22,7 @@ - name: "Add current user roles to the user roles flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -38,7 +39,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the output directory for user roles: {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/users.yml b/roles/filetree_create/tasks/users.yml index f78c95a21..aee2d8f17 100644 --- a/roles/filetree_create/tasks/users.yml +++ b/roles/filetree_create/tasks/users.yml @@ -32,6 +32,7 @@ - name: "Add current users to the users flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -53,7 +54,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the output directory for users in {{ output_path }}" ansible.builtin.file: diff --git a/roles/filetree_create/tasks/workflow_job_templates.yml b/roles/filetree_create/tasks/workflow_job_templates.yml index 87901364d..32e3c56ef 100644 --- a/roles/filetree_create/tasks/workflow_job_templates.yml +++ b/roles/filetree_create/tasks/workflow_job_templates.yml @@ -21,6 +21,7 @@ - name: "Add current workflow_job_templates to the workflow_job_templates flat file" ansible.builtin.blockinfile: create: true + mode: "0644" insertafter: EOF path: "{{ __dest }}" marker: "" @@ -59,7 +60,7 @@ state: absent - name: "Block for to generate the filetre_create normal output" - when: flatten_output is not defined or (flatten_output | bool) == false + when: flatten_output is not defined or not (flatten_output | bool) block: - name: "Create the /workflow_job_templates output directory for workflow job templates in {{ output_path }}" ansible.builtin.file: diff --git a/roles/object_diff/tasks/roles.yml b/roles/object_diff/tasks/roles.yml index f284ccbfa..97d56dabc 100644 --- a/roles/object_diff/tasks/roles.yml +++ b/roles/object_diff/tasks/roles.yml @@ -13,6 +13,7 @@ - name: "Get the API list of all roles" ansible.builtin.set_fact: + # noqa jinja[spacing] __controller_api_roles: "{{ (__controller_api_roles | default([])) + [{ 'users': current_users, 'teams': current_teams, From 574445cec54df9ccd6feb2cad651a4e5d38cbba2 Mon Sep 17 00:00:00 2001 From: ivarmu <26822043+ivarmu@users.noreply.github.com> Date: Wed, 8 Nov 2023 09:26:21 +0100 Subject: [PATCH 4/8] fix missing version for awx in the ci_standalone. Add ansible-playbook example command line for filetree_create --- .github/workflows/ci_standalone.yml | 1 + roles/filetree_create/tests/filetree_create.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/ci_standalone.yml b/.github/workflows/ci_standalone.yml index 6040a803d..3ef020bc1 100644 --- a/.github/workflows/ci_standalone.yml +++ b/.github/workflows/ci_standalone.yml @@ -23,6 +23,7 @@ jobs: - 23.3.0 - 23.0.0 - 22.7.0 + - 21.13.0 uses: "./.github/workflows/ci_standalone_versioned.yml" with: awx_version: ${{ matrix.awx_version }} diff --git a/roles/filetree_create/tests/filetree_create.yml b/roles/filetree_create/tests/filetree_create.yml index e54608a39..19e64aba7 100644 --- a/roles/filetree_create/tests/filetree_create.yml +++ b/roles/filetree_create/tests/filetree_create.yml @@ -47,3 +47,4 @@ status_code: 204 when: controller_oauthtoken_url is defined ... +# ansible-playbook -i localhost, filetree_create.yml -e '{controller_configuration_inventories_enforce_defaults: false, controller_configuration_inventory_sources_enforce_defaults: false, controller_validate_certs: false, controller_hostname: localhost:8443, controller_username: , controller_password: , flatten_output: true}' From b8bfbe6243da8429526351b8f6c851fee7927312 Mon Sep 17 00:00:00 2001 From: ivarmu <26822043+ivarmu@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:01:36 +0100 Subject: [PATCH 5/8] fix versions for awx in the ci_standalone and release --- .github/workflows/ci_standalone.yml | 1 - .github/workflows/release.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/ci_standalone.yml b/.github/workflows/ci_standalone.yml index 3ef020bc1..6040a803d 100644 --- a/.github/workflows/ci_standalone.yml +++ b/.github/workflows/ci_standalone.yml @@ -23,7 +23,6 @@ jobs: - 23.3.0 - 23.0.0 - 22.7.0 - - 21.13.0 uses: "./.github/workflows/ci_standalone_versioned.yml" with: awx_version: ${{ matrix.awx_version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2ba3a0b4..ab4f63af7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,6 @@ jobs: - devel - 22.4.0 - 22.3.0 - - 21.13.0 - 21.11.0 uses: "./.github/workflows/ci_standalone_versioned.yml" with: From 42f547a3bf68cfcf1c49453ad747c5799222ed8a Mon Sep 17 00:00:00 2001 From: ivarmu <26822043+ivarmu@users.noreply.github.com> Date: Wed, 8 Nov 2023 15:26:18 +0100 Subject: [PATCH 6/8] updated README.md. Added ansible-playbook command example --- README.md | 110 ++++++++++++++++++ playbooks/flatten_filetree_create_output.yaml | 10 +- 2 files changed, 118 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 71fa463a5..af447eb4b 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,116 @@ The awx command line can export json that is compatible with this collection. In addition there is an awx.awx/ansible.controller export module that use the awx command line to export. More details can be found [here](EXPORT_README.md) +There's another possible way to export the controller configuration, which is using the `filetree_create` module. It can generate output files in two different ways: + +- **Structured output**: + + The output files are distributed in separate directories, by organization first, and then by object type. Into each of these directories, one file per object is generated. This way allows to organize the files using different criteria, for example, by funcionalities or applications. + + The expotation can be triggered with the following command: + + ```console + ansible-playbook -i localhost, filetree_create.yml -e '{controller_validate_certs: false, controller_hostname: localhost:8443, controller_username: admin, controller_password: password}' + ``` + + One example of this approach follows: + + ```console + /tmp/filetree_output_distributted + ├── current_credential_types.yaml + ├── current_execution_environments.yaml + ├── current_instance_groups.yaml + ├── current_settings.yaml + ├── Default + │   ├── applications + │   │   ├── 23_controller_application-app2.yaml + │   │   └── 24_controller_application-app3.yaml + │   ├── credentials + │   │   ├── 82_Demo Credential.yaml + │   │   └── 84_Demo Custom Credential.yaml + │   ├── current_organization.yaml + │   ├── inventories + │   │   ├── Demo Inventory + │   │   │   └── 81_Demo Inventory.yaml + │   │   └── Test Inventory - Smart + │   │   ├── 78_Test Inventory - Smart.yaml + │   │   └── current_hosts.yaml + │   ├── job_templates + │   │   ├── 177_test-template-1.yaml + │   │   └── 190_Demo Job Template.yaml + │   ├── labels + │   │   ├── 52_Prod.yaml + │   │   ├── 53_differential.yaml + │   ├── notification_templates + │   │   ├── Email notification differential.yaml + │   │   └── Email notification.yaml + │   ├── projects + │   │   ├── 169_Test Project.yaml + │   │   ├── 170_Demo Project.yaml + │   ├── teams + │   │   ├── 28_satellite-qe.yaml + │   │   └── 29_tower-team.yaml + │   └── workflow_job_templates + │   ├── 191_Simple workflow schema.yaml + │   └── 200_Complicated workflow schema.yaml + ├── ORGANIZATIONLESS + │   ├── credentials + │   │   ├── 2_Ansible Galaxy.yaml + │   │   └── 3_Default Execution Environment Registry Credential.yaml + │   └── users + │   ├── admin.yaml + │   ├── controller_user.yaml + ├── schedules + │   ├── 1_Cleanup Job Schedule.yaml + │   ├── 2_Cleanup Activity Schedule.yaml + │   ├── 4_Cleanup Expired Sessions.yaml + │   ├── 52_Demo Schedule.yaml + │   ├── 53_Demo Schedule 2.yaml + │   └── 5_Cleanup Expired OAuth 2 Tokens.yaml + ├── team_roles + │   ├── current_roles_satellite-qe.yaml + │   └── current_roles_tower-team.yaml + └── user_roles + └── current_roles_controller_user.yaml + ``` + +- **Flatten files**: + + The output files are all located in the same directory. Each file contains a YAML list with all the objects belonging to the same object type. This output format allows to load all the objects both from the standard Ansible `group_vars` and from the `infra.controller_configuration.filetree_read` role. + + The expotation can be triggered with the following command: + + ```console + ansible-playbook -i localhost, filetree_create.yml -e '{controller_validate_certs: false, controller_hostname: localhost:8443, controller_username: admin, controller_password: password, flatten_output: true}' + ``` + + One example of this approach follows: + + ```console + /tmp/filetree_output_flatten + ├── applications.yaml + ├── credentials.yaml + ├── current_credential_types.yaml + ├── current_execution_environments.yaml + ├── current_instance_groups.yaml + ├── current_settings.yaml + ├── groups.yaml + ├── hosts.yaml + ├── inventories.yaml + ├── inventory_sources.yaml + ├── job_templates.yaml + ├── labels.yaml + ├── notification_templates.yaml + ├── organizations.yaml + ├── projects.yaml + ├── schedules.yaml + ├── team_roles.yaml + ├── teams.yaml + ├── user_roles.yaml + ├── users.yaml + └── workflow_job_templates.yaml + ``` + ### Template Example A Template to use in order to start using the collections can be found [here](https://github.com/redhat-cop/aap_configuration_template) diff --git a/playbooks/flatten_filetree_create_output.yaml b/playbooks/flatten_filetree_create_output.yaml index cdaacec4e..474e0f81b 100644 --- a/playbooks/flatten_filetree_create_output.yaml +++ b/playbooks/flatten_filetree_create_output.yaml @@ -36,12 +36,14 @@ - name: "Write all the objects to the corresponding file" ansible.builtin.copy: - dest: "{{ filetree_create_output_dir }}_flatten/{{ item.name }}.yaml" + dest: "{{ filetree_create_output_dir }}_flatten/{{ object_type.name }}.yaml" mode: "0644" content: | --- - {{ item.value | to_nice_yaml(indent=2) }} + {{ object_type.value | to_nice_yaml(indent=2) }} ... + loop_control: + loop_var: object_type loop: - name: controller_settings value: "{{ controller_settings }}" @@ -86,3 +88,7 @@ - name: controller_roles value: "{{ controller_roles }}" ... +# Sample usage: +# +# ansible-playbook infra.controller_configuration.flatten_filetree_create_output.yaml -e '{filetree_create_output_dir: /tmp/filetree_output}' +# From fbc150d26ef8fbf12c0634faca762179bb0c5255 Mon Sep 17 00:00:00 2001 From: ivarmu <26822043+ivarmu@users.noreply.github.com> Date: Wed, 8 Nov 2023 15:35:40 +0100 Subject: [PATCH 7/8] Fixed the wrong location for the new information. --- README.md | 110 ------------------------------ roles/filetree_create/README.md | 116 ++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index af447eb4b..71fa463a5 100644 --- a/README.md +++ b/README.md @@ -153,116 +153,6 @@ The awx command line can export json that is compatible with this collection. In addition there is an awx.awx/ansible.controller export module that use the awx command line to export. More details can be found [here](EXPORT_README.md) -There's another possible way to export the controller configuration, which is using the `filetree_create` module. It can generate output files in two different ways: - -- **Structured output**: - - The output files are distributed in separate directories, by organization first, and then by object type. Into each of these directories, one file per object is generated. This way allows to organize the files using different criteria, for example, by funcionalities or applications. - - The expotation can be triggered with the following command: - - ```console - ansible-playbook -i localhost, filetree_create.yml -e '{controller_validate_certs: false, controller_hostname: localhost:8443, controller_username: admin, controller_password: password}' - ``` - - One example of this approach follows: - - ```console - /tmp/filetree_output_distributted - ├── current_credential_types.yaml - ├── current_execution_environments.yaml - ├── current_instance_groups.yaml - ├── current_settings.yaml - ├── Default - │   ├── applications - │   │   ├── 23_controller_application-app2.yaml - │   │   └── 24_controller_application-app3.yaml - │   ├── credentials - │   │   ├── 82_Demo Credential.yaml - │   │   └── 84_Demo Custom Credential.yaml - │   ├── current_organization.yaml - │   ├── inventories - │   │   ├── Demo Inventory - │   │   │   └── 81_Demo Inventory.yaml - │   │   └── Test Inventory - Smart - │   │   ├── 78_Test Inventory - Smart.yaml - │   │   └── current_hosts.yaml - │   ├── job_templates - │   │   ├── 177_test-template-1.yaml - │   │   └── 190_Demo Job Template.yaml - │   ├── labels - │   │   ├── 52_Prod.yaml - │   │   ├── 53_differential.yaml - │   ├── notification_templates - │   │   ├── Email notification differential.yaml - │   │   └── Email notification.yaml - │   ├── projects - │   │   ├── 169_Test Project.yaml - │   │   ├── 170_Demo Project.yaml - │   ├── teams - │   │   ├── 28_satellite-qe.yaml - │   │   └── 29_tower-team.yaml - │   └── workflow_job_templates - │   ├── 191_Simple workflow schema.yaml - │   └── 200_Complicated workflow schema.yaml - ├── ORGANIZATIONLESS - │   ├── credentials - │   │   ├── 2_Ansible Galaxy.yaml - │   │   └── 3_Default Execution Environment Registry Credential.yaml - │   └── users - │   ├── admin.yaml - │   ├── controller_user.yaml - ├── schedules - │   ├── 1_Cleanup Job Schedule.yaml - │   ├── 2_Cleanup Activity Schedule.yaml - │   ├── 4_Cleanup Expired Sessions.yaml - │   ├── 52_Demo Schedule.yaml - │   ├── 53_Demo Schedule 2.yaml - │   └── 5_Cleanup Expired OAuth 2 Tokens.yaml - ├── team_roles - │   ├── current_roles_satellite-qe.yaml - │   └── current_roles_tower-team.yaml - └── user_roles - └── current_roles_controller_user.yaml - ``` - -- **Flatten files**: - - The output files are all located in the same directory. Each file contains a YAML list with all the objects belonging to the same object type. This output format allows to load all the objects both from the standard Ansible `group_vars` and from the `infra.controller_configuration.filetree_read` role. - - The expotation can be triggered with the following command: - - ```console - ansible-playbook -i localhost, filetree_create.yml -e '{controller_validate_certs: false, controller_hostname: localhost:8443, controller_username: admin, controller_password: password, flatten_output: true}' - ``` - - One example of this approach follows: - - ```console - /tmp/filetree_output_flatten - ├── applications.yaml - ├── credentials.yaml - ├── current_credential_types.yaml - ├── current_execution_environments.yaml - ├── current_instance_groups.yaml - ├── current_settings.yaml - ├── groups.yaml - ├── hosts.yaml - ├── inventories.yaml - ├── inventory_sources.yaml - ├── job_templates.yaml - ├── labels.yaml - ├── notification_templates.yaml - ├── organizations.yaml - ├── projects.yaml - ├── schedules.yaml - ├── team_roles.yaml - ├── teams.yaml - ├── user_roles.yaml - ├── users.yaml - └── workflow_job_templates.yaml - ``` - ### Template Example A Template to use in order to start using the collections can be found [here](https://github.com/redhat-cop/aap_configuration_template) diff --git a/roles/filetree_create/README.md b/roles/filetree_create/README.md index 98e3f2199..8bb745205 100644 --- a/roles/filetree_create/README.md +++ b/roles/filetree_create/README.md @@ -79,6 +79,122 @@ A list of other roles hosted on Galaxy should go here, plus any details in regar ... ``` +This role can generate output files in two different ways: + +- **Structured output**: + + The output files are distributed in separate directories, by organization first, and then by object type. Into each of these directories, one file per object is generated. This way allows to organize the files using different criteria, for example, by funcionalities or applications. + + The expotation can be triggered with the following command: + + ```console + ansible-playbook -i localhost, filetree_create.yml -e '{controller_validate_certs: false, controller_hostname: localhost:8443, controller_username: admin, controller_password: password}' + ``` + + One example of this approach follows: + + ```console + /tmp/filetree_output_distributted + ├── current_credential_types.yaml + ├── current_execution_environments.yaml + ├── current_instance_groups.yaml + ├── current_settings.yaml + ├── Default + │   ├── applications + │   │   ├── 23_controller_application-app2.yaml + │   │   └── 24_controller_application-app3.yaml + │   ├── credentials + │   │   ├── 82_Demo Credential.yaml + │   │   └── 84_Demo Custom Credential.yaml + │   ├── current_organization.yaml + │   ├── inventories + │   │   ├── Demo Inventory + │   │   │   └── 81_Demo Inventory.yaml + │   │   └── Test Inventory - Smart + │   │   ├── 78_Test Inventory - Smart.yaml + │   │   └── current_hosts.yaml + │   ├── job_templates + │   │   ├── 177_test-template-1.yaml + │   │   └── 190_Demo Job Template.yaml + │   ├── labels + │   │   ├── 52_Prod.yaml + │   │   ├── 53_differential.yaml + │   ├── notification_templates + │   │   ├── Email notification differential.yaml + │   │   └── Email notification.yaml + │   ├── projects + │   │   ├── 169_Test Project.yaml + │   │   ├── 170_Demo Project.yaml + │   ├── teams + │   │   ├── 28_satellite-qe.yaml + │   │   └── 29_tower-team.yaml + │   └── workflow_job_templates + │   ├── 191_Simple workflow schema.yaml + │   └── 200_Complicated workflow schema.yaml + ├── ORGANIZATIONLESS + │   ├── credentials + │   │   ├── 2_Ansible Galaxy.yaml + │   │   └── 3_Default Execution Environment Registry Credential.yaml + │   └── users + │   ├── admin.yaml + │   ├── controller_user.yaml + ├── schedules + │   ├── 1_Cleanup Job Schedule.yaml + │   ├── 2_Cleanup Activity Schedule.yaml + │   ├── 4_Cleanup Expired Sessions.yaml + │   ├── 52_Demo Schedule.yaml + │   ├── 53_Demo Schedule 2.yaml + │   └── 5_Cleanup Expired OAuth 2 Tokens.yaml + ├── team_roles + │   ├── current_roles_satellite-qe.yaml + │   └── current_roles_tower-team.yaml + └── user_roles + └── current_roles_controller_user.yaml + ``` + +- **Flatten files**: + + The output files are all located in the same directory. Each file contains a YAML list with all the objects belonging to the same object type. This output format allows to load all the objects both from the standard Ansible `group_vars` and from the `infra.controller_configuration.filetree_read` role. + + The expotation can be triggered with the following command: + + ```console + ansible-playbook -i localhost, filetree_create.yml -e '{controller_validate_certs: false, controller_hostname: localhost:8443, controller_username: admin, controller_password: password, flatten_output: true}' + ``` + + One example of this approach follows: + + ```console + /tmp/filetree_output_flatten + ├── applications.yaml + ├── credentials.yaml + ├── current_credential_types.yaml + ├── current_execution_environments.yaml + ├── current_instance_groups.yaml + ├── current_settings.yaml + ├── groups.yaml + ├── hosts.yaml + ├── inventories.yaml + ├── inventory_sources.yaml + ├── job_templates.yaml + ├── labels.yaml + ├── notification_templates.yaml + ├── organizations.yaml + ├── projects.yaml + ├── schedules.yaml + ├── team_roles.yaml + ├── teams.yaml + ├── user_roles.yaml + ├── users.yaml + └── workflow_job_templates.yaml + ``` + +A playbook to convert from the structured output to the flattened one is provided, and can be executed with the following command: + +```console +ansible-playbook infra.controller_configuration.flatten_filetree_create_output.yaml -e '{filetree_create_output_dir: /tmp/filetree_output}' +``` + ## License GPLv3+ From 86bad9b821492314ee02167f376645bc448c48dd Mon Sep 17 00:00:00 2001 From: ivarmu <26822043+ivarmu@users.noreply.github.com> Date: Wed, 8 Nov 2023 16:24:18 +0100 Subject: [PATCH 8/8] Fixed the wrong location for the new information. Fix lintering --- roles/filetree_create/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/filetree_create/README.md b/roles/filetree_create/README.md index 8bb745205..893d30190 100644 --- a/roles/filetree_create/README.md +++ b/roles/filetree_create/README.md @@ -155,13 +155,13 @@ This role can generate output files in two different ways: - **Flatten files**: The output files are all located in the same directory. Each file contains a YAML list with all the objects belonging to the same object type. This output format allows to load all the objects both from the standard Ansible `group_vars` and from the `infra.controller_configuration.filetree_read` role. - + The expotation can be triggered with the following command: ```console ansible-playbook -i localhost, filetree_create.yml -e '{controller_validate_certs: false, controller_hostname: localhost:8443, controller_username: admin, controller_password: password, flatten_output: true}' ``` - + One example of this approach follows: ```console