mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-03-27 05:43:02 +00:00
k8s - patch existing resource (#90)
* patch only * add changelogs * Rename 89-k8s-add-parameter-patch_only.yml to 90-k8s-add-parameter-patch_only.yml * Update 90-k8s-add-parameter-patch_only.yml * patch_only parameter changed to state=patched * Update 90-k8s-add-parameter-patch_only.yml * Update plugins/modules/k8s.py Co-authored-by: Fabian von Feilitzsch <fabian@fabianism.us> * Update molecule/default/tasks/patched.yml Co-authored-by: John Mazzitelli <mazz@redhat.com> * Update molecule/default/tasks/patched.yml Co-authored-by: John Mazzitelli <mazz@redhat.com> * sanity issue Co-authored-by: Fabian von Feilitzsch <fabian@fabianism.us> Co-authored-by: John Mazzitelli <mazz@redhat.com>
This commit is contained in:
3
changelogs/fragments/90-k8s-add-parameter-patch_only.yml
Normal file
3
changelogs/fragments/90-k8s-add-parameter-patch_only.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
minor_changes:
|
||||
- k8s - support ``patched`` value for ``state`` option. patched state is an existing resource that has a given patch applied (https://github.com/ansible-collections/kubernetes.core/pull/90).
|
||||
@@ -141,6 +141,14 @@
|
||||
tags:
|
||||
- always
|
||||
|
||||
- name: Include patched.yml
|
||||
include_tasks:
|
||||
file: tasks/patched.yml
|
||||
apply:
|
||||
tags: [ patched, k8s ]
|
||||
tags:
|
||||
- always
|
||||
|
||||
roles:
|
||||
- role: helm
|
||||
tags:
|
||||
|
||||
123
molecule/default/tasks/patched.yml
Normal file
123
molecule/default/tasks/patched.yml
Normal file
@@ -0,0 +1,123 @@
|
||||
---
|
||||
- block:
|
||||
- set_fact:
|
||||
patch_only_namespace:
|
||||
first: patched-namespace-1
|
||||
second: patched-namespace-2
|
||||
|
||||
- name: Ensure namespace {{ patch_only_namespace.first }} exist
|
||||
kubernetes.core.k8s:
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: "{{ patch_only_namespace.first }}"
|
||||
labels:
|
||||
existingLabel: "labelValue"
|
||||
annotations:
|
||||
existingAnnotation: "annotationValue"
|
||||
wait: yes
|
||||
|
||||
- name: Ensure namespace {{ patch_only_namespace.second }} does not exist
|
||||
kubernetes.core.k8s_info:
|
||||
kind: namespace
|
||||
name: "{{ patch_only_namespace.second }}"
|
||||
register: second_namespace
|
||||
|
||||
- name: assert that second namespace does not exist
|
||||
assert:
|
||||
that:
|
||||
- second_namespace.resources | length == 0
|
||||
|
||||
- name: apply patch on existing resource
|
||||
kubernetes.core.k8s:
|
||||
state: patched
|
||||
wait: yes
|
||||
definition: |
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: "{{ patch_only_namespace.first }}"
|
||||
labels:
|
||||
ansible: patched
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: "{{ patch_only_namespace.second }}"
|
||||
labels:
|
||||
ansible: patched
|
||||
register: patch_resource
|
||||
|
||||
- name: assert that patch succeed
|
||||
assert:
|
||||
that:
|
||||
- patch_resource.changed
|
||||
- patch_resource.result.results | selectattr('warning', 'defined') | list | length == 1
|
||||
|
||||
- name: Ensure namespace {{ patch_only_namespace.first }} was patched correctly
|
||||
kubernetes.core.k8s_info:
|
||||
kind: namespace
|
||||
name: "{{ patch_only_namespace.first }}"
|
||||
register: first_namespace
|
||||
|
||||
- name: assert labels are as expected
|
||||
assert:
|
||||
that:
|
||||
- first_namespace.resources[0].metadata.labels.ansible == "patched"
|
||||
- first_namespace.resources[0].metadata.labels.existingLabel == "labelValue"
|
||||
- first_namespace.resources[0].metadata.annotations.existingAnnotation == "annotationValue"
|
||||
- name: Ensure namespace {{ patch_only_namespace.second }} was not created
|
||||
kubernetes.core.k8s_info:
|
||||
kind: namespace
|
||||
name: "{{ patch_only_namespace.second }}"
|
||||
register: second_namespace
|
||||
|
||||
- name: assert that second namespace does not exist
|
||||
assert:
|
||||
that:
|
||||
- second_namespace.resources | length == 0
|
||||
|
||||
- name: patch all resources (create if does not exist)
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition: |
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: "{{ patch_only_namespace.first }}"
|
||||
labels:
|
||||
patch: ansible
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: "{{ patch_only_namespace.second }}"
|
||||
labels:
|
||||
patch: ansible
|
||||
wait: yes
|
||||
register: patch_resource
|
||||
|
||||
- name: Ensure namespace {{ patch_only_namespace.second }} was created
|
||||
kubernetes.core.k8s_info:
|
||||
kind: namespace
|
||||
name: "{{ patch_only_namespace.second }}"
|
||||
register: second_namespace
|
||||
|
||||
- name: assert that second namespace exist
|
||||
assert:
|
||||
that:
|
||||
- second_namespace.resources | length == 1
|
||||
|
||||
always:
|
||||
- name: Remove namespace
|
||||
kubernetes.core.k8s:
|
||||
kind: Namespace
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
with_items:
|
||||
- "{{ patch_only_namespace.first }}"
|
||||
- "{{ patch_only_namespace.second }}"
|
||||
ignore_errors: true
|
||||
@@ -529,7 +529,8 @@ class K8sAnsibleMixin(object):
|
||||
if self.params['validate'] is not None:
|
||||
self.warnings = self.validate(definition)
|
||||
result = self.perform_action(resource, definition)
|
||||
result['warnings'] = self.warnings
|
||||
if self.warnings:
|
||||
result['warnings'] = self.warnings
|
||||
changed = changed or result['changed']
|
||||
results.append(result)
|
||||
|
||||
@@ -670,6 +671,7 @@ class K8sAnsibleMixin(object):
|
||||
else:
|
||||
self.fail_json(msg=build_error_msg(definition['kind'], origin_name, msg), **result)
|
||||
return result
|
||||
|
||||
else:
|
||||
if apply:
|
||||
if self.check_mode:
|
||||
@@ -713,7 +715,14 @@ class K8sAnsibleMixin(object):
|
||||
return result
|
||||
|
||||
if not existing:
|
||||
if self.check_mode:
|
||||
if state == 'patched':
|
||||
# Silently skip this resource (do not raise an error) as 'patch_only' is set to true
|
||||
result['changed'] = False
|
||||
result['warning'] = "resource 'kind={kind},name={name}' was not found but will not be created as 'state'\
|
||||
parameter has been set to '{state}'".format(
|
||||
kind=definition['kind'], name=origin_name, state=state)
|
||||
return result
|
||||
elif self.check_mode:
|
||||
k8s_obj = _encode_stringdata(definition)
|
||||
else:
|
||||
try:
|
||||
@@ -762,7 +771,7 @@ class K8sAnsibleMixin(object):
|
||||
match = False
|
||||
diffs = []
|
||||
|
||||
if existing and force:
|
||||
if state == 'present' and existing and force:
|
||||
if self.check_mode:
|
||||
k8s_obj = _encode_stringdata(definition)
|
||||
else:
|
||||
|
||||
@@ -30,7 +30,6 @@ description:
|
||||
- Supports check mode.
|
||||
|
||||
extends_documentation_fragment:
|
||||
- kubernetes.core.k8s_state_options
|
||||
- kubernetes.core.k8s_name_options
|
||||
- kubernetes.core.k8s_resource_options
|
||||
- kubernetes.core.k8s_auth_options
|
||||
@@ -38,6 +37,21 @@ extends_documentation_fragment:
|
||||
- kubernetes.core.k8s_delete_options
|
||||
|
||||
options:
|
||||
state:
|
||||
description:
|
||||
- Determines if an object should be created, patched, or deleted. When set to C(present), an object will be
|
||||
created, if it does not already exist. If set to C(absent), an existing object will be deleted. If set to
|
||||
C(present), an existing object will be patched, if its attributes differ from those specified using
|
||||
I(resource_definition) or I(src).
|
||||
- C(patched) state is an existing resource that has a given patch applied. If the resource doesn't exist, silently skip it (do not raise an error).
|
||||
type: str
|
||||
default: present
|
||||
choices: [ absent, present, patched ]
|
||||
force:
|
||||
description:
|
||||
- If set to C(yes), and I(state) is C(present), an existing object will be replaced.
|
||||
type: bool
|
||||
default: no
|
||||
merge_type:
|
||||
description:
|
||||
- Whether to override the default patch merge approach with a specific type. By default, the strategic
|
||||
@@ -236,6 +250,17 @@ EXAMPLES = r'''
|
||||
type: Progressing
|
||||
status: Unknown
|
||||
reason: DeploymentPaused
|
||||
|
||||
# Patch existing namespace : add label
|
||||
- name: add label to existing namespace
|
||||
kubernetes.core.k8s:
|
||||
state: patched
|
||||
kind: Namespace
|
||||
name: patch_namespace
|
||||
definition:
|
||||
metadata:
|
||||
labels:
|
||||
support: patch
|
||||
'''
|
||||
|
||||
RETURN = r'''
|
||||
@@ -284,7 +309,7 @@ import copy
|
||||
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import AnsibleModule
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
|
||||
AUTH_ARG_SPEC, WAIT_ARG_SPEC, NAME_ARG_SPEC, COMMON_ARG_SPEC, RESOURCE_ARG_SPEC, DELETE_OPTS_ARG_SPEC)
|
||||
AUTH_ARG_SPEC, WAIT_ARG_SPEC, NAME_ARG_SPEC, RESOURCE_ARG_SPEC, DELETE_OPTS_ARG_SPEC)
|
||||
|
||||
|
||||
def validate_spec():
|
||||
@@ -296,8 +321,7 @@ def validate_spec():
|
||||
|
||||
|
||||
def argspec():
|
||||
argument_spec = copy.deepcopy(COMMON_ARG_SPEC)
|
||||
argument_spec.update(copy.deepcopy(NAME_ARG_SPEC))
|
||||
argument_spec = copy.deepcopy(NAME_ARG_SPEC)
|
||||
argument_spec.update(copy.deepcopy(RESOURCE_ARG_SPEC))
|
||||
argument_spec.update(copy.deepcopy(AUTH_ARG_SPEC))
|
||||
argument_spec.update(copy.deepcopy(WAIT_ARG_SPEC))
|
||||
@@ -308,6 +332,9 @@ def argspec():
|
||||
argument_spec['template'] = dict(type='raw', default=None)
|
||||
argument_spec['delete_options'] = dict(type='dict', default=None, options=copy.deepcopy(DELETE_OPTS_ARG_SPEC))
|
||||
argument_spec['continue_on_error'] = dict(type='bool', default=False)
|
||||
argument_spec['state'] = dict(default='present', choices=['present', 'absent', 'patched'])
|
||||
argument_spec['force'] = dict(type='bool', default=False)
|
||||
|
||||
return argument_spec
|
||||
|
||||
|
||||
@@ -319,6 +346,7 @@ def execute_module(module, k8s_ansible_mixin):
|
||||
k8s_ansible_mixin.fail_json = k8s_ansible_mixin.module.fail_json
|
||||
k8s_ansible_mixin.fail = k8s_ansible_mixin.module.fail_json
|
||||
k8s_ansible_mixin.exit_json = k8s_ansible_mixin.module.exit_json
|
||||
k8s_ansible_mixin.warn = k8s_ansible_mixin.module.warn
|
||||
k8s_ansible_mixin.warnings = []
|
||||
|
||||
k8s_ansible_mixin.kind = k8s_ansible_mixin.params.get('kind')
|
||||
|
||||
Reference in New Issue
Block a user