From 62ab827c3444df39e201088837fce38e25ca9edb Mon Sep 17 00:00:00 2001 From: Gilles Dartiguelongue Date: Fri, 8 Apr 2016 17:50:52 +0200 Subject: [PATCH 1/5] Replace postmap_macro by generic handling of map files Merge existing handling of postfix lookup table/map files into a single template. Mappings are read from pillar in `postfix:mapping`. Configuration is written to the file pointed to by the relevant directive in `postfix:config`. A single target file is supported at the moment. The file is postmap'ed if needed. The pillar accepts a dict or an OrderedDict. --- pillar.example | 41 ++++++++++++++--------- postfix/files/mapping.j2 | 19 +++++++++++ postfix/init.sls | 72 +++++++++++++++++++--------------------- postfix/relay_domains | 7 ---- postfix/sasl_passwd | 7 ---- postfix/sender_canonical | 7 ---- postfix/virtual | 17 ---------- 7 files changed, 78 insertions(+), 92 deletions(-) create mode 100644 postfix/files/mapping.j2 delete mode 100644 postfix/relay_domains delete mode 100644 postfix/sasl_passwd delete mode 100644 postfix/sender_canonical delete mode 100644 postfix/virtual diff --git a/pillar.example b/pillar.example index cd33d3e..4d12ba1 100644 --- a/pillar.example +++ b/pillar.example @@ -5,22 +5,6 @@ postfix: enable_service: True - virtual: - groupaliasexample: - - someuser_1@example.com - - someuser_2@example.com - singlealiasexample: 'someuser_3@example.com' - - relay_domains: - example.com: 'OK' - - sasl_passwd: - smtp.example.com: 'somepassword' - - sender_canonical: - root: 'servers@example.com' - nagios: 'alerts@example.com' - postgrey: enabled: True enable_service: True @@ -62,6 +46,14 @@ postfix: smtp_tls_cert_file: /etc/postfix/ssl/example.com-relay-client-cert.crt smtp_tls_key_file: /etc/postfix/ssl/example.com-relay-client-cert.key + smtp_sasl_password_maps: hash:/etc/postfix/sasl_passwd + + sender_canonical_maps: hash:/etc/postfix/sender_canonical + + relay_recipient_maps: hash:/etc/postfix/relay_domains + + virtual_alias_maps: hash:/etc/postfix/virtual + certificates: server-cert: public_cert: | @@ -88,3 +80,20 @@ postfix: -----BEGIN RSA PRIVATE KEY----- (Your Private key) -----END RSA PRIVATE KEY----- + + mapping: + smtp_sasl_password_maps: + - smtp.example.com: myaccount:somepassword + + sender_canonical_maps: + - root: servers@example.com + - nagios: alerts@example.com + + relay_recipient_maps: + - example.com: OK + + virtual_alias_maps: + - groupaliasexample: + - someuser_1@example.com + - someuser_2@example.com + - singlealiasexample: someuser_3@example.com diff --git a/postfix/files/mapping.j2 b/postfix/files/mapping.j2 new file mode 100644 index 0000000..e403ac3 --- /dev/null +++ b/postfix/files/mapping.j2 @@ -0,0 +1,19 @@ +# Managed by config management + +{% if data is mapping -%} + {% for key, value in data.iteritems() -%} + {# Some settings, like virtual_alias_maps can take multiple values. Handle this case. -#} + {% if value is iterable and value is not string -%} + {% for item in value -%} +{{ key }} {{ item }} + {% endfor -%} + {% else -%} +{{ key }} {{ value }} + {% endif -%} + {% endfor -%} +{% else -%} + {# Some settings need order, handle OrderedDict -#} + {% for item in data -%} +{{ item.keys()[0] }} {{ item.values()[0] }} +{% endfor -%} +{% endif -%} diff --git a/postfix/init.sls b/postfix/init.sls index 494496e..fb0483c 100644 --- a/postfix/init.sls +++ b/postfix/init.sls @@ -12,25 +12,6 @@ postfix: - watch: - pkg: postfix -{%- macro postmap_file(filename, mode=644) %} -{%- set file_path = '/etc/postfix/' ~ filename %} -postmap_{{ filename }}: - file.managed: - - name: {{ file_path }} - - source: salt://postfix/{{ filename }} - - user: root - - group: root - - mode: {{ mode }} - - template: jinja - - require: - - pkg: postfix - cmd.wait: - - name: /usr/sbin/postmap {{ file_path }} - - cwd: / - - watch: - - file: {{ file_path }} -{%- endmacro %} - # manage /etc/aliases if data found in pillar {% if 'aliases' in pillar.get('postfix', '') %} {{ postfix.aliases_file }}: @@ -51,22 +32,37 @@ run-newaliases: - file: {{ postfix.aliases_file }} {% endif %} -# manage /etc/postfix/virtual if data found in pillar -{% if 'virtual' in pillar.get('postfix', '') %} -{{ postmap_file('virtual') }} -{% endif %} - -# manage /etc/postfix/relay_domains if data found in pillar -{% if 'relay_domains' in pillar.get('postfix', '') %} -{{ postmap_file('relay_domains') }} -{% endif %} - -# manage /etc/postfix/sasl_passwd if data found in pillar -{% if 'sasl_passwd' in pillar.get('postfix', '') %} -{{ postmap_file('sasl_passwd', 600) }} -{% endif %} - -# manage /etc/postfix/sender_canonical if data found in pillar -{% if 'sender_canonical' in pillar.get('postfix', '') %} -{{ postmap_file('sender_canonical') }} -{% endif %} +# manage various mappings +{% for mapping, data in salt['pillar.get']('postfix:mapping', {}).items() %} + {%- set need_postmap = False %} + {%- set file_path = salt['pillar.get']('postfix:config:' ~ mapping) %} + {%- if ':' in file_path %} + {%- set file_path = file_path.split(':')[1] %} + {%- set need_postmap = True %} + {%- endif %} +postfix_{{ mapping }}: + file.managed: + - name: {{ file_path }} + - source: salt://postfix/files/mapping.j2 + - user: root + - group: root + {%- if mapping == 'smtp_sasl_password_maps' %} + - mode: 600 + {%- else %} + - mode: 644 + {%- endif %} + - template: jinja + - context: + data: {{ data|json() }} + - require: + - pkg: postfix + {%- if need_postmap %} + cmd.wait: + - name: /usr/sbin/postmap {{ file_path }} + - cwd: / + - watch: + - file: {{ file_path }} + - watch_in: + - service: postfix + {%- endif %} +{% endfor %} diff --git a/postfix/relay_domains b/postfix/relay_domains deleted file mode 100644 index 1992301..0000000 --- a/postfix/relay_domains +++ /dev/null @@ -1,7 +0,0 @@ -# Managed by config management -{% set canonical = salt['pillar.get']('postfix:relay_domains',{}) -%} -{% if canonical is iterable -%} -{% for key,value in salt['pillar.get']('postfix:relay_domains',{}).iteritems() -%} -{{ key }} {{ value }} -{% endfor %} -{% endif %} diff --git a/postfix/sasl_passwd b/postfix/sasl_passwd deleted file mode 100644 index df651c3..0000000 --- a/postfix/sasl_passwd +++ /dev/null @@ -1,7 +0,0 @@ -# Managed by config management -{% set canonical = salt['pillar.get']('postfix:sasl_passwd',{}) -%} -{% if canonical is iterable -%} -{% for key,value in salt['pillar.get']('postfix:sasl_passwd',{}).iteritems() -%} -{{ key }} {{ value }} -{% endfor %} -{% endif %} diff --git a/postfix/sender_canonical b/postfix/sender_canonical deleted file mode 100644 index b0f7e9c..0000000 --- a/postfix/sender_canonical +++ /dev/null @@ -1,7 +0,0 @@ -# Managed by config management -{% set canonical = salt['pillar.get']('postfix:sender_canonical',{}) -%} -{% if canonical is iterable -%} - {% for key,value in salt['pillar.get']('postfix:sender_canonical',{}).iteritems() -%} - {{ key }} {{ value }} - {% endfor %} -{% endif %} diff --git a/postfix/virtual b/postfix/virtual deleted file mode 100644 index 55f9f43..0000000 --- a/postfix/virtual +++ /dev/null @@ -1,17 +0,0 @@ -# Managed by config management -{% set virtual = salt['pillar.get']('postfix:virtual',{}) -%} -{# to have virtual file emptied, just set an empty key 'virtual' -#} -{% if virtual is iterable -%} - {% for key, value in virtual.iteritems() -%} - {# Mutiple values available for single key in virtual alias maps - ie for dist groups -#} - {# We test if list was provided as value, and iterate if so -#} - {% if value is iterable and value is not string -%} - {% for item in value -%} -{{key }} {{ item }} - {% endfor -%} - {% else -%} - {# ..otherwise expect it to be just a string for the value -#} -{{ key }} {{ value }} - {% endif -%} - {% endfor -%} -{% endif -%} From 4c780c184eb7c9d7bedde6fb7984611d7886e774 Mon Sep 17 00:00:00 2001 From: Gilles Dartiguelongue Date: Fri, 8 Apr 2016 17:54:09 +0200 Subject: [PATCH 2/5] Handle smtp/lmtp password maps file mode Do not hardcode the key name, even if there is only two at the moment --- postfix/init.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postfix/init.sls b/postfix/init.sls index fb0483c..3f4e717 100644 --- a/postfix/init.sls +++ b/postfix/init.sls @@ -46,7 +46,7 @@ postfix_{{ mapping }}: - source: salt://postfix/files/mapping.j2 - user: root - group: root - {%- if mapping == 'smtp_sasl_password_maps' %} + {%- if mapping.endswith('_sasl_password_maps') %} - mode: 600 {%- else %} - mode: 644 From 80645badee7c108656c108a76287c2ae23d3268c Mon Sep 17 00:00:00 2001 From: Gilles Dartiguelongue Date: Fri, 8 Apr 2016 18:27:15 +0200 Subject: [PATCH 3/5] Handle mappings passed as dict or OrderedDict --- postfix/files/mapping.j2 | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/postfix/files/mapping.j2 b/postfix/files/mapping.j2 index e403ac3..5045b1f 100644 --- a/postfix/files/mapping.j2 +++ b/postfix/files/mapping.j2 @@ -1,19 +1,23 @@ # Managed by config management -{% if data is mapping -%} - {% for key, value in data.iteritems() -%} - {# Some settings, like virtual_alias_maps can take multiple values. Handle this case. -#} - {% if value is iterable and value is not string -%} - {% for item in value -%} +{%- 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 -%} + {%- for item in value %} {{ key }} {{ item }} - {% endfor -%} - {% else -%} + {%- endfor %} + {%- else -%} {{ key }} {{ value }} - {% endif -%} - {% endfor -%} -{% else -%} - {# Some settings need order, handle OrderedDict -#} - {% for item in data -%} -{{ item.keys()[0] }} {{ item.values()[0] }} -{% endfor -%} -{% endif -%} + {%- endif -%} +{%- endmacro %} + +{%- if data is mapping %} +{% for key, value in data.iteritems() %} +{{ format_value(key, value) }} +{%- endfor -%} +{%- else %} +{#- Some settings need order, handle OrderedDict #} +{% for item in data %} +{{ format_value(item.keys()[0], item.values()[0]) }} +{%- endfor -%} +{%- endif %} From 573211150f85508735e133772dae1b2ec06d1bf0 Mon Sep 17 00:00:00 2001 From: Gilles Dartiguelongue Date: Mon, 20 Jun 2016 18:40:48 +0200 Subject: [PATCH 4/5] Actually print multiple value as described in man 5 virtual --- postfix/files/mapping.j2 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/postfix/files/mapping.j2 b/postfix/files/mapping.j2 index 5045b1f..fac8e7f 100644 --- a/postfix/files/mapping.j2 +++ b/postfix/files/mapping.j2 @@ -3,8 +3,9 @@ {%- 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 -%} - {%- for item in value %} -{{ key }} {{ item }} +{{ key }} {% for item in value -%} + {{ item }} + {%- if not loop.last %}, {% endif %} {%- endfor %} {%- else -%} {{ key }} {{ value }} From e10ad0e7456edaa76509508de9c23103603607f7 Mon Sep 17 00:00:00 2001 From: Gilles Dartiguelongue Date: Mon, 20 Jun 2016 19:02:41 +0200 Subject: [PATCH 5/5] Make prope use of jinja templating features join is available in jinja-2.6, released in 2011. --- postfix/files/mapping.j2 | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/postfix/files/mapping.j2 b/postfix/files/mapping.j2 index fac8e7f..976a205 100644 --- a/postfix/files/mapping.j2 +++ b/postfix/files/mapping.j2 @@ -3,10 +3,7 @@ {%- 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 }} {% for item in value -%} - {{ item }} - {%- if not loop.last %}, {% endif %} - {%- endfor %} +{{ key }} {{ value|join(", ") }} {%- else -%} {{ key }} {{ value }} {%- endif -%}