instance-balancer.cfg.in 9.43 KB
Newer Older
1
{% set part_list = [] -%}
2
{% set ssl_parameter_dict = slapparameter_dict.get('ssl', {}) %}
3 4 5 6 7 8 9 10 11 12
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% set use_ipv6 = slapparameter_dict.get('use-ipv6', False) -%}
{#
XXX: This template only supports exactly one IPv4 and (if ipv6 is used) one IPv6
per partition. No more (undefined result), no less (IndexError).
-#}
# TODO: insert varnish between apache & haproxy.
# And think of a way to specify which urls goe through varnish, which go
# directly to haproxy. (maybe just passing literal configuration file chunk)
{% set ipv4 = (ipv4_set | list)[0] -%}
13 14 15 16 17
{% set apache_ip_list = [ipv4] -%}
{% if ipv6_set -%}
{%   set ipv6 = (ipv6_set | list)[0] -%}
{%   do apache_ip_list.append('[' ~ ipv6 ~ ']') -%}
{% endif -%}
18

19
[jinja2-template-base]
20
recipe = slapos.recipe.template:jinja2
21 22 23 24
mode = 644

[simplefile]
< = jinja2-template-base
25 26 27 28 29 30 31 32 33 34 35 36 37 38
template = inline:{{ '{{ content }}' }}

{% macro simplefile(section_name, file_path, content, mode='') -%}
{%   set content_section_name = section_name ~ '-content' -%}
[{{  content_section_name }}]
content = {{ dumps(content) }}

[{{  section(section_name) }}]
< = simplefile
rendered = {{ file_path }}
context = key content {{content_section_name}}:content
mode = {{ mode }}
{%- endmacro %}

39 40 41 42 43 44 45 46 47 48 49
{% if use_ipv6 -%}
[zope-tunnel-base]
recipe = slapos.cookbook:ipv4toipv6
runner-path = ${directory:services}/${:base-name}
6tunnel-path = {{ parameter_dict['6tunnel'] }}/bin/6tunnel
shell-path = {{ parameter_dict['dash'] }}/bin/dash
ipv4 = {{ ipv4 }}

{% endif -%}
{% set haproxy_dict = {} -%}
{% set apache_dict = {} -%}
50
{% set next_port = itertools.count(slapparameter_dict['tcpv4-port']).next -%}
51 52
{% for family_name, parameter_id_list in sorted(
  slapparameter_dict['zope-family-dict'].iteritems()) -%}
53
{%   set zope_family_address_list = [] -%}
54
{%   set has_webdav = [] -%}
55 56
{%   for parameter_id in parameter_id_list -%}
{%     set zope_address_list = slapparameter_dict[parameter_id] -%}
57 58 59 60
{%     for zope_address, maxconn, webdav in zope_address_list -%}
{%       if webdav -%}
{%         do has_webdav.append(None) %}
{%       endif -%}
61
{%       if use_ipv6 -%}
62 63
{%         set current_port = next_port() -%}
[{{ section('zope-tunnel-' ~ current_port) }}]
64
< = zope-tunnel-base
65 66
base-name = {{ 'zeo-tunnel-' ~ current_port }}
ipv4-port = {{ current_port }}
67 68
ipv6-port = {{ zope_address.split(']:')[1] }}
ipv6 = {{ zope_address.split(']:')[0][1:] }}
69
{%         set zope_effective_address = ipv4 ~ ":" ~ current_port -%}
70 71 72
{%       else -%}
{%         set zope_effective_address = zope_address -%}
{%       endif -%}
73
{%       do zope_family_address_list.append((zope_effective_address, maxconn, webdav)) -%}
74 75
{%     endfor -%}
{%   endfor -%}
76 77 78 79
{# Make rendering fail artificially if any family has no known backend.
 # This is useful as haproxy's hot-reconfiguration mechanism is
 # supervisord-incompatible.
 # As jinja2 postpones KeyError until place-holder value is actually used,
80
 # do a no-op getitem.
81
-#}
82
{%   do zope_family_address_list[0][0] -%}
83
{%   set haproxy_port = next_port() -%}
84
{%   do haproxy_dict.__setitem__(family_name, (haproxy_port, zope_family_address_list)) -%}
85 86 87 88 89 90 91
{%   if has_webdav -%}
{%     set internal_scheme = 'http' -%}{# mod_rewrite does not recognise webdav scheme -#}
{%     set external_scheme = 'webdavs' -%}
{%   else %}
{%     set internal_scheme = 'http' -%}
{%     set external_scheme = 'https' -%}
{%   endif -%}
92
{%   do apache_dict.__setitem__(family_name, (next_port(), external_scheme, internal_scheme ~ '://' ~ ipv4 ~ ':' ~ haproxy_port ~ slapparameter_dict['backend-path'])) -%}
93 94
{% endfor -%}

95
[haproxy-cfg-parameter-dict]
96
socket-path = ${directory:run}/haproxy.sock
97
server-check-path = {{ dumps(slapparameter_dict['haproxy-server-check-path']) }}
98
backend-dict = {{ dumps(haproxy_dict) }}
99 100 101
ip = {{ ipv4 }}

[haproxy-cfg]
102
< = jinja2-template-base
103 104 105
template = {{ parameter_dict['template-haproxy-cfg'] }}
rendered = ${directory:etc}/haproxy.cfg
context = section parameter_dict haproxy-cfg-parameter-dict
106
extensions = jinja2.ext.do
107 108 109 110 111 112 113

[{{ section('haproxy') }}]
recipe = slapos.cookbook:wrapper
wrapper-path = ${directory:services}/haproxy
command-line = "{{ parameter_dict['haproxy'] }}/sbin/haproxy" -f "${haproxy-cfg:rendered}"

{# TODO: build socat and wrap it as "${directory:bin}/haproxy-ctl" to connect to "${haproxy-cfg-parameter-dict:socket-path}" #}
114

115 116 117 118 119 120 121
[apache-conf-ssl]
cert = ${directory:apache-conf}/apache.crt
key = ${directory:apache-conf}/apache.pem
ca-cert =  ${directory:apache-conf}/ca.crt
crl = ${directory:apache-conf}/crl.pem

[apache-conf-parameter-dict]
122
backend-list = {{ dumps(apache_dict.values()) }}
123
ip-list = {{ dumps(apache_ip_list) }}
124 125 126
pid-file = ${directory:run}/apache.pid
error-log = ${directory:log}/apache-error.log
access-log = ${directory:log}/apache-access.log
127 128 129 130 131 132 133 134 135 136 137 138
# Apache 2.4's default value (60 seconds) can be a bit too short
timeout = 300
# Basic SSL server configuration
cert = ${apache-ssl:cert}
key = ${apache-ssl:key}
cipher =
ssl-session-cache = ${directory:log}/apache-ssl-session-cache
# Client x509 auth
ca-cert = ${apache-ssl-client:cert}
crl = ${apache-ssl-client:crl}

[apache-conf]
139
< = jinja2-template-base
140 141 142 143 144 145 146 147
template = {{ parameter_dict['template-apache-conf'] }}
rendered = ${directory:apache-conf}/apache.conf
context = section parameter_dict apache-conf-parameter-dict

[{{ section('apache') }}]
recipe = slapos.cookbook:wrapper
wrapper-path = ${directory:services}/apache
command-line = "{{ parameter_dict['apache'] }}/bin/httpd" -f "${apache-conf:rendered}" -DFOREGROUND
148

149 150 151 152 153 154 155
[{{ section('apache-promise') }}]
# Check any apache port in ipv4, expect other ports and ipv6 to behave consistently
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/apache
hostname = {{ ipv4 }}
port = {{ apache_dict.values()[0][0] }}

156 157
[publish]
recipe = slapos.cookbook:publish.serialised
158 159 160
{% for family_name, (apache_port, scheme, _) in apache_dict.items() -%}
{{   family_name ~ '-v6' }} = {% if ipv6_set %}{{ scheme ~ '://[' ~ ipv6 ~ ']:' ~ apache_port }}{% endif %}
{{   family_name }} = {{ scheme ~ '://' ~ ipv4 ~ ':' ~ apache_port }}
161
{% endfor -%}
162
monitor-base-url = ${monitor-publish-parameters:monitor-base-url}
163

164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
[apache-ssl]
{% if ssl_parameter_dict.get('key') -%}
key = ${apache-ssl-key:rendered}
cert = ${apache-ssl-cert:rendered}
{{ simplefile('apache-ssl-key', '${apache-conf-ssl:key}', ssl_parameter_dict['key']) }}
{{ simplefile('apache-ssl-cert', '${apache-conf-ssl:cert}', ssl_parameter_dict['cert']) }}
{% else %}
recipe = plone.recipe.command
command = "{{ parameter_dict['openssl'] }}/bin/openssl" req -newkey rsa -batch -new -x509 -days 3650 -nodes -keyout "${:key}" -out "${:cert}"
key = ${apache-conf-ssl:key}
cert = ${apache-conf-ssl:cert}
{%- endif %}

[apache-ssl-client]
{% if ssl_parameter_dict.get('ca-cert') -%}
cert = ${apache-ssl-ca:rendered}
crl = ${apache-ssl-crl:rendered}
{{ simplefile('apache-ssl-ca', '${apache-conf-ssl:ca-cert}', ssl_parameter_dict['ca-cert']) }}
{{ simplefile('apache-ssl-crl', '${apache-conf-ssl:crl}', ssl_parameter_dict['crl']) }}
{% else %}
cert =
crl =
{%- endif %}
187 188

[logrotate-apache]
189
< = logrotate-entry-base
190
name = apache
191
log = ${apache-conf-parameter-dict:error-log} ${apache-conf-parameter-dict:access-log}
192
post = test ! -s ${apache-conf-parameter-dict:pid-file} || {{ parameter_dict['bin-directory'] }}/slapos-kill --pidfile ${apache-conf-parameter-dict:pid-file} -s USR1
193 194 195 196 197 198

[directory]
recipe = slapos.cookbook:mkdirectory
apache-conf = ${:etc}/apache
bin = ${buildout:directory}/bin
etc = ${buildout:directory}/etc
199
promise = ${directory:etc}/promise
200 201 202 203 204 205 206 207 208 209
services = ${:etc}/run
var = ${buildout:directory}/var
run = ${:var}/run
log = ${:var}/log
ca-dir = ${buildout:directory}/srv/ssl
requests = ${:ca-dir}/requests
private = ${:ca-dir}/private
certs = ${:ca-dir}/certs
newcerts = ${:ca-dir}/newcerts
crl = ${:ca-dir}/crl
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
apachedex = ${monitor-directory:private}/apachedex

[monitor-generate-apachedex-report]
recipe = slapos.cookbook:wrapper
wrapper-path = ${monitor-directory:reports}/${:command}
command-line = "{{ parameter_dict['run-apachedex-location'] }}" "{{ parameter_dict['apachedex-location'] }}" "${directory:apachedex}" --default "${apachedex-parameters:default}" --apache-log-list "${apachedex-parameters:apache-log-list}" --base-list "${apachedex-parameters:base-list}" --skip-base-list "${apachedex-parameters:skip-base-list}" --erp5-base-list "${apachedex-parameters:erp5-base-list}"
command = apachedex_every_3_hour

[apachedex-parameters]
default_parameter = 
# XXX - Sample log file with curent date: apache_access.log-%(date)s.gz
# which will be equivalent to apache_access.log-20150112.gz if the date is 2015-01-12
apache-log-list = ${apache-conf-parameter-dict:access-log}
default = ${monitor-directory:etc}/apdex_default
base-list = ${monitor-directory:etc}/apdex_base_list
skip-base-list = ${monitor-directory:etc}/apdex_skip_base_list
erp5-base-list = ${monitor-directory:etc}/apdex_erp5_base_list
227

228 229
[monitor-instance-parameter]
monitor-httpd-ipv6 = {{ (ipv6_set | list)[0] }}
230
monitor-httpd-port = {{ next_port() }}
231
monitor-title = Balancer monitor
232
password = {{ slapparameter_dict['monitor-passwd'] }}
233 234 235 236 237
instance-configuration = 
  file apachedex-default ${apachedex-parameters:default}
  file apachedex-base-list ${apachedex-parameters:base-list}
  file apachedex-skip-base-list ${apachedex-parameters:skip-base-list}
  file apachedex-erp5-base-list ${apachedex-parameters:erp5-base-list}
238

239
[buildout]
240 241 242
extends =
  {{ logrotate_cfg }}
  {{ parameter_dict['template-monitor'] }}
243 244 245
parts +=
  publish
  logrotate-apache
246
  monitor-generate-apachedex-report
247
  {{ part_list | join('\n  ') }}