{%- if slap_software_type == software_type -%}
{% import "caucase" as caucase with context %}
{%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] -%}
[buildout]
extends =
  {{ parameter_dict['common_profile'] }}
  {{ parameter_dict['monitor_template'] }}
  {{ parameter_dict['logrotate_base_instance'] }}

parts =
  directory
  logrotate-entry-caddy
  caddy-frontend
  switch-caddy-softwaretype
  caucase-updater
  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

  trafficserver-launcher
  trafficserver-reload
  trafficserver-configuration-directory
  trafficserver-records-config
  trafficserver-remap-config
  trafficserver-plugin-config
  trafficserver-storage-config
  trafficserver-ip-allow-config
  trafficserver-logging-config
  trafficserver-promise-listen-port
  trafficserver-promise-cache-availability
  cron-entry-logrotate-trafficserver
## Monitor for Caddy
  monitor-base
  monitor-ats-cache-stats-wrapper
  monitor-traffic-summary-last-stats-wrapper
  monitor-caddy-server-status-wrapper
  monitor-verify-re6st-connectivity

  backend-haproxy-rsyslogd-configuration
  backend-haproxy-rsyslogd
  logrotate-entry-backend-haproxy
  backend-haproxy
  backend-haproxy-graceful
  promise-backend-haproxy-http
  promise-backend-haproxy-https
  promise-backend-haproxy-configuration

# Create all needed directories
[directory]
recipe = slapos.cookbook:mkdirectory

bin = ${buildout:directory}/bin/
etc = ${buildout:directory}/etc/
srv = ${buildout:directory}/srv/
var = ${buildout:directory}/var/
tmp = ${:var}/tmp
template = ${buildout:directory}/template/

backup = ${:srv}/backup
log = ${:var}/log
run = ${:var}/run
backend-haproxy-rsyslogd-spool = ${:run}/backend-haproxy-rsyslogd-spool
service = ${:etc}/service
etc-run = ${:etc}/run

ca-dir = ${:srv}/ssl
backend-client-dir = ${:srv}/backend-client
# BBB: SlapOS Master non-zero knowledge BEGIN
bbb-ssl-dir = ${:srv}/bbb-ssl
# BBB: SlapOS Master non-zero knowledge END

frontend_cluster = ${:var}/frontend_cluster

# csr_id publication
csr_id = ${:srv}/csr_id
caddy-csr_id = ${:etc}/caddy-csr_id
caddy-csr_id-log = ${:log}/httpd-csr_id

[switch-caddy-softwaretype]
recipe = slapos.cookbook:softwaretype
single-default = ${dynamic-custom-personal-template-slave-list:rendered}
single-custom-personal = ${dynamic-custom-personal-template-slave-list:rendered}

[frontend-configuration]
template-log-access = {{ parameter_dict['template_log_access'] }}
log-access-configuration = ${directory:etc}/log-access.conf
ip-access-certificate = ${self-signed-ip-access:certificate}
caddy-directory = {{ parameter_dict['caddy_location'] }}
caddy-ipv6 = {{ instance_parameter['ipv6-random'] }}
caddy-https-port = ${configuration:port}

[self-signed-ip-access]
# Self Signed certificate for HTTPS IP accesses to the frontend
recipe = plone.recipe.command
update-command = ${:command}
ipv6 = ${slap-network-information:global-ipv6}
ipv4 = {{instance_parameter['ipv4-random']}}
certificate = ${caddy-directory:master-autocert-dir}/ip-access-${:ipv6}-${:ipv4}.crt
stop-on-error = True
command =
  [ -f ${:certificate} ] && exit 0
  rm -f ${:certificate}
  /bin/bash -c ' \
  {{ parameter_dict['openssl'] }} req \
     -new -newkey rsa:2048 -sha256 \
     -nodes -x509 -days 36500 \
     -keyout ${:certificate} \
     -subj "/CN=Self Signed IP Access" \
     -reqexts SAN \
     -extensions SAN \
     -config <(cat {{ parameter_dict['openssl_cnf'] }} \
         <(printf "\n[SAN]\nsubjectAltName=IP:${:ipv6},IP:${:ipv4}")) \
     -out ${:certificate}'

[self-signed-fallback-access]
# Self Signed certificate for HTTPS access to the frontend with fallback certificate
recipe = plone.recipe.command
update-command = ${:command}
ipv6 = ${slap-network-information:global-ipv6}
ipv4 = {{instance_parameter['ipv4-random']}}
certificate = ${caddy-directory:master-autocert-dir}/fallback-access.crt
stop-on-error = True
command =
  [ -f ${:certificate} ] && exit 0
  rm -f ${:certificate}
  /bin/bash -c ' \
  {{ parameter_dict['openssl'] }} req \
     -new -newkey rsa:2048 -sha256 \
     -nodes -x509 -days 36500 \
     -keyout ${:certificate} \
     -subj "/CN=Fallback certificate/OU={{ instance_parameter['configuration.frontend-name'] }}" \
     -out ${:certificate}'

[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/${:filename}
extensions = jinja2.ext.do
extra-context =
slapparameter_dict = {{ dumps(instance_parameter['configuration']) }}
slap_software_type = {{ dumps(instance_parameter['slap-software-type']) }}
context =
    import json_module json
    raw common_profile {{ parameter_dict['common_profile'] }}
    raw logrotate_base_instance {{ parameter_dict['logrotate_base_instance'] }}
    raw monitor_template {{ parameter_dict['monitor_template'] }}
    key slap_software_type :slap_software_type
    key slapparameter_dict :slapparameter_dict
    section directory directory
    ${:extra-context}

[software-release-path]
template-empty = {{ parameter_dict['template_empty'] }}
template-default-slave-virtualhost = {{ parameter_dict['template_default_slave_virtualhost'] }}
template-backend-haproxy-configuration = {{ parameter_dict['template_backend_haproxy_configuration'] }}
template-backend-haproxy-rsyslogd-conf = {{ parameter_dict['template_backend_haproxy_rsyslogd_conf'] }}
caddy-location = {{ parameter_dict['caddy_location'] }}

[kedifa-login-config]
d = ${directory:ca-dir}
template-csr = ${:d}/kedifa-login-template-csr.pem
key = ${:d}/kedifa-login-certificate.pem
certificate = ${:key}
ca-certificate = ${:d}/kedifa-caucase-ca.pem
cas-ca-certificate = ${:d}/kedifa-cas-caucase-ca.pem
crl = ${:d}/kedifa-login-crl.pem

[kedifa-login-csr]
recipe = plone.recipe.command
organization = {{ slapparameter_dict['cluster-identification'] }}
organizational_unit = {{ instance_parameter['configuration.frontend-name'] }}
command =
{% if slapparameter_dict['kedifa-caucase-url'] %}
  if [ ! -f ${:template-csr} ] && [ ! -f ${:key} ]  ; then
    {{ parameter_dict['openssl'] }} req -new -sha256 \
      -newkey rsa:2048 -nodes -keyout ${:key} \
      -subj "/O=${:organization}/OU=${:organizational_unit}" \
      -out ${:template-csr}
  fi
{% endif %}
  test -f ${:key} && test -f ${:template-csr}
update-command = ${:command}
template-csr = ${kedifa-login-config:template-csr}
key = ${kedifa-login-config:key}
stop-on-error = True

{{ caucase.updater(
     prefix='caucase-updater',
     buildout_bin_directory=parameter_dict['bin_directory'],
     updater_path='${directory:service}/kedifa-login-certificate-caucase-updater',
     url=slapparameter_dict['kedifa-caucase-url'],
     data_dir='${directory:srv}/caucase-updater',
     crt_path='${kedifa-login-config:certificate}',
     ca_path='${kedifa-login-config:ca-certificate}',
     crl_path='${kedifa-login-config:crl}',
     key_path='${kedifa-login-csr:key}',
     template_csr='${kedifa-login-csr:template-csr}'
)}}

[kedifa-configuration]
caucase-url = {{ slapparameter_dict['kedifa-caucase-url'] }}
ca-certificate = ${kedifa-login-config:ca-certificate}
certificate = ${kedifa-login-config:certificate}
cas-ca-certificate = ${kedifa-login-config:cas-ca-certificate}
csr = ${caucase-updater-csr:csr}
crl = ${kedifa-login-config:crl}
kedifa-updater = {{ parameter_dict['kedifa-updater'] }}
kedifa-updater-mapping-file = ${directory:etc}/kedifa_updater_mapping.txt
kedifa-updater-state-file = ${directory:srv}/kedifa_updater_state.json
slave_kedifa_information = {{ dumps(slapparameter_dict['slave-kedifa-information']) }}

[backend-client-login-config]
d = ${directory:backend-client-dir}
template-csr = ${:d}/csr.pem
key = ${:d}/certificate.pem
certificate = ${:key}
ca-certificate = ${:d}/ca.pem
cas-ca-certificate = ${:d}/cas-ca.pem
crl = ${:d}/crl.pem

[backend-client-login-csr]
recipe = plone.recipe.command
organization = {{ slapparameter_dict['cluster-identification'] }}
organizational_unit = {{ instance_parameter['configuration.frontend-name'] }}
command =
{% if slapparameter_dict['backend-client-caucase-url'] %}
  if [ ! -f ${:template-csr} ] && [ ! -f ${:key} ]  ; then
    {{ parameter_dict['openssl'] }} req -new -sha256 \
      -newkey rsa:2048 -nodes -keyout ${:key} \
      -subj "/O=${:organization}/OU=${:organizational_unit}" \
      -out ${:template-csr}
  fi
{% endif %}
  test -f ${:key} && test -f ${:template-csr}
update-command = ${:command}
template-csr = ${backend-client-login-config:template-csr}
key = ${backend-client-login-config:key}
stop-on-error = True

{{ caucase.updater(
     prefix='backend-client-caucase-updater',
     buildout_bin_directory=parameter_dict['bin_directory'],
     updater_path='${directory:service}/backend-client-login-certificate-caucase-updater',
     url=slapparameter_dict['backend-client-caucase-url'],
     data_dir='${directory:srv}/backend-client-caucase-updater',
     crt_path='${backend-client-login-config:certificate}',
     ca_path='${backend-client-login-config:ca-certificate}',
     crl_path='${backend-client-login-config:crl}',
     key_path='${backend-client-login-csr:key}',
     template_csr='${backend-client-login-csr:template-csr}'
)}}

[dynamic-custom-personal-template-slave-list]
< = jinja2-template-base
template = {{ parameter_dict['template_slave_list'] }}
filename = custom-personal-instance-slave-list.cfg
slave_instance_list = {{ dumps(instance_parameter['slave-instance-list']) }}
extra_slave_instance_list = {{ dumps(instance_parameter.get('configuration.extra_slave_instance_list')) }}
master_key_download_url = {{ dumps(slapparameter_dict['master-key-download-url']) }}
local_ipv4 = {{ dumps(instance_parameter['ipv4-random']) }}
local_ipv6 = {{ dumps(instance_parameter['ipv6-random']) }}
software_type = single-custom-personal
bin_directory = {{ parameter_dict['bin_directory'] }}
caddy_executable = {{ parameter_dict['caddy'] }}
sixtunnel_executable = {{ parameter_dict['sixtunnel'] }}/bin/6tunnel
organization = {{ slapparameter_dict['cluster-identification'] }}
organizational-unit = {{ instance_parameter['configuration.frontend-name'] }}
backend-client-caucase-url = {{ slapparameter_dict['backend-client-caucase-url'] }}
extra-context =
    key caddy_configuration_directory caddy-directory:slave-configuration
    key backend_client_caucase_url :backend-client-caucase-url
    import urlparse_module urlparse
    key caddy_executable :caddy_executable
    key http_port configuration:plain_http_port
    key https_port configuration:port
    key public_ipv4 configuration:public-ipv4
    key slave_instance_list :slave_instance_list
    key extra_slave_instance_list :extra_slave_instance_list
    key master_key_download_url :master_key_download_url
    key autocert caddy-directory:autocert
    key master_certificate caddy-configuration:master-certificate
    key caddy_log_directory caddy-directory:slave-log
    key expose_csr_id_organization :organization
    key expose_csr_id_organizational_unit :organizational-unit
    key local_ipv4 :local_ipv4
    key local_ipv6 :local_ipv6
    key global_ipv6 slap-network-information:global-ipv6
    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_graceful_reload caddy-configuration:frontend-graceful-command
    section frontend_configuration frontend-configuration
    section caddy_configuration caddy-configuration
    key monitor_base_url monitor-instance-parameter:monitor-base-url 
    key bin_directory :bin_directory
    key enable_http2_by_default configuration:enable-http2-by-default
    key global_disable_http2 configuration:global-disable-http2
    key ciphers configuration:ciphers
    key access_log caddy-configuration:access-log
    key error_log caddy-configuration:error-log
    key sixtunnel_executable :sixtunnel_executable
    key not_found_file caddy-configuration:not-found-file
    key custom_ssl_directory caddy-directory:custom-ssl-directory
    section kedifa_configuration kedifa-configuration
# BBB: SlapOS Master non-zero knowledge BEGIN
    key apache_certificate apache-certificate:rendered
# BBB: SlapOS Master non-zero knowledge END
## backend haproxy
    key template_backend_haproxy_configuration software-release-path:template-backend-haproxy-configuration
    section backend_haproxy_configuration backend-haproxy-configuration
## full configuration
    section configuration configuration

# Deploy Caddy Frontend with Jinja power
[dynamic-caddy-frontend-template]
< = jinja2-template-base
template = {{ parameter_dict['template_caddy_frontend_configuration'] }}
rendered = ${caddy-configuration:frontend-configuration}
local_ipv4 =  {{ dumps(instance_parameter['ipv4-random']) }}
extra-context =
    key httpd_home software-release-path:caddy-location
    key httpd_mod_ssl_cache_directory caddy-directory:mod-ssl
    key instance_home buildout:directory
    key master_certificate caddy-configuration:master-certificate
    key access_log caddy-configuration:access-log
    key slave_configuration_directory caddy-directory:slave-configuration
    section frontend_configuration frontend-configuration
    key http_port configuration:plain_http_port
    key https_port configuration:port
    key local_ipv4 :local_ipv4
    key global_ipv6 slap-network-information:global-ipv6
    key error_log caddy-configuration:error-log
    key not_found_file caddy-configuration:not-found-file
    key username monitor-instance-parameter:username
    key password monitor-htpasswd:passwd
# BBB: SlapOS Master non-zero knowledge BEGIN
    key apache_certificate apache-certificate:rendered
# BBB: SlapOS Master non-zero knowledge END

[caddy-wrapper]
recipe = slapos.recipe.template:jinja2
template = inline:
  #!/bin/sh
  export CADDYPATH=${directory:frontend_cluster}
  ulimit -n $(ulimit -Hn)
  exec {{ parameter_dict['caddy'] }} \
  -conf ${dynamic-caddy-frontend-template:rendered} \
  -log ${caddy-configuration:error-log} \
  -log-roll-mb 0 \
{% if instance_parameter['configuration.global-disable-http2'].lower() in TRUE_VALUES %}
  -http2=false \
{% else %}
  -http2=true \
{% endif %}
  -grace {{ instance_parameter['configuration.mpm-graceful-shutdown-timeout'] }}s \
  -disable-http-challenge \
  -disable-tls-alpn-challenge \
   "$@"
rendered = ${directory:bin}/caddy-wrapper
mode = 0755

[caddy-frontend]
recipe = slapos.cookbook:wrapper
command-line = ${caddy-wrapper:rendered} -pidfile ${caddy-configuration:pid-file}
wrapper-path = ${directory:service}/frontend_caddy
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  {{ 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/
cache = ${directory:var}/cache
mod-ssl = ${:cache}/httpd_mod_ssl
slave-log = ${directory:log}/httpd
autocert = ${directory:srv}/autocert
master-autocert-dir = ${:autocert}/master-autocert
custom-ssl-directory = ${:slave-configuration}/ssl

[caddy-configuration]
frontend-configuration = ${directory:etc}/Caddyfile
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
# Communication with ATS
cache-port = ${trafficserver-variable:input-port}

# BBB: SlapOS Master non-zero knowledge BEGIN
[get-self-signed-fallback-access]
recipe = collective.recipe.shelloutput
commands =
  certificate = cat ${self-signed-fallback-access:certificate}

[apache-certificate]
recipe = slapos.recipe.template:jinja2
template = inline:
{% raw %}
  {{ certificate or fallback_certificate }}
  {{ key or '' }}
{% endraw %}
context =
  key certificate configuration:apache-certificate
  key key configuration:apache-key
  key fallback_certificate get-self-signed-fallback-access:certificate
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} &

#################
# Trafficserver
#################
[trafficserver-directory]
recipe = slapos.cookbook:mkdirectory
configuration = ${directory:etc}/trafficserver
local-state = ${directory:var}/trafficserver
bin_path = {{ parameter_dict['trafficserver'] }}/bin
log = ${directory:log}/trafficserver
cache-path = ${directory:srv}/ats_cache
logrotate-backup = ${logrotate-directory:logrotate-backup}/trafficserver

[trafficserver-variable]
wrapper-path = ${directory:service}/trafficserver
reload-path = ${directory:etc-run}/trafficserver-reload
local-ip = {{ instance_parameter['ipv4-random'] }}
input-port = 23432
hostname = ${configuration:frontend-name}
plugin-config =
ip-allow-config = src_ip=0.0.0.0-255.255.255.255 action=ip_allow
cache-path = ${trafficserver-directory:cache-path}
disk-cache-size = ${configuration:disk-cache-size}
synthetic-port = ${configuration:trafficserver-synthetic-port}
mgmt-port = ${configuration:trafficserver-mgmt-port}
ram-cache-size = ${configuration:ram-cache-size}
templates-dir = {{ parameter_dict['trafficserver'] }}/etc/trafficserver/body_factory
request-timeout = ${configuration:request-timeout}

[trafficserver-configuration-directory]
recipe = plone.recipe.command
command = cp -rn {{ parameter_dict['trafficserver'] }}/etc/trafficserver/* ${:target}
target = ${trafficserver-directory:configuration}

[trafficserver-launcher]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['trafficserver'] }}/bin/traffic_cop
wrapper-path = ${trafficserver-variable:wrapper-path}
environment = TS_ROOT=${buildout:directory}
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg

[trafficserver-reload]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['trafficserver'] }}/bin/traffic_ctl config reload
wrapper-path = ${trafficserver-variable:reload-path}
environment = TS_ROOT=${buildout:directory}

# XXX Dedicated Jinja Section without slapparameter
[trafficserver-jinja2-template-base]
recipe = slapos.recipe.template:jinja2
rendered = ${trafficserver-directory:configuration}/${:filename}
extra-context =
mode = 600
context =
    section ats_directory trafficserver-directory
    section ats_configuration trafficserver-variable
    ${:extra-context}

[trafficserver-records-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_trafficserver_records_config'] }}
filename = records.config
extra-context =
    import os_module os

[trafficserver-storage-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_trafficserver_storage_config'] }}
filename = storage.config

[trafficserver-logging-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_trafficserver_logging_config'] }}
filename = logging.config

[trafficserver-remap-config]
<= trafficserver-jinja2-template-base
{%- raw %}
template = inline:
  map /HTTPS/ http://{{ ipv4 }}:{{ https_port }}
  map / http://{{ ipv4 }}:{{ http_port }}
{%- endraw %}
extra-context =
  raw ipv4 {{ instance_parameter['ipv4-random'] }}
  key https_port backend-haproxy-configuration:https-port
  key http_port backend-haproxy-configuration:http-port

filename = remap.config

[trafficserver-plugin-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
filename = plugin.config
context =
    key content trafficserver-variable:plugin-config

[trafficserver-ip-allow-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
filename = ip_allow.config
context =
    key content trafficserver-variable:ip-allow-config

[trafficserver-promise-listen-port]
<= monitor-promise-base
module = check_port_listening
name = trafficserver-port-listening.py
config-hostname = ${trafficserver-variable:local-ip}
config-port = ${trafficserver-variable:input-port}

[trafficserver-ctl]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['trafficserver'] }}/bin/traffic_ctl
wrapper-path = ${directory:bin}/traffic_ctl
environment = TS_ROOT=${buildout:directory}

[trafficserver-promise-cache-availability]
<= monitor-promise-base
module = trafficserver_cache_availability
name = trafficserver-cache-availability.py
config-wrapper-path = ${trafficserver-ctl:wrapper-path}

[trafficserver-rotate-script]
< = jinja2-template-base
template = {{ parameter_dict['template_rotate_script'] }}
rendered = ${directory:bin}/trafficserver-rotate
mode = 0700
xz_binary = {{ parameter_dict['xz_location'] ~ '/bin/xz' }}
pattern = *.old
# days to keep log files
keep_days = 365

extra-context =
  key log_dir trafficserver-directory:log
  key rotate_dir trafficserver-directory:logrotate-backup
  key xz_binary :xz_binary
  key keep_days :keep_days
  key pattern :pattern

[cron-entry-logrotate-trafficserver]
recipe = slapos.cookbook:cron.d
cron-entries = ${directory:etc}/cron.d
name = trafficserver-logrotate
frequency = 0 0 * * *
command = ${trafficserver-rotate-script:rendered}

### End of ATS sections

### Caddy Graceful and promises
[frontend-caddy-configuration-state]
< = jinja2-template-base
template = {{ parameter_dict['template_configuration_state_script'] }}
rendered = ${directory:bin}/${:_buildout_section_name_}
mode = 0700

path_list = ${caddy-configuration:frontend-configuration} ${frontend-configuration:log-access-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
sha256sum = {{ parameter_dict['sha256sum'] }}

extra-context =
    key path_list :path_list
    key sha256sum :sha256sum
    key signature_file :signature_file

[frontend-caddy-configuration-state-graceful]
< = frontend-caddy-configuration-state
signature_file = ${directory:run}/graceful_configuration_state_signature

[frontend-caddy-configuration-state-validate]
< = frontend-caddy-configuration-state
signature_file = ${directory:run}/validate_configuration_state_signature

[frontend-caddy-graceful]
< = jinja2-template-base
template = {{ parameter_dict['template_graceful_script'] }}
rendered = ${directory:etc-run}/frontend-caddy-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

[frontend-caddy-validate]
< = jinja2-template-base
template = {{ parameter_dict['template_validate_script'] }}
rendered = ${directory:bin}/frontend-caddy-validate
mode = 0700
last_state_file = ${directory:run}/caddy_configuration_last_state
validate_command = ${caddy-wrapper:rendered} -validate
extra-context =
    key validate_command :validate_command
    key configuration_state_command frontend-caddy-configuration-state-validate:rendered
    key last_state_file :last_state_file

[frontend-caddy-lazy-graceful]
< = jinja2-template-base
template = {{ parameter_dict['template_caddy_lazy_script_call'] }}
rendered = ${directory:bin}/frontend-caddy-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

# Promises checking configuration:
[promise-helper-last-configuration-state]
< = jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
rendered = ${directory:bin}/frontend-read-last-configuration-state
mode = 0700
content =
  #!/bin/sh
  exit `cat ${frontend-caddy-validate:last_state_file}`
context =
    key content :content

[promise-frontend-caddy-configuration]
<= monitor-promise-base
module = validate_frontend_configuration
name = frontend-caddy-configuration-promise.py
config-verification-script = ${promise-helper-last-configuration-state:rendered}

[promise-caddy-frontend-v4-https]
<= monitor-promise-base
module = check_port_listening
name = caddy_frontend_ipv4_https.py
config-hostname = {{ instance_parameter['ipv4-random'] }}
config-port = ${configuration:port}

[promise-caddy-frontend-v4-http]
<= monitor-promise-base
module = check_port_listening
name = caddy_frontend_ipv4_http.py
config-hostname = {{ instance_parameter['ipv4-random'] }}
config-port = ${configuration:plain_http_port}

[promise-caddy-frontend-v6-https]
<= monitor-promise-base
module = check_port_listening
name = caddy_frontend_ipv6_https.py
config-hostname = {{ instance_parameter['ipv6-random'] }}
config-port = ${configuration:port}

[promise-caddy-frontend-v6-http]
<= monitor-promise-base
module = check_port_listening
name = caddy_frontend_ipv6_http.py
config-hostname = {{ instance_parameter['ipv6-random'] }}
config-port = ${configuration:plain_http_port}

[promise-backend-haproxy-http]
<= monitor-promise-base
module = check_port_listening
name = backend_haproxy_http.py
config-hostname = {{ instance_parameter['ipv4-random'] }}
config-port = ${backend-haproxy-configuration:http-port}

[promise-backend-haproxy-https]
<= monitor-promise-base
module = check_port_listening
name = backend_haproxy_https.py
config-hostname = {{ instance_parameter['ipv4-random'] }}
config-port = ${backend-haproxy-configuration:https-port}

[backend-haproxy-configuration]
file = ${directory:etc}/backend-haproxy.cfg
pid-file = ${directory:run}/backend-haproxy.pid
log-socket = ${backend-haproxy-rsyslogd-config:log-socket}
graceful-command = ${backend-haproxy-validate:rendered} && kill -USR2 $(cat ${:pid-file})
http-port = ${configuration:backend-haproxy-http-port}
https-port = ${configuration:backend-haproxy-https-port}
# Caucase related configuration
caucase-url = {{ slapparameter_dict['backend-client-caucase-url'] }}
ca-certificate = ${backend-client-login-config:ca-certificate}
certificate = ${backend-client-login-config:certificate}
cas-ca-certificate = ${backend-client-login-config:cas-ca-certificate}
csr = ${backend-client-caucase-updater-csr:csr}
crl = ${backend-client-login-config:crl}

[backend-haproxy]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['haproxy_executable'] }} -f ${backend-haproxy-configuration:file}
wrapper-path = ${directory:service}/backend-haproxy
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg

[backend-haproxy-rsyslogd-lazy-graceful]
< = jinja2-template-base
template = {{ parameter_dict['template_caddy_lazy_script_call'] }}
rendered = ${directory:bin}/backend-haproxy-rsyslogd-lazy-graceful
mode = 0700
pid-file = ${directory:run}/backend-haproxy-rsyslogd-lazy-graceful.pid
wait_time = 60
extra-context =
    key pid_file :pid-file
    key wait_time :wait_time
    key lazy_command backend-haproxy-rsyslogd-config:graceful-command

[logrotate-entry-backend-haproxy]
<= logrotate-entry-base
name = backend-haproxy
log = ${backend-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 = ${backend-haproxy-rsyslogd-lazy-graceful:rendered} &

[backend-haproxy-configuration-state]
<= jinja2-template-base
template = {{ parameter_dict['template_configuration_state_script'] }}
rendered = ${directory:bin}/${:_buildout_section_name_}
mode = 0700

path_list = ${backend-haproxy-configuration:file} ${backend-client-login-config:certificate}
sha256sum = {{ parameter_dict['sha256sum'] }}

extra-context =
    key path_list :path_list
    key sha256sum :sha256sum
    key signature_file :signature_file

[backend-haproxy-configuration-state-graceful]
<= backend-haproxy-configuration-state
signature_file = ${directory:run}/backend_haproxy_graceful_configuration_state_signature

[backend-haproxy-configuration-state-validate]
<= backend-haproxy-configuration-state
signature_file = ${directory:run}/backend_haproxy_validate_configuration_state_signature

[backend-haproxy-graceful]
< = jinja2-template-base
template = {{ parameter_dict['template_graceful_script'] }}
rendered = ${directory:etc-run}/backend-haproxy-safe-graceful
mode = 0700

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 = {{ 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 = {{ 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
name = backend-haproxy-configuration.py
config-verification-script = ${promise-backend-haproxy-configuration-helper:rendered}

[promise-backend-haproxy-configuration-helper]
< = jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
rendered = ${directory:bin}/backend-haproxy-read-last-configuration-state
mode = 0700
content =
  #!/bin/sh
  exit `cat ${backend-haproxy-validate:last_state_file}`
context =
    key content :content

[backend-haproxy-rsyslogd-config]
log-socket = ${directory:run}/bhlog.sck
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}

[backend-haproxy-rsyslogd-configuration]
<= jinja2-template-base
template = ${software-release-path:template-backend-haproxy-rsyslogd-conf}
rendered = ${directory:etc}/backend-haproxy-rsyslogd.conf
extra-context =
  section configuration backend-haproxy-rsyslogd-config

[backend-haproxy-rsyslogd]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['rsyslogd_executable'] }} -i ${backend-haproxy-rsyslogd-config:pid-file} -n -f ${backend-haproxy-rsyslogd-configuration:rendered}
wrapper-path = ${directory:service}/backend-haproxy-rsyslogd
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg

#######
# Monitoring sections
#

[monitor-instance-parameter]
# Note: Workaround for monitor stack, which uses monitor-httpd-port parameter
#       directly, and in our case it can come from the network, thus resulting
#       with need to strip !py!'u'
monitor-httpd-port = {{ instance_parameter['configuration.monitor-httpd-port'] | int }}
password = {{ instance_parameter['configuration.monitor-password'] | string }}

[monitor-conf-parameters]
private-path-list += 
  ${logrotate-directory:logrotate-backup}


[monitor-traffic-summary-last-stats-wrapper]
< = jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${directory:bin}/traffic-summary-last-stats_every_1_hour
mode = 0700
command = export TS_ROOT=${buildout:directory} && echo "<pre>$({{ parameter_dict['trafficserver'] }}/bin/traffic_logstats -f ${trafficserver-directory:log}/squid.blog)</pre>"
extra-context =
  key content monitor-traffic-summary-last-stats-wrapper:command

# Produce ATS Cache stats
[monitor-ats-cache-stats-wrapper]
< = jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${directory:bin}/ats-cache-stats_every_1_hour
mode = 0700
command = export TS_ROOT=${buildout:directory} && echo "<pre>$({{ parameter_dict['trafficserver'] }}/bin/traffic_shell ${monitor-ats-cache-stats-config:rendered})</pre>"
extra-context =
  key content monitor-ats-cache-stats-wrapper:command

[monitor-caddy-server-status-wrapper]
< = jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${directory:bin}/monitor-caddy-server-status-wrapper
mode = 0700
command = {{ parameter_dict['curl'] }}/bin/curl -s http://{{ instance_parameter['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 = {{ parameter_dict['template_empty'] }}
rendered = ${trafficserver-configuration-directory:target}/cache-config.stats
mode = 644
context =
    raw content show:cache-stats

[monitor-verify-re6st-connectivity]
<= monitor-promise-base
module = check_url_available
name = re6st-connectivity.py
config-url = ${configuration:re6st-verification-url}

[port-redirection]
<= jinja2-template-base
template = inline:
  [{"srcPort": 80, "destPort": {{ '{{' }} http_port {{ '}}' }}}, {"srcPort": 443, "destPort": {{ '{{' }} https_port {{ '}}' }}}]
rendered = ${buildout:directory}/.slapos-port-redirect
mode = 0644
extra-context =
    key http_port configuration:plain_http_port
    key https_port configuration:port

[configuration]
{%- for key, value in instance_parameter.iteritems() -%}
{%-   if key.startswith('configuration.') %}
{{ key.replace('configuration.', '') }} = {{ dumps(value) }}
{%-   endif -%}
{%- endfor -%}
{%- endif -%} {# if slap_software_type == software_type #}
