mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-03-26 21:33:02 +00:00
Remove omit from template resource (#432)
Remove ``omit`` value from template args SUMMARY While defining resource using template parameter, the code does not remove the omit value if any. This fix adds a post process to remove any omit value from the resource definition. fixes #431 ISSUE TYPE Bugfix Pull Request COMPONENT NAME k8s* Reviewed-by: Mike Graves <mgraves@redhat.com> Reviewed-by: Abhijeet Kasurde <None>
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
bugfixes:
|
||||||
|
- Remove `omit` placeholder when defining resource using template parameter (https://github.com/ansible-collections/kubernetes.core/issues/431).
|
||||||
@@ -12,7 +12,6 @@ import traceback
|
|||||||
import os
|
import os
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
|
||||||
from ansible.config.manager import ensure_type
|
from ansible.config.manager import ensure_type
|
||||||
from ansible.errors import (
|
from ansible.errors import (
|
||||||
AnsibleError,
|
AnsibleError,
|
||||||
@@ -26,6 +25,31 @@ from ansible.module_utils._text import to_text, to_bytes, to_native
|
|||||||
from ansible.plugins.action import ActionBase
|
from ansible.plugins.action import ActionBase
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveOmit(object):
|
||||||
|
def __init__(self, buffer, omit_value):
|
||||||
|
try:
|
||||||
|
import yaml
|
||||||
|
except ImportError:
|
||||||
|
raise AnsibleError("Failed to import the required Python library (PyYAML).")
|
||||||
|
self.data = yaml.safe_load_all(buffer)
|
||||||
|
self.omit = omit_value
|
||||||
|
|
||||||
|
def remove_omit(self, data):
|
||||||
|
if isinstance(data, dict):
|
||||||
|
result = dict()
|
||||||
|
for key, value in iteritems(data):
|
||||||
|
if value == self.omit:
|
||||||
|
continue
|
||||||
|
result[key] = self.remove_omit(value)
|
||||||
|
return result
|
||||||
|
if isinstance(data, list):
|
||||||
|
return [self.remove_omit(v) for v in data if v != self.omit]
|
||||||
|
return data
|
||||||
|
|
||||||
|
def output(self):
|
||||||
|
return [self.remove_omit(d) for d in self.data]
|
||||||
|
|
||||||
|
|
||||||
class ActionModule(ActionBase):
|
class ActionModule(ActionBase):
|
||||||
|
|
||||||
TRANSFERS_FILES = True
|
TRANSFERS_FILES = True
|
||||||
@@ -180,6 +204,7 @@ class ActionModule(ActionBase):
|
|||||||
"'template' is only a supported parameter for the 'k8s' module."
|
"'template' is only a supported parameter for the 'k8s' module."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
omit_value = task_vars.get("omit")
|
||||||
template_params = []
|
template_params = []
|
||||||
if isinstance(template, string_types) or isinstance(template, dict):
|
if isinstance(template, string_types) or isinstance(template, dict):
|
||||||
template_params.append(self.get_template_args(template))
|
template_params.append(self.get_template_args(template))
|
||||||
@@ -245,7 +270,10 @@ class ActionModule(ActionBase):
|
|||||||
preserve_trailing_newlines=True,
|
preserve_trailing_newlines=True,
|
||||||
escape_backslashes=False,
|
escape_backslashes=False,
|
||||||
)
|
)
|
||||||
result_template.append(result)
|
if omit_value is not None:
|
||||||
|
result_template.extend(RemoveOmit(result, omit_value).output())
|
||||||
|
else:
|
||||||
|
result_template.append(result)
|
||||||
self._templar.available_variables = old_vars
|
self._templar.available_variables = old_vars
|
||||||
resource_definition = self._task.args.get("definition", None)
|
resource_definition = self._task.args.get("definition", None)
|
||||||
if not resource_definition:
|
if not resource_definition:
|
||||||
|
|||||||
@@ -239,6 +239,63 @@
|
|||||||
- resource.result.results | selectattr('changed') | list | length == 1
|
- resource.result.results | selectattr('changed') | list | length == 1
|
||||||
- resource.result.results | selectattr('error', 'defined') | list | length == 1
|
- resource.result.results | selectattr('error', 'defined') | list | length == 1
|
||||||
|
|
||||||
|
# Test resource definition using template with 'omit'
|
||||||
|
- name: Deploy configmap using template
|
||||||
|
k8s:
|
||||||
|
namespace: "{{ template_namespace }}"
|
||||||
|
name: test-data
|
||||||
|
template: configmap.yml.j2
|
||||||
|
|
||||||
|
- name: Read configmap created
|
||||||
|
k8s_info:
|
||||||
|
kind: configmap
|
||||||
|
namespace: "{{ template_namespace }}"
|
||||||
|
name: test-data
|
||||||
|
register: _configmap
|
||||||
|
|
||||||
|
- name: Validate that the configmap does not contains annotations
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"annotations" not in _configmap.resources.0.metadata'
|
||||||
|
|
||||||
|
- name: Create resource once again
|
||||||
|
k8s:
|
||||||
|
namespace: "{{ template_namespace }}"
|
||||||
|
name: test-data
|
||||||
|
template: configmap.yml.j2
|
||||||
|
register: _configmap
|
||||||
|
|
||||||
|
- name: assert that nothing changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- _configmap is not changed
|
||||||
|
|
||||||
|
- name: Create resource once again (using description)
|
||||||
|
k8s:
|
||||||
|
namespace: "{{ template_namespace }}"
|
||||||
|
name: test-data
|
||||||
|
template: configmap.yml.j2
|
||||||
|
register: _configmap
|
||||||
|
vars:
|
||||||
|
k8s_configmap_desc: "This is a simple configmap used to test ansible k8s collection"
|
||||||
|
|
||||||
|
- name: assert that configmap was changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- _configmap is changed
|
||||||
|
|
||||||
|
- name: Read configmap created
|
||||||
|
k8s_info:
|
||||||
|
kind: configmap
|
||||||
|
namespace: "{{ template_namespace }}"
|
||||||
|
name: test-data
|
||||||
|
register: _configmap
|
||||||
|
|
||||||
|
- name: Validate that the configmap does not contains annotations
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- _configmap.resources.0.metadata.annotations.description == "This is a simple configmap used to test ansible k8s collection"
|
||||||
|
|
||||||
always:
|
always:
|
||||||
- name: Remove namespace (Cleanup)
|
- name: Remove namespace (Cleanup)
|
||||||
kubernetes.core.k8s:
|
kubernetes.core.k8s:
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
description: "{{ k8s_configmap_desc | default(omit) }}"
|
||||||
|
data:
|
||||||
|
key: "testing-template"
|
||||||
104
tests/unit/action/test_remove_omit.py
Normal file
104
tests/unit/action/test_remove_omit.py
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright: (c) 2022, Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from ansible_collections.kubernetes.core.plugins.action.k8s_info import RemoveOmit
|
||||||
|
|
||||||
|
|
||||||
|
def get_omit_token():
|
||||||
|
return "__omit_place_holder__%s" % datetime.now().strftime("%Y%m%d%H%M%S")
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_omit_from_str():
|
||||||
|
omit_token = get_omit_token()
|
||||||
|
src = """
|
||||||
|
project: ansible
|
||||||
|
collection: {omit}
|
||||||
|
""".format(
|
||||||
|
omit=omit_token
|
||||||
|
)
|
||||||
|
result = RemoveOmit(src, omit_value=omit_token).output()
|
||||||
|
assert len(result) == 1
|
||||||
|
assert result[0] == dict(project="ansible")
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_omit_from_list():
|
||||||
|
omit_token = get_omit_token()
|
||||||
|
src = """
|
||||||
|
items:
|
||||||
|
- {omit}
|
||||||
|
""".format(
|
||||||
|
omit=omit_token
|
||||||
|
)
|
||||||
|
result = RemoveOmit(src, omit_value=omit_token).output()
|
||||||
|
assert len(result) == 1
|
||||||
|
assert result[0] == dict(items=[])
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_omit_from_list_of_dict():
|
||||||
|
omit_token = get_omit_token()
|
||||||
|
src = """
|
||||||
|
items:
|
||||||
|
- owner: ansible
|
||||||
|
team: {omit}
|
||||||
|
- simple_list_item
|
||||||
|
""".format(
|
||||||
|
omit=omit_token
|
||||||
|
)
|
||||||
|
result = RemoveOmit(src, omit_value=omit_token).output()
|
||||||
|
assert len(result) == 1
|
||||||
|
assert result[0] == dict(items=[dict(owner="ansible"), "simple_list_item"])
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_omit_combined():
|
||||||
|
omit_token = get_omit_token()
|
||||||
|
src = """
|
||||||
|
items:
|
||||||
|
- {omit}
|
||||||
|
- list_item_a
|
||||||
|
- list_item_b
|
||||||
|
parent:
|
||||||
|
child:
|
||||||
|
subchilda: {omit}
|
||||||
|
subchildb:
|
||||||
|
name: {omit}
|
||||||
|
age: 3
|
||||||
|
""".format(
|
||||||
|
omit=omit_token
|
||||||
|
)
|
||||||
|
result = RemoveOmit(src, omit_value=omit_token).output()
|
||||||
|
assert len(result) == 1
|
||||||
|
assert result[0] == dict(
|
||||||
|
items=["list_item_a", "list_item_b"],
|
||||||
|
parent=dict(child=dict(subchildb=dict(age=3))),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_omit_mutiple_documents():
|
||||||
|
omit_token = get_omit_token()
|
||||||
|
src = [
|
||||||
|
"""
|
||||||
|
project: ansible
|
||||||
|
collection: {omit}
|
||||||
|
""".format(
|
||||||
|
omit=omit_token
|
||||||
|
),
|
||||||
|
"---",
|
||||||
|
"""
|
||||||
|
project: kubernetes
|
||||||
|
environment: production
|
||||||
|
collection: {omit}""".format(
|
||||||
|
omit=omit_token
|
||||||
|
),
|
||||||
|
]
|
||||||
|
src = "\n".join(src)
|
||||||
|
print(src)
|
||||||
|
result = RemoveOmit(src, omit_value=omit_token).output()
|
||||||
|
assert len(result) == 2
|
||||||
|
assert result[0] == dict(project="ansible")
|
||||||
|
assert result[1] == dict(project="kubernetes", environment="production")
|
||||||
Reference in New Issue
Block a user