From 5745bdaac2d36f380c77aab492ac5f73754e98b2 Mon Sep 17 00:00:00 2001 From: Jorge Gallegos Date: Thu, 4 Sep 2025 19:28:23 -0700 Subject: [PATCH] Integration test for new IAP connection plugin 1. creates instances with a custom ssh keypair 2. change the connection plugin method and perform basic checks 3. cleanup --- .../targets/connection_plugin/aliases | 1 + .../connection_plugin/playbooks/setup.yml | 66 +++++++++++++++++++ .../connection_plugin/playbooks/teardown.yml | 34 ++++++++++ .../connection_plugin/playbooks/test.yml | 25 +++++++ .../targets/connection_plugin/runme.sh | 25 +++++++ .../templates/inventory.yml.j2 | 31 +++++++++ .../connection_plugin/test.gcp_compute.yml | 1 + .../targets/connection_plugin/vars.yml | 32 +++++++++ 8 files changed, 215 insertions(+) create mode 100644 tests/integration/targets/connection_plugin/aliases create mode 100644 tests/integration/targets/connection_plugin/playbooks/setup.yml create mode 100644 tests/integration/targets/connection_plugin/playbooks/teardown.yml create mode 100644 tests/integration/targets/connection_plugin/playbooks/test.yml create mode 100755 tests/integration/targets/connection_plugin/runme.sh create mode 100644 tests/integration/targets/connection_plugin/templates/inventory.yml.j2 create mode 100644 tests/integration/targets/connection_plugin/test.gcp_compute.yml create mode 100644 tests/integration/targets/connection_plugin/vars.yml diff --git a/tests/integration/targets/connection_plugin/aliases b/tests/integration/targets/connection_plugin/aliases new file mode 100644 index 00000000..26507c23 --- /dev/null +++ b/tests/integration/targets/connection_plugin/aliases @@ -0,0 +1 @@ +cloud/gcp diff --git a/tests/integration/targets/connection_plugin/playbooks/setup.yml b/tests/integration/targets/connection_plugin/playbooks/setup.yml new file mode 100644 index 00000000..128feaeb --- /dev/null +++ b/tests/integration/targets/connection_plugin/playbooks/setup.yml @@ -0,0 +1,66 @@ +--- +- name: Setup test suite + hosts: localhost + connection: local + gather_facts: false + vars_files: + - ../vars.yml + environment: + GCP_SERVICE_ACCOUNT_FILE: "{{ gcp_cred_file }}" + GCP_AUTH_KIND: "{{ gcp_cred_kind }}" + GCP_PROJECT: "{{ gcp_project }}" + tasks: + - name: SETUP | Create SSH key pair + community.crypto.openssh_keypair: + path: "{{ ansible_ssh_private_key_file }}" + type: ed25519 + register: _keypair + + - name: SETUP | Create network + google.cloud.gcp_compute_network: + name: "{{ prefix }}" + auto_create_subnetworks: true + state: present + register: _network + + - name: SETUP | Allow SSH through IAP + google.cloud.gcp_compute_firewall: + name: all-iap + state: present + source_ranges: + - 35.235.240.0/20 + allowed: + - ip_protocol: tcp + ports: + - 22 + network: "{{ _network }}" + + - name: SETUP | Create instances + google.cloud.gcp_compute_instance: + name: "{{ prefix }}-{{ item.name }}" + machine_type: "{{ gcp_machine_type }}" + disks: + - auto_delete: true + boot: true + initialize_params: + source_image: "{{ gcp_disk_image }}" + disk_type: pd-standard + network_interfaces: + - network: "{{ _network }}" + metadata: + ssh-keys: "{{ ansible_ssh_user }}:{{ _keypair.public_key }}" + labels: "{{ item.labels | default({}) }}" + hostname: "{{ item.hostname | default(omit) }}" + zone: "{{ gcp_zone }}" + state: present + loop: "{{ sut }}" + + - name: SETUP | Render dynamic inventory file + ansible.builtin.copy: + dest: ../test.gcp_compute.yml + content: "{{ lookup('template', '../templates/inventory.yml.j2') }}" + mode: preserve + + - name: SETUP | Give time for instances to be up + ansible.builtin.pause: + seconds: 30 diff --git a/tests/integration/targets/connection_plugin/playbooks/teardown.yml b/tests/integration/targets/connection_plugin/playbooks/teardown.yml new file mode 100644 index 00000000..9c598267 --- /dev/null +++ b/tests/integration/targets/connection_plugin/playbooks/teardown.yml @@ -0,0 +1,34 @@ +--- +- name: Teardown test suite + hosts: localhost + connection: local + gather_facts: false + vars_files: + - ../vars.yml + environment: + GCP_SERVICE_ACCOUNT_FILE: "{{ gcp_cred_file }}" + GCP_AUTH_KIND: "{{ gcp_cred_kind }}" + GCP_PROJECT: "{{ gcp_project }}" + tasks: + - name: TEARDOWN | Destroy instances # noqa: ignore-errors + google.cloud.gcp_compute_instance: + name: "{{ prefix }}-{{ item.name }}" + machine_type: "{{ gcp_machine_type }}" + zone: "{{ gcp_zone }}" + state: absent + loop: "{{ sut }}" + ignore_errors: true + + - name: TEARDOWN | Remove IAP firewall rule # noqa: ignore-errors + google.cloud.gcp_compute_firewall: + name: all-iap + state: absent + network: + selfLink: "networks/{{ prefix }}" + ignore_errors: true + + - name: TEARDOWN | Destroy network # noqa: ignore-errors + google.cloud.gcp_compute_network: + name: "{{ prefix }}" + state: absent + ignore_errors: true diff --git a/tests/integration/targets/connection_plugin/playbooks/test.yml b/tests/integration/targets/connection_plugin/playbooks/test.yml new file mode 100644 index 00000000..94c7fef9 --- /dev/null +++ b/tests/integration/targets/connection_plugin/playbooks/test.yml @@ -0,0 +1,25 @@ +--- +- name: Test IAP connection plugin + hosts: gcp_cluster_web:gcp_cluster_db + connection: google.cloud.iap + gather_facts: false + vars_files: + - ../vars.yml + tasks: + - name: TEST | Ping + ansible.builtin.ping: + + - name: TEST | Copy + ansible.builtin.copy: + content: "Test file test" + dest: "/tmp/{{ prefix }}.txt" + mode: "0644" + + - name: TEST | Slurp + ansible.builtin.slurp: + src: "/tmp/{{ prefix }}.txt" + register: _content + + - name: TEST | Debug + ansible.builtin.debug: + msg: "{{ _content['content'] | b64decode }}" diff --git a/tests/integration/targets/connection_plugin/runme.sh b/tests/integration/targets/connection_plugin/runme.sh new file mode 100755 index 00000000..678cb6a6 --- /dev/null +++ b/tests/integration/targets/connection_plugin/runme.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -eux + +# test infra +ansible-playbook playbooks/setup.yml "$@" + +export ANSIBLE_INVENTORY=test.gcp_compute.yml + +ansible-inventory --graph + +RC=0 +# we want to run teardown regardless of playbook exit status, so catch the +# exit code of ansible-playbook manually +set +e +ansible-playbook -vvvvv playbooks/test.yml "$@" +RC=$? +set -e + +unset ANSIBLE_INVENTORY + +# delete test infra +ansible-playbook playbooks/teardown.yml "$@" + +exit $RC diff --git a/tests/integration/targets/connection_plugin/templates/inventory.yml.j2 b/tests/integration/targets/connection_plugin/templates/inventory.yml.j2 new file mode 100644 index 00000000..ae83258e --- /dev/null +++ b/tests/integration/targets/connection_plugin/templates/inventory.yml.j2 @@ -0,0 +1,31 @@ +--- +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 + +filters: +- 'labels.test:{{ prefix }}' + +hostnames: +- name + +# set variables for the connection plugin +compose: + ansible_gcloud_zone: zone + ansible_gcloud_project: project diff --git a/tests/integration/targets/connection_plugin/test.gcp_compute.yml b/tests/integration/targets/connection_plugin/test.gcp_compute.yml new file mode 100644 index 00000000..fdffa2a0 --- /dev/null +++ b/tests/integration/targets/connection_plugin/test.gcp_compute.yml @@ -0,0 +1 @@ +# placeholder diff --git a/tests/integration/targets/connection_plugin/vars.yml b/tests/integration/targets/connection_plugin/vars.yml new file mode 100644 index 00000000..dde5fcd0 --- /dev/null +++ b/tests/integration/targets/connection_plugin/vars.yml @@ -0,0 +1,32 @@ +--- +prefix: "{{ resource_prefix | default('d3adb33f') }}" + +gcp_region: us-central1 +gcp_zones: + - "{{ gcp_region }}-a" + - "{{ gcp_region }}-b" + - "{{ gcp_region }}-c" + - "{{ gcp_region }}-f" +gcp_zone: "{{ gcp_zones | last }}" +gcp_disk_image: projects/centos-cloud/global/images/family/centos-stream-9 +gcp_machine_type: g1-small + +sut: + - name: vm1 + labels: + test: "{{ prefix }}" + cluster: web + - name: vm2 + labels: + test: "{{ prefix }}" + cluster: web + - name: vm3 + labels: + test: "{{ prefix }}" + cluster: db + +ansible_python_interpreter: /usr/bin/python3 + +# these are only useful when connection != local +ansible_ssh_user: cloud-user +ansible_ssh_private_key_file: "{{ playbook_dir }}/ssh_key"