apache-custom-slave-list.cfg.in 26.7 KB
Newer Older
1 2 3
{%- if software_type == slap_software_type %}
{%- set kedifa_updater_mapping = [] %}
{%- set cached_server_dict = {} %}
4
{%- set backend_slave_list = [] %}
5 6
{%- set part_list = [] %}
{%- set cache_port = caddy_configuration.get('cache-port') %}
7 8 9 10
{%- 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']) %}
11
{%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] %}
12
{%- 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']} %}
13
{%- set slave_log_dict = {} %}
14
{%- set slave_instance_information_list = [] %}
15
{%- set slave_instance_list = instance_parameter_dict['slave-instance-list'] %}
16 17
{%- if configuration['extra_slave_instance_list'] %}
{%-   do slave_instance_list.extend(json_module.loads(configuration['extra_slave_instance_list'])) %}
18 19
{%- endif %}
{%- if master_key_download_url %}
20
{%-   do kedifa_updater_mapping.append((master_key_download_url, caddy_configuration['master-certificate'], apache_certificate)) %}
21
{%- else %}
22
{%-   do kedifa_updater_mapping.append(('notreadyyet', caddy_configuration['master-certificate'], apache_certificate)) %}
23
{%- endif %}
24 25
{%- if kedifa_configuration['slave_kedifa_information'] %}
{%-   set slave_kedifa_information = json_module.loads(kedifa_configuration['slave_kedifa_information']) %}
26 27 28
{%- else %}
{%-   set slave_kedifa_information = {} %}
{%- endif -%}
29 30 31 32 33
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
extra-context =
context =
34
    raw profile_common {{ profile_common }}
35 36
    ${:extra-context}

37 38 39
# empty sections if no slaves are available
[slave-log-directory-dict]
[slave-password]
40
[slave-htpasswd]
41

42
{#- Loop thought slave list to set up slaves #}
43
{%- set DEFAULT_PORT = {'http': 80, 'https': 443, '': None} %}
44
{%- for slave_instance in slave_instance_list %}
45 46
{#- prepare backend parameters #}
{%- for key, prefix in [('url', 'http_backend'), ('https-url', 'https_backend')] %}
47
{%-   set parsed = urlparse_module.urlparse(slave_instance.get(key, '').strip()) %}
48 49 50 51
{%-   set info_dict = {'scheme': parsed.scheme, 'hostname': parsed.hostname, 'port': parsed.port or DEFAULT_PORT[parsed.scheme], 'path': parsed.path, 'fragment': parsed.fragment} %}
{%-   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) %}
52 53 54 55 56
{#-   Manage ciphers #}
{%-   set slave_ciphers = slave_instance.get('ciphers', '').strip().split() %}
{%-   if slave_ciphers %}
{%-     set slave_cipher_list = ' '.join(slave_ciphers) %}
{%-   else %}
57
{%-     set slave_cipher_list = configuration['ciphers'].strip() %}
58 59
{%-   endif %}
{%-   do slave_instance.__setitem__('cipher_list', slave_cipher_list) %}
60
{#-   Manage common instance parameters #}
61 62 63 64
{%-   set slave_type = slave_instance.get('type', '') %}
{%-   set enable_cache = (('' ~ slave_instance.get('enable_cache', '')).lower() in TRUE_VALUES and slave_type != 'redirect') %}
{%-   set slave_reference = slave_instance.get('slave_reference') %}
{%-   set slave_kedifa = slave_kedifa_information.get(slave_reference) %}
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
{#-   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 %}
88 89 90 91 92 93 94 95 96 97
{%-   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" %}
98
{%-   set slave_log_directory_section = slave_reference + "-log-directory" %}
99
{%-   set slave_password_section = slave_reference + "-password" %}
100
{%-   set slave_htpasswd_section = slave_reference + "-htpasswd" %}
101 102 103
{%-   set slave_ln_section = slave_reference + "-ln" %}
{#-   extend parts #}
{%-   do part_list.extend([slave_ln_section]) %}
104
{%-   do part_list.extend([slave_section_title]) %}
105 106
{%-   set slave_log_folder = '${logrotate-directory:logrotate-backup}/' + slave_reference + "-logs" %}
{#-   Pass HTTP2 switch #}
107 108
{%-   do slave_instance.__setitem__('enable_http2_by_default', configuration['enable-http2-by-default']) %}
{%-   do slave_instance.__setitem__('global_disable_http2', configuration['global-disable-http2']) %}
109
{#-   Pass backend timeout values #}
110
{%-   for key in ['backend-connect-timeout', 'backend-connect-retries', 'request-timeout', 'authenticate-to-backend'] %}
111 112 113 114
{%-     if slave_instance.get(key, '') == '' %}
{%-       do slave_instance.__setitem__(key, configuration[key]) %}
{%-     endif %}
{%-   endfor %}
115
{%-   do slave_instance.__setitem__('authenticate-to-backend', ('' ~ slave_instance.get('authenticate-to-backend', '')).lower() in TRUE_VALUES) %}
116 117 118
{#-   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])) %}
119
{%-   do slave_parameter_dict.__setitem__('backend_log', '/'.join([caddy_log_directory, '%s_backend_log' % slave_reference])) %}
120 121
{%-   do slave_instance.__setitem__('access_log', slave_parameter_dict.get('access_log')) %}
{%-   do slave_instance.__setitem__('error_log', slave_parameter_dict.get('error_log')) %}
122
{%-   do slave_instance.__setitem__('backend_log', slave_parameter_dict.get('backend_log')) %}
123 124
{#-   Add slave log directory to the slave log access dict #}
{%-   do slave_log_dict.__setitem__(slave_reference, slave_log_folder) %}
125 126 127 128 129 130
{%-   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()) %}
131 132
{%-   do slave_publish_dict.__setitem__('log-access', slave_log_access_url) %}
{%-   do slave_publish_dict.__setitem__('slave-reference', slave_reference) %}
133
{%-   do slave_publish_dict.__setitem__('public-ipv4', configuration['public-ipv4']) %}
134
{%-   do slave_publish_dict.__setitem__('backend-client-caucase-url', backend_client_caucase_url) %}
135 136 137 138 139 140 141 142 143
{#-   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')) %}
144

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

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

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

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

159
[{{slave_logrotate_section}}]
160
<= logrotate-entry-base
161
name = ${:_buildout_section_name_}
162
log = {{slave_parameter_dict.get('access_log')}} {{slave_parameter_dict.get('error_log')}} {{slave_parameter_dict.get('backend_log')}}
163
backup = {{ '${' + slave_log_directory_section + ':log-directory}' }}
164
rotate-num = {{ dumps('' ~ configuration['rotate-num']) }}
165 166
# disable delayed compression, as log filenames shall be stable
delaycompress =
167 168

{#-   integrate current logs inside #}
169 170 171 172

[{{slave_ln_section}}]
recipe = plone.recipe.command
stop-on-error = false
173 174
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
175

176 177
{#-   Set password for slave #}

178 179
[{{slave_password_section}}]
recipe = slapos.cookbook:generate.password
180
storage-path = {{caddy_configuration_directory}}/.{{slave_reference}}.passwd
181 182
bytes = 8

183 184
[{{ slave_htpasswd_section }}]
recipe = plone.recipe.command
185
{#- Can be stopped on error, as does not rely on self provided service #}
186 187
stop-on-error = True
file = {{ caddy_configuration_directory }}/.{{ slave_reference }}.htpasswd
188 189 190
{#- 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}
191

192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
{#-   ################################################## #}
{#-   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')%}
{%-       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__('path_to_' + cert_name, cert_file) %}
{#-         Store certificates on fs #}
207 208 209 210 211 212
[{{ cert_title }}]
< = jinja2-template-base
template = {{ empty_template }}
rendered = {{ cert_file }}
extra-context =
    key content {{ cert_title + '-config:value' }}
213 214
{#-         BBB: SlapOS Master non-zero knowledge BEGIN #}
{#-         Store certificate in config #}
215 216
[{{ cert_title + '-config' }}]
value = {{ dumps(slave_instance.get(cert_name)) }}
217 218
{%-       endif %}
{%-     endfor %}
219
{#-   Set Up Certs #}
220 221
{%-   if 'ssl_key' in slave_instance and 'ssl_crt' in slave_instance %}
{%-     set cert_title = '%s-crt' % (slave_reference) %}
222
{%-     set cert_file = '/'.join([directory['bbb-ssl-dir'], cert_title.replace('-','.')]) %}
223 224 225
{%-     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) %}
226 227 228 229 230

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

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

242
[{{ slave_configuration_section_name }}]
243
certificate = {{ certificate }}
244 245
https_port = {{ dumps('' ~ configuration['port']) }}
http_port = {{ dumps('' ~ configuration['plain_http_port']) }}
246
local_ipv4 = {{ dumps('' ~ instance_parameter_dict['ipv4-random']) }}
247 248
{%-   for key, value in slave_instance.iteritems() %}
{%-     if value is not none %}
249
{{ key }} = {{ dumps('' ~ value) }}
250 251
{%-     endif %}
{%-   endfor %}
252 253 254

[{{ slave_section_title }}]
< = jinja2-template-base
255
rendered = {{ caddy_configuration_directory }}/${:filename}
256 257

template = {{ template_default_slave_configuration }}
258 259 260
extra-context =
    section slave_parameter {{ slave_configuration_section_name }}
    import urllib_module urllib
261 262 263 264 265

filename = {{ '%s.conf' % slave_reference }}
{{ '\n' }}


266 267 268 269
{%-   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) %}
270
[{{ monitor_ipv6_section_title }}]
271
<= monitor-promise-base
272 273 274 275 276
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
277 278 279 280 281
{%-   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) %}
282
[{{ monitor_ipv4_section_title }}]
283
<= monitor-promise-base
284 285 286 287 288 289
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
290
{%-   endif %}
291

292 293
{#-   ###############################  #}
{#-   Publish Slave Information        #}
294
{%-   if not configuration['extra_slave_instance_list'] %}
295 296
{%-     set publish_section_title = 'publish-%s-connection-information' % slave_instance.get('slave_reference') %}
{%-     do part_list.append(publish_section_title) %}
297 298
[{{ publish_section_title }}]
recipe = slapos.cookbook:publish
299
{%-     for key, value in slave_publish_dict.iteritems() %}
300
{{ key }} = {{ value }}
301 302 303 304
{%-     endfor %}
{%-   else %}
{%-     do slave_instance_information_list.append(slave_publish_dict) %}
{%-   endif %}
305 306 307
{%-  if slave_type != 'redirect' %}
{%-    do backend_slave_list.append(slave_instance) %}
{%-  endif %}
308
{%- endfor %} {# Slave iteration ends for slave_instance in slave_instance_list #}
309

310
{%- do part_list.append('caddy-log-access') %}
311
{%- do part_list.append('slave-introspection') %}
312 313
{#- ############################################## #}
{#- ## Prepare virtualhost for slaves using cache  #}
314 315 316 317 318
{#- Define IPv6 to IPV4 tunneling #}
[tunnel-6to4-base]
recipe = slapos.cookbook:wrapper
ipv4 = ${slap-network-information:local-ipv4}
ipv6 = ${slap-network-information:global-ipv6}
319
wrapper-path = {{ directory['service'] }}/6tunnel-${:ipv6-port}
320
command-line = {{ software_parameter_dict['sixtunnel'] }}/bin/6tunnel -6 -4 -d -l ${:ipv6} ${:ipv6-port} ${:ipv4} ${:ipv4-port}
321
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
322 323 324

[tunnel-6to4-base-http_port]
<= tunnel-6to4-base
325 326
ipv4-port = {{ configuration['plain_http_port'] }}
ipv6-port = {{ configuration['plain_http_port'] }}
327 328 329

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

333 334
{#- Define log access #}

335 336 337
[caddy-log-access-parameters]
caddy_log_directory = {{ dumps(caddy_log_directory) }}
caddy_configuration_directory = {{ dumps(caddy_configuration_directory) }}
338
local_ipv4 = {{ dumps(instance_parameter_dict['ipv4-random']) }}
339
global_ipv6 = {{ dumps(global_ipv6) }}
340 341
https_port = {{ dumps(configuration['port']) }}
http_port = {{ dumps(configuration['plain_http_port']) }}
342
ip_access_certificate = {{ frontend_configuration.get('ip-access-certificate') }}
343 344 345
access_log = {{ dumps(caddy_configuration['access-log']) }}
error_log = {{ dumps(caddy_configuration['error-log']) }}
not_found_file = {{ dumps(caddy_configuration['not-found-file']) }}
346

347
[caddy-log-access]
348
< = jinja2-template-base
349
template = {{ software_parameter_dict['template_log_access'] }}
350 351
rendered = {{frontend_configuration.get('log-access-configuration')}}
extra-context =
352 353
    section slave_log_directory slave-log-directory-dict
    section slave_password slave-password
354
    section parameter_dict caddy-log-access-parameters
355

356
[slave-introspection-parameters]
357
local-ipv4 = {{ dumps(instance_parameter_dict['ipv4-random']) }}
358 359 360
global-ipv6 = {{ dumps(global_ipv6) }}
https-port = {{ frontend_configuration['slave-introspection-https-port'] }}
ip-access-certificate = {{ frontend_configuration.get('ip-access-certificate') }}
361
nginx-mime = {{ software_parameter_dict['nginx_mime'] }}
362 363 364 365 366 367 368
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
369
template = {{ software_parameter_dict['template_slave_introspection_httpd_nginx'] }}
370 371 372 373 374 375 376 377
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
378
command-line = {{ software_parameter_dict['nginx'] }}
379 380 381 382 383 384
  -c ${slave-introspection-config:rendered}

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


385

386
{#- Publish information for the instance #}
387
[publish-caddy-information]
388
recipe = slapos.cookbook:publish.serialised
389
public-ipv4 = {{ configuration['public-ipv4'] }}
390
private-ipv4 = {{ instance_parameter_dict['ipv4-random'] }}
391
{%- if configuration['extra_slave_instance_list'] %}
392
{#-   sort_keys are important in order to avoid shuffling parameters on each run #}
393
slave-instance-information-list = {{ json_module.dumps(slave_instance_information_list, sort_keys=True) }}
394
{%- endif %}
395
monitor-base-url = {{ monitor_base_url }}
396
csr_id-url = https://[${expose-csr_id-configuration:ip}]:${expose-csr_id-configuration:port}/csr_id.txt
397
backend-client-csr_id-url = https://[${expose-csr_id-configuration:ip}]:${expose-csr_id-configuration:port}/backend-haproxy-csr_id.txt
398
csr_id-certificate = ${get-csr_id-certificate:certificate}
399 400 401 402 403 404 405
{%-   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 }}
406

407 408
[kedifa-updater]
recipe = slapos.cookbook:wrapper
409
command-line = {{ software_parameter_dict['kedifa-updater'] }}
410 411
  --server-ca-certificate {{ kedifa_configuration['ca-certificate'] }}
  --identity {{ kedifa_configuration['certificate'] }}
412 413
  --master-certificate {{ caddy_configuration['master-certificate'] }}
  --on-update "{{ caddy_configuration['frontend-graceful-command'] }}"
414
  ${kedifa-updater-mapping:file}
415
  {{ kedifa_configuration['kedifa-updater-state-file'] }}
416

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

420 421
[kedifa-updater-run]
recipe = plone.recipe.command
422
{#- Can be stopped on error, as does not rely on self provided service but on service which comes from another partition #}
423
stop-on-error = True
424
command = {{ software_parameter_dict['kedifa-updater'] }} --prepare-only ${kedifa-updater-mapping:file} --on-update "{{ caddy_configuration['frontend-graceful-command'] }}"
425 426
update-command = ${:command}

427 428
[kedifa-updater-mapping]
recipe = slapos.recipe.template:jinja2
429
file = {{ kedifa_configuration['kedifa-updater-mapping-file'] }}
430
template = inline:
431
{%- for mapping in kedifa_updater_mapping %}
432
  {{ mapping[0] }} {{ mapping[1] }} {{ mapping[2] }}
433
{%- endfor %}
434 435 436

rendered = ${:file}

437
[caddy-log-access-empty]
438 439 440
# Caddy refuse to start if an `import`ed file is empty, so we prepend a header
# so that the file is never empty.
< = jinja2-template-base
441
template = inline: # This file contain directives to serve directories with log files for shared instances, but no shared instances are defined yet.
442 443
rendered = {{frontend_configuration.get('log-access-configuration')}}

444 445 446 447 448 449 450 451 452 453 454
##<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]
455 456 457
{%- for key, value in backend_haproxy_configuration.items() %}
{{ key }} = {{ value }}
{%- endfor %}
458
local-ipv4 = {{ dumps('' ~ instance_parameter_dict['ipv4-random']) }}
459
global-ipv6 = ${slap-network-information:global-ipv6}
460 461 462
request-timeout = {{ dumps('' ~ configuration['request-timeout']) }}
backend-connect-timeout = {{ dumps('' ~ configuration['backend-connect-timeout']) }}
backend-connect-retries =  {{ dumps('' ~ configuration['backend-connect-retries']) }}
463 464 465 466 467 468 469 470 471 472

[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 =
473
  {{ software_parameter_dict['bin_directory'] }}/caucase \
474 475 476 477 478 479 480
    --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}

481 482
##<Backend haproxy>

483
[buildout]
484
extends =
485 486 487
  {{ profile_common }}
  {{ profile_logrotate_base }}
  {{ profile_monitor }}
488

489
parts +=
490
    kedifa-updater
491
    kedifa-updater-run
492
    backend-haproxy-configuration
493
    promise-logrotate-setup
494
{%- for part in part_list %}
495
{{ '    %s' % part }}
496 497
{%- endfor %}
{%- if 'caddy-log-access' not in part_list %}
498
    caddy-log-access-empty
499
{%- endif %}
500
    publish-caddy-information
501 502
    tunnel-6to4-base-http_port
    tunnel-6to4-base-https_port
503
    expose-csr_id
504
    promise-expose-csr_id-ip-port
505 506 507

cache-access = {{ cache_access }}

508 509 510
[store-csr_id]
recipe = plone.recipe.command

511 512
csr_id_path = {{ directory['csr_id'] }}/csr_id.txt
csr_work_path = {{ directory['tmp'] }}/${:_buildout_section_name_}
513 514 515 516

stop-on-error = False
update-command = ${:command}
command =
517
  {{ software_parameter_dict['bin_directory'] }}/caucase \
518 519 520
    --ca-url {{ kedifa_configuration['caucase-url'] }} \
    --ca-crt {{ kedifa_configuration['cas-ca-certificate'] }} \
    --crl {{ kedifa_configuration['crl'] }} \
521
    --mode service \
522
    --send-csr {{ kedifa_configuration['csr'] }} > ${:csr_work_path} && \
523 524 525 526
  cut -d ' ' -f 1 ${:csr_work_path} > ${:csr_id_path}

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

530
{#- Can be stopped on error, as does not rely on self provided service #}
531 532 533 534 535
stop-on-error = True
update-command = ${:command}
command =
  if ! [ -f ${:key} ] && ! [ -f ${:certificate} ] ; then
    openssl req -new -newkey rsa:2048 -sha256 -subj \
536
      "/O={{ expose_csr_id_organization }}/OU={{ expose_csr_id_organizational_unit }}/CN=${slap-network-information:global-ipv6}" \
537 538 539 540 541 542 543 544
      -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}
545
error-log = {{ directory['caddy-csr_id-log'] }}/expose-csr_id.log
546 547 548 549 550 551 552 553 554 555

[expose-csr_id-template]
recipe = slapos.recipe.template:jinja2
template = inline:
  https://:${expose-csr_id-configuration:port}/ {
    bind ${expose-csr_id-configuration:ip}
    tls ${expose-csr_id-configuration:certificate} ${expose-csr_id-configuration:key}
    log ${expose-csr_id-configuration:error-log}
  }

556
rendered = {{ directory['caddy-csr_id'] }}/Caddyfile
557

558
[promise-expose-csr_id-ip-port]
559
<= monitor-promise-base
560 561 562 563 564
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}

565
[expose-csr_id]
566 567 568
depends =
  ${store-csr_id:command}
  ${store-backend-haproxy-csr_id:command}
569
recipe = slapos.cookbook:wrapper
570
command-line = {{ software_parameter_dict['caddy'] }}
571 572 573 574
  -conf ${expose-csr_id-template:rendered}
  -log ${expose-csr_id-configuration:error-log}
  -http2=true
  -disable-http-challenge
575
  -disable-tls-alpn-challenge
576
  -root {{ directory['csr_id'] }}
577

578
wrapper-path = {{ directory['service'] }}/expose-csr_id
579
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
580 581 582 583 584 585

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

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