Files
jinjatemplating/renderTemplate.py
T
2021-07-05 23:57:01 +02:00

180 lines
5.0 KiB
Python
Executable File

#!/usr/bin/env python3
import configparser
import json
import os
import socket
import sys
import dotenv
import toml
import yaml
from jinja2 import Environment, TemplateError
import argparse
argsparser = argparse.ArgumentParser(description='Jinja Template Helper')
infilegroup = argsparser.add_mutually_exclusive_group(required=False)
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('--env', dest='env_file', type=bool, required=False, default=False,
help='Load .env file from current directory')
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:
if args.env_file:
dotenv.load_dotenv(dotenv.find_dotenv(raise_error_if_not_found=False))
# 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)