From cebfb5f958950bbd38ca8a04d648178aefface12 Mon Sep 17 00:00:00 2001 From: Vadim Reyder Date: Mon, 3 Feb 2020 22:59:38 +0700 Subject: [PATCH] Add to_yaml variable filter (#116) --- README.md | 1 + k8s_handle/templating.py | 5 +++++ tests/fixtures/config.yaml | 17 +++++++++++++++++ tests/templates_tests/filters.yaml.j2 | 4 ++++ tests/test_templating.py | 17 +++++++++++++++++ 5 files changed, 44 insertions(+) create mode 100644 tests/templates_tests/filters.yaml.j2 diff --git a/README.md b/README.md index a06e2cf..3e96e14 100644 --- a/README.md +++ b/README.md @@ -276,6 +276,7 @@ Templates in k8s-handle use jinja2 syntax and support all standard filters + som * `{{ my_var | b64encode }}` - encode value of my_var to base64 * `{{ my_var | b64decode }}` - decode value of my_var from base64 * `{{ my_var | hash_sha256 }}` - encode value of my_var to sha256sum +* `{{ my_var | to_yaml(flow_style=True, width=99999) }}` - Tries to render yaml representation of given variable(flow_style=True - render in one line, False multiline. width - max line width for rendered yaml lines) > Warning: You can use filters only for templates and can't for config.yaml ### Functions * `{{ include_file('my_file.txt') }}` - include my_file.txt to resulting resource w/o parsing it, useful for include configs to configmap. diff --git a/k8s_handle/templating.py b/k8s_handle/templating.py index 408c6ee..7f2d6b7 100644 --- a/k8s_handle/templating.py +++ b/k8s_handle/templating.py @@ -59,6 +59,10 @@ def hash_sha256(string): return res.hexdigest() +def to_yaml(data, flow_style=True, width=99999): + return yaml.safe_dump(data, default_flow_style=flow_style, width=width) + + def get_env(templates_dir): # https://stackoverflow.com/questions/9767585/insert-static-files-literally-into-jinja-templates-without-parsing-them def include_file(path): @@ -76,6 +80,7 @@ def include_file(path): env.filters['b64decode'] = b64decode env.filters['b64encode'] = b64encode env.filters['hash_sha256'] = hash_sha256 + env.filters['to_yaml'] = to_yaml env.globals['include_file'] = include_file log.debug('Available templates in path {}: {}'.format(templates_dir, env.list_templates())) diff --git a/tests/fixtures/config.yaml b/tests/fixtures/config.yaml index 3855240..9ba9813 100644 --- a/tests/fixtures/config.yaml +++ b/tests/fixtures/config.yaml @@ -71,6 +71,23 @@ templates_regex_invalid: - template: '[' - template: template1.yaml.j2 +test_filters: + to_base64: hello world + from_base64: azhzLWhhbmRsZQ== + to_sha256: k8s-hanle + affinity: + - key: "dedicated" + operator: "Equal" + value: "monitoring" + effect: "NoSchedule" + - key: "dedicated" + operator: "Equal" + value: + hello: world + effect: "NoSchedule" + templates: + - template: filters.yaml.j2 + section_with_kubectl: dirs: - dst: /tmp/test_directory1/ diff --git a/tests/templates_tests/filters.yaml.j2 b/tests/templates_tests/filters.yaml.j2 new file mode 100644 index 0000000..abdfd87 --- /dev/null +++ b/tests/templates_tests/filters.yaml.j2 @@ -0,0 +1,4 @@ +b64encode: {{ to_base64 | b64encode }} +b64decode: {{ from_base64 | b64decode }} +sha256: {{ to_sha256 | hash_sha256 }} +affinity: {{ affinity | to_yaml() }} diff --git a/tests/test_templating.py b/tests/test_templating.py index b0d9a5f..cd1ecfe 100644 --- a/tests/test_templating.py +++ b/tests/test_templating.py @@ -1,4 +1,5 @@ import os +import yaml import shutil import unittest from k8s_handle import settings @@ -163,3 +164,19 @@ def test_templates_regex_parse_failed(self): with self.assertRaises(TemplateRenderingError) as context: r.generate_by_context(c) self.assertTrue('Processing [: template [ hasn\'t been found' in str(context.exception)) + + def test_filters(self): + r = templating.Renderer(os.path.join(os.path.dirname(__file__), 'templates_tests')) + context = config.load_context_section('test_filters') + r.generate_by_context(context) + result = '{}/filters.yaml'.format(settings.TEMP_DIR) + with open(result, 'r') as f: + actual = yaml.safe_load(f) + self.assertEqual('aGVsbG8gd29ybGQ=', actual.get('b64encode')) + self.assertEqual('k8s-handle', actual.get('b64decode')) + self.assertEqual('8fae6dd899aace000fd494fd6d795e26e2c85bf8e59d4262ef56b03dc91e924c', actual.get('sha256')) + affinity = [ + {'effect': 'NoSchedule', 'key': 'dedicated', 'operator': 'Equal', 'value': 'monitoring'}, + {'effect': 'NoSchedule', 'key': 'dedicated', 'operator': 'Equal', 'value': {'hello': 'world'}} + ] + self.assertEqual(affinity, actual.get('affinity'))