From 1200460f26646493f42be0a83775710c18dfe7af Mon Sep 17 00:00:00 2001 From: Jeff Geerling Date: Wed, 12 Feb 2020 12:07:19 -0600 Subject: [PATCH 1/6] Issue #10: Attempt setting up a KinD cluster in CI workflow.g --- .github/workflows/ansible-test.yml | 40 ++++++++++++++++++++++++++++-- README.md | 9 +++++++ codecov.yml | 1 + galaxy.yml | 1 + molecule/default/molecule.yml | 34 +++++++++++++++++++++++++ molecule/default/playbook.yml | 23 +++++++++++++++++ 6 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 molecule/default/molecule.yml create mode 100644 molecule/default/playbook.yml diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index e0872b94..9761fe48 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -1,6 +1,6 @@ +--- name: CI -on: - push: +'on': pull_request: schedule: - cron: '0 6 * * *' @@ -53,3 +53,39 @@ jobs: - name: Upload coverage data run: tests/coverage.sh + + molecule: + runs-on: ubuntu-latest + strategy: + matrix: + python_version: ['3.7'] + steps: + - name: Check out code + uses: actions/checkout@v1 + with: + path: ansible_collections/community/kubernetes + + - name: Set up KinD cluster + uses: engineerd/setup-kind@v0.3.0 + + - name: Set up Python ${{ matrix.python_version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python_version }} + + - name: Install molecule and openshift dependencies + run: pip install molecule openshift + + - name: Install ansible-base + run: pip install git+https://github.com/ansible-collection-migration/ansible-base.git --disable-pip-version-check + + - name: Create default collection path symlink + run: | + mkdir -p /home/runner/.ansible + ln -s /home/runner/work/kubernetes /home/runner/.ansible/collections + + - name: Copy kubernetes integration test role into roles directory. + run: cp -R tests/integration/targets/kubernetes roles/ + + - name: Run molecule default test scenario + run: molecule --debug test diff --git a/README.md b/README.md index ecbf5577..2ad55d1e 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,8 @@ For documentation on how to use individual modules and other content included in If you want to develop new content for this collection or improve what's already here, the easiest way to work on the collection is to clone it into one of the configured [`COLLECTIONS_PATHS`](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#collections-paths), and work on it there. +### Testing with `ansible-test` + The `tests` directory contains configuration for running sanity and integration tests using [`ansible-test`](https://docs.ansible.com/ansible/latest/dev_guide/testing_integration.html). You can run the collection's test suites with the commands: @@ -112,6 +114,13 @@ You can run the collection's test suites with the commands: ansible-test sanity --docker -v --color ansible-test integration --docker -v --color +### Testing with `molecule` + +There are also integration tests in the `molecule` directory which are meant to be run against a local Kubernetes cluster, e.g. using [KinD](https://kind.sigs.k8s.io) or [Minikube](https://minikube.sigs.k8s.io). To run the tests, set up a local cluster, then run Molecule: + + kind create cluster + molecule test + ## Publishing New Versions The current process for publishing new versions of the Kubernetes Collection is manual, and requires a user who has access to the `community.kubernetes` namespace on Ansible Galaxy to publish the build artifact. diff --git a/codecov.yml b/codecov.yml index f0f6358e..33c8f6ee 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,3 +1,4 @@ +--- coverage: precision: 2 round: down diff --git a/galaxy.yml b/galaxy.yml index 069d5af1..5c57a6e3 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,3 +1,4 @@ +--- authors: - chouseknecht (https://github.com/chouseknecht) - geerlingguy (https://www.jeffgeerling.com/) diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml new file mode 100644 index 00000000..be33836a --- /dev/null +++ b/molecule/default/molecule.yml @@ -0,0 +1,34 @@ +--- +driver: + name: delegated + options: + managed: false + login_cmd_template: 'docker exec -ti {instance} bash' + ansible_connection_options: + ansible_connection: docker +lint: + name: yamllint + options: + config-data: + line-length: + max: 160 +platforms: + - name: instance-kind +provisioner: + name: ansible + log: true + lint: {} + inventory: + host_vars: + localhost: + ansible_python_interpreter: '{{ ansible_playbook_python }}' + env: + ANSIBLE_ROLES_PATH: ${ANSIBLE_ROLES_PATH}:../../tests/integration/targets +scenario: + name: default + test_sequence: + # - lint + - syntax + - converge + - idempotence + - verify diff --git a/molecule/default/playbook.yml b/molecule/default/playbook.yml new file mode 100644 index 00000000..3b628765 --- /dev/null +++ b/molecule/default/playbook.yml @@ -0,0 +1,23 @@ +--- +- name: Converge + hosts: localhost + connection: local + gather_facts: false + + collections: + - community.kubernetes + + tasks: + - name: Testing. + k8s_info: + namespace: kube-system + kind: Pod + register: pod_list + + - name: Testing listing. + debug: + msg: "{{ pod_list.resources | count }}" + + - name: Include Kubernetes integration testing role. + include_role: + name: kubernetes From b2e639b82365d37b288153ca7c37801125b7a555 Mon Sep 17 00:00:00 2001 From: Jeff Geerling Date: Thu, 13 Feb 2020 11:21:26 -0600 Subject: [PATCH 2/6] Issue #10: Move integration tests into molecule playbook. --- .github/workflows/ansible-test.yml | 10 ++- molecule/default/molecule.yml | 4 +- molecule/default/playbook.yml | 18 +++-- .../default}/tasks/append_hash.yml | 0 .../default}/tasks/apply.yml | 41 +++++----- .../default}/tasks/crd.yml | 23 +++--- .../default}/tasks/delete.yml | 32 +++----- .../default/tasks/full.yml | 52 +++++------- .../default}/tasks/lists.yml | 0 .../default}/tasks/waiter.yml | 80 +++++++++---------- molecule/default/vars/main.yml | 33 ++++++++ .../targets/kubernetes/defaults/main.yml | 32 +------- .../files/manifest-example/MANIFEST.json | 43 ++++++++++ .../files/manifest-example/README.md | 5 ++ .../targets/kubernetes/tasks/main.yml | 23 ++---- 15 files changed, 205 insertions(+), 191 deletions(-) rename {tests/integration/targets/kubernetes => molecule/default}/tasks/append_hash.yml (100%) rename {tests/integration/targets/kubernetes => molecule/default}/tasks/apply.yml (82%) rename {tests/integration/targets/kubernetes => molecule/default}/tasks/crd.yml (60%) rename {tests/integration/targets/kubernetes => molecule/default}/tasks/delete.yml (75%) rename tests/integration/targets/kubernetes/tasks/full_test.yml => molecule/default/tasks/full.yml (90%) rename {tests/integration/targets/kubernetes => molecule/default}/tasks/lists.yml (100%) rename {tests/integration/targets/kubernetes => molecule/default}/tasks/waiter.yml (82%) create mode 100644 molecule/default/vars/main.yml create mode 100644 tests/integration/targets/kubernetes/files/manifest-example/MANIFEST.json create mode 100644 tests/integration/targets/kubernetes/files/manifest-example/README.md diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index 9761fe48..04b3903b 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -84,8 +84,12 @@ jobs: mkdir -p /home/runner/.ansible ln -s /home/runner/work/kubernetes /home/runner/.ansible/collections - - name: Copy kubernetes integration test role into roles directory. - run: cp -R tests/integration/targets/kubernetes roles/ + # TODO: Once community.general is on public Galaxy, drop the -s. + - name: Install community.general role to get json_query filter. + run: | + cp tests/integration/targets/kubernetes/files/manifest-example/MANIFEST.json MANIFEST.json + pip install jmespath + ansible-galaxy collection install -vvv -s https://sivel.eng.ansible.com/api community.general - name: Run molecule default test scenario - run: molecule --debug test + run: molecule test diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index be33836a..41cf5521 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -23,12 +23,10 @@ provisioner: localhost: ansible_python_interpreter: '{{ ansible_playbook_python }}' env: - ANSIBLE_ROLES_PATH: ${ANSIBLE_ROLES_PATH}:../../tests/integration/targets + ANSIBLE_FORCE_COLOR: 'true' scenario: name: default test_sequence: - # - lint - syntax - converge - - idempotence - verify diff --git a/molecule/default/playbook.yml b/molecule/default/playbook.yml index 3b628765..8a85279c 100644 --- a/molecule/default/playbook.yml +++ b/molecule/default/playbook.yml @@ -7,17 +7,21 @@ collections: - community.kubernetes + vars_files: + - vars/main.yml + tasks: - - name: Testing. + - name: Verify cluster is working. k8s_info: namespace: kube-system kind: Pod register: pod_list - - name: Testing listing. - debug: - msg: "{{ pod_list.resources | count }}" + - name: Verify cluster has more than 5 pods running. + assert: + that: (pod_list.resources | count) > 5 - - name: Include Kubernetes integration testing role. - include_role: - name: kubernetes + - include_tasks: tasks/delete.yml + - include_tasks: tasks/apply.yml + - include_tasks: tasks/waiter.yml + - include_tasks: tasks/full.yml diff --git a/tests/integration/targets/kubernetes/tasks/append_hash.yml b/molecule/default/tasks/append_hash.yml similarity index 100% rename from tests/integration/targets/kubernetes/tasks/append_hash.yml rename to molecule/default/tasks/append_hash.yml diff --git a/tests/integration/targets/kubernetes/tasks/apply.yml b/molecule/default/tasks/apply.yml similarity index 82% rename from tests/integration/targets/kubernetes/tasks/apply.yml rename to molecule/default/tasks/apply.yml index 20ecd9c8..f5362220 100644 --- a/tests/integration/targets/kubernetes/tasks/apply.yml +++ b/molecule/default/tasks/apply.yml @@ -1,14 +1,9 @@ +--- - block: - # TODO: Not available in ansible-base - # - python_requirements_info: - # dependencies: - # - openshift - # - kubernetes - - set_fact: apply_namespace: apply - - name: ensure namespace exists + - name: Ensure namespace exists k8s: definition: apiVersion: v1 @@ -16,7 +11,7 @@ metadata: name: "{{ apply_namespace }}" - - name: add a configmap + - name: Add a configmap k8s: name: "apply-configmap" namespace: "{{ apply_namespace }}" @@ -30,13 +25,13 @@ apply: yes register: k8s_configmap - - name: check configmap was created + - name: Check configmap was created assert: that: - k8s_configmap is changed - k8s_configmap.result.metadata.annotations|default(False) - - name: add same configmap again + - name: Add same configmap again k8s: definition: kind: ConfigMap @@ -51,12 +46,12 @@ apply: yes register: k8s_configmap_2 - - name: check nothing changed + - name: Check nothing changed assert: that: - k8s_configmap_2 is not changed - - name: add same configmap again with check mode on + - name: Add same configmap again with check mode on k8s: definition: kind: ConfigMap @@ -72,12 +67,12 @@ check_mode: yes register: k8s_configmap_check - - name: check nothing changed + - name: Check nothing changed assert: that: - k8s_configmap_check is not changed - - name: add same configmap again but using name and namespace args + - name: Add same configmap again but using name and namespace args k8s: name: "apply-configmap" namespace: "{{ apply_namespace }}" @@ -91,12 +86,12 @@ apply: yes register: k8s_configmap_2a - - name: check nothing changed + - name: Check nothing changed assert: that: - k8s_configmap_2a is not changed - - name: update configmap + - name: Update configmap k8s: definition: kind: ConfigMap @@ -111,14 +106,14 @@ apply: yes register: k8s_configmap_3 - - name: ensure that configmap has been correctly updated + - name: Ensure that configmap has been correctly updated assert: that: - k8s_configmap_3 is changed - "'four' in k8s_configmap_3.result.data" - "'two' not in k8s_configmap_3.result.data" - - name: add a service + - name: Add a service k8s: definition: apiVersion: v1 @@ -136,7 +131,7 @@ apply: yes register: k8s_service - - name: add exactly same service + - name: Add exactly same service k8s: definition: apiVersion: v1 @@ -154,12 +149,12 @@ apply: yes register: k8s_service_2 - - name: check nothing changed + - name: Check nothing changed assert: that: - k8s_service_2 is not changed - - name: change service ports + - name: Change service ports k8s: definition: apiVersion: v1 @@ -177,7 +172,7 @@ apply: yes register: k8s_service_3 - - name: check ports are correct + - name: Check ports are correct assert: that: - k8s_service_3 is changed @@ -185,7 +180,7 @@ - k8s_service_3.result.spec.ports[0].port == 8081 always: - - name: remove namespace + - name: Remove namespace k8s: kind: Namespace name: "{{ apply_namespace }}" diff --git a/tests/integration/targets/kubernetes/tasks/crd.yml b/molecule/default/tasks/crd.yml similarity index 60% rename from tests/integration/targets/kubernetes/tasks/crd.yml rename to molecule/default/tasks/crd.yml index c9e47632..11b4d17c 100644 --- a/tests/integration/targets/kubernetes/tasks/crd.yml +++ b/molecule/default/tasks/crd.yml @@ -1,33 +1,28 @@ -# TODO: This is the only way I could get the kubeconfig, I don't know why. Running the lookup outside of debug seems to return an empty string -#- debug: msg={{ lookup('env', 'K8S_AUTH_KUBECONFIG') }} -# register: kubeconfig - -# Kubernetes resources - +--- - block: - name: Create a namespace k8s: name: crd kind: Namespace - - name: install custom resource definitions + - name: Install custom resource definitions k8s: - definition: "{{ lookup('file', role_path + '/files/setup-crd.yml') }}" + definition: "{{ lookup('file', kubernetes_role_path + '/files/setup-crd.yml') }}" - - name: pause 5 seconds to avoid race condition + - name: Pause 5 seconds to avoid race condition pause: seconds: 5 - name: create custom resource definition k8s: - definition: "{{ lookup('file', role_path + '/files/crd-resource.yml') }}" + definition: "{{ lookup('file', kubernetes_role_path + '/files/crd-resource.yml') }}" namespace: crd apply: "{{ create_crd_with_apply | default(omit) }}" register: create_crd - name: patch custom resource definition k8s: - definition: "{{ lookup('file', role_path + '/files/crd-resource.yml') }}" + definition: "{{ lookup('file', kubernetes_role_path + '/files/crd-resource.yml') }}" namespace: crd register: recreate_crd ignore_errors: yes @@ -40,14 +35,14 @@ - block: - name: recreate custom resource definition with merge_type k8s: - definition: "{{ lookup('file', role_path + '/files/crd-resource.yml') }}" + definition: "{{ lookup('file', kubernetes_role_path + '/files/crd-resource.yml') }}" merge_type: merge namespace: crd register: recreate_crd_with_merge - name: recreate custom resource definition with merge_type list k8s: - definition: "{{ lookup('file', role_path + '/files/crd-resource.yml') }}" + definition: "{{ lookup('file', kubernetes_role_path + '/files/crd-resource.yml') }}" merge_type: - strategic-merge - merge @@ -58,7 +53,7 @@ - name: remove crd k8s: - definition: "{{ lookup('file', role_path + '/files/crd-resource.yml') }}" + definition: "{{ lookup('file', kubernetes_role_path + '/files/crd-resource.yml') }}" namespace: crd state: absent diff --git a/tests/integration/targets/kubernetes/tasks/delete.yml b/molecule/default/tasks/delete.yml similarity index 75% rename from tests/integration/targets/kubernetes/tasks/delete.yml rename to molecule/default/tasks/delete.yml index fef6e5e9..2c00be0e 100644 --- a/tests/integration/targets/kubernetes/tasks/delete.yml +++ b/molecule/default/tasks/delete.yml @@ -1,13 +1,9 @@ -- name: ensure that there are actually some nodes - k8s_info: - kind: Node - register: nodes - +--- - block: - set_fact: delete_namespace: delete - - name: ensure namespace exists + - name: Ensure namespace exists k8s: definition: apiVersion: v1 @@ -15,10 +11,10 @@ metadata: name: "{{ delete_namespace }}" - - name: add a daemonset + - name: Add a daemonset k8s: definition: - apiVersion: extensions/v1beta1 + apiVersion: apps/v1 kind: DaemonSet metadata: name: delete-daemonset @@ -35,12 +31,12 @@ k8s_pod_image: gcr.io/kuar-demo/kuard-amd64:1 register: ds - - name: check that daemonset wait worked + - name: Check that daemonset wait worked assert: that: - ds.result.status.currentNumberScheduled == ds.result.status.desiredNumberScheduled - - name: check if pods exist + - name: Check if pods exist k8s_info: namespace: "{{ delete_namespace }}" kind: Pod @@ -50,12 +46,12 @@ k8s_pod_name: delete-ds register: pods_create - - name: assert that there are pods + - name: Assert that there are pods assert: that: - pods_create.resources - - name: remove the daemonset + - name: Remove the daemonset k8s: kind: DaemonSet name: delete-daemonset @@ -63,7 +59,7 @@ state: absent wait: yes - - name: show status of pods + - name: Show status of pods k8s_info: namespace: "{{ delete_namespace }}" kind: Pod @@ -72,11 +68,11 @@ vars: k8s_pod_name: delete-ds - - name: wait for background deletion + - name: Wait for background deletion pause: seconds: 30 - - name: check if pods still exist + - name: Check if pods still exist k8s_info: namespace: "{{ delete_namespace }}" kind: Pod @@ -86,16 +82,14 @@ k8s_pod_name: delete-ds register: pods_delete - - name: assert that deleting the daemonset deleted the pods + - name: Assert that deleting the daemonset deleted the pods assert: that: - not pods_delete.resources always: - - name: remove namespace + - name: Remove namespace k8s: kind: Namespace name: "{{ delete_namespace }}" state: absent - - when: (nodes.resources | length) > 0 diff --git a/tests/integration/targets/kubernetes/tasks/full_test.yml b/molecule/default/tasks/full.yml similarity index 90% rename from tests/integration/targets/kubernetes/tasks/full_test.yml rename to molecule/default/tasks/full.yml index fdf3d700..7eec9280 100644 --- a/tests/integration/targets/kubernetes/tasks/full_test.yml +++ b/molecule/default/tasks/full.yml @@ -1,13 +1,4 @@ -# TODO: This is the only way I could get the kubeconfig, I don't know why. Running the lookup outside of debug seems to return an empty string -#- debug: msg={{ lookup('env', 'K8S_AUTH_KUBECONFIG') }} -# register: kubeconfig - -# Kubernetes resources - -- include_tasks: delete.yml -- include_tasks: apply.yml -- include_tasks: waiter.yml - +--- - block: - name: Create a namespace k8s: @@ -19,24 +10,25 @@ debug: var: output - - name: Setting validate_certs to true causes a failure - k8s: - name: testing - kind: Namespace - validate_certs: yes - ignore_errors: yes - register: output - - - name: assert that validate_certs caused a failure (and therefore was correctly translated to verify_ssl) - assert: - that: - - output is failed + # TODO: See https://github.com/ansible-collections/kubernetes/pull/22#issuecomment-585852073 + # - name: Setting validate_certs to true causes a failure + # k8s: + # name: testing + # kind: Namespace + # validate_certs: yes + # ignore_errors: yes + # register: output + # + # - name: assert that validate_certs caused a failure (and therefore was correctly translated to verify_ssl) + # assert: + # that: + # - output is failed - name: k8s_info works with empty resources k8s_info: kind: Deployment namespace: testing - api_version: extensions/v1beta1 + api_version: apps/v1 register: k8s_info - name: assert that k8s_info is in correct format @@ -134,7 +126,7 @@ k8s: state: present inline: &deployment - apiVersion: extensions/v1beta1 + apiVersion: apps/v1 kind: Deployment metadata: name: elastic @@ -143,6 +135,11 @@ service: elastic namespace: testing spec: + replicas: 1 + selector: + matchLabels: + app: galaxy + service: elastic template: metadata: labels: @@ -160,7 +157,6 @@ - name: elastic-volume persistentVolumeClaim: claimName: elastic-volume - replicas: 1 strategy: type: RollingUpdate register: output @@ -179,12 +175,6 @@ assert: that: not output.changed - - debug: - var: k8s_openshift - - - include: openshift.yml - when: k8s_openshift | bool - ### Type tests - name: Create a namespace from a string k8s: diff --git a/tests/integration/targets/kubernetes/tasks/lists.yml b/molecule/default/tasks/lists.yml similarity index 100% rename from tests/integration/targets/kubernetes/tasks/lists.yml rename to molecule/default/tasks/lists.yml diff --git a/tests/integration/targets/kubernetes/tasks/waiter.yml b/molecule/default/tasks/waiter.yml similarity index 82% rename from tests/integration/targets/kubernetes/tasks/waiter.yml rename to molecule/default/tasks/waiter.yml index 757d7899..26402c86 100644 --- a/tests/integration/targets/kubernetes/tasks/waiter.yml +++ b/molecule/default/tasks/waiter.yml @@ -1,13 +1,9 @@ -- name: ensure that there are actually some nodes - k8s_info: - kind: Node - register: nodes - +--- - block: - set_fact: wait_namespace: wait - - name: ensure namespace exists + - name: Ensure namespace exists k8s: definition: apiVersion: v1 @@ -15,7 +11,7 @@ metadata: name: "{{ wait_namespace }}" - - name: add a simple pod + - name: Add a simple pod k8s: definition: apiVersion: v1 @@ -34,15 +30,15 @@ register: wait_pod ignore_errors: yes - - name: assert that pod creation succeeded + - name: Assert that pod creation succeeded assert: that: - wait_pod is successful - - name: add a daemonset + - name: Add a daemonset k8s: definition: - apiVersion: extensions/v1beta1 + apiVersion: apps/v1 kind: DaemonSet metadata: name: wait-daemonset @@ -60,15 +56,15 @@ k8s_pod_image: gcr.io/kuar-demo/kuard-amd64:1 register: ds - - name: check that daemonset wait worked + - name: Check that daemonset wait worked assert: that: - ds.result.status.currentNumberScheduled == ds.result.status.desiredNumberScheduled - - name: update a daemonset in check_mode + - name: Update a daemonset in check_mode k8s: definition: - apiVersion: extensions/v1beta1 + apiVersion: apps/v1 kind: DaemonSet metadata: name: wait-daemonset @@ -88,15 +84,15 @@ k8s_pod_image: gcr.io/kuar-demo/kuard-amd64:2 register: update_ds_check_mode - - name: check that check_mode returned changed + - name: Check that check_mode returned changed assert: that: - update_ds_check_mode is changed - - name: update a daemonset + - name: Update a daemonset k8s: definition: - apiVersion: extensions/v1beta1 + apiVersion: apps/v1 kind: DaemonSet metadata: name: wait-daemonset @@ -116,7 +112,7 @@ k8s_pod_image: gcr.io/kuar-demo/kuard-amd64:3 register: ds - - name: get updated pods + - name: Get updated pods k8s_info: api_version: v1 kind: Pod @@ -125,13 +121,13 @@ - app=wait-ds register: updated_ds_pods - - name: check that daemonset wait worked + - name: Check that daemonset wait worked assert: that: - ds.result.status.currentNumberScheduled == ds.result.status.desiredNumberScheduled - updated_ds_pods.resources[0].spec.containers[0].image.endswith(":3") - - name: add a crashing pod + - name: Add a crashing pod k8s: definition: apiVersion: v1 @@ -151,12 +147,12 @@ register: crash_pod ignore_errors: yes - - name: check that task failed + - name: Check that task failed assert: that: - crash_pod is failed - - name: use a non-existent image + - name: Use a non-existent image k8s: definition: apiVersion: v1 @@ -174,15 +170,15 @@ register: no_image_pod ignore_errors: yes - - name: check that task failed + - name: Check that task failed assert: that: - no_image_pod is failed - - name: add a deployment + - name: Add a deployment k8s: definition: - apiVersion: extensions/v1beta1 + apiVersion: apps/v1 kind: Deployment metadata: name: wait-deploy @@ -204,15 +200,15 @@ register: deploy - - name: check that deployment wait worked + - name: Check that deployment wait worked assert: that: - deploy.result.status.availableReplicas == deploy.result.status.replicas - - name: update a deployment + - name: Update a deployment k8s: definition: - apiVersion: extensions/v1beta1 + apiVersion: apps/v1 kind: Deployment metadata: name: wait-deploy @@ -233,7 +229,7 @@ protocol: TCP register: update_deploy - - name: get updated pods + - name: Get updated pods k8s_info: api_version: v1 kind: Pod @@ -242,16 +238,16 @@ - app=wait-deploy register: updated_deploy_pods - - name: check that deployment wait worked + - name: Check that deployment wait worked assert: that: - deploy.result.status.availableReplicas == deploy.result.status.replicas - updated_deploy_pods.resources[0].spec.containers[0].image.endswith(":2") - - name: pause a deployment + - name: Pause a deployment k8s: definition: - apiVersion: extensions/v1beta1 + apiVersion: apps/v1 kind: Deployment metadata: name: wait-deploy @@ -266,15 +262,15 @@ reason: DeploymentPaused register: pause_deploy - - name: check that paused deployment wait worked + - name: Check that paused deployment wait worked assert: that: - condition.reason == "DeploymentPaused" - condition.status == "Unknown" vars: - condition: '{{ pause_deploy.result.status.conditions | json_query("[?type==`Progressing`]") | first }}' + condition: '{{ pause_deploy.result.status.conditions | community.general.json_query("[?type==`Progressing`]") | first }}' - - name: add a service based on the deployment + - name: Add a service based on the deployment k8s: definition: apiVersion: v1 @@ -294,15 +290,15 @@ k8s_pod_name: wait-deploy register: service - - name: assert that waiting for service works + - name: Assert that waiting for service works assert: that: - service is successful - - name: add a crashing deployment + - name: Add a crashing deployment k8s: definition: - apiVersion: extensions/v1beta1 + apiVersion: apps/v1 kind: Deployment metadata: name: wait-crash-deploy @@ -322,12 +318,12 @@ register: wait_crash_deploy ignore_errors: yes - - name: check that task failed + - name: Check that task failed assert: that: - wait_crash_deploy is failed - - name: remove Pod with very short timeout + - name: Remove Pod with very short timeout k8s: api_version: v1 kind: Pod @@ -340,16 +336,14 @@ ignore_errors: yes register: short_wait_remove_pod - - name: check that task failed + - name: Check that task failed assert: that: - short_wait_remove_pod is failed always: - - name: remove namespace + - name: Remove namespace k8s: kind: Namespace name: "{{ wait_namespace }}" state: absent - - when: (nodes.resources | length) > 0 diff --git a/molecule/default/vars/main.yml b/molecule/default/vars/main.yml new file mode 100644 index 00000000..27670cfc --- /dev/null +++ b/molecule/default/vars/main.yml @@ -0,0 +1,33 @@ +--- +recreate_crd_default_merge_expectation: recreate_crd is not failed + +k8s_pod_metadata: + labels: + app: "{{ k8s_pod_name }}" + +k8s_pod_spec: + containers: + - image: "{{ k8s_pod_image }}" + imagePullPolicy: Always + name: "{{ k8s_pod_name }}" + command: "{{ k8s_pod_command }}" + readinessProbe: + initialDelaySeconds: 15 + exec: + command: + - /bin/true + resources: + limits: + cpu: "100m" + memory: "100Mi" + ports: "{{ k8s_pod_ports }}" + +k8s_pod_command: [] + +k8s_pod_ports: [] + +k8s_pod_template: + metadata: "{{ k8s_pod_metadata }}" + spec: "{{ k8s_pod_spec }}" + +kubernetes_role_path: ../../tests/integration/targets/kubernetes diff --git a/tests/integration/targets/kubernetes/defaults/main.yml b/tests/integration/targets/kubernetes/defaults/main.yml index 68fde7c4..d1271d67 100644 --- a/tests/integration/targets/kubernetes/defaults/main.yml +++ b/tests/integration/targets/kubernetes/defaults/main.yml @@ -1,32 +1,4 @@ +--- recreate_crd_default_merge_expectation: recreate_crd is not failed -k8s_pod_metadata: - labels: - app: "{{ k8s_pod_name }}" - -k8s_pod_spec: - containers: - - image: "{{ k8s_pod_image }}" - imagePullPolicy: Always - name: "{{ k8s_pod_name }}" - command: "{{ k8s_pod_command }}" - readinessProbe: - initialDelaySeconds: 15 - exec: - command: - - /bin/true - resources: - limits: - cpu: "100m" - memory: "100Mi" - ports: "{{ k8s_pod_ports }}" - -k8s_pod_command: [] - -k8s_pod_ports: [] - -k8s_pod_template: - metadata: "{{ k8s_pod_metadata }}" - spec: "{{ k8s_pod_spec }}" - -k8s_openshift: yes +k8s_openshift: true diff --git a/tests/integration/targets/kubernetes/files/manifest-example/MANIFEST.json b/tests/integration/targets/kubernetes/files/manifest-example/MANIFEST.json new file mode 100644 index 00000000..ef7258e5 --- /dev/null +++ b/tests/integration/targets/kubernetes/files/manifest-example/MANIFEST.json @@ -0,0 +1,43 @@ +{ + "collection_info": { + "namespace": "community", + "name": "kubernetes", + "version": "1.0.0", + "authors": [ + "chouseknecht (https://github.com/chouseknecht)", + "geerlingguy (https://www.jeffgeerling.com/)", + "maxamillion (https://github.com/maxamillion)", + "jmontleon (https://github.com/jmontleon)", + "fabianvf (https://github.com/fabianvf)", + "willthames (https://github.com/willthames)", + "mmazur (https://github.com/mmazur)", + "jamescassell (https://github.com/jamescassell)" + ], + "readme": "README.md", + "tags": [ + "kubernetes", + "k8s", + "cloud", + "infrastructure", + "openshift", + "okd", + "cluster" + ], + "description": "Kubernetes Collection for Ansible.", + "license": [], + "license_file": "LICENSE", + "dependencies": {}, + "repository": "https://github.com/ansible-collections/kubernetes", + "documentation": "", + "homepage": "", + "issues": "https://github.com/ansible-collections/kubernetes/issues" + }, + "file_manifest_file": { + "name": "FILES.json", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "38d130899a6e46be25cbde550675c62b55827a79c3cfe29dc43fecd8e1de7ef6", + "format": 1 + }, + "format": 1 +} \ No newline at end of file diff --git a/tests/integration/targets/kubernetes/files/manifest-example/README.md b/tests/integration/targets/kubernetes/files/manifest-example/README.md new file mode 100644 index 00000000..17f3a4bb --- /dev/null +++ b/tests/integration/targets/kubernetes/files/manifest-example/README.md @@ -0,0 +1,5 @@ +# MANIFEST.json README + +This manifest file is used in the test environment to overcome a bug currently in Ansible core: https://github.com/ansible/ansible/issues/67399 + +Once that bug is fixed, this file can be removed, along with the `cp` command used in the CI GitHub Actions workflow for this repository. diff --git a/tests/integration/targets/kubernetes/tasks/main.yml b/tests/integration/targets/kubernetes/tasks/main.yml index 706cb4dd..d1416915 100644 --- a/tests/integration/targets/kubernetes/tasks/main.yml +++ b/tests/integration/targets/kubernetes/tasks/main.yml @@ -72,23 +72,10 @@ state: absent no_log: yes -# Run full test suite +# Test openshift -- pip: - name: - - openshift>=0.9.2 - - coverage - virtualenv: "{{ virtualenv }}" - virtualenv_command: "{{ virtualenv_command }}" - virtualenv_site_packages: no +- debug: + var: k8s_openshift -- include_tasks: full_test.yml - vars: - ansible_python_interpreter: "{{ virtualenv_interpreter }}" - create_crd_with_apply: no - playbook_namespace: ansible-test-k8s-full - -- file: - path: "{{ virtualenv }}" - state: absent - no_log: yes +- include: openshift.yml + when: k8s_openshift | bool From 6dafb4c1dbdf01f9a2ffc25b1333976cecdce2a8 Mon Sep 17 00:00:00 2001 From: Jeff Geerling Date: Thu, 13 Feb 2020 15:05:22 -0600 Subject: [PATCH 3/6] Issue #10: Don't add dependent collections when installing community.general. --- .github/workflows/ansible-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index 04b3903b..3e2958bb 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -89,7 +89,7 @@ jobs: run: | cp tests/integration/targets/kubernetes/files/manifest-example/MANIFEST.json MANIFEST.json pip install jmespath - ansible-galaxy collection install -vvv -s https://sivel.eng.ansible.com/api community.general + ansible-galaxy collection install --no-deps -s https://sivel.eng.ansible.com/api community.general - name: Run molecule default test scenario run: molecule test From 15641b6323974bf33f1948ea9f3ff44124c8e689 Mon Sep 17 00:00:00 2001 From: Jeff Geerling Date: Thu, 13 Feb 2020 15:29:45 -0600 Subject: [PATCH 4/6] More debugging. --- molecule/default/tasks/full.yml | 2 +- molecule/default/tasks/waiter.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/molecule/default/tasks/full.yml b/molecule/default/tasks/full.yml index 7eec9280..0130507a 100644 --- a/molecule/default/tasks/full.yml +++ b/molecule/default/tasks/full.yml @@ -10,7 +10,7 @@ debug: var: output - # TODO: See https://github.com/ansible-collections/kubernetes/pull/22#issuecomment-585852073 + # TODO: See https://github.com/ansible-collections/kubernetes/issues/24 # - name: Setting validate_certs to true causes a failure # k8s: # name: testing diff --git a/molecule/default/tasks/waiter.yml b/molecule/default/tasks/waiter.yml index 26402c86..689efac0 100644 --- a/molecule/default/tasks/waiter.yml +++ b/molecule/default/tasks/waiter.yml @@ -262,6 +262,8 @@ reason: DeploymentPaused register: pause_deploy + - debug: var=pause_deploy + - name: Check that paused deployment wait worked assert: that: From a75593c36acfbdb735cb9eac1c0ceb9a84a3fb64 Mon Sep 17 00:00:00 2001 From: Jeff Geerling Date: Thu, 13 Feb 2020 15:47:24 -0600 Subject: [PATCH 5/6] Attempt to resolve #23 entirely without a json_query(). --- .github/workflows/ansible-test.yml | 7 --- molecule/default/tasks/waiter.yml | 4 +- .../files/manifest-example/MANIFEST.json | 43 ------------------- .../files/manifest-example/README.md | 5 --- 4 files changed, 1 insertion(+), 58 deletions(-) delete mode 100644 tests/integration/targets/kubernetes/files/manifest-example/MANIFEST.json delete mode 100644 tests/integration/targets/kubernetes/files/manifest-example/README.md diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index 3e2958bb..0e00e1ea 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -84,12 +84,5 @@ jobs: mkdir -p /home/runner/.ansible ln -s /home/runner/work/kubernetes /home/runner/.ansible/collections - # TODO: Once community.general is on public Galaxy, drop the -s. - - name: Install community.general role to get json_query filter. - run: | - cp tests/integration/targets/kubernetes/files/manifest-example/MANIFEST.json MANIFEST.json - pip install jmespath - ansible-galaxy collection install --no-deps -s https://sivel.eng.ansible.com/api community.general - - name: Run molecule default test scenario run: molecule test diff --git a/molecule/default/tasks/waiter.yml b/molecule/default/tasks/waiter.yml index 689efac0..1269c2e9 100644 --- a/molecule/default/tasks/waiter.yml +++ b/molecule/default/tasks/waiter.yml @@ -262,15 +262,13 @@ reason: DeploymentPaused register: pause_deploy - - debug: var=pause_deploy - - name: Check that paused deployment wait worked assert: that: - condition.reason == "DeploymentPaused" - condition.status == "Unknown" vars: - condition: '{{ pause_deploy.result.status.conditions | community.general.json_query("[?type==`Progressing`]") | first }}' + condition: '{{ pause_deploy.result.status.conditions[1] }}' - name: Add a service based on the deployment k8s: diff --git a/tests/integration/targets/kubernetes/files/manifest-example/MANIFEST.json b/tests/integration/targets/kubernetes/files/manifest-example/MANIFEST.json deleted file mode 100644 index ef7258e5..00000000 --- a/tests/integration/targets/kubernetes/files/manifest-example/MANIFEST.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "collection_info": { - "namespace": "community", - "name": "kubernetes", - "version": "1.0.0", - "authors": [ - "chouseknecht (https://github.com/chouseknecht)", - "geerlingguy (https://www.jeffgeerling.com/)", - "maxamillion (https://github.com/maxamillion)", - "jmontleon (https://github.com/jmontleon)", - "fabianvf (https://github.com/fabianvf)", - "willthames (https://github.com/willthames)", - "mmazur (https://github.com/mmazur)", - "jamescassell (https://github.com/jamescassell)" - ], - "readme": "README.md", - "tags": [ - "kubernetes", - "k8s", - "cloud", - "infrastructure", - "openshift", - "okd", - "cluster" - ], - "description": "Kubernetes Collection for Ansible.", - "license": [], - "license_file": "LICENSE", - "dependencies": {}, - "repository": "https://github.com/ansible-collections/kubernetes", - "documentation": "", - "homepage": "", - "issues": "https://github.com/ansible-collections/kubernetes/issues" - }, - "file_manifest_file": { - "name": "FILES.json", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "38d130899a6e46be25cbde550675c62b55827a79c3cfe29dc43fecd8e1de7ef6", - "format": 1 - }, - "format": 1 -} \ No newline at end of file diff --git a/tests/integration/targets/kubernetes/files/manifest-example/README.md b/tests/integration/targets/kubernetes/files/manifest-example/README.md deleted file mode 100644 index 17f3a4bb..00000000 --- a/tests/integration/targets/kubernetes/files/manifest-example/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# MANIFEST.json README - -This manifest file is used in the test environment to overcome a bug currently in Ansible core: https://github.com/ansible/ansible/issues/67399 - -Once that bug is fixed, this file can be removed, along with the `cp` command used in the CI GitHub Actions workflow for this repository. From bc5121363bbf43141fb4d3c00a906e46a8ac9ccd Mon Sep 17 00:00:00 2001 From: Jeff Geerling Date: Thu, 13 Feb 2020 16:05:24 -0600 Subject: [PATCH 6/6] Issue #10: Grammar fixes for some test tasks. --- molecule/default/tasks/append_hash.yml | 14 +++++++------- molecule/default/tasks/crd.yml | 14 +++++++------- molecule/default/tasks/full.yml | 17 +++++++++-------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/molecule/default/tasks/append_hash.yml b/molecule/default/tasks/append_hash.yml index 876e876a..858a3338 100644 --- a/molecule/default/tasks/append_hash.yml +++ b/molecule/default/tasks/append_hash.yml @@ -4,7 +4,7 @@ kind: Namespace name: append-hash - - name: create k8s_resource variable + - name: Create k8s_resource variable set_fact: k8s_resource: metadata: @@ -21,26 +21,26 @@ append_hash: yes register: k8s_configmap1 - - name: check configmap is created with a hash + - name: Check configmap is created with a hash assert: that: - k8s_configmap1 is changed - k8s_configmap1.result.metadata.name != 'config-map-test' - k8s_configmap1.result.metadata.name[:-10] == 'config-map-test-' - - name: recreate same config map + - name: Recreate same config map k8s: definition: "{{ k8s_resource }}" append_hash: yes register: k8s_configmap2 - - name: check configmaps are different + - name: Check configmaps are different assert: that: - k8s_configmap2 is not changed - k8s_configmap1.result.metadata.name == k8s_configmap2.result.metadata.name - - name: add key to config map + - name: Add key to config map k8s: definition: metadata: @@ -54,14 +54,14 @@ append_hash: yes register: k8s_configmap3 - - name: check configmaps are different + - name: Check configmaps are different assert: that: - k8s_configmap3 is changed - k8s_configmap1.result.metadata.name != k8s_configmap3.result.metadata.name always: - - name: ensure that namespace is removed + - name: Ensure that namespace is removed k8s: kind: Namespace name: append-hash diff --git a/molecule/default/tasks/crd.yml b/molecule/default/tasks/crd.yml index 11b4d17c..3d014af8 100644 --- a/molecule/default/tasks/crd.yml +++ b/molecule/default/tasks/crd.yml @@ -13,34 +13,34 @@ pause: seconds: 5 - - name: create custom resource definition + - name: Create custom resource definition k8s: definition: "{{ lookup('file', kubernetes_role_path + '/files/crd-resource.yml') }}" namespace: crd apply: "{{ create_crd_with_apply | default(omit) }}" register: create_crd - - name: patch custom resource definition + - name: Patch custom resource definition k8s: definition: "{{ lookup('file', kubernetes_role_path + '/files/crd-resource.yml') }}" namespace: crd register: recreate_crd ignore_errors: yes - - name: assert that recreating crd is as expected + - name: Assert that recreating crd is as expected assert: that: - recreate_crd_default_merge_expectation - block: - - name: recreate custom resource definition with merge_type + - name: Recreate custom resource definition with merge_type k8s: definition: "{{ lookup('file', kubernetes_role_path + '/files/crd-resource.yml') }}" merge_type: merge namespace: crd register: recreate_crd_with_merge - - name: recreate custom resource definition with merge_type list + - name: Recreate custom resource definition with merge_type list k8s: definition: "{{ lookup('file', kubernetes_role_path + '/files/crd-resource.yml') }}" merge_type: @@ -51,14 +51,14 @@ when: recreate_crd is successful - - name: remove crd + - name: Remove crd k8s: definition: "{{ lookup('file', kubernetes_role_path + '/files/crd-resource.yml') }}" namespace: crd state: absent always: - - name: remove crd namespace + - name: Remove crd namespace k8s: kind: Namespace name: crd diff --git a/molecule/default/tasks/full.yml b/molecule/default/tasks/full.yml index 0130507a..b99f0d3a 100644 --- a/molecule/default/tasks/full.yml +++ b/molecule/default/tasks/full.yml @@ -6,7 +6,7 @@ kind: Namespace register: output - - name: show output + - name: Show output debug: var: output @@ -24,14 +24,14 @@ # that: # - output is failed - - name: k8s_info works with empty resources + - name: Ensure k8s_info works with empty resources k8s_info: kind: Deployment namespace: testing api_version: apps/v1 register: k8s_info - - name: assert that k8s_info is in correct format + - name: Assert that k8s_info is in correct format assert: that: - "'resources' in k8s_info" @@ -60,7 +60,7 @@ port: 8000 register: output - - name: show output + - name: Show output debug: var: output @@ -118,7 +118,7 @@ state: present inline: *pvc - - name: PVC creation should be idempotent + - name: Ensure PVC creation is idempotent assert: that: not output.changed @@ -171,7 +171,7 @@ inline: *deployment register: output - - name: Deployment creation should be idempotent + - name: Ensure Deployment creation is idempotent assert: that: not output.changed @@ -293,7 +293,8 @@ metadata: name: testing5 - - k8s_info: + - name: Get info about terminating resources + k8s_info: api_version: v1 kind: Namespace name: "{{ item }}" @@ -302,7 +303,7 @@ - testing5 register: k8s_info - - name: Resources are terminating if still in results + - name: Ensure resources are terminating if still in results assert: that: not item.resources or item.resources[0].status.phase == "Terminating" loop: "{{ k8s_info.results }}"