From 0e24782c3c623c659840eff30ba5c3161ecfa47b Mon Sep 17 00:00:00 2001 From: "jasonpage.tas" Date: Wed, 14 Aug 2024 13:52:25 +1000 Subject: [PATCH] feat(playbooks): migration of centurion playbooks to github gh pr checkout 17 --- playbooks/centurion_teams.yaml | 244 +++++++++++++++++++++++++++++++++ playbooks/itsm_inventory.yaml | 171 +++++++++++++++++++++++ 2 files changed, 415 insertions(+) create mode 100644 playbooks/centurion_teams.yaml create mode 100644 playbooks/itsm_inventory.yaml diff --git a/playbooks/centurion_teams.yaml b/playbooks/centurion_teams.yaml new file mode 100644 index 0000000..8967e89 --- /dev/null +++ b/playbooks/centurion_teams.yaml @@ -0,0 +1,244 @@ +- name: Centurion ERP Teams Setup + hosts: |- + {%- if nfc_pb_host is defined -%} + {{ nfc_pb_host }} + {%- else -%} + all + {%- endif %} + become: false + gather_facts: false + connection: local # Play uses HTTP requests ONLY!! + + + tasks: + + + - name: Confirm required vars exist + ansible.builtin.assert: + that: + - centurion_erp.teams is defined + - | + centurion_erp.teams is not mapping + and + centurion_erp.teams is iterable + and + centurion_erp.teams is not string + + msg: "Missing required variable or it's of the incorrect type[list]" + run_once: true + delegate_to: localhost + + + - name: Collect organizations from centurion ERP + ansible.builtin.uri: + url: |- + {{ lookup('env', 'CENTURION_API') }}/api/organization/ + method: GET + body_format: json + headers: + authorization: Token {{ lookup('env', 'CENTURION_TOKEN') }} + validate_certs: "{{ lookup('env', 'VALIDATE_CENTURION_CERTS') | default(true) | bool }}" + return_content: true + status_code: + - 200 + register: api_get_organizations + run_once: true + delegate_to: localhost + no_log: > # Contains a secret that logging shows + {{ nfc_pb_disable_log | default(true) }} + + + - name: Collect teams from centurion ERP + ansible.builtin.uri: + url: "{{ item }}" + method: GET + body_format: json + headers: + authorization: Token {{ lookup('env', 'CENTURION_TOKEN') }} + validate_certs: "{{ lookup('env', 'VALIDATE_CENTURION_CERTS') | default(true) | bool }}" + return_content: true + status_code: + - 200 + loop: "{{ api_get_organizations.json.results | map(attribute='url') | list }}" + register: api_get_permissions + run_once: true + delegate_to: localhost + no_log: > # Contains a secret that logging shows + {{ nfc_pb_disable_log | default(true) }} + + + - name: Create list of Teams + ansible.builtin.set_fact: + team_permissions: | + [ + {% for config_organisation in centurion_erp.teams %} + + {% set ns = namespace(added_teams = []) %} + + {% for config_team in config_organisation.teams %} + + {% for organization in api_get_permissions.results %} + + {% if organization.json.name == config_organisation.name %} + + {% for team in organization.json.teams %} + + {% if team.team_name == config_team.name %} + + { + "organization_id": "{{ organization.json.id }}", + "team_name": "{{ team.team_name }}", + "url": "{{ team.url }}", + "notes": "{{ config_team.notes }}", + "permissions": + {{ config_team.permissions }} + }, + + {% set ns.added_teams = ns.added_teams + [ config_team.name ] %} + + {% endif %} + + {% endfor %} + + {% endif %} + + {% endfor %} + + {% if config_team.name not in ns.added_teams %} + { + "organization_id": + {% for organization in api_get_permissions.results %} + {% if organization.json.name == config_organisation.name %} + "{{ organization.json.id }}", + {% endif %} + {% endfor %} + "team_name": "{{ config_team.name }}", + "notes": "{{ config_team.notes }}", + "permissions": + {{ config_team.permissions }} + }, + {% set ns.added_teams = ns.added_teams + [ config_team.name ] %} + + {% endif %} + + {% endfor %} + + {% endfor %} + ] + delegate_to: localhost + run_once: true + no_log: > # Contains a secret that logging shows + {{ nfc_pb_disable_log | default(true) }} + + + - name: Create new teams in centurion_ERP + ansible.builtin.uri: + url: |- + {{ lookup('env', 'CENTURION_API') }}/api/organization/{{ item.organization_id }}/team + method: POST + body_format: json + body: |- + { + "team_name": "{{ item.team_name }}" + } + headers: + Authorization: Token {{ lookup('env', 'CENTURION_TOKEN') }} + validate_certs: "{{ lookup('env', 'VALIDATE_CENTURION_CERTS') | default(true) | bool }}" + status_code: + - 201 + when: > + item.url is not defined + loop: "{{ team_permissions | list }}" + register: api_post_teams + delegate_to: localhost + run_once: true + no_log: > # Contains a secret that logging shows + {{ nfc_pb_disable_log | default(true) }} + + + - name: update permissions to include newly created teams + ansible.builtin.set_fact: + team_permissions: | + [ + {% for team in team_permissions %} + + { + "organization_id": "{{ team.organization_id }}", + "team_name": "{{ team.team_name }}", + "notes": "{{ team.notes }}", + "permissions": + {{ team.permissions }}, + "url": + {% if team.url is defined %} + "{{ team.url }}", + + {% elif team.url is not defined %} + + {% for api_values in api_post_teams.results %} + + {% if api_values.item.organization_id == team.organization_id %} + + {% if api_values.json.team_name == team.team_name %} + + "{{ api_values.json.url }}", + + {% endif %} + + {% endif %} + + {% endfor %} + + {% endif %} + }, + + {% endfor %} + ] + delegate_to: localhost + run_once: true + no_log: > # Contains a secret that logging shows + {{ nfc_pb_disable_log | default(true) }} + + + - name: Patch team permissions + ansible.builtin.uri: + url: |- + {{ item.url }}permissions + method: PATCH + body_format: json + body: "{{ item.permissions }}" + headers: + Authorization: Token {{ lookup('env', 'CENTURION_TOKEN') }} + validate_certs: "{{ lookup('env', 'VALIDATE_CENTURION_CERTS') | default(true) | bool }}" + status_code: + - 200 + when: > + item.url is defined + loop: "{{ team_permissions | list }}" + delegate_to: localhost + run_once: true + no_log: > # Contains a secret that logging shows + {{ nfc_pb_disable_log | default(true) }} + + + - name: Patch team notes + ansible.builtin.uri: + url: |- + {{ item.url }} + method: PATCH + body_format: json + body: |- + { + "model_notes": "{{ item.notes }}" + } + headers: + Authorization: Token {{ lookup('env', 'CENTURION_TOKEN') }} + validate_certs: "{{ lookup('env', 'VALIDATE_CENTURION_CERTS') | default(true) | bool }}" + status_code: + - 200 + when: > + item.url is defined + loop: "{{ team_permissions | list }}" + delegate_to: localhost + run_once: true + no_log: > # Contains a secret that logging shows + {{ nfc_pb_disable_log | default(true) }} diff --git a/playbooks/itsm_inventory.yaml b/playbooks/itsm_inventory.yaml new file mode 100644 index 0000000..d0f2673 --- /dev/null +++ b/playbooks/itsm_inventory.yaml @@ -0,0 +1,171 @@ +- name: Inventory + hosts: |- + {%- if nfc_pb_host is defined -%} + {{ nfc_pb_host }} + {%- else -%} + all + {%- endif %} + become: true + + + + tasks: + + - name: Inventory host + block: + + - name: Test Packages + ansible.builtin.package_facts: + manager: auto + become: true + + + + - name: Inventory Details + ansible.builtin.set_fact: + details: { + "name": "{{ ansible_hostname }}", + "serial_number": "{{ ansible_product_serial }}", + "uuid": "{{ ansible_product_uuid }}" + } + + + - name: Inventory Software [a-k] + ansible.builtin.set_fact: + cacheable: false + software: "{{ software | default([]) + [{ + 'name': package.value[0].name, + 'category': package.value[0].category | default(''), + 'version': package.value[0].version + }] }}" + # no_log: true + loop: "{{ ansible_facts.packages | dict2items() }}" + loop_control: + loop_var: package + label: "{{ package.key }}" + when: > + package.value[0].name | regex_search("^[a-k]") + + +# - name: Inventory Software [l] +# ansible.builtin.set_fact: +# cacheable: false +# software: "{{ software | default([]) + [{ +# 'name': package.value[0].name, +# 'category': package.value[0].category | default(''), +# 'version': package.value[0].version +# }] }}" +# # no_log: true +# loop: "{{ ansible_facts.packages | dict2items() }}" +# loop_control: +# loop_var: package +# label: "{{ package.key }}" +# when: > +# package.value[0].name | regex_search("^[l]") + + + - name: Inventory Software [m-z] + ansible.builtin.set_fact: + cacheable: false + software: "{{ software | default([]) + [{ + 'name': package.value[0].name, + 'category': package.value[0].category | default(''), + 'version': package.value[0].version + }] }}" + # no_log: true + loop: "{{ ansible_facts.packages | dict2items() }}" + loop_control: + loop_var: package + label: "{{ package.key }}" + when: > + package.value[0].name | regex_search("^[m-z]") + + + - name: Inventory Document + ansible.builtin.set_fact: + report: { + "details": "{{ details }}", + "os": { + "name": "{{ ansible_distribution | lower }}", + "version": "{{ ansible_distribution_version }}", + "version_major": "{{ ansible_distribution_major_version }}" + }, + "software": "{{ software }}" + } + + + - name: Save report + ansible.builtin.copy: + content: "{{ report | to_nice_json }}" + dest: "/tmp/{{ ansible_hostname }}.json" + + + - name: Upload inventory - {{ ansible_hostname }} + ansible.builtin.uri: + url: |- + {{ lookup('env', 'ITSM_API') }}/api/device/inventory + + method: POST + body_format: json + src: "/tmp/{{ ansible_hostname }}.json" + remote_src: true + headers: + Authorization: Token {{ lookup('env', 'ITSM_TOKEN') }} + validate_certs: "{{ lookup('env', 'ITSM_VALIDATE_CERTS') | default(true) | bool }}" + timeout: 300 + status_code: + - 200 + - 201 + no_log: > # Contains a secret that logging shows + {{ nfc_pb_disable_log | default(true) }} + + always: + - name: Remove report + ansible.builtin.file: + path: "/tmp/{{ ansible_hostname }}.json" + state: absent + + vars: + + nfc_pb_awx_tower_template: + + - name: "ITSM/Machine/Inventory" + ask_tags_on_launch: false + ask_inventory_on_launch: true + ask_credential_on_launch: true + ask_limit_on_launch: true + concurrent_jobs_enabled: true + description: Collect inventory of host machines and publish to itsm django + execution_environment: "No Fuss Computing EE" + job_type: "run" + # job_tags: complete + labels: + - itsm + - itam + - inventory + use_fact_cache: true + credential_types: + - name: 'Playbook/Inventory/Django ITSM' + description: | + Credentials for authentication to the django ITSM application + inputs: | + fields: + - id: itsm_url + type: string + label: itsm url + help_text: Ensure that `https://` is prefixed to url + - id: itsm_token + type: string + label: api token + secret: true + - id: itsm_validate_certs + type: boolean + label: Validate SSL Certificate + required: + - itsm_api + - itsm_token + injectors: > + env: + ITSM_API: '{{ itsm_url }}' + ITSM_TOKEN: '{{ itsm_token }}' + ITSM_VALIDATE_CERTS: '{{ itsm_validate_certs | default(true) }}'