From d25277323c30f617bfaf055899541c1dea025326 Mon Sep 17 00:00:00 2001 From: jurgenhaas <juergen@paragon-es.de> Date: Thu, 5 Mar 2020 11:39:25 +0100 Subject: [PATCH] Implement support for maintenance mode for individual domains --- files/maintenance.http | 34 ++++++++++++++++++++++++++++++++++ tasks/configure.yml | 10 ++++++++++ tasks/install.yml | 1 + templates/haproxy_cfg.jinja2 | 10 ++++++++++ templates/maintenance_list | 3 +++ 5 files changed, 58 insertions(+) create mode 100644 files/maintenance.http create mode 100644 templates/maintenance_list diff --git a/files/maintenance.http b/files/maintenance.http new file mode 100644 index 0000000..c0364cb --- /dev/null +++ b/files/maintenance.http @@ -0,0 +1,34 @@ +HTTP/1.0 503 Service Unavailable +Cache-Control: no-cache +Connection: close +Content-Type: text/html + +<!doctype html> +<!-- 503 Service Unavailable --> +<html> + <title>Site Maintenance | Wartung</title> + <style> + body { text-align: center; padding: 150px; } + h1 { font-size: 50px; } + body { font: 20px Helvetica, sans-serif; color: #333; } + article { display: block; text-align: left; width: 650px; margin: 0 auto; } + a { color: #dc8100; text-decoration: none; } + a:hover { color: #333; text-decoration: none; } + </style> + + <body> + <article> + <h1>We’ll be back soon!</h1> + <div> + <p>Sorry for the inconvenience but we're performing some maintenance at the moment. We'll be back online shortly!</p> + </div> + </article> + + <article> + <h1>Wir sind bald zurück!</h1> + <div> + <p>Wir führen derzeit einige Wartungsarbeiten durch und entschuldigen uns für die Unannehmlichkeiten. Wir sind bald wieder online!</p> + </div> + </article> + </body> +</html> diff --git a/tasks/configure.yml b/tasks/configure.yml index b664a9c..7f19c54 100644 --- a/tasks/configure.yml +++ b/tasks/configure.yml @@ -16,6 +16,16 @@ notify: - Check HAProxy Config +- name: Create maintenance lists + template: + src: maintenance_list + dest: /etc/haproxy/maintenance.list + owner: root + group: root + mode: 0644 + notify: + - Check HAProxy Config + - name: Create host lists template: src: host_list diff --git a/tasks/install.yml b/tasks/install.yml index ebe15c9..a8d3d0b 100644 --- a/tasks/install.yml +++ b/tasks/install.yml @@ -66,6 +66,7 @@ - '502' - '503' - '504' + - 'maintenance' tags: - errorfiles notify: diff --git a/templates/haproxy_cfg.jinja2 b/templates/haproxy_cfg.jinja2 index 7544eee..110e09a 100644 --- a/templates/haproxy_cfg.jinja2 +++ b/templates/haproxy_cfg.jinja2 @@ -64,6 +64,7 @@ frontend http_in {% endfor %} http-request set-header x-routing-host undefined acl letsencrypt_challenge path_beg /.well-known/acme-challenge/ + http-request set-header x-routing-host maintenance if !letsencrypt_challenge { hdr(x-routing-host) undefined } { hdr(host) -i -n -f /etc/haproxy/maintenance.list } http-request redirect code 301 location %[base,lower,map(/etc/haproxy/redirect.domain-and-path.map)] if !letsencrypt_challenge { base,lower,map(/etc/haproxy/redirect.domain-and-path.map) -m found } http-request redirect code 301 location %[capture.req.uri,lower,map(/etc/haproxy/redirect.path.map)] if !letsencrypt_challenge { capture.req.uri,lower,map(/etc/haproxy/redirect.path.map) -m found } http-request redirect code 301 location %[hdr(host),lower,map(/etc/haproxy/redirect.domain.map)] if !letsencrypt_challenge { hdr(host),lower,map(/etc/haproxy/redirect.domain.map) -m found } @@ -141,6 +142,7 @@ frontend http_in http-request set-header x-routing-host {{ routing.default }} if !letsencrypt_challenge { hdr(x-routing-host) undefined } { hdr(host) -i -n {{ routing.domain }} } {% endif %} use_backend backend_letsencrypt if letsencrypt_challenge + use_backend backend_maintenance if { hdr(x-routing-host) maintenance } {% if kibana_domain is defined %} acl kibana_present hdr(host) -i -n '{{ kibana_domain|default(inventory_hostname) }}' use_backend backend_redirect_ssl if kibana_present @@ -224,6 +226,7 @@ frontend https_in_{{ cert.ip }} http-request deny if { {{ rule }} } {% endfor %} http-request set-header x-routing-host undefined + http-request set-header x-routing-host maintenance if { hdr(x-routing-host) undefined } { hdr(host) -i -n -f /etc/haproxy/maintenance.list } {% for host in groups['all']|sort %} {% for redirect in hostvars[host].proxy_redirect|default([]) %} {% for from in redirect.from %} @@ -283,6 +286,7 @@ frontend https_in_{{ cert.ip }} {% if routing is defined and routing.default is defined %} http-request set-header x-routing-host {{ routing.default }} if { hdr(x-routing-host) undefined } { hdr(host) -i -n {{ routing.domain }} } {% endif %} + use_backend backend_maintenance if { hdr(x-routing-host) maintenance } {% if kibana_domain is defined %} acl kibana_present hdr(host) -i -n '{{ kibana_domain|default(inventory_hostname) }}' use_backend backend_kibana if kibana_present @@ -473,3 +477,9 @@ backend backend_kibana {% endif %} server kibana 127.0.0.1:5601 check maxconn 32 {% endif %} + +backend backend_maintenance +{% if proxy_debug %} + http-response set-header X-Proxy-Backend "maintenance" +{% endif %} + errorfile 503 /etc/haproxy/errors/maintenance.http diff --git a/templates/maintenance_list b/templates/maintenance_list new file mode 100644 index 0000000..9501976 --- /dev/null +++ b/templates/maintenance_list @@ -0,0 +1,3 @@ +{% for domain in proxy_maintenance_domains|default([]) %} +{{domain}} +{% endfor %} -- GitLab