instance-kedifa.cfg.in 11.2 KB
Newer Older
1 2 3 4 5 6 7
{%- if slap_software_type == software_type -%}
{% import "caucase" as caucase with context %}
# KeDiFa instance profile
[buildout]
extends =
  {{ parameter_dict['common_profile'] }}
  {{ parameter_dict['monitor_template'] }}
8
  {{ parameter_dict['logrotate_base_instance'] }}
9 10

parts =
11
  monitor-base
12 13
  directory
  kedifa
14
  logrotate-entry-kedifa
15
  promise-kedifa-http-reply
16 17 18 19
  slave-kedifa-information
  caucased
  caucased-promise
  caucase-updater
20
  expose-csr_id
21
  promise-expose-csr_id-ip-port
22
  promise-logrotate-setup
23

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

31
[caucased]
32
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

{%  set caucase_host = '[' ~ instance_parameter['ipv6-random'] ~ ']' %}
{%  set caucase_netloc = caucase_host ~ ':' ~ instance_parameter['configuration.caucase_port'] -%}
{%  set caucase_url = 'http://' ~ caucase_netloc -%}
{{  caucase.caucased(
      prefix='caucased',
      buildout_bin_directory=parameter_dict['bin_directory'],
      caucased_path='${directory:service}/caucased',
      backup_dir='${directory:backup-caucased}',
      data_dir='${directory:caucased}',
      netloc=caucase_netloc,
      service_auto_approve_count=0,
      user_auto_approve_count=1,
      key_len=2048,
)}}

# 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/
57
tmp = ${buildout:directory}/tmp/
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

backup = ${:srv}/backup
log = ${:var}/log
run = ${:var}/run
service = ${:etc}/service
etc-run = ${:etc}/run

# KeDiFa directories
kedifa = ${:srv}/kedifa
etc-kedifa = ${:etc}/kedifa

# CAUCASE directories
caucased = ${:srv}/caucased
backup-caucased = ${:backup}/caucased

# reservation
reservation = ${:srv}/reservation

76 77 78 79
# csr_id publication
csr_id = ${:srv}/csr_id
caddy-csr_id = ${:etc}/caddy-csr_id

80 81 82 83 84
[kedifa-csr]
recipe = plone.recipe.command
organization = {{ slapparameter_dict['cluster-identification'] }}
organizational_unit = Kedifa Partition
command =
85
  if [ ! -f ${:template-csr} ] && [ ! -f ${:key} ]  ; then
86 87 88 89 90 91
    /bin/bash -c '{{ parameter_dict['openssl'] }} req -new -sha256 \
      -newkey rsa:2048 -nodes -keyout ${:key} \
      -subj "/O=${:organization}/OU=${:organizational_unit}" \
      -reqexts SAN \
      -config <(cat {{ parameter_dict['openssl_cnf'] }} \
      <(printf "\n[SAN]\nsubjectAltName=IP:${kedifa-config:ip}")) \
92
      -out ${:template-csr}'
93 94
  fi
update-command = ${:command}
95
template-csr = ${kedifa-config:template-csr}
96 97 98 99 100 101 102 103 104 105 106 107 108
key = ${kedifa-config:key}
stop-on-error = True

{{ caucase.updater(
     prefix='caucase-updater',
     buildout_bin_directory=parameter_dict['bin_directory'],
     updater_path='${directory:service}/caucase-updater',
     url=caucase_url,
     data_dir='${directory:srv}/caucase-updater',
     crt_path='${kedifa-config:certificate}',
     ca_path='${kedifa-config:ca-certificate}',
     crl_path='${kedifa-config:crl}',
     key_path='${kedifa-csr:key}',
109
     on_renew='${kedifa-reloader:rendered}',
110
     template_csr='${kedifa-csr:template-csr}'
111 112
)}}

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
[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 =
  {{ parameter_dict['bin_directory'] }}/caucase \
    --ca-url {{ caucase_url }} \
    --ca-crt ${kedifa-config:ca-certificate} \
    --crl ${kedifa-config:crl} \
    --mode service \
{#- XXX: Need to use caucase-updater-csr:csr, as there is no way to obatin csr_id from caucase-updater -#}
{#- XXX: nor directly path to the generated CSR #}
    --send-csr ${caucase-updater-csr:csr} > ${:csr_work_path} && \
  cut -d ' ' -f 1 ${:csr_work_path} > ${:csr_id_path}

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

stop-on-error = True
update-command = ${:command}
command =
  if ! [ -f ${:key} ] && ! [ -f ${:certificate} ] ; then
141
    {{ parameter_dict['openssl'] }} req -new -newkey rsa:2048 -sha256 -subj \
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
      "/O=${kedifa-csr:organization}/OU=${kedifa-csr:organizational_unit}/CN={{ instance_parameter['ipv6-random'] }}" \
      -days 5 -nodes -x509 -keyout ${:key} -out ${:certificate}
  fi

[expose-csr_id-configuration]
ip = {{ instance_parameter['ipv6-random'] }}
port = 17000
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
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}
  }

rendered = ${directory:caddy-csr_id}/Caddyfile

164
[promise-expose-csr_id-ip-port]
165
<= monitor-promise-base
166 167 168 169 170
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}

171 172 173 174 175 176 177 178
[expose-csr_id]
depends = ${store-csr_id:command}
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['caddy'] }}
  -conf ${expose-csr_id-template:rendered}
  -log ${expose-csr_id-configuration:error-log}
  -http2=true
  -disable-http-challenge
179
  -disable-tls-alpn-challenge
180 181 182
  -root ${directory:csr_id}

wrapper-path = ${directory:service}/expose-csr_id
183
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
184 185 186 187 188 189

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

190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/${:filename}
extra-context =
slapparameter_dict = {{ dumps(instance_parameter['configuration']) }}
slap_software_type = {{ dumps(instance_parameter['slap-software-type']) }}
context =
    import json_module json
    raw common_profile {{ parameter_dict['common_profile'] }}
    key slap_software_type :slap_software_type
    key slapparameter_dict :slapparameter_dict
    section directory directory
    ${:extra-context}

[kedifa-config]
ip = {{ instance_parameter['ipv6-random'] }}
port = {{ instance_parameter['configuration.kedifa_port'] }}
db = ${directory:kedifa}/kedifa.sqlite
certificate = ${directory:etc-kedifa}/certificate.pem
key = ${:certificate}
210
ca-certificate = ${directory:etc-kedifa}/ca-certificate.pem
211
crl = ${directory:etc-kedifa}/crl.pem
212
template-csr = ${directory:etc-kedifa}/template-csr.pem
213
pidfile = ${directory:run}/kedifa.pid
Łukasz Nowak's avatar
Łukasz Nowak committed
214
logfile = ${directory:log}/kedifa.log
215 216

[kedifa-reloader]
217 218 219 220 221 222 223 224
<= jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${directory:etc-run}/kedifa-reloader
command =
  kill -HUP `cat ${kedifa-config:pidfile}`
mode = 0700
extra-context =
  key content :command
225

226
[promise-kedifa-http-reply]
227
<= monitor-promise-base
228 229
module = check_url_available
name = kedifa-http-reply.py
230 231
# Kedifa replies 400 on /, so use it to be sure that Kedifa replied
config-http_code = 400
232 233
config-url = https://[${kedifa-config:ip}]:${kedifa-config:port}
config-ca-cert-file = ${kedifa-config:ca-certificate}
234

235 236 237 238
[logrotate-entry-kedifa]
<= logrotate-entry-base
name = kedifa
log = ${kedifa-config:logfile}
239
rotate-num = {{ instance_parameter['configuration.rotate-num'] | int }}
240
delaycompress =
241

242 243 244 245 246 247 248 249 250 251
[kedifa]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['kedifa'] }}
  --ip ${kedifa-config:ip}
  --port ${kedifa-config:port}
  --db ${kedifa-config:db}
  --certificate ${kedifa-config:certificate}
  --ca-certificate ${kedifa-config:ca-certificate}
  --crl ${kedifa-config:crl}
  --pidfile ${kedifa-config:pidfile}
252
  --logfile ${kedifa-config:logfile}
253 254

wrapper-path = ${directory:service}/kedifa
255
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
256 257 258 259 260 261 262 263 264

# Publish KeDiFa configuration for upload and download for each slave
{%- set slave_kedifa_information = {} -%}
{%- for slave in slapparameter_dict['slave-list'] -%}
{%-   set slave_reference = slave['slave_reference'] -%}
{%-   set slave_dict = {} -%}
{%-   do slave_dict.__setitem__('key-generate-auth-url', 'https://[${kedifa-config:ip}]:${kedifa-config:port}/${%s-auth-random:passwd}/generateauth' % (slave_reference,)) -%}
{%-   do slave_dict.__setitem__('key-upload-url', 'https://[${kedifa-config:ip}]:${kedifa-config:port}/${%s-auth-random:passwd}?auth=' % (slave_reference,)) -%}
{%-   do slave_dict.__setitem__('key-download-url', 'https://[${kedifa-config:ip}]:${kedifa-config:port}/${%s-auth-random:passwd}' % (slave_reference,)) -%}
265
{%-   do slave_dict.__setitem__('kedifa-caucase-url', caucase_url ) -%}
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
{%-   do slave_kedifa_information.__setitem__(slave_reference, slave_dict) %}
[{{ slave_reference }}-auth-random-generate]
recipe = plone.recipe.command
file = ${directory:reservation}/${:_buildout_section_name_}
command =
  [ ! -f ${:file} ] && {{ parameter_dict['curl'] }}/bin/curl -s -g -X POST https://[${kedifa-config:ip}]:${kedifa-config:port}/reserve-id --cert ${kedifa-config:certificate} --cacert ${kedifa-config:ca-certificate} > ${:file}.tmp && mv ${:file}.tmp ${:file}
update-command = ${:command}

[{{ slave_reference }}-auth-random]
recipe = collective.recipe.shelloutput
file = {{ '${' + slave_reference }}-auth-random-generate:file}
commands =
  passwd = cat ${:file} 2>/dev/null || echo "NotReadyYet"

{% endfor %}

[master-auth-random-generate]
recipe = plone.recipe.command
file = ${directory:reservation}/${:_buildout_section_name_}
command =
  [ ! -f ${:file} ] && {{ parameter_dict['curl'] }}/bin/curl -s -g -X POST https://[${kedifa-config:ip}]:${kedifa-config:port}/reserve-id --cert ${kedifa-config:certificate} --cacert ${kedifa-config:ca-certificate} > ${:file}.tmp && mv ${:file}.tmp ${:file}
update-command = ${:command}

[master-auth-random]
recipe = collective.recipe.shelloutput
file = ${master-auth-random-generate:file}
commands =
  passwd = cat ${:file} 2>/dev/null || echo "NotReadyYet"

[slave-kedifa-information]
recipe = slapos.cookbook:publish.serialised
297 298
{# sort_keys are important in order to avoid shuffling parameters on each run #}
slave-kedifa-information = {{ json_module.dumps(slave_kedifa_information, sort_keys=True) }}
299 300 301 302
caucase-url = {{ caucase_url }}
master-key-generate-auth-url = https://[${kedifa-config:ip}]:${kedifa-config:port}/${master-auth-random:passwd}/generateauth
master-key-upload-url = https://[${kedifa-config:ip}]:${kedifa-config:port}/${master-auth-random:passwd}?auth=
master-key-download-url = https://[${kedifa-config:ip}]:${kedifa-config:port}/${master-auth-random:passwd}
303 304
csr_id-url = https://[${expose-csr_id-configuration:ip}]:${expose-csr_id-configuration:port}/csr_id.txt
csr_id-certificate = ${get-csr_id-certificate:certificate}
305
monitor-base-url = ${monitor-instance-parameter:monitor-base-url}
306 307 308 309 310 311 312 313

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

314
{%- endif -%} {# if slap_software_type in software_type #}