From e290d36699455d61c1132dbe48c8d929251e9a83 Mon Sep 17 00:00:00 2001 From: Heinz Wiesinger Date: Mon, 8 May 2017 16:43:47 +0200 Subject: [PATCH 01/16] Add option to manage mail aliases using alias states. --- pillar.example | 15 +++++++++++++++ postfix/aliases | 2 +- postfix/init.sls | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/pillar.example b/pillar.example index d83b61c..bb09c3a 100644 --- a/pillar.example +++ b/pillar.example @@ -94,6 +94,21 @@ postfix: hosts: DB_HOST dbname: postfix_db + aliases: + # manage single aliases + # this uses the aliases file defined in the minion config, /etc/aliases by default + use_file: false + present: + root: info@example.com + absent: + - root + + # manage entire aliases file + use_file: true + content: | + # Forward all local *nix users mail to our admins (via greedy regexp) + /.+/ admins@example.com + certificates: server-cert: public_cert: | diff --git a/postfix/aliases b/postfix/aliases index d02055c..04fa424 100644 --- a/postfix/aliases +++ b/postfix/aliases @@ -1,3 +1,3 @@ # Managed by config management # See man 5 aliases for format -{{pillar['postfix']['aliases']}} +{{pillar['postfix']['aliases']['content']}} diff --git a/postfix/init.sls b/postfix/init.sls index fc6d6c2..8d364ee 100644 --- a/postfix/init.sls +++ b/postfix/init.sls @@ -17,6 +17,7 @@ postfix: # manage /etc/aliases if data found in pillar {% if 'aliases' in pillar.get('postfix', '') %} +{% if salt['pillar.get']('postfix:aliases:use_file', true) == true %} {%- set need_newaliases = False %} {%- set file_path = postfix.aliases_file %} {%- if ':' in file_path %} @@ -44,6 +45,19 @@ postfix_alias_database: - watch: - file: {{ file_path }} {%- endif %} +{% else %} + {%- for user, target in salt['pillar.get']('postfix:aliases:present', {}).items() %} +postfix_alias_present_{{ user }}: + alias.present: + - name: {{ user }} + - target: {{ target }} + {%- endfor %} + {%- for user in salt['pillar.get']('postfix:aliases:absent', {}) %} +postfix_alias_absent_{{ user }}: + alias.absent: + - name: {{ user }} + {%- endfor %} +{% endif %} {% endif %} # manage various mappings From f30c63f9ed68d787508e5b077ec3a18af021b092 Mon Sep 17 00:00:00 2001 From: Florian Ermisch Date: Thu, 24 Aug 2017 11:21:48 +0200 Subject: [PATCH 02/16] Import map.jinja+defaults.yaml structure from salt-formula Now using the `deep_merge()` macro so we can move the values which are identical on most distributions from `map.jinja` to `defaults.yaml`. --- postfix/defaults.yaml | 10 ++++++ postfix/map.jinja | 74 ++++++++++++++++++++++++++++++++----------- 2 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 postfix/defaults.yaml diff --git a/postfix/defaults.yaml b/postfix/defaults.yaml new file mode 100644 index 0000000..ef4f857 --- /dev/null +++ b/postfix/defaults.yaml @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml + +postfix: + aliases_file: /etc/aliases + config_path: /etc/postfix + package: postfix + postsrsd_pkg: postsrsd + postgrey_pkg: postgrey + service: postfix diff --git a/postfix/map.jinja b/postfix/map.jinja index dc1df91..3e0846c 100644 --- a/postfix/map.jinja +++ b/postfix/map.jinja @@ -1,36 +1,74 @@ -{% set postfix = salt['grains.filter_by']({ +# -*- coding: utf-8 -*- +# vim: ft=jinja + +{%- macro deep_merge(a, b) %} +{#- This whole `'dict' in x.__class__.__name__` mess is a + workaround for the missing mapping test in CentOS 6's + ancient Jinja2, see #193 #} +{%- for k,v in b.iteritems() %} +{%- if v is string or v is number %} +{%- do a.update({ k: v }) %} +{%- elif 'dict' not in v.__class__.__name__ %} +{%- if a[k] is not defined %} +{%- do a.update({ k: v }) %} +{%- elif a[k] is iterable and 'dict' not in a[k].__class__.__name__ and + a[k] is not string %} +{%- do a.update({ k: v|list + a[k]|list}) %} +{%- else %} +{%- do a.update({ k: v }) %} +{%- endif %} +{%- elif 'dict' in v.__class__.__name__ %} +{%- if a[k] is not defined %} +{%- do a.update({ k: v }) %} +{%- elif 'dict' in a[k].__class__.__name__ %} +{%- do a.update({ k: v }) %} +{%- else %} +{%- do deep_merge(a[k], v) %} +{%- endif %} +{%- else %} +{%- do a.update({ k: 'ERROR: case not contempled in merging!' }) %} +{%- endif %} +{%- endfor %} +{%- endmacro %} + + +{## Start with defaults from defaults.yaml ##} +{% import_yaml "postfix/defaults.yaml" as default_settings %} + +{## +Setup variable using grains['os_family'] based logic, only add key:values here +that differ from whats in defaults.yaml +##} +{% set osrelease = salt['grains.get']('osrelease') %} +{# set salt_release = salt['pillar.get']('salt:release', 'latest') #} +{# set postfix = salt['grains.filter_by'](#} +{% set os_family_map = salt['grains.filter_by']({ 'Debian': { - 'package': 'postfix', 'policyd_spf_pkg': 'postfix-policyd-spf-python', - 'postsrsd_pkg': 'postsrsd', - 'postgrey_pkg': 'postgrey', 'pcre_pkg': 'postfix-pcre', 'mysql_pkg': 'postfix-mysql', - 'service': 'postfix', - 'aliases_file': '/etc/aliases', }, 'Gentoo': { 'package': 'mail-mta/postfix', 'policyd_spf_pkg': 'mail-filter/pypolicyd-spf', - 'postsrsd_pkg': 'mail-filter/postsrsd', 'postgrey_pkg': 'mail-filter/postgrey', - 'service': 'postfix', + 'postsrsd_pkg': 'mail-filter/postsrsd', 'aliases_file': '/etc/mail/aliases', }, 'RedHat': { - 'package': 'postfix', 'policyd_spf_pkg': 'pypolicyd-spf', - 'postsrsd_pkg': 'postsrsd', - 'postgrey_pkg': 'postgrey', - 'service': 'postfix', - 'aliases_file': '/etc/aliases', }, 'Arch' : { - 'package': 'postfix', 'policyd_spf_pkg': 'python-postfix-policyd-spf', - 'postsrsd_pkg': 'postsrsd', - 'postgrey_pkg': 'postgrey', - 'service': 'postfix', - 'aliases_file': '/etc/aliases', }, }, merge=salt['pillar.get']('postfix:lookup')) %} + +{## Merge the flavor_map to the default settings ##} +{% do deep_merge(default_settings.postfix, os_family_map) %} + +{## Merge in postfix:lookup pillar ##} +{% set postfix = salt['pillar.get']( + 'postfix', + default=default_settings.postfix, + merge=True) +%} From af5e9f88628d15481dac21ee8bc7b30d9c857955 Mon Sep 17 00:00:00 2001 From: Florian Ermisch Date: Thu, 24 Aug 2017 11:27:43 +0200 Subject: [PATCH 03/16] Add FreeBSD to map.jinja; root_grp, xbin_prefix to defaults.yaml Accidentally already added config_path in the last commit, not redoing it again. --- postfix/defaults.yaml | 2 ++ postfix/map.jinja | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/postfix/defaults.yaml b/postfix/defaults.yaml index ef4f857..4cdf80d 100644 --- a/postfix/defaults.yaml +++ b/postfix/defaults.yaml @@ -7,4 +7,6 @@ postfix: package: postfix postsrsd_pkg: postsrsd postgrey_pkg: postgrey + root_grp: root service: postfix + xbin_prefix: /usr diff --git a/postfix/map.jinja b/postfix/map.jinja index 3e0846c..af305fd 100644 --- a/postfix/map.jinja +++ b/postfix/map.jinja @@ -61,6 +61,13 @@ that differ from whats in defaults.yaml 'Arch' : { 'policyd_spf_pkg': 'python-postfix-policyd-spf', }, + 'FreeBSD' : { + 'policyd_spf_pkg': 'py27-postfix-policyd-spf-python', + 'aliases_file': '/etc/mail/aliases', + 'xbin_prefix': '/usr/local', + 'config_path': '/usr/local/etc/postfix', + 'root_grp': 'wheel', + }, }, merge=salt['pillar.get']('postfix:lookup')) %} {## Merge the flavor_map to the default settings ##} From 099d84ab734baf58246252c1190a24732608e5b2 Mon Sep 17 00:00:00 2001 From: Florian Ermisch Date: Thu, 24 Aug 2017 13:02:46 +0200 Subject: [PATCH 04/16] Template paths and groups to make them work on FreeBSD, too. --- postfix/config.sls | 31 ++++++++++++++++--------------- postfix/files/master.cf | 2 +- postfix/init.sls | 6 +++--- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/postfix/config.sls b/postfix/config.sls index 0554677..0215705 100644 --- a/postfix/config.sls +++ b/postfix/config.sls @@ -1,19 +1,20 @@ +{% from "postfix/map.jinja" import postfix with context %} include: - postfix -/etc/postfix: +{{ postfix.config_path }}: file.directory: - user: root - - group: root + - group: {{ postfix.root_grp }} - dir_mode: 755 - file_mode: 644 - makedirs: True -/etc/postfix/main.cf: +{{ postfix.config_path }}/main.cf: file.managed: - source: salt://postfix/files/main.cf - user: root - - group: root + - group: {{ postfix.root_grp }} - mode: 644 - require: - pkg: postfix @@ -22,7 +23,7 @@ include: - template: jinja {% if 'vmail' in pillar.get('postfix', '') %} -/etc/postfix/virtual_alias_maps.cf: +{{ postfix.config_path }}/virtual_alias_maps.cf: file.managed: - source: salt://postfix/files/virtual_alias_maps.cf - user: root @@ -34,7 +35,7 @@ include: - service: postfix - template: jinja -/etc/postfix/virtual_mailbox_domains.cf: +{{ postfix.config_path }}/virtual_mailbox_domains.cf: file.managed: - source: salt://postfix/files/virtual_mailbox_domains.cf - user: root @@ -46,7 +47,7 @@ include: - service: postfix - template: jinja -/etc/postfix/virtual_mailbox_maps.cf: +{{ postfix.config_path }}/virtual_mailbox_maps.cf: file.managed: - source: salt://postfix/files/virtual_mailbox_maps.cf - user: root @@ -60,11 +61,11 @@ include: {% endif %} {% if salt['pillar.get']('postfix:manage_master_config', True) %} -/etc/postfix/master.cf: +{{ postfix.config_path }}/master.cf: file.managed: - source: salt://postfix/files/master.cf - user: root - - group: root + - group: {{ postfix.root_grp }} - mode: 644 - require: - pkg: postfix @@ -74,11 +75,11 @@ include: {% endif %} {% if 'transport' in pillar.get('postfix', '') %} -/etc/postfix/transport: +{{ postfix.config_path }}/transport: file.managed: - source: salt://postfix/files/transport - user: root - - group: root + - group: {{ postfix.root_grp }} - mode: 644 - require: - pkg: postfix @@ -88,10 +89,10 @@ include: run-postmap: cmd.wait: - - name: /usr/sbin/postmap /etc/postfix/transport + - name: {{ postfix.xbin_prefix }}/sbin/postmap {{ postfix.config_path }}/transport - cwd: / - watch: - - file: /etc/postfix/transport + - file: {{ postfix.config_path }}/transport {% endif %} {%- for domain in salt['pillar.get']('postfix:certificates', {}).keys() %} @@ -99,7 +100,7 @@ run-postmap: postfix_{{ domain }}_ssl_certificate: file.managed: - - name: /etc/postfix/ssl/{{ domain }}.crt + - name: {{ postfix.config_path }}/ssl/{{ domain }}.crt - makedirs: True - contents_pillar: postfix:certificates:{{ domain }}:public_cert - watch_in: @@ -107,7 +108,7 @@ postfix_{{ domain }}_ssl_certificate: postfix_{{ domain }}_ssl_key: file.managed: - - name: /etc/postfix/ssl/{{ domain }}.key + - name: {{ postfix.config_path }}/ssl/{{ domain }}.key - mode: 600 - makedirs: True - contents_pillar: postfix:certificates:{{ domain }}:private_key diff --git a/postfix/files/master.cf b/postfix/files/master.cf index 0238620..c993a80 100644 --- a/postfix/files/master.cf +++ b/postfix/files/master.cf @@ -133,5 +133,5 @@ scache unix - - n - 1 scache # ${nexthop} ${user} {% if salt['pillar.get']('postfix:policyd-spf:enabled', False) %} policy-spf unix - n n - - spawn - user=nobody argv=/usr/bin/policyd-spf + user=nobody argv={{ xbin_prefix }}/bin/policyd-spf {%- endif %} diff --git a/postfix/init.sls b/postfix/init.sls index 8d364ee..6642bb6 100644 --- a/postfix/init.sls +++ b/postfix/init.sls @@ -33,7 +33,7 @@ postfix_alias_database: - name: {{ file_path }} - source: salt://postfix/aliases - user: root - - group: root + - group: {{ postfix.root_grp }} - mode: 644 - template: jinja - require: @@ -77,7 +77,7 @@ postfix_{{ mapping }}: - name: {{ file_path }} - source: salt://postfix/files/mapping.j2 - user: root - - group: root + - group: {{ postfix.root_grp }} {%- if mapping.endswith('_sasl_password_maps') %} - mode: 600 {%- else %} @@ -90,7 +90,7 @@ postfix_{{ mapping }}: - pkg: postfix {%- if need_postmap %} cmd.wait: - - name: /usr/sbin/postmap {{ file_path }} + - name: {{ postfix.xbin_prefix }}/sbin/postmap {{ file_path }} - cwd: / - watch: - file: {{ file_path }} From d51f60647acd60bd32e2141c09611a3366de94d8 Mon Sep 17 00:00:00 2001 From: Florian Ermisch Date: Thu, 24 Aug 2017 12:49:05 +0200 Subject: [PATCH 05/16] add optional context variable "colon" to mapping.j2 for aliases file --- postfix/aliases | 3 --- postfix/files/mapping.j2 | 7 +++++-- postfix/init.sls | 5 ++++- 3 files changed, 9 insertions(+), 6 deletions(-) delete mode 100644 postfix/aliases diff --git a/postfix/aliases b/postfix/aliases deleted file mode 100644 index 04fa424..0000000 --- a/postfix/aliases +++ /dev/null @@ -1,3 +0,0 @@ -# Managed by config management -# See man 5 aliases for format -{{pillar['postfix']['aliases']['content']}} diff --git a/postfix/files/mapping.j2 b/postfix/files/mapping.j2 index 976a205..a177bf4 100644 --- a/postfix/files/mapping.j2 +++ b/postfix/files/mapping.j2 @@ -1,11 +1,14 @@ # Managed by config management +{%- if colon is not defined %} + {%- set colon = False %} +{%- endif %} {%- macro format_value(key, value) %} {#- Some settings, like virtual_alias_maps can take multiple values. Handle this case. -#} {%- if value is iterable and value is not string -%} -{{ key }} {{ value|join(", ") }} +{{ key }}{% if colon %}:{% endif %} {{ value|join(", ") }} {%- else -%} -{{ key }} {{ value }} +{{ key }}{% if colon %}:{% endif %} {{ value }} {%- endif -%} {%- endmacro %} diff --git a/postfix/init.sls b/postfix/init.sls index 6642bb6..b428ef3 100644 --- a/postfix/init.sls +++ b/postfix/init.sls @@ -31,11 +31,14 @@ postfix: postfix_alias_database: file.managed: - name: {{ file_path }} - - source: salt://postfix/aliases + - source: salt://postfix/files/mapping.j2 - user: root - group: {{ postfix.root_grp }} - mode: 644 - template: jinja + - context: + data: {{ salt['pillar.get']('postfix:aliases:present') }} + colon: True - require: - pkg: postfix {%- if need_newaliases %} From 136e02a61cfc0e6dfcfacf94cd1be981c753ca9d Mon Sep 17 00:00:00 2001 From: Florian Ermisch Date: Thu, 24 Aug 2017 12:52:06 +0200 Subject: [PATCH 06/16] check for absolute `file_path`s for maps --- postfix/init.sls | 3 +++ 1 file changed, 3 insertions(+) diff --git a/postfix/init.sls b/postfix/init.sls index b428ef3..0b1d4c8 100644 --- a/postfix/init.sls +++ b/postfix/init.sls @@ -72,6 +72,9 @@ postfix_alias_absent_{{ user }}: {%- else %} {%- set file_type = default_database_type %} {%- endif %} + {%- if not file_path.startswith('/') %} + {%- set file_path = postfix.config_path ~ '/' ~ file_path %} + {%- endif %} {%- if file_type in ("btree", "cdb", "dbm", "hash", "sdbm") %} {%- set need_postmap = True %} {%- endif %} From 8eed254773586506bab5b59adb892fe303b7ca57 Mon Sep 17 00:00:00 2001 From: Florian Ermisch Date: Thu, 24 Aug 2017 13:10:54 +0200 Subject: [PATCH 07/16] one for-loop for all of the mappings --- postfix/files/main.cf | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/postfix/files/main.cf b/postfix/files/main.cf index 4d686bc..219ee6b 100644 --- a/postfix/files/main.cf +++ b/postfix/files/main.cf @@ -97,17 +97,22 @@ policy-spf_time_limit = {{ policyd_spf.get('time_limit', '3600s') }} {%- endif %} {{ set_parameter('smtpd_recipient_restrictions', recipient_restrictions) }} -{% if 'virtual' in pillar.get('postfix','') %} -virtual_alias_maps = hash:/etc/postfix/virtual -{% endif %} +{# From init.sls #} +{%- set default_database_type = salt['pillar.get']('postfix:config:default_database_type', 'hash') %} -{% if 'sasl_passwd' in pillar.get('postfix','') %} -smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd -{% endif %} +{%- for mapping, data in salt['pillar.get']('postfix:mapping', {}).items() %} + {%- set file_path = salt['pillar.get']('postfix:config:' ~ mapping) %} + {%- if ':' in file_path %} + {%- set file_type, file_path = file_path.split(':') %} + {%- else %} + {%- set file_type = default_database_type %} + {%- endif %} + {%- if not file_path.startswith('/') %} + {%- set file_path = postfix.config_path ~ '/' ~ file_path %} + {%- endif %} -{% if 'sender_canonical' in pillar.get('postfix','') %} -sender_canonical_maps = hash:/etc/postfix/sender_canonical -{% endif %} +{{ mapping }} = {{ file_type }}:{{ file_path }} +{% endfor %} {# Accept arbitrary parameters -#} {% for parameter in config -%} From c60c3bab6f2786fcbbf1de5b5569570198777c11 Mon Sep 17 00:00:00 2001 From: Florian Ermisch Date: Thu, 24 Aug 2017 13:25:38 +0200 Subject: [PATCH 08/16] adjust processed_parameters to match pillar.example --- postfix/files/main.cf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/postfix/files/main.cf b/postfix/files/main.cf index 219ee6b..57cab2b 100644 --- a/postfix/files/main.cf +++ b/postfix/files/main.cf @@ -1,6 +1,11 @@ {%- from "postfix/map.jinja" import postfix with context -%} {%- set config = salt['pillar.get']('postfix:config', {}) -%} -{% set processed_parameters = ['aliases_file', 'virtual', 'sasl_passwd', 'sender_canonical'] %} +{%- set processed_parameters = [ + 'aliases_file', + 'virtual_alias_maps', + 'smtp_sasl_password_maps', + 'sender_canonical_maps', + ] %} {%- macro set_parameter(parameter, default=None) -%} {% set value = config.get(parameter, default) %} {%- if value is not none %} From f514881e5a2edfee927cee015c2331a3566bbe0d Mon Sep 17 00:00:00 2001 From: Florian Ermisch Date: Thu, 24 Aug 2017 13:35:24 +0200 Subject: [PATCH 09/16] explain the difference between alias_maps and alias_database --- pillar.example | 3 +++ postfix/files/main.cf | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pillar.example b/pillar.example index bb09c3a..6199c41 100644 --- a/pillar.example +++ b/pillar.example @@ -36,6 +36,9 @@ postfix: # Alias alias_maps: hash:/etc/aliases + # This is the list of files for the newaliases + # cmd to process (see postconf(5) for details). + # Only local hash/btree/dbm files: alias_database: hash:/etc/aliases # Virtual users diff --git a/postfix/files/main.cf b/postfix/files/main.cf index 57cab2b..f775745 100644 --- a/postfix/files/main.cf +++ b/postfix/files/main.cf @@ -1,7 +1,7 @@ {%- from "postfix/map.jinja" import postfix with context -%} {%- set config = salt['pillar.get']('postfix:config', {}) -%} +{#- TODO: alias_maps probably belongs here, too: #} {%- set processed_parameters = [ - 'aliases_file', 'virtual_alias_maps', 'smtp_sasl_password_maps', 'sender_canonical_maps', @@ -74,6 +74,7 @@ {%- endif %} {{ set_parameter('myhostname', grains['fqdn']) }} +{#- TODO: The following two may not be the same: #} {{ set_parameter('alias_maps', 'hash:' ~ postfix.aliases_file) }} {{ set_parameter('alias_database', 'hash:' ~ postfix.aliases_file) }} {{ set_parameter('mydestination', [grains['fqdn'], 'localhost', 'localhost.localdomain', grains['domain']]) }} From 9ed99927c2436eef20b66f360a790c77ed4223fb Mon Sep 17 00:00:00 2001 From: Florian Ermisch Date: Fri, 25 Aug 2017 14:54:20 +0200 Subject: [PATCH 10/16] explain what the colon in mapping.j2 is for --- postfix/files/mapping.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/postfix/files/mapping.j2 b/postfix/files/mapping.j2 index a177bf4..348ab4d 100644 --- a/postfix/files/mapping.j2 +++ b/postfix/files/mapping.j2 @@ -1,5 +1,7 @@ # Managed by config management - +{#- Some files (mainly the aliases one) require key and values + to be separated with a colon. For this `colon: True` should + be passed to the template #} {%- if colon is not defined %} {%- set colon = False %} {%- endif %} From ae878da8fae288c3c19ee82108a75fd2f671e7ea Mon Sep 17 00:00:00 2001 From: Alexander Weidinger Date: Fri, 8 Dec 2017 03:06:42 +0100 Subject: [PATCH 11/16] Use defaults.yaml and osmap.yaml --- postfix/defaults.yaml | 16 ++++---- postfix/map.jinja | 86 +++++-------------------------------------- postfix/osmap.yaml | 24 ++++++++++++ 3 files changed, 42 insertions(+), 84 deletions(-) create mode 100644 postfix/osmap.yaml diff --git a/postfix/defaults.yaml b/postfix/defaults.yaml index 4cdf80d..0ff63f7 100644 --- a/postfix/defaults.yaml +++ b/postfix/defaults.yaml @@ -2,11 +2,11 @@ # vim: ft=yaml postfix: - aliases_file: /etc/aliases - config_path: /etc/postfix - package: postfix - postsrsd_pkg: postsrsd - postgrey_pkg: postgrey - root_grp: root - service: postfix - xbin_prefix: /usr + aliases_file: /etc/aliases + config_path: /etc/postfix + package: postfix + postsrsd_pkg: postsrsd + postgrey_pkg: postgrey + root_grp: root + service: postfix + xbin_prefix: /usr diff --git a/postfix/map.jinja b/postfix/map.jinja index af305fd..341d727 100644 --- a/postfix/map.jinja +++ b/postfix/map.jinja @@ -1,81 +1,15 @@ # -*- coding: utf-8 -*- # vim: ft=jinja -{%- macro deep_merge(a, b) %} -{#- This whole `'dict' in x.__class__.__name__` mess is a - workaround for the missing mapping test in CentOS 6's - ancient Jinja2, see #193 #} -{%- for k,v in b.iteritems() %} -{%- if v is string or v is number %} -{%- do a.update({ k: v }) %} -{%- elif 'dict' not in v.__class__.__name__ %} -{%- if a[k] is not defined %} -{%- do a.update({ k: v }) %} -{%- elif a[k] is iterable and 'dict' not in a[k].__class__.__name__ and - a[k] is not string %} -{%- do a.update({ k: v|list + a[k]|list}) %} -{%- else %} -{%- do a.update({ k: v }) %} -{%- endif %} -{%- elif 'dict' in v.__class__.__name__ %} -{%- if a[k] is not defined %} -{%- do a.update({ k: v }) %} -{%- elif 'dict' in a[k].__class__.__name__ %} -{%- do a.update({ k: v }) %} -{%- else %} -{%- do deep_merge(a[k], v) %} -{%- endif %} -{%- else %} -{%- do a.update({ k: 'ERROR: case not contempled in merging!' }) %} -{%- endif %} -{%- endfor %} -{%- endmacro %} +{% import_yaml "postfix/defaults.yaml" as defaults %} +{% import_yaml "postfix/osmap.yaml" as osmap %} - -{## Start with defaults from defaults.yaml ##} -{% import_yaml "postfix/defaults.yaml" as default_settings %} - -{## -Setup variable using grains['os_family'] based logic, only add key:values here -that differ from whats in defaults.yaml -##} -{% set osrelease = salt['grains.get']('osrelease') %} -{# set salt_release = salt['pillar.get']('salt:release', 'latest') #} -{# set postfix = salt['grains.filter_by'](#} -{% set os_family_map = salt['grains.filter_by']({ - 'Debian': { - 'policyd_spf_pkg': 'postfix-policyd-spf-python', - 'pcre_pkg': 'postfix-pcre', - 'mysql_pkg': 'postfix-mysql', - }, - 'Gentoo': { - 'package': 'mail-mta/postfix', - 'policyd_spf_pkg': 'mail-filter/pypolicyd-spf', - 'postgrey_pkg': 'mail-filter/postgrey', - 'postsrsd_pkg': 'mail-filter/postsrsd', - 'aliases_file': '/etc/mail/aliases', - }, - 'RedHat': { - 'policyd_spf_pkg': 'pypolicyd-spf', - }, - 'Arch' : { - 'policyd_spf_pkg': 'python-postfix-policyd-spf', - }, - 'FreeBSD' : { - 'policyd_spf_pkg': 'py27-postfix-policyd-spf-python', - 'aliases_file': '/etc/mail/aliases', - 'xbin_prefix': '/usr/local', - 'config_path': '/usr/local/etc/postfix', - 'root_grp': 'wheel', - }, -}, merge=salt['pillar.get']('postfix:lookup')) %} - -{## Merge the flavor_map to the default settings ##} -{% do deep_merge(default_settings.postfix, os_family_map) %} - -{## Merge in postfix:lookup pillar ##} -{% set postfix = salt['pillar.get']( - 'postfix', - default=default_settings.postfix, - merge=True) +{% set postfix = salt['grains.filter_by']( + defaults, + merge=salt['grains.filter_by']( + osmap, + grain='os', + merge=salt['pillar.get']('postfix:lookup', {}), + ), + base='postfix') %} diff --git a/postfix/osmap.yaml b/postfix/osmap.yaml new file mode 100644 index 0000000..a63d17a --- /dev/null +++ b/postfix/osmap.yaml @@ -0,0 +1,24 @@ +Arch: + policyd_spf_pkg: python-postfix-policyd-spf + +Debian: + policyd_spf_pkg: postfix-policyd-spf-python + pcre_pkg: postfix-pcre + mysql_pkg: postfix-mysql + +FreeBSD: + policyd_spf_pkg: py27-postfix-policyd-spf-python + aliases_file: /etc/mail/aliases + xbin_prefix: /usr/local + config_path: /usr/local/etc/postfix + root_grp: wheel + +Gentoo: + package: mail-mta/postfix + policyd_spf_pkg: mail-filter/pypolicyd-spf + postsrsd_pkg: mail-filter/postsrsd + postgrey_pkg: mail-filter/postgrey + aliases_file: /etc/mail/aliases + +RedHat: + policyd_spf_pkg: pypolicyd-spf From 4c7c2a269d7ccc2f727ec9f2ea033f3cbe1ff9b6 Mon Sep 17 00:00:00 2001 From: Alexander Weidinger Date: Fri, 8 Dec 2017 13:20:01 +0100 Subject: [PATCH 12/16] master.cf: made submission configurable --- pillar.example | 5 +++++ postfix/files/master.cf | 19 +++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/pillar.example b/pillar.example index 6199c41..9733ba2 100644 --- a/pillar.example +++ b/pillar.example @@ -2,6 +2,11 @@ postfix: manage_master_config: True master_config: enable_submission: False + # To replace the defaults use this: + submission: + smtpd_tls_security_level: encrypt + smtpd_sasl_auth_enable: yes + smtpd_client_restrictions: permit_sasl_authenticated,reject enable_service: True diff --git a/postfix/files/master.cf b/postfix/files/master.cf index c993a80..39d7615 100644 --- a/postfix/files/master.cf +++ b/postfix/files/master.cf @@ -1,4 +1,13 @@ +{%- macro set_option(parameter, value) -%} + {%- if value is number or value is string -%} +-o {{ parameter }}={{ value }} + {%- elif value is iterable -%} +-o {{ parameter }}={{ value | join(', ')}} + {%- endif -%} +{%- endmacro -%} + {% set master_config = salt['pillar.get']('postfix:master_config', {}) -%} + # # Postfix master process configuration file. For details on the format # of the file, see the master(5) manual page (command: "man 5 master" or @@ -15,11 +24,17 @@ smtp inet n - n - - smtpd #smtpd pass - - n - - smtpd #dnsblog unix - - n - 0 dnsblog #tlsproxy unix - - n - 0 tlsproxy -{% if master_config.get('enable_submission', False) %} +{%- if master_config.get('enable_submission', False) %} submission inet n - n - - smtpd +{%- if master_config.get('submission', False) -%} +{% for parameter, value in master_config.get('submission', {}).items() %} + {{ set_option(parameter, value) }} +{%- endfor -%} +{% else %} # -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes +{% endif %} # -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions @@ -27,7 +42,7 @@ submission inet n - n - - smtpd # -o smtpd_recipient_restrictions= # -o smtpd_relay_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING -{% endif %} +{% endif -%} #smtps inet n - n - - smtpd # -o syslog_name=postfix/smtps # -o smtpd_tls_wrappermode=yes From caee18415852a8021b82529080e0f3b347eebfd4 Mon Sep 17 00:00:00 2001 From: Alexander Weidinger Date: Fri, 8 Dec 2017 14:04:35 +0100 Subject: [PATCH 13/16] master.cf: added dovecot --- pillar.example | 8 ++++++++ postfix/defaults.yaml | 1 + postfix/files/master.cf | 9 ++++++++- postfix/osmap.yaml | 1 + 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/pillar.example b/pillar.example index 9733ba2..2441d2f 100644 --- a/pillar.example +++ b/pillar.example @@ -1,6 +1,14 @@ postfix: manage_master_config: True master_config: + enable_dovecot: False + # The following are the default values: + dovecot: + user: vmail + group: vmail + flags: DRhu + argv: "/usr/lib/dovecot/deliver -d ${recipient}" + enable_submission: False # To replace the defaults use this: submission: diff --git a/postfix/defaults.yaml b/postfix/defaults.yaml index 0ff63f7..584c6f6 100644 --- a/postfix/defaults.yaml +++ b/postfix/defaults.yaml @@ -10,3 +10,4 @@ postfix: root_grp: root service: postfix xbin_prefix: /usr + dovecot_deliver: /usr/lib/dovecot/deliver diff --git a/postfix/files/master.cf b/postfix/files/master.cf index 39d7615..5b69be5 100644 --- a/postfix/files/master.cf +++ b/postfix/files/master.cf @@ -1,3 +1,5 @@ +{%- from "postfix/map.jinja" import postfix with context -%} + {%- macro set_option(parameter, value) -%} {%- if value is number or value is string -%} -o {{ parameter }}={{ value }} @@ -146,7 +148,12 @@ scache unix - - n - 1 scache #mailman unix - n n - - pipe # flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py # ${nexthop} ${user} -{% if salt['pillar.get']('postfix:policyd-spf:enabled', False) %} +{%- if salt['pillar.get']('postfix:policyd-spf:enabled', False) %} policy-spf unix - n n - - spawn user=nobody argv={{ xbin_prefix }}/bin/policyd-spf {%- endif %} +{%- if master_config.get('enable_dovecot', False) -%} +{%- set dovecot = master_config.get('dovecot', {} )%} +dovecot unix - n n - - pipe + flags={{ dovecot.get('flags', 'DRhu') }} user={{ dovecot.get('user', 'vmail') }}:{{ dovecot.get('group', 'vmail') }} argv={{ dovecot.get('argv', postfix.dovecot_deliver) ~ ' -d ${recipient}' }} +{% endif -%} diff --git a/postfix/osmap.yaml b/postfix/osmap.yaml index a63d17a..c5e79a3 100644 --- a/postfix/osmap.yaml +++ b/postfix/osmap.yaml @@ -12,6 +12,7 @@ FreeBSD: xbin_prefix: /usr/local config_path: /usr/local/etc/postfix root_grp: wheel + dovecot_deliver: /usr/local/libexec/dovecot/deliver Gentoo: package: mail-mta/postfix From 014c5227bcd1f49b03d0da0f57fe0c5ae20958e4 Mon Sep 17 00:00:00 2001 From: Alexander Weidinger Date: Fri, 8 Dec 2017 14:53:58 +0100 Subject: [PATCH 14/16] Let the user handle mappings manually --- postfix/files/main.cf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/postfix/files/main.cf b/postfix/files/main.cf index f775745..a3c0105 100644 --- a/postfix/files/main.cf +++ b/postfix/files/main.cf @@ -1,11 +1,18 @@ {%- from "postfix/map.jinja" import postfix with context -%} {%- set config = salt['pillar.get']('postfix:config', {}) -%} + +{%- if not salt['pillar.get']('postfix:mapping', False) %} +{#- Let the user configure mapping manually. -#} +{%- set processed_parameters = [] %} +{%- else -%} {#- TODO: alias_maps probably belongs here, too: #} {%- set processed_parameters = [ 'virtual_alias_maps', 'smtp_sasl_password_maps', 'sender_canonical_maps', ] %} +{%- endif -%} + {%- macro set_parameter(parameter, default=None) -%} {% set value = config.get(parameter, default) %} {%- if value is not none %} @@ -17,6 +24,7 @@ {%- do processed_parameters.append(parameter) %} {%- endif %} {%- endmacro -%} + # Managed by config management # See /usr/share/postfix/main.cf.dist for a commented, more complete version From f4a10a28438655ccc8f4c1365aa833e0635360ff Mon Sep 17 00:00:00 2001 From: Alexander Weidinger Date: Thu, 28 Dec 2017 21:42:23 +0100 Subject: [PATCH 15/16] re-enable Pillar postfix:aliases:content --- postfix/init.sls | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/postfix/init.sls b/postfix/init.sls index 0b1d4c8..8540765 100644 --- a/postfix/init.sls +++ b/postfix/init.sls @@ -31,7 +31,11 @@ postfix: postfix_alias_database: file.managed: - name: {{ file_path }} + {% if salt['pillar.get']('postfix:aliases:content', None) is string %} + - contents_pillar: postfix:aliases:content + {% else %} - source: salt://postfix/files/mapping.j2 + {% endif %} - user: root - group: {{ postfix.root_grp }} - mode: 644 From f30071afd290c35432556573b0418f31ade9854f Mon Sep 17 00:00:00 2001 From: Niels Abspoel Date: Wed, 7 Mar 2018 21:17:57 +0100 Subject: [PATCH 16/16] replace iteritems with items --- postfix/files/mapping.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postfix/files/mapping.j2 b/postfix/files/mapping.j2 index 348ab4d..1e564c6 100644 --- a/postfix/files/mapping.j2 +++ b/postfix/files/mapping.j2 @@ -15,7 +15,7 @@ {%- endmacro %} {%- if data is mapping %} -{% for key, value in data.iteritems() %} +{% for key, value in data.items() %} {{ format_value(key, value) }} {%- endfor -%} {%- else %}