Commit 0b72f184 authored by Łukasz Nowak's avatar Łukasz Nowak

XXX caddy-frontend: Switch from Caddy to Haproxy

XXX: checkpoint reached, the frontend-haproxy is able to start, serves nothing
parent 12e43b30
Pipeline #17453 failed with stage
in 0 seconds
......@@ -22,7 +22,7 @@ md5sum = 5784bea3bd608913769ff9a8afcccb68
[profile-caddy-frontend]
filename = instance-apache-frontend.cfg.in
md5sum = 51087ac7615bd7cc01e60eb23701f625
md5sum = f92bc3b2d263819494c8e1fe7ae9860d
[profile-caddy-replicate]
filename = instance-apache-replicate.cfg.in
......@@ -30,15 +30,19 @@ md5sum = 99741e618b1c249bd17c9e02778d74ee
[profile-slave-list]
_update_hash_filename_ = templates/apache-custom-slave-list.cfg.in
md5sum = 9bb51f663f69d66b5b3708bf892dd3e6
md5sum = 5306d90305215ae7917a17701830c23a
[profile-replicate-publish-slave-information]
_update_hash_filename_ = templates/replicate-publish-slave-information.cfg.in
md5sum = df304a8aee87b6f2425241016a48f7a5
[profile-caddy-frontend-configuration]
_update_hash_filename_ = templates/Caddyfile.in
md5sum = fdf46b1dee6ea6b91b9aa9e322a0530d
[template-frontend-haproxy-configuration]
_update_hash_filename_ = templates/frontend-haproxy.cfg.in
md5sum = 6fd120cdbdacecb2b7b93c8d1237e126
[template-frontend-haproxy-crt-list]
_update_hash_filename_ = templates/frontend-haproxy-crt-list.in
md5sum = 251c7d8c775db20381c8f0b5bb220f75
[template-not-found-html]
_update_hash_filename_ = templates/notfound.html
......@@ -50,7 +54,7 @@ md5sum = 13cd08d630cc51666a9f7e469fb6ea52
[template-backend-haproxy-configuration]
_update_hash_filename_ = templates/backend-haproxy.cfg.in
md5sum = 5e126be0f74d8ae390a5594e1e912a59
md5sum = db8c3cc4dcb0282c8316742ecd7f4761
[template-empty]
_update_hash_filename_ = templates/empty.in
......@@ -104,6 +108,10 @@ md5sum = 38792c2dceae38ab411592ec36fff6a8
filename = instance-kedifa.cfg.in
md5sum = eab5ae579471ca86b40bd2da3b53fefa
[template-frontend-haproxy-rsyslogd-conf]
_update_hash_filename_ = templates/frontend-haproxy-rsyslogd.conf.in
md5sum = 420f66264d4cd24070a5a7b325e09ccd
[template-backend-haproxy-rsyslogd-conf]
_update_hash_filename_ = templates/backend-haproxy-rsyslogd.conf.in
md5sum = 3336d554661b138dcef97b1d1866803c
......
......@@ -16,13 +16,7 @@ parts =
caucase-updater-promise
backend-client-caucase-updater
backend-client-caucase-updater-promise
frontend-caddy-graceful
port-redirection
promise-frontend-caddy-configuration
promise-caddy-frontend-v4-https
promise-caddy-frontend-v4-http
promise-caddy-frontend-v6-https
promise-caddy-frontend-v6-http
promise-logrotate-setup
trafficserver-launcher
......@@ -37,13 +31,23 @@ parts =
trafficserver-promise-listen-port
trafficserver-promise-cache-availability
cron-entry-logrotate-trafficserver
## Monitor for Caddy
## Monitor
monitor-base
monitor-ats-cache-stats-wrapper
monitor-traffic-summary-last-stats-wrapper
monitor-caddy-server-status-wrapper
monitor-verify-re6st-connectivity
frontend-haproxy-rsyslogd-configuration
frontend-haproxy-rsyslogd
logrotate-entry-frontend-haproxy
frontend-haproxy
frontend-haproxy-graceful
promise-frontend-frontend-haproxy-configuration
promise-frontend-haproxy-v4-https
promise-frontend-haproxy-v4-http
promise-frontend-haproxy-v6-https
promise-frontend-haproxy-v6-http
backend-haproxy-rsyslogd-configuration
backend-haproxy-rsyslogd
logrotate-entry-backend-haproxy
......@@ -77,6 +81,7 @@ backup = ${:srv}/backup
log = ${:var}/log
run = ${:var}/run
backend-haproxy-rsyslogd-spool = ${:run}/backend-haproxy-rsyslogd-spool
frontend-haproxy-rsyslogd-spool = ${:run}/frontend-haproxy-rsyslogd-spool
service = ${:etc}/service
etc-run = ${:etc}/run
......@@ -105,8 +110,6 @@ single-custom-personal = dynamic-custom-personal-profile-slave-list:rendered
[frontend-configuration]
ip-access-certificate = ${self-signed-ip-access:certificate}
caddy-ipv6 = {{ instance_parameter_dict['ipv6-random'] }}
caddy-https-port = ${configuration:port}
slave-introspection-configuration = ${directory:etc}/slave-introspection-httpd-nginx.conf
slave-introspection-https-port = ${configuration:slave-introspection-https-port}
slave-introspection-secure_access = ${slave-introspection-frontend:connection-secure_access}
......@@ -118,7 +121,7 @@ recipe = plone.recipe.command
update-command = ${:command}
ipv6 = ${slap-configuration:ipv6-random}
ipv4 = {{instance_parameter_dict['ipv4-random']}}
certificate = ${caddy-directory:master-autocert-dir}/ip-access-${:ipv6}-${:ipv4}.crt
certificate = ${frontend-directory:master-autocert-dir}/ip-access-${:ipv6}-${:ipv4}.crt
{#- Can be stopped on error, as does not rely on self provided service #}
stop-on-error = True
command =
......@@ -142,7 +145,7 @@ recipe = plone.recipe.command
update-command = ${:command}
ipv6 = ${slap-configuration:ipv6-random}
ipv4 = {{instance_parameter_dict['ipv4-random']}}
certificate = ${caddy-directory:master-autocert-dir}/fallback-access.crt
certificate = ${frontend-directory:master-autocert-dir}/fallback-access.crt
{#- Can be stopped on error, as does not rely on self provided service #}
stop-on-error = True
command =
......@@ -176,6 +179,9 @@ context =
[software-release-path]
template-empty = {{ software_parameter_dict['template_empty'] }}
template-default-slave-virtualhost = {{ software_parameter_dict['template_default_slave_virtualhost'] }}
template-frontend-haproxy-configuration = {{ software_parameter_dict['template_frontend_haproxy_configuration'] }}
template-frontend-haproxy-crt-list = {{ software_parameter_dict['template_frontend_haproxy_crt_list'] }}
template-frontend-haproxy-rsyslogd-conf = {{ software_parameter_dict['template_frontend_haproxy_rsyslogd_conf'] }}
template-backend-haproxy-configuration = {{ software_parameter_dict['template_backend_haproxy_configuration'] }}
template-backend-haproxy-rsyslogd-conf = {{ software_parameter_dict['template_backend_haproxy_rsyslogd_conf'] }}
......@@ -286,43 +292,50 @@ organizational-unit = {{ instance_parameter_dict['configuration.frontend-name']
backend-client-caucase-url = {{ slapparameter_dict['backend-client-caucase-url'] }}
partition_ipv6 = ${slap-configuration:ipv6-random}
extra-context =
key caddy_configuration_directory caddy-directory:slave-configuration
key backend_client_caucase_url :backend-client-caucase-url
import urlparse_module urlparse
import furl_module furl
import urllib_module urllib
key master_key_download_url :master_key_download_url
key autocert caddy-directory:autocert
key caddy_log_directory caddy-directory:slave-log
key expose_csr_id_organization :organization
key expose_csr_id_organizational_unit :organizational-unit
key global_ipv6 slap-configuration:ipv6-random
key empty_template software-release-path:template-empty
key template_default_slave_configuration software-release-path:template-default-slave-virtualhost
key software_type :software_type
key frontend_lazy_graceful_reload frontend-caddy-lazy-graceful:rendered
key frontend_lazy_graceful_reload frontend-haproxy-lazy-graceful:rendered
key monitor_base_url monitor-instance-parameter:monitor-base-url
key custom_ssl_directory caddy-directory:custom-ssl-directory
# BBB: SlapOS Master non-zero knowledge BEGIN
key apache_certificate apache-certificate:rendered
# BBB: SlapOS Master non-zero knowledge END
## frontend haproxy
key template_frontend_haproxy_configuration software-release-path:template-frontend-haproxy-configuration
key template_frontend_haproxy_crt_list software-release-path:template-frontend-haproxy-crt-list
## backend haproxy
key template_backend_haproxy_configuration software-release-path:template-backend-haproxy-configuration
## Configuration passed by section
section frontend_directory frontend-directory
section configuration configuration
section frontend_haproxy_configuration frontend-haproxy-configuration
section backend_haproxy_configuration backend-haproxy-configuration
section instance_parameter_dict instance-parameter-section
section frontend_configuration frontend-configuration
section caddy_configuration caddy-configuration
section kedifa_configuration kedifa-configuration
section software_parameter_dict software-parameter-section
# Deploy Caddy Frontend with Jinja power
[dynamic-caddy-frontend-template]
< = jinja2-template-base
template = {{ software_parameter_dict['template_caddy_frontend_configuration'] }}
rendered = ${caddy-configuration:frontend-configuration}
local_ipv4 = {{ dumps(instance_parameter_dict['ipv4-random']) }}
# Deploy frontend with Jinja power
[frontend-haproxy-rsyslogd-config]
log-socket = ${directory:run}/fhlog.sck
log-file = ${directory:log}/frontend-haproxy.log
pid-file = ${directory:run}/frontend-haproxy-rsyslogd.pid
spool-directory = ${directory:frontend-haproxy-rsyslogd-spool}
graceful-command = kill -HUP $(cat ${:pid-file})
slave-log-directory = ${frontend-directory:slave-log}
[frontend-haproxy-rsyslogd-configuration]
<= jinja2-template-base
template = ${software-release-path:template-frontend-haproxy-rsyslogd-conf}
rendered = ${directory:etc}/frontend-haproxy-rsyslogd.conf
extra-context =
key instance_home buildout:directory
key master_certificate caddy-configuration:master-certificate
......@@ -340,59 +353,39 @@ extra-context =
# BBB: SlapOS Master non-zero knowledge BEGIN
key apache_certificate apache-certificate:rendered
# BBB: SlapOS Master non-zero knowledge END
section configuration frontend-haproxy-rsyslogd-config
[caddy-wrapper]
recipe = slapos.recipe.template:jinja2
template = inline:
#!/bin/sh
export CADDYPATH=${directory:frontend_cluster}
ulimit -n $(ulimit -Hn)
exec {{ software_parameter_dict['caddy'] }} \
-conf ${dynamic-caddy-frontend-template:rendered} \
-log ${caddy-configuration:error-log} \
-log-roll-mb 0 \
{% if instance_parameter_dict['configuration.global-disable-http2'].lower() in TRUE_VALUES %}
-http2=false \
{% else %}
-http2=true \
{% endif %}
-grace {{ instance_parameter_dict['configuration.mpm-graceful-shutdown-timeout'] }}s \
-disable-http-challenge \
-disable-tls-alpn-challenge \
"$@"
rendered = ${directory:bin}/caddy-wrapper
mode = 0755
[caddy-frontend]
[frontend-haproxy-rsyslogd]
recipe = slapos.cookbook:wrapper
command-line = ${caddy-wrapper:rendered} -pidfile ${caddy-configuration:pid-file}
wrapper-path = ${directory:service}/frontend_caddy
command-line = {{ software_parameter_dict['rsyslogd_executable'] }} -i ${frontend-haproxy-rsyslogd-config:pid-file} -n -f ${frontend-haproxy-rsyslogd-configuration:rendered}
wrapper-path = ${directory:service}/frontend-haproxy-rsyslogd
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
hash-files = ${caddy-wrapper:rendered}
[not-found-html]
recipe = plone.recipe.command
update-command = ${:command}
filename = notfound.html
command = ln -sf {{ software_parameter_dict['template_not_found_html'] }} ${caddy-directory:document-root}/${:filename}
[caddy-directory]
recipe = slapos.cookbook:mkdirectory
document-root = ${directory:srv}/htdocs
slave-configuration = ${directory:etc}/caddy-slave-conf.d/
slave-log = ${directory:log}/httpd
autocert = ${directory:srv}/autocert
master-autocert-dir = ${:autocert}/master-autocert
custom-ssl-directory = ${:slave-configuration}/ssl
[logrotate-entry-frontend-haproxy]
<= logrotate-entry-base
name = frontend-haproxy
log = ${frontend-haproxy-rsyslogd-config:log-file}
rotate-num = ${configuration:rotate-num}
# Note: Slaves do not define their own reload, as this would be repeated,
# because sharedscripts work per entry, and each slave needs its own
# olddir
# Here we trust that there will be something to be rotated with error
# or access log, and that this will trigger postrotate script.
post = ${frontend-haproxy-rsyslogd-lazy-graceful:rendered} &
delaycompress =
[caddy-configuration]
frontend-configuration = ${directory:etc}/Caddyfile
[frontend-haproxy-configuration]
file = ${directory:etc}/frontend-haproxy.cfg
crt-list = ${directory:etc}/frontend-haproxy-crt-list.txt
log-socket = ${frontend-haproxy-rsyslogd-config:log-socket}
access-log = ${directory:log}/frontend-access.log
error-log = ${directory:log}/frontend-error.log
pid-file = ${directory:run}/httpd.pid
frontend-graceful-command = ${frontend-caddy-validate:rendered} && kill -USR1 $(cat ${:pid-file})
not-found-file = ${caddy-directory:document-root}/${not-found-html:filename}
master-certificate = ${caddy-directory:master-autocert-dir}/master.pem
frontend-graceful-command = ${frontend-haproxy-validate:rendered} && kill -USR2 $(cat ${:pid-file})
not-found-file = ${frontend-directory:document-root}/${not-found-html:filename}
master-certificate = ${frontend-directory:master-autocert-dir}/master.pem
http-port = ${configuration:plain_http_port}
https-port = ${configuration:port}
# Communication with ATS
cache-port = ${trafficserver-variable:input-port}
# slave instrspection
......@@ -400,6 +393,22 @@ slave-introspection-access-log = ${directory:log}/slave-introspection-access.log
slave-introspection-error-log = ${directory:log}/slave-introspection-error.log
slave-introspection-pid-file = ${directory:run}/slave-introspection.pid
slave-introspection-graceful-command = ${slave-introspection-validate:rendered} && kill -HUP $(cat ${:slave-introspection-pid-file})
local_ipv4 = {{ dumps(instance_parameter_dict['ipv4-random']) }}
[not-found-html]
recipe = plone.recipe.command
update-command = ${:command}
filename = notfound.html
command = ln -sf {{ software_parameter_dict['template_not_found_html'] }} ${frontend-directory:document-root}/${:filename}
[frontend-directory]
recipe = slapos.cookbook:mkdirectory
document-root = ${directory:srv}/htdocs
slave-configuration = ${directory:etc}/frontend-haproxy.d/
slave-log = ${directory:log}/httpd
autocert = ${directory:srv}/autocert
master-autocert-dir = ${:autocert}/master-autocert
custom-ssl-directory = ${:slave-configuration}/ssl
# BBB: SlapOS Master non-zero knowledge BEGIN
[get-self-signed-fallback-access]
......@@ -421,19 +430,6 @@ context =
rendered = ${directory:bbb-ssl-dir}/frontend.crt
# BBB: SlapOS Master non-zero knowledge END
[logrotate-entry-caddy]
<= logrotate-entry-base
name = caddy
log = ${caddy-configuration:error-log} ${caddy-configuration:access-log}
rotate-num = ${configuration:rotate-num}
# Note: Slaves do not define their own reload, as this would be repeated,
# because sharedscripts work per entry, and each slave needs its own
# olddir
# Here we trust that there will be something to be rotated with error
# or access log, and that this will trigger postrotate script.
post = ${frontend-caddy-lazy-graceful:rendered} &
delaycompress =
#################
# Trafficserver
#################
......@@ -581,14 +577,14 @@ command = ${trafficserver-rotate-script:rendered}
### End of ATS sections
### Caddy Graceful and promises
[frontend-caddy-configuration-state]
### Frontend Graceful and promises
[frontend-haproxy-configuration-state]
< = jinja2-template-base
template = {{ software_parameter_dict['template_configuration_state_script'] }}
rendered = ${directory:bin}/${:_buildout_section_name_}
mode = 0700
path_list = ${caddy-configuration:frontend-configuration} ${caddy-directory:slave-configuration}/*.conf ${caddy-directory:master-autocert-dir}/*.key ${caddy-directory:master-autocert-dir}/*.crt ${caddy-directory:master-autocert-dir}/*.pem ${caddy-directory:autocert}/*.pem ${caddy-directory:custom-ssl-directory}/*.proxy_ca_crt ${directory:bbb-ssl-dir}/*.crt
path_list = ${frontend-haproxy-configuration:file} ${frontend-haproxy-configuration:crt-list} ${frontend-directory:master-autocert-dir}/*.key ${frontend-directory:master-autocert-dir}/*.crt ${frontend-directory:master-autocert-dir}/*.pem ${frontend-directory:autocert}/*.pem ${frontend-directory:custom-ssl-directory}/*.proxy_ca_crt ${directory:bbb-ssl-dir}/*.crt
sha256sum = {{ software_parameter_dict['sha256sum'] }}
extra-context =
......@@ -596,47 +592,59 @@ extra-context =
key sha256sum :sha256sum
key signature_file :signature_file
[frontend-caddy-configuration-state-graceful]
< = frontend-caddy-configuration-state
[frontend-haproxy-configuration-state-graceful]
< = frontend-haproxy-configuration-state
signature_file = ${directory:run}/graceful_configuration_state_signature
[frontend-caddy-configuration-state-validate]
< = frontend-caddy-configuration-state
[frontend-haproxy-configuration-state-validate]
< = frontend-haproxy-configuration-state
signature_file = ${directory:run}/validate_configuration_state_signature
[frontend-caddy-graceful]
[frontend-haproxy-graceful]
< = jinja2-template-base
template = {{ software_parameter_dict['template_graceful_script'] }}
rendered = ${directory:etc-run}/frontend-caddy-safe-graceful
rendered = ${directory:etc-run}/frontend-haproxy-safe-graceful
mode = 0700
extra-context =
key graceful_reload_command caddy-configuration:frontend-graceful-command
key caddy_configuration_state frontend-caddy-configuration-state-graceful:rendered
key graceful_reload_command frontend-haproxy-configuration:frontend-graceful-command
key caddy_configuration_state frontend-haproxy-configuration-state-graceful:rendered
[frontend-caddy-validate]
[frontend-haproxy-validate]
< = jinja2-template-base
template = {{ software_parameter_dict['template_validate_script'] }}
rendered = ${directory:bin}/frontend-caddy-validate
rendered = ${directory:bin}/frontend-haproxy-validate
mode = 0700
last_state_file = ${directory:run}/caddy_configuration_last_state
validate_command = ${caddy-wrapper:rendered} -validate
last_state_file = ${directory:run}/frontend_haproxy_configuration_last_state
validate_command = {{ software_parameter_dict['haproxy_executable'] }} -f ${frontend-haproxy-configuration:file} -c
extra-context =
key validate_command :validate_command
key configuration_state_command frontend-caddy-configuration-state-validate:rendered
key configuration_state_command frontend-haproxy-configuration-state-validate:rendered
key last_state_file :last_state_file
[frontend-caddy-lazy-graceful]
[backend-haproxy-validate]
<= jinja2-template-base
template = {{ software_parameter_dict['template_validate_script'] }}
rendered = ${directory:bin}/backend-haproxy-validate
mode = 0700
last_state_file = ${directory:run}/backend_haproxy_configuration_last_state
validate_command = {{ software_parameter_dict['haproxy_executable'] }} -f ${backend-haproxy-configuration:file} -c
extra-context =
key validate_command :validate_command
key configuration_state_command backend-haproxy-configuration-state-validate:rendered
key last_state_file :last_state_file
[frontend-haproxy-lazy-graceful]
< = jinja2-template-base
template = {{ software_parameter_dict['template_caddy_lazy_script_call'] }}
rendered = ${directory:bin}/frontend-caddy-lazy-graceful
rendered = ${directory:bin}/frontend-haproxy-lazy-graceful
mode = 0700
pid-file = ${directory:run}/lazy-graceful.pid
wait_time = 60
extra-context =
key pid_file :pid-file
key wait_time :wait_time
key lazy_command caddy-configuration:frontend-graceful-command
key lazy_command frontend-haproxy-configuration:frontend-graceful-command
# Promises checking configuration:
[promise-helper-last-configuration-state]
......@@ -646,41 +654,41 @@ rendered = ${directory:bin}/frontend-read-last-configuration-state
mode = 0700
content =
#!/bin/sh
exit `cat ${frontend-caddy-validate:last_state_file}`
exit `cat ${frontend-haproxy-validate:last_state_file}`
context =
key content :content
[promise-frontend-caddy-configuration]
[promise-frontend-frontend-haproxy-configuration]
<= monitor-promise-base
module = validate_frontend_configuration
name = frontend-caddy-configuration-promise.py
name = frontend-frontend-haproxy-configuration-promise.py
config-verification-script = ${promise-helper-last-configuration-state:rendered}
[promise-caddy-frontend-v4-https]
[promise-frontend-haproxy-v4-https]
<= monitor-promise-base
module = check_socket_listening
name = caddy_frontend_ipv4_https.py
name = frontend_haproxy_ipv4_https.py
config-host = {{ instance_parameter_dict['ipv4-random'] }}
config-port = ${configuration:port}
[promise-caddy-frontend-v4-http]
[promise-frontend-haproxy-v4-http]
<= monitor-promise-base
module = check_socket_listening
name = caddy_frontend_ipv4_http.py
name = frontend_haproxy_ipv4_http.py
config-host = {{ instance_parameter_dict['ipv4-random'] }}
config-port = ${configuration:plain_http_port}
[promise-caddy-frontend-v6-https]
[promise-frontend-haproxy-v6-https]
<= monitor-promise-base
module = check_socket_listening
name = caddy_frontend_ipv6_https.py
name = frontend_haproxy_ipv6_https.py
config-host = {{ instance_parameter_dict['ipv6-random'] }}
config-port = ${configuration:port}
[promise-caddy-frontend-v6-http]
[promise-frontend-haproxy-v6-http]
<= monitor-promise-base
module = check_socket_listening
name = caddy_frontend_ipv6_http.py
name = frontend_haproxy_ipv6_http.py
config-host = {{ instance_parameter_dict['ipv6-random'] }}
config-port = ${configuration:plain_http_port}
......@@ -720,6 +728,24 @@ statistic-password = ${monitor-htpasswd:passwd}
statistic-identification = {{ instance_parameter_dict['configuration.frontend-name'] + ' @ ' + slapparameter_dict['cluster-identification'] }}
statistic-frontend-secure_access = ${backend-haproxy-statistic-frontend:connection-secure_access}
[frontend-haproxy]
recipe = slapos.cookbook:wrapper
command-line = {{ software_parameter_dict['haproxy_executable'] }} -f ${frontend-haproxy-configuration:file}
wrapper-path = ${directory:service}/frontend-haproxy
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
[frontend-haproxy-rsyslogd-lazy-graceful]
< = jinja2-template-base
template = {{ software_parameter_dict['template_caddy_lazy_script_call'] }}
rendered = ${directory:bin}/frontend-haproxy-rsyslogd-lazy-graceful
mode = 0700
pid-file = ${directory:run}/frontend-haproxy-rsyslogd-lazy-graceful.pid
wait_time = 60
extra-context =
key pid_file :pid-file
key wait_time :wait_time
key lazy_command frontend-haproxy-rsyslogd-config:graceful-command
[backend-haproxy]
recipe = slapos.cookbook:wrapper
command-line = {{ software_parameter_dict['haproxy_executable'] }} -f ${backend-haproxy-configuration:file}
......@@ -783,18 +809,6 @@ extra-context =
key graceful_reload_command backend-haproxy-configuration:graceful-command
key caddy_configuration_state backend-haproxy-configuration-state-graceful:rendered
[backend-haproxy-validate]
<= jinja2-template-base
template = {{ software_parameter_dict['template_validate_script'] }}
rendered = ${directory:bin}/backend-haproxy-validate
mode = 0700
last_state_file = ${directory:run}/backend_haproxy_configuration_last_state
validate_command = {{ software_parameter_dict['haproxy_executable'] }} -f ${backend-haproxy-configuration:file} -c
extra-context =
key validate_command :validate_command
key configuration_state_command backend-haproxy-configuration-state-validate:rendered
key last_state_file :last_state_file
[promise-backend-haproxy-configuration]
<= monitor-promise-base
module = validate_frontend_configuration
......@@ -818,7 +832,7 @@ log-file = ${directory:log}/backend-haproxy.log
pid-file = ${directory:run}/backend-haproxy-rsyslogd.pid
spool-directory = ${directory:backend-haproxy-rsyslogd-spool}
graceful-command = kill -HUP $(cat ${:pid-file})
caddy-log-directory = ${caddy-directory:slave-log}
caddy-log-directory = ${frontend-directory:slave-log}
[backend-haproxy-rsyslogd-configuration]
<= jinja2-template-base
......@@ -868,15 +882,6 @@ command = export TS_ROOT=${buildout:directory} && echo "<pre>$({{ software_param
extra-context =
key content monitor-ats-cache-stats-wrapper:command
[monitor-caddy-server-status-wrapper]
< = jinja2-template-base
template = {{ software_parameter_dict['template_wrapper'] }}
rendered = ${directory:bin}/monitor-caddy-server-status-wrapper
mode = 0700
command = {{ software_parameter_dict['curl'] }}/bin/curl -s http://{{ instance_parameter_dict['ipv4-random'] }}:${configuration:plain_http_port}/server-status -u ${monitor-instance-parameter:username}:${monitor-htpasswd:passwd} 2>&1
extra-context =
key content monitor-caddy-server-status-wrapper:command
[monitor-ats-cache-stats-config]
< = jinja2-template-base
template = {{ software_parameter_dict['template_empty'] }}
......@@ -950,7 +955,7 @@ rendered = ${directory:etc-run}/slave-introspection-safe-graceful
mode = 0700
extra-context =
key graceful_reload_command caddy-configuration:slave-introspection-graceful-command
key graceful_reload_command frontend-haproxy-configuration:slave-introspection-graceful-command
key caddy_configuration_state slave-introspection-configuration-state-graceful:rendered
[slave-introspection-validate]
......@@ -992,9 +997,9 @@ config-port = ${frontend-configuration:slave-introspection-https-port}
[logrotate-entry-slave-introspection]
<= logrotate-entry-base
name = slave-introspection
log = ${caddy-configuration:slave-introspection-access-log} ${caddy-configuration:slave-introspection-error-log}
log = ${frontend-haproxy-configuration:slave-introspection-access-log} ${frontend-haproxy-configuration:slave-introspection-error-log}
rotate-num = ${configuration:rotate-num}
post = kill -USR1 $(cat ${caddy-configuration:slave-introspection-pid-file})
post = kill -USR2 $(cat ${frontend-haproxy-configuration:slave-introspection-pid-file})
delaycompress =
[promise-logrotate-setup]
......
......@@ -84,16 +84,6 @@
"title": "Disabled Cookies",
"type": "string"
},
"enable-http2": {
"default": "true",
"description": "Use HTTP2 Protocol for the site",
"enum": [
"true",
"false"
],
"title": "Enable HTTP2 Protocol",
"type": "string"
},
"https-url": {
"description": "HTTPS URL of the backend if it is different from url parameter",
"pattern": "^(http|https|ftp)://",
......@@ -209,11 +199,6 @@
"title": "HTTP Request timeout in seconds",
"type": "integer"
},
"ciphers": {
"description": "List of ciphers. Empty defaults to cluster list of ciphers, which by default are Caddy list of ciphers. See https://caddyserver.com/docs/tls for more information.",
"title": "Ordered space separated list of ciphers",
"type": "string"
},
"authenticate-to-backend": {
"description": "If set to true the frontend certificate will be used as authentication certificate to the backend. Note: backend might have to know the frontend CA, available with 'backend-client-caucase-url'.",
"enum": [
......
......@@ -3,7 +3,6 @@ extends =
buildout.hash.cfg
../../stack/slapos.cfg
../../component/dash/buildout.cfg
../../component/caddy/buildout.cfg
../../component/gzip/buildout.cfg
../../component/logrotate/buildout.cfg
../../component/trafficserver/buildout.cfg
......@@ -97,7 +96,9 @@ profile_slave_list = ${profile-slave-list:target}
# templates
template_backend_haproxy_configuration = ${template-backend-haproxy-configuration:target}
template_backend_haproxy_rsyslogd_conf = ${template-backend-haproxy-rsyslogd-conf:target}
template_caddy_frontend_configuration = ${profile-caddy-frontend-configuration:target}
template_frontend_haproxy_configuration = ${template-frontend-haproxy-configuration:target}
template_frontend_haproxy_crt_list = ${template-frontend-haproxy-crt-list:target}
template_frontend_haproxy_rsyslogd_conf = ${template-frontend-haproxy-rsyslogd-conf:target}
template_caddy_lazy_script_call = ${template-caddy-lazy-script-call:target}
template_configuration_state_script = ${template-configuration-state-script:target}
template_default_slave_virtualhost = ${template-default-slave-virtualhost:target}
......@@ -119,7 +120,6 @@ bin_directory = ${buildout:bin-directory}
sixtunnel = ${6tunnel:location}
nginx = ${nginx-output:nginx}
nginx_mime = ${nginx-output:mime}
caddy = ${caddy:output}
haproxy_executable = ${haproxy:location}/sbin/haproxy
rsyslogd_executable = ${rsyslogd:location}/sbin/rsyslogd
curl = ${curl:location}
......@@ -170,7 +170,10 @@ mode = 640
[profile-replicate-publish-slave-information]
<=download-template
[profile-caddy-frontend-configuration]
[template-frontend-haproxy-configuration]
<=download-template
[template-frontend-haproxy-crt-list]
<=download-template
[template-not-found-html]
......@@ -221,6 +224,9 @@ mode = 0644
[template-backend-haproxy-rsyslogd-conf]
<=download-template
[template-frontend-haproxy-rsyslogd-conf]
<=download-template
[versions]
# Modern KeDiFa requires zc.lockfile
zc.lockfile = 1.4
......
# Main caddy configuration file
import {{ slave_configuration_directory }}/*.conf
:{{ https_port }} {
tls {{ master_certificate }} {{ master_certificate }}
bind {{ local_ipv4 }}
status 404 /
log / {{ access_log }} "{remote} - {>REMOTE_USER} [{when}] \"{method} {uri} {proto}\" {status} {size} \"{>Referer}\" \"{>User-Agent}\" {latency_ms}" {
rotate_size 10000000
}
errors {{ error_log }} {
rotate_size 10000000
* {{ not_found_file }}
}
}
:{{ http_port }} {
bind {{ local_ipv4 }}
status 404 /
log / {{ access_log }} "{remote} - {>REMOTE_USER} [{when}] \"{method} {uri} {proto}\" {status} {size} \"{>Referer}\" \"{>User-Agent}\" {latency_ms}" {
rotate_size 10000000
}
errors {{ error_log }} {
rotate_size 10000000
* {{ not_found_file }}
}
}
# Access to server-status Caddy-style
https://[{{ global_ipv6 }}]:{{ https_port }}/server-status, https://{{ local_ipv4 }}:{{ https_port }}/server-status {
tls {{ frontend_configuration['ip-access-certificate'] }} {{ frontend_configuration['ip-access-certificate'] }}
bind {{ local_ipv4 }}
basicauth "{{ username }}" {{ password | trim }} {
"Server Status"
/
}
expvar
pprof
log / {{ access_log }} "{remote} - {>REMOTE_USER} [{when}] \"{method} {uri} {proto}\" {status} {size} \"{>Referer}\" \"{>User-Agent}\" {latency_ms}" {
rotate_size 10000000
}
errors {{ error_log }} {
rotate_size 10000000
* {{ not_found_file }}
}
}
......@@ -3,7 +3,7 @@
{%- set backend_slave_list = [] %}
{%- set frontend_slave_list = [] %}
{%- set part_list = [] %}
{%- set cache_port = caddy_configuration.get('cache-port') %}
{%- set cache_port = frontend_haproxy_configuration.get('cache-port') %}
{%- set cache_access = "http://%s:%s/HTTP" % (instance_parameter_dict['ipv4-random'], cache_port) %}
{%- set ssl_cache_access = "http://%s:%s/HTTPS" % (instance_parameter_dict['ipv4-random'], cache_port) %}
{%- set backend_haproxy_http_url = 'http://%s:%s' % (instance_parameter_dict['ipv4-random'], backend_haproxy_configuration['http-port']) %}
......@@ -17,9 +17,9 @@
{%- do slave_instance_list.extend(json_module.loads(configuration['extra_slave_instance_list'])) %}
{%- endif %}
{%- if master_key_download_url %}
{%- do kedifa_updater_mapping.append((master_key_download_url, caddy_configuration['master-certificate'], apache_certificate)) %}
{%- do kedifa_updater_mapping.append((master_key_download_url, frontend_haproxy_configuration['master-certificate'], apache_certificate)) %}
{%- else %}
{%- do kedifa_updater_mapping.append(('notreadyyet', caddy_configuration['master-certificate'], apache_certificate)) %}
{%- do kedifa_updater_mapping.append(('notreadyyet', frontend_haproxy_configuration['master-certificate'], apache_certificate)) %}
{%- endif %}
{%- if kedifa_configuration['slave_kedifa_information'] %}
{%- set slave_kedifa_information = json_module.loads(kedifa_configuration['slave_kedifa_information']) %}
......@@ -52,7 +52,10 @@ context =
{#- * setup defaults to simplify other profiles #}
{#- * stabilise values for backend #}
{%- for key, prefix in [('url', 'http_backend'), ('https-url', 'https_backend')] %}
{%- set parsed = urlparse_module.urlparse(slave_instance.get(key, '').strip()) %}
{#- XXX BELOW IS BAD #}
{#- It shall connect to backend haproxy or ATS in case of cached slave #}
{%- set parsed = urlparse_module.urlparse((slave_instance.get(key, '') or slave_instance.get('url', '')).strip()) %}
{#- XXX ABOVE IS BAD #}
{%- set info_dict = {'scheme': parsed.scheme, 'hostname': parsed.hostname, 'port': parsed.port or DEFAULT_PORT[parsed.scheme], 'path': parsed.path, 'fragment': parsed.fragment, 'query': parsed.query} %}
{%- do slave_instance.__setitem__(prefix, info_dict) %}
{%- endfor %}
......@@ -97,7 +100,8 @@ context =
{%- set enable_cache = (slave_instance['enable_cache'] and slave_type != 'redirect') %}
{%- set slave_reference = slave_instance.get('slave_reference') %}
{%- set slave_kedifa = slave_kedifa_information.get(slave_reference) %}
{#- Setup backend URLs for front facing Caddy #}
{#- Setup backend URLs for frontend-haproxy #}
{%- if slave_type == 'redirect' %}
{%- do slave_instance.__setitem__('backend-http-url', slave_instance.get('url', '').rstrip('/')) %}
{%- if slave_instance.get('https-url') %}
......@@ -120,12 +124,24 @@ context =
{%- do slave_instance.__setitem__('backend-https-url', backend_haproxy_https_url) %}
{%- endif %}
{%- endif %}
{%- for frontend_key, key in [('backend-http-info', 'backend-http-url'), ('backend-https-info', 'backend-https-url')] %}
{%- if key in slave_instance %}
{%- set parsed = urlparse_module.urlparse(slave_instance[key]) %}
{%- do slave_instance.__setitem__(frontend_key, {
'scheme': parsed.scheme,
'hostname': parsed.hostname,
'port': parsed.port or DEFAULT_PORT[parsed.scheme],
'path': parsed.path,
'fragment': parsed.fragment,
'query': parsed.query }) %}
{%- endif %}
{%- endfor %}
{%- if slave_kedifa %}
{%- set key_download_url = slave_kedifa.get('key-download-url') %}
{%- else %}
{%- set key_download_url = 'notreadyyet' %}
{%- endif %}
{%- set slave_section_title = 'dynamic-template-slave-instance-%s' % slave_reference %}
{%- set slave_parameter_dict = generic_instance_parameter_dict.copy() %}
{%- set slave_publish_dict = {} %}
{%- set slave_configuration_section_name = 'slave-instance-%s-configuration' % slave_reference %}
......@@ -136,7 +152,6 @@ context =
{%- set slave_ln_section = slave_reference + "-ln" %}
{#- extend parts #}
{%- do part_list.extend([slave_ln_section]) %}
{%- do part_list.extend([slave_section_title]) %}
{%- set slave_log_folder = '${logrotate-directory:logrotate-backup}/' + slave_reference + "-logs" %}
{#- Pass backend timeout values #}
{%- for key in ['backend-connect-timeout', 'backend-connect-retries', 'request-timeout', 'authenticate-to-backend'] %}
......@@ -175,11 +190,9 @@ context =
{%- do slave_instance.__setitem__('health-check-http-path', '') %}
{%- endif %} {# if slave_instance['health-check'] #}
{#- Set Up log files #}
{%- do slave_parameter_dict.__setitem__('access_log', '/'.join([caddy_log_directory, '%s_access_log' % slave_reference])) %}
{%- do slave_parameter_dict.__setitem__('error_log', '/'.join([caddy_log_directory, '%s_error_log' % slave_reference])) %}
{%- do slave_parameter_dict.__setitem__('backend_log', '/'.join([caddy_log_directory, '%s_backend_log' % slave_reference])) %}
{%- do slave_parameter_dict.__setitem__('access_log', '/'.join([frontend_directory['slave-log'], '%s_access_log' % slave_reference])) %}
{%- do slave_parameter_dict.__setitem__('backend_log', '/'.join([frontend_directory['slave-log'], '%s_backend_log' % slave_reference])) %}
{%- do slave_instance.__setitem__('access_log', slave_parameter_dict.get('access_log')) %}
{%- do slave_instance.__setitem__('error_log', slave_parameter_dict.get('error_log')) %}
{%- do slave_instance.__setitem__('backend_log', slave_parameter_dict.get('backend_log')) %}
{#- Add slave log directory to the slave log access dict #}
{%- do slave_log_dict.__setitem__(slave_reference, slave_log_folder) %}
......@@ -241,7 +254,7 @@ log-directory = {{ '${slave-log-directory-dict:' + slave_reference + '}' }}
[{{slave_logrotate_section}}]
<= logrotate-entry-base
name = ${:_buildout_section_name_}
log = {{slave_parameter_dict.get('access_log')}} {{slave_parameter_dict.get('error_log')}} {{slave_parameter_dict.get('backend_log')}}
log = {{slave_parameter_dict.get('access_log')}} {{slave_parameter_dict.get('backend_log')}}
backup = {{ '${' + slave_log_directory_section + ':log-directory}' }}
rotate-num = {{ dumps('' ~ configuration['rotate-num']) }}
# disable delayed compression, as log filenames shall be stable
......@@ -253,20 +266,22 @@ delaycompress =
recipe = plone.recipe.command
stop-on-error = false
log-directory = {{ '${' + slave_logrotate_section + ':backup}' }}
command = ln -sf {{slave_parameter_dict.get('error_log')}} ${:log-directory}/error.log && ln -sf {{slave_parameter_dict.get('access_log')}} ${:log-directory}/access.log && ln -sf {{slave_parameter_dict.get('backend_log')}} ${:log-directory}/backend.log
command =
ln -sf {{slave_parameter_dict.get('access_log')}} ${:log-directory}/access.log
ln -sf {{slave_parameter_dict.get('backend_log')}} ${:log-directory}/backend.log
{#- Set password for slave #}
[{{slave_password_section}}]
recipe = slapos.cookbook:generate.password
storage-path = {{caddy_configuration_directory}}/.{{slave_reference}}.passwd
storage-path = {{ frontend_directory['slave-configuration'] }}/.{{slave_reference}}.passwd
bytes = 8
[{{ slave_htpasswd_section }}]
recipe = plone.recipe.command
{#- Can be stopped on error, as does not rely on self provided service #}
stop-on-error = True
file = {{ caddy_configuration_directory }}/.{{ slave_reference }}.htpasswd
file = {{ frontend_directory['slave-configuration'] }}/.{{ slave_reference }}.htpasswd
{#- update-command is not needed, as if the ${:password} would change, the whole part will be recalculated #}
password = {{ '${' + slave_password_section + ':passwd}' }}
command = {{ software_parameter_dict['htpasswd'] }} -cb ${:file} {{ slave_reference.lower() }} ${:password}
......@@ -275,14 +290,15 @@ command = {{ software_parameter_dict['htpasswd'] }} -cb ${:file} {{ slave_refere
{#- Set Slave Certificates if needed #}
{#- Set certificate key for custom configuration #}
{%- set cert_name = slave_reference.replace('-','.') + '.pem' %}
{%- set certificate = '%s/%s' % (autocert, cert_name) %}
{%- set certificate = '%s/%s' % (frontend_directory['autocert'], cert_name) %}
{%- do slave_parameter_dict.__setitem__('certificate', certificate )%}
{%- do slave_instance.__setitem__('certificate', certificate )%}
{#- Set ssl certificates for each slave #}
{%- for cert_name in ('ssl_csr', 'ssl_proxy_ca_crt', 'health-check-failover-ssl-proxy-ca-crt')%}
{%- set cert_file_key = 'path_to_' + cert_name %}
{%- if cert_name in slave_instance %}
{%- set cert_title = '%s-%s' % (slave_reference, cert_name.replace('ssl_', '')) %}
{%- set cert_file = '/'.join([custom_ssl_directory, cert_title.replace('-','.')]) %}
{%- set cert_file = '/'.join([frontend_directory['custom-ssl-directory'], cert_title.replace('-','.')]) %}
{%- do part_list.append(cert_title) %}
{%- do slave_parameter_dict.__setitem__(cert_name, cert_file) %}
{%- do slave_instance.__setitem__(cert_file_key, cert_file) %}
......@@ -317,7 +333,7 @@ cert-content = {{ dumps(slave_instance.get('ssl_crt') + '\n' + slave_instance.ge
extra-context =
key content :cert-content
{%- else %}
{%- do kedifa_updater_mapping.append((key_download_url, certificate, caddy_configuration['master-certificate'])) %}
{%- do kedifa_updater_mapping.append((key_download_url, certificate, frontend_haproxy_configuration['master-certificate'])) %}
{%- endif %}
{#- BBB: SlapOS Master non-zero knowledge END #}
......@@ -335,18 +351,6 @@ local_ipv4 = {{ dumps('' ~ instance_parameter_dict['ipv4-random']) }}
{%- endif %}
{%- endfor %}
[{{ slave_section_title }}]
< = jinja2-template-base
rendered = {{ caddy_configuration_directory }}/${:filename}
template = {{ template_default_slave_configuration }}
extra-context =
section slave_parameter {{ slave_configuration_section_name }}
filename = {{ '%s.conf' % slave_reference }}
{{ '\n' }}
{%- set monitor_ipv6_test = slave_instance.get('monitor-ipv6-test', '') %}
{%- if monitor_ipv6_test %}
{%- set monitor_ipv6_section_title = 'check-%s-ipv6-packet-list-test' % slave_instance.get('slave_reference') %}
......@@ -420,10 +424,10 @@ global-ipv6 = {{ dumps(global_ipv6) }}
https-port = {{ frontend_configuration['slave-introspection-https-port'] }}
ip-access-certificate = {{ frontend_configuration.get('ip-access-certificate') }}
nginx-mime = {{ software_parameter_dict['nginx_mime'] }}
access-log = {{ dumps(caddy_configuration['slave-introspection-access-log']) }}
error-log = {{ dumps(caddy_configuration['slave-introspection-error-log']) }}
access-log = {{ dumps(frontend_haproxy_configuration['slave-introspection-access-log']) }}
error-log = {{ dumps(frontend_haproxy_configuration['slave-introspection-error-log']) }}
var = {{ directory['slave-introspection-var'] }}
pid = {{ caddy_configuration['slave-introspection-pid-file'] }}
pid = {{ frontend_haproxy_configuration['slave-introspection-pid-file'] }}
[slave-introspection-config]
<= jinja2-template-base
......@@ -468,8 +472,8 @@ recipe = slapos.cookbook:wrapper
command-line = {{ software_parameter_dict['kedifa-updater'] }}
--server-ca-certificate {{ kedifa_configuration['ca-certificate'] }}
--identity {{ kedifa_configuration['certificate'] }}
--master-certificate {{ caddy_configuration['master-certificate'] }}
--on-update "{{ caddy_configuration['frontend-graceful-command'] }}"
--master-certificate {{ frontend_haproxy_configuration['master-certificate'] }}
--on-update "{{ frontend_haproxy_configuration['frontend-graceful-command'] }}"
${kedifa-updater-mapping:file}
{{ kedifa_configuration['kedifa-updater-state-file'] }}
......@@ -480,7 +484,7 @@ hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
recipe = plone.recipe.command
{#- Can be stopped on error, as does not rely on self provided service but on service which comes from another partition #}
stop-on-error = True
command = {{ software_parameter_dict['kedifa-updater'] }} --prepare-only ${kedifa-updater-mapping:file} --on-update "{{ caddy_configuration['frontend-graceful-command'] }}"
command = {{ software_parameter_dict['kedifa-updater'] }} --prepare-only ${kedifa-updater-mapping:file} --on-update "{{ frontend_haproxy_configuration['frontend-graceful-command'] }}"
update-command = ${:command}
[kedifa-updater-mapping]
......@@ -493,6 +497,40 @@ template = inline:
rendered = ${:file}
##<Frontend haproxy>
[frontend-haproxy-slave-list]
list = {{ dumps(sorted(frontend_slave_list)) }}
[frontend-haproxy-crt-list]
<= jinja2-template-base
template = {{ template_frontend_haproxy_crt_list }}
rendered = ${frontend-haproxy-config:crt-list}
extra-context =
key frontend_slave_list frontend-haproxy-slave-list:list
section configuration frontend-haproxy-config
[frontend-haproxy-configuration]
< = jinja2-template-base
template = {{ template_frontend_haproxy_configuration }}
rendered = ${frontend-haproxy-config:file}
extra-context =
key frontend_slave_list frontend-haproxy-slave-list:list
key crt_list frontend-haproxy-crt-list:rendered
section configuration frontend-haproxy-config
[frontend-haproxy-config]
{%- for key, value in frontend_haproxy_configuration.items() %}
{{ key }} = {{ value }}
{%- endfor %}
local-ipv4 = {{ dumps('' ~ instance_parameter_dict['ipv4-random']) }}
global-ipv6 = ${slap-network-information:global-ipv6}
request-timeout = {{ dumps('' ~ configuration['request-timeout']) }}
autocert-directory = {{ frontend_directory['autocert'] }}
{#- backend-connect-timeout = {{ dumps('' ~ configuration['backend-connect-timeout']) }} XXX TODO #}
{#- backend-connect-retries = {{ dumps('' ~ configuration['backend-connect-retries']) }} XXX TODO #}
##</Frontend haproxy>
##<Backend haproxy>
[backend-haproxy-configuration]
< = jinja2-template-base
......@@ -530,7 +568,7 @@ command =
--send-csr {{ backend_haproxy_configuration['csr'] }} > ${:csr_work_path} && \
cut -d ' ' -f 1 ${:csr_work_path} > ${:csr_id_path}
##<Backend haproxy>
##</Backend haproxy>
[buildout]
extends =
......@@ -541,6 +579,7 @@ extends =
parts +=
kedifa-updater
kedifa-updater-run
frontend-haproxy-configuration
backend-haproxy-configuration
promise-logrotate-setup
{%- for part in part_list %}
......
......@@ -169,4 +169,4 @@ backend {{ slave_instance['slave_reference'] }}-{{ scheme }}-failover
{%- endif %}
{%- endif %}
{%- endfor %}
{%- endfor %}
{% endfor %}
{%- for slave in frontend_slave_list %}
{%- set entry_list = [] %}
{#- <crtfile> #}
{%- do entry_list.append(slave['certificate']) %}
{#- <snifilter> #}
{%- do entry_list.extend(slave['host_list']) %}
{{ ' '.join(entry_list) }}
{% endfor %}
{#- Fallback to default certificate -#}
{{ configuration['master-certificate'] }}
# END OF FILE
module(
load="imuxsock"
SysSock.Name="{{ configuration['log-socket'] }}")
# Just simply output the raw line without any additional information, as
# haproxy emits enough information by itself
# Also cut out first empty space in msg, which is related to rsyslogd
# internal and end up cutting on 8k, as it's default of $MaxMessageSize
template(name="rawoutput" type="string" string="%msg:2:8192%\n")
$ActionFileDefaultTemplate rawoutput
$FileCreateMode 0600
$DirCreateMode 0700
$Umask 0022
$WorkDirectory {{ configuration['spool-directory'] }}
# Setup logging per slave, by extracting the slave name from the log stream
{%- set regex = "^\\\\s*(\\\\S.*)-https{0,1} (.*)" %}
# Extract file name part from 1st match
template(name="extract_slave_name" type="string" string="%msg:R,ERE,1,FIELD:{{ regex }}--end%")
set $!slave_name = exec_template("extract_slave_name");
template(name="slave_output" type="string" string="{{ configuration['slave-log-directory'] }}/%$!slave_name%_access_log")
# Output only 2nd match, add the newline in the ned
template(name="haproxy_slave_line" type="string" string="%msg:R,ERE,2,FIELD:{{ regex }}--end%\n")
# React on match
if (re_match($msg, '{{ regex }}')) then {
action(type="omfile" dynaFile="slave_output" template="haproxy_slave_line")
stop
}
{#- emit all not catched messages to full log file #}
*.* {{ configuration['log-file'] }}
global
pidfile {{ configuration['pid-file'] }}
# master-worker is compatible with foreground with process management
master-worker
expose-experimental-directives
log {{ configuration['log-socket'] }} local0
defaults
mode http
log global
option httplog
{#- timeout queue XXX TODO #}
{#- timeout server XXX TODO #}
{#- timeout client XXX TODO #}
{#- timeout connect XXX TODO #}
{#- retries XXX TODO #}
{%- set SCHEME_PREFIX_MAPPING = { 'http': 'backend-http-info', 'https': 'backend-https-info'} %}
{%- macro frontend_entry(slave_instance, scheme, wildcard) %}
{#- wildcard switch allows to put dangerous entries in the end, as haproxy parses with first match #}
{#- if slave_instance[SCHEME_PREFIX_MAPPING[scheme]]['hostname'] and slave_instance[SCHEME_PREFIX_MAPPING[scheme]]['port'] #}
{%- set host_list = (slave_instance.get('server-alias') or '').split() %}
{%- if slave_instance.get('custom_domain') not in host_list %}
{%- do host_list.append(slave_instance.get('custom_domain')) %}
{%- endif %}
{%- set matched = {'count': 0} %}
{%- for host in host_list %}
{#- Match up to the end or optional port (starting with ':') #}
{#- Please note that this matching is quite sensitive to changes and hard to test, so avoid needless changes #}
{%- if wildcard and host.startswith('*.') %}
{%- do matched.__setitem__('count', matched['count'] + 1) %}
# match wildcard {{ host }}
acl is_{{ slave_instance['slave_reference'] }} hdr_reg(host) -i {{ host[2:] }}($|:.*)
{%- elif not wildcard and not host.startswith('*.') %}
{%- do matched.__setitem__('count', matched['count'] + 1) %}
acl is_{{ slave_instance['slave_reference'] }} hdr_reg(host) -i ^{{ host }}($|:.*)
{%- endif %}
{%- endfor %}
{%- if matched['count'] > 0 %}
use_backend {{ slave_instance['slave_reference'] }}-{{ scheme }} if is_{{ slave_instance['slave_reference'] }}
{%- endif %}
{#- endif #}
{%- endmacro %}
{%- macro frontend_common() %}
# normalize URIs as it's expected by the backends
http-request normalize-uri path-merge-slashes
http-request normalize-uri path-strip-dot
http-request normalize-uri path-strip-dotdot
# setup X-Forwarded-*
option forwardfor
# Combined Log Format
capture request header REMOTE_USER len 255
capture request header Referer len 255
capture request header User-Agent len 255
log-format "%{+E}o %b %ci - %[capture.req.hdr(0)] [%trl] \"%HM %HU %HV\" %ST %B \"%[capture.req.hdr(1)]\" \"%[capture.req.hdr(2)]\" %Ta"
{%- endmacro %}
frontend http-frontend
bind {{ configuration['local-ipv4'] }}:{{ configuration['http-port'] }}
{{ frontend_common() }}
http-request set-header X-Forwarded-Proto http
http-request set-header X-Forwarded-Port {{ configuration['http-port'] }}
# Here use Host header
{%- for slave_instance in frontend_slave_list -%}
{{ frontend_entry(slave_instance, 'http', False) }}
{%- endfor %}
{%- for slave_instance in frontend_slave_list -%}
{{ frontend_entry(slave_instance, 'http', True) }}
{%- endfor %}
frontend https-frontend
bind {{ configuration['local-ipv4'] }}:{{ configuration['https-port'] }} ssl crt-list {{ crt_list }}
{{ frontend_common() }}
http-request set-header X-Forwarded-Proto https
http-request set-header X-Forwarded-Port {{ configuration['https-port'] }}
# Here use ssl_fc_sni and fallback to Host header
{%- for slave_instance in frontend_slave_list -%}
{{ frontend_entry(slave_instance, 'https', False) }}
{%- endfor %}
{%- for slave_instance in frontend_slave_list -%}
{{ frontend_entry(slave_instance, 'https', True) }}
{%- endfor %}
# Backends
{%- for slave_instance in frontend_slave_list %}
{%- for (scheme, prefix) in SCHEME_PREFIX_MAPPING.items() %}
{%- set info_dict = slave_instance.get(prefix, slave_instance.get('backend-http-info')) %}
backend {{ slave_instance['slave_reference'] }}-{{ scheme }}
{%- if scheme == 'http' and slave_instance['https-only'] %}
{#- Support https-only if connected via http #}
redirect scheme https code 302
{%- else %}
{%- if 'hostname' in info_dict and 'port' in info_dict %}
server {{ slave_instance['slave_reference'] }}-backend-{{ scheme }} {{ info_dict['hostname'] }}:{{ info_dict['port'] }}
{%- if info_dict['path'] %}
http-request set-path {{ info_dict['path'] }}%[path]
{%- endif %} {# if info_dict['path'] #}
{%- endif %} {# if 'hostname' in info_dict and 'port' in info_dict #}
{%- endif %} {# if scheme == 'http' and slave_instance['https-only'] #}
{%- endfor %} {# for (scheme, prefix) in SCHEME_PREFIX_MAPPING.items() #}
{%- for k, v in slave_instance.items() %}
{#- # {{ k }} => {{ v }} #}
{%- endfor %}
{% endfor %}
......@@ -838,14 +838,14 @@ class HttpFrontendTestCase(SlapOSInstanceTestCase):
)
self.assertEqual(
sorted([q['name'] for q in result.json()]),
['access.log', 'backend.log', 'error.log'])
['access.log', 'backend.log'])
self.assertEqual(
httplib.OK,
requests.get(url + 'access.log', verify=False).status_code
)
self.assertEqual(
httplib.OK,
requests.get(url + 'error.log', verify=False).status_code
requests.get(url + 'backend.log', verify=False).status_code
)
# assert only for few tests, as backend log is not available for many of
# them, as it's created on the fly
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment