This commit is contained in:
abikouo
2021-05-19 15:58:43 +02:00
parent ac97df6565
commit dd821f06aa
8 changed files with 187 additions and 52 deletions

View File

@@ -29,7 +29,7 @@ from distutils.version import LooseVersion
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (AUTH_ARG_MAP, AUTH_ARG_SPEC, AUTH_PROXY_HEADERS_SPEC)
from ansible_collections.kubernetes.core.plugins.module_utils.hashes import generate_hash
from ansible_collections.kubernetes.core.plugins.module_utils.exceptions import WaitException
from ansible_collections.kubernetes.core.plugins.module_utils.jsonpath import match_json_property
from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.six import iteritems, string_types
@@ -98,14 +98,6 @@ except ImportError as e:
k8s_import_exception = e
K8S_IMP_ERR = traceback.format_exc()
try:
import jsonpath_rw
HAS_JSONPATH_RW = True
jsonpath_import_exception = None
except ImportError as e:
HAS_JSONPATH_RW = False
jsonpath_import_exception = e
JSON_PATCH_IMP_ERR = None
try:
import jsonpatch
@@ -250,7 +242,7 @@ class K8sAnsibleMixin(object):
self.fail(msg='Failed to find exact match for {0}.{1} by [kind, name, singularName, shortNames]'.format(api_version, kind))
def kubernetes_facts(self, kind, api_version, name=None, namespace=None, label_selectors=None, field_selectors=None,
wait=False, wait_sleep=5, wait_timeout=120, state='present', condition=None, wait_for=None):
wait=False, wait_sleep=5, wait_timeout=120, state='present', condition=None, wait_property=None):
resource = self.find_resource(kind, api_version)
api_found = bool(resource)
if not api_found:
@@ -306,7 +298,7 @@ class K8sAnsibleMixin(object):
for resource_instance in resource_list:
success, res, duration = self.wait(resource, resource_instance,
sleep=wait_sleep, timeout=wait_timeout,
state=state, condition=condition, wait_for=wait_for)
state=state, condition=condition, wait_property=wait_property)
if not success:
self.fail(msg="Failed to gather information about %s(s) even"
" after waiting for %s seconds" % (res.get('kind'), duration))
@@ -391,7 +383,7 @@ class K8sAnsibleMixin(object):
response = response.to_dict()
return False, response, _wait_for_elapsed()
def wait(self, resource, definition, sleep, timeout, state='present', condition=None, wait_for=None):
def wait(self, resource, definition, sleep, timeout, state='present', condition=None, property=None):
def _deployment_ready(deployment):
# FIXME: frustratingly bool(deployment.status) is True even if status is empty
@@ -441,28 +433,16 @@ class K8sAnsibleMixin(object):
def _resource_absent(resource):
return not resource
# wait_for requires jsonpath-rw library
jsonpath_expr = None
if wait_for is not None:
if not HAS_JSONPATH_RW:
if hasattr(self, 'fail_json'):
self.fail_json(msg=missing_required_lib('jsonpath_rw'), error=to_native(jsonpath_import_exception))
raise WaitException("wait_for option requires 'jsonpath_rw' library")
try:
wait_expr = wait_for
if wait_for.startswith("."):
wait_expr = "$" + wait_for
jsonpath_expr = jsonpath_rw.parse(wait_expr)
except Exception as parse_err:
if hasattr(self, 'fail_json'):
self.fail_json(msg="Failed to parse wait_for attribute {0}".format(wait_for), error=to_native(parse_err))
raise WaitException("Failed to parse wait_for attribute {0} error is {1}".format(wait_for, to_native(parse_err)))
with open("/tmp/resource.txt", "w+") as f:
import json
f.write("------- Property -------\n{}".format(json.dumps(property, indent=2)))
def _wait_for_property(resource):
try:
return all([match.value for match in jsonpath_expr.find(resource)])
except Exception as e:
return False
test = match_json_property(self, resource.to_dict(), property.get('property'), property.get('value', None))
with open("/tmp/resource.txt", "w+") as f:
import json
f.write("------- test = {}\n{}".format(test, json.dumps(resource.to_dict(), indent=2)))
return test
waiter = dict(
Deployment=_deployment_ready,
@@ -472,17 +452,17 @@ class K8sAnsibleMixin(object):
kind = definition['kind']
predicates = []
if state == 'present':
if condition is None and wait_for is None:
if condition is None and property is None:
predicates.append(waiter.get(kind, lambda x: x))
else:
if condition:
# add waiter on custom condition
predicates.append(_custom_condition)
if wait_for:
if property:
# json path predicate
predicates.append(_wait_for_property)
else:
predicates.append(_resource_absent)
predicates = [_resource_absent]
return self._wait_for(resource, definition['metadata']['name'], definition['metadata'].get('namespace'), predicates, sleep, timeout, state)
def set_resource_definitions(self, module):
@@ -625,7 +605,7 @@ class K8sAnsibleMixin(object):
continue_on_error = self.params.get('continue_on_error')
if self.params.get('wait_condition') and self.params['wait_condition'].get('type'):
wait_condition = self.params['wait_condition']
wait_for = self.params.get('wait_for')
wait_property = self.params.get('wait_property')
def build_error_msg(kind, name, msg):
return "%s %s: %s" % (kind, name, msg)
@@ -735,7 +715,7 @@ class K8sAnsibleMixin(object):
result['result'] = k8s_obj
if wait and not self.check_mode:
success, result['result'], result['duration'] = self.wait(resource, definition, wait_sleep, wait_timeout,
condition=wait_condition, wait_for=wait_for)
condition=wait_condition, property=wait_property)
if existing:
existing = existing.to_dict()
else:
@@ -788,8 +768,8 @@ class K8sAnsibleMixin(object):
success = True
result['result'] = k8s_obj
if wait and not self.check_mode:
success, result['result'], result['duration'] = self.wait(resource, definition, wait_sleep,
wait_timeout, condition=wait_condition, wait_for=wait_for)
success, result['result'], result['duration'] = self.wait(resource, definition, wait_sleep, wait_timeout,
condition=wait_condition, property=wait_property)
result['changed'] = True
result['method'] = 'create'
if not success:
@@ -824,8 +804,8 @@ class K8sAnsibleMixin(object):
success = True
result['result'] = k8s_obj
if wait and not self.check_mode:
success, result['result'], result['duration'] = self.wait(resource, definition, wait_sleep,
wait_timeout, condition=wait_condition, wait_for=wait_for)
success, result['result'], result['duration'] = self.wait(resource, definition, wait_sleep, wait_timeout,
condition=wait_condition, property=wait_property)
match, diffs = self.diff_objects(existing.to_dict(), result['result'])
result['changed'] = not match
result['method'] = 'replace'
@@ -859,8 +839,8 @@ class K8sAnsibleMixin(object):
success = True
result['result'] = k8s_obj
if wait and not self.check_mode:
success, result['result'], result['duration'] = self.wait(resource, definition,
wait_sleep, wait_timeout, condition=wait_condition, wait_for=wait_for)
success, result['result'], result['duration'] = self.wait(resource, definition, wait_sleep, wait_timeout,
condition=wait_condition, property=wait_property)
match, diffs = self.diff_objects(existing.to_dict(), result['result'])
result['changed'] = not match
result['method'] = 'patch'