import json, uuid, glob, copy, re, subprocess class Config : def __init__(self) : with open("/opt/settings.json", "r") as f : self.__settings = json.loads(f.read()) def __env_to_dict(self, filename) : with open(filename, "r") as f : env = f.read() data = {} for line in env.split("\n") : var = line.split("=")[0] val = line.replace(var + "=", "", 1) data[var] = val return data def __dict_to_env(self, filename, variables) : env = "" for k, v in variables.items() : env += k + "=" + v + "\n" with open(filename, "w") as f : f.write(env) def __gen_conf(self, global_conf, services_conf) : conf = copy.deepcopy(global_conf) servers = conf["SERVER_NAME"].split(" ") if conf["SERVER_NAME"] == "" : servers = [] for service in services_conf : first_server = service["SERVER_NAME"].split(" ")[0] if not first_server in servers : servers.append(first_server) for k, v in service.items() : conf[first_server + "_" + k] = v conf["SERVER_NAME"] = " ".join(servers) env_file = "/tmp/" + str(uuid.uuid4()) + ".env" self.__dict_to_env(env_file, conf) proc = subprocess.run(["/bin/su", "-c", "/opt/gen/main.py --settings /opt/settings.json --templates /opt/confs --output /etc/nginx --variables " + env_file, "nginx"], capture_output=True) stderr = proc.stderr.decode("ascii") #stdout = proc.stdout.decode("ascii") if stderr != "" or proc.returncode != 0 : raise Exception("Error from generator (return code = " + str(proc.returncode) + ") : " + stderr) def get_settings(self) : return self.__settings def get_config(self) : return self.__env_to_dict("/etc/nginx/global.env") def get_services(self) : services = [] for filename in glob.iglob("/etc/nginx/**/site.env") : env = self.__env_to_dict(filename) services.append(env) return services def check_variables(self, variables) : for k, v in variables.items() : check = False for category in self.__settings : for param in self.__settings[category]["params"] : multiple = False if param["type"] != "multiple" : real_params = [param] else : real_params = param["params"] multiple = True for real_param in real_params : if (((not multiple and k == real_param["env"]) or (multiple and re.search("^" + real_param["env"] + "_" + "[0-9]+$", k))) and real_param["context"] == "multisite" and re.search(real_param["regex"], v)) : check = True if not check : raise Exception("Variable " + k + " is not valid.") def new_service(self, variables) : global_env = self.__env_to_dict("/etc/nginx/global.env") services = self.get_services() for service in services : if service["SERVER_NAME"] == variables["SERVER_NAME"] or service["SERVER_NAME"] in variables["SERVER_NAME"].split(" ") : raise Exception("Service " + service["SERVER_NAME"] + " already exists.") services.append(variables) self.__gen_conf(global_env, services) return "Configuration for " + variables["SERVER_NAME"] + " has been generated." def edit_service(self, old_server_name, variables) : self.delete_service(old_server_name) self.new_service(variables) return "Configuration for " + old_server_name + " has been edited." def delete_service(self, server_name) : global_env = self.__env_to_dict("/etc/nginx/global.env") services = self.get_services() new_services = [] found = False for service in services : if service["SERVER_NAME"].split(" ")[0] == server_name : found = True else : new_services.append(service) if not found : raise Exception("Can't delete missing " + server_name + " configuration.") new_servers = global_env["SERVER_NAME"].split(" ") if server_name in new_servers : new_servers.remove(server_name) global_env["SERVER_NAME"] = " ".join(new_servers) self.__gen_conf(global_env, new_services) return "Configuration for " + server_name + " has been deleted."