diff --git a/assets/etc/haproxy/certs/README.md b/assets/etc/haproxy/certs/README.md deleted file mode 100644 index 828a1d8..0000000 --- a/assets/etc/haproxy/certs/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Certs Folder - -Docker Easy HAProxy will save the SSL Certs here. diff --git a/assets/scripts/certbot.sh b/assets/scripts/certbot.sh index 4756b66..0d633eb 100755 --- a/assets/scripts/certbot.sh +++ b/assets/scripts/certbot.sh @@ -2,16 +2,37 @@ @todo +mkdir -p /var/log/letsencrypt ln -sf /dev/stdout /var/log/letsencrypt/letsencrypt.log -certbot certonly \ - --standalone \ - --preferred-challenges http \ - --http-01-port 2080 \ - --agree-tos \ - --issuance-timeout 90 \ - --no-eff-email \ - --non-interactive \ - --max-log-backups=0 \ - --post-hook "/scripts/certbot_to_haproxy.sh && systemctl reload haproxy.service" - -d dev.globalnetguide.com -d other.domain.com --email info@xpto.us +REQUEST_CERTS="" +RENEW_CERTS="" + +for domain in $(cat /scripts/letsencrypt_hosts.txt); do + if [ ! -f "/etc/haproxy/certs/$domain.pem" ]; then + REQUEST_CERTS="$REQUES_CERTS -d $domain" + continue + fi + + if [[ $(find "/etc/haproxy/certs/$domain.pem" -mtime +30 -print) ]]; then + RENEW_CERTS="$RENEW_CERTS -d $domain" + fi +done + +if [ -n "$REQUEST_CERTS" ]; then + certbot certonly \ + --standalone \ + --preferred-challenges http \ + --http-01-port 2080 \ + --agree-tos \ + --issuance-timeout 90 \ + --no-eff-email \ + --non-interactive \ + --max-log-backups=0 \ + --post-hook "/scripts/certbot_to_haproxy.sh" \ + $REQUEST_CERTS --email info@xpto.us +fi + +if [ -n "$RENEW_CERTS" ]; then + certbot renew --post-hook "/scripts/certbot_to_haproxy.sh" +fi \ No newline at end of file diff --git a/assets/scripts/certbot_to_haproxy.sh b/assets/scripts/certbot_to_haproxy.sh index ab2c53a..58afeda 100755 --- a/assets/scripts/certbot_to_haproxy.sh +++ b/assets/scripts/certbot_to_haproxy.sh @@ -9,3 +9,5 @@ for CERTIFICATE in `find /etc/letsencrypt/live/* -type d`; do # Combine certificate and private key to single file cat /etc/letsencrypt/live/$CERTIFICATE/fullchain.pem /etc/letsencrypt/live/$CERTIFICATE/privkey.pem > /etc/haproxy/certs/$CERTIFICATE.pem done + +/usr/sbin/haproxy -W -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -x /var/run/haproxy.sock -sf $(cat /run/haproxy.pid) & diff --git a/easymapping/__init__.py b/easymapping/__init__.py index fa5a81c..989e928 100644 --- a/easymapping/__init__.py +++ b/easymapping/__init__.py @@ -42,11 +42,10 @@ class DockerLabelHandler: class HaproxyConfigGenerator: - def __init__(self, mapping, ssl_cert_folder="/etc/haproxy/certs"): + def __init__(self, mapping, ssl_cert_folder="/etc/haproxy/certs/discover"): self.mapping = mapping self.label = DockerLabelHandler(mapping['lookup_label'] if 'lookup_label' in mapping else "easyhaproxy") self.ssl_cert_folder = ssl_cert_folder - self.ssl_cert_increment = 0 self.letsencrypt_hosts = [] os.makedirs(self.ssl_cert_folder, exist_ok=True) @@ -112,16 +111,8 @@ class HaproxyConfigGenerator: ) self.letsencrypt_hosts.append(d[host_label]) if letsencrypt and d[host_label] not in self.letsencrypt_hosts else self.letsencrypt_hosts - hash = "" - if self.label.create([definition, "sslcert"]) in d: - hash = hashlib.md5( - d[self.label.create([definition, "sslcert"])].encode('utf-8') - ).hexdigest() - - key = port if not hash else port + "_" + hash - - if key not in easymapping: - easymapping[key] = { + if port not in easymapping: + easymapping[port] = { "mode": mode, "health-check": "", "port": port, @@ -135,25 +126,38 @@ class HaproxyConfigGenerator: "80" ) - easymapping[key]["health-check"] = self.label.get( + easymapping[port]["health-check"] = self.label.get( self.label.create([definition, "health-check"]), "" ) - easymapping[key]["hosts"].setdefault(d[host_label], {}) - easymapping[key]["hosts"][d[host_label]].setdefault("containers", []) - easymapping[key]["hosts"][d[host_label]].setdefault("letsencrypt", False) - easymapping[key]["hosts"][d[host_label]]["containers"] += ["{}:{}".format(container, ct_port)] - easymapping[key]["hosts"][d[host_label]]["letsencrypt"] = letsencrypt + easymapping[port]["hosts"].setdefault(d[host_label], {}) + easymapping[port]["hosts"][d[host_label]].setdefault("containers", []) + easymapping[port]["hosts"][d[host_label]].setdefault("letsencrypt", False) + easymapping[port]["hosts"][d[host_label]]["containers"] += ["{}:{}".format(container, ct_port)] + easymapping[port]["hosts"][d[host_label]]["letsencrypt"] = letsencrypt + + if letsencrypt: + if "443" not in easymapping: + easymapping["443"] = { + "mode": "http", + "health-check": "ssl", + "port": "443", + "hosts": dict(), + "redirect": dict(), + } + easymapping["443"]["hosts"][d[host_label]] = dict(easymapping[port]["hosts"][d[host_label]]) + easymapping["443"]["hosts"][d[host_label]]["letsencrypt"] = False + + # handle SSL ssl_label = self.label.create([definition, "sslcert"]) if self.label.has_label(ssl_label): - self.ssl_cert_increment += 1 - filename = "{}/{}.{}.pem".format( - self.ssl_cert_folder, d[host_label], str(self.ssl_cert_increment) + filename = "{}/{}.pem".format( + self.ssl_cert_folder, d[host_label] ) - easymapping[key]["ssl_cert"] = filename + easymapping[port]["ssl_cert"] = filename with open(filename, 'wb') as file: file.write( base64.b64decode(d[ssl_label]) @@ -166,6 +170,6 @@ class HaproxyConfigGenerator: if len(redirect) > 0: for r in redirect.split(","): r_parts = r.split("--") - easymapping[key]["redirect"][r_parts[0]] = r_parts[1] + easymapping[port]["redirect"][r_parts[0]] = r_parts[1] return easymapping.values() diff --git a/examples/docker/docker-compose.yml b/examples/docker/docker-compose.yml index 9b1d9e6..c57920f 100644 --- a/examples/docker/docker-compose.yml +++ b/examples/docker/docker-compose.yml @@ -3,6 +3,9 @@ # # or add to /etc/hosts # 127.0.0.1 host1.local +# +# Test SSL: +# openssl s_client -showcerts -connect 127.0.0.1:443 --servername host1.local version: "3" @@ -33,4 +36,17 @@ services: easyhaproxy.https.port: 443 easyhaproxy.https.localport: 8080 easyhaproxy.https.host: host1.local - easyhaproxy.https.sslcert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZEVENDQXZXZ0F3SUJBZ0lVUmkrdzFaVmdlZWRUbE5JQXdxUUJNSnY2ZFhzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xhRzl6ZERFdWJHOWpZV3d3SGhjTk1qRXdPREV3TVRnME9UQTJXaGNOTXpFdwpPREE0TVRnME9UQTJXakFXTVJRd0VnWURWUVFEREF0b2IzTjBNUzVzYjJOaGJEQ0NBaUl3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFNQkRBaExBeWdKdWFXNnc2ZmZpZ3pUQUFHWHBtRXowdEl4bjFrNFoKeDV3TjVycHYvcXUwUU1ZeitBdjJ1MWVPS0VLWmVhRlJWcFQwcjkzZFg3SXZiRVpIdDI1R1BpQnZsTEdxaGpLUgpQblNrLzdVOFhtc250dFVBVjdyVkVLMVVyZEZ3OC9Jd3JpUUMrZGhyMG1uWWZTRE1rdkJvTUZwZGhWTlRyYkFaCjFUQjZyUWpFN0FyME10OG15OTZYSm13cmNqSzJUaitFMnJnUElVejFlNWNla0ZZSURTQmF0bXcrMyt2citUNXgKRk5Ga0oybzMwVzVvOFpmbENKSnpyVmFpaHFRaWNzNlpLRGdwZjdpcVhNRml3V0lsaGRRcEd2eDVHZi9LRlRLOQpVYU9uUlp6L1grMkNlYkFGYVRIUjNrL1BZcHBXVGdCQkJ1UnZscEN3K3dkbmttdGVDMFNRUkY5MVFXVnI3ZWpvCjdLYU9sR0k1VnR2TVVzV3ZUZUFabXBheW1JYUFURVR1T0phWTBKVTExT21MZUQ5RE9qNUUyU1E3cUlYL3BGY3AKeHB6RzVqNGMrTWxndnhQMlZBa05UZUFYQ2FZaVBCUUg1WlpnMEhFMlduQjFLaExSRmxIZDRpSFFEMkdKNXlOLwo2ZkNGQmZaZktTZUs4SmF1d3hnV2tyYTUzT2NEcS9tS2QrREEvZEsrL3J1Rzd0cXdWZ0lhMDRIT3Bsek03TFlSCkdCMElyczkrbHI1L1BKYlFabVUwNzNNZG42Y1hBZzNwKzZ3dndGbERrUzV2MTNnQkRZTkh0RjYyYmM1NTFlZEYKWjZrR3pKN3dtR1JvODRhQlA3TXVSWmVSZUxPclNTNjdhMXdMZHpac01uUDFUSjd4OUxmcjlNS2wydURuUWRuWQpleDhEQWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJTUS9tdFpkNmg4ZW45WVFWSDZITzFQbFdXaXF6QWZCZ05WCkhTTUVHREFXZ0JTUS9tdFpkNmg4ZW45WVFWSDZITzFQbFdXaXF6QVBCZ05WSFJNQkFmOEVCVEFEQVFIL01BMEcKQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUNoUVlOdWFoMyttVHBJQkRZeEdyalRKTnVPVElNYVd6TXlpMXRrZitMMApzRUd3cGJtQU8ybVdXUVlGN1dWTHNpOThQVUxoM2FkanQyaml1ZDlWbGFhQzZnbnduNVpvMStQaWxvOXNOTExXCjZpajArck40a3dJbS9wTnFpK2pEdXUyY3ZBdUhJd1pXZWg4YkVlLzVVQ3hvNGlobVdGUU44ZUo2VFVLQ3BoUkMKNkVvci9TU1paQlFIZ1BsMEJjaHpIT2t3dTdSM0xDbmRScXhqaEFvVmI5eVFPVitac21UZUpYdWx3TnpKMXVMdApUOE9JZ0lpRHBtQm83SFNOMkgwazNjaHgwMEFzalV5SjltbUFXUGVqRmUvS1hMUlBjVlpSMTdqaHpnZklCRXpzCk01V3RXRm0xYUhEalZ2Nk02aXRlVm02MUU5VCtrL00xMXJ1MWUyWXdzeFREdmI2eDA0bWNyTnU5c29xZGRCYnIKVmZwbHV1b1EvaEVBYlh0Rk5Qb1R5U3B6MGN3T3djSENvd1ZPTG1kS2d2SW1zelppTXlISEc4VkdHbVBoODhuNwp3VnhiMGdWMFA0Uk1yY01MZGVUZG41NVlRcjFDcUJyMzRlQjZvbDZBc2JUbTNWekJIUlZtRk5rc2wxbzVKQjV0CnRYTGdGL0c4L3J6Si80bTFQYVZ1eHJCN0R4VW1JazhFUGJTSVZrdlp2ZDdMQnpLd1E2SWZWYXVjZXdIZkVhalEKVklpZXhTTWlGYzdsdzNLbnhqT0haamY2Rk05VllnM05vKytHZEM5OXM3TGtJdUp3QU1MTnFUUTdIdmhuN1l2UAo0RmxTSWdjNnhqMFlrR1pFUWxiNW8vNW5hdUVxUVUwQUJndzZqdEk0TnhyTkxUNmNwN0NPNE0weElERWcvM1lECmFBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQotLS0tLUJFR0lOIFBSSVZBVEUgS0VZLS0tLS0KTUlJSlF3SUJBREFOQmdrcWhraUc5dzBCQVFFRkFBU0NDUzB3Z2drcEFnRUFBb0lDQVFEQVF3SVN3TW9DYm1sdQpzT24zNG9NMHdBQmw2WmhNOUxTTVo5Wk9HY2VjRGVhNmIvNnJ0RURHTS9nTDlydFhqaWhDbVhtaFVWYVU5Sy9kCjNWK3lMMnhHUjdkdVJqNGdiNVN4cW9ZeWtUNTBwUCsxUEY1cko3YlZBRmU2MVJDdFZLM1JjUFB5TUs0a0F2blkKYTlKcDJIMGd6Skx3YURCYVhZVlRVNjJ3R2RVd2VxMEl4T3dLOURMZkpzdmVseVpzSzNJeXRrNC9oTnE0RHlGTQo5WHVYSHBCV0NBMGdXclpzUHQvcjYvaytjUlRSWkNkcU45RnVhUEdYNVFpU2M2MVdvb2FrSW5MT21TZzRLWCs0CnFsekJZc0ZpSllYVUtScjhlUm4veWhVeXZWR2pwMFdjLzEvdGdubXdCV2t4MGQ1UHoyS2FWazRBUVFia2I1YVEKc1BzSFo1SnJYZ3RFa0VSZmRVRmxhKzNvNk95bWpwUmlPVmJiekZMRnIwM2dHWnFXc3BpR2dFeEU3amlXbU5DVgpOZFRwaTNnL1F6bytSTmtrTzZpRi82UlhLY2FjeHVZK0hQakpZTDhUOWxRSkRVM2dGd21tSWp3VUIrV1dZTkJ4Ck5scHdkU29TMFJaUjNlSWgwQTloaWVjamYrbndoUVgyWHlrbml2Q1dyc01ZRnBLMnVkem5BNnY1aW5mZ3dQM1MKdnY2N2h1N2FzRllDR3RPQnpxWmN6T3kyRVJnZENLN1BmcGErZnp5VzBHWmxOTzl6SForbkZ3SU42ZnVzTDhCWgpRNUV1YjlkNEFRMkRSN1JldG0zT2VkWG5SV2VwQnN5ZThKaGthUE9HZ1QrekxrV1hrWGl6cTBrdXUydGNDM2MyCmJESno5VXllOGZTMzYvVENwZHJnNTBIWjJIc2ZBd0lEQVFBQkFvSUNBUUMveFpiWjBjY3RxYWdzcXZhVk5URWUKZXExcStoZmFHdlBFWVFhWUhJcklFKzJpNVhjbkdjTEtjS2ZvZHhEakFuOFIvemdkT3A2Y01YMENWbi9Qb2hIawpBRUR0RTgrQVZ3d0FNMUZzT3dnTEhWR2FHejhxcnhCbFlkUWdIY3BtdWVJdTJQWGJDOGVIVUJpYVVPSXVoYXc1Ci9SUk1EQUMvQWkyc3NmaTdnT2p2VkU0b1F4UVcwUUcxS0dPT0FVSm4vdVlIdzJSRlkyVXUxcGlteE8ya0RPNTMKZ2N4bUMxV09ueUNIbUhhaVcvVWg3ejZKYW1mU000ZFh0VEpac2x5aDM3ZGhIS05iZzlWa1A3Q1FLQTRoTHpvcApoYmY1cVk2cmFyZ09OaW55MUhnTVB4cm13S3VVb3VKeU90TjB5QnR4akRDVU5hWFVCd2l5N3NOR1MrSDR2c3lCCjVQOUhoSUhTdHUrRlp0M0hHN0VJcUNuZGlhU0tEUzRqV2FWUUFiYm80bloyWnMyQkQreERlUFJDUlVxWDdyTTQKNFh6UElSV1dYbW1XZi83SWcyOUhicnA0YTlMY09tUTJsZUNKdGJhVEZTTjk2T0xVSjVFK2hRMHVsQ1pnQlZtUQpSQ1VZa0pQNGxPemJhS2R6anhnSE1ySHptNDVlVUZmOExpck94aTJ1eXhYSFFtRE51NGIzWDE4a3QzUGdVbVVtCjNkWHBsM2ZxU3lKYTdTQ1Y4Wk5CcnNyRHExRSt0aFl0dTkxUWJWU0d4SGQ5SHJOVmUzWGRMYk9DZFU5Q3VDNjkKTmdsem5hYTdzWkxxbXlLZWpUZkdzWTd4cldkTmNNUGw0cDRmY0lEL080RXBBU1pmb3JwVGVLTlQwWklmWlpldwpiMG1BUWVZWnFRTThpL3FNWU4vdUFRS0NBUUVBNXFnMXNSTk1jNlZkTS90UmdsYXNHWW94amdSQzJPcUFEWmdzCm1BWE1VSjNrRXJweXh0K2VDaW15OGlidVlwelJUSVE4ZkJUV1JrQ3RSWlhKNytLY0xWdGs5UVpJb0xiaHlOd2QKNEl4RVFaRnVVbGpEYnZTalRMU3ljc0h2bzY1aWJXSWZUTDdiZ1dsTEdnR3EvVU96ZkdzZ0g2Uzl3THA1RzMwRwo4RUx5akk1ZVRJWUlDcmZUbVZMK2M0NU1ScEVNS28rY3Z6OFB5c2lhT0ZUbjNjeXN3UFZkWWFlRUVxTVFqVTh3CklHTnNHWkx5dFk3QkFCQmNZMGxkcnRiYS9PK0Z2LytSSDd1VXR6UDd4cENJd0ZDeDgwWnpOK1dSeTlOdkk2M1UKenEzeUlCb1c5R3lBcEQyK1BMYVBOeGY3UUxUVUNoWTFaei9kWVJsdEtPeHYyQWE1Z1FLQ0FRRUExV0xXTnFwMApmaEIvWnRmU0VTaHhGTU04OWNqTjZBYXoxV0tMN3VUQm91OW9TSm54amtoa2FWNzZhY25UL2lxWHR4TU5nSGkxCmZJbURwVTNQdk0wWTRVZDJUNDdvSGM2UDFCclpQTi9HbVh5L3M2QkFFZFB3TGU3Sis0blRJU0hBZEdtcmgrYS8KNXBrdHUzMmc5bFdxZnR4ZWNGSVZTTFBXa3hUMFhLaU14cDFmZmtMK09hdnBNZ01GWks0MWlLczNkTlNoS1BvZwpMOEdTUGNQOXgveW43OFAyZUszTitQR2psQTZwUHpyQU55V1U3TjAvYm1IY0I5VEtQK3VkWVdjalZocnU3TVlOCndOckU0a0tkQzh2OGk3eDd0RGJ2Yjc5VCtGbzZQSWg1M3AwT3NuWnpBOFVSMFFOUit2RFF1ZlF1eWFqOFJFQysKWkc4WXlDS3N2azh5Z3dLQ0FRQS9mc1N4QjBmL2VlRXJZeDZ3QzUzNnRlRW9ZQ0hxeHJzVGd2V2JyOVRyeUZzMQprSi95QVRMblIwMWNmYjBYNW1WemM5K1dwTUhMdXhnMzFLRXZhU2xuRHdhK3NNa2pmTlN3ejI5bUZoYmdHZUhOCngyT2RVcmoxYjdURUJJRXNoTi9SanJaaEVSVXFEY3MvMEgrNmtuMkJYWmdOUGZPQ2I1TFJMMXpPblE5YUJBTVAKZThJUStVUEZyR1FoZVdXajgxL3ZBM081N2VreUFJRDd5dHU5WWcrWVdyTW5JODhtdGo3ak40NWZEQitBOXNQYgptUDJtUDlxKzlqNVUyQTZXbkhVc1FuVTMwQktEVUVzYUFVV3o4MExaWG1adlY4SUg0eDl3S2ZVd0pCQklLQVp6CnFMN005N1k3em1Ha1gvU3BmbDMwbk9KOGxzY2hhTGQxRVlsRVphMkJBb0lCQVFDeWUyNVQ0VFY1TUpGdjB6dVoKTUd1TmcxU2MvTzRGa24yZkVVT2NlV2pod1VCSDRjUGpUL2YxRHdXRHNOYUo5TlJieENyNTkzMU9BclBEYzVjOApBNDA0K1k0ak01UkJRa0tabGk5NHRIQW9kK2pjOVVCQjZUVXZKbGw1OVNsTXdDOTY3OXdTMjFaT0tuZlBLR0NYClNzWkdRRXNaeGY2Wmhoc0hnWEozZ2wvbHpVSlBtUGVPQTVZVlIrT2Q5LzA5S0lGRlRvalNmb3luaFZDdUt4NDkKeGI0dVZZbjJIT0o0eEowZlBUZ2hkQ0hNdnJtWGVlUVJqdmI4OGVhTm1xVlVFSEhGRnRnYjRma2xBNWZFN1JUeApCaGxpUkRCd1o3YlVrSU5LNnlWazluNkJUbnM1bU12UkxtZ2RuSnBZdkU3S0MwMkxUYlpiM0krajhDMFpVYStOCnF5N0RBb0lCQUFpZXJpYlM3V1VjbDJhQmxrbTUrVzdxTm0vSU5tNXp2bm9TUG82VjN3YTVoczZmOStDL2tiZEYKODdqUVBBL1lGZTN1UjJzQUo3c2xYNWV1Wks4V21mcEZtZ3psdTBzRXo4MU1MUS9XeXBadFp5dHlWdFd6QjJQdQpYQ1cxdGRTSDllSTJCbWhYZ29rSE5UTTQ4TmsveE9FTnJQL3NlWHJJeDVMSzBobkRIWm90dS96NitZU2tCOWhGCmNtMmZaeWdEMWRNTFg2bGlSaW14eUZZK2RJQ0pOQjk1SmlmVExXWW5XZUdkZGt3UHRYVWVHWEUxb2x6dk5rTEQKek16RTA5dWhreC9sUkpudGVPQkVaYWY4ME9CLzA5T2k5YjkvcnhZNTlkd3NINkdheExvVGZFS3VQbnZCVk1OUgpZa1UxNFd6UUtsZUZraUJKSTlsVnZuZmdHbk9sZ2cwPQotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0t \ No newline at end of file + easyhaproxy.https.sslcert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZEVENDQXZXZ0F3SUJBZ0lVUmkrdzFaVmdlZWRUbE5JQXdxUUJNSnY2ZFhzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xhRzl6ZERFdWJHOWpZV3d3SGhjTk1qRXdPREV3TVRnME9UQTJXaGNOTXpFdwpPREE0TVRnME9UQTJXakFXTVJRd0VnWURWUVFEREF0b2IzTjBNUzVzYjJOaGJEQ0NBaUl3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFNQkRBaExBeWdKdWFXNnc2ZmZpZ3pUQUFHWHBtRXowdEl4bjFrNFoKeDV3TjVycHYvcXUwUU1ZeitBdjJ1MWVPS0VLWmVhRlJWcFQwcjkzZFg3SXZiRVpIdDI1R1BpQnZsTEdxaGpLUgpQblNrLzdVOFhtc250dFVBVjdyVkVLMVVyZEZ3OC9Jd3JpUUMrZGhyMG1uWWZTRE1rdkJvTUZwZGhWTlRyYkFaCjFUQjZyUWpFN0FyME10OG15OTZYSm13cmNqSzJUaitFMnJnUElVejFlNWNla0ZZSURTQmF0bXcrMyt2citUNXgKRk5Ga0oybzMwVzVvOFpmbENKSnpyVmFpaHFRaWNzNlpLRGdwZjdpcVhNRml3V0lsaGRRcEd2eDVHZi9LRlRLOQpVYU9uUlp6L1grMkNlYkFGYVRIUjNrL1BZcHBXVGdCQkJ1UnZscEN3K3dkbmttdGVDMFNRUkY5MVFXVnI3ZWpvCjdLYU9sR0k1VnR2TVVzV3ZUZUFabXBheW1JYUFURVR1T0phWTBKVTExT21MZUQ5RE9qNUUyU1E3cUlYL3BGY3AKeHB6RzVqNGMrTWxndnhQMlZBa05UZUFYQ2FZaVBCUUg1WlpnMEhFMlduQjFLaExSRmxIZDRpSFFEMkdKNXlOLwo2ZkNGQmZaZktTZUs4SmF1d3hnV2tyYTUzT2NEcS9tS2QrREEvZEsrL3J1Rzd0cXdWZ0lhMDRIT3Bsek03TFlSCkdCMElyczkrbHI1L1BKYlFabVUwNzNNZG42Y1hBZzNwKzZ3dndGbERrUzV2MTNnQkRZTkh0RjYyYmM1NTFlZEYKWjZrR3pKN3dtR1JvODRhQlA3TXVSWmVSZUxPclNTNjdhMXdMZHpac01uUDFUSjd4OUxmcjlNS2wydURuUWRuWQpleDhEQWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJTUS9tdFpkNmg4ZW45WVFWSDZITzFQbFdXaXF6QWZCZ05WCkhTTUVHREFXZ0JTUS9tdFpkNmg4ZW45WVFWSDZITzFQbFdXaXF6QVBCZ05WSFJNQkFmOEVCVEFEQVFIL01BMEcKQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUNoUVlOdWFoMyttVHBJQkRZeEdyalRKTnVPVElNYVd6TXlpMXRrZitMMApzRUd3cGJtQU8ybVdXUVlGN1dWTHNpOThQVUxoM2FkanQyaml1ZDlWbGFhQzZnbnduNVpvMStQaWxvOXNOTExXCjZpajArck40a3dJbS9wTnFpK2pEdXUyY3ZBdUhJd1pXZWg4YkVlLzVVQ3hvNGlobVdGUU44ZUo2VFVLQ3BoUkMKNkVvci9TU1paQlFIZ1BsMEJjaHpIT2t3dTdSM0xDbmRScXhqaEFvVmI5eVFPVitac21UZUpYdWx3TnpKMXVMdApUOE9JZ0lpRHBtQm83SFNOMkgwazNjaHgwMEFzalV5SjltbUFXUGVqRmUvS1hMUlBjVlpSMTdqaHpnZklCRXpzCk01V3RXRm0xYUhEalZ2Nk02aXRlVm02MUU5VCtrL00xMXJ1MWUyWXdzeFREdmI2eDA0bWNyTnU5c29xZGRCYnIKVmZwbHV1b1EvaEVBYlh0Rk5Qb1R5U3B6MGN3T3djSENvd1ZPTG1kS2d2SW1zelppTXlISEc4VkdHbVBoODhuNwp3VnhiMGdWMFA0Uk1yY01MZGVUZG41NVlRcjFDcUJyMzRlQjZvbDZBc2JUbTNWekJIUlZtRk5rc2wxbzVKQjV0CnRYTGdGL0c4L3J6Si80bTFQYVZ1eHJCN0R4VW1JazhFUGJTSVZrdlp2ZDdMQnpLd1E2SWZWYXVjZXdIZkVhalEKVklpZXhTTWlGYzdsdzNLbnhqT0haamY2Rk05VllnM05vKytHZEM5OXM3TGtJdUp3QU1MTnFUUTdIdmhuN1l2UAo0RmxTSWdjNnhqMFlrR1pFUWxiNW8vNW5hdUVxUVUwQUJndzZqdEk0TnhyTkxUNmNwN0NPNE0weElERWcvM1lECmFBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQotLS0tLUJFR0lOIFBSSVZBVEUgS0VZLS0tLS0KTUlJSlF3SUJBREFOQmdrcWhraUc5dzBCQVFFRkFBU0NDUzB3Z2drcEFnRUFBb0lDQVFEQVF3SVN3TW9DYm1sdQpzT24zNG9NMHdBQmw2WmhNOUxTTVo5Wk9HY2VjRGVhNmIvNnJ0RURHTS9nTDlydFhqaWhDbVhtaFVWYVU5Sy9kCjNWK3lMMnhHUjdkdVJqNGdiNVN4cW9ZeWtUNTBwUCsxUEY1cko3YlZBRmU2MVJDdFZLM1JjUFB5TUs0a0F2blkKYTlKcDJIMGd6Skx3YURCYVhZVlRVNjJ3R2RVd2VxMEl4T3dLOURMZkpzdmVseVpzSzNJeXRrNC9oTnE0RHlGTQo5WHVYSHBCV0NBMGdXclpzUHQvcjYvaytjUlRSWkNkcU45RnVhUEdYNVFpU2M2MVdvb2FrSW5MT21TZzRLWCs0CnFsekJZc0ZpSllYVUtScjhlUm4veWhVeXZWR2pwMFdjLzEvdGdubXdCV2t4MGQ1UHoyS2FWazRBUVFia2I1YVEKc1BzSFo1SnJYZ3RFa0VSZmRVRmxhKzNvNk95bWpwUmlPVmJiekZMRnIwM2dHWnFXc3BpR2dFeEU3amlXbU5DVgpOZFRwaTNnL1F6bytSTmtrTzZpRi82UlhLY2FjeHVZK0hQakpZTDhUOWxRSkRVM2dGd21tSWp3VUIrV1dZTkJ4Ck5scHdkU29TMFJaUjNlSWgwQTloaWVjamYrbndoUVgyWHlrbml2Q1dyc01ZRnBLMnVkem5BNnY1aW5mZ3dQM1MKdnY2N2h1N2FzRllDR3RPQnpxWmN6T3kyRVJnZENLN1BmcGErZnp5VzBHWmxOTzl6SForbkZ3SU42ZnVzTDhCWgpRNUV1YjlkNEFRMkRSN1JldG0zT2VkWG5SV2VwQnN5ZThKaGthUE9HZ1QrekxrV1hrWGl6cTBrdXUydGNDM2MyCmJESno5VXllOGZTMzYvVENwZHJnNTBIWjJIc2ZBd0lEQVFBQkFvSUNBUUMveFpiWjBjY3RxYWdzcXZhVk5URWUKZXExcStoZmFHdlBFWVFhWUhJcklFKzJpNVhjbkdjTEtjS2ZvZHhEakFuOFIvemdkT3A2Y01YMENWbi9Qb2hIawpBRUR0RTgrQVZ3d0FNMUZzT3dnTEhWR2FHejhxcnhCbFlkUWdIY3BtdWVJdTJQWGJDOGVIVUJpYVVPSXVoYXc1Ci9SUk1EQUMvQWkyc3NmaTdnT2p2VkU0b1F4UVcwUUcxS0dPT0FVSm4vdVlIdzJSRlkyVXUxcGlteE8ya0RPNTMKZ2N4bUMxV09ueUNIbUhhaVcvVWg3ejZKYW1mU000ZFh0VEpac2x5aDM3ZGhIS05iZzlWa1A3Q1FLQTRoTHpvcApoYmY1cVk2cmFyZ09OaW55MUhnTVB4cm13S3VVb3VKeU90TjB5QnR4akRDVU5hWFVCd2l5N3NOR1MrSDR2c3lCCjVQOUhoSUhTdHUrRlp0M0hHN0VJcUNuZGlhU0tEUzRqV2FWUUFiYm80bloyWnMyQkQreERlUFJDUlVxWDdyTTQKNFh6UElSV1dYbW1XZi83SWcyOUhicnA0YTlMY09tUTJsZUNKdGJhVEZTTjk2T0xVSjVFK2hRMHVsQ1pnQlZtUQpSQ1VZa0pQNGxPemJhS2R6anhnSE1ySHptNDVlVUZmOExpck94aTJ1eXhYSFFtRE51NGIzWDE4a3QzUGdVbVVtCjNkWHBsM2ZxU3lKYTdTQ1Y4Wk5CcnNyRHExRSt0aFl0dTkxUWJWU0d4SGQ5SHJOVmUzWGRMYk9DZFU5Q3VDNjkKTmdsem5hYTdzWkxxbXlLZWpUZkdzWTd4cldkTmNNUGw0cDRmY0lEL080RXBBU1pmb3JwVGVLTlQwWklmWlpldwpiMG1BUWVZWnFRTThpL3FNWU4vdUFRS0NBUUVBNXFnMXNSTk1jNlZkTS90UmdsYXNHWW94amdSQzJPcUFEWmdzCm1BWE1VSjNrRXJweXh0K2VDaW15OGlidVlwelJUSVE4ZkJUV1JrQ3RSWlhKNytLY0xWdGs5UVpJb0xiaHlOd2QKNEl4RVFaRnVVbGpEYnZTalRMU3ljc0h2bzY1aWJXSWZUTDdiZ1dsTEdnR3EvVU96ZkdzZ0g2Uzl3THA1RzMwRwo4RUx5akk1ZVRJWUlDcmZUbVZMK2M0NU1ScEVNS28rY3Z6OFB5c2lhT0ZUbjNjeXN3UFZkWWFlRUVxTVFqVTh3CklHTnNHWkx5dFk3QkFCQmNZMGxkcnRiYS9PK0Z2LytSSDd1VXR6UDd4cENJd0ZDeDgwWnpOK1dSeTlOdkk2M1UKenEzeUlCb1c5R3lBcEQyK1BMYVBOeGY3UUxUVUNoWTFaei9kWVJsdEtPeHYyQWE1Z1FLQ0FRRUExV0xXTnFwMApmaEIvWnRmU0VTaHhGTU04OWNqTjZBYXoxV0tMN3VUQm91OW9TSm54amtoa2FWNzZhY25UL2lxWHR4TU5nSGkxCmZJbURwVTNQdk0wWTRVZDJUNDdvSGM2UDFCclpQTi9HbVh5L3M2QkFFZFB3TGU3Sis0blRJU0hBZEdtcmgrYS8KNXBrdHUzMmc5bFdxZnR4ZWNGSVZTTFBXa3hUMFhLaU14cDFmZmtMK09hdnBNZ01GWks0MWlLczNkTlNoS1BvZwpMOEdTUGNQOXgveW43OFAyZUszTitQR2psQTZwUHpyQU55V1U3TjAvYm1IY0I5VEtQK3VkWVdjalZocnU3TVlOCndOckU0a0tkQzh2OGk3eDd0RGJ2Yjc5VCtGbzZQSWg1M3AwT3NuWnpBOFVSMFFOUit2RFF1ZlF1eWFqOFJFQysKWkc4WXlDS3N2azh5Z3dLQ0FRQS9mc1N4QjBmL2VlRXJZeDZ3QzUzNnRlRW9ZQ0hxeHJzVGd2V2JyOVRyeUZzMQprSi95QVRMblIwMWNmYjBYNW1WemM5K1dwTUhMdXhnMzFLRXZhU2xuRHdhK3NNa2pmTlN3ejI5bUZoYmdHZUhOCngyT2RVcmoxYjdURUJJRXNoTi9SanJaaEVSVXFEY3MvMEgrNmtuMkJYWmdOUGZPQ2I1TFJMMXpPblE5YUJBTVAKZThJUStVUEZyR1FoZVdXajgxL3ZBM081N2VreUFJRDd5dHU5WWcrWVdyTW5JODhtdGo3ak40NWZEQitBOXNQYgptUDJtUDlxKzlqNVUyQTZXbkhVc1FuVTMwQktEVUVzYUFVV3o4MExaWG1adlY4SUg0eDl3S2ZVd0pCQklLQVp6CnFMN005N1k3em1Ha1gvU3BmbDMwbk9KOGxzY2hhTGQxRVlsRVphMkJBb0lCQVFDeWUyNVQ0VFY1TUpGdjB6dVoKTUd1TmcxU2MvTzRGa24yZkVVT2NlV2pod1VCSDRjUGpUL2YxRHdXRHNOYUo5TlJieENyNTkzMU9BclBEYzVjOApBNDA0K1k0ak01UkJRa0tabGk5NHRIQW9kK2pjOVVCQjZUVXZKbGw1OVNsTXdDOTY3OXdTMjFaT0tuZlBLR0NYClNzWkdRRXNaeGY2Wmhoc0hnWEozZ2wvbHpVSlBtUGVPQTVZVlIrT2Q5LzA5S0lGRlRvalNmb3luaFZDdUt4NDkKeGI0dVZZbjJIT0o0eEowZlBUZ2hkQ0hNdnJtWGVlUVJqdmI4OGVhTm1xVlVFSEhGRnRnYjRma2xBNWZFN1JUeApCaGxpUkRCd1o3YlVrSU5LNnlWazluNkJUbnM1bU12UkxtZ2RuSnBZdkU3S0MwMkxUYlpiM0krajhDMFpVYStOCnF5N0RBb0lCQUFpZXJpYlM3V1VjbDJhQmxrbTUrVzdxTm0vSU5tNXp2bm9TUG82VjN3YTVoczZmOStDL2tiZEYKODdqUVBBL1lGZTN1UjJzQUo3c2xYNWV1Wks4V21mcEZtZ3psdTBzRXo4MU1MUS9XeXBadFp5dHlWdFd6QjJQdQpYQ1cxdGRTSDllSTJCbWhYZ29rSE5UTTQ4TmsveE9FTnJQL3NlWHJJeDVMSzBobkRIWm90dS96NitZU2tCOWhGCmNtMmZaeWdEMWRNTFg2bGlSaW14eUZZK2RJQ0pOQjk1SmlmVExXWW5XZUdkZGt3UHRYVWVHWEUxb2x6dk5rTEQKek16RTA5dWhreC9sUkpudGVPQkVaYWY4ME9CLzA5T2k5YjkvcnhZNTlkd3NINkdheExvVGZFS3VQbnZCVk1OUgpZa1UxNFd6UUtsZUZraUJKSTlsVnZuZmdHbk9sZ2cwPQotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0t + + container2: + image: byjg/static-httpserver + labels: + easyhaproxy.http.redirect: host2.local--https://host2.local + easyhaproxy.http.host: host2.local + easyhaproxy.http.port: 80 + + easyhaproxy.https.port: 443 + easyhaproxy.https.localport: 8080 + easyhaproxy.https.host: host2.local + easyhaproxy.https.sslcert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxVENDQXBHZ0F3SUJBZ0lVSWQ1Yjl0OXVxSDc4ZzAyRXpiV0Y2RktWdzNnd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1pERUxNQWtHQTFVRUJoTUNRbEl4RnpBVkJnTlZCQWdNRGxKcGJ5QmtaU0JLWVc1bGFYSnZNUmN3RlFZRApWUVFIREE1U2FXOGdaR1VnU21GdVpXbHliekVOTUFzR0ExVUVDZ3dFUVVOTlJURVVNQklHQTFVRUF3d0xhRzl6CmRESXViRzlqWVd3d0hoY05Nakl3T0RFMU1EUXlOekExV2hjTk1qTXdPREUxTURReU56QTFXakJrTVFzd0NRWUQKVlFRR0V3SkNVakVYTUJVR0ExVUVDQXdPVW1sdklHUmxJRXBoYm1WcGNtOHhGekFWQmdOVkJBY01EbEpwYnlCawpaU0JLWVc1bGFYSnZNUTB3Q3dZRFZRUUtEQVJCUTAxRk1SUXdFZ1lEVlFRRERBdG9iM04wTWk1c2IyTmhiRENDCkFTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTVNLdnJPYWhhdkNYbnZTRjUxMzFocG8KNms2NUM1N2pnUlE4NEZhRGo1TWJKT1ZsWVFWRnRNRzBYT2s3YStoaDV2MWZlNHdIMFI3STZGRG8wVjlzUytzcwprbzVic0VsYzF4WWxnNUhidUtxODl2UlNLZzZFRGx6dHgzQktiaTkxMlBtdDV2RkdOSjE2emN3NzdEVXJRSVhvCjRJL2I0YTNwbUJpV2o0M05vVElybVNXSHRzR3d3T2ozaUR2U3dlcWRZWEpJcjNocEhINXU2cG9oakRvUXZxRHoKSzZNdThwNm1oQ1VLTnM3S0ZKbk5Jbk5HMjVvUVQ2TzBuNE9HdG1nUmpMV29wZEVuT2hNa0tzZklvSTFYdGxYQgpMQkR2N2h1SUNrM3Q1eXd0ZkNReU8wOWtYN2xGSWdkNXJuNytNandINVdOZXFiUUp4dWFxam9YUW5OWlVnVXNDCkF3RUFBYU5UTUZFd0hRWURWUjBPQkJZRUZOaE1CRzhxNmEraUsybkVDd1ZUbjZCOUVYWk9NQjhHQTFVZEl3UVkKTUJhQUZOaE1CRzhxNmEraUsybkVDd1ZUbjZCOUVYWk9NQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSQpodmNOQVFFTEJRQURnZ0VCQUptdWR2eDgrcDVpSVVzVDhmbS9mYlZNMERBNnFXQUxEWVVKblRuM2o2THE0dnBmClBGQytxMUxtdVdmQlFNeXFLckhyUDNlNDkzRWN0WG9pU0taTzZpTjVkVkpJdXIwMk9qR3VpQUVjc1l1WTFuTG4KczlwaWlJK1VFd3hINnV4MU5hSFVuenNXYXVvQnZSaHpqWHZPNlNBVlNaSllhOWRZNW1pelhrbER5RE51RzVVMApsWHY5ZWdNR0JzeTBkRzZlRlhrVTVDUGR4V1U1NDB5STJzQ3RTQWo3eitXUlVENWs3Z0o3dFZvWTMvL2pIUVpHCjVTVFRtbTV0OWtwSVpUV2twdHlKb3M5b1pKRllNSVhxVzJGYzZ0eUxacFJwMzFSNzh0RHM2RVRJa1RvRGMwUlIKano2NnRoNkhJK1psZ0lCUWh3MDkraFlBaEJEZTkrRG1kL1N6UVpjPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gUFJJVkFURSBLRVktLS0tLQpNSUlFdndJQkFEQU5CZ2txaGtpRzl3MEJBUUVGQUFTQ0JLa3dnZ1NsQWdFQUFvSUJBUURFaXI2em1vV3J3bDU3CjBoZWRkOVlhYU9wT3VRdWU0NEVVUE9CV2c0K1RHeVRsWldFRlJiVEJ0RnpwTzJ2b1llYjlYM3VNQjlFZXlPaFEKNk5GZmJFdnJMSktPVzdCSlhOY1dKWU9SMjdpcXZQYjBVaW9PaEE1YzdjZHdTbTR2ZGRqNXJlYnhSalNkZXMzTQpPK3cxSzBDRjZPQ1AyK0d0NlpnWWxvK056YUV5SzVrbGg3YkJzTURvOTRnNzBzSHFuV0Z5U0s5NGFSeCtidXFhCklZdzZFTDZnOHl1akx2S2Vwb1FsQ2piT3loU1p6U0p6UnR1YUVFK2p0SitEaHJab0VZeTFxS1hSSnpvVEpDckgKeUtDTlY3WlZ3U3dRNys0YmlBcE43ZWNzTFh3a01qdFBaRis1UlNJSGVhNSsvakk4QitWalhxbTBDY2JtcW82RgowSnpXVklGTEFnTUJBQUVDZ2dFQkFLY2VpdFZST1FRNWUvbXhSUjlDZksxc05IL0gzTmUzLzFQa0I2WElyRmFiCnFCM2V2RWF0Wk91b243QTZOS0VlVGpsMzdTZStwZFNWWk9VWGNxQy9CemJyYVpyZTMrRWhya3BJajcyQXBWK1kKMml3WmlXVmFhSlFnSTR1WjNtTkF3OFJhV0pzajVTMWE5SThMRE9pUTVJWjQ1Q212QUJEUEplTVNjdkpTdlJSWQplNU4wTDZzdHFTN1orSW95R1ZLVWZwMWlOTzBZeXl3T1VpU2tJUlhnc2N1UlhaR1lwaUdQb21zSitKczFlanpXCmp5U3RsWkpFcjRMMTI4NXJHUHJtSHFqVHdGZCtoRzgwV2M0MTc5eEwrV1JFNkhCRVVaU2l5OTVmZTZrY1BIWFgKQmdpVll0Y0ZLbWlCaTJkVGJ4bDRlOTR1dDIzOWkwSHRsSjFaSnRMaCtCRUNnWUVBOGEyOThLMnpYa0hvc3hoTgp0UnJIN1hmTVBUa0hERGQzcnhNMjFMVCtmSVhxaW5HVXA5TFlhRGNianVUUHM4ZTMzdUtNZDdSNlE0MHg4OXlXCklYTmthL1ZMMFBYVWVWNjdhQ1ZMTHFnWERMR3VkbHVKaW5IMFh2bUkwQ21CZWNGU01xSUZtUWxncUVSb0dHczMKVU1hYzBwODc2VDRYa0dRUUpkZjYyYkZwRTRVQ2dZRUEwREJIMFBEbE9wd1hjY0RnWHJNZmF5cjhIQWhJK0c1Ugp5V1EvLzlpaXJ0VTgzY2h3SVd3a2g1M2VMTE16TGdkcUpuUGlXeWFVVzVCcXptWXVEMjNuaHhjUTdQTmRJcU9PCkgxc0U2enFMTnNodjQ2dDVRS2xoMVE0cWpkN1VxdGdyU3JZNjNSWEpDTVdUd25OTWVETHRqOGdhS2Jqa3JHM1IKQk0yaWxkdDZVbzhDZ1lCWDdORFVsaTFTbG9IMVhsc3ZEMDQ3UzhGSGFNN3lsOTk0RjNKMFVtRGZwc3pjajFQNAo5cEY2NE1tcTQvM1l0MGxpMG1NdVRiL0pnYjN4cllnRkpYa2NlY0thaEVWSDNyb3B1cCt1bXNMQUFJaXJVTVFxClZTa0Z3SjBRdG5qL2RlRFV3UE51YU9YOGNkNjVPNUNGVjZ6SVI5eEJFREQ4ZkJzUDJaTE96bWVmRFFLQmdRREYKbTI0dlZ0aGQvMWNKZENnRCswVnhOWVhESGVJVlhMRm8xUzBpTFlDTkxuM3RqWmxSUUJLVVh6WkplM2F5MC9yZgpzTk5EN2FTWUhNWWtUenlkREpiYzFQb056eG15RFVpVFhwT1dxeVVFeE0vZmJCMVZVUEU1aDQ3QXhxZFoyb0dOCkV0ZGdqcE1aTG1DSUMyU2tHc0wrM05Kb2s4VUtIZHB1RXJtbVFJTWs1UUtCZ1FDZ0VXY1l0TFhDM1lEWU1GZEkKVWdjVGViRnFTczNtTFlndWIxeGVrVzNJWFIyeW9tNFY1ZlFUTGlGN1lmbjJkcERXNEljTVUwVUpGWVZzVWxoSwphR3RldDRWbTVObjgrTWdob3Q1eUFqcU85eUFVYXViN3dnaWZLSWU5OXRRS2Q4dVp5Q3ZKMGhodm1ERFNmeDRtCkIvVEVpRkFPOTl5RjQ5aVN4RVZTQVM2cHFRPT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo= + diff --git a/templates/bind.j2 b/templates/bind.j2 index 6cad5ff..7c8425f 100644 --- a/templates/bind.j2 +++ b/templates/bind.j2 @@ -1,5 +1,5 @@ {% if "ssl_cert" in o %} - bind *:{{ o["port"] }} ssl crt {{ o["ssl_cert"] }} + bind *:{{ o["port"] }} ssl crt /etc/haproxy/certs/discover/ crt /etc/haproxy/certs/ {% elif "h2" in o and o["h2"] %} bind *:{{ o["port"] }} proto h2 option http-use-htx diff --git a/templates/frontend-mode-http.j2 b/templates/frontend-mode-http.j2 index 620d536..738761a 100644 --- a/templates/frontend-mode-http.j2 +++ b/templates/frontend-mode-http.j2 @@ -4,7 +4,7 @@ {% endfor %} {%- for k in o["hosts"] %} - {% set host = k.replace(".", "_") + "_{0}_{1}".format(o["port"], salt) %} + {% set host = k.replace(".", "_") + "_{0}".format(o["port"]) %} {% set letsencrypt = o["hosts"][k]["letsencrypt"] %} acl is_rule_{{ host }}_1 hdr(host) -i {{ k }} diff --git a/templates/frontend-mode-tcp.j2 b/templates/frontend-mode-tcp.j2 index 012d865..f08a403 100644 --- a/templates/frontend-mode-tcp.j2 +++ b/templates/frontend-mode-tcp.j2 @@ -2,5 +2,5 @@ option tcplog log global {% set backend = (o["hosts"]|first) %} - default_backend srv_{{ backend.replace(".", "_") + "_{0}_{1}".format(o["port"], salt) }} + default_backend srv_{{ backend.replace(".", "_") + "_{0}".format(o["port"]) }} diff --git a/templates/haproxy.cfg.j2 b/templates/haproxy.cfg.j2 index df5adad..c99f94c 100644 --- a/templates/haproxy.cfg.j2 +++ b/templates/haproxy.cfg.j2 @@ -39,9 +39,8 @@ backend srv_stats {% endif %} {% for o in data["easymapping"] -%} {% set mode = o["mode"] or "http" %} - {% set salt = loop.index %} -frontend {{ mode }}_in_{{ o["port"] }}_{{ salt }} +frontend {{ mode }}_in_{{ o["port"] }} {% include "bind.j2" %} {% if mode == "http" %} {% include "frontend-mode-http.j2" %} @@ -50,7 +49,7 @@ frontend {{ mode }}_in_{{ o["port"] }}_{{ salt }} {% endif %} {% for k in o["hosts"] -%} - {% set host = k.replace(".", "_") + "_{0}_{1}".format(o["port"], salt) %} + {% set host = k.replace(".", "_") + "_{0}".format(o["port"]) %} backend srv_{{ host }} balance roundrobin mode {{ mode }} @@ -69,4 +68,5 @@ backend srv_{{ host }} {% endfor %} backend letsencrypt_backend + mode http server certbot 127.0.0.1:2080 \ No newline at end of file diff --git a/tests/expected/no-services.txt b/tests/expected/no-services.txt index 42767c1..6450ea3 100644 --- a/tests/expected/no-services.txt +++ b/tests/expected/no-services.txt @@ -12,4 +12,5 @@ defaults backend letsencrypt_backend + mode http server certbot 127.0.0.1:2080 \ No newline at end of file diff --git a/tests/expected/services-multi-containers.txt b/tests/expected/services-multi-containers.txt index 6eebe88..e1876cd 100644 --- a/tests/expected/services-multi-containers.txt +++ b/tests/expected/services-multi-containers.txt @@ -11,15 +11,15 @@ defaults timeout server 10m -frontend http_in_19901_1 +frontend http_in_19901 bind *:19901 mode http - acl is_rule_www_helloworld_com_19901_1_1 hdr(host) -i www.helloworld.com - acl is_rule_www_helloworld_com_19901_1_2 hdr(host) -i www.helloworld.com:19901 - use_backend srv_www_helloworld_com_19901_1 if is_rule_www_helloworld_com_19901_1_1 OR is_rule_www_helloworld_com_19901_1_2 + acl is_rule_www_helloworld_com_19901_1 hdr(host) -i www.helloworld.com + acl is_rule_www_helloworld_com_19901_2 hdr(host) -i www.helloworld.com:19901 + use_backend srv_www_helloworld_com_19901 if is_rule_www_helloworld_com_19901_1 OR is_rule_www_helloworld_com_19901_2 -backend srv_www_helloworld_com_19901_1 +backend srv_www_helloworld_com_19901 balance roundrobin mode http option forwardfor @@ -29,4 +29,5 @@ backend srv_www_helloworld_com_19901_1 server srv-1 test_nginx.1.p552hqxkdx88narjrp5kouwb2:80 check weight 1 backend letsencrypt_backend + mode http server certbot 127.0.0.1:2080 \ No newline at end of file diff --git a/tests/expected/services-tcp.txt b/tests/expected/services-tcp.txt index 1e8fb77..f988f44 100644 --- a/tests/expected/services-tcp.txt +++ b/tests/expected/services-tcp.txt @@ -11,14 +11,14 @@ defaults timeout server 10m -frontend tcp_in_31339_1 +frontend tcp_in_31339 bind *:31339 mode tcp option tcplog log global - default_backend srv_agent_quantum_local_31339_1 + default_backend srv_agent_quantum_local_31339 -backend srv_agent_quantum_local_31339_1 +backend srv_agent_quantum_local_31339 balance roundrobin mode tcp option tcp-check @@ -26,4 +26,5 @@ backend srv_agent_quantum_local_31339_1 server srv-0 test_agent:9001 check weight 1 verify none backend letsencrypt_backend + mode http server certbot 127.0.0.1:2080 \ No newline at end of file diff --git a/tests/expected/services.txt b/tests/expected/services.txt index c55ac96..b74d48e 100644 --- a/tests/expected/services.txt +++ b/tests/expected/services.txt @@ -11,42 +11,42 @@ defaults timeout server 10m -frontend tcp_in_31339_1 +frontend tcp_in_31339 bind *:31339 mode tcp option tcplog log global - default_backend srv_agent_quantum_example_org_31339_1 + default_backend srv_agent_quantum_example_org_31339 -backend srv_agent_quantum_example_org_31339_1 +backend srv_agent_quantum_example_org_31339 balance roundrobin mode tcp option tcp-check tcp-check connect server srv-0 my-stack_agent:9001 check weight 1 -frontend http_in_31337_2 +frontend http_in_31337 bind *:31337 mode http - acl is_rule_cadvisor_quantum_example_org_31337_2_1 hdr(host) -i cadvisor.quantum.example.org - acl is_rule_cadvisor_quantum_example_org_31337_2_2 hdr(host) -i cadvisor.quantum.example.org:31337 - use_backend srv_cadvisor_quantum_example_org_31337_2 if is_rule_cadvisor_quantum_example_org_31337_2_1 OR is_rule_cadvisor_quantum_example_org_31337_2_2 + acl is_rule_cadvisor_quantum_example_org_31337_1 hdr(host) -i cadvisor.quantum.example.org + acl is_rule_cadvisor_quantum_example_org_31337_2 hdr(host) -i cadvisor.quantum.example.org:31337 + use_backend srv_cadvisor_quantum_example_org_31337 if is_rule_cadvisor_quantum_example_org_31337_1 OR is_rule_cadvisor_quantum_example_org_31337_2 - acl is_rule_node-exporter_quantum_example_org_31337_2_1 hdr(host) -i node-exporter.quantum.example.org - acl is_rule_node-exporter_quantum_example_org_31337_2_2 hdr(host) -i node-exporter.quantum.example.org:31337 - acl is_letsencrypt_node-exporter_quantum_example_org_31337_2 path_beg /.well-known/acme-challenge/ - use_backend letsencrypt_backend if is_letsencrypt_node-exporter_quantum_example_org_31337_2 is_rule_node-exporter_quantum_example_org_31337_2_1 OR is_letsencrypt_node-exporter_quantum_example_org_31337_2 is_rule_node-exporter_quantum_example_org_31337_2_2 - use_backend srv_node-exporter_quantum_example_org_31337_2 if is_rule_node-exporter_quantum_example_org_31337_2_1 OR is_rule_node-exporter_quantum_example_org_31337_2_2 + acl is_rule_node-exporter_quantum_example_org_31337_1 hdr(host) -i node-exporter.quantum.example.org + acl is_rule_node-exporter_quantum_example_org_31337_2 hdr(host) -i node-exporter.quantum.example.org:31337 + acl is_letsencrypt_node-exporter_quantum_example_org_31337 path_beg /.well-known/acme-challenge/ + use_backend letsencrypt_backend if is_letsencrypt_node-exporter_quantum_example_org_31337 is_rule_node-exporter_quantum_example_org_31337_1 OR is_letsencrypt_node-exporter_quantum_example_org_31337 is_rule_node-exporter_quantum_example_org_31337_2 + use_backend srv_node-exporter_quantum_example_org_31337 if is_rule_node-exporter_quantum_example_org_31337_1 OR is_rule_node-exporter_quantum_example_org_31337_2 -backend srv_cadvisor_quantum_example_org_31337_2 +backend srv_cadvisor_quantum_example_org_31337 balance roundrobin mode http option forwardfor http-request set-header X-Forwarded-Port %[dst_port] http-request add-header X-Forwarded-Proto https if { ssl_fc } server srv-0 my-stack_cadvisor:8080 check weight 1 -backend srv_node-exporter_quantum_example_org_31337_2 +backend srv_node-exporter_quantum_example_org_31337 balance roundrobin mode http option forwardfor @@ -54,7 +54,39 @@ backend srv_node-exporter_quantum_example_org_31337_2 http-request add-header X-Forwarded-Proto https if { ssl_fc } server srv-0 my-stack_node-exporter:9100 check weight 1 -frontend http_in_80_3 +frontend http_in_443 + bind *:443 ssl crt /etc/haproxy/certs/discover/ crt /etc/haproxy/certs/ + mode http + redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i somehost.com.br } + redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i somehost.com } + redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i www.somehost.com } + redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i byjg.ca } + redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i www.byjg.ca } + + acl is_rule_node-exporter_quantum_example_org_443_1 hdr(host) -i node-exporter.quantum.example.org + acl is_rule_node-exporter_quantum_example_org_443_2 hdr(host) -i node-exporter.quantum.example.org:443 + use_backend srv_node-exporter_quantum_example_org_443 if is_rule_node-exporter_quantum_example_org_443_1 OR is_rule_node-exporter_quantum_example_org_443_2 + + acl is_rule_www_somehost_com_br_443_1 hdr(host) -i www.somehost.com.br + acl is_rule_www_somehost_com_br_443_2 hdr(host) -i www.somehost.com.br:443 + use_backend srv_www_somehost_com_br_443 if is_rule_www_somehost_com_br_443_1 OR is_rule_www_somehost_com_br_443_2 + +backend srv_node-exporter_quantum_example_org_443 + balance roundrobin + mode http + option forwardfor + http-request set-header X-Forwarded-Port %[dst_port] + http-request add-header X-Forwarded-Proto https if { ssl_fc } + server srv-0 my-stack_node-exporter:9100 check weight 1 +backend srv_www_somehost_com_br_443 + balance roundrobin + mode http + option forwardfor + http-request set-header X-Forwarded-Port %[dst_port] + http-request add-header X-Forwarded-Proto https if { ssl_fc } + server srv-0 some-service:80 check weight 1 + +frontend http_in_80 bind *:80 mode http redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i somehost.com.br } @@ -63,32 +95,11 @@ frontend http_in_80_3 redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i byjg.ca } redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i www.byjg.ca } - acl is_rule_www_somehost_com_br_80_3_1 hdr(host) -i www.somehost.com.br - acl is_rule_www_somehost_com_br_80_3_2 hdr(host) -i www.somehost.com.br:80 - use_backend srv_www_somehost_com_br_80_3 if is_rule_www_somehost_com_br_80_3_1 OR is_rule_www_somehost_com_br_80_3_2 + acl is_rule_www_somehost_com_br_80_1 hdr(host) -i www.somehost.com.br + acl is_rule_www_somehost_com_br_80_2 hdr(host) -i www.somehost.com.br:80 + use_backend srv_www_somehost_com_br_80 if is_rule_www_somehost_com_br_80_1 OR is_rule_www_somehost_com_br_80_2 -backend srv_www_somehost_com_br_80_3 - balance roundrobin - mode http - option forwardfor - http-request set-header X-Forwarded-Port %[dst_port] - http-request add-header X-Forwarded-Proto https if { ssl_fc } - server srv-0 some-service:80 check weight 1 - -frontend http_in_443_4 - bind *:443 ssl crt /tmp/www.somehost.com.br.1.pem - mode http - redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i somehost.com.br } - redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i somehost.com } - redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i www.somehost.com } - redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i byjg.ca } - redirect prefix https://www.somehost.com.br code 301 if { hdr(host) -i www.byjg.ca } - - acl is_rule_www_somehost_com_br_443_4_1 hdr(host) -i www.somehost.com.br - acl is_rule_www_somehost_com_br_443_4_2 hdr(host) -i www.somehost.com.br:443 - use_backend srv_www_somehost_com_br_443_4 if is_rule_www_somehost_com_br_443_4_1 OR is_rule_www_somehost_com_br_443_4_2 - -backend srv_www_somehost_com_br_443_4 +backend srv_www_somehost_com_br_80 balance roundrobin mode http option forwardfor @@ -97,4 +108,5 @@ backend srv_www_somehost_com_br_443_4 server srv-0 some-service:80 check weight 1 backend letsencrypt_backend + mode http server certbot 127.0.0.1:2080 \ No newline at end of file diff --git a/tests/expected/static.txt b/tests/expected/static.txt index a84241b..4aad923 100644 --- a/tests/expected/static.txt +++ b/tests/expected/static.txt @@ -34,29 +34,29 @@ backend srv_stats mode http server Local 127.0.0.1:1936 -frontend http_in_80_1 +frontend http_in_80 bind *:80 mode http redirect prefix http://host1.com.br code 301 if { hdr(host) -i www.host1.com.br } - acl is_rule_host1_com_br_80_1_1 hdr(host) -i host1.com.br - acl is_rule_host1_com_br_80_1_2 hdr(host) -i host1.com.br:80 - acl is_letsencrypt_host1_com_br_80_1 path_beg /.well-known/acme-challenge/ - use_backend letsencrypt_backend if is_letsencrypt_host1_com_br_80_1 is_rule_host1_com_br_80_1_1 OR is_letsencrypt_host1_com_br_80_1 is_rule_host1_com_br_80_1_2 - use_backend srv_host1_com_br_80_1 if is_rule_host1_com_br_80_1_1 OR is_rule_host1_com_br_80_1_2 + acl is_rule_host1_com_br_80_1 hdr(host) -i host1.com.br + acl is_rule_host1_com_br_80_2 hdr(host) -i host1.com.br:80 + acl is_letsencrypt_host1_com_br_80 path_beg /.well-known/acme-challenge/ + use_backend letsencrypt_backend if is_letsencrypt_host1_com_br_80 is_rule_host1_com_br_80_1 OR is_letsencrypt_host1_com_br_80 is_rule_host1_com_br_80_2 + use_backend srv_host1_com_br_80 if is_rule_host1_com_br_80_1 OR is_rule_host1_com_br_80_2 - acl is_rule_host2_com_br_80_1_1 hdr(host) -i host2.com.br - acl is_rule_host2_com_br_80_1_2 hdr(host) -i host2.com.br:80 - use_backend srv_host2_com_br_80_1 if is_rule_host2_com_br_80_1_1 OR is_rule_host2_com_br_80_1_2 + acl is_rule_host2_com_br_80_1 hdr(host) -i host2.com.br + acl is_rule_host2_com_br_80_2 hdr(host) -i host2.com.br:80 + use_backend srv_host2_com_br_80 if is_rule_host2_com_br_80_1 OR is_rule_host2_com_br_80_2 -backend srv_host1_com_br_80_1 +backend srv_host1_com_br_80 balance roundrobin mode http option forwardfor http-request set-header X-Forwarded-Port %[dst_port] http-request add-header X-Forwarded-Proto https if { ssl_fc } server srv-0 container:5000 check weight 1 -backend srv_host2_com_br_80_1 +backend srv_host2_com_br_80 balance roundrobin mode http option forwardfor @@ -64,15 +64,15 @@ backend srv_host2_com_br_80_1 http-request add-header X-Forwarded-Proto https if { ssl_fc } server srv-0 other:3000 check weight 1 -frontend http_in_443_2 - bind *:443 ssl crt /etc/haproxy/certs/mycert.pem +frontend http_in_443 + bind *:443 ssl crt /etc/haproxy/certs/discover/ crt /etc/haproxy/certs/ mode http - acl is_rule_host1_com_br_443_2_1 hdr(host) -i host1.com.br - acl is_rule_host1_com_br_443_2_2 hdr(host) -i host1.com.br:443 - use_backend srv_host1_com_br_443_2 if is_rule_host1_com_br_443_2_1 OR is_rule_host1_com_br_443_2_2 + acl is_rule_host1_com_br_443_1 hdr(host) -i host1.com.br + acl is_rule_host1_com_br_443_2 hdr(host) -i host1.com.br:443 + use_backend srv_host1_com_br_443 if is_rule_host1_com_br_443_1 OR is_rule_host1_com_br_443_2 -backend srv_host1_com_br_443_2 +backend srv_host1_com_br_443 balance roundrobin mode http option forwardfor @@ -80,15 +80,15 @@ backend srv_host1_com_br_443_2 http-request add-header X-Forwarded-Proto https if { ssl_fc } server srv-0 container:80 check weight 1 -frontend http_in_8080_3 +frontend http_in_8080 bind *:8080 mode http - acl is_rule_host3_com_br_8080_3_1 hdr(host) -i host3.com.br - acl is_rule_host3_com_br_8080_3_2 hdr(host) -i host3.com.br:8080 - use_backend srv_host3_com_br_8080_3 if is_rule_host3_com_br_8080_3_1 OR is_rule_host3_com_br_8080_3_2 + acl is_rule_host3_com_br_8080_1 hdr(host) -i host3.com.br + acl is_rule_host3_com_br_8080_2 hdr(host) -i host3.com.br:8080 + use_backend srv_host3_com_br_8080 if is_rule_host3_com_br_8080_1 OR is_rule_host3_com_br_8080_2 -backend srv_host3_com_br_8080_3 +backend srv_host3_com_br_8080 balance roundrobin mode http option forwardfor @@ -97,4 +97,5 @@ backend srv_host3_com_br_8080_3 server srv-0 domain:8181 check weight 1 backend letsencrypt_backend + mode http server certbot 127.0.0.1:2080 \ No newline at end of file diff --git a/tests/test_parser.py b/tests/test_parser.py index 5298e98..52043e3 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -19,7 +19,7 @@ def test_parser_doesnt_crash(): "customerrors": False } - cfg = easymapping.HaproxyConfigGenerator(result, "/tmp") + cfg = easymapping.HaproxyConfigGenerator(result, "/tmp/certs") haproxy_config = cfg.generate(line_list) assert len(haproxy_config) > 0 @@ -35,11 +35,11 @@ def test_parser_finds_services(): "customerrors": False } - cert_file = "/tmp/www.somehost.com.br.1.pem" + cert_file = "/tmp/certs/www.somehost.com.br.pem" if os.path.exists(cert_file): os.remove(cert_file) - cfg = easymapping.HaproxyConfigGenerator(result, "/tmp") + cfg = easymapping.HaproxyConfigGenerator(result, "/tmp/certs") haproxy_config = cfg.generate(line_list) assert len(haproxy_config) > 0 @@ -60,11 +60,11 @@ def test_parser_finds_services_changed_label(): "lookup_label": "haproxy" } - cert_file = "/tmp/www.somehost.com.br.1.pem" + cert_file = "/tmp/certs/www.somehost.com.br.pem" if os.path.exists(cert_file): os.remove(cert_file) - cfg = easymapping.HaproxyConfigGenerator(result, "/tmp") + cfg = easymapping.HaproxyConfigGenerator(result, "/tmp/certs") haproxy_config = cfg.generate(line_list) assert len(haproxy_config) > 0 @@ -84,11 +84,11 @@ def test_parser_finds_services_raw(): "customerrors": False } - cert_file = "/tmp/www.somehost.com.br.1.pem" + cert_file = "/tmp/certs/www.somehost.com.br.pem" if os.path.exists(cert_file): os.remove(cert_file) - cfg = easymapping.HaproxyConfigGenerator(result, "/tmp") + cfg = easymapping.HaproxyConfigGenerator(result, "/tmp/certs") parsed_object = [ { @@ -129,6 +129,33 @@ def test_parser_finds_services_raw(): } }, + { + "mode":"http", + "health-check":"", + "port":"443", + "hosts":{ + "node-exporter.quantum.example.org": { + "containers": [ + "my-stack_node-exporter:9100" + ], + "letsencrypt": False + }, + "www.somehost.com.br":{ + "containers": [ + "some-service:80" + ], + "letsencrypt": False + } + }, + "redirect":{ + "somehost.com.br":"https://www.somehost.com.br", + "somehost.com":"https://www.somehost.com.br", + "www.somehost.com":"https://www.somehost.com.br", + "byjg.ca":"https://www.somehost.com.br", + "www.byjg.ca":"https://www.somehost.com.br" + }, + "ssl_cert":"/tmp/certs/www.somehost.com.br.pem" + }, { "mode":"http", "health-check":"", @@ -148,27 +175,6 @@ def test_parser_finds_services_raw(): "byjg.ca":"https://www.somehost.com.br", "www.byjg.ca":"https://www.somehost.com.br" } - }, - { - "mode":"http", - "health-check":"", - "port":"443", - "hosts":{ - "www.somehost.com.br":{ - "containers": [ - "some-service:80" - ], - "letsencrypt": False - } - }, - "redirect":{ - "somehost.com.br":"https://www.somehost.com.br", - "somehost.com":"https://www.somehost.com.br", - "www.somehost.com":"https://www.somehost.com.br", - "byjg.ca":"https://www.somehost.com.br", - "www.byjg.ca":"https://www.somehost.com.br" - }, - "ssl_cert":"/tmp/www.somehost.com.br.1.pem" } ] @@ -184,7 +190,7 @@ def test_parser_static(): with open(path + "/fixtures/static.yml", 'r') as content_file: parsed = yaml.load(content_file.read(), Loader=yaml.FullLoader) - cfg = easymapping.HaproxyConfigGenerator(parsed, "/tmp") + cfg = easymapping.HaproxyConfigGenerator(parsed, "/tmp/certs") haproxy_config = cfg.generate() assert len(haproxy_config) > 0 @@ -259,7 +265,7 @@ def test_parser_tcp(): "customerrors": False } - cfg = easymapping.HaproxyConfigGenerator(result, "/tmp") + cfg = easymapping.HaproxyConfigGenerator(result, "/tmp/certs") haproxy_config = cfg.generate(line_list) # print(haproxy_config) @@ -276,7 +282,7 @@ def test_parser_multi_containers(): "customerrors": False } - cfg = easymapping.HaproxyConfigGenerator(result, "/tmp") + cfg = easymapping.HaproxyConfigGenerator(result, "/tmp/certs") haproxy_config = cfg.generate(line_list) assert len(haproxy_config) > 0