mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-07-28 10:24:45 +00:00
2
changelogs/fragments/18_k8s_info_wait.yml
Normal file
2
changelogs/fragments/18_k8s_info_wait.yml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
bugfixes:
|
||||||
|
- k8s_info - add wait functionality (https://github.com/ansible-collections/community.kubernetes/issues/18).
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
- include_tasks: tasks/full.yml
|
- include_tasks: tasks/full.yml
|
||||||
- include_tasks: tasks/exec.yml
|
- include_tasks: tasks/exec.yml
|
||||||
- include_tasks: tasks/log.yml
|
- include_tasks: tasks/log.yml
|
||||||
|
- include_tasks: tasks/info.yml
|
||||||
|
|
||||||
roles:
|
roles:
|
||||||
- helm
|
- helm
|
||||||
|
|||||||
167
molecule/default/tasks/info.yml
Normal file
167
molecule/default/tasks/info.yml
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
---
|
||||||
|
- block:
|
||||||
|
- set_fact:
|
||||||
|
wait_namespace: wait
|
||||||
|
k8s_pod_name: pod-info-1
|
||||||
|
multi_pod_one: multi-pod-1
|
||||||
|
multi_pod_two: multi-pod-2
|
||||||
|
|
||||||
|
- name: Ensure namespace exists
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ wait_namespace }}"
|
||||||
|
|
||||||
|
- name: Add a simple pod with initContainer
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: "{{ k8s_pod_name }}"
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: init-01
|
||||||
|
image: python:3.7-alpine
|
||||||
|
command: ['sh', '-c', 'sleep 20']
|
||||||
|
containers:
|
||||||
|
- name: utilitypod-01
|
||||||
|
image: python:3.7-alpine
|
||||||
|
command: ['sh', '-c', 'sleep 360']
|
||||||
|
|
||||||
|
- name: Wait and gather information about new pod
|
||||||
|
k8s_info:
|
||||||
|
name: "{{ k8s_pod_name }}"
|
||||||
|
kind: Pod
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
wait: yes
|
||||||
|
wait_sleep: 5
|
||||||
|
wait_timeout: 400
|
||||||
|
register: wait_info
|
||||||
|
|
||||||
|
- name: Assert that pod creation succeeded
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- wait_info is successful
|
||||||
|
- not wait_info.changed
|
||||||
|
- wait_info.resources[0].status.phase == "Running"
|
||||||
|
|
||||||
|
- name: Remove Pod
|
||||||
|
k8s:
|
||||||
|
api_version: v1
|
||||||
|
kind: Pod
|
||||||
|
name: "{{ k8s_pod_name }}"
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
state: absent
|
||||||
|
wait: yes
|
||||||
|
ignore_errors: yes
|
||||||
|
register: short_wait_remove_pod
|
||||||
|
|
||||||
|
- name: Check if pod is removed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- short_wait_remove_pod is successful
|
||||||
|
- short_wait_remove_pod.changed
|
||||||
|
|
||||||
|
- name: Create multiple pod with initContainer
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
run: multi-box
|
||||||
|
name: "{{ multi_pod_one }}"
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: init-01
|
||||||
|
image: python:3.7-alpine
|
||||||
|
command: ['sh', '-c', 'sleep 25']
|
||||||
|
containers:
|
||||||
|
- name: multi-pod-01
|
||||||
|
image: python:3.7-alpine
|
||||||
|
command: ['sh', '-c', 'sleep 360']
|
||||||
|
|
||||||
|
- name: Create another pod with same label as previous pod
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
run: multi-box
|
||||||
|
name: "{{ multi_pod_two }}"
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: init-02
|
||||||
|
image: python:3.7-alpine
|
||||||
|
command: ['sh', '-c', 'sleep 25']
|
||||||
|
containers:
|
||||||
|
- name: multi-pod-02
|
||||||
|
image: python:3.7-alpine
|
||||||
|
command: ['sh', '-c', 'sleep 360']
|
||||||
|
|
||||||
|
- name: Wait and gather information about new pods
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
wait: yes
|
||||||
|
wait_sleep: 5
|
||||||
|
wait_timeout: 400
|
||||||
|
label_selectors:
|
||||||
|
- run == multi-box
|
||||||
|
register: wait_info
|
||||||
|
|
||||||
|
- name: Assert that pod creation succeeded
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- wait_info is successful
|
||||||
|
- not wait_info.changed
|
||||||
|
- wait_info.resources[0].status.phase == "Running"
|
||||||
|
- wait_info.resources[1].status.phase == "Running"
|
||||||
|
|
||||||
|
- name: "Remove Pod {{ multi_pod_one }}"
|
||||||
|
k8s:
|
||||||
|
api_version: v1
|
||||||
|
kind: Pod
|
||||||
|
name: "{{ multi_pod_one }}"
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
state: absent
|
||||||
|
wait: yes
|
||||||
|
ignore_errors: yes
|
||||||
|
register: multi_pod_one_remove
|
||||||
|
|
||||||
|
- name: "Check if {{ multi_pod_one }} pod is removed"
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- multi_pod_one_remove is successful
|
||||||
|
- multi_pod_one_remove.changed
|
||||||
|
|
||||||
|
- name: "Remove Pod {{ multi_pod_two }}"
|
||||||
|
k8s:
|
||||||
|
api_version: v1
|
||||||
|
kind: Pod
|
||||||
|
name: "{{ multi_pod_two }}"
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
state: absent
|
||||||
|
wait: yes
|
||||||
|
ignore_errors: yes
|
||||||
|
register: multi_pod_two_remove
|
||||||
|
|
||||||
|
- name: "Check if {{ multi_pod_two }} pod is removed"
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- multi_pod_two_remove is successful
|
||||||
|
- multi_pod_two_remove.changed
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Remove namespace
|
||||||
|
k8s:
|
||||||
|
kind: Namespace
|
||||||
|
name: "{{ wait_namespace }}"
|
||||||
|
state: absent
|
||||||
67
plugins/doc_fragments/k8s_wait_options.py
Normal file
67
plugins/doc_fragments/k8s_wait_options.py
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright: (c) 2020, Red Hat | Ansible
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
# Options for specifying object wait
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleDocFragment(object):
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
options:
|
||||||
|
wait:
|
||||||
|
description:
|
||||||
|
- Whether to wait for certain resource kinds to end up in the desired state.
|
||||||
|
- By default the module exits once Kubernetes has received the request.
|
||||||
|
- Implemented for C(state=present) for C(Deployment), C(DaemonSet) and C(Pod), and for C(state=absent) for all resource kinds.
|
||||||
|
- For resource kinds without an implementation, C(wait) returns immediately unless C(wait_condition) is set.
|
||||||
|
default: no
|
||||||
|
type: bool
|
||||||
|
wait_sleep:
|
||||||
|
description:
|
||||||
|
- Number of seconds to sleep between checks.
|
||||||
|
default: 5
|
||||||
|
type: int
|
||||||
|
wait_timeout:
|
||||||
|
description:
|
||||||
|
- How long in seconds to wait for the resource to end up in the desired state.
|
||||||
|
- Ignored if C(wait) is not set.
|
||||||
|
default: 120
|
||||||
|
type: int
|
||||||
|
wait_condition:
|
||||||
|
description:
|
||||||
|
- Specifies a custom condition on the status to wait for.
|
||||||
|
- Ignored if C(wait) is not set or is set to False.
|
||||||
|
suboptions:
|
||||||
|
type:
|
||||||
|
type: str
|
||||||
|
description:
|
||||||
|
- The type of condition to wait for.
|
||||||
|
- For example, the C(Pod) resource will set the C(Ready) condition (among others).
|
||||||
|
- Required if you are specifying a C(wait_condition).
|
||||||
|
- If left empty, the C(wait_condition) field will be ignored.
|
||||||
|
- The possible types for a condition are specific to each resource type in Kubernetes.
|
||||||
|
- See the API documentation of the status field for a given resource to see possible choices.
|
||||||
|
status:
|
||||||
|
type: str
|
||||||
|
description:
|
||||||
|
- The value of the status field in your desired condition.
|
||||||
|
- For example, if a C(Deployment) is paused, the C(Progressing) C(type) will have the C(Unknown) status.
|
||||||
|
choices:
|
||||||
|
- True
|
||||||
|
- False
|
||||||
|
- Unknown
|
||||||
|
default: "True"
|
||||||
|
reason:
|
||||||
|
type: str
|
||||||
|
description:
|
||||||
|
- The value of the reason field in your desired condition
|
||||||
|
- For example, if a C(Deployment) is paused, The C(Progressing) C(type) will have the C(DeploymentPaused) reason.
|
||||||
|
- The possible reasons in a condition are specific to each resource type in Kubernetes.
|
||||||
|
- See the API documentation of the status field for a given resource to see possible choices.
|
||||||
|
type: dict
|
||||||
|
'''
|
||||||
@@ -81,6 +81,20 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
from ansible.module_utils.common.dict_transformations import recursive_diff
|
from ansible.module_utils.common.dict_transformations import recursive_diff
|
||||||
|
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
# >=0.10
|
||||||
|
from openshift.dynamic.resource import ResourceInstance
|
||||||
|
except ImportError:
|
||||||
|
# <0.10
|
||||||
|
from openshift.dynamic.client import ResourceInstance
|
||||||
|
HAS_K8S_INSTANCE_HELPER = True
|
||||||
|
k8s_import_exception = None
|
||||||
|
except ImportError as e:
|
||||||
|
HAS_K8S_INSTANCE_HELPER = False
|
||||||
|
k8s_import_exception = e
|
||||||
|
K8S_IMP_ERR = traceback.format_exc()
|
||||||
|
|
||||||
|
|
||||||
def list_dict_str(value):
|
def list_dict_str(value):
|
||||||
if isinstance(value, (list, dict, string_types)):
|
if isinstance(value, (list, dict, string_types)):
|
||||||
@@ -158,6 +172,21 @@ AUTH_ARG_SPEC = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WAIT_ARG_SPEC = dict(
|
||||||
|
wait=dict(type='bool', default=False),
|
||||||
|
wait_sleep=dict(type='int', default=5),
|
||||||
|
wait_timeout=dict(type='int', default=120),
|
||||||
|
wait_condition=dict(
|
||||||
|
type='dict',
|
||||||
|
default=None,
|
||||||
|
options=dict(
|
||||||
|
type=dict(),
|
||||||
|
status=dict(default=True, choices=[True, False, "Unknown"]),
|
||||||
|
reason=dict()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Map kubernetes-client parameters to ansible parameters
|
# Map kubernetes-client parameters to ansible parameters
|
||||||
AUTH_ARG_MAP = {
|
AUTH_ARG_MAP = {
|
||||||
'kubeconfig': 'kubeconfig',
|
'kubeconfig': 'kubeconfig',
|
||||||
@@ -249,22 +278,46 @@ class K8sAnsibleMixin(object):
|
|||||||
if fail:
|
if fail:
|
||||||
self.fail(msg='Failed to find exact match for {0}.{1} by [kind, name, singularName, shortNames]'.format(api_version, kind))
|
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):
|
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):
|
||||||
resource = self.find_resource(kind, api_version)
|
resource = self.find_resource(kind, api_version)
|
||||||
if not resource:
|
if not resource:
|
||||||
return dict(resources=[])
|
return dict(resources=[])
|
||||||
|
|
||||||
|
if not label_selectors:
|
||||||
|
label_selectors = []
|
||||||
|
if not field_selectors:
|
||||||
|
field_selectors = []
|
||||||
|
|
||||||
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)).to_dict()
|
field_selector=','.join(field_selectors))
|
||||||
except openshift.dynamic.exceptions.NotFoundError:
|
if wait:
|
||||||
|
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)
|
||||||
|
result = result.to_dict()
|
||||||
|
except (openshift.dynamic.exceptions.BadRequestError, openshift.dynamic.exceptions.NotFoundError):
|
||||||
return dict(resources=[])
|
return dict(resources=[])
|
||||||
|
|
||||||
if 'items' in result:
|
if 'items' in result:
|
||||||
return dict(resources=result['items'])
|
return dict(resources=result['items'])
|
||||||
else:
|
return dict(resources=[result])
|
||||||
return dict(resources=[result])
|
|
||||||
|
|
||||||
def remove_aliases(self):
|
def remove_aliases(self):
|
||||||
"""
|
"""
|
||||||
@@ -330,8 +383,7 @@ class K8sAnsibleMixin(object):
|
|||||||
if predicate(response):
|
if predicate(response):
|
||||||
if response:
|
if response:
|
||||||
return True, response.to_dict(), _wait_for_elapsed()
|
return True, response.to_dict(), _wait_for_elapsed()
|
||||||
else:
|
return True, {}, _wait_for_elapsed()
|
||||||
return True, {}, _wait_for_elapsed()
|
|
||||||
time.sleep(sleep)
|
time.sleep(sleep)
|
||||||
except NotFoundError:
|
except NotFoundError:
|
||||||
if state == 'absent':
|
if state == 'absent':
|
||||||
@@ -440,21 +492,20 @@ class K8sAnsibleMixin(object):
|
|||||||
|
|
||||||
def check_library_version(self):
|
def check_library_version(self):
|
||||||
validate = self.params.get('validate')
|
validate = self.params.get('validate')
|
||||||
if validate:
|
if validate and LooseVersion(self.openshift_version) < LooseVersion("0.8.0"):
|
||||||
if LooseVersion(self.openshift_version) < LooseVersion("0.8.0"):
|
self.fail_json(msg="openshift >= 0.8.0 is required for validate")
|
||||||
self.fail_json(msg="openshift >= 0.8.0 is required for validate")
|
|
||||||
self.append_hash = self.params.get('append_hash')
|
self.append_hash = self.params.get('append_hash')
|
||||||
if self.append_hash:
|
if self.append_hash and not HAS_K8S_CONFIG_HASH:
|
||||||
if not HAS_K8S_CONFIG_HASH:
|
self.fail_json(msg=missing_required_lib("openshift >= 0.7.2", reason="for append_hash"),
|
||||||
self.fail_json(msg=missing_required_lib("openshift >= 0.7.2", reason="for append_hash"),
|
exception=K8S_CONFIG_HASH_IMP_ERR)
|
||||||
exception=K8S_CONFIG_HASH_IMP_ERR)
|
if self.params['merge_type'] and LooseVersion(self.openshift_version) < LooseVersion("0.6.2"):
|
||||||
if self.params['merge_type']:
|
self.fail_json(msg=missing_required_lib("openshift >= 0.6.2", reason="for merge_type"))
|
||||||
if LooseVersion(self.openshift_version) < LooseVersion("0.6.2"):
|
|
||||||
self.fail_json(msg=missing_required_lib("openshift >= 0.6.2", reason="for merge_type"))
|
|
||||||
self.apply = self.params.get('apply', False)
|
self.apply = self.params.get('apply', False)
|
||||||
if self.apply:
|
if self.apply and not HAS_K8S_APPLY:
|
||||||
if not HAS_K8S_APPLY:
|
self.fail_json(msg=missing_required_lib("openshift >= 0.9.2", reason="for apply"))
|
||||||
self.fail_json(msg=missing_required_lib("openshift >= 0.9.2", reason="for apply"))
|
wait = self.params.get('wait', False)
|
||||||
|
if wait and not HAS_K8S_INSTANCE_HELPER:
|
||||||
|
self.fail_json(msg=missing_required_lib("openshift >= 0.4.0", reason="for wait"))
|
||||||
|
|
||||||
def flatten_list_kind(self, list_resource, definitions):
|
def flatten_list_kind(self, list_resource, definitions):
|
||||||
flattened = []
|
flattened = []
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ extends_documentation_fragment:
|
|||||||
- community.kubernetes.k8s_name_options
|
- community.kubernetes.k8s_name_options
|
||||||
- community.kubernetes.k8s_resource_options
|
- community.kubernetes.k8s_resource_options
|
||||||
- community.kubernetes.k8s_auth_options
|
- community.kubernetes.k8s_auth_options
|
||||||
|
- community.kubernetes.k8s_wait_options
|
||||||
|
|
||||||
notes:
|
notes:
|
||||||
- If your OpenShift Python library is not 0.9.0 or newer and you are trying to
|
- If your OpenShift Python library is not 0.9.0 or newer and you are trying to
|
||||||
@@ -61,53 +62,6 @@ options:
|
|||||||
- strategic-merge
|
- strategic-merge
|
||||||
type: list
|
type: list
|
||||||
elements: str
|
elements: str
|
||||||
wait:
|
|
||||||
description:
|
|
||||||
- Whether to wait for certain resource kinds to end up in the desired state. By default the module exits once Kubernetes has
|
|
||||||
received the request
|
|
||||||
- Implemented for C(state=present) for C(Deployment), C(DaemonSet) and C(Pod), and for C(state=absent) for all resource kinds.
|
|
||||||
- For resource kinds without an implementation, C(wait) returns immediately unless C(wait_condition) is set.
|
|
||||||
default: no
|
|
||||||
type: bool
|
|
||||||
wait_sleep:
|
|
||||||
description:
|
|
||||||
- Number of seconds to sleep between checks.
|
|
||||||
default: 5
|
|
||||||
type: int
|
|
||||||
wait_timeout:
|
|
||||||
description:
|
|
||||||
- How long in seconds to wait for the resource to end up in the desired state. Ignored if C(wait) is not set.
|
|
||||||
default: 120
|
|
||||||
type: int
|
|
||||||
wait_condition:
|
|
||||||
description:
|
|
||||||
- Specifies a custom condition on the status to wait for. Ignored if C(wait) is not set or is set to False.
|
|
||||||
suboptions:
|
|
||||||
type:
|
|
||||||
type: str
|
|
||||||
description:
|
|
||||||
- The type of condition to wait for. For example, the C(Pod) resource will set the C(Ready) condition (among others)
|
|
||||||
- Required if you are specifying a C(wait_condition). If left empty, the C(wait_condition) field will be ignored.
|
|
||||||
- The possible types for a condition are specific to each resource type in Kubernetes. See the API documentation of the status field
|
|
||||||
for a given resource to see possible choices.
|
|
||||||
status:
|
|
||||||
type: str
|
|
||||||
description:
|
|
||||||
- The value of the status field in your desired condition.
|
|
||||||
- For example, if a C(Deployment) is paused, the C(Progressing) C(type) will have the C(Unknown) status.
|
|
||||||
choices:
|
|
||||||
- True
|
|
||||||
- False
|
|
||||||
- Unknown
|
|
||||||
default: "True"
|
|
||||||
reason:
|
|
||||||
type: str
|
|
||||||
description:
|
|
||||||
- The value of the reason field in your desired condition
|
|
||||||
- For example, if a C(Deployment) is paused, The C(Progressing) C(type) will have the C(DeploymentPaused) reason.
|
|
||||||
- The possible reasons in a condition are specific to each resource type in Kubernetes. See the API documentation of the status field
|
|
||||||
for a given resource to see possible choices.
|
|
||||||
type: dict
|
|
||||||
validate:
|
validate:
|
||||||
description:
|
description:
|
||||||
- how (if at all) to validate the resource definition against the kubernetes schema.
|
- how (if at all) to validate the resource definition against the kubernetes schema.
|
||||||
@@ -264,7 +218,7 @@ import copy
|
|||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible_collections.community.kubernetes.plugins.module_utils.common import (
|
from ansible_collections.community.kubernetes.plugins.module_utils.common import (
|
||||||
K8sAnsibleMixin, COMMON_ARG_SPEC, NAME_ARG_SPEC, RESOURCE_ARG_SPEC, AUTH_ARG_SPEC)
|
K8sAnsibleMixin, COMMON_ARG_SPEC, NAME_ARG_SPEC, RESOURCE_ARG_SPEC, AUTH_ARG_SPEC, WAIT_ARG_SPEC)
|
||||||
|
|
||||||
|
|
||||||
class KubernetesModule(K8sAnsibleMixin):
|
class KubernetesModule(K8sAnsibleMixin):
|
||||||
@@ -277,25 +231,14 @@ class KubernetesModule(K8sAnsibleMixin):
|
|||||||
strict=dict(type='bool', default=True)
|
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
|
@property
|
||||||
def argspec(self):
|
def argspec(self):
|
||||||
argument_spec = copy.deepcopy(COMMON_ARG_SPEC)
|
argument_spec = copy.deepcopy(COMMON_ARG_SPEC)
|
||||||
argument_spec.update(copy.deepcopy(NAME_ARG_SPEC))
|
argument_spec.update(copy.deepcopy(NAME_ARG_SPEC))
|
||||||
argument_spec.update(copy.deepcopy(RESOURCE_ARG_SPEC))
|
argument_spec.update(copy.deepcopy(RESOURCE_ARG_SPEC))
|
||||||
argument_spec.update(copy.deepcopy(AUTH_ARG_SPEC))
|
argument_spec.update(copy.deepcopy(AUTH_ARG_SPEC))
|
||||||
|
argument_spec.update(copy.deepcopy(WAIT_ARG_SPEC))
|
||||||
argument_spec['merge_type'] = dict(type='list', elements='str', choices=['json', 'merge', 'strategic-merge'])
|
argument_spec['merge_type'] = dict(type='list', elements='str', choices=['json', 'merge', 'strategic-merge'])
|
||||||
argument_spec['wait'] = dict(type='bool', default=False)
|
|
||||||
argument_spec['wait_sleep'] = dict(type='int', default=5)
|
|
||||||
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['validate'] = dict(type='dict', default=None, options=self.validate_spec)
|
||||||
argument_spec['append_hash'] = dict(type='bool', default=False)
|
argument_spec['append_hash'] = dict(type='bool', default=False)
|
||||||
argument_spec['apply'] = dict(type='bool', default=False)
|
argument_spec['apply'] = dict(type='bool', default=False)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ options:
|
|||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- community.kubernetes.k8s_auth_options
|
- community.kubernetes.k8s_auth_options
|
||||||
- community.kubernetes.k8s_name_options
|
- community.kubernetes.k8s_name_options
|
||||||
|
- community.kubernetes.k8s_wait_options
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- "python >= 2.7"
|
- "python >= 2.7"
|
||||||
@@ -99,6 +100,15 @@ EXAMPLES = r'''
|
|||||||
community.kubernetes.k8s_info:
|
community.kubernetes.k8s_info:
|
||||||
kind: MyCustomObject
|
kind: MyCustomObject
|
||||||
api_version: "stable.example.com/v1"
|
api_version: "stable.example.com/v1"
|
||||||
|
|
||||||
|
- name: Wait till the Object is created
|
||||||
|
community.kubernetes.k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
wait: yes
|
||||||
|
name: pod-not-yet-created
|
||||||
|
namespace: default
|
||||||
|
wait_sleep: 10
|
||||||
|
wait_timeout: 360
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
@@ -134,7 +144,7 @@ import copy
|
|||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible_collections.community.kubernetes.plugins.module_utils.common import (
|
from ansible_collections.community.kubernetes.plugins.module_utils.common import (
|
||||||
K8sAnsibleMixin, AUTH_ARG_SPEC)
|
K8sAnsibleMixin, AUTH_ARG_SPEC, WAIT_ARG_SPEC)
|
||||||
|
|
||||||
|
|
||||||
class KubernetesInfoModule(K8sAnsibleMixin):
|
class KubernetesInfoModule(K8sAnsibleMixin):
|
||||||
@@ -156,14 +166,19 @@ class KubernetesInfoModule(K8sAnsibleMixin):
|
|||||||
self.exit_json(changed=False,
|
self.exit_json(changed=False,
|
||||||
**self.kubernetes_facts(self.params['kind'],
|
**self.kubernetes_facts(self.params['kind'],
|
||||||
self.params['api_version'],
|
self.params['api_version'],
|
||||||
self.params['name'],
|
name=self.params['name'],
|
||||||
self.params['namespace'],
|
namespace=self.params['namespace'],
|
||||||
self.params['label_selectors'],
|
label_selectors=self.params['label_selectors'],
|
||||||
self.params['field_selectors']))
|
field_selectors=self.params['field_selectors'],
|
||||||
|
wait=self.params['wait'],
|
||||||
|
wait_sleep=self.params['wait_sleep'],
|
||||||
|
wait_timeout=self.params['wait_timeout'],
|
||||||
|
condition=self.params['wait_condition']))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def argspec(self):
|
def argspec(self):
|
||||||
args = copy.deepcopy(AUTH_ARG_SPEC)
|
args = copy.deepcopy(AUTH_ARG_SPEC)
|
||||||
|
args.update(WAIT_ARG_SPEC)
|
||||||
args.update(
|
args.update(
|
||||||
dict(
|
dict(
|
||||||
kind=dict(required=True),
|
kind=dict(required=True),
|
||||||
|
|||||||
Reference in New Issue
Block a user