resolve bugs on the stable version
This commit is contained in:
parent
15bdb076c8
commit
36b8760d4d
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,5 +1,16 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v1.2.8 - 2021/07/22
|
||||||
|
|
||||||
|
- Fix broken links in README
|
||||||
|
- Fix regex for EMAIL_LETS_ENCRYPT
|
||||||
|
- Fix regex for REMOTE_PHP and REMOTE_PHP_PATH
|
||||||
|
- Fix regex for SELF_SIGNED_*
|
||||||
|
- Fix various bugs related to web UI
|
||||||
|
- Fix bug in autoconf (missing instances parameter to reload function)
|
||||||
|
- Remove old .env files when generating a new configuration
|
||||||
|
-
|
||||||
|
|
||||||
## v1.2.7 - 2021/06/14
|
## v1.2.7 - 2021/06/14
|
||||||
|
|
||||||
- Add custom robots.txt and sitemap to RTD
|
- Add custom robots.txt and sitemap to RTD
|
||||||
|
|||||||
@ -432,8 +432,8 @@ bunkerized-nginx comes with a set of predefined security settings that you can (
|
|||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
This project is licensed under the terms of the [GNU Affero General Public License (AGPL) version 3](https://github.com/bunkerity/bunkerized-nginx/LICENSE.md).
|
This project is licensed under the terms of the [GNU Affero General Public License (AGPL) version 3](https://github.com/bunkerity/bunkerized-nginx/blob/master/LICENSE.md).
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
If you would like to contribute to the project you can read the [contributing guidelines](https://github.com/bunkerity/bunkerized-nginx/CONTRIBUTING.md) to get started.
|
If you would like to contribute to the project you can read the [contributing guidelines](https://github.com/bunkerity/bunkerized-nginx/blob/master/CONTRIBUTING.md) to get started.
|
||||||
|
|||||||
@ -173,7 +173,7 @@ class AutoConf :
|
|||||||
self.__servers[id].reload()
|
self.__servers[id].reload()
|
||||||
utils.log("[*] Deactivating config for " + vars["SERVER_NAME"])
|
utils.log("[*] Deactivating config for " + vars["SERVER_NAME"])
|
||||||
self.__gen_env()
|
self.__gen_env()
|
||||||
if self.__config.reload() :
|
if self.__config.reload(self.__instances) :
|
||||||
utils.log("[*] Deactivated config for " + vars["SERVER_NAME"])
|
utils.log("[*] Deactivated config for " + vars["SERVER_NAME"])
|
||||||
else :
|
else :
|
||||||
utils.log("[!] Can't deactivate config for " + vars["SERVER_NAME"])
|
utils.log("[!] Can't deactivate config for " + vars["SERVER_NAME"])
|
||||||
|
|||||||
14
gen/main.py
14
gen/main.py
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import argparse, os, sys, shutil
|
import argparse, os, sys, shutil, glob
|
||||||
|
|
||||||
import utils
|
import utils
|
||||||
from Configurator import Configurator
|
from Configurator import Configurator
|
||||||
@ -51,14 +51,10 @@ if __name__ == "__main__" :
|
|||||||
config = configurator.get_config()
|
config = configurator.get_config()
|
||||||
#print(config)
|
#print(config)
|
||||||
|
|
||||||
# Remove old config
|
# TODO : find a proper way to remove old sites
|
||||||
# TODO : remove unnecessary files after rendering
|
env_list = glob.glob(args.output + "/**/*.env", recursive=True)
|
||||||
# for filename in os.listdir(args.output):
|
for env in env_list :
|
||||||
# file_path = os.path.join(args.output, filename)
|
os.remove(env)
|
||||||
# if os.path.isfile(file_path) or os.path.islink(file_path):
|
|
||||||
# os.unlink(file_path)
|
|
||||||
# elif os.path.isdir(file_path):
|
|
||||||
# shutil.rmtree(file_path)
|
|
||||||
|
|
||||||
# Generate the files from templates and config
|
# Generate the files from templates and config
|
||||||
templator = Templator(config, args.templates, args.output, args.target)
|
templator = Templator(config, args.templates, args.output, args.target)
|
||||||
|
|||||||
@ -525,7 +525,7 @@
|
|||||||
"env": "EMAIL_LETS_ENCRYPT",
|
"env": "EMAIL_LETS_ENCRYPT",
|
||||||
"id": "email-lets-encrypt",
|
"id": "email-lets-encrypt",
|
||||||
"label": "Email lets encrypt",
|
"label": "Email lets encrypt",
|
||||||
"regex": "^([a-z0-9\\-\\.]+@([a-z\\-0-9]+\\.?)|.{0})$",
|
"regex": "^([a-z0-9\\-\\.]+@[a-z\\-0-9\\.]+|.{0})$",
|
||||||
"type": "text"
|
"type": "text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -615,7 +615,7 @@
|
|||||||
"env": "SELF_SIGNED_SSL_COUNTRY",
|
"env": "SELF_SIGNED_SSL_COUNTRY",
|
||||||
"id": "self-signed-ssl-country",
|
"id": "self-signed-ssl-country",
|
||||||
"label": "Country of the self-signed certificate",
|
"label": "Country of the self-signed certificate",
|
||||||
"regex": "^[:print:]+$",
|
"regex": "^[A-Z]{2}$",
|
||||||
"type": "text"
|
"type": "text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -624,7 +624,7 @@
|
|||||||
"env": "SELF_SIGNED_SSL_STATE",
|
"env": "SELF_SIGNED_SSL_STATE",
|
||||||
"id": "self-signed-ssl-state",
|
"id": "self-signed-ssl-state",
|
||||||
"label": "State of the self-signed certificate",
|
"label": "State of the self-signed certificate",
|
||||||
"regex": "^[:print:]+$",
|
"regex": "^[A-Za-z\\- ]+$",
|
||||||
"type": "text"
|
"type": "text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -633,7 +633,7 @@
|
|||||||
"env": "SELF_SIGNED_SSL_CITY",
|
"env": "SELF_SIGNED_SSL_CITY",
|
||||||
"id": "self-signed-ssl-city",
|
"id": "self-signed-ssl-city",
|
||||||
"label": "City of the self-signed certificate",
|
"label": "City of the self-signed certificate",
|
||||||
"regex": "^[:print:]+$",
|
"regex": "^[A-Za-z\\- ]+$",
|
||||||
"type": "text"
|
"type": "text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -642,7 +642,7 @@
|
|||||||
"env": "SELF_SIGNED_SSL_OU",
|
"env": "SELF_SIGNED_SSL_OU",
|
||||||
"id": "self-signed-ssl-ou",
|
"id": "self-signed-ssl-ou",
|
||||||
"label": "Organizational Unit of the self-signed certificate",
|
"label": "Organizational Unit of the self-signed certificate",
|
||||||
"regex": "^[:print:]+$",
|
"regex": "^[A-Za-z\\- ]+$",
|
||||||
"type": "text"
|
"type": "text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -651,7 +651,7 @@
|
|||||||
"env": "SELF_SIGNED_SSL_ORG",
|
"env": "SELF_SIGNED_SSL_ORG",
|
||||||
"id": "self-signed-ssl-org",
|
"id": "self-signed-ssl-org",
|
||||||
"label": "Organization name of the self-signed certificate",
|
"label": "Organization name of the self-signed certificate",
|
||||||
"regex": "^[:print:]+$",
|
"regex": "^[A-Za-z\\- ]+$",
|
||||||
"type": "text"
|
"type": "text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -660,7 +660,7 @@
|
|||||||
"env": "SELF_SIGNED_SSL_CN",
|
"env": "SELF_SIGNED_SSL_CN",
|
||||||
"id": "self-signed-ssl-cn",
|
"id": "self-signed-ssl-cn",
|
||||||
"label": "Common Name of the self-signed certificate",
|
"label": "Common Name of the self-signed certificate",
|
||||||
"regex": "^[:print:]+$",
|
"regex": "^[A-Za-z\\-\\.0-9]+$",
|
||||||
"type": "text"
|
"type": "text"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -947,7 +947,7 @@
|
|||||||
"env": "REMOTE_PHP",
|
"env": "REMOTE_PHP",
|
||||||
"id": "remote-php",
|
"id": "remote-php",
|
||||||
"label": "Remote php",
|
"label": "Remote php",
|
||||||
"regex": "^([a-z\\-0-9\\_]+\\.?)*$",
|
"regex": "^[a-z\\-0-9_\\.]*$",
|
||||||
"type": "text"
|
"type": "text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -956,7 +956,7 @@
|
|||||||
"env": "REMOTE_PHP_PATH",
|
"env": "REMOTE_PHP_PATH",
|
||||||
"id": "remote-php-path",
|
"id": "remote-php-path",
|
||||||
"label": "Remote php path",
|
"label": "Remote php path",
|
||||||
"regex": "^/([A-Za-z0-9\\-]/?)*$",
|
"regex": "^\\/[a-zA-Z\\-0-9_\\.\\/]*$",
|
||||||
"type": "text"
|
"type": "text"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
204
ui/Config.py
204
ui/Config.py
@ -1,113 +1,121 @@
|
|||||||
import json, uuid, glob, copy, re, subprocess
|
import json, uuid, glob, copy, re, subprocess, os
|
||||||
|
|
||||||
class Config :
|
class Config :
|
||||||
|
|
||||||
def __init__(self) :
|
def __init__(self) :
|
||||||
with open("/opt/settings.json", "r") as f :
|
with open("/opt/settings.json", "r") as f :
|
||||||
self.__settings = json.loads(f.read())
|
self.__settings = json.loads(f.read())
|
||||||
|
|
||||||
def __env_to_dict(self, filename) :
|
def __env_to_dict(self, filename) :
|
||||||
with open(filename, "r") as f :
|
if not os.path.isfile(filename) :
|
||||||
env = f.read()
|
return {}
|
||||||
data = {}
|
with open(filename, "r") as f :
|
||||||
for line in env.split("\n") :
|
env = f.read()
|
||||||
var = line.split("=")[0]
|
data = {}
|
||||||
val = line.replace(var + "=", "", 1)
|
for line in env.split("\n") :
|
||||||
data[var] = val
|
var = line.split("=")[0]
|
||||||
return data
|
val = line.replace(var + "=", "", 1)
|
||||||
|
data[var] = val
|
||||||
|
return data
|
||||||
|
|
||||||
def __dict_to_env(self, filename, variables) :
|
def __dict_to_env(self, filename, variables) :
|
||||||
env = ""
|
env = ""
|
||||||
for k, v in variables.items() :
|
for k, v in variables.items() :
|
||||||
env += k + "=" + v + "\n"
|
env += k + "=" + v + "\n"
|
||||||
with open(filename, "w") as f :
|
with open(filename, "w") as f :
|
||||||
f.write(env)
|
f.write(env)
|
||||||
|
|
||||||
def __gen_conf(self, global_conf, services_conf) :
|
def __gen_conf(self, global_conf, services_conf) :
|
||||||
conf = copy.deepcopy(global_conf)
|
conf = copy.deepcopy(global_conf)
|
||||||
servers = conf["SERVER_NAME"].split(" ")
|
if not "SERVER_NAME" in conf :
|
||||||
if conf["SERVER_NAME"] == "" :
|
conf["SERVER_NAME"] = ""
|
||||||
servers = []
|
servers = conf["SERVER_NAME"].split(" ")
|
||||||
for service in services_conf :
|
if conf["SERVER_NAME"] == "" :
|
||||||
first_server = service["SERVER_NAME"].split(" ")[0]
|
servers = []
|
||||||
if not first_server in servers :
|
for service in services_conf :
|
||||||
servers.append(first_server)
|
first_server = service["SERVER_NAME"].split(" ")[0]
|
||||||
for k, v in service.items() :
|
if not first_server in servers :
|
||||||
conf[first_server + "_" + k] = v
|
servers.append(first_server)
|
||||||
conf["SERVER_NAME"] = " ".join(servers)
|
for k, v in service.items() :
|
||||||
env_file = "/tmp/" + str(uuid.uuid4()) + ".env"
|
conf[first_server + "_" + k] = v
|
||||||
self.__dict_to_env(env_file, conf)
|
conf["SERVER_NAME"] = " ".join(servers)
|
||||||
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)
|
env_file = "/tmp/" + str(uuid.uuid4()) + ".env"
|
||||||
stderr = proc.stderr.decode("ascii")
|
self.__dict_to_env(env_file, conf)
|
||||||
#stdout = proc.stdout.decode("ascii")
|
proc = subprocess.run(["/opt/gen/main.py", "--settings", "/opt/settings.json", "--templates", "/opt/confs", "--output", "/etc/nginx", "--variables", env_file], capture_output=True)
|
||||||
if stderr != "" or proc.returncode != 0 :
|
stderr = proc.stderr.decode("ascii")
|
||||||
raise Exception("Error from generator (return code = " + str(proc.returncode) + ") : " + stderr)
|
stdout = proc.stdout.decode("ascii")
|
||||||
|
if stderr != "" or proc.returncode != 0 :
|
||||||
|
raise Exception("Error from generator (return code = " + str(proc.returncode) + ") : " + stderr + "\n" + stdout)
|
||||||
|
|
||||||
def get_settings(self) :
|
def get_settings(self) :
|
||||||
return self.__settings
|
return self.__settings
|
||||||
|
|
||||||
def get_config(self) :
|
def get_config(self) :
|
||||||
return self.__env_to_dict("/etc/nginx/global.env")
|
return self.__env_to_dict("/etc/nginx/global.env")
|
||||||
|
|
||||||
def get_services(self) :
|
def get_services(self) :
|
||||||
services = []
|
services = []
|
||||||
for filename in glob.iglob("/etc/nginx/**/site.env") :
|
for filename in glob.iglob("/etc/nginx/**/site.env") :
|
||||||
env = self.__env_to_dict(filename)
|
env = self.__env_to_dict(filename)
|
||||||
services.append(env)
|
services.append(env)
|
||||||
return services
|
no_multisite = self.__env_to_dict("/etc/nginx/site.env")
|
||||||
|
if len(no_multisite) > 0 :
|
||||||
|
services.append(no_multisite)
|
||||||
|
return services
|
||||||
|
|
||||||
def check_variables(self, variables) :
|
def check_variables(self, variables) :
|
||||||
for k, v in variables.items() :
|
for k, v in variables.items() :
|
||||||
check = False
|
check = False
|
||||||
for category in self.__settings :
|
for category in self.__settings :
|
||||||
for param in self.__settings[category]["params"] :
|
for param in self.__settings[category]["params"] :
|
||||||
multiple = False
|
multiple = False
|
||||||
if param["type"] != "multiple" :
|
if param["type"] != "multiple" :
|
||||||
real_params = [param]
|
real_params = [param]
|
||||||
else :
|
else :
|
||||||
real_params = param["params"]
|
real_params = param["params"]
|
||||||
multiple = True
|
multiple = True
|
||||||
for real_param in real_params :
|
for real_param in real_params :
|
||||||
if (((not multiple and k == real_param["env"]) or
|
if (((not multiple and k == real_param["env"]) or
|
||||||
(multiple and re.search("^" + real_param["env"] + "_" + "[0-9]+$", k))) and
|
(multiple and re.search("^" + real_param["env"] + "_" + "[0-9]+$", k))) and
|
||||||
real_param["context"] == "multisite" and
|
real_param["context"] == "multisite" and
|
||||||
re.search(real_param["regex"], v)) :
|
re.search(real_param["regex"], v)) :
|
||||||
check = True
|
check = True
|
||||||
if not check :
|
if not check :
|
||||||
raise Exception("Variable " + k + " is not valid.")
|
raise Exception("Variable " + k + " is not valid.")
|
||||||
|
|
||||||
def new_service(self, variables) :
|
def new_service(self, variables) :
|
||||||
global_env = self.__env_to_dict("/etc/nginx/global.env")
|
global_env = self.__env_to_dict("/etc/nginx/global.env")
|
||||||
services = self.get_services()
|
services = self.get_services()
|
||||||
for service in services :
|
for service in services :
|
||||||
if service["SERVER_NAME"] == variables["SERVER_NAME"] or service["SERVER_NAME"] in variables["SERVER_NAME"].split(" ") :
|
if service["SERVER_NAME"] == variables["SERVER_NAME"] or service["SERVER_NAME"] in variables["SERVER_NAME"].split(" ") :
|
||||||
raise Exception("Service " + service["SERVER_NAME"] + " already exists.")
|
raise Exception("Service " + service["SERVER_NAME"] + " already exists.")
|
||||||
services.append(variables)
|
services.append(variables)
|
||||||
self.__gen_conf(global_env, services)
|
self.__gen_conf(global_env, services)
|
||||||
return "Configuration for " + variables["SERVER_NAME"] + " has been generated."
|
return "Configuration for " + variables["SERVER_NAME"] + " has been generated."
|
||||||
|
|
||||||
def edit_service(self, old_server_name, variables) :
|
def edit_service(self, old_server_name, variables) :
|
||||||
self.delete_service(old_server_name)
|
self.delete_service(old_server_name)
|
||||||
self.new_service(variables)
|
self.new_service(variables)
|
||||||
return "Configuration for " + old_server_name + " has been edited."
|
return "Configuration for " + old_server_name + " has been edited."
|
||||||
|
|
||||||
|
|
||||||
def delete_service(self, server_name) :
|
def delete_service(self, server_name) :
|
||||||
global_env = self.__env_to_dict("/etc/nginx/global.env")
|
global_env = self.__env_to_dict("/etc/nginx/global.env")
|
||||||
services = self.get_services()
|
services = self.get_services()
|
||||||
new_services = []
|
new_services = []
|
||||||
found = False
|
found = False
|
||||||
for service in services :
|
for service in services :
|
||||||
if service["SERVER_NAME"].split(" ")[0] == server_name :
|
if service["SERVER_NAME"].split(" ")[0] == server_name :
|
||||||
found = True
|
found = True
|
||||||
else :
|
else :
|
||||||
new_services.append(service)
|
new_services.append(service)
|
||||||
if not found :
|
if not found :
|
||||||
raise Exception("Can't delete missing " + server_name + " configuration.")
|
raise Exception("Can't delete missing " + server_name + " configuration.")
|
||||||
new_servers = global_env["SERVER_NAME"].split(" ")
|
new_servers = global_env["SERVER_NAME"].split(" ")
|
||||||
if server_name in new_servers :
|
if server_name in new_servers :
|
||||||
new_servers.remove(server_name)
|
new_servers.remove(server_name)
|
||||||
global_env["SERVER_NAME"] = " ".join(new_servers)
|
global_env["SERVER_NAME"] = " ".join(new_servers)
|
||||||
self.__gen_conf(global_env, new_services)
|
self.__gen_conf(global_env, new_services)
|
||||||
return "Configuration for " + server_name + " has been deleted."
|
return "Configuration for " + server_name + " has been deleted."
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -17,8 +17,10 @@ class Docker :
|
|||||||
return self.__client.containers.get(id)
|
return self.__client.containers.get(id)
|
||||||
|
|
||||||
def reload_instance(self, id) :
|
def reload_instance(self, id) :
|
||||||
self.get_instance(id).kill(signal="SIGHUP")
|
if self.get_instance(id).status == "running" :
|
||||||
return "Instance " + id + " has been reloaded."
|
self.get_instance(id).kill(signal="SIGHUP")
|
||||||
|
return "Instance " + id + " has been reloaded."
|
||||||
|
return "Instance " + id + " is not running, skipping reload."
|
||||||
|
|
||||||
def start_instance(self, id) :
|
def start_instance(self, id) :
|
||||||
self.get_instance(id).start()
|
self.get_instance(id).start()
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
{% if param["type"] != "multiple" and param["context"] == "multisite" %}
|
{% if param["type"] != "multiple" and param["context"] == "multisite" %}
|
||||||
<div class="row mb-3" id="form-new-{{ param["id"] }}">
|
<div class="row mb-3" id="form-new-{{ param["id"] }}">
|
||||||
{% set default = {"value": param["default"]} %}
|
{% set default = {"value": param["default"]} %}
|
||||||
{% if param["env"] in config["CONFIG"].get_config() %}
|
{% if param["env"] in config["CONFIG"].get_config() and param["env"] != "SERVER_NAME" %}
|
||||||
{% set x = default.update({"value": config["CONFIG"].get_config()[param["env"]]}) %}
|
{% set x = default.update({"value": config["CONFIG"].get_config()[param["env"]]}) %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ form_service_gen("form-new-" + param["id"], param["label"], param["type"], default["value"], param["env"])|safe }}
|
{{ form_service_gen("form-new-" + param["id"], param["label"], param["type"], default["value"], param["env"])|safe }}
|
||||||
@ -57,4 +57,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -58,12 +58,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include "services-new.html" %}
|
|
||||||
{% include "services-edit.html" %}
|
{% include "services-edit.html" %}
|
||||||
{% include "services-delete.html" %}
|
{% include "services-delete.html" %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
{% include "services-new.html" %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user