From a57ffadf8a0558f52c68aaa11fdbac74c5104e8b Mon Sep 17 00:00:00 2001 From: Sheppy Date: Wed, 21 Dec 2022 12:18:37 +0100 Subject: [PATCH] feat: nginx autoconf --- main.py | 47 ++++++++++++++++++++++++++++--- vm.py | 85 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 86 insertions(+), 46 deletions(-) diff --git a/main.py b/main.py index d1919e6..73c82fb 100644 --- a/main.py +++ b/main.py @@ -1,12 +1,51 @@ import json import vm +ACME_CONTENT = ''' +location /.well-known/acme-challenge/ { + auth_basic off; + alias /var/www/.well-known/acme-challenge/; +} +''' + if __name__ == "__main__": FILE = "vms.json" with open(FILE) as f: jsonList = json.load(f) - vmList = [ vm.VM(obj) for obj in jsonList ] - - for vmo in vmList: - [ print(c) for c in vmo.dumpHAProxyComponents()] + vmList = [] + for obj in jsonList: + try: + vmo = vm.VM(obj) + vmList.append(vmo) + except ValueError as e: + print(e) + + with open("./build/stream_include.conf", "w") as f: + for vmo in vmList: + [ print(c) for c in vmo.dumpStreamComponents()] + [ f.write(c) for c in vmo.dumpStreamComponents()] + + with open("./build/http_include.conf", "w") as f: + for vmo in vmList: + [ print(c) for c in vmo.dumpServerComponents()] + [ f.write(c) for c in vmo.dumpServerComponents()] + + with open("./build/acme-challenge.conf", "w") as f: + f.write(ACME_CONTENT) + + with open("./build/cert.sh", "w") as f: + + f.write("certbot certonly --webroot -w /var/www \\") + domains = [] + for vmo in vmList: + for subdomain in vmo.subdomains: + if type(subdomain) == dict: + domains.append(subdomain["name"]) + else: + domains.append(subdomain) + + for d in set(domains): + f.write(" -d {} \\".format(d)) + + f.write("--rsa-key-size 2048 --expand") diff --git a/vm.py b/vm.py index 0ff17c9..9ec7a6b 100644 --- a/vm.py +++ b/vm.py @@ -1,32 +1,10 @@ import libvirt - -BASE_DOMAIN = "new.atlantishq.de" - -HA_PROXY_TEMPLATE_PORT = ''' -listen {name} - bind 0.0.0.0:{port} - mode {proto} - timeout connect 4000 - timeout client 180000 - timeout client 180000 - server srv1 {ip} - -''' - -HA_PROXY_TEMPLATE_SNI = ''' -frontend {subdomain}.{basedomain} - bind 0.0.0.0:80 - bind 0.0.0.0:443 ssl - http-request redirect scheme https unless {{ ssl_fc }} - default_backend {name} - -backend {name} - server srv1 {ip} check maxconn 20 - -''' +import jinja2 class VM: + environment = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath="./templates")) + def __init__(self, args): self.hostname = args.get("hostname") @@ -47,26 +25,49 @@ class VM: raise ValueError("Hostname {} doesn't have a DHCP lease".format(self.hostname)) - def dumpHAProxyComponents(self): - - components = [] - + def dumpStreamComponents(self): + # port forwarding components # - for pObj in self.ports: - name = str(pObj.get("name")).replace(" ", "") - portOrRange = str(pObj.get("port")).replace(" ", "") - proto = pObj.get("proto") or "tcp" - compositeName = "-".join((self.hostname, name, portOrRange, proto)) + components = [] + template = self.environment.get_template("nginx_server_block.conf.j2") - component = HA_PROXY_TEMPLATE_PORT.format(name=compositeName, port=portOrRange, - proto=proto, ip=self.ip) - components.append(component) + for portStruct in self.ports: - # https components # - for subdomain in self.subdomains: - compositeName = "-".join((self.hostname, subdomain.replace(".","-"))) - component = HA_PROXY_TEMPLATE_SNI.format(name=compositeName, basedomain=BASE_DOMAIN, - ip=self.ip, subdomain=subdomain) + name = str(portStruct.get("name")).replace(" ", "") + portstring = str(portStruct.get("port")).replace(" ", "") + transparent = portStruct.get("transparent") + proto = portStruct.get("proto") or "tcp" + isUDP = proto == "udp" + + compositeName = "-".join((self.hostname, name, portstring, proto)) + + component = template.render(targetip=self.ip, udp=isUDP, portstring=portstring, + transparent=transparent) + components.append(component) + + return components + + def dumpServerComponents(self): + + # https components # + components = [] + template = self.environment.get_template("nginx_server_block.conf.j2") + targetport = 80 + + if all([type(e) == dict for e in self.subdomains]): + for subdomain in self.subdomains: + compositeName = "-".join((self.hostname, subdomain["name"].replace(".","-"))) + targetport = subdomain["port"] + component = template.render(targetip=self.ip, targetport=targetport, + servernames=[subdomain["name"]], comment=compositeName) + components.append(component) + + elif any([type(e) == dict for e in self.subdomains]): + raise ValueError("Mixed subdomains not allowed - must be all complex or all simple") + else: + compositeName = "-".join((self.hostname, self.subdomains[0].replace(".","-"))) + component = template.render(targetip=self.ip, targetport=targetport, + servernames=self.subdomains, comment=compositeName) components.append(component) return components