180 lines
5.0 KiB
Python
Executable File
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)
|