mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-05-08 14:02:38 +00:00
Honor wait_timeout in k8s_info for missing resource (#360)
* Honor wait in k8s_info for missing resource The wait logic in the k8s_info module immediately returns when no resources are found, regardless whether a wait_timeout has been specified. This expands the logic to wait when a name has been provided. The case this is specifically meant to address is when querying for a resource that is indirectly created by another resource, for example, a pod created by a deployment or an operator. The existing logic in every other case should remain as it was before. This means if a query might return more than one resource--all pods with some label, for example--the module will return immediately if no pods are found, even if a wait_timeout has been provided. * Add changelog fragment
This commit is contained in:
2
changelogs/fragments/360-k8s_info-wait-timeout.yaml
Normal file
2
changelogs/fragments/360-k8s_info-wait-timeout.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
bugfixes:
|
||||||
|
- respect the ``wait_timeout`` parameter in the ``k8s`` and ``k8s_info`` modules when a resource does not exist (https://github.com/ansible-collections/community.kubernetes/issues/344).
|
||||||
@@ -182,6 +182,24 @@
|
|||||||
- not dne_api.resources
|
- not dne_api.resources
|
||||||
- not dne_api.api_found
|
- not dne_api.api_found
|
||||||
|
|
||||||
|
- name: Start timer
|
||||||
|
set_fact:
|
||||||
|
start: "{{ lookup('pipe', 'date +%s') }}"
|
||||||
|
|
||||||
|
- name: Wait for non-existent pod to be created
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
name: does-not-exist
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
wait: yes
|
||||||
|
wait_timeout: 45
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Check that module waited
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "{{ lookup('pipe', 'date +%s') }} - {{ start }} > 30"
|
||||||
|
|
||||||
always:
|
always:
|
||||||
- name: Remove namespace
|
- name: Remove namespace
|
||||||
k8s:
|
k8s:
|
||||||
|
|||||||
@@ -319,31 +319,58 @@ class K8sAnsibleMixin(object):
|
|||||||
if not field_selectors:
|
if not field_selectors:
|
||||||
field_selectors = []
|
field_selectors = []
|
||||||
|
|
||||||
|
result = None
|
||||||
try:
|
try:
|
||||||
result = resource.get(name=name,
|
result = resource.get(name=name, namespace=namespace,
|
||||||
namespace=namespace,
|
|
||||||
label_selector=','.join(label_selectors),
|
label_selector=','.join(label_selectors),
|
||||||
field_selector=','.join(field_selectors))
|
field_selector=','.join(field_selectors))
|
||||||
if wait:
|
except openshift.dynamic.exceptions.BadRequestError:
|
||||||
satisfied_by = []
|
|
||||||
if isinstance(result, ResourceInstance):
|
|
||||||
# We have a list of ResourceInstance
|
|
||||||
resource_list = result.get('items', [])
|
|
||||||
if not resource_list:
|
|
||||||
resource_list = [result]
|
|
||||||
|
|
||||||
for resource_instance in resource_list:
|
|
||||||
success, res, duration = self.wait(resource, resource_instance,
|
|
||||||
sleep=wait_sleep, timeout=wait_timeout,
|
|
||||||
state=state, condition=condition)
|
|
||||||
if not success:
|
|
||||||
self.fail(msg="Failed to gather information about %s(s) even"
|
|
||||||
" after waiting for %s seconds" % (res.get('kind'), duration))
|
|
||||||
satisfied_by.append(res)
|
|
||||||
return dict(resources=satisfied_by, api_found=True)
|
|
||||||
result = result.to_dict()
|
|
||||||
except (openshift.dynamic.exceptions.BadRequestError, openshift.dynamic.exceptions.NotFoundError):
|
|
||||||
return dict(resources=[], api_found=True)
|
return dict(resources=[], api_found=True)
|
||||||
|
except openshift.dynamic.exceptions.NotFoundError:
|
||||||
|
if not wait or name is None:
|
||||||
|
return dict(resources=[], api_found=True)
|
||||||
|
|
||||||
|
if not wait:
|
||||||
|
result = result.to_dict()
|
||||||
|
if 'items' in result:
|
||||||
|
return dict(resources=result['items'], api_found=True)
|
||||||
|
return dict(resources=[result], api_found=True)
|
||||||
|
|
||||||
|
start = datetime.now()
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
if isinstance(result, ResourceInstance):
|
||||||
|
satisfied_by = []
|
||||||
|
# We have a list of ResourceInstance
|
||||||
|
resource_list = result.get('items', [])
|
||||||
|
if not resource_list:
|
||||||
|
resource_list = [result]
|
||||||
|
|
||||||
|
for resource_instance in resource_list:
|
||||||
|
success, res, duration = self.wait(resource, resource_instance,
|
||||||
|
sleep=wait_sleep, timeout=wait_timeout,
|
||||||
|
state=state, condition=condition)
|
||||||
|
if not success:
|
||||||
|
self.fail(msg="Failed to gather information about %s(s) even"
|
||||||
|
" after waiting for %s seconds" % (res.get('kind'), duration))
|
||||||
|
satisfied_by.append(res)
|
||||||
|
return dict(resources=satisfied_by, api_found=True)
|
||||||
|
result = result.to_dict()
|
||||||
|
|
||||||
if 'items' in result:
|
if 'items' in result:
|
||||||
return dict(resources=result['items'], api_found=True)
|
return dict(resources=result['items'], api_found=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user