From 99c8bf755c5a53d52396c82c4159e2324223c215 Mon Sep 17 00:00:00 2001 From: Mike Graves Date: Mon, 4 Oct 2021 10:35:11 -0400 Subject: [PATCH 1/3] Don't wait on *List resources for info module 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. --- molecule/default/tasks/info.yml | 32 ++++++++++++++++++++++++++++++++ plugins/module_utils/common.py | 30 +++++++++++++++--------------- plugins/modules/k8s_info.py | 4 ++++ 3 files changed, 51 insertions(+), 15 deletions(-) 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..d655a4b1e8 100644 --- a/plugins/module_utils/common.py +++ b/plugins/module_utils/common.py @@ -360,21 +360,21 @@ 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) From 9624de0c0134de6e77428da71a99fa3e1cfde7d4 Mon Sep 17 00:00:00 2001 From: Mike Graves Date: Mon, 4 Oct 2021 15:12:37 -0400 Subject: [PATCH 2/3] Add changelog fragment --- changelogs/fragments/253-dont-wait-on-list-resources.yaml | 3 +++ 1 file changed, 3 insertions(+) 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). From b5c03f0609893b89a36f09226cba540488a1450d Mon Sep 17 00:00:00 2001 From: Mike Graves Date: Mon, 8 Nov 2021 09:55:27 -0500 Subject: [PATCH 3/3] Black formatting --- plugins/module_utils/common.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/plugins/module_utils/common.py b/plugins/module_utils/common.py index d655a4b1e8..09ecc1aee2 100644 --- a/plugins/module_utils/common.py +++ b/plugins/module_utils/common.py @@ -361,13 +361,20 @@ def _elapsed(): return (datetime.now() - start).seconds def result_empty(result): - return result is None or result.kind.endswith("List") and not result.get("items") + 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)) + 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):