instance-apache-frontend.cfg.in 39.4 KB
Newer Older
1
{%- if instance_parameter_dict['slap-software-type'] == software_type -%}
2
{% import "caucase" as caucase with context %}
Łukasz Nowak's avatar
Łukasz Nowak committed
3
{%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] -%}
4 5
[buildout]
extends =
6 7 8
  {{ software_parameter_dict['profile_common'] }}
  {{ software_parameter_dict['profile_monitor'] }}
  {{ software_parameter_dict['profile_logrotate_base'] }}
9 10 11 12 13 14

parts =
  directory
  logrotate-entry-caddy
  caddy-frontend
  switch-caddy-softwaretype
15
  caucase-updater
16
  caucase-updater-promise
17 18
  backend-client-caucase-updater
  backend-client-caucase-updater-promise
19 20 21 22 23 24 25
  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
26
  promise-logrotate-setup
27 28 29 30 31 32 33 34

  trafficserver-launcher
  trafficserver-reload
  trafficserver-configuration-directory
  trafficserver-records-config
  trafficserver-remap-config
  trafficserver-plugin-config
  trafficserver-storage-config
35
  trafficserver-ip-allow-config
36
  trafficserver-logging-yaml
37 38
  trafficserver-promise-listen-port
  trafficserver-promise-cache-availability
39
  cron-entry-logrotate-trafficserver
40 41 42 43 44 45 46
## 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

47 48 49
  backend-haproxy-rsyslogd-configuration
  backend-haproxy-rsyslogd
  logrotate-entry-backend-haproxy
50 51 52 53 54 55
  backend-haproxy
  backend-haproxy-graceful
  promise-backend-haproxy-http
  promise-backend-haproxy-https
  promise-backend-haproxy-configuration

56 57 58 59 60 61 62 63 64
  slave-introspection-frontend
  slave-introspection-graceful
  promise-slave-introspection-https
  promise-slave-introspection-configuration
  logrotate-entry-slave-introspection

[caddyprofiledeps]
recipe = caddyprofiledeps

65 66 67 68 69 70 71 72
# 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/
73
tmp = ${:var}/tmp
74 75 76 77 78
template = ${buildout:directory}/template/

backup = ${:srv}/backup
log = ${:var}/log
run = ${:var}/run
79
backend-haproxy-rsyslogd-spool = ${:run}/backend-haproxy-rsyslogd-spool
80 81 82 83
service = ${:etc}/service
etc-run = ${:etc}/run

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

89 90
frontend_cluster = ${:var}/frontend_cluster

91 92 93 94 95
# csr_id publication
csr_id = ${:srv}/csr_id
caddy-csr_id = ${:etc}/caddy-csr_id
caddy-csr_id-log = ${:log}/httpd-csr_id

96 97 98
# slave introspection
slave-introspection-var = ${:var}/slave-introspection

99 100
[switch-caddy-softwaretype]
recipe = slapos.cookbook:softwaretype
101 102
single-default = ${dynamic-custom-personal-profile-slave-list:rendered}
single-custom-personal = ${dynamic-custom-personal-profile-slave-list:rendered}
103 104 105

[frontend-configuration]
log-access-configuration = ${directory:etc}/log-access.conf
106
ip-access-certificate = ${self-signed-ip-access:certificate}
107
caddy-ipv6 = {{ instance_parameter_dict['ipv6-random'] }}
108
caddy-https-port = ${configuration:port}
109 110 111 112
slave-introspection-configuration = ${directory:etc}/slave-introspection-httpd-nginx.conf
slave-introspection-https-port = ${configuration:slave-introspection-https-port}
slave-introspection-secure_access = ${slave-introspection-frontend:connection-secure_access}
slave-introspection-domain = ${slave-introspection-frontend:connection-domain}
113

114 115 116 117 118
[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}
119
ipv4 = {{instance_parameter_dict['ipv4-random']}}
120
certificate = ${caddy-directory:master-autocert-dir}/ip-access-${:ipv6}-${:ipv4}.crt
121 122
stop-on-error = True
command =
123 124
  [ -f ${:certificate} ] && exit 0
  rm -f ${:certificate}
125
  /bin/bash -c ' \
126
  {{ software_parameter_dict['openssl'] }} req \
127 128
     -new -newkey rsa:2048 -sha256 \
     -nodes -x509 -days 36500 \
129
     -keyout ${:certificate} \
130 131 132
     -subj "/CN=Self Signed IP Access" \
     -reqexts SAN \
     -extensions SAN \
133
     -config <(cat {{ software_parameter_dict['openssl_cnf'] }} \
134 135 136
         <(printf "\n[SAN]\nsubjectAltName=IP:${:ipv6},IP:${:ipv4}")) \
     -out ${:certificate}'

137 138 139 140 141
[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}
142
ipv4 = {{instance_parameter_dict['ipv4-random']}}
143 144 145 146 147 148
certificate = ${caddy-directory:master-autocert-dir}/fallback-access.crt
stop-on-error = True
command =
  [ -f ${:certificate} ] && exit 0
  rm -f ${:certificate}
  /bin/bash -c ' \
149
  {{ software_parameter_dict['openssl'] }} req \
150 151 152
     -new -newkey rsa:2048 -sha256 \
     -nodes -x509 -days 36500 \
     -keyout ${:certificate} \
153
     -subj "/CN=Fallback certificate/OU={{ instance_parameter_dict['configuration.frontend-name'] }}" \
154 155
     -out ${:certificate}'

156 157 158
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/${:filename}
159
extensions = jinja2.ext.do
160
extra-context =
161
slapparameter_dict = {{ dumps(slapparameter_dict) }}
162
slap_software_type = {{ dumps(instance_parameter_dict['slap-software-type']) }}
163 164
context =
    import json_module json
165 166 167
    raw profile_common {{ software_parameter_dict['profile_common'] }}
    raw profile_logrotate_base {{ software_parameter_dict['profile_logrotate_base'] }}
    raw profile_monitor {{ software_parameter_dict['profile_monitor'] }}
168 169 170 171 172 173
    key slap_software_type :slap_software_type
    key slapparameter_dict :slapparameter_dict
    section directory directory
    ${:extra-context}

[software-release-path]
174 175 176 177 178
template-empty = {{ software_parameter_dict['template_empty'] }}
template-default-slave-virtualhost = {{ software_parameter_dict['template_default_slave_virtualhost'] }}
template-backend-haproxy-configuration = {{ software_parameter_dict['template_backend_haproxy_configuration'] }}
template-backend-haproxy-rsyslogd-conf = {{ software_parameter_dict['template_backend_haproxy_rsyslogd_conf'] }}
caddy-location = {{ software_parameter_dict['caddy_location'] }}
179

180 181
[kedifa-login-config]
d = ${directory:ca-dir}
182
template-csr = ${:d}/kedifa-login-template-csr.pem
183 184 185 186 187 188 189 190 191
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'] }}
192
organizational_unit = {{ instance_parameter_dict['configuration.frontend-name'] }}
193 194
command =
{% if slapparameter_dict['kedifa-caucase-url'] %}
195
  if [ ! -f ${:template-csr} ] && [ ! -f ${:key} ]  ; then
196
    {{ software_parameter_dict['openssl'] }} req -new -sha256 \
197 198
      -newkey rsa:2048 -nodes -keyout ${:key} \
      -subj "/O=${:organization}/OU=${:organizational_unit}" \
199
      -out ${:template-csr}
200 201
  fi
{% endif %}
202
  test -f ${:key} && test -f ${:template-csr}
203
update-command = ${:command}
204
template-csr = ${kedifa-login-config:template-csr}
205 206 207 208 209
key = ${kedifa-login-config:key}
stop-on-error = True

{{ caucase.updater(
     prefix='caucase-updater',
210
     buildout_bin_directory=software_parameter_dict['bin_directory'],
211 212 213 214 215 216 217
     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}',
218
     template_csr='${kedifa-login-csr:template-csr}'
219 220
)}}

221 222 223 224 225 226 227 228 229 230 231
[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-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']) }}

232 233 234 235 236 237 238 239 240 241 242 243
[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'] }}
244
organizational_unit = {{ instance_parameter_dict['configuration.frontend-name'] }}
245 246 247
command =
{% if slapparameter_dict['backend-client-caucase-url'] %}
  if [ ! -f ${:template-csr} ] && [ ! -f ${:key} ]  ; then
248
    {{ software_parameter_dict['openssl'] }} req -new -sha256 \
249 250 251 252 253 254 255 256 257 258 259 260 261
      -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',
262
     buildout_bin_directory=software_parameter_dict['bin_directory'],
263 264 265 266 267 268 269 270 271 272
     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}'
)}}

273
[dynamic-custom-personal-profile-slave-list]
274
< = jinja2-template-base
275
depends = ${caddyprofiledeps:recipe}
276
template = {{ software_parameter_dict['profile_slave_list'] }}
277
filename = custom-personal-instance-slave-list.cfg
278
master_key_download_url = {{ dumps(slapparameter_dict['master-key-download-url']) }}
279
software_type = single-custom-personal
280
organization = {{ slapparameter_dict['cluster-identification'] }}
281
organizational-unit = {{ instance_parameter_dict['configuration.frontend-name'] }}
282
backend-client-caucase-url = {{ slapparameter_dict['backend-client-caucase-url'] }}
283 284
extra-context =
    key caddy_configuration_directory caddy-directory:slave-configuration
285
    key backend_client_caucase_url :backend-client-caucase-url
286
    import urlparse_module urlparse
287
    import furl_module furl
288 289
    key master_key_download_url :master_key_download_url
    key autocert caddy-directory:autocert
290
    key caddy_log_directory caddy-directory:slave-log
291 292
    key expose_csr_id_organization :organization
    key expose_csr_id_organizational_unit :organizational-unit
293 294 295
    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
296
    key software_type :software_type
297 298
    key frontend_lazy_graceful_reload frontend-caddy-lazy-graceful:rendered
    key monitor_base_url monitor-instance-parameter:monitor-base-url 
299
    key custom_ssl_directory caddy-directory:custom-ssl-directory
300
# BBB: SlapOS Master non-zero knowledge BEGIN
301 302
    key apache_certificate apache-certificate:rendered
# BBB: SlapOS Master non-zero knowledge END
303 304
## backend haproxy
    key template_backend_haproxy_configuration software-release-path:template-backend-haproxy-configuration
305
## Configuration passed by section
306
    section configuration configuration
307
    section backend_haproxy_configuration backend-haproxy-configuration
308
    section instance_parameter_dict instance-parameter-section
309 310 311
    section frontend_configuration frontend-configuration
    section caddy_configuration caddy-configuration
    section kedifa_configuration kedifa-configuration
312
    section software_parameter_dict software-parameter-section
313 314 315 316

# Deploy Caddy Frontend with Jinja power
[dynamic-caddy-frontend-template]
< = jinja2-template-base
317
template = {{ software_parameter_dict['template_caddy_frontend_configuration'] }}
318
rendered = ${caddy-configuration:frontend-configuration}
319
local_ipv4 =  {{ dumps(instance_parameter_dict['ipv4-random']) }}
320 321 322 323
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
324
    key master_certificate caddy-configuration:master-certificate
325 326 327 328 329 330 331 332 333 334 335
    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
336 337 338
# BBB: SlapOS Master non-zero knowledge BEGIN
    key apache_certificate apache-certificate:rendered
# BBB: SlapOS Master non-zero knowledge END
339 340

[caddy-wrapper]
341 342 343 344 345
recipe = slapos.recipe.template:jinja2
template = inline:
  #!/bin/sh
  export CADDYPATH=${directory:frontend_cluster}
  ulimit -n $(ulimit -Hn)
346
  exec {{ software_parameter_dict['caddy'] }} \
347 348 349
  -conf ${dynamic-caddy-frontend-template:rendered} \
  -log ${caddy-configuration:error-log} \
  -log-roll-mb 0 \
350
{% if instance_parameter_dict['configuration.global-disable-http2'].lower() in TRUE_VALUES %}
351
  -http2=false \
352
{% else %}
353
  -http2=true \
Łukasz Nowak's avatar
Łukasz Nowak committed
354
{% endif %}
355
  -grace {{ instance_parameter_dict['configuration.mpm-graceful-shutdown-timeout'] }}s \
356 357 358 359 360
  -disable-http-challenge \
  -disable-tls-alpn-challenge \
   "$@"
rendered = ${directory:bin}/caddy-wrapper
mode = 0755
361 362 363

[caddy-frontend]
recipe = slapos.cookbook:wrapper
364
command-line = ${caddy-wrapper:rendered} -pidfile ${caddy-configuration:pid-file}
365
wrapper-path = ${directory:service}/frontend_caddy
366
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
367
hash-files = ${caddy-wrapper:rendered}
368 369

[not-found-html]
370 371 372
recipe = plone.recipe.command
update-command = ${:command}
filename = notfound.html
373
command = ln -sf  {{ software_parameter_dict['template_not_found_html'] }} ${caddy-directory:document-root}/${:filename}
374 375 376 377 378 379 380 381

[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
382 383
autocert = ${directory:srv}/autocert
master-autocert-dir = ${:autocert}/master-autocert
384
custom-ssl-directory = ${:slave-configuration}/ssl
385 386 387 388 389 390

[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
391
frontend-graceful-command = ${frontend-caddy-validate:rendered} && kill -USR1 $(cat ${:pid-file})
392
not-found-file = ${caddy-directory:document-root}/${not-found-html:filename}
393
master-certificate = ${caddy-directory:master-autocert-dir}/master.pem
394 395
# Communication with ATS
cache-port = ${trafficserver-variable:input-port}
396 397 398 399 400
# slave instrspection
slave-introspection-access-log = ${directory:log}/slave-introspection-access.log
slave-introspection-error-log = ${directory:log}/slave-introspection-error.log
slave-introspection-pid-file = ${directory:run}/slave-introspection.pid
slave-introspection-graceful-command = ${slave-introspection-validate:rendered} && kill -HUP $(cat ${:slave-introspection-pid-file})
401

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

408
[apache-certificate]
409 410 411
recipe = slapos.recipe.template:jinja2
template = inline:
{% raw %}
412 413
  {{ certificate or fallback_certificate }}
  {{ key or '' }}
414 415 416 417
{% endraw %}
context =
  key certificate configuration:apache-certificate
  key key configuration:apache-key
418
  key fallback_certificate get-self-signed-fallback-access:certificate
419 420 421
rendered = ${directory:bbb-ssl-dir}/frontend.crt
# BBB: SlapOS Master non-zero knowledge END

422
[logrotate-entry-caddy]
423
<= logrotate-entry-base
424 425
name = caddy
log = ${caddy-configuration:error-log} ${caddy-configuration:access-log}
426
rotate-num = ${configuration:rotate-num}
427 428 429 430 431
# 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.
432
post = ${frontend-caddy-lazy-graceful:rendered} &
433
delaycompress =
434 435 436 437 438 439 440 441

#################
# Trafficserver
#################
[trafficserver-directory]
recipe = slapos.cookbook:mkdirectory
configuration = ${directory:etc}/trafficserver
local-state = ${directory:var}/trafficserver
442
bin_path = {{ software_parameter_dict['trafficserver'] }}/bin
443 444
log = ${directory:log}/trafficserver
cache-path = ${directory:srv}/ats_cache
445
logrotate-backup = ${logrotate-directory:logrotate-backup}/trafficserver
446 447 448 449

[trafficserver-variable]
wrapper-path = ${directory:service}/trafficserver
reload-path = ${directory:etc-run}/trafficserver-reload
450
local-ip = {{ instance_parameter_dict['ipv4-random'] }}
451 452
input-port = 23432
hostname = ${configuration:frontend-name}
453 454
plugin-config =
ip-allow-config = src_ip=0.0.0.0-255.255.255.255 action=ip_allow
455 456 457
cache-path = ${trafficserver-directory:cache-path}
disk-cache-size = ${configuration:disk-cache-size}
ram-cache-size = ${configuration:ram-cache-size}
458
templates-dir = {{ software_parameter_dict['trafficserver'] }}/etc/trafficserver/body_factory
459
request-timeout = ${configuration:request-timeout}
460 461 462

[trafficserver-configuration-directory]
recipe = plone.recipe.command
463
command = cp -rn {{ software_parameter_dict['trafficserver'] }}/etc/trafficserver/* ${:target}
464 465 466 467
target = ${trafficserver-directory:configuration}

[trafficserver-launcher]
recipe = slapos.cookbook:wrapper
468
command-line = {{ software_parameter_dict['trafficserver'] }}/bin/traffic_manager
469 470
wrapper-path = ${trafficserver-variable:wrapper-path}
environment = TS_ROOT=${buildout:directory}
471
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
472 473 474

[trafficserver-reload]
recipe = slapos.cookbook:wrapper
475
command-line = {{ software_parameter_dict['trafficserver'] }}/bin/traffic_ctl config reload
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
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
492
template = {{ software_parameter_dict['template_trafficserver_records_config'] }}
493 494 495 496 497 498
filename = records.config
extra-context =
    import os_module os

[trafficserver-storage-config]
< = trafficserver-jinja2-template-base
499
template = {{ software_parameter_dict['template_trafficserver_storage_config'] }}
500 501
filename = storage.config

502
[trafficserver-logging-yaml]
503
< = trafficserver-jinja2-template-base
504
template = {{ software_parameter_dict['template_trafficserver_logging_yaml'] }}
505
filename = logging.yaml
506

507
[trafficserver-remap-config]
508 509 510 511 512 513 514
<= trafficserver-jinja2-template-base
{%- raw %}
template = inline:
  map /HTTPS/ http://{{ ipv4 }}:{{ https_port }}
  map / http://{{ ipv4 }}:{{ http_port }}
{%- endraw %}
extra-context =
515
  raw ipv4 {{ instance_parameter_dict['ipv4-random'] }}
516 517 518
  key https_port backend-haproxy-configuration:https-port
  key http_port backend-haproxy-configuration:http-port

519 520 521 522
filename = remap.config

[trafficserver-plugin-config]
< = trafficserver-jinja2-template-base
523
template = {{ software_parameter_dict['template_empty'] }}
524 525 526 527
filename = plugin.config
context =
    key content trafficserver-variable:plugin-config

528 529
[trafficserver-ip-allow-config]
< = trafficserver-jinja2-template-base
530
template = {{ software_parameter_dict['template_empty'] }}
531 532 533 534
filename = ip_allow.config
context =
    key content trafficserver-variable:ip-allow-config

535
[trafficserver-promise-listen-port]
536
<= monitor-promise-base
537 538 539 540
module = check_port_listening
name = trafficserver-port-listening.py
config-hostname = ${trafficserver-variable:local-ip}
config-port = ${trafficserver-variable:input-port}
541

542
[trafficserver-ctl]
543
recipe = slapos.cookbook:wrapper
544
command-line = {{ software_parameter_dict['trafficserver'] }}/bin/traffic_ctl
545
wrapper-path = ${directory:bin}/traffic_ctl
546 547 548
environment = TS_ROOT=${buildout:directory}

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

554 555
[trafficserver-rotate-script]
< = jinja2-template-base
556
template = {{ software_parameter_dict['template_rotate_script'] }}
557 558
rendered = ${directory:bin}/trafficserver-rotate
mode = 0700
559
xz_binary = {{ software_parameter_dict['xz_location'] ~ '/bin/xz' }}
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
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}

578 579 580
### End of ATS sections

### Caddy Graceful and promises
581
[frontend-caddy-configuration-state]
582
< = jinja2-template-base
583
template = {{ software_parameter_dict['template_configuration_state_script'] }}
584
rendered = ${directory:bin}/${:_buildout_section_name_}
585
mode = 0700
586

587
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
588
sha256sum = {{ software_parameter_dict['sha256sum'] }}
589

590
extra-context =
591 592 593
    key path_list :path_list
    key sha256sum :sha256sum
    key signature_file :signature_file
594

595 596 597 598 599 600 601 602 603 604
[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
605
template = {{ software_parameter_dict['template_graceful_script'] }}
606 607 608 609 610 611 612
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

613 614
[frontend-caddy-validate]
< = jinja2-template-base
615
template = {{ software_parameter_dict['template_validate_script'] }}
616 617
rendered = ${directory:bin}/frontend-caddy-validate
mode = 0700
618
last_state_file = ${directory:run}/caddy_configuration_last_state
619
validate_command = ${caddy-wrapper:rendered} -validate
620
extra-context =
621 622
    key validate_command :validate_command
    key configuration_state_command frontend-caddy-configuration-state-validate:rendered
623
    key last_state_file :last_state_file
624

625 626
[frontend-caddy-lazy-graceful]
< = jinja2-template-base
627
template = {{ software_parameter_dict['template_caddy_lazy_script_call'] }}
628 629 630
rendered = ${directory:bin}/frontend-caddy-lazy-graceful
mode = 0700
pid-file = ${directory:run}/lazy-graceful.pid
631
wait_time = 60
632 633
extra-context =
    key pid_file :pid-file
634
    key wait_time :wait_time
635 636 637
    key lazy_command caddy-configuration:frontend-graceful-command

# Promises checking configuration:
638 639
[promise-helper-last-configuration-state]
< = jinja2-template-base
640
template = {{ software_parameter_dict['template_empty'] }}
641 642 643 644 645 646 647 648
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

649
[promise-frontend-caddy-configuration]
650
<= monitor-promise-base
651 652
module = validate_frontend_configuration
name = frontend-caddy-configuration-promise.py
653
config-verification-script = ${promise-helper-last-configuration-state:rendered}
654 655

[promise-caddy-frontend-v4-https]
656
<= monitor-promise-base
657 658
module = check_port_listening
name = caddy_frontend_ipv4_https.py
659
config-hostname = {{ instance_parameter_dict['ipv4-random'] }}
660
config-port = ${configuration:port}
661 662

[promise-caddy-frontend-v4-http]
663
<= monitor-promise-base
664 665
module = check_port_listening
name = caddy_frontend_ipv4_http.py
666
config-hostname = {{ instance_parameter_dict['ipv4-random'] }}
667
config-port = ${configuration:plain_http_port}
668 669

[promise-caddy-frontend-v6-https]
670
<= monitor-promise-base
671 672
module = check_port_listening
name = caddy_frontend_ipv6_https.py
673
config-hostname = {{ instance_parameter_dict['ipv6-random'] }}
674
config-port = ${configuration:port}
675 676

[promise-caddy-frontend-v6-http]
677
<= monitor-promise-base
678 679
module = check_port_listening
name = caddy_frontend_ipv6_http.py
680
config-hostname = {{ instance_parameter_dict['ipv6-random'] }}
681
config-port = ${configuration:plain_http_port}
682

683
[promise-backend-haproxy-http]
684
<= monitor-promise-base
685
module = check_port_listening
686
name = backend_haproxy_http.py
687
config-hostname = {{ instance_parameter_dict['ipv4-random'] }}
688
config-port = ${backend-haproxy-configuration:http-port}
689

690
[promise-backend-haproxy-https]
691
<= monitor-promise-base
692
module = check_port_listening
693
name = backend_haproxy_https.py
694
config-hostname = {{ instance_parameter_dict['ipv4-random'] }}
695 696 697 698 699
config-port = ${backend-haproxy-configuration:https-port}

[backend-haproxy-configuration]
file = ${directory:etc}/backend-haproxy.cfg
pid-file = ${directory:run}/backend-haproxy.pid
700
log-socket = ${backend-haproxy-rsyslogd-config:log-socket}
701 702 703
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}
704 705 706 707 708 709 710
# 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}
711 712 713 714 715 716 717
# the statistic page
statistic-certificate = ${self-signed-ip-access:certificate}
statistic-port = ${configuration:backend-haproxy-statistic-port}
statistic-username = ${monitor-instance-parameter:username}
statistic-password = ${monitor-htpasswd:passwd}
statistic-identification = {{ slapparameter_dict['cluster-identification'] }}
statistic-frontend-secure_access = ${backend-haproxy-statistic-frontend:connection-secure_access}
718 719 720

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

725 726
[backend-haproxy-rsyslogd-lazy-graceful]
< = jinja2-template-base
727
template = {{ software_parameter_dict['template_caddy_lazy_script_call'] }}
728 729 730 731 732 733 734 735 736
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

737 738 739
[logrotate-entry-backend-haproxy]
<= logrotate-entry-base
name = backend-haproxy
740
log = ${backend-haproxy-rsyslogd-config:log-file}
741
rotate-num = ${configuration:rotate-num}
742 743 744 745 746 747
# 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} &
748
delaycompress =
749

750 751
[backend-haproxy-configuration-state]
<= jinja2-template-base
752
template = {{ software_parameter_dict['template_configuration_state_script'] }}
753 754 755
rendered = ${directory:bin}/${:_buildout_section_name_}
mode = 0700

756
path_list = ${backend-haproxy-configuration:file} ${backend-client-login-config:certificate}
757
sha256sum = {{ software_parameter_dict['sha256sum'] }}
758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773

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
774
template = {{ software_parameter_dict['template_graceful_script'] }}
775 776 777 778 779 780 781 782 783
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
784
template = {{ software_parameter_dict['template_validate_script'] }}
785 786 787
rendered = ${directory:bin}/backend-haproxy-validate
mode = 0700
last_state_file = ${directory:run}/backend_haproxy_configuration_last_state
788
validate_command = {{ software_parameter_dict['haproxy_executable'] }} -f ${backend-haproxy-configuration:file} -c
789 790 791 792 793 794 795 796 797 798 799 800 801
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
802
template = {{ software_parameter_dict['template_empty'] }}
803 804 805 806 807 808 809
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
810

811
[backend-haproxy-rsyslogd-config]
812 813 814
log-socket = ${directory:run}/bhlog.sck
log-file = ${directory:log}/backend-haproxy.log
pid-file = ${directory:run}/backend-haproxy-rsyslogd.pid
815 816 817 818 819 820 821 822
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
823
extra-context =
824
  section configuration backend-haproxy-rsyslogd-config
825 826 827

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

832 833 834 835 836
#######
# Monitoring sections
#

[monitor-instance-parameter]
837 838 839
# 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'
840 841
monitor-httpd-port = {{ instance_parameter_dict['configuration.monitor-httpd-port'] | int }}
password = {{ instance_parameter_dict['configuration.monitor-password'] | string }}
842 843 844

[monitor-conf-parameters]
private-path-list += 
845
  ${logrotate-directory:logrotate-backup}
846 847 848 849


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

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

[monitor-caddy-server-status-wrapper]
< = jinja2-template-base
869
template = {{ software_parameter_dict['template_wrapper'] }}
870
rendered = ${directory:bin}/monitor-caddy-server-status-wrapper
871
mode = 0700
872
command = {{ software_parameter_dict['curl'] }}/bin/curl -s http://{{ instance_parameter_dict['ipv4-random'] }}:${configuration:plain_http_port}/server-status -u ${monitor-instance-parameter:username}:${monitor-htpasswd:passwd} 2>&1
873 874 875 876 877
extra-context =
  key content monitor-caddy-server-status-wrapper:command

[monitor-ats-cache-stats-config]
< = jinja2-template-base
878
template = {{ software_parameter_dict['template_empty'] }}
879 880 881 882 883 884
rendered = ${trafficserver-configuration-directory:target}/cache-config.stats
mode = 644
context =
    raw content show:cache-stats

[monitor-verify-re6st-connectivity]
885
<= monitor-promise-base
886 887 888
module = check_url_available
name = re6st-connectivity.py
config-url = ${configuration:re6st-verification-url}
889 890 891 892 893 894 895 896 897 898 899

[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

900 901 902
[slave-introspection-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
903
name = Slave Introspection Frontend {{ instance_parameter_dict['configuration.frontend-name'] }}
904 905
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
slave = true
906
config-url = https://[${slap-network-information:global-ipv6}]:{{ instance_parameter_dict['configuration.slave-introspection-https-port'] }}/
907 908 909
config-https-only = true
return = domain secure_access

910 911 912
[backend-haproxy-statistic-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
913
name = Backend Haproxy Statistic Frontend {{ instance_parameter_dict['configuration.frontend-name'] }}
914 915
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
slave = true
916
config-url = https://[${slap-network-information:global-ipv6}]:{{ instance_parameter_dict['configuration.backend-haproxy-statistic-port'] }}/
917 918 919
config-https-only = true
return = domain secure_access

920 921
[slave-introspection-configuration-state]
<= jinja2-template-base
922
template = {{ software_parameter_dict['template_configuration_state_script'] }}
923 924 925 926
rendered = ${directory:bin}/${:_buildout_section_name_}
mode = 0700

path_list = ${frontend-configuration:slave-introspection-configuration} ${frontend-configuration:ip-access-certificate}
927
sha256sum = {{ software_parameter_dict['sha256sum'] }}
928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943

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

[slave-introspection-configuration-state-graceful]
<= slave-introspection-configuration-state
signature_file = ${directory:run}/slave_introspection_graceful_configuration_state_signature

[slave-introspection-configuration-state-validate]
<= slave-introspection-configuration-state
signature_file = ${directory:run}/slave_introspection_validate_configuration_state_signature

[slave-introspection-graceful]
< = jinja2-template-base
944
template = {{ software_parameter_dict['template_graceful_script'] }}
945 946 947 948 949 950 951 952 953
rendered = ${directory:etc-run}/slave-introspection-safe-graceful
mode = 0700

extra-context =
    key graceful_reload_command caddy-configuration:slave-introspection-graceful-command
    key caddy_configuration_state slave-introspection-configuration-state-graceful:rendered

[slave-introspection-validate]
<= jinja2-template-base
954
template = {{ software_parameter_dict['template_validate_script'] }}
955 956 957
rendered = ${directory:bin}/slave-introspection-validate
mode = 0700
last_state_file = ${directory:run}/slave_introspection_configuration_last_state
958
validate_command = {{ software_parameter_dict['nginx'] }} -c ${frontend-configuration:slave-introspection-configuration} -t
959 960 961 962 963 964 965 966 967 968 969 970 971
extra-context =
    key validate_command :validate_command
    key configuration_state_command slave-introspection-configuration-state-validate:rendered
    key last_state_file :last_state_file

[promise-slave-introspection-configuration]
<= monitor-promise-base
module = validate_frontend_configuration
name = slave-introspection-configuration.py
config-verification-script = ${promise-slave-introspection-configuration-helper:rendered}

[promise-slave-introspection-configuration-helper]
< = jinja2-template-base
972
template = {{ software_parameter_dict['template_empty'] }}
973 974 975 976 977 978 979 980 981 982 983 984
rendered = ${directory:bin}/slave-introspection-read-last-configuration-state
mode = 0700
content =
  #!/bin/sh
  exit `cat ${slave-introspection-validate:last_state_file}`
context =
    key content :content

[promise-slave-introspection-https]
<= monitor-promise-base
module = check_port_listening
name = slave_introspection_https.py
985
config-hostname = {{ instance_parameter_dict['ipv6-random'] }}
986 987 988 989 990
config-port = ${frontend-configuration:slave-introspection-https-port}

[logrotate-entry-slave-introspection]
<= logrotate-entry-base
name = slave-introspection
991
log = ${caddy-configuration:slave-introspection-access-log} ${caddy-configuration:slave-introspection-error-log}
992 993
rotate-num = ${configuration:rotate-num}
post = kill -USR1 $(cat ${caddy-configuration:slave-introspection-pid-file})
994
delaycompress =
995

996 997 998 999 1000 1001 1002
[promise-logrotate-setup]
<= monitor-promise-base
module = check_command_execute
name = ${:_buildout_section_name_}.py
config-command =
  ${logrotate:wrapper-path} -d

1003
[configuration]
1004
{%- for key, value in instance_parameter_dict.iteritems() -%}
1005 1006 1007
{%-   if key.startswith('configuration.') %}
{{ key.replace('configuration.', '') }} = {{ dumps(value) }}
{%-   endif -%}
1008 1009
{%- endfor %}

1010
[instance-parameter-section]
1011 1012 1013
{#- There are dangerous keys like recipe, etc #}
{#- XXX: Some other approach would be useful #}
{%- set DROP_KEY_LIST = ['recipe', '__buildout_signature__', 'computer', 'partition', 'url', 'key', 'cert'] %}
1014
{%- for key, value in instance_parameter_dict.iteritems() -%}
1015 1016 1017
{%-   if not key.startswith('configuration.') and key not in DROP_KEY_LIST %}
{{ key }} = {{ dumps(value) }}
{%-   endif -%}
1018 1019 1020 1021 1022 1023 1024
{%- endfor %}

[software-parameter-section]
{%- for key, value in software_parameter_dict.iteritems() %}
{{ key }} = {{ dumps(value) }}
{%- endfor %}

1025
{%- endif -%} {# if instance_parameter_dict['slap-software-type'] == software_type #}