From bf26f5a3be025822f8f26250c09f39d8ff73da11 Mon Sep 17 00:00:00 2001 From: Mike Graves Date: Mon, 8 Nov 2021 13:12:25 -0500 Subject: [PATCH] Don't wait on *List resources for info module (#253) Don't wait on *List resources for info module SUMMARY We can't use the same wait logic on *List resources because they lack the same metadata that other resources have. We should ensure that we are waiting on the items in the list, but not the list itself. Waiting on the list itself results in unexpected behavior. This fixes the waiting logic when waiting on a list to wait until the list being queried contains one or more items, or the wait timeout has been reached. Each item in the list can then be waited on with the usual wait logic. ISSUE TYPE Bugfix Pull Request COMPONENT NAME ADDITIONAL INFORMATION Reviewed-by: None Reviewed-by: Alina Buzachis Reviewed-by: None --- .../253-dont-wait-on-list-resources.yaml | 3 ++ molecule/default/tasks/info.yml | 32 ++++++++++++++++ plugins/module_utils/common.py | 37 +++++++++++-------- plugins/modules/k8s_info.py | 4 ++ 4 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 changelogs/fragments/253-dont-wait-on-list-resources.yaml diff --git a/changelogs/fragments/253-dont-wait-on-list-resources.yaml b/changelogs/fragments/253-dont-wait-on-list-resources.yaml new file mode 100644 index 0000000000..b826e55886 --- /dev/null +++ b/changelogs/fragments/253-dont-wait-on-list-resources.yaml @@ -0,0 +1,3 @@ +--- +bugfixes: + - k8s_info - don't wait on empty List resources (https://github.com/ansible-collections/kubernetes.core/pull/253). diff --git a/molecule/default/tasks/info.yml b/molecule/default/tasks/info.yml index ac27f06fd1..9c1633d1e1 100644 --- a/molecule/default/tasks/info.yml +++ b/molecule/default/tasks/info.yml @@ -199,6 +199,38 @@ that: - "{{ lookup('pipe', 'date +%s') }} - {{ start }} > 30" + - name: Create simple pod + k8s: + definition: + apiVersion: v1 + kind: Pod + metadata: + name: wait-pod-1 + namespace: "{{ wait_namespace }}" + spec: + containers: + - image: busybox + name: busybox + command: + - /bin/sh + - -c + - while true; do sleep 5; done + + - name: Wait for multiple non-existent pods to be created + k8s_info: + kind: Pod + namespace: "{{ wait_namespace }}" + label_selectors: + - thislabel=doesnotexist + wait: yes + wait_timeout: 10 + register: result + + - name: Assert no pods were found + assert: + that: + - not result.resources + vars: k8s_pod_name: pod-info-1 diff --git a/plugins/module_utils/common.py b/plugins/module_utils/common.py index d0a6b0f510..09ecc1aee2 100644 --- a/plugins/module_utils/common.py +++ b/plugins/module_utils/common.py @@ -360,21 +360,28 @@ def kubernetes_facts( def _elapsed(): return (datetime.now() - start).seconds - if result is None: - while _elapsed() < wait_timeout: - try: - result = resource.get( - name=name, - namespace=namespace, - label_selector=",".join(label_selectors), - field_selector=",".join(field_selectors), - ) - break - except NotFoundError: - pass - time.sleep(wait_sleep) - if result is None: - return dict(resources=[], api_found=True) + def result_empty(result): + return ( + result is None + or result.kind.endswith("List") + and not result.get("items") + ) + + while result_empty(result) and _elapsed() < wait_timeout: + try: + result = resource.get( + name=name, + namespace=namespace, + label_selector=",".join(label_selectors), + field_selector=",".join(field_selectors), + ) + except NotFoundError: + pass + if not result_empty(result): + break + time.sleep(wait_sleep) + if result_empty(result): + return dict(resources=[], api_found=True) if isinstance(result, ResourceInstance): satisfied_by = [] diff --git a/plugins/modules/k8s_info.py b/plugins/modules/k8s_info.py index 6983314d98..65d4cac890 100644 --- a/plugins/modules/k8s_info.py +++ b/plugins/modules/k8s_info.py @@ -198,6 +198,10 @@ def main(): k8s_ansible_mixin = K8sAnsibleMixin(module) k8s_ansible_mixin.client = get_api_client(module=module) + k8s_ansible_mixin.fail_json = module.fail_json + k8s_ansible_mixin.fail = module.fail_json + k8s_ansible_mixin.exit_json = module.exit_json + k8s_ansible_mixin.warn = module.warn execute_module(module, k8s_ansible_mixin)