mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-03-30 23:33:03 +00:00
updates
This commit is contained in:
3
changelogs/fragments/105-wait_property.yaml
Normal file
3
changelogs/fragments/105-wait_property.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
minor_changes:
|
||||
- k8s - add new option ``wait_property`` to support ability to wait on arbitrary property (https://github.com/ansible-collections/kubernetes.core/pull/105).
|
||||
@@ -364,6 +364,93 @@
|
||||
that:
|
||||
- short_wait_remove_pod is failed
|
||||
|
||||
- name: add a simple crashing pod and wait until container is running
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod-crash-0
|
||||
namespace: "{{ wait_namespace }}"
|
||||
spec:
|
||||
containers:
|
||||
- name: crashing-container
|
||||
image: busybox
|
||||
command: ['/dummy/dummy-shell', '-c', 'sleep 2000']
|
||||
wait: yes
|
||||
wait_timeout: 10
|
||||
wait_property:
|
||||
property: status.containerStatuses[*].state.running
|
||||
ignore_errors: true
|
||||
register: crash_pod
|
||||
|
||||
- name: assert that task failed
|
||||
assert:
|
||||
that:
|
||||
- crash_pod is failed
|
||||
- crash_pod.changed
|
||||
- '"Resource creation timed out" in crash_pod.msg'
|
||||
|
||||
- name: add a valid pod and wait until container is running
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod-valid-0
|
||||
namespace: "{{ wait_namespace }}"
|
||||
spec:
|
||||
containers:
|
||||
- name: crashing-container
|
||||
image: busybox
|
||||
command: ['/bin/sh', '-c', 'sleep 10000']
|
||||
wait: yes
|
||||
wait_timeout: 10
|
||||
wait_property:
|
||||
property: status.containerStatuses[*].state.running
|
||||
ignore_errors: true
|
||||
register: valid_pod
|
||||
|
||||
- name: assert that task failed
|
||||
assert:
|
||||
that:
|
||||
- valid_pod is successful
|
||||
- valid_pod.changed
|
||||
- valid_pod.result.status.containerStatuses[0].state.running is defined
|
||||
|
||||
- name: create pod (waiting for container.ready set to false)
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: redis-pod
|
||||
namespace: "{{ wait_namespace }}"
|
||||
spec:
|
||||
containers:
|
||||
- name: redis-container
|
||||
image: redis
|
||||
volumeMounts:
|
||||
- name: test
|
||||
mountPath: "/etc/test"
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: test
|
||||
configMap:
|
||||
name: redis-config
|
||||
wait: yes
|
||||
wait_timeout: 10
|
||||
wait_property:
|
||||
property: status.containerStatuses[0].ready
|
||||
value: "false"
|
||||
register: wait_boolean
|
||||
|
||||
- name: assert that pod was created but not running
|
||||
assert:
|
||||
that:
|
||||
- wait_boolean.changed
|
||||
- wait_boolean.result.status.phase == 'Pending'
|
||||
|
||||
always:
|
||||
- name: Remove namespace
|
||||
k8s:
|
||||
|
||||
@@ -69,6 +69,7 @@ options:
|
||||
- Specifies a property on the resource to wait for.
|
||||
- Ignored if C(wait) is not set or is set to I(False).
|
||||
type: dict
|
||||
version_added: '2.0.0'
|
||||
suboptions:
|
||||
property:
|
||||
type: str
|
||||
@@ -80,5 +81,6 @@ options:
|
||||
type: str
|
||||
description:
|
||||
- The expected value of the C(property).
|
||||
- The value is not case-sensitive.
|
||||
- If this is missing, we will check only that the attribute C(property) is present.
|
||||
'''
|
||||
|
||||
@@ -434,16 +434,8 @@ class K8sAnsibleMixin(object):
|
||||
def _resource_absent(resource):
|
||||
return not resource
|
||||
|
||||
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):
|
||||
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
|
||||
return match_json_property(self, resource.to_dict(), property.get('property'), property.get('value', None))
|
||||
|
||||
waiter = dict(
|
||||
Deployment=_deployment_ready,
|
||||
|
||||
@@ -23,11 +23,10 @@ from ansible.module_utils._text import to_native
|
||||
try:
|
||||
import jmespath
|
||||
HAS_JMESPATH_LIB = True
|
||||
jmespath_import_exception = None
|
||||
JMESPATH_IMP_ERR = None
|
||||
except ImportError as e:
|
||||
HAS_JMESPATH_LIB = False
|
||||
jmespath_import_exception = e
|
||||
JMESPATH_IMP_ERR = traceback.format_exc()
|
||||
JMESPATH_IMP_ERR = e
|
||||
|
||||
|
||||
def match_json_property(module, data, expr, value=None):
|
||||
@@ -44,18 +43,29 @@ def match_json_property(module, data, expr, value=None):
|
||||
raise err
|
||||
|
||||
def _match_value(buf, v):
|
||||
# convert all values from bool to str and lowercase them
|
||||
return v.lower() in [str(i).lower() for i in buf]
|
||||
if isinstance(buf, list):
|
||||
# convert all values from bool to str and lowercase them
|
||||
return v.lower() in [str(i).lower() for i in buf]
|
||||
elif isinstance(buf, str):
|
||||
return v.lower() == content.lower()
|
||||
elif isinstance(buf, bool):
|
||||
return v.lower() == str(content).lower()
|
||||
else:
|
||||
# unable to test single value against dict
|
||||
return False
|
||||
|
||||
if not HAS_JMESPATH_LIB:
|
||||
_raise_or_fail(jmespath_import_exception, msg=missing_required_lib('jmespath'), exception=JMESPATH_IMP_ERR)
|
||||
_raise_or_fail(JMESPATH_IMP_ERR, msg=missing_required_lib('jmespath'))
|
||||
|
||||
jmespath.functions.REVERSE_TYPES_MAP['string'] = jmespath.functions.REVERSE_TYPES_MAP['string'] + ('AnsibleUnicode', 'AnsibleUnsafeText', )
|
||||
try:
|
||||
content = jmespath.search(expr, data)
|
||||
if not content:
|
||||
with open("/tmp/play.cont", "w") as f:
|
||||
f.write("{}".format(content))
|
||||
if content is None or content == []:
|
||||
return False
|
||||
if not value or _match_value(content, value):
|
||||
if value is None or _match_value(content, value):
|
||||
# looking for state present
|
||||
return True
|
||||
return False
|
||||
except Exception as err:
|
||||
|
||||
@@ -24,7 +24,6 @@ jmespath = pytest.importorskip("jmespath")
|
||||
|
||||
def test_property_present():
|
||||
data = {
|
||||
"Kind": "Pod",
|
||||
"containers": [
|
||||
{"name": "t0", "image": "nginx"},
|
||||
{"name": "t1", "image": "python"},
|
||||
@@ -37,7 +36,6 @@ def test_property_present():
|
||||
|
||||
def test_property_value():
|
||||
data = {
|
||||
"Kind": "Pod",
|
||||
"containers": [
|
||||
{"name": "t0", "image": "nginx"},
|
||||
{"name": "t1", "image": "python"},
|
||||
@@ -52,7 +50,7 @@ def test_property_value():
|
||||
def test_boolean_value():
|
||||
data = {
|
||||
"containers": [
|
||||
{"image": "nginx"},
|
||||
{"image": "nginx", "poweron": False},
|
||||
{"image": "python"},
|
||||
{"image": "mongo", "connected": True}
|
||||
]
|
||||
@@ -60,6 +58,7 @@ def test_boolean_value():
|
||||
assert match_json_property(None, data, "containers[*].connected", "true")
|
||||
assert match_json_property(None, data, "containers[*].connected", "True")
|
||||
assert match_json_property(None, data, "containers[*].connected", "TRUE")
|
||||
assert match_json_property(None, data, "containers[0].poweron", "false")
|
||||
|
||||
|
||||
def test_valid_expression():
|
||||
|
||||
Reference in New Issue
Block a user