From a684bb9f5b70fb666e26cb2d0f2b357760565951 Mon Sep 17 00:00:00 2001 From: Will Thames Date: Thu, 19 Sep 2019 13:30:31 +1000 Subject: [PATCH] Ensure k8s apply works with check mode (#60572) * Ensure k8s apply works with check mode Update the new predicted object with fields from the previous object before applying in check mode Don't log output of `file` with `state: absent` on huge virtualenvs! Fixes #60510 * Use openshift client fix to improve apply for check mode Use new apply_object method to get a better approximation of the expected object in check mode. Requires released upgrade to openshift * Add changelog fragment for k8s apply check mode fix * Update changelogs/fragments/60510-k8s-apply-check-mode.yml Co-Authored-By: Felix Fontein --- .../fragments/60510-k8s-apply-check-mode.yml | 2 ++ lib/ansible/module_utils/k8s/raw.py | 15 +++++++++---- test/integration/targets/k8s/tasks/apply.yml | 21 +++++++++++++++++++ test/integration/targets/k8s/tasks/main.yml | 10 ++++++--- .../k8s/tasks/older_openshift_fail.yml | 2 +- 5 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 changelogs/fragments/60510-k8s-apply-check-mode.yml diff --git a/changelogs/fragments/60510-k8s-apply-check-mode.yml b/changelogs/fragments/60510-k8s-apply-check-mode.yml new file mode 100644 index 00000000000..b71c115a4ce --- /dev/null +++ b/changelogs/fragments/60510-k8s-apply-check-mode.yml @@ -0,0 +1,2 @@ +bugfixes: + - k8s - ensure that apply works with check mode. Bumps minimum openshift version for apply to 0.9.2. diff --git a/lib/ansible/module_utils/k8s/raw.py b/lib/ansible/module_utils/k8s/raw.py index 605e880db7a..41e71032f92 100644 --- a/lib/ansible/module_utils/k8s/raw.py +++ b/lib/ansible/module_utils/k8s/raw.py @@ -54,6 +54,13 @@ except ImportError: K8S_CONFIG_HASH_IMP_ERR = traceback.format_exc() HAS_K8S_CONFIG_HASH = False +HAS_K8S_APPLY = None +try: + from openshift.dynamic.apply import apply_object + HAS_K8S_APPLY = True +except ImportError: + HAS_K8S_APPLY = False + class KubernetesRawModule(KubernetesAnsibleModule): @@ -118,11 +125,11 @@ class KubernetesRawModule(KubernetesAnsibleModule): if LooseVersion(self.openshift_version) < LooseVersion("0.6.2"): self.fail_json(msg=missing_required_lib("openshift >= 0.6.2", reason="for merge_type")) if self.params.get('apply') is not None: - if LooseVersion(self.openshift_version) < LooseVersion("0.9.0"): - self.fail_json(msg=missing_required_lib("openshift >= 0.9.0", reason="for apply")) + if not HAS_K8S_APPLY: + self.fail_json(msg=missing_required_lib("openshift >= 0.9.2", reason="for apply")) self.apply = self.params['apply'] else: - self.apply = LooseVersion(self.openshift_version) >= LooseVersion("0.9.0") + self.apply = HAS_K8S_APPLY if resource_definition: if isinstance(resource_definition, string_types): @@ -293,7 +300,7 @@ class KubernetesRawModule(KubernetesAnsibleModule): else: if self.apply: if self.check_mode: - k8s_obj = definition + ignored, k8s_obj = apply_object(resource, definition) else: try: k8s_obj = resource.apply(definition, namespace=namespace).to_dict() diff --git a/test/integration/targets/k8s/tasks/apply.yml b/test/integration/targets/k8s/tasks/apply.yml index 7a4abdfd6da..abfda06acfc 100644 --- a/test/integration/targets/k8s/tasks/apply.yml +++ b/test/integration/targets/k8s/tasks/apply.yml @@ -55,6 +55,27 @@ that: - k8s_configmap_2 is not changed + - name: add same configmap again with check mode on + k8s: + definition: + kind: ConfigMap + apiVersion: v1 + metadata: + name: "apply-configmap" + namespace: "{{ apply_namespace }}" + data: + one: "1" + two: "2" + three: "3" + apply: yes + check_mode: yes + register: k8s_configmap_check + + - name: check nothing changed + assert: + that: + - k8s_configmap_check is not changed + - name: add same configmap again but using name and namespace args k8s: name: "apply-configmap" diff --git a/test/integration/targets/k8s/tasks/main.yml b/test/integration/targets/k8s/tasks/main.yml index f1fc919b917..bb11bbc6862 100644 --- a/test/integration/targets/k8s/tasks/main.yml +++ b/test/integration/targets/k8s/tasks/main.yml @@ -12,7 +12,7 @@ - pip: name: - - 'openshift>=0.9.0' + - openshift>=0.9.2 - coverage virtualenv: "{{ virtualenv }}" virtualenv_command: "{{ virtualenv_command }}" @@ -25,13 +25,14 @@ - file: path: "{{ virtualenv }}" state: absent + no_log: yes # Test validate with kubernetes-validate - pip: name: - kubernetes-validate==1.12.0 - - 'openshift>=0.9.0' + - openshift>=0.9.2 - coverage virtualenv: "{{ virtualenv }}" virtualenv_command: "{{ virtualenv_command }}" @@ -45,6 +46,7 @@ - file: path: "{{ virtualenv }}" state: absent + no_log: yes # Test graceful failure for older versions of openshift @@ -66,12 +68,13 @@ - file: path: "{{ virtualenv }}" state: absent + no_log: yes # Run full test suite - pip: name: - - 'openshift>=0.9.0' + - openshift>=0.9.2 - coverage virtualenv: "{{ virtualenv }}" virtualenv_command: "{{ virtualenv_command }}" @@ -86,3 +89,4 @@ - file: path: "{{ virtualenv }}" state: absent + no_log: yes diff --git a/test/integration/targets/k8s/tasks/older_openshift_fail.yml b/test/integration/targets/k8s/tasks/older_openshift_fail.yml index e9006f8597e..2acf3d2175c 100644 --- a/test/integration/targets/k8s/tasks/older_openshift_fail.yml +++ b/test/integration/targets/k8s/tasks/older_openshift_fail.yml @@ -66,4 +66,4 @@ assert: that: - k8s_apply is failed - - "k8s_apply.msg.startswith('Failed to import the required Python library (openshift >= 0.9.0)')" + - "k8s_apply.msg.startswith('Failed to import the required Python library (openshift >= 0.9.2)')"