#!/usr/bin/env python3 import sys as _sys import os as _os import yaml as _yaml import json as _json import argparse as _argparse def file_read(path): handle = open(path, "r") content = handle.read() handle.close() return content def file_write(path, content): directory = _os.path.dirname(path) if (not _os.path.exists(directory)): _os.makedirs(directory, exist_ok = True) else: pass handle = open(path, "w") handle.write(content) handle.close() return content def dict_merge(core, mantle, path = None): if (path is None): path = [] result = {} for source in [core, mantle]: for (key, value_new, ) in source.items(): path_ = (path + [key]) type_new = type(value_new) if (not (key in result)): result[key] = value_new else: value_old = result[key] type_old = type(value_old) if (value_old is None): result[key] = value_new else: if (not (type_old == type_new)): raise ValueError( "type mismatch at path %s: %s vs. %s" % ( ".".join(path), str(type_old), str(type_new), ) ) else: if (type_old == dict): result[key] = dict_merge(value_old, value_new, path_) elif (type_old == list): result[key] = (value_old + value_new) else: result[key] = value_new return result def main(): ## args argument_parser = _argparse.ArgumentParser() argument_parser.add_argument( "-m", "--main-file-path", type = str, dest = "main_file_path", default = "/etc/authelia/conf.d/main.json", metavar = "", ) argument_parser.add_argument( "-c", "--clients-directory-path", type = str, dest = "clients_directory_path", default = "/etc/authelia/conf.d/clients", metavar = "", ) argument_parser.add_argument( "-f", "--output-format", type = str, choices = ["json", "yaml"], dest = "output_format", default = "yaml", metavar = "", ) argument_parser.add_argument( "-o", "--output-path", type = str, dest = "output_path", default = "/etc/authelia/configuration.yml", metavar = "", ) args = argument_parser.parse_args() ## exec data = {} ### main if True: data_ = _json.loads(file_read(args.main_file_path)) data = dict_merge(data, data_) ### clients if True: for name in _os.listdir(args.clients_directory_path): data__ = _json.loads(file_read(_os.path.join(args.clients_directory_path, name))) data_ = { "identity_providers": { "oidc": { "clients": [data__] } } } data = dict_merge(data, data_) ### postprocess if True: if (len(data["identity_providers"]["oidc"]["clients"]) <= 0): data["identity_providers"]["oidc"]["clients"].append( { "public": False, "id": "_dummy", "description": "not a real client; just here to make Authelia run", "authorization_policy": "one_factor", "secret": "", "scopes": [], "redirect_uris": [], "grant_types": [], "response_types": [], "response_modes": [], } ) else: pass ## output if True: if (args.output_format == "json"): output_content = _json.dumps(data, indent = "\t") elif (args.output_format == "yaml"): output_content = _yaml.dump(data) else: raise ValueError("invalid output format") file_write(args.output_path, output_content) main()