{% set part_list = [] -%} {% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%} {% if slapparameter_dict['use-ipv6'] -%} {% set ip = '[' ~ (ipv6_set | list)[0] ~ ']' -%} {% else -%} {% set ip = (ipv4_set | list)[0] -%} {% endif -%} {% set tcpv4_port = slapparameter_dict['tcpv4-port'] -%} {% set relay = slapparameter_dict.get('relay', {}) -%} {% set divert = slapparameter_dict.get('divert', []) -%} {% set alias_dict = slapparameter_dict.get('alias-dict', {}) -%} {% do alias_dict.setdefault('postmaster', [slapparameter_dict['postmaster']]) -%} {% set smtpd_sasl_user = slapparameter_dict['smtpd-sasl-user'] -%} {% set smtpd_sasl_password = slapparameter_dict['smtpd-sasl-password'] -%} {% set milter_list = [] %} [jinja2-template-base] recipe = slapos.recipe.template:jinja2 mode = 644 [smtpd-password] recipe = slapos.cookbook:generate.password storage-path = [{{ section('publish') }}] recipe = slapos.cookbook:publish.serialised url = {{ dumps('smtp://' ~ urllib.quote_plus(smtpd_sasl_user) ~ ':' ~ urllib.quote_plus(smtpd_sasl_password) ~ '@' ~ ip ~ ':' ~ tcpv4_port) }} [directory] recipe = slapos.cookbook:mkdirectory etc = ${buildout:directory}/etc plugin = ${:etc}/plugin etc-postfix = ${:etc}/postfix etc-cyrus = ${:etc}/cyrus run = ${:etc}/run bin = ${buildout:directory}/bin usr = ${buildout:directory}/usr srv = ${buildout:directory}/srv var = ${buildout:directory}/var var-lib = ${:var}/lib var-lib-postfix = ${:var-lib}/postfix var-spool = ${:var}/spool var-spool-postfix = ${:var-spool}/postfix # Not used at buildout level, presence needed by postfix. var-spool-postfix-active = ${:var-spool-postfix}/active var-spool-postfix-bounce = ${:var-spool-postfix}/bounce var-spool-postfix-corrupt = ${:var-spool-postfix}/corrupt var-spool-postfix-defer = ${:var-spool-postfix}/defer var-spool-postfix-deferred = ${:var-spool-postfix}/deferred var-spool-postfix-flush = ${:var-spool-postfix}/flush var-spool-postfix-hold = ${:var-spool-postfix}/hold var-spool-postfix-incoming = ${:var-spool-postfix}/incoming var-spool-postfix-maildrop = ${:var-spool-postfix}/maildrop var-spool-postfix-pid = ${:var-spool-postfix}/pid var-spool-postfix-private = ${:var-spool-postfix}/private var-spool-postfix-public = ${:var-spool-postfix}/public var-spool-postfix-saved = ${:var-spool-postfix}/saved var-spool-postfix-trace = ${:var-spool-postfix}/trace # Used for ERP5 resiliency or (more probably) # webrunner resiliency with erp5 inside. [{{ section("resiliency-exclude-file") }}] # Generate rdiff exclude file recipe = slapos.recipe.template:jinja2 mode = 644 template = {{ 'inline:{{ "**\\n" }}' }} rendered = ${directory:srv}/exporter.exclude {% if divert -%} {% set milter_port = tcpv4_port + 1 -%} {% set socket = 'inet:' ~ ip ~ ':' ~ milter_port -%} [{{ section('divert-milter') }}] recipe = slapos.cookbook:wrapper command-line = '{{ parameter_dict['buildout-bin-directory'] }}/munnel' --listen '{{ socket }}' -- {{ ' '.join(divert) }} wrapper-path = ${directory:run}/munnel {% do milter_list.append(socket) -%} [{{ section('munnel-promise') }}] <= monitor-promise-base module = check_port_listening name = munnel.py config-hostname = {{ ip }} config-port = {{ milter_port }} {% endif -%} [configuration] smtp = {{ dumps(tcpv4_port) }} inet-interfaces = {{ dumps(ip) }} alias-dict = {{ dumps(alias_dict) }} relayhost = {{ dumps(relay.get('host')) }} relay-sasl-credential = {{ dumps(relay.get('sasl-credential')) }} cyrus-sasldb = ${directory:etc-cyrus}/postfix.gdbm milter-list = {{ dumps(milter_list) }} [userinfo] recipe = slapos.cookbook:userinfo [smtp-sasl-passwd] < = jinja2-template-base rendered = ${directory:etc-postfix}/sasl_passwd {% if relay -%} template = inline:{{ "{{ host }} {{ sasl_credential }}" }} {%- else -%} template = inline: {%- endif %} context = key host configuration:relayhost key sasl_credential configuration:relay-sasl-credential mode = 600 [{{ section('cyrus-smtpd-conf') }}] < = jinja2-template-base rendered = ${directory:etc-cyrus}/smtpd.conf template = inline: pwcheck_method: auxprop mech_list: PLAIN LOGIN sasldb_path: {{ '{{ sasldb }}' }} context = key sasldb configuration:cyrus-sasldb [{{ section('cyrus-smtpd-password') }}] recipe = plone.recipe.command stop-on-error = true command = rm -f '${configuration:cyrus-sasldb}' && echo '{{ smtpd_sasl_password }}' | '${wrapper-postfix-saslpasswd2:wrapper-path}' -pc '{{ smtpd_sasl_user }}' update-command = ${:command} [smtpd-ssl] recipe = plone.recipe.command stop-on-error = true openssl = '{{ parameter_dict['openssl'] }}/bin/openssl' cert = ${directory:etc-postfix}/smtpd.crt key = ${directory:etc-postfix}/smtpd.pem dh-512 = ${directory:etc-postfix}/dh512.pem dh-2048 = ${directory:etc-postfix}/dh2048.pem command = ${:openssl} dhparam -out '${:dh-512}' 512 && ${:openssl} dhparam -out '${:dh-2048}' 2048 && ${:update} update = ${:openssl} req -newkey rsa -batch -new -x509 -days 3650 -nodes -keyout '${:key}' -out '${:cert}' [{{ section('postfix-main-cf') }}] < = jinja2-template-base rendered = ${directory:etc-postfix}/main.cf template = {{ parameter_dict['template-postfix-main-cf'] }} context = key bin_directory directory:bin key usr_directory directory:usr key queue_directory directory:var-spool-postfix key data_directory directory:var-lib-postfix key spool_directory directory:var-spool key mail_owner userinfo:pw-name key setgid_group userinfo:gr-name key inet_interfaces configuration:inet-interfaces key relayhost configuration:relayhost key sasl_passwd typed-paths:smtp-sasl-passwd key aliases typed-paths:aliases key milter_list configuration:milter-list key cyrus_directory directory:etc-cyrus key cert smtpd-ssl:cert key key smtpd-ssl:key key dh_512 smtpd-ssl:dh-512 key dh_2048 smtpd-ssl:dh-2048 [{{ section('postfix-master-cf') }}] < = jinja2-template-base rendered = ${directory:etc-postfix}/master.cf template = {{ parameter_dict['template-postfix-master-cf'] }} context = key smtp configuration:smtp [aliases] < = jinja2-template-base template = {{ parameter_dict['template-postfix-aliases'] }} rendered = ${directory:etc-postfix}/aliases context = key alias_dict configuration:alias-dict [typed-paths] # Postfix-friendly rendering of file paths, prefixed with database type. aliases = hash:${aliases:rendered} smtp-sasl-passwd = hash:${smtp-sasl-passwd:rendered} [{{ section('postalias-db') }}] recipe = plone.recipe.command stop-on-error = true command = '${wrapper-postalias:wrapper-path}' '${typed-paths:aliases}' '${typed-paths:smtp-sasl-passwd}' update-command = ${:command} [wrapper-postfix-saslpasswd2] recipe = slapos.cookbook:wrapper command-line = '{{ parameter_dict['cyrus-sasl-location'] }}/sbin/saslpasswd2' -f '${configuration:cyrus-sasldb}' wrapper-path = ${directory:bin}/saslpasswd2 [base-wrapper] recipe = slapos.cookbook:wrapper environment = MAIL_CONFIG=${directory:etc-postfix} SASL_CONF_PATH=${directory:etc-cyrus} [base-bin-wrapper] < = base-wrapper command-line = ${:path}/${:basename} wrapper-path = ${directory:bin}/${:basename} [base-bin-bin-wrapper] < = base-bin-wrapper path = {{ parameter_dict['postfix-location'] }}/usr/bin [base-sbin-bin-wrapper] < = base-bin-wrapper path = {{ parameter_dict['postfix-location'] }}/usr/sbin {% for extend, basename_list in ( ( 'base-bin-bin-wrapper', ( 'mailq', 'newaliases', ), ), ( 'base-sbin-bin-wrapper', ( 'postalias', 'postcat', 'postconf', 'postdrop', 'postfix', 'postkick', 'postlock', 'postlog', 'postmap', 'postmulti', 'postqueue', 'postsuper', 'sendmail', ), ), ) %} {% for basename in basename_list -%} [{{ section('wrapper-' ~ basename) }}] < = {{ extend }} basename = {{ basename }} {% endfor %} {% endfor %} [{{ section('postfix-symlinks-libexec') }}] recipe = slapos.cookbook:symbolic.link target-directory = ${directory:usr} link-binary = {{ parameter_dict['postfix-location'] }}/usr/libexec [{{ section('service-postfix-master') }}] < = base-wrapper command-line = ${directory:usr}/libexec/postfix/master wrapper-path = ${directory:run}/postfix-master [{{ section('postfix-promise') }}] <= monitor-promise-base module = check_port_listening name = postfix.py config-hostname = {{ ip }} config-port = {{ tcpv4_port }} [{{ section('promise-check-computer-memory') }}] <= monitor-promise-base module = check_command_execute name = check-computer-memory.py config-command = "{{ parameter_dict["check-computer-memory-binary"] }}" -db ${monitor-instance-parameter:collector-db} --threshold "{{ slapparameter_dict["computer-memory-percent-threshold"] }}" --unit percent [monitor-instance-parameter] monitor-httpd-ipv6 = {{ (ipv6_set | list)[0] }} monitor-httpd-port = {{ tcpv4_port + 2 }} monitor-title = {{ slapparameter_dict['name'] }} password = {{ slapparameter_dict['monitor-passwd'] }} [buildout] extends = {{ template_monitor }} parts = {{ part_list | join('\n ') }}