diff --git a/changelogs/fragments/146-k8s-add-support-diff-mode.yml b/changelogs/fragments/146-k8s-add-support-diff-mode.yml new file mode 100644 index 0000000000..6e29732bd1 --- /dev/null +++ b/changelogs/fragments/146-k8s-add-support-diff-mode.yml @@ -0,0 +1,2 @@ +bugfixes: + - k8s - Fixes a bug where diff was always returned when using apply or modifying an existing object, even when diff=no was specified. The module no longer returns diff unless requested and will now honor diff=no (https://github.com/ansible-collections/kubernetes.core/pull/146). diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 730081e6a8..4f2d960165 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -164,6 +164,14 @@ tags: - always + - name: Include diff.yml + include_tasks: + file: tasks/diff.yml + apply: + tags: [ diff, k8s ] + tags: + - always + roles: - role: helm tags: diff --git a/molecule/default/tasks/diff.yml b/molecule/default/tasks/diff.yml new file mode 100644 index 0000000000..0e13067b71 --- /dev/null +++ b/molecule/default/tasks/diff.yml @@ -0,0 +1,153 @@ +--- +- set_fact: + diff_namespace: "diff" + diff_configmap: "diff-configmap" + +- block: + - name: Ensure namespace + k8s: + kind: Namespace + name: '{{ diff_namespace }}' + + # Using option 'apply' set to 'yes' + - name: Create Pod using apply and diff set to yes + k8s: + namespace: '{{ diff_namespace }}' + apply: yes + template: "pod_diff.j2" + diff: yes + vars: + pod_name: "pod-apply" + pod_image: "busybox:1.32.0" + register: result + + - name: check that result has diff attribute + assert: + that: + - result is changed + - result.diff is defined + + - name: Update pod definition using apply and diff set to no + k8s: + namespace: '{{ diff_namespace }}' + apply: yes + template: "pod_diff.j2" + diff: no + vars: + pod_name: "pod-apply" + pod_image: "busybox:1.33.0" + register: result + + - name: check that output has no diff attribute + assert: + that: + - result is changed + - result.diff is not defined + + # Using option 'state=patched' + - name: Create Pod using state=present and diff set to yes + k8s: + namespace: '{{ diff_namespace }}' + state: present + template: "pod_diff.j2" + vars: + pod_name: "pod-patch" + pod_image: "busybox:1.32.0" + register: result + + - name: Update pod definition using state=patched + k8s: + namespace: '{{ diff_namespace }}' + state: patched + template: "pod_diff.j2" + diff: no + vars: + pod_name: "pod-patch" + pod_image: "busybox:1.33.0" + pod_label: "patching" + register: result + + - name: check that output has no diff attribute + assert: + that: + - result is changed + - result.diff is not defined + + - name: Update pod definition using state=patched and diff=yes + k8s: + namespace: '{{ diff_namespace }}' + state: patched + template: "pod_diff.j2" + diff: yes + vars: + pod_name: "pod-patch" + pod_image: "busybox:1.33.0" + pod_label: "running" + register: result + + - name: check that output has no diff attribute + assert: + that: + - result is changed + - result.diff is defined + + # check diff mode using force=yes + - name: Create a ConfigMap + k8s: + kind: ConfigMap + name: '{{ diff_configmap }}' + namespace: '{{ diff_namespace }}' + definition: + data: + key: "initial value" + diff: yes + register: result + + - name: check that output has no diff attribute + assert: + that: + - result is changed + - result.diff is not defined + + - name: Update ConfigMap using force and diff=no + k8s: + kind: ConfigMap + name: '{{ diff_configmap }}' + namespace: '{{ diff_namespace }}' + force: yes + definition: + data: + key: "update value with diff=no" + diff: no + register: result + + - name: check that output has no diff attribute + assert: + that: + - result is changed + - result.diff is not defined + + - name: Update ConfigMap using force and diff=yes + k8s: + kind: ConfigMap + name: '{{ diff_configmap }}' + namespace: '{{ diff_namespace }}' + force: yes + definition: + data: + key: "update value with diff=yes" + diff: yes + register: result + + - name: check that output has diff attribute + assert: + that: + - result is changed + - result.diff is defined + + always: + - name: Ensure namespace is deleted + k8s: + state: absent + kind: Namespace + name: '{{ diff_namespace }}' diff --git a/molecule/default/tasks/json_patch.yml b/molecule/default/tasks/json_patch.yml index 3c7aec0723..4aa1bd0ef7 100644 --- a/molecule/default/tasks/json_patch.yml +++ b/molecule/default/tasks/json_patch.yml @@ -43,6 +43,7 @@ value: busybox:glibc check_mode: yes register: result + diff: yes - name: Assert patch was made assert: @@ -50,6 +51,7 @@ - result.changed - result.result.metadata.labels.label2 == "bar" - result.result.spec.containers[0].image == "busybox:glibc" + - result.diff - name: Describe pod kubernetes.core.k8s_info: @@ -82,6 +84,7 @@ assert: that: - result.changed + - result.diff is not defined - name: Describe pod kubernetes.core.k8s_info: diff --git a/molecule/default/tasks/scale.yml b/molecule/default/tasks/scale.yml index 866a5debd4..7a846ae13d 100644 --- a/molecule/default/tasks/scale.yml +++ b/molecule/default/tasks/scale.yml @@ -54,6 +54,7 @@ replicas: 0 wait: yes register: scale_down + diff: true - name: Get pods in scale-deploy k8s_info: @@ -143,7 +144,7 @@ that: - scale_up is changed - '"duration" in scale_up' - - scale_up.diff + - scale_up.diff is not defined - scale_up_further_deploy_pods.resources | length == 2 - name: Don't scale the deployment up @@ -170,7 +171,7 @@ assert: that: - scale_up_noop is not changed - - not scale_up_noop.diff + - scale_up_noop.diff is not defined - scale_up_noop_pods.resources | length == 2 - '"duration" in scale_up_noop' @@ -183,6 +184,7 @@ replicas: 1 wait: no register: scale_down_no_wait + diff: true - name: Ensure that scale down succeeds k8s_info: diff --git a/molecule/default/templates/pod_diff.j2 b/molecule/default/templates/pod_diff.j2 new file mode 100644 index 0000000000..5bdb6e0acd --- /dev/null +++ b/molecule/default/templates/pod_diff.j2 @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: {{ pod_name }} + labels: + ansible: {{ pod_label | default('demo') }} +spec: + containers: + - name: c0 + image: {{ pod_image }} + command: + - /bin/sh + - -c + - while true;do date;sleep 5; done \ No newline at end of file diff --git a/plugins/module_utils/common.py b/plugins/module_utils/common.py index 844d20aeba..96b67acf42 100644 --- a/plugins/module_utils/common.py +++ b/plugins/module_utils/common.py @@ -693,7 +693,8 @@ def build_error_msg(kind, name, msg): existing = {} match, diffs = self.diff_objects(existing, result['result']) result['changed'] = not match - result['diff'] = diffs + if self.module._diff: + result['diff'] = diffs result['method'] = 'apply' if not success: msg = "Resource apply timed out" @@ -785,7 +786,8 @@ def build_error_msg(kind, name, msg): match, diffs = self.diff_objects(existing.to_dict(), result['result']) result['changed'] = not match result['method'] = 'replace' - result['diff'] = diffs + if self.module._diff: + result['diff'] = diffs if not success: msg = "Resource replacement timed out" if continue_on_error: @@ -819,7 +821,8 @@ def build_error_msg(kind, name, msg): match, diffs = self.diff_objects(existing.to_dict(), result['result']) result['changed'] = not match result['method'] = 'patch' - result['diff'] = diffs + if self.module._diff: + result['diff'] = diffs if not success: msg = "Resource update timed out" diff --git a/plugins/modules/k8s_json_patch.py b/plugins/modules/k8s_json_patch.py index 6db98811a5..c38e2eb6b5 100644 --- a/plugins/modules/k8s_json_patch.py +++ b/plugins/modules/k8s_json_patch.py @@ -254,7 +254,8 @@ def build_error_msg(kind, name, msg): success, result['result'], result['duration'] = k8s_module.wait(resource, definition, wait_sleep, wait_timeout, condition=wait_condition) match, diffs = k8s_module.diff_objects(existing.to_dict(), obj) result["changed"] = not match - result["diff"] = diffs + if module._diff: + result["diff"] = diffs if not success: msg = "Resource update timed out" diff --git a/plugins/modules/k8s_scale.py b/plugins/modules/k8s_scale.py index 85c6a276ee..58d178eebc 100644 --- a/plugins/modules/k8s_scale.py +++ b/plugins/modules/k8s_scale.py @@ -181,7 +181,9 @@ def execute_module(module, k8s_ansible_mixin,): wait_sleep = module.params.get('wait_sleep') existing = None existing_count = None - return_attributes = dict(result=dict(), diff=dict()) + return_attributes = dict(result=dict()) + if module._diff: + return_attributes['diff'] = dict() if wait: return_attributes['duration'] = 0 @@ -256,7 +258,9 @@ def _continue_or_exit(warn): name = existing.metadata.name namespace = existing.metadata.namespace existing = resource.get(name=name, namespace=namespace) - result = {'changed': False, 'result': existing.to_dict(), 'diff': {}} + result = {'changed': False, 'result': existing.to_dict()} + if module._diff: + result['diff'] = {} if wait: result['duration'] = 0 # append result to the return attribute @@ -302,7 +306,8 @@ def scale(module, k8s_ansible_mixin, resource, existing_object, replicas, wait, result = dict() result['result'] = k8s_obj result['changed'] = not match - result['diff'] = diffs + if module._diff: + result['diff'] = diffs if wait: success, result['result'], result['duration'] = k8s_ansible_mixin.wait(resource, scale_obj, wait_sleep, wait_time)