bunkerweb/gen/Configurator.py
2022-06-03 17:24:14 +02:00

135 lines
5.8 KiB
Python

import sys, json, glob, re, os, traceback
sys.path.append("/opt/bunkerweb/utils")
from logger import log
class Configurator :
def __init__(self, settings, core, plugins, variables) :
self.__settings = self.__load_settings(settings)
self.__core = self.__load_plugins(core)
self.__plugins = self.__load_plugins(plugins)
self.__variables = self.__load_variables(variables)
self.__multisite = False
if "MULTISITE" in self.__variables and self.__variables["MULTISITE"] == "yes" :
self.__multisite = True
self.__servers = self.__map_servers()
def __map_servers(self) :
if not self.__multisite or not "SERVER_NAME" in self.__variables :
return {}
servers = {}
for server_name in self.__variables["SERVER_NAME"].split(" ") :
if not re.search(self.__settings["SERVER_NAME"]["regex"], server_name) :
log("GENERATOR", "⚠️", "Ignoring server name " + server_name + " because regex is not valid")
continue
names = [server_name]
if server_name + "_SERVER_NAME" in self.__variables :
if not re.search(self.__settings["SERVER_NAME"]["regex"], self.__variables[server_name + "_SERVER_NAME"]) :
log("GENERATOR", "⚠️", "Ignoring " + server_name + "_SERVER_NAME because regex is not valid")
else :
names = self.__variables[server_name + "_SERVER_NAME"].split(" ")
servers[server_name] = names
return servers
def __load_settings(self, path) :
with open(path) as f :
return json.loads(f.read())
def __load_plugins(self, path) :
plugins = {}
files = glob.glob(path + "/*/plugin.json")
for file in files :
try :
with open(file) as f :
plugins.update(json.loads(f.read())["settings"])
except :
log("GENERATOR", "", "Exception while loading JSON from " + file + " :")
print(traceback.format_exc())
return plugins
def __load_variables(self, path) :
variables = {}
with open(path) as f :
lines = f.readlines()
for line in lines :
line = line.strip()
if line.startswith("#") or line == "" or not "=" in line :
continue
var = line.split("=")[0]
value = line[len(var)+1:]
variables[var] = value
return variables
def get_config(self) :
config = {}
# Extract default settings
default_settings = [self.__settings, self.__core, self.__plugins]
for settings in default_settings :
for setting, data in settings.items() :
config[setting] = data["default"]
# Override with variables
for variable, value in self.__variables.items() :
ret, err = self.__check_var(variable)
if ret :
config[variable] = value
else :
log("GENERATOR", "⚠️", "Ignoring variable " + variable + " : " + err)
# Expand variables to each sites if MULTISITE=yes and if not present
if config["MULTISITE"] == "yes" :
for server_name in config["SERVER_NAME"].split(" ") :
if server_name == "" :
continue
for settings in default_settings :
for setting, data in settings.items() :
if data["context"] == "global" :
continue
key = server_name + "_" + setting
if setting == "SERVER_NAME" :
if key not in config :
config[key] = server_name
continue
if key not in config :
config[key] = config[setting]
return config
def __check_var(self, variable) :
value = self.__variables[variable]
# MULTISITE=no
if not self.__multisite :
where, real_var = self.__find_var(variable)
if not where :
return False, "variable name " + variable + " doesn't exist"
if not "regex" in where[real_var] :
return False, "missing regex for variable " + variable
if not re.search(where[real_var]["regex"], value) :
return False, "value " + value + " doesn't match regex " + where[real_var]["regex"]
return True, "ok"
# MULTISITE=yes
prefixed, real_var = self.__var_is_prefixed(variable)
where, real_var = self.__find_var(real_var)
if not where :
return False, "variable name " + variable + " doesn't exist"
if prefixed and where[real_var]["context"] != "multisite" :
return False, "context of " + variable + " isn't multisite"
if not re.search(where[real_var]["regex"], value) :
return False, "value " + value + " doesn't match regex " + where[real_var]["regex"]
return True, "ok"
def __find_var(self, variable) :
targets = [self.__settings, self.__core, self.__plugins]
for target in targets :
if variable in target :
return target, variable
for real_var, settings in target.items() :
if "multiple" in settings and re.search("^" + real_var + "_" + "[0-9]+$", variable) :
return target, real_var
return False, variable
def __var_is_prefixed(self, variable) :
for server in self.__servers :
if variable.startswith(server + "_") :
return True, variable.replace(server + "_", "", 1)
return False, variable