instance-kedifa.cfg.in 12.3 KB
Newer Older
1
{%- if instance_parameter_dict['slap-software-type'] == software_type -%}
2 3 4 5
{% import "caucase" as caucase with context %}
# KeDiFa instance profile
[buildout]
extends =
6 7 8
  {{ software_parameter_dict['profile_common'] }}
  {{ software_parameter_dict['profile_monitor'] }}
  {{ software_parameter_dict['profile_logrotate_base'] }}
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
[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'
28 29
monitor-httpd-port = {{ instance_parameter_dict['configuration.monitor-httpd-port'] | int }}
password = {{ instance_parameter_dict['configuration.monitor-password'] | string }}
30

31
[caucased]
32
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
33

34 35
{%  set caucase_host = '[' ~ instance_parameter_dict['ipv6-random'] ~ ']' %}
{%  set caucase_netloc = caucase_host ~ ':' ~ instance_parameter_dict['configuration.caucase_port'] -%}
36 37 38
{%  set caucase_url = 'http://' ~ caucase_netloc -%}
{{  caucase.caucased(
      prefix='caucased',
39
      buildout_bin_directory=software_parameter_dict['bin_directory'],
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
      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
# csr_id publication
csr_id = ${:srv}/csr_id
78 79
certificate-csr_id = ${:var}/certificate-csr_id
expose-csr_id-var = ${:var}/expose-csr_id
80

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

{{ caucase.updater(
     prefix='caucase-updater',
103
     buildout_bin_directory=software_parameter_dict['bin_directory'],
104 105 106 107 108 109 110
     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}',
111
     on_renew='${kedifa-reloader:rendered}',
112
     template_csr='${kedifa-csr:template-csr}'
113 114
)}}

115 116 117 118 119 120 121 122 123
[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 =
124
  {{ software_parameter_dict['bin_directory'] }}/caucase \
125 126 127 128 129 130 131 132 133 134 135
    --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
136 137
certificate = ${directory:certificate-csr_id}/certificate.pem
key = ${directory:certificate-csr_id}/key.pem
138

139
{#- Can be stopped on error, as does not rely on self provided service #}
140 141 142 143
stop-on-error = True
update-command = ${:command}
command =
  if ! [ -f ${:key} ] && ! [ -f ${:certificate} ] ; then
144
    {{ software_parameter_dict['openssl'] }} req -new -newkey rsa:2048 -sha256 -subj \
145
      "/O=${kedifa-csr:organization}/OU=${kedifa-csr:organizational_unit}/CN={{ instance_parameter_dict['ipv6-random'] }}" \
146 147 148 149
      -days 5 -nodes -x509 -keyout ${:key} -out ${:certificate}
  fi

[expose-csr_id-configuration]
150
ip = {{ instance_parameter_dict['ipv6-random'] }}
151 152 153 154 155 156 157
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
158 159 160
var = ${directory:expose-csr_id-var}
pid = ${directory:var}/nginx-expose-csr_id.pid
rendered = ${directory:etc}/nginx-expose-csr_id.conf
161
template = inline:
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
  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;
      }
    }
191 192
  }

193
[promise-expose-csr_id-ip-port]
194
<= monitor-promise-base
195 196 197 198 199
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}

200 201 202
[expose-csr_id]
depends = ${store-csr_id:command}
recipe = slapos.cookbook:wrapper
203 204
command-line = {{ software_parameter_dict['nginx'] }}
  -c ${expose-csr_id-template:rendered}
205 206

wrapper-path = ${directory:service}/expose-csr_id
207
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
208 209 210 211 212 213

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

214 215 216 217
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/${:filename}
extra-context =
218
slapparameter_dict = {{ dumps(slapparameter_dict) }}
219
slap_software_type = {{ dumps(instance_parameter_dict['slap-software-type']) }}
220 221
context =
    import json_module json
222
    raw profile_common {{ software_parameter_dict['profile_common'] }}
223 224 225 226 227 228
    key slap_software_type :slap_software_type
    key slapparameter_dict :slapparameter_dict
    section directory directory
    ${:extra-context}

[kedifa-config]
229 230
ip = {{ instance_parameter_dict['ipv6-random'] }}
port = {{ instance_parameter_dict['configuration.kedifa_port'] }}
231 232 233
db = ${directory:kedifa}/kedifa.sqlite
certificate = ${directory:etc-kedifa}/certificate.pem
key = ${:certificate}
234
ca-certificate = ${directory:etc-kedifa}/ca-certificate.pem
235
crl = ${directory:etc-kedifa}/crl.pem
236
template-csr = ${directory:etc-kedifa}/template-csr.pem
237
pidfile = ${directory:run}/kedifa.pid
Łukasz Nowak's avatar
Łukasz Nowak committed
238
logfile = ${directory:log}/kedifa.log
239 240

[kedifa-reloader]
241
<= jinja2-template-base
242
template = {{ software_parameter_dict['template_wrapper'] }}
243 244 245 246 247 248
rendered = ${directory:etc-run}/kedifa-reloader
command =
  kill -HUP `cat ${kedifa-config:pidfile}`
mode = 0700
extra-context =
  key content :command
249

250
[promise-kedifa-http-reply]
251
<= monitor-promise-base
252 253
module = check_url_available
name = kedifa-http-reply.py
254 255
# Kedifa replies 400 on /, so use it to be sure that Kedifa replied
config-http_code = 400
256 257
config-url = https://[${kedifa-config:ip}]:${kedifa-config:port}
config-ca-cert-file = ${kedifa-config:ca-certificate}
258

259 260 261 262
[logrotate-entry-kedifa]
<= logrotate-entry-base
name = kedifa
log = ${kedifa-config:logfile}
263
rotate-num = {{ instance_parameter_dict['configuration.rotate-num'] | int }}
264
delaycompress =
265

266 267
[kedifa]
recipe = slapos.cookbook:wrapper
268
command-line = {{ software_parameter_dict['kedifa'] }}
269 270 271 272 273 274 275
  --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}
276
  --logfile ${kedifa-config:logfile}
277 278

wrapper-path = ${directory:service}/kedifa
279
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
280 281 282 283 284 285 286 287 288

# 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,)) -%}
289
{%-   do slave_dict.__setitem__('kedifa-caucase-url', caucase_url ) -%}
290 291 292 293 294
{%-   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 =
295
  [ ! -f ${:file} ] && {{ software_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}
296 297 298 299 300 301 302 303 304 305 306 307 308 309
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 =
310
  [ ! -f ${:file} ] && {{ software_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}
311 312 313 314 315 316 317 318 319 320
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
321 322
{# 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) }}
323 324 325 326
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}
327 328
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}
329
monitor-base-url = ${monitor-instance-parameter:monitor-base-url}
330 331 332 333 334 335 336 337

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

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