mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-27 07:01:22 -07:00
Allow user to specify a custom condition when waiting (#52185)
This commit is contained in:
parent
b979b26a74
commit
65424dd614
3 changed files with 88 additions and 7 deletions
|
@ -66,6 +66,14 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
|||
strict=dict(type='bool', default=True)
|
||||
)
|
||||
|
||||
@property
|
||||
def condition_spec(self):
|
||||
return dict(
|
||||
type=dict(),
|
||||
status=dict(default=True, choices=[True, False, "Unknown"]),
|
||||
reason=dict()
|
||||
)
|
||||
|
||||
@property
|
||||
def argspec(self):
|
||||
argument_spec = copy.deepcopy(COMMON_ARG_SPEC)
|
||||
|
@ -73,6 +81,7 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
|||
argument_spec['merge_type'] = dict(type='list', choices=['json', 'merge', 'strategic-merge'])
|
||||
argument_spec['wait'] = dict(type='bool', default=False)
|
||||
argument_spec['wait_timeout'] = dict(type='int', default=120)
|
||||
argument_spec['wait_condition'] = dict(type='dict', default=None, options=self.condition_spec)
|
||||
argument_spec['validate'] = dict(type='dict', default=None, options=self.validate_spec)
|
||||
argument_spec['append_hash'] = dict(type='bool', default=False)
|
||||
return argument_spec
|
||||
|
@ -211,6 +220,9 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
|||
existing = None
|
||||
wait = self.params.get('wait')
|
||||
wait_timeout = self.params.get('wait_timeout')
|
||||
wait_condition = None
|
||||
if self.params.get('wait_condition') and self.params['wait_condition'].get('type'):
|
||||
wait_condition = self.params['wait_condition']
|
||||
|
||||
self.remove_aliases()
|
||||
|
||||
|
@ -280,7 +292,7 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
|||
success = True
|
||||
result['result'] = k8s_obj
|
||||
if wait and not self.check_mode:
|
||||
success, result['result'], result['duration'] = self.wait(resource, definition, wait_timeout)
|
||||
success, result['result'], result['duration'] = self.wait(resource, definition, wait_timeout, condition=wait_condition)
|
||||
result['changed'] = True
|
||||
result['method'] = 'create'
|
||||
if not success:
|
||||
|
@ -305,7 +317,7 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
|||
success = True
|
||||
result['result'] = k8s_obj
|
||||
if wait:
|
||||
success, result['result'], result['duration'] = self.wait(resource, definition, wait_timeout)
|
||||
success, result['result'], result['duration'] = self.wait(resource, definition, wait_timeout, condition=wait_condition)
|
||||
match, diffs = self.diff_objects(existing.to_dict(), result['result'].to_dict())
|
||||
result['changed'] = not match
|
||||
result['method'] = 'replace'
|
||||
|
@ -333,7 +345,7 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
|||
success = True
|
||||
result['result'] = k8s_obj
|
||||
if wait:
|
||||
success, result['result'], result['duration'] = self.wait(resource, definition, wait_timeout)
|
||||
success, result['result'], result['duration'] = self.wait(resource, definition, wait_timeout, condition=wait_condition)
|
||||
match, diffs = self.diff_objects(existing.to_dict(), result['result'])
|
||||
result['result'] = k8s_obj
|
||||
result['changed'] = not match
|
||||
|
@ -398,7 +410,7 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
|||
response = response.to_dict()
|
||||
return False, response, _wait_for_elapsed()
|
||||
|
||||
def wait(self, resource, definition, timeout, state='present'):
|
||||
def wait(self, resource, definition, timeout, state='present', condition=None):
|
||||
|
||||
def _deployment_ready(deployment):
|
||||
# FIXME: frustratingly bool(deployment.status) is True even if status is empty
|
||||
|
@ -416,6 +428,23 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
|||
daemonset.status.numberReady == daemonset.status.desiredNumberScheduled and
|
||||
daemonset.status.observedGeneration == daemonset.metadata.generation)
|
||||
|
||||
def _custom_condition(resource):
|
||||
if not resource.status or not resource.status.conditions:
|
||||
return False
|
||||
match = [x for x in resource.status.conditions if x.type == condition['type']]
|
||||
if not match:
|
||||
return False
|
||||
# There should never be more than one condition of a specific type
|
||||
match = match[0]
|
||||
if match.status == 'Unknown':
|
||||
return False
|
||||
status = True if match.status == 'True' else False
|
||||
if status == condition['status']:
|
||||
if condition.get('reason'):
|
||||
return match.reason == condition['reason']
|
||||
return True
|
||||
return False
|
||||
|
||||
def _resource_absent(resource):
|
||||
return not resource
|
||||
|
||||
|
@ -425,8 +454,10 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
|||
Pod=_pod_ready
|
||||
)
|
||||
kind = definition['kind']
|
||||
if state == 'present':
|
||||
predicate = waiter.get(kind, lambda x: True)
|
||||
if state == 'present' and not condition:
|
||||
predicate = waiter.get(kind, lambda x: x)
|
||||
elif state == 'present' and condition:
|
||||
predicate = _custom_condition
|
||||
else:
|
||||
predicate = _resource_absent
|
||||
return self._wait_for(resource, definition['metadata']['name'], definition['metadata'].get('namespace'), predicate, timeout, state)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue