templating - road to web ui

This commit is contained in:
bunkerity 2021-05-31 17:49:37 +02:00
parent 1d96620ae6
commit 2db967ad1d
No known key found for this signature in database
GPG Key ID: 3D80806F12602A7C
14 changed files with 186 additions and 285 deletions

View File

@ -3,37 +3,45 @@ import jinja2, glob, os, pathlib, copy, crypt, random, string
class Templator :
def __init__(self, config, input_path, output_path, target_path) :
self.__config = config
self.__config_global = copy.deepcopy(config)
if config["MULTISITE"] == "yes" and config["SERVER_NAME"] != "" :
self.__config_sites = {}
for server_name in config["SERVER_NAME"].split(" ") :
self.__config_sites[server_name] = {}
for k, v in config.items() :
if k.startswith(server_name + "_") :
self.__config_sites[server_name][k.replace(server_name + "_", "", 1)] = v
del self.__config_global[k]
self.__input_path = input_path
self.__output_path = output_path
self.__target_path = target_path
if not self.__target_path.endswith("/") :
self.__target_path += "/"
self.__template_env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath=self.__input_path), trim_blocks=True, lstrip_blocks=True)
self.__template_env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath=self.__input_path), lstrip_blocks=True)
def render_global(self) :
return self.__render("global")
def render_site(self, server_name=None, first_server=None) :
if server_name is None :
server_name = self.__config["SERVER_NAME"]
server_name = self.__config_global["SERVER_NAME"]
if first_server is None :
first_server = self.__config["SERVER_NAME"].split(" ")[0]
first_server = self.__config_global["SERVER_NAME"].split(" ")[0]
return self.__render("site", server_name, first_server)
def __prepare_config(self, type, server_name=None, first_server=None) :
real_config = copy.deepcopy(self.__config)
real_config = copy.deepcopy(self.__config_global)
if type == "site" and self.__config_global["MULTISITE"] == "yes" :
site_config = copy.deepcopy(self.__config_sites[first_server])
real_config.update(site_config)
if not server_name is None :
real_config["SERVER_NAME"] = server_name
if not first_server is None :
real_config["FIRST_SERVER"] = first_server
real_config["NGINX_PREFIX"] = self.__target_path
if real_config["MULTISITE"] == "yes" and type == "site" :
if self.__config_global["MULTISITE"] == "yes" and type == "site" :
real_config["NGINX_PREFIX"] += first_server + "/"
real_config["ROOT_FOLDER"] += "/" + first_server
for variable, value in self.__config.items() :
if variable.startswith(first_server + "_") :
real_config[variable.replace(first_server + "_", "", 1)] = value
if real_config["ROOT_SITE_SUBFOLDER"] != "" :
real_config["ROOT_FOLDER"] += "/" + real_config["ROOT_SITE_SUBFOLDER"]
return real_config

View File

@ -1 +1 @@
./main.py --settings /opt/work/bunkerized-nginx/settings.json --templates /opt/work/bunkerized-nginx/confs2 --output /tmp/debug --variables /tmp/variables.env
./main.py --settings /opt/work/bunkerized-nginx/settings.json --templates /opt/work/bunkerized-nginx/confs --output /tmp/debug --variables /tmp/variables.env

91
ui/Config.py Normal file
View File

@ -0,0 +1,91 @@
import json, uuid, glob
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)
for service in services_conf :
first_server = service["SERVER_NAME"].split(" ")[0]
for k, v in service.items() :
conf[first_server + "_" + k] = v
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")
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_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"] :
if type != "multiple" :
real_params = [param]
else :
real_params = param
for real_param in real_params :
if k == real_param["env"] 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)
def edit_service(self, old_server_name, variables) :
self.delete_service(old_server_name)
self.new_service(variables)
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.")
self.__gen_conf(global_env, new_services)

View File

@ -17,16 +17,21 @@ class Docker :
return self.__client.containers.get(id)
def reload_instance(self, id) :
return self.get_instance(id).kill(signal="SIGHUP")
self.get_instance(id).kill(signal="SIGHUP")
return "Instance " + id + " has been reloaded."
def start_instance(self, id) :
return self.get_instance(id).start()
self.get_instance(id).start()
return "Instance " + id + " has been started."
def stop_instance(self, id) :
return self.get_instance(id).stop()
self.get_instance(id).stop()
return "Instance " + id + " has been stopped."
def restart_instance(self, id) :
return self.get_instance(id).restart()
self.get_instance(id).restart()
return "Instance " + id + " has been restarted."
def remove_instance(self, id) :
return self.get_instance(id).remove(v=True, force=True)
def delete_instance(self, id) :
self.get_instance(id).remove(v=True, force=True)
return "Instance " + id + " has been deleted."

View File

@ -10,14 +10,12 @@ RUN chmod +x /tmp/dependencies.sh && \
rm -f /tmp/dependencies.sh
COPY gen/ /opt/gen
#COPY entrypoint/ /opt/entrypoint
#COPY confs/global/ /opt/confs/global
COPY confs/site/ /opt/confs/site
COPY ui/* /opt/entrypoint/
COPY ui/ /opt/entrypoint
COPY settings.json /opt
COPY ui/prepare.sh /tmp
chmod +x /tmp/prepare && \
RUN chmod +x /tmp/prepare.sh && \
/tmp/prepare.sh && \
rm -f /tmp/prepare.sh
@ -25,4 +23,4 @@ EXPOSE 5000
WORKDIR /opt/entrypoint
ENV FLASK_APP entrypoint.py
ENTRYPOINT ["/usr/bin/python3", "-m", "flask", "run", "--host=0.0.0.0"]
ENTRYPOINT ["/usr/bin/python3", "-m", "flask", "run", "--host=0.0.0.0"]

View File

@ -10,14 +10,12 @@ RUN chmod +x /tmp/dependencies.sh && \
rm -f /tmp/dependencies.sh
COPY gen/ /opt/gen
#COPY entrypoint/ /opt/entrypoint
#COPY confs/global/ /opt/confs/global
COPY confs/site/ /opt/confs/site
COPY ui/* /opt/entrypoint/
COPY ui/ /opt/entrypoint
COPY settings.json /opt
COPY ui/prepare.sh /tmp
chmod +x /tmp/prepare && \
RUN chmod +x /tmp/prepare && \
/tmp/prepare.sh && \
rm -f /tmp/prepare.sh
@ -25,4 +23,4 @@ EXPOSE 5000
WORKDIR /opt/entrypoint
ENV FLASK_APP entrypoint.py
ENTRYPOINT ["/usr/bin/python3", "-m", "flask", "run", "--host=0.0.0.0"]
ENTRYPOINT ["/usr/bin/python3", "-m", "flask", "run", "--host=0.0.0.0"]

View File

@ -16,14 +16,12 @@ RUN chmod +x /tmp/dependencies.sh && \
rm -f /tmp/dependencies.sh
COPY gen/ /opt/gen
#COPY entrypoint/ /opt/entrypoint
#COPY confs/global/ /opt/confs/global
COPY confs/site/ /opt/confs/site
COPY ui/* /opt/entrypoint/
COPY ui/ /opt/entrypoint
COPY settings.json /opt
COPY ui/prepare.sh /tmp
chmod +x /tmp/prepare && \
RUN chmod +x /tmp/prepare && \
/tmp/prepare.sh && \
rm -f /tmp/prepare.sh
@ -31,4 +29,4 @@ EXPOSE 5000
WORKDIR /opt/entrypoint
ENV FLASK_APP entrypoint.py
ENTRYPOINT ["/usr/bin/python3", "-m", "flask", "run", "--host=0.0.0.0"]
ENTRYPOINT ["/usr/bin/python3", "-m", "flask", "run", "--host=0.0.0.0"]

View File

@ -16,14 +16,12 @@ RUN chmod +x /tmp/dependencies.sh && \
rm -f /tmp/dependencies.sh
COPY gen/ /opt/gen
#COPY entrypoint/ /opt/entrypoint
#COPY confs/global/ /opt/confs/global
COPY confs/site/ /opt/confs/site
COPY ui/* /opt/entrypoint/
COPY ui/ /opt/entrypoint
COPY settings.json /opt
COPY ui/prepare.sh /tmp
chmod +x /tmp/prepare && \
RUN chmod +x /tmp/prepare && \
/tmp/prepare.sh && \
rm -f /tmp/prepare.sh
@ -31,4 +29,4 @@ EXPOSE 5000
WORKDIR /opt/entrypoint
ENV FLASK_APP entrypoint.py
ENTRYPOINT ["/usr/bin/python3", "-m", "flask", "run", "--host=0.0.0.0"]
ENTRYPOINT ["/usr/bin/python3", "-m", "flask", "run", "--host=0.0.0.0"]

View File

@ -10,14 +10,12 @@ RUN chmod +x /tmp/dependencies.sh && \
rm -f /tmp/dependencies.sh
COPY gen/ /opt/gen
#COPY entrypoint/ /opt/entrypoint
#COPY confs/global/ /opt/confs/global
COPY confs/site/ /opt/confs/site
COPY ui/* /opt/entrypoint/
COPY ui/ /opt/entrypoint
COPY settings.json /opt
COPY ui/prepare.sh /tmp
chmod +x /tmp/prepare && \
RUN chmod +x /tmp/prepare && \
/tmp/prepare.sh && \
rm -f /tmp/prepare.sh
@ -25,4 +23,4 @@ EXPOSE 5000
WORKDIR /opt/entrypoint
ENV FLASK_APP entrypoint.py
ENTRYPOINT ["/usr/bin/python3", "-m", "flask", "run", "--host=0.0.0.0"]
ENTRYPOINT ["/usr/bin/python3", "-m", "flask", "run", "--host=0.0.0.0"]

View File

@ -3,7 +3,8 @@
from flask import Flask, render_template, current_app, request
from Docker import Docker
import Docker, wrappers, utils
from Config import Config
import utils
import os, json, re
app = Flask(__name__, static_url_path="/", static_folder="static", template_folder="templates")
@ -11,9 +12,8 @@ ABSOLUTE_URI = ""
if "ABSOLUTE_URI" in os.environ :
ABSOLUTE_URI = os.environ["ABSOLUTE_URI"]
app.config["ABSOLUTE_URI"] = ABSOLUTE_URI
with open("/opt/settings.json", "r") as f :
app.config["CONFIG"] = json.loads(f.read())
app.config["DOCKER"] = Docker()
app.config["CONFIG"] = Config()
app.jinja_env.globals.update(env_to_summary_class=utils.env_to_summary_class)
app.jinja_env.globals.update(form_service_gen=utils.form_service_gen)
app.jinja_env.globals.update(form_service_gen_multiple=utils.form_service_gen_multiple)
@ -24,7 +24,7 @@ app.jinja_env.globals.update(form_service_gen_multiple_values=utils.form_service
def home() :
try :
instances_number = len(app.config["DOCKER"].get_instances())
services_number = 0 # TODO
services_number = len(app.config["CONFIG"].get_services())
return render_template("home.html", title="Home", instances_number=instances_number, services_number=services_number)
except Exception as e :
return render_template("error.html", title="Error", error=e)
@ -38,88 +38,70 @@ def instances() :
# Check operation
if not "operation" in request.form or not request.form["operation"] in ["reload", "start", "stop", "restart", "delete"] :
return render_template("error.html", title="Error", error="Missing operation parameter on /instances.")
raise Exception("Missing operation parameter on /instances.")
# Check that all fields are present
if not "INSTANCE_ID" in request.form :
return render_template("error.html", title="Error", error="Missing INSTANCE_ID parameter.")
raise Exception("Missing INSTANCE_ID parameter.")
# Do the operation
if request.form["operation"] == "reload" :
app.config["DOCKER"].reload(request_form["INSTANCE_ID"])
operation = app.config["DOCKER"].reload(request_form["INSTANCE_ID"])
elif request.form["operation"] == "start" :
app.config["DOCKER"].start(request_form["INSTANCE_ID"])
operation = app.config["DOCKER"].start(request_form["INSTANCE_ID"])
elif request.form["operation"] == "stop" :
app.config["DOCKER"].stop(request_form["INSTANCE_ID"])
operation = app.config["DOCKER"].stop(request_form["INSTANCE_ID"])
elif request.form["operation"] == "restart" :
app.config["DOCKER"].restart(request_form["INSTANCE_ID"])
operation = app.config["DOCKER"].restart(request_form["INSTANCE_ID"])
elif request.form["operation"] == "delete" :
app.config["DOCKER"].remove(request_form["INSTANCE_ID"])
operation = app.config["DOCKER"].delete(request_form["INSTANCE_ID"])
# Display instances
instances = app.config["DOCKER"].get_instances()
return render_template("instances.html", title="Instances", instances=instances, operation="todo")
return render_template("instances.html", title="Instances", instances=instances, operation=operation)
except Exception as e :
return render_template("error.html", title="Error", error=e)
return render_template("error.html", title="Error", error=str(e))
@app.route('/services', methods=["GET", "POST"])
def services():
try :
# Manage services
operation = ""
if request.method == "POST" :
# Get the client
check, client = wrappers.get_client()
if not check :
return render_template("error.html", title="Error", error=client)
# Check operation
if not "operation" in request.form or not request.form["operation"] in ["new", "edit", "delete"] :
raise Exception("Missing operation parameter on /services.")
# Manage services
operation = ""
if request.method == "POST" :
# Check variables
variables = copy.deepcopy(request.form)
if not "OLD_SERVER_NAME" in request.form and request.form["operation"] == "edit" :
raise Exception("Missing OLD_SERVER_NAME parameter.")
if request.form["operation"] in ["new", "edit"] :
del variables["operation"]
if request.form["operation"] == "edit" :
del variables["OLD_SERVER_NAME"]
app.config["CONFIG"].check_variables(variables)
# Check operation
if not "operation" in request.form or not request.form["operation"] in ["new", "edit", "delete"] :
return render_template("error.html", title="Error", error="Missing operation parameter on /services.")
# Delete
elif request.form["operation"] == "delete" :
if not "SERVER_NAME" in request.form :
raise Exception("Missing SERVER_NAME parameter.")
app.config["CONFIG"].check_variables({"SERVER_NAME" : request.form["SERVER_NAME"]})
# Check that all fields are present and they match the corresponding regex
env = {}
env["MULTISITE"] = "yes"
if request.form["operation"] in ["new", "edit"] :
for category in current_app.config["CONFIG"] :
for param in current_app.config["CONFIG"][category]["params"] :
if param["type"] == "multiple" :
for param_user in request.form :
if param_user.startswith(param["params"][0]["env"]) :
suffix = param_user.replace(param["params"][0]["env"], "")
for param_multiple in param["params"] :
if not param_multiple["env"] + suffix in request.form :
return render_template("error.html", title="Error", error="Missing " + param["env"] + " parameter.")
if not re.search(param_multiple["regex"], request.form[param_multiple["env"] + suffix]) :
return render_template("error.html", title="Error", error="Parameter " + param["env"] + " doesn't match regex.")
env[param_multiple["env"] + suffix] = request.form[param_multiple["env"] + suffix]
else :
if not param["env"] in request.form :
return render_template("error.html", title="Error", error="Missing " + param["env"] + " parameter.")
if not re.search(param["regex"], request.form[param["env"]]) :
return render_template("error.html", title="Error", error="Parameter " + param["env"] + " doesn't match regex.")
env[param["env"]] = request.form[param["env"]]
if request.form["operation"] == "edit" :
if not "OLD_SERVER_NAME" in request.form :
return render_template("error.html", title="Error", error="Missing OLD_SERVER_NAME parameter.")
if not re.search("^([a-z\-0-9]+\.?)+$", request.form["OLD_SERVER_NAME"]) :
return render_template("error.html", title="Error", error="Parameter OLD_SERVER_NAME doesn't match regex.")
elif request.form["operation"] == "delete" :
if not "SERVER_NAME" in request.form :
return render_template("error.html", title="Error", error="Missing SERVER_NAME parameter.")
if not re.search("^([a-z\-0-9]+\.?)+$", request.form["SERVER_NAME"]) :
return render_template("error.html", title="Error", error="Parameter SERVER_NAME doesn't match regex.")
# Do the operation
if request.form["operation"] == "new" :
operation = app.config["CONFIG"].new_service(variables)
elif request.form["operation"] == "edit" :
operation = app.config["CONFIG"].edit_service(request.form["OLD_SERVER_NAME"], variables)
elif request.form["operation"] == "delete" :
operation = app.config["CONFIG"].delete_service(request.form["SERVER_NAME"])
# Do the operation
check, operation = wrappers.operation_service(client, request.form, env)
if not check :
render_template("error.html", title="Error", error=operation)
# Display services
services = app.config["CONFIG"].get_services()
return render_template("services.html", title="Services", services=services, operation=operation)
# Display services
check, services = wrappers.get_services()
if not check :
return render_template("error.html", title="Error", error=services)
return render_template("services.html", title="Services", services=services, operation=operation)
except Exception as e :
return render_template("error.html", title="Error", error=str(e))

View File

@ -8,7 +8,7 @@
<div class="modal-body">
<ul class="nav nav-pills mb-3" id="pills-tab-edit" role="tablist">
{% set check = {"active": "active", "selected": "true"} %}
{% for k, v in config["CONFIG"].items() %}
{% for k, v in config["CONFIG"].get_config().items() %}
<li class="nav-item" role="presentation">
<a class="nav-link {{ check.active }}" id="edit-{{ v["id"] }}-{{ id_server_name }}-tab" data-bs-toggle="pill" href="#edit-{{ v["id"] }}-{{ id_server_name }}" role="tab" aria-controls="edit-{{ v["id"] }}-{{ id_server_name }}" aria-selected="{{ check.selected }}">{{ k }}</a>
</li>
@ -20,7 +20,7 @@
<input type="hidden" value="{{ service["SERVER_NAME"] }}" name="OLD_SERVER_NAME">
<div class="tab-content" id="edit-content-{{ id_server_name }}">
{% set check = {"class": "show active"} %}
{% for k, v in config["CONFIG"].items() %}
{% for k, v in config["CONFIG"].get_config().items() %}
<div class="tab-pane fade {{ check.class }}" id="edit-{{ v["id"] }}-{{ id_server_name }}" role="tabpanel" aria-labelledby="edit-{{ v["id"] }}-{{ id_server_name }}-tab">
{% for param in v["params"] %}
<div class="row mb-3" id="form-edit-{{ id_server_name }}-{{ param["id"] }}">

View File

@ -8,7 +8,7 @@
<div class="modal-body">
<ul class="nav nav-pills mb-3" id="pills-tab-new" role="tablist">
{% set check = {"active": "active", "selected": "true"} %}
{% for k, v in config["CONFIG"].items() %}
{% for k, v in config["CONFIG"].get_config().items() %}
<li class="nav-item" role="presentation">
<a class="nav-link {{ check.active }}" id="new-{{ v["id"] }}-tab" data-bs-toggle="pill" href="#new-{{ v["id"] }}" role="tab" aria-controls="new-{{ v["id"] }}" aria-selected="{{ check.selected }}">{{ k }}</a>
</li>
@ -19,7 +19,7 @@
<form id="form-new">
<div class="tab-content" id="new-content">
{% set check = {"class": "show active"} %}
{% for k, v in config["CONFIG"].items() %}
{% for k, v in config["CONFIG"].get_config().items() %}
<div class="tab-pane fade {{ check.class }}" id="new-{{ v["id"] }}" role="tabpanel" aria-labelledby="new-{{ v["id"] }}-tab">
{% for param in v["params"] %}
<div class="row mb-3" id="form-new-{{ param["id"] }}">
@ -43,4 +43,4 @@
</div>
</div>
</div>
</div>
</div>

View File

@ -5,13 +5,6 @@ import datetime, re, json
def log(event) :
print("[" + str(datetime.datetime.now().replace(microsecond=0)) + "] " + event, flush=True)
def replace_in_file(file, old_str, new_str) :
with open(file) as f :
data = f.read()
data = data[::-1].replace(old_str[::-1], new_str[::-1], 1)[::-1]
with open(file, "w") as f :
f.write(data)
def env_to_summary_class(var, value) :
if type(var) is list and type(value) is list :
for i in range(0, len(var)) :

View File

@ -1,168 +0,0 @@
#!/usr/bin/python3
import utils
import docker, os, stat, sys, subprocess, shutil
def get_client() :
endpoint = "/var/run/docker.sock"
if not os.path.exists(endpoint) or not stat.S_ISSOCK(os.stat(endpoint).st_mode) :
return False, "Can't connect to /var/run/docker.sock (is it mounted ?)"
try :
client = docker.DockerClient(base_url='unix:///var/run/docker.sock')
except Exception as e :
return False, "Can't instantiate DockerClient : " + str(e)
return True, client
def get_containers(client, label) :
try :
containers = client.containers.list(all=True, filters={"label" : "bunkerized-nginx." + label})
except docker.errors.APIError as e :
return False, "Docker API error " + str(e)
return True, containers
def get_instances(client) :
return get_containers(client, "UI")
def get_services() :
services = []
try :
for root, dirs, files in os.walk("/etc/nginx") :
for file in files :
filepath = os.path.join(root, file)
if filepath.endswith("/nginx.env") :
with open(filepath, "r") as f :
service = {}
for line in f.readlines() :
name = line.split("=")[0]
value = line.replace(name + "=", "", 1).strip()
service[name] = value
services.append(service)
except Exception as e :
return False, str(e)
return True, services
def reload_instances(client) :
check, instances = get_instances(client)
if not check :
return check, instances
i = 0
for instance in instances :
try :
instance.kill(signal="SIGHUP")
except docker.errors.APIError as e :
return False, str(e)
i += 1
return True, i
def new_service(client, env) :
proc = subprocess.run(["/bin/su", "-s", "/bin/sh", "-c", "/opt/entrypoint/site-config.sh" + " " + env["SERVER_NAME"], "nginx"], env=env, capture_output=True)
if proc.returncode != 0 :
return False, "Error code " + str(proc.returncode) + " while generating config."
utils.replace_in_file("/etc/nginx/nginx.conf", "}", "include /etc/nginx/" + env["SERVER_NAME"] + "/server.conf;\n}")
check, nb = reload_instances(client)
if not check :
return check, nb
return True, "Web service " + env["SERVER_NAME"] + " has been added."
def edit_service(client, old_server_name, env) :
check, delete = delete_service(client, old_server_name)
if not check :
return check, delete
check, new = new_service(client, env)
if not check :
return check, new
return True, "Web service " + old_server_name + " has been edited."
def delete_service(client, server_name) :
if not os.path.isdir("/etc/nginx/" + server_name) :
return False, "Config doesn't exist."
try :
shutil.rmtree("/etc/nginx/" + server_name)
except Exception as e :
return False, str(e)
utils.replace_in_file("/etc/nginx/nginx.conf", "include /etc/nginx/" + server_name + "/server.conf;\n", "")
check, nb = reload_instances(client)
if not check :
return check, nb
return True, "Web service " + server_name + " has been deleted."
def operation_service(client, form, env) :
if form["operation"] == "new" :
return new_service(client, env)
if form["operation"] == "edit" :
return edit_service(client, form["OLD_SERVER_NAME"], env)
if form["operation"] == "delete" :
return delete_service(client, form["SERVER_NAME"])
return False, "Wrong operation parameter."
def get_instance(client, id) :
try :
instance = client.containers.get(id)
if not "bunkerized-nginx.UI" in instance.labels :
raise docker.errors.NotFound()
except Exception as e :
return False, str(e)
return True, instance
def reload_instance(client, id) :
check, instance = get_instance(client, id)
if not check :
return check, instance
try :
instance.kill(signal="SIGHUP")
except docker.errors.APIError as e :
return False, str(e)
return True, "Instance " + id + " has been reloaded."
def start_instance(client, id) :
check, instance = get_instance(client, id)
if not check :
return check, instance
try :
instance.start()
except docker.errors.APIError as e :
return False, str(e)
return True, "Instance " + id + " has been started."
def stop_instance(client, id) :
check, instance = get_instance(client, id)
if not check :
return check, instance
try :
instance.stop()
except docker.errors.APIError as e :
return False, str(e)
return True, "Instance " + id + " has been stopped."
def restart_instance(client, id) :
check, instance = get_instance(client, id)
if not check :
return check, instance
try :
instance.restart()
except docker.errors.APIError as e :
return False, str(e)
return True, "Instance " + id + " has been restarted."
def delete_instance(client, id) :
check, instance = get_instance(client, id)
if not check :
return check, instance
try :
instance.remove(v=True, force=True)
except docker.errors.APIError as e :
return False, str(e)
return True, "Instance " + id + " has been deleted."
def operation_instance(client, form) :
if form["operation"] == "reload" :
return reload_instance(client, form["INSTANCE_ID"])
if form["operation"] == "start" :
return start_instance(client, form["INSTANCE_ID"])
if form["operation"] == "stop" :
return stop_instance(client, form["INSTANCE_ID"])
if form["operation"] == "restart" :
return restart_instance(client, form["INSTANCE_ID"])
if form["operation"] == "delete" :
return delete_instance(client, form["INSTANCE_ID"])
return False, "Wrong operation parameter."