{%- if software_type == slap_software_type %}
{%- set kedifa_updater_mapping = [] %}
{%- set cached_server_dict = {} %}
{%- set backend_slave_list = [] %}
{%- set frontend_slave_list = [] %}
{%- set part_list = [] %}
{%- set cache_port = caddy_configuration.get('cache-port') %}
{%- set cache_access = "http://%s:%s" % (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']) %}
{%- set backend_haproxy_https_url = 'http://%s:%s' % (instance_parameter_dict['ipv4-random'], backend_haproxy_configuration['https-port']) %}
{%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] %}
{%- set generic_instance_parameter_dict = { 'cache_access': cache_access, 'local_ipv4': instance_parameter_dict['ipv4-random'], 'http_port': configuration['plain_http_port'], 'https_port': configuration['port']} %}
{%- set slave_log_dict = {} %}
{%- set slave_instance_information_list = [] %}
{%- set slave_instance_list = instance_parameter_dict['slave-instance-list'] %}
{%- if configuration['extra_slave_instance_list'] %}
{%-   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)) %}
{%- else %}
{%-   do kedifa_updater_mapping.append(('notreadyyet', caddy_configuration['master-certificate'], apache_certificate)) %}
{%- endif %}
{%- if kedifa_configuration['slave_kedifa_information'] %}
{%-   set slave_kedifa_information = json_module.loads(kedifa_configuration['slave_kedifa_information']) %}
{%- else %}
{%-   set slave_kedifa_information = {} %}
{%- endif -%}
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
extra-context =
context =
    raw profile_common {{ profile_common }}
    ${:extra-context}

# empty sections if no slaves are available
[slave-log-directory-dict]
[slave-password]
[slave-htpasswd]

{#- Prepare configuration parameters #}
{%- set DEFAULT_PORT = {'http': 80, 'https': 443, '': None} %}
{%- for key in ['enable-http2-by-default', 'global-disable-http2'] %}
{%-   do configuration.__setitem__(key, ('' ~ configuration[key]).lower() in TRUE_VALUES) %}
{%- endfor %}
{#- Loop thought slave list to set up slaves #}
{%- for slave_instance in slave_instance_list %}
{#-   Prepare slave parameters: #}
{#-     * convert strings to booleans (as slapproxy and SlapOS Master differ a bit) #}
{#-     * create real lists from string lists #}
{#-     * 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()) %}
{%-     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 %}
{%-   do slave_instance.__setitem__('ssl_proxy_verify', ('' ~ slave_instance.get('ssl-proxy-verify', '')).lower() in TRUE_VALUES) %}
{%-   do slave_instance.__setitem__('enable-http2', ('' ~ slave_instance.get('enable-http2', configuration['enable-http2-by-default'])).lower() in TRUE_VALUES) %}
{%-   for key in ['https-only', 'websocket-transparent'] %}
{%-     do slave_instance.__setitem__(key, ('' ~ slave_instance.get(key, 'true')).lower() in TRUE_VALUES) %}
{%-   endfor %}
{%-   for key in ['enable_cache', 'disable-no-cache-request', 'disable-via-header', 'prefer-gzip-encoding-to-backend', 'strict-transport-security-sub-domains', 'strict-transport-security-preload'] %}
{%-     do slave_instance.__setitem__(key, ('' ~ slave_instance.get(key, 'false')).lower() in TRUE_VALUES) %}
{%-   endfor %}
{%-   for key in ['disabled-cookie-list'] %}
{%-     do slave_instance.__setitem__(key, slave_instance.get(key, '').split()) %}
{%-   endfor %}
{%-   for key, default in [('virtualhostroot-http-port', '80'), ('virtualhostroot-https-port', '443')] %}
{%-     do slave_instance.__setitem__(key, int(slave_instance.get(key, default))) %}
{%-   endfor %}
{%-   do slave_instance.__setitem__('default-path', slave_instance.get('default-path', '').strip('/') | urlencode) %}
{%-   do slave_instance.__setitem__('path', slave_instance.get('path', '').strip('/')) %}
{#-   Manage ciphers #}
{%-   set slave_ciphers = slave_instance.get('ciphers', '').strip().split() %}
{%-   if slave_ciphers %}
{%-     set slave_cipher_list = ' '.join(slave_ciphers) %}
{%-   else %}
{%-     set slave_cipher_list = configuration['ciphers'].strip() %}
{%-   endif %}
{%-   do slave_instance.__setitem__('ciphers', slave_cipher_list) %}
{#-   Manage common instance parameters #}
{%-   set slave_type = slave_instance.get('type', '') %}
{%-   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 #}
{%-   if slave_type == 'redirect' %}
{%-     do slave_instance.__setitem__('backend-http-url', slave_instance.get('url', '').rstrip('/')) %}
{%-     if slave_instance.get('https-url') %}
{%-       do slave_instance.__setitem__('backend-https-url', slave_instance.get['https-url'].rstrip('/')) %}
{%-     endif %}
{%-   elif enable_cache %}
{%-     if 'domain' in slave_instance %}
{%-       if not slave_instance.get('custom_domain') %}
{%-         do slave_instance.__setitem__('custom_domain', slave_instance.get('domain')) %}
{%-       endif %}
{%-     endif %}
{%-     do slave_instance.__setitem__('backend-http-url', cache_access) %}
{%-     if slave_instance.get('https-url') %}
{%-       do slave_instance.__setitem__('backend-https-url', ssl_cache_access) %}
{%-     endif %}
{%-     do cached_server_dict.__setitem__(slave_reference, slave_configuration_section_name) %}
{%-   else %}
{%-     do slave_instance.__setitem__('backend-http-url', backend_haproxy_http_url) %}
{%-     if slave_instance.get('https-url') %}
{%-       do slave_instance.__setitem__('backend-https-url', backend_haproxy_https_url) %}
{%-     endif %}
{%-   endif %}
{%-   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 %}
{%-   set slave_logrotate_section = slave_reference + "-logs" %}
{%-   set slave_log_directory_section = slave_reference + "-log-directory" %}
{%-   set slave_password_section = slave_reference + "-password" %}
{%-   set slave_htpasswd_section = slave_reference + "-htpasswd" %}
{%-   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', 'strict-transport-security'] %}
{%-     if slave_instance.get(key, '') == '' %}
{%-       do slave_instance.__setitem__(key, configuration[key]) %}
{%-     endif %}
{%-   endfor %}
{%-   do slave_instance.__setitem__('strict-transport-security', int(slave_instance['strict-transport-security'])) %}
{%-   do slave_instance.__setitem__('authenticate-to-backend', ('' ~ slave_instance.get('authenticate-to-backend', '')).lower() in TRUE_VALUES) %}
{#-   Setup active check #}
{%-   do slave_instance.__setitem__('health-check',  ('' ~ slave_instance.get('health-check', '')).lower() in TRUE_VALUES) %}
{%-   if slave_instance['health-check']  %}
{%-     if 'health-check-http-method' not in slave_instance %}
{%-       do slave_instance.__setitem__('health-check-http-method', 'GET') %}
{%-     endif %}
{%-     if 'health-check-http-version' not in slave_instance %}
{%-       do slave_instance.__setitem__('health-check-http-version', 'HTTP/1.1') %}
{%-     endif %}
{%-     if 'health-check-interval' not in slave_instance %}
{%-       do slave_instance.__setitem__('health-check-interval', '5') %}
{%-     endif %}
{%-     if 'health-check-rise' not in slave_instance %}
{%-       do slave_instance.__setitem__('health-check-rise', '1') %}
{%-     endif %}
{%-     if 'health-check-fall' not in slave_instance %}
{%-       do slave_instance.__setitem__('health-check-fall', '2') %}
{%-     endif %}
{%-     if 'health-check-timeout' not in slave_instance %}
{%-       do slave_instance.__setitem__('health-check-timeout', '2') %}
{%-     endif %}
{%-     do slave_instance.__setitem__('health-check-http-path', slave_instance.get('health-check-http-path') or '/') %}
{%-   else %}
{%-     do slave_instance.__setitem__('health-check-http-method', '') %}
{%-     do slave_instance.__setitem__('health-check-http-version', '') %}
{%-     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_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) %}
{%-   set furled = furl_module.furl(frontend_configuration['slave-introspection-secure_access']) %}
{%-   do furled.set(username = slave_reference.lower()) %}
{%-   do furled.set(password = '${'+ slave_password_section +':passwd}') %}
{%-   do furled.set(path = slave_reference.lower() + '/') %}
{#-   We unquote, as furl quotes automatically, but there is buildout value on purpose like ${...:...} in the passwod #}
{%-   set slave_log_access_url = urlparse_module.unquote(furled.tostr()) %}
{%-   do slave_publish_dict.__setitem__('log-access', slave_log_access_url) %}
{%-   do slave_publish_dict.__setitem__('slave-reference', slave_reference) %}
{%-   do slave_publish_dict.__setitem__('backend-client-caucase-url', backend_client_caucase_url) %}
{#-   Set slave domain if none was defined #}
{%-   if slave_instance.get('custom_domain', None) == None %}
{%-     set domain_prefix = slave_instance.get('slave_reference').replace("-", "").replace("_", "").lower() %}
{%-     do slave_instance.__setitem__('custom_domain', "%s.%s" % (domain_prefix, slapparameter_dict.get('domain'))) %}
{%-   endif %}
{%-   do slave_publish_dict.__setitem__('domain', slave_instance.get('custom_domain')) %}
{%-   do slave_publish_dict.__setitem__('url', "http://%s" % slave_instance.get('custom_domain')) %}
{%-   do slave_publish_dict.__setitem__('site_url', "http://%s" % slave_instance.get('custom_domain')) %}
{%-   do slave_publish_dict.__setitem__('secure_access', 'https://%s' % slave_instance.get('custom_domain')) %}
{%-   set host_list = slave_instance.get('server-alias', '').split() %}
{%-   if slave_instance.get('custom_domain') not in host_list %}
{%-     do host_list.append(slave_instance.get('custom_domain')) %}
{%-   endif %}
{%-   do slave_instance.__setitem__('host_list', host_list) %}
{%-   do slave_instance.__setitem__('type', slave_instance.get('type', '')) %}
{%-   set websocket_path_list = [] %}
{%-   for websocket_path in slave_instance.get('websocket-path-list', '').split() %}
{%-     set websocket_path = websocket_path.strip('/') %}
{#-   Unquote the path, so %20 and similar can be represented correctly #}
{%-     set websocket_path = urllib_module.unquote(websocket_path.strip()) %}
{%-     if websocket_path %}
{%-       do websocket_path_list.append(websocket_path) %}
{%-     endif %}
{%-   endfor %}
{%-   do slave_instance.__setitem__('websocket-path-list', websocket_path_list) %}
{%-   do slave_instance.__setitem__('enable_h2', not configuration['global-disable-http2'] and slave_instance['enable-http2']) %}
{%-   if slave_instance['type'] in ['notebook', 'websocket'] %}
{#    websocket style needs http 1.1 max #}
{%-     do slave_instance.__setitem__('enable_h2', False) %}
{%-   endif %}
{%-   do slave_instance.__setitem__('default-path', slave_instance.get('default-path', '').strip('/') | urlencode) %}

[slave-log-directory-dict]
{{slave_reference}} = {{ slave_log_folder }}

[slave-password]
{{ slave_reference }} = {{ '${' + slave_password_section + ':passwd}' }}

[slave-htpasswd]
{{ slave_reference }} = {{ '${' + slave_htpasswd_section + ':file}' }}

{#-   Set slave logrotate entry #}
[{{slave_log_directory_section}}]
recipe = slapos.cookbook:mkdirectory
log-directory = {{ '${slave-log-directory-dict:' + slave_reference.lower() + '}' }}

[{{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')}}
backup = {{ '${' + slave_log_directory_section + ':log-directory}' }}
rotate-num = {{ dumps('' ~ configuration['rotate-num']) }}
# disable delayed compression, as log filenames shall be stable
delaycompress =

{#-   integrate current logs inside #}

[{{slave_ln_section}}]
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

{#-   Set password for slave #}

[{{slave_password_section}}]
recipe = slapos.cookbook:generate.password
storage-path = {{caddy_configuration_directory}}/.{{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
{#- 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}

{#-   ################################################## #}
{#-   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) %}
{%-   do slave_parameter_dict.__setitem__('certificate', certificate )%}
{#-   Set ssl certificates for each slave #}
{%-     for cert_name in ('ssl_csr', '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('-','.')]) %}
{%-         do part_list.append(cert_title) %}
{%-         do slave_parameter_dict.__setitem__(cert_name, cert_file) %}
{%-         do slave_instance.__setitem__(cert_file_key, cert_file) %}
{#-         Store certificates on fs #}
[{{ cert_title }}]
< = jinja2-template-base
template = {{ empty_template }}
rendered = {{ cert_file }}
extra-context =
    key content {{ cert_title + '-config:value' }}
{#-         BBB: SlapOS Master non-zero knowledge BEGIN #}
{#-         Store certificate in config #}
[{{ cert_title + '-config' }}]
value = {{ dumps(slave_instance.get(cert_name)) }}
{%-       else %}
{%-         do slave_instance.__setitem__(cert_file_key, None) %}
{%-       endif %} {#- if cert_name in slave_instance #}
{%-     endfor %}
{#-   Set Up Certs #}
{%-   if 'ssl_key' in slave_instance and 'ssl_crt' in slave_instance %}
{%-     set cert_title = '%s-crt' % (slave_reference) %}
{%-     set cert_file = '/'.join([directory['bbb-ssl-dir'], cert_title.replace('-','.')]) %}
{%-     do kedifa_updater_mapping.append((key_download_url, certificate, cert_file)) %}
{%-     do part_list.append(cert_title) %}
{%-     do slave_parameter_dict.__setitem__("ssl_crt", cert_file) %}

[{{cert_title}}]
< = jinja2-template-base
template = {{ empty_template }}
rendered = {{ cert_file }}
cert-content = {{ dumps(slave_instance.get('ssl_crt') + '\n' + slave_instance.get('ssl_ca_crt', '') + '\n' + slave_instance.get('ssl_key')) }}
extra-context =
    key content :cert-content
{%-   else %}
{%-     do kedifa_updater_mapping.append((key_download_url, certificate, caddy_configuration['master-certificate'])) %}
{%-   endif %}
{#-   BBB: SlapOS Master non-zero knowledge END #}

{#-   ########################################## #}
{#-   Set Slave Configuration                    #}

[{{ slave_configuration_section_name }}]
certificate = {{ certificate }}
https_port = {{ dumps('' ~ configuration['port']) }}
http_port = {{ dumps('' ~ configuration['plain_http_port']) }}
local_ipv4 = {{ dumps('' ~ instance_parameter_dict['ipv4-random']) }}
{%-   for key, value in slave_instance.iteritems() %}
{%-     if value is not none %}
{{ key }} = {{ dumps(value) }}
{%-     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') %}
{%-     do part_list.append(monitor_ipv6_section_title) %}
[{{ monitor_ipv6_section_title }}]
<= monitor-promise-base
module = check_icmp_packet_lost
name = {{ monitor_ipv6_section_title }}.py
config-address = {{ dumps(monitor_ipv6_test) }}
# promise frequency in minutes (2 times/day)
config-frequency = 720
{%-   endif %}
{%-   set monitor_ipv4_test = slave_instance.get('monitor-ipv4-test', '') %}
{%-   if monitor_ipv4_test %}
{%-     set monitor_ipv4_section_title = 'check-%s-ipv4-packet-list-test' % slave_instance.get('slave_reference') %}
{%-     do part_list.append(monitor_ipv4_section_title) %}
[{{ monitor_ipv4_section_title }}]
<= monitor-promise-base
module = check_icmp_packet_lost
name = {{ monitor_ipv4_section_title }}.py
config-address = {{ dumps(monitor_ipv4_test) }}
config-ipv4 = true
# promise frequency in minutes (2 times/day)
config-frequency = 720
{%-   endif %}

{#-   ###############################  #}
{#-   Publish Slave Information        #}
{%-   if not configuration['extra_slave_instance_list'] %}
{%-     set publish_section_title = 'publish-%s-connection-information' % slave_instance.get('slave_reference') %}
{%-     do part_list.append(publish_section_title) %}
[{{ publish_section_title }}]
recipe = slapos.cookbook:publish
{%-     for key, value in slave_publish_dict.iteritems() %}
{{ key }} = {{ value }}
{%-     endfor %}
{%-   else %}
{%-     do slave_instance_information_list.append(slave_publish_dict) %}
{%-   endif %}
{%-  do frontend_slave_list.append(slave_instance) %}
{%-  if slave_type != 'redirect' %}
{%-    do backend_slave_list.append(slave_instance) %}
{%-  endif %}
{%- endfor %} {# Slave iteration ends for slave_instance in slave_instance_list #}

{%- do part_list.append('slave-introspection') %}
{#- ############################################## #}
{#- ## Prepare virtualhost for slaves using cache  #}
{#- Define IPv6 to IPV4 tunneling #}
[tunnel-6to4-base]
recipe = slapos.cookbook:wrapper
ipv4 = ${slap-network-information:local-ipv4}
ipv6 = ${slap-network-information:global-ipv6}
wrapper-path = {{ directory['service'] }}/6tunnel-${:ipv6-port}
command-line = {{ software_parameter_dict['sixtunnel'] }}/bin/6tunnel -6 -4 -d -l ${:ipv6} ${:ipv6-port} ${:ipv4} ${:ipv4-port}
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg

[tunnel-6to4-base-http_port]
<= tunnel-6to4-base
ipv4-port = {{ configuration['plain_http_port'] }}
ipv6-port = {{ configuration['plain_http_port'] }}

[tunnel-6to4-base-https_port]
<= tunnel-6to4-base
ipv4-port = {{ configuration['port'] }}
ipv6-port = {{ configuration['port'] }}

[slave-introspection-parameters]
local-ipv4 = {{ dumps(instance_parameter_dict['ipv4-random']) }}
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']) }}
var = {{ directory['slave-introspection-var'] }}
pid = {{ caddy_configuration['slave-introspection-pid-file'] }}

[slave-introspection-config]
<= jinja2-template-base
template = {{ software_parameter_dict['template_slave_introspection_httpd_nginx'] }}
rendered = {{ frontend_configuration['slave-introspection-configuration'] }}
extra-context =
    section slave_log_directory slave-log-directory-dict
    section slave_htpasswd slave-htpasswd
    section parameter_dict slave-introspection-parameters

[slave-introspection]
recipe = slapos.cookbook:wrapper
command-line = {{ software_parameter_dict['nginx'] }}
  -c ${slave-introspection-config:rendered}

wrapper-path = {{ directory['service'] }}/slave-instrospection-nginx
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg



{#- Publish information for the instance #}
[publish-caddy-information]
recipe = slapos.cookbook:publish.serialised
{%- if configuration['extra_slave_instance_list'] %}
{#-   sort_keys are important in order to avoid shuffling parameters on each run #}
slave-instance-information-list = {{ json_module.dumps(slave_instance_information_list, sort_keys=True) }}
{%- endif %}
monitor-base-url = {{ monitor_base_url }}
csr_id-url = https://[${expose-csr_id-configuration:ip}]:${expose-csr_id-configuration:port}/csr_id.txt
backend-client-csr_id-url = https://[${expose-csr_id-configuration:ip}]:${expose-csr_id-configuration:port}/backend-haproxy-csr_id.txt
csr_id-certificate = ${get-csr_id-certificate:certificate}
{%-   set furled = furl_module.furl(backend_haproxy_configuration['statistic-frontend-secure_access']) %}
{%-   do furled.set(username = backend_haproxy_configuration['statistic-username']) %}
{%-   do furled.set(password = backend_haproxy_configuration['statistic-password']) %}
{%-   do furled.set(path = '/') %}
{#-   We unquote, as furl quotes automatically, but there is buildout value on purpose like ${...:...} in the passwod #}
{%-   set statistic_url = urlparse_module.unquote(furled.tostr()) %}
backend-haproxy-statistic-url = {{ statistic_url }}

[kedifa-updater]
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'] }}"
  ${kedifa-updater-mapping:file}
  {{ kedifa_configuration['kedifa-updater-state-file'] }}

wrapper-path = {{ directory['service'] }}/kedifa-updater
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg

[kedifa-updater-run]
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'] }}"
update-command = ${:command}

[kedifa-updater-mapping]
recipe = slapos.recipe.template:jinja2
file = {{ kedifa_configuration['kedifa-updater-mapping-file'] }}
template = inline:
{%- for mapping in kedifa_updater_mapping %}
  {{ mapping[0] }} {{ mapping[1] }} {{ mapping[2] }}
{%- endfor %}

rendered = ${:file}

##<Backend haproxy>
[backend-haproxy-configuration]
< = jinja2-template-base
template = {{ template_backend_haproxy_configuration }}
rendered = ${backend-haproxy-config:file}
backend_slave_list = {{ dumps(sorted(backend_slave_list)) }}
extra-context =
  key backend_slave_list :backend_slave_list
  section configuration backend-haproxy-config

[backend-haproxy-config]
{%- for key, value in backend_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']) }}
backend-connect-timeout = {{ dumps('' ~ configuration['backend-connect-timeout']) }}
backend-connect-retries =  {{ dumps('' ~ configuration['backend-connect-retries']) }}

[store-backend-haproxy-csr_id]
recipe = plone.recipe.command

csr_id_path = {{ directory['csr_id'] }}/backend-haproxy-csr_id.txt
csr_work_path = {{ directory['tmp'] }}/${:_buildout_section_name_}

stop-on-error = False
update-command = ${:command}
command =
  {{ software_parameter_dict['bin_directory'] }}/caucase \
    --ca-url {{ backend_haproxy_configuration['caucase-url'] }} \
    --ca-crt {{ backend_haproxy_configuration['cas-ca-certificate'] }} \
    --crl {{ backend_haproxy_configuration['crl'] }} \
    --mode service \
    --send-csr {{ backend_haproxy_configuration['csr'] }} > ${:csr_work_path} && \
  cut -d ' ' -f 1 ${:csr_work_path} > ${:csr_id_path}

##<Backend haproxy>

[buildout]
extends =
  {{ profile_common }}
  {{ profile_logrotate_base }}
  {{ profile_monitor }}

parts +=
    kedifa-updater
    kedifa-updater-run
    backend-haproxy-configuration
    promise-logrotate-setup
{%- for part in part_list %}
{{ '    %s' % part }}
{%- endfor %}
    publish-caddy-information
    tunnel-6to4-base-http_port
    tunnel-6to4-base-https_port
    expose-csr_id
    promise-expose-csr_id-ip-port

cache-access = {{ cache_access }}

[store-csr_id]
recipe = plone.recipe.command

csr_id_path = {{ directory['csr_id'] }}/csr_id.txt
csr_work_path = {{ directory['tmp'] }}/${:_buildout_section_name_}

stop-on-error = False
update-command = ${:command}
command =
  {{ software_parameter_dict['bin_directory'] }}/caucase \
    --ca-url {{ kedifa_configuration['caucase-url'] }} \
    --ca-crt {{ kedifa_configuration['cas-ca-certificate'] }} \
    --crl {{ kedifa_configuration['crl'] }} \
    --mode service \
    --send-csr {{ kedifa_configuration['csr'] }} > ${:csr_work_path} && \
  cut -d ' ' -f 1 ${:csr_work_path} > ${:csr_id_path}

[certificate-csr_id]
recipe = plone.recipe.command
certificate = {{ directory['certificate-csr_id'] }}/certificate.pem
key = {{ directory['certificate-csr_id'] }}/key.pem

{#- Can be stopped on error, as does not rely on self provided service #}
stop-on-error = True
update-command = ${:command}
command =
  if ! [ -f ${:key} ] && ! [ -f ${:certificate} ] ; then
    openssl req -new -newkey rsa:2048 -sha256 -subj \
      "/O={{ expose_csr_id_organization }}/OU={{ expose_csr_id_organizational_unit }}/CN=${slap-network-information:global-ipv6}" \
      -days 5 -nodes -x509 -keyout ${:key} -out ${:certificate}
  fi

[expose-csr_id-configuration]
ip = ${slap-network-information:global-ipv6}
port = 17001
key = ${certificate-csr_id:key}
certificate = ${certificate-csr_id:certificate}
error-log = {{ directory['log'] }}/expose-csr_id.log

[expose-csr_id-template]
recipe = slapos.recipe.template:jinja2
var = {{ directory['expose-csr_id-var'] }}
pid = {{ directory['var'] }}/nginx-expose-csr_id.pid
rendered = {{ directory['etc'] }}/nginx-expose-csr_id.conf
template = inline:
  daemon off;
  pid ${:pid};
  error_log ${expose-csr_id-configuration:error-log};
  events {
  }
  http {
    include {{ software_parameter_dict['nginx_mime'] }};
    server {
      server_name_in_redirect off;
      port_in_redirect off;
      error_log ${expose-csr_id-configuration:error-log};
      access_log /dev/null;
      listen [${expose-csr_id-configuration:ip}]:${expose-csr_id-configuration:port} ssl;                                                          
      ssl_certificate ${expose-csr_id-configuration:certificate};
      ssl_certificate_key ${expose-csr_id-configuration:key};
      default_type application/octet-stream;
      client_body_temp_path ${:var} 1 2;
      proxy_temp_path ${:var} 1 2;
      fastcgi_temp_path ${:var} 1 2;
      uwsgi_temp_path ${:var} 1 2;
      scgi_temp_path ${:var} 1 2;

      location / {
        alias {{ directory['csr_id'] }}/;
        autoindex off;
        sendfile on;
        sendfile_max_chunk 1m;
      }
    }
  }

[promise-expose-csr_id-ip-port]
<= monitor-promise-base
module = check_port_listening
name = expose-csr_id-ip-port-listening.py
config-hostname = ${expose-csr_id-configuration:ip}
config-port = ${expose-csr_id-configuration:port}

[expose-csr_id]
depends =
  ${store-csr_id:command}
  ${store-backend-haproxy-csr_id:command}
recipe = slapos.cookbook:wrapper
command-line = {{ software_parameter_dict['nginx'] }}
  -c ${expose-csr_id-template:rendered}

wrapper-path = {{ directory['service'] }}/expose-csr_id
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg

[get-csr_id-certificate]
recipe = collective.recipe.shelloutput
commands =
  certificate = cat ${certificate-csr_id:certificate}

[promise-logrotate-setup]
<= monitor-promise-base
module = check_command_execute
name = ${:_buildout_section_name_}.py
config-command =
  ${logrotate:wrapper-path} -d
{%- endif %} {# if software_type == slap_software_type #}
