diff --git a/settings.json b/settings.json index 69dff66..592c5a9 100644 --- a/settings.json +++ b/settings.json @@ -656,7 +656,7 @@ "env": "SELF_SIGNED_SSL_COUNTRY", "id": "self-signed-ssl-country", "label": "Country of the self-signed certificate", - "regex": "^[:print:]+$", + "regex": "^[A-Z]{2}$", "type": "text" }, { @@ -665,7 +665,7 @@ "env": "SELF_SIGNED_SSL_STATE", "id": "self-signed-ssl-state", "label": "State of the self-signed certificate", - "regex": "^[:print:]+$", + "regex": "^[A-Za-z\\-]+$", "type": "text" }, { @@ -674,7 +674,7 @@ "env": "SELF_SIGNED_SSL_CITY", "id": "self-signed-ssl-city", "label": "City of the self-signed certificate", - "regex": "^[:print:]+$", + "regex": "^[A-Za-z\\-]+$", "type": "text" }, { @@ -683,7 +683,7 @@ "env": "SELF_SIGNED_SSL_OU", "id": "self-signed-ssl-ou", "label": "Organizational Unit of the self-signed certificate", - "regex": "^[:print:]+$", + "regex": "^[A-Za-z\\-]+$$", "type": "text" }, { @@ -692,7 +692,7 @@ "env": "SELF_SIGNED_SSL_ORG", "id": "self-signed-ssl-org", "label": "Organization name of the self-signed certificate", - "regex": "^[:print:]+$", + "regex": "^[A-Za-z\\- ]+$$", "type": "text" }, { @@ -701,7 +701,7 @@ "env": "SELF_SIGNED_SSL_CN", "id": "self-signed-ssl-cn", "label": "Common Name of the self-signed certificate", - "regex": "^[:print:]+$", + "regex": "^[A-Za-z\\-\\.0-9]+$", "type": "text" } ] diff --git a/ui/Docker.py b/ui/Docker.py deleted file mode 100644 index 2facce6..0000000 --- a/ui/Docker.py +++ /dev/null @@ -1,37 +0,0 @@ -import docker - -class Docker : - - def __init__(self, docker_host) : - self.__client = docker.DockerClient(base_url=docker_host) - - def get_instances(self) : - return self.__client.containers.list(all=True, filters={"label" : "bunkerized-nginx.UI"}) - - def reload_instances(self) : - for instance in self.get_instances() : - instance.kill(signal="SIGHUP") - return True - - def get_instance(self, id) : - return self.__client.containers.get(id) - - def reload_instance(self, id) : - self.get_instance(id).kill(signal="SIGHUP") - return "Instance " + id + " has been reloaded." - - def start_instance(self, id) : - self.get_instance(id).start() - return "Instance " + id + " has been started." - - def stop_instance(self, id) : - self.get_instance(id).stop() - return "Instance " + id + " has been stopped." - - def restart_instance(self, id) : - self.get_instance(id).restart() - return "Instance " + id + " has been restarted." - - def delete_instance(self, id) : - self.get_instance(id).remove(v=True, force=True) - return "Instance " + id + " has been deleted." diff --git a/ui/Dockerfile b/ui/Dockerfile index 7219923..5dca2ac 100644 --- a/ui/Dockerfile +++ b/ui/Dockerfile @@ -1,6 +1,6 @@ FROM alpine -RUN apk add py3-pip bash +RUN apk add py3-pip bash build-base python3-dev libffi-dev COPY ui/requirements.txt /tmp RUN pip3 install -r /tmp/requirements.txt @@ -19,4 +19,4 @@ EXPOSE 5000 WORKDIR /opt/bunkerized-nginx/ui USER nginx:nginx -ENTRYPOINT ["/usr/bin/gunicorn", "--bind", "0.0.0.0:5000", "-m", "007", "wsgi:app"] \ No newline at end of file +ENTRYPOINT ["/usr/bin/gunicorn", "--bind", "0.0.0.0:5000", "-m", "007", "wsgi:app"] diff --git a/ui/entrypoint.py b/ui/entrypoint.py index 203814f..29ffc37 100644 --- a/ui/entrypoint.py +++ b/ui/entrypoint.py @@ -6,9 +6,8 @@ from flask_wtf.csrf import CSRFProtect, CSRFError from src.Instances import Instances from src.User import User +from src.Config import Config -from Docker import Docker -from Config import Config import utils import os, json, re, copy, traceback @@ -73,7 +72,7 @@ def home() : 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) + return render_template("error.html", title="Error", error=str(e) + "
" + traceback.format_exc().replace("\n", "
")) @app.route('/instances', methods=["GET", "POST"]) @login_required @@ -106,7 +105,7 @@ def instances() : return render_template("instances.html", title="Instances", instances=instances, operation=operation) except Exception as e : - return render_template("error.html", title="Error", error=str(e)) + return render_template("error.html", title="Error", error=str(e) + "\n" + traceback.format_exc()) @app.route('/services', methods=["GET", "POST"]) @@ -123,6 +122,7 @@ def services(): # Check variables variables = copy.deepcopy(request.form.to_dict()) + del variables["csrf_token"] 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"] : @@ -145,13 +145,14 @@ def services(): elif request.form["operation"] == "delete" : operation = app.config["CONFIG"].delete_service(request.form["SERVER_NAME"]) - # Reload containers - for instance in app.config["DOCKER"].get_instances() : - app.config["DOCKER"].reload_instance(instance.id) + # Reload instances + reload = app.config["INSTANCES"].reload_instances() + if not reload : + operation = "Reload failed for at least one instance..." # Display services services = app.config["CONFIG"].get_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) + traceback.format_exc()) + return render_template("error.html", title="Error", error=str(e) + "\n" + traceback.format_exc()) diff --git a/ui/Config.py b/ui/src/Config.py similarity index 92% rename from ui/Config.py rename to ui/src/Config.py index 02843d7..9f24cef 100644 --- a/ui/Config.py +++ b/ui/src/Config.py @@ -1,4 +1,4 @@ -import json, uuid, glob, copy, re, subprocess +import json, uuid, glob, copy, re, subprocess, os class Config : @@ -7,6 +7,8 @@ class Config : self.__settings = json.loads(f.read()) def __env_to_dict(self, filename) : + if not os.path.isfile(filename) : + return {} with open(filename, "r") as f : env = f.read() data = {} @@ -25,6 +27,8 @@ class Config : def __gen_conf(self, global_conf, services_conf) : conf = copy.deepcopy(global_conf) + if not "SERVER_NAME" in conf : + conf["SERVER_NAME"] = "" servers = conf["SERVER_NAME"].split(" ") if conf["SERVER_NAME"] == "" : servers = [] @@ -39,9 +43,9 @@ class Config : self.__dict_to_env(env_file, conf) proc = subprocess.run(["/opt/bunkerized-nginx/gen/main.py", "--settings", "/opt/bunkerized-nginx/settings.json", "--templates", "/opt/bunkerized-nginx/confs", "--output", "/etc/nginx", "--variables", env_file], capture_output=True) stderr = proc.stderr.decode("ascii") - #stdout = proc.stdout.decode("ascii") + stdout = proc.stdout.decode("ascii") if stderr != "" or proc.returncode != 0 : - raise Exception("Error from generator (return code = " + str(proc.returncode) + ") : " + stderr) + raise Exception("Error from generator (return code = " + str(proc.returncode) + ") : " + stderr + "\n" + stdout) def get_settings(self) : return self.__settings @@ -54,6 +58,7 @@ class Config : for filename in glob.iglob("/etc/nginx/**/site.env") : env = self.__env_to_dict(filename) services.append(env) + services.append(self.__env_to_dict("/etc/nginx/site.env")) return services def check_variables(self, variables) : diff --git a/ui/templates/error.html b/ui/templates/error.html index e5927c4..9580c98 100644 --- a/ui/templates/error.html +++ b/ui/templates/error.html @@ -4,7 +4,9 @@
Something went wrong...

- {{ error }} + {% autoescape false %} + {{ error | replace("\n", "
") }} + {% endautoescape %}
{% endblock %} diff --git a/ui/templates/instances.html b/ui/templates/instances.html index aa11bbc..583d218 100644 --- a/ui/templates/instances.html +++ b/ui/templates/instances.html @@ -15,6 +15,12 @@
+ {% if instances|length == 0 %} +
+ No instance to show... +
+ {% endif %} + {% for instance in instances %} {% set color = "dark" %} {% if instance["status"] == "up" %} diff --git a/ui/templates/services.html b/ui/templates/services.html index 7b06486..ce1a3a9 100644 --- a/ui/templates/services.html +++ b/ui/templates/services.html @@ -2,24 +2,25 @@ {% block content %} -{% if operation != "" %} -
-
- -
-
-{% endif %} - -
+ {% if operation != "" %} + + {% endif %} + + {% if services|length == 0 %} +
+ No service to show... +
+ {% endif %} + {% for service in services %} {% set id_server_name = service["SERVER_NAME"].replace(".", "-") %} @@ -58,12 +59,13 @@
- {% include "services-new.html" %} {% include "services-edit.html" %} {% include "services-delete.html" %} {% endfor %} + {% include "services-new.html" %} + {% endblock %}