diff --git a/tests/integration/targets/inventory_gce/aliases b/tests/integration/targets/inventory_gce/aliases new file mode 100644 index 00000000..0e4419e3 --- /dev/null +++ b/tests/integration/targets/inventory_gce/aliases @@ -0,0 +1 @@ +cloud/gcp \ No newline at end of file diff --git a/tests/integration/targets/inventory_gce/playbooks/setup.yml b/tests/integration/targets/inventory_gce/playbooks/setup.yml new file mode 100644 index 00000000..d26ce149 --- /dev/null +++ b/tests/integration/targets/inventory_gce/playbooks/setup.yml @@ -0,0 +1,51 @@ +--- +- name: Setup test suite + hosts: localhost + connection: local + gather_facts: false + vars_files: + - vars.yml + tasks: + - name: SETUP | Create network + google.cloud.gcp_compute_network: + name: "{{ prefix }}" + project: "{{ gcp_project }}" + auth_kind: "{{ gcp_cred_kind }}" + service_account_file: "{{ gcp_cred_file }}" + auto_create_subnetworks: true + state: present + register: _network + + - name: SETUP | Create disks + google.cloud.gcp_compute_disk: + name: "{{ prefix }}-{{ item.name }}" + size_gb: 20 + zone: "{{ gcp_zone }}" + project: "{{ gcp_project }}" + service_account_file: "{{ gcp_cred_file }}" + source_image: "{{ gcp_disk_image }}" + auth_kind: "{{ gcp_cred_kind }}" + state: present + register: _disks + loop: "{{ sut }}" + + - name: SETUP | Create instance + google.cloud.gcp_compute_instance: + name: "{{ prefix }}-{{ item.name }}" + machine_type: n1-standard-1 + disks: + - auto_delete: true + boot: true + source: "{{ _disks.results[idx] }}" + network_interfaces: + - network: "{{ _network }}" + labels: "{{ item.labels | default({}) }}" + hostname: "{{ item.hostname | default(omit) }}" + zone: "{{ gcp_zone }}" + project: "{{ gcp_project }}" + auth_kind: "{{ gcp_cred_kind }}" + service_account_file: "{{ gcp_cred_file }}" + state: present + loop: "{{ sut }}" + loop_control: + index_var: idx diff --git a/tests/integration/targets/inventory_gce/playbooks/teardown.yml b/tests/integration/targets/inventory_gce/playbooks/teardown.yml new file mode 100644 index 00000000..b4e48041 --- /dev/null +++ b/tests/integration/targets/inventory_gce/playbooks/teardown.yml @@ -0,0 +1,38 @@ +--- +- name: Teardown test suite + hosts: localhost + connection: local + gather_facts: false + vars_files: + - vars.yml + tasks: + - name: TEARDOWN | Delete instance # noqa: ignore-errors + google.cloud.gcp_compute_instance: + name: "{{ prefix }}-{{ item.name }}" + zone: "{{ gcp_zone }}" + project: "{{ gcp_project }}" + auth_kind: "{{ gcp_cred_kind }}" + service_account_file: "{{ gcp_cred_file }}" + state: absent + loop: "{{ sut }}" + ignore_errors: true # try to delete as much as possible + + - name: TEARDOWN | Delete disk # noqa: ignore-errors + google.cloud.gcp_compute_disk: + name: "{{ prefix }}-{{ item.name }}" + zone: "{{ gcp_zone }}" + project: "{{ gcp_project }}" + service_account_file: "{{ gcp_cred_file }}" + source_image: "{{ gcp_disk_image }}" + auth_kind: "{{ gcp_cred_kind }}" + state: absent + loop: "{{ sut }}" + ignore_errors: true # try to delete as much as possible + + - name: TEARDOWN | Delete network + google.cloud.gcp_compute_network: + name: "{{ prefix }}" + project: "{{ gcp_project }}" + auth_kind: "{{ gcp_cred_kind }}" + service_account_file: "{{ gcp_cred_file }}" + state: absent diff --git a/tests/integration/targets/inventory_gce/playbooks/test.yml b/tests/integration/targets/inventory_gce/playbooks/test.yml new file mode 100644 index 00000000..da119970 --- /dev/null +++ b/tests/integration/targets/inventory_gce/playbooks/test.yml @@ -0,0 +1,30 @@ +--- +- name: Test + hosts: localhost + connection: local + gather_facts: false + vars_files: + - vars.yml + tasks: + - name: TEST | render inventory file + ansible.builtin.copy: + dest: "../{{ inventory_filename }}" + content: "{{ lookup('template', '../templates/inventory.yml.j2') }}" + mode: preserve + + - name: slurp + ansible.builtin.slurp: + src: "../{{ inventory_filename }}" + register: _inv + + - name: debug + ansible.builtin.debug: + msg: "{{ _inv.content | b64decode }}" + verbosity: 3 + + - name: TEST | refresh inventory + ansible.builtin.meta: refresh_inventory + + - name: TEST | run test case + ansible.builtin.include_tasks: + file: "testcase_{{ testcase }}.yml" diff --git a/tests/integration/targets/inventory_gce/playbooks/testcase_basic.yml b/tests/integration/targets/inventory_gce/playbooks/testcase_basic.yml new file mode 100644 index 00000000..0f0841ee --- /dev/null +++ b/tests/integration/targets/inventory_gce/playbooks/testcase_basic.yml @@ -0,0 +1,16 @@ +--- +- name: TEST | print hosts + ansible.builtin.debug: + var: groups + +- name: TEST | assert instances exist + ansible.builtin.assert: + that: + - groups['all'] | length > 0 + +- name: TEST | assert grouping works + ansible.builtin.assert: + that: + - groups['gcp_env_prod'] | length == 2 + - groups['gcp_cluster_db'] | length == 1 + - groups['gcp_cluster_web'] | length == 1 diff --git a/tests/integration/targets/inventory_gce/playbooks/testcase_hostname.yml b/tests/integration/targets/inventory_gce/playbooks/testcase_hostname.yml new file mode 100644 index 00000000..1bcf3224 --- /dev/null +++ b/tests/integration/targets/inventory_gce/playbooks/testcase_hostname.yml @@ -0,0 +1,22 @@ +--- +- name: TEST | print hosts + ansible.builtin.debug: + var: groups + +- name: TEST | fetch instance info for vm1 + google.cloud.gcp_compute_instance_info: + filters: + - name = {{ prefix }}-vm1 + zone: "{{ gcp_zone }}" + project: "{{ gcp_project }}" + auth_kind: "{{ gcp_cred_kind }}" + service_account_file: "{{ gcp_cred_file }}" + scopes: + - https://www.googleapis.com/auth/compute + register: _vm + +- name: TEST | compare API vs inventory hostnames + ansible.builtin.assert: + that: + - _vm.resources | length > 0 + - _vm.resources[0].hostname in groups['gcp_dns_static'] diff --git a/tests/integration/targets/inventory_gce/playbooks/vars.yml b/tests/integration/targets/inventory_gce/playbooks/vars.yml new file mode 100644 index 00000000..87e8d04d --- /dev/null +++ b/tests/integration/targets/inventory_gce/playbooks/vars.yml @@ -0,0 +1,38 @@ +--- +gcp_region: us-central1 +gcp_zones: + - "{{ gcp_region }}-a" + - "{{ gcp_region }}-b" + - "{{ gcp_region }}-c" + - "{{ gcp_region }}-f" +gcp_zone: "{{ gcp_zones | first }}" +gcp_disk_image: projects/centos-cloud/global/images/centos-stream-9-v20250513 + +prefix: "{{ resource_prefix | default('d3adb33f') }}" +sut: + - name: vm1 + hostname: "vm1.static.{{ prefix }}.com" + labels: + dns: static + - name: vm2 + labels: + cluster: db + env: prod + - name: vm3 + labels: + cluster: web + env: prod + +testcase: basic +testcases: + basic: + filters: + - status = RUNNING + hostnames: + - name + hostname: + hostnames: + - hostname + - name + +inventory_filename: test.gcp_compute.yml diff --git a/tests/integration/targets/inventory_gce/runme.sh b/tests/integration/targets/inventory_gce/runme.sh new file mode 100755 index 00000000..6eec2599 --- /dev/null +++ b/tests/integration/targets/inventory_gce/runme.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +set -eux + +# test infra +ansible-playbook playbooks/setup.yml "$@" + +export ANSIBLE_INVENTORY=test.gcp_compute.yml + +RC=0 +# we want to run teardown regardless of playbook exit status, so catch the +# exit code of ansible-playbook manually +set +e +for ts in playbooks/testcase_*.yml; +do + testcase="$( basename $ts | sed -e 's/testcase_//' | sed -e 's/.yml//' )" + ansible-playbook playbooks/test.yml "$@" --extra-vars "testcase=${testcase}" + RC=$? + test $RC -ne 0 && break +done +set -e + +unset ANSIBLE_INVENTORY + +# delete test infra +ansible-playbook playbooks/teardown.yml "$@" + +exit $RC diff --git a/tests/integration/targets/inventory_gce/templates/inventory.yml.j2 b/tests/integration/targets/inventory_gce/templates/inventory.yml.j2 new file mode 100644 index 00000000..ff0d3ec0 --- /dev/null +++ b/tests/integration/targets/inventory_gce/templates/inventory.yml.j2 @@ -0,0 +1,27 @@ +--- +plugin: google.cloud.gcp_compute + +zones: +{{ gcp_zones | to_nice_yaml }} +projects: +- {{ gcp_project }} + +auth_kind: {{ gcp_cred_kind }} + +service_account_file: {{ gcp_cred_file }} + +scopes: +- 'https://www.googleapis.com/auth/cloud-platform' +- 'https://www.googleapis.com/auth/compute.readonly' + +keyed_groups: +- prefix: gcp + key: labels + +name_suffix: .{{ prefix }}.com + +filters: +{{ testcases[testcase]['filters'] | default(testcases['basic']['filters']) | default([]) | to_nice_yaml }} + +hostnames: +{{ testcases[testcase]['hostnames'] | default(testcases['basic']['hostnames']) | default([]) | to_nice_yaml }} diff --git a/tests/integration/targets/inventory_gce/test.gcp_compute.yml b/tests/integration/targets/inventory_gce/test.gcp_compute.yml new file mode 100644 index 00000000..7c6a5ed2 --- /dev/null +++ b/tests/integration/targets/inventory_gce/test.gcp_compute.yml @@ -0,0 +1 @@ +# keep empty