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: 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/playbooks/flatten_filetree_create_output.yaml b/playbooks/flatten_filetree_create_output.yaml new file mode 100644 index 000000000..474e0f81b --- /dev/null +++ b/playbooks/flatten_filetree_create_output.yaml @@ -0,0 +1,94 @@ +--- +- 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 + mode: "0755" + + - name: "Write all the objects to the corresponding file" + ansible.builtin.copy: + dest: "{{ filetree_create_output_dir }}_flatten/{{ object_type.name }}.yaml" + mode: "0644" + content: | + --- + {{ object_type.value | to_nice_yaml(indent=2) }} + ... + loop_control: + loop_var: object_type + 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 }}" +... +# Sample usage: +# +# ansible-playbook infra.controller_configuration.flatten_filetree_create_output.yaml -e '{filetree_create_output_dir: /tmp/filetree_output}' +# diff --git a/roles/filetree_create/README.md b/roles/filetree_create/README.md index cfc66f5e9..893d30190 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 @@ -78,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+ diff --git a/roles/filetree_create/tasks/applications.yml b/roles/filetree_create/tasks/applications.yml index 5fbcaf85d..1d8b7a9c9 100644 --- a/roles/filetree_create/tasks/applications.yml +++ b/roles/filetree_create/tasks/applications.yml @@ -11,32 +11,67 @@ 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 + mode: "0644" + 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 not (flatten_output | bool) + 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..fdee02e91 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,78 @@ 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" + ansible.builtin.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 + mode: "0644" + 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 not (flatten_output | bool) + 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..97e27b956 100644 --- a/roles/filetree_create/tasks/credentials.yml +++ b/roles/filetree_create/tasks/credentials.yml @@ -11,32 +11,67 @@ 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 + mode: "0644" + 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 not (flatten_output | bool) + 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..cec0dbfb7 100644 --- a/roles/filetree_create/tasks/groups.yml +++ b/roles/filetree_create/tasks/groups.yml @@ -1,14 +1,39 @@ --- -- 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 + mode: "0644" + 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 not (flatten_output | bool) + 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..514929fcf 100644 --- a/roles/filetree_create/tasks/hosts.yml +++ b/roles/filetree_create/tasks/hosts.yml @@ -1,14 +1,39 @@ --- -- 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 + mode: "0644" + 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 not (flatten_output | bool) + 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..fd05db1f9 100644 --- a/roles/filetree_create/tasks/inventory.yml +++ b/roles/filetree_create/tasks/inventory.yml @@ -12,47 +12,99 @@ 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 + mode: "0644" + 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 not (flatten_output | bool) + 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 +114,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 +138,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..0c67ca6cf 100644 --- a/roles/filetree_create/tasks/inventory_sources.yml +++ b/roles/filetree_create/tasks/inventory_sources.yml @@ -1,15 +1,40 @@ --- -- 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 + mode: "0644" + 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 not (flatten_output | bool) + 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 3a5125052..90f7076bf 100644 --- a/roles/filetree_create/tasks/job_templates.yml +++ b/roles/filetree_create/tasks/job_templates.yml @@ -11,45 +11,93 @@ 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' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool 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 }}" + __dest: "{{ output_path }}/job_templates.yaml" + block: + - name: "Add current job_templates to the job_templates flat file" + ansible.builtin.blockinfile: + create: true + mode: "0644" + 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('/', '_') }}" + 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: "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 not (flatten_output | bool) + 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/labels.yml b/roles/filetree_create/tasks/labels.yml index db9f44fcc..d54144e74 100644 --- a/roles/filetree_create/tasks/labels.yml +++ b/roles/filetree_create/tasks/labels.yml @@ -11,32 +11,67 @@ 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 + mode: "0644" + 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 not (flatten_output | bool) + 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..5aa2da2d9 100644 --- a/roles/filetree_create/tasks/notification_templates.yml +++ b/roles/filetree_create/tasks/notification_templates.yml @@ -11,29 +11,61 @@ 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 + mode: "0644" + 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 not (flatten_output | bool) + 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..f2de44b6f 100644 --- a/roles/filetree_create/tasks/organizations.yml +++ b/roles/filetree_create/tasks/organizations.yml @@ -11,40 +11,85 @@ 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 + mode: "0644" + 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 not (flatten_output | bool) + 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..4cf7a838b 100644 --- a/roles/filetree_create/tasks/projects.yml +++ b/roles/filetree_create/tasks/projects.yml @@ -11,42 +11,87 @@ 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 + mode: "0644" + 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 not (flatten_output | bool) + 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..0fc38b364 100644 --- a/roles/filetree_create/tasks/schedules.yml +++ b/roles/filetree_create/tasks/schedules.yml @@ -7,32 +7,75 @@ }}" 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 + mode: "0644" + 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 not (flatten_output | bool) + 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 1db22c86d..19a003d6f 100644 --- a/roles/filetree_create/tasks/team_roles.yml +++ b/roles/filetree_create/tasks/team_roles.yml @@ -7,18 +7,52 @@ }}" 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: "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' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool vars: - current_team_roles_asset_value: "{{ team_roles_lookvar }}" - when: team_roles_lookvar | length > 0 + __dest: "{{ output_path }}/team_roles.yaml" + block: + - name: "Stat if the output file exists" + ansible.builtin.stat: + path: "{{ __dest }}" + register: team_roles_file + + - name: "Add current team roles to the team roles flat file" + ansible.builtin.blockinfile: + create: true + mode: "0644" + insertafter: EOF + path: "{{ __dest }}" + marker: "" + block: "{{ lookup('template', 'templates/current_team_roles.j2') }}" + vars: + current_team_roles_asset_value: "{{ team_roles_lookvar }}" + 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 not (flatten_output | bool) + 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..e84807768 100644 --- a/roles/filetree_create/tasks/teams.yml +++ b/roles/filetree_create/tasks/teams.yml @@ -11,42 +11,79 @@ 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' +- name: "Block for to generate flatten output" + when: + - flatten_output is defined + - flatten_output | bool 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 }}" + __dest: "{{ output_path }}/teams.yaml" + block: + - name: "Add current teams to the teams flat file" + ansible.builtin.blockinfile: + create: true + mode: "0644" + 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('/', '_') }}" + 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: "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 not (flatten_output | bool) + 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/tasks/user_roles.yml b/roles/filetree_create/tasks/user_roles.yml index cd4335327..24eab4c86 100644 --- a/roles/filetree_create/tasks/user_roles.yml +++ b/roles/filetree_create/tasks/user_roles.yml @@ -7,18 +7,52 @@ }}" 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 + mode: "0644" + 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 not (flatten_output | bool) + 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..aee2d8f17 100644 --- a/roles/filetree_create/tasks/users.yml +++ b/roles/filetree_create/tasks/users.yml @@ -22,41 +22,77 @@ 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 + mode: "0644" + 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 not (flatten_output | bool) + 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..32e3c56ef 100644 --- a/roles/filetree_create/tasks/workflow_job_templates.yml +++ b/roles/filetree_create/tasks/workflow_job_templates.yml @@ -11,48 +11,99 @@ 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 + mode: "0644" + 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 not (flatten_output | bool) + 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 a5e848b41..c9c160cbc 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 | default(0)) == 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') }}" @@ -50,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 %} @@ -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 | 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 61dda0ae9..d70d0a080 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 | default(true) | 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 | default(true) | bool %} ... +{% endif %} diff --git a/roles/filetree_create/templates/current_teams.j2 b/roles/filetree_create/templates/current_teams.j2 index d8f471e24..259c47df8 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 | 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 | 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 %} 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}' 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,