From c9051d63076d9b847d24f1ceff27e0d227ad9400 Mon Sep 17 00:00:00 2001 From: Dennis Twardowsky Date: Sat, 3 Jul 2021 15:20:00 +0200 Subject: [PATCH] First Issue --- .idea/.gitignore | 8 + .idea/JinjaTemplating.iml | 8 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + renderTemplate.py | 171 ++++++++++++++++++ template/test.tpl | 8 + testfiles/test.ini | 3 + testfiles/test.json | 6 + testfiles/test.toml | 5 + testfiles/test.yaml | 4 + 12 files changed, 237 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/JinjaTemplating.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100755 renderTemplate.py create mode 100644 template/test.tpl create mode 100644 testfiles/test.ini create mode 100644 testfiles/test.json create mode 100644 testfiles/test.toml create mode 100644 testfiles/test.yaml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/JinjaTemplating.iml b/.idea/JinjaTemplating.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/JinjaTemplating.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d56657a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..34ac36c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/renderTemplate.py b/renderTemplate.py new file mode 100755 index 0000000..333b95b --- /dev/null +++ b/renderTemplate.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python3 +import configparser +import json +import os +import socket +import sys +import toml +import yaml +from jinja2 import Environment, Template, TemplateError, pass_eval_context +import argparse + + +argsparser = argparse.ArgumentParser(description='Jinja Template Helper') + +infilegroup = argsparser.add_mutually_exclusive_group(required=True) +infilegroup.add_argument('--yaml', dest='yaml_file', type=str, required=False, + help='YAML file path') +infilegroup.add_argument('--json', dest='json_file', type=str, required=False, + help='JSON file path') +infilegroup.add_argument('--toml', dest='toml_file', type=str, required=False, + help='TOML file path') +infilegroup.add_argument('--ini', dest='ini_file', type=str, required=False, + help='INI fil path') + +argsparser.add_argument('--output', default='/dev/stdout', + help='Output File') +argsparser.add_argument('infile', metavar="input-file", + help="Input File") + + +# Print Errors +def print_error(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +# Jinja Environment +# ----------------- +jenv = Environment(autoescape=True, + trim_blocks=False, + keep_trailing_newline=True, + optimized=True) + +# Jinja Filters +# ------------- +def filter_env(name, defvalue=""): + return os.getenv(name, defvalue) + + +def filter_domain2ldap(value, unit='dc', delimiter='.'): + parts = value.split(delimiter) + concat_domain = "" + for part in parts: + if len(concat_domain) > 0: + concat_domain += "," + concat_domain = concat_domain + unit + "=" + part + return concat_domain + + +def filter_hostbyaddr(value): + addr = socket.gethostbyaddr(value) + if addr: + return addr[0] + + +def filter_hostbyname(value): + return socket.gethostbyname(value) + + +jenv.filters['env'] = filter_env +jenv.filters['ldap_dn'] = filter_domain2ldap +jenv.filters['hostbyaddr'] = filter_hostbyaddr +jenv.filters['hostbyname'] = filter_hostbyname + + +# Loader +# ------ +def load_template(filename): + try: + with open(filename) as file_: + template = jenv.from_string(file_.read()) + return template + except TemplateError as exc: + print_error("Template Error:", exc.message) + return None + + +def load_yaml_file(filename): + if os.path.isfile(filename): + with open(filename, 'r') as instream: + try: + return yaml.safe_load(instream) + except yaml.YAMLError as exc: + print_error("YAML error:", exc) + else: + print_error("ERROR:", filename, "- File not found") + + return None + + +def load_toml_file(filename): + if os.path.isfile(filename): + with open(filename, 'r') as instream: + try: + return toml.load(instream) + except toml.TomlDecodeError as exc: + print_error("TOML error:", exc) + else: + print_error("ERROR:", filename, "- File not found") + + return None + + +def load_json_file(filename): + if os.path.isfile(filename): + with open(filename, 'r') as instream: + try: + return json.load(instream) + except json.JSONDecodeError as exc: + print_error("JSON error: [", exc.lineno ,"," ,exc.colno, "]", exc.msg) + else: + print_error("ERROR:", filename, "- File not found") + + return None + + +def load_ini_file(filename): + iniparser = configparser.ConfigParser() + if os.path.isfile(filename): + iniparser.read(filename) + return iniparser.items() + else: + print_error("ERROR:", filename, "- File not found") + + return None + + +# Render +# ------ +def render_template(template, outfile, variables=None): + try: + with open(outfile, 'w') as file_: + file_.write(template.render(variables)) if variables else file_.write(template.render()) + + except TemplateError as exc: + print_error("Rendering Error:", exc.message) + +if __name__ == '__main__': + # Read command line arguments + args = argsparser.parse_args() + + tpl = load_template(args.infile) + content = None + + # If template was found + if tpl: + # Load content from file, if present + if args.yaml_file: + content = load_yaml_file(args.yaml_file) + elif args.json_file: + content = load_json_file(args.json_file) + elif args.toml_file: + content = load_toml_file(args.toml_file) + elif args.ini_file: + content = load_ini_file(args.ini_file) + + # Render template with or without external content + render_template(tpl, args.output, content) if content else render_template(tpl, args.output) + else: + exit(1) + + exit(0) diff --git a/template/test.tpl b/template/test.tpl new file mode 100644 index 0000000..ca2d547 --- /dev/null +++ b/template/test.tpl @@ -0,0 +1,8 @@ +{ + "Type": "{{ "TESTVAR" | env }}", + "Level1": { + "Key": "{{ level1.key }}", + "Value": {{ level1.value }}, + }, + "LDAP": "{{ "example.com" | ldap_dn("ou") }}" +} diff --git a/testfiles/test.ini b/testfiles/test.ini new file mode 100644 index 0000000..1154ea3 --- /dev/null +++ b/testfiles/test.ini @@ -0,0 +1,3 @@ +[level1] +key=TestIni +value=42 diff --git a/testfiles/test.json b/testfiles/test.json new file mode 100644 index 0000000..5a23493 --- /dev/null +++ b/testfiles/test.json @@ -0,0 +1,6 @@ +{ + "level1": { + "key": "TestJson", + "value": 42 + } +} \ No newline at end of file diff --git a/testfiles/test.toml b/testfiles/test.toml new file mode 100644 index 0000000..f464228 --- /dev/null +++ b/testfiles/test.toml @@ -0,0 +1,5 @@ +title = "Test" + +[level1] +key = "TestToml" +value = 42 diff --git a/testfiles/test.yaml b/testfiles/test.yaml new file mode 100644 index 0000000..65bd241 --- /dev/null +++ b/testfiles/test.yaml @@ -0,0 +1,4 @@ +level1: + key: "TestYaml" + value: 42 +