├── postfix ├── postsrsd.sls ├── policyd-spf.sls ├── mysql.sls ├── pcre.sls ├── map.jinja ├── _mapdata │ ├── _mapdata.jinja │ └── init.sls ├── defaults.yaml ├── postgrey.sls ├── iptables-input.sls ├── files │ ├── mapping.j2 │ ├── virtual_alias_maps.cf │ ├── virtual_mailbox_maps.cf │ ├── virtual_mailbox_domains.cf │ ├── main.cf │ └── master.cf ├── osfamilymap.yaml ├── init.sls ├── config.sls └── services.yaml ├── test ├── integration │ ├── default │ │ ├── controls │ │ │ ├── pkgs_spec.rb │ │ │ ├── service_spec.rb │ │ │ ├── postfix_maps_spec.rb │ │ │ ├── postfix_maps_type_spec.rb │ │ │ └── postfix_spec.rb │ │ ├── inspec.yml │ │ └── README.md │ └── share │ │ ├── inspec.yml │ │ ├── README.md │ │ └── libraries │ │ └── system.rb └── salt │ └── pillar │ └── default.sls ├── .github ├── settings.yml ├── workflows │ ├── commitlint.yml │ └── main.yml └── renovate.json5 ├── FORMULA ├── .rstcheck.cfg ├── commitlint.config.js ├── bin ├── install-hooks └── kitchen ├── .copier-answers.ssf-ci.yml ├── LICENSE ├── .yamllint ├── .rubocop.yml ├── .salt-lint ├── Gemfile ├── pre-commit_semantic-release.sh ├── release.config.js ├── .gitignore ├── CODEOWNERS ├── docs ├── README.rst ├── AUTHORS.rst └── CHANGELOG.rst ├── .pre-commit-config.yaml ├── AUTHORS.md ├── .travis.yml ├── kitchen.yml ├── pillar.example ├── .gitlab-ci.yml ├── CHANGELOG.md └── Gemfile.lock /postfix/postsrsd.sls: -------------------------------------------------------------------------------- 1 | {% from "postfix/map.jinja" import postfix with context %} 2 | 3 | postfix-postsrsd-pkg-latest-postsrsd: 4 | pkg.latest: 5 | - name: {{ postfix.postsrsd_pkg }} 6 | 7 | -------------------------------------------------------------------------------- /postfix/policyd-spf.sls: -------------------------------------------------------------------------------- 1 | {% from "postfix/map.jinja" import postfix with context %} 2 | 3 | postfix-policyd-spf-pkg-installed-policyd_spf: 4 | pkg.installed: 5 | - name: {{ postfix.policyd_spf_pkg }} 6 | -------------------------------------------------------------------------------- /test/integration/default/controls/pkgs_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | control 'Postfix packages' do 4 | title 'should be installed' 5 | 6 | describe package('postfix') do 7 | it { should be_installed } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /postfix/mysql.sls: -------------------------------------------------------------------------------- 1 | {% from "postfix/map.jinja" import postfix with context %} 2 | 3 | postfix-mysql-pkg-installed-mysql: 4 | pkg.installed: 5 | - name: {{ postfix.mysql_pkg }} 6 | - watch_in: 7 | - service: postfix-init-service-running-postfix 8 | -------------------------------------------------------------------------------- /postfix/pcre.sls: -------------------------------------------------------------------------------- 1 | {% from "postfix/map.jinja" import postfix with context %} 2 | 3 | postfix-pcre-pkg-installed-pcre: 4 | pkg.installed: 5 | - name: {{ postfix.pcre_pkg }} 6 | - watch_in: 7 | - service: postfix-init-service-running-postfix 8 | -------------------------------------------------------------------------------- /.github/settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # These settings are synced to GitHub by https://probot.github.io/apps/settings/ 3 | 4 | repository: 5 | # See https://docs.github.com/en/rest/reference/repos#update-a-repository 6 | # for all available settings 7 | 8 | allow_squash_merge: false 9 | -------------------------------------------------------------------------------- /FORMULA: -------------------------------------------------------------------------------- 1 | name: postfix 2 | os: Debian, Ubuntu, Raspbian, RedHat, Fedora, CentOS, Suse, openSUSE 3 | os_family: Debian, RedHat, Suse 4 | version: 2.0.3 5 | release: 1 6 | minimum_version: 2016.11 7 | summary: Postfix formula 8 | description: Formula to install and configure Postfix mail server 9 | top_level_dir: postfix 10 | -------------------------------------------------------------------------------- /.rstcheck.cfg: -------------------------------------------------------------------------------- 1 | [rstcheck] 2 | report=info 3 | ignore_language=rst 4 | # salt['config.get']('roles') is misidentified as a Markdown link. 5 | # Ignore for now, but perhaps try to submit a fix upstream in rstcheck 6 | ignore_messages=(Duplicate (ex|im)plicit target.*|Hyperlink target ".*" is not referenced\.$|\(rst\) Link is formatted in Markdown style\.) 7 | -------------------------------------------------------------------------------- /test/integration/default/controls/service_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | control 'Postfix service' do 4 | title 'should be running' 5 | 6 | describe service('postfix') do 7 | it { should be_enabled } 8 | it { should be_running } 9 | end 10 | 11 | describe port(25) do 12 | it { should be_listening } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /.github/workflows/commitlint.yml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | name: Commitlint 5 | 'on': [pull_request] 6 | 7 | jobs: 8 | lint: 9 | runs-on: ubuntu-latest 10 | env: 11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | fetch-depth: 0 16 | - uses: wagoid/commitlint-github-action@v1 17 | -------------------------------------------------------------------------------- /postfix/map.jinja: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=jinja 3 | 4 | {% import_yaml "postfix/defaults.yaml" as defaults %} 5 | {% import_yaml "postfix/osfamilymap.yaml" as os_familymap %} 6 | 7 | {% set postfix = salt['grains.filter_by']( 8 | defaults, 9 | merge=salt['grains.filter_by']( 10 | os_familymap, 11 | merge=salt['pillar.get']('postfix:lookup', {}), 12 | ), 13 | base='postfix') 14 | %} 15 | -------------------------------------------------------------------------------- /postfix/_mapdata/_mapdata.jinja: -------------------------------------------------------------------------------- 1 | # yamllint disable rule:indentation rule:line-length 2 | # {{ grains.get("osfinger", grains.os) }} 3 | --- 4 | {#- use salt.slsutil.serialize to avoid encoding errors on some platforms #} 5 | {{ salt["slsutil.serialize"]( 6 | "yaml", 7 | map, 8 | default_flow_style=False, 9 | allow_unicode=True, 10 | ) 11 | | regex_replace("^\s+'$", "'", multiline=True) 12 | | trim 13 | }} 14 | -------------------------------------------------------------------------------- /postfix/defaults.yaml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | postfix: 5 | aliases_file: /etc/aliases 6 | config_path: /etc/postfix 7 | package: postfix 8 | postsrsd_pkg: postsrsd 9 | postgrey_pkg: postgrey 10 | root_grp: root 11 | setgid_group: postdrop 12 | daemon_directory: /usr/libexec/postfix 13 | service: postfix 14 | xbin_prefix: /usr 15 | dovecot_deliver: /usr/lib/dovecot/deliver 16 | default_database_type: hash 17 | -------------------------------------------------------------------------------- /.github/renovate.json5: -------------------------------------------------------------------------------- 1 | { 2 | $schema: 'https://docs.renovatebot.com/renovate-schema.json', 3 | extends: [ 4 | "github>saltstack-formulas/.github", 5 | "github>saltstack-formulas/.github:copier" 6 | ], 7 | /********************************************************** 8 | * This file is managed as part of a Copier template. * 9 | * Please make your own changes below this comment. * 10 | *********************************************************/ 11 | } 12 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'body-max-line-length': [2, 'always', 120], 5 | 'footer-max-line-length': [2, 'always', 120], 6 | 'header-max-length': [2, 'always', 72] 7 | }, 8 | ignores: [ 9 | (commit) => commit.startsWith('chore(copier):'), 10 | (commit) => commit.startsWith('chore(deps):'), 11 | (commit) => commit.startsWith('ci(pre-commit.ci):'), 12 | (commit) => commit.startsWith('[CI merge]') 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /postfix/postgrey.sls: -------------------------------------------------------------------------------- 1 | {% from "postfix/map.jinja" import postfix with context %} 2 | 3 | postfix-postgrey-pkg-installed-postgrey: 4 | pkg.installed: 5 | - name: {{ postfix.postgrey_pkg }} 6 | 7 | postfix-postgrey-service-running-postgrey: 8 | service.running: 9 | - name: postgrey 10 | - enable: {{ salt['pillar.get']('postfix:postgrey:enable_service', True) }} 11 | - require: 12 | - pkg: postfix-postgrey-pkg-installed-postgrey 13 | - watch: 14 | - pkg: postfix-postgrey-pkg-installed-postgrey 15 | 16 | -------------------------------------------------------------------------------- /bin/install-hooks: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -o nounset # Treat unset variables as an error and immediately exit 3 | set -o errexit # If a command fails exit the whole script 4 | 5 | if [ "${DEBUG:-false}" = "true" ]; then 6 | set -x # Run the entire script in debug mode 7 | fi 8 | 9 | if ! command -v pre-commit >/dev/null 2>&1; then 10 | echo "pre-commit not found: please install or check your PATH" >&2 11 | echo "See https://pre-commit.com/#installation" >&2 12 | exit 1 13 | fi 14 | 15 | pre-commit install --install-hooks 16 | pre-commit install --hook-type commit-msg --install-hooks 17 | -------------------------------------------------------------------------------- /.copier-answers.ssf-ci.yml: -------------------------------------------------------------------------------- 1 | # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY 2 | _commit: v2.10.2 3 | _src_path: https://github.com/dafyddj/copier-ssf-ci 4 | failure_permitted_ignored: [] 5 | failure_permitted_patterns: [] 6 | formula_name: postfix 7 | release_using_gha: false 8 | renovate_extend_presets: 9 | - github>saltstack-formulas/.github 10 | - github>saltstack-formulas/.github:copier 11 | renovate_ignore_presets: [] 12 | supported_oses: 13 | - AlmaLinux OS 14 | - Amazon Linux 15 | - CentOS 16 | - Debian 17 | - Fedora Linux 18 | - openSUSE 19 | - Oracle Linux 20 | - Rocky Linux 21 | - Ubuntu 22 | test_using_gha: false 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2015 Salt Stack Formulas 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | # Extend the `default` configuration provided by `yamllint` 5 | extends: 'default' 6 | 7 | rules: 8 | comments: 9 | min-spaces-from-content: 1 10 | empty-values: 11 | forbid-in-block-mappings: true 12 | forbid-in-flow-mappings: true 13 | key-duplicates: 14 | ignore: | 15 | pillar.example 16 | line-length: 17 | # Increase from default of `80` 18 | # Based on https://github.com/PyCQA/flake8-bugbear#opinionated-warnings (`B950`) 19 | max: 88 20 | allow-non-breakable-inline-mappings: true 21 | octal-values: 22 | forbid-implicit-octal: true 23 | forbid-explicit-octal: true 24 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | # General overrides used across formulas in the org 5 | Layout/LineLength: 6 | # Increase from default of `80` 7 | # Based on https://github.com/PyCQA/flake8-bugbear#opinionated-warnings (`B950`) 8 | Max: 88 9 | Metrics/BlockLength: 10 | AllowedMethods: 11 | - control 12 | - describe 13 | # Increase from default of `25` 14 | Max: 30 15 | Security/YAMLLoad: 16 | Exclude: 17 | - test/integration/**/_mapdata.rb 18 | 19 | # General settings across all cops in this formula 20 | AllCops: 21 | NewCops: enable 22 | 23 | # Any offenses that should be fixed, e.g. collected via. `rubocop --auto-gen-config` 24 | -------------------------------------------------------------------------------- /.salt-lint: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | exclude_paths: [] 5 | rules: 6 | 203: # Most files should not contain tabs 7 | ignore: | 8 | postfix/files/mapping.j2 9 | skip_list: 10 | # Using `salt-lint` for linting other files as well, such as Jinja macros/templates 11 | - 205 # Use ".sls" as a Salt State file extension 12 | # Skipping `207` and `208` because `210` is sufficient, at least for the time-being 13 | # I.e. Allows 3-digit unquoted codes to still be used, such as `644` and `755` 14 | - 207 # File modes should always be encapsulated in quotation marks 15 | - 208 # File modes should always contain a leading zero 16 | tags: [] 17 | verbosity: 1 18 | -------------------------------------------------------------------------------- /postfix/iptables-input.sls: -------------------------------------------------------------------------------- 1 | postfix-iptables-iptables-chain-present-smtp-input: 2 | iptables.chain_present: 3 | - name: smtp.input 4 | 5 | postfix-iptables-iptables-insert-smtp-iptables-tcp: 6 | iptables.insert: 7 | - name: smtp.iptables.tcp 8 | - table: filter 9 | - position: 1 10 | - chain: smtp.input 11 | - jump: ACCEPT 12 | - match: state 13 | - connstate: NEW,ESTABLISHED 14 | - dport: 25 15 | - proto: tcp 16 | - save: True 17 | 18 | postfix-iptables-iptables-insert-smtp-iptables-filter: 19 | iptables.insert: 20 | - name: smtp.iptables.filter 21 | - table: filter 22 | - position: 1 23 | - chain: INPUT 24 | - jump: smtp.input 25 | - save: True 26 | -------------------------------------------------------------------------------- /test/integration/default/controls/postfix_maps_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | control 'Postfix maps' do 4 | title 'maps have been generated properly' 5 | 6 | describe command('postmap -q example.com /etc/postfix/transport') do 7 | its('stdout') { should eq "10.1.1.1\n" } 8 | its('exit_status') { should eq 0 } 9 | end 10 | 11 | describe command('postmap -q example.com /etc/postfix/tls_policy') do 12 | its('stdout') { should eq "encrypt\n" } 13 | its('exit_status') { should eq 0 } 14 | end 15 | 16 | describe command('postmap -q .example.com /etc/postfix/tls_policy') do 17 | its('stdout') { should eq "encrypt\n" } 18 | its('exit_status') { should eq 0 } 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /test/integration/share/inspec.yml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | name: share 5 | title: InSpec shared resources 6 | maintainer: SaltStack Formulas 7 | license: Apache-2.0 8 | summary: shared resources 9 | supports: 10 | - platform-name: debian 11 | - platform-name: ubuntu 12 | - platform-name: centos 13 | - platform-name: fedora 14 | - platform-name: opensuse 15 | - platform-name: suse 16 | - platform-name: freebsd 17 | - platform-name: openbsd 18 | - platform-name: amazon 19 | - platform-name: oracle 20 | - platform-name: arch 21 | - platform-name: gentoo 22 | - platform-name: almalinux 23 | - platform-name: rocky 24 | - platform-name: mac_os_x 25 | - platform: windows 26 | -------------------------------------------------------------------------------- /postfix/_mapdata/init.sls: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=sls 3 | --- 4 | {#- Get the `tplroot` from `tpldir` #} 5 | {%- set tplroot = tpldir.split("/")[0] %} 6 | {%- from tplroot ~ "/map.jinja" import postfix with context %} 7 | 8 | {%- set _mapdata = { 9 | "values": postfix, 10 | } %} 11 | {%- do salt["log.debug"]("### MAP.JINJA DUMP ###\n" ~ _mapdata | yaml(False)) %} 12 | 13 | {%- set output_dir = "/temp" if grains.os_family == "Windows" else "/tmp" %} 14 | {%- set output_file = output_dir ~ "/salt_mapdata_dump.yaml" %} 15 | 16 | {{ tplroot }}-mapdata-dump: 17 | file.managed: 18 | - name: {{ output_file }} 19 | - source: salt://{{ tplroot }}/_mapdata/_mapdata.jinja 20 | - template: jinja 21 | - context: 22 | map: {{ _mapdata | yaml }} 23 | -------------------------------------------------------------------------------- /test/integration/default/inspec.yml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | name: default 5 | title: postfix formula 6 | maintainer: SaltStack Formulas 7 | license: Apache-2.0 8 | summary: Verify that the postfix formula is setup and configured correctly 9 | depends: 10 | - name: share 11 | path: test/integration/share 12 | supports: 13 | - platform-name: debian 14 | - platform-name: ubuntu 15 | - platform-name: centos 16 | - platform-name: fedora 17 | - platform-name: opensuse 18 | - platform-name: suse 19 | - platform-name: freebsd 20 | - platform-name: openbsd 21 | - platform-name: amazon 22 | - platform-name: oracle 23 | - platform-name: arch 24 | - platform-name: gentoo 25 | - platform-name: almalinux 26 | - platform-name: rocky 27 | - platform-name: mac_os_x 28 | - platform: windows 29 | -------------------------------------------------------------------------------- /test/integration/default/controls/postfix_maps_type_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | control 'Postfix map types' do 4 | title 'maps types are generated properly' 5 | 6 | # CIDR 7 | describe command('postmap -q "192.168.0.0/16" /etc/postfix/check_cidr') do 8 | its('stdout') { should eq "REJECT\n" } 9 | its('exit_status') { should eq 0 } 10 | end 11 | 12 | # PCRE 13 | describe command( 14 | 'postmap -q "/^(?!owner-)(.*)-outgoing@(.*)/" /etc/postfix/check_pcre' 15 | ) do 16 | its('stdout') { should eq "550 Use ${1}@${2} instead\n" } 17 | its('exit_status') { should eq 0 } 18 | end 19 | 20 | # REGEXP 21 | describe command('postmap -q "/[%!@].*[%!@]/" /etc/postfix/check_client_access') do 22 | its('stdout') { should eq "550 Sender-specified routing rejected\n" } 23 | its('exit_status') { should eq 0 } 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /bin/kitchen: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'kitchen' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | require 'pathname' 12 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', 13 | Pathname.new(__FILE__).realpath) 14 | 15 | bundle_binstub = File.expand_path('bundle', __dir__) 16 | 17 | if File.file?(bundle_binstub) 18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ 19 | load(bundle_binstub) 20 | else 21 | abort( 22 | 'Your `bin/bundle` was not generated by Bundler, ' \ 23 | 'so this binstub cannot run. Replace `bin/bundle` by running ' \ 24 | '`bundle binstubs bundler --force`, then run this command again.' 25 | ) 26 | end 27 | end 28 | 29 | require 'rubygems' 30 | require 'bundler/setup' 31 | 32 | load Gem.bin_path('test-kitchen', 'kitchen') 33 | -------------------------------------------------------------------------------- /postfix/files/mapping.j2: -------------------------------------------------------------------------------- 1 | # Managed by config management 2 | {#- Some files (mainly the aliases one) require key and values 3 | to be separated with a colon. For this `colon: True` should 4 | be passed to the template #} 5 | {%- if colon is not defined %} 6 | {%- set colon = False %} 7 | {%- endif %} 8 | {%- macro format_value(key, value) %} 9 | {#- Some settings, like virtual_alias_maps can take multiple values. Handle this case. -#} 10 | {%- if value is iterable and value is not string -%} 11 | {{ key }}{% if colon %}:{% endif %} {{ value|join(", ") }} 12 | {%- else -%} 13 | {{ key }}{% if colon %}:{% endif %} {{ value }} 14 | {%- endif -%} 15 | {%- endmacro %} 16 | 17 | {%- if data is mapping %} 18 | {% for key, value in data.items() %} 19 | {{ format_value(key, value) }} 20 | {%- endfor -%} 21 | {%- else %} 22 | {#- Some settings need order, handle OrderedDict #} 23 | {% for item in data %} 24 | {%- set key, value = item.popitem() %} 25 | {{ format_value(key, value) }} 26 | {%- endfor -%} 27 | {%- endif %} 28 | -------------------------------------------------------------------------------- /postfix/files/virtual_alias_maps.cf: -------------------------------------------------------------------------------- 1 | {%- if 'mysql' in salt['pillar.get']('postfix:config:virtual_alias_maps', '') %} 2 | {%- set config = salt['pillar.get']('postfix:mysql:virtual_alias_maps', {}) -%} 3 | {%- for key,value in salt['pillar.get']('postfix:vmail').items() %} 4 | {{ key }} = {{ value }} 5 | {%- endfor %} 6 | query = SELECT {{ config.select_field|default('destination') }} FROM {{ config.table|default('virtual_aliases') }} WHERE {{ config.where_field|default('email') }}='%s' 7 | {%- else %} 8 | {% set config = salt['pillar.get']('postfix:vmail', {}) -%} 9 | {% macro set_parameter(parameter, default=None) -%} 10 | {% set value = config.get(parameter, default) -%} 11 | {% if value is not none -%} 12 | {{ parameter }} = {{ value }} 13 | {% endif -%} 14 | {% endmacro -%} 15 | 16 | {# Accept arbitrary parameters -#} 17 | {% for parameter in config -%} 18 | {{ set_parameter(parameter) }} 19 | {% endfor -%} 20 | 21 | {{ set_parameter('table', 'alias') }} 22 | {{ set_parameter('select_field', 'goto') }} 23 | {{ set_parameter('where_field', 'address') }} 24 | {%- endif %} 25 | -------------------------------------------------------------------------------- /postfix/files/virtual_mailbox_maps.cf: -------------------------------------------------------------------------------- 1 | {%- if 'mysql' in salt['pillar.get']('postfix:config:virtual_mailbox_maps', '') %} 2 | {%- set config = salt['pillar.get']('postfix:mysql:virtual_mailbox_maps', {}) -%} 3 | {%- for key,value in salt['pillar.get']('postfix:vmail').items() %} 4 | {{ key }} = {{ value }} 5 | {%- endfor %} 6 | query = SELECT {{ config.select_field|default('1') }} FROM {{ config.table|default('virtual_users') }} WHERE {{ config.where_field|default('email') }}='%s' 7 | {%- else %} 8 | {% set config = salt['pillar.get']('postfix:vmail', {}) -%} 9 | {% macro set_parameter(parameter, default=None) -%} 10 | {% set value = config.get(parameter, default) -%} 11 | {% if value is not none -%} 12 | {{ parameter }} = {{ value }} 13 | {% endif -%} 14 | {% endmacro -%} 15 | 16 | {# Accept arbitrary parameters -#} 17 | {% for parameter in config -%} 18 | {{ set_parameter(parameter) }} 19 | {% endfor -%} 20 | 21 | {{ set_parameter('table', 'mailbox') }} 22 | {{ set_parameter('select_field', 'maildir') }} 23 | {{ set_parameter('where_field', 'username') }} 24 | {%- endif %} 25 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source ENV.fetch('PROXY_RUBYGEMSORG', 'https://rubygems.org') 4 | 5 | # Install the `inspec` gem using `git` because versions after `4.22.22` 6 | # suppress diff output; this version fixes this for our uses. 7 | # rubocop:disable Layout/LineLength 8 | gem 'inspec', git: 'https://gitlab.com/saltstack-formulas/infrastructure/inspec', branch: 'ssf' 9 | # rubocop:enable Layout/LineLength 10 | 11 | # Install the `kitchen-docker` gem using `git` in order to gain a performance 12 | # improvement: avoid package installations which are already covered by the 13 | # `salt-image-builder` (i.e. the pre-salted images that we're using) 14 | # rubocop:disable Layout/LineLength 15 | gem 'kitchen-docker', git: 'https://github.com/test-kitchen/kitchen-docker', ref: '511e4ad36856b9e2eccceb56603586e6cebd296a' 16 | # rubocop:enable Layout/LineLength 17 | 18 | gem 'kitchen-inspec', '3.0.0' 19 | gem 'kitchen-salt', '0.7.2' 20 | 21 | # Avoid the error 'pkeys are immutable on OpenSSL 3.0' 22 | gem 'net-ssh', '>= 7.0.0' 23 | 24 | gem 'test-kitchen', '3.9.0' 25 | -------------------------------------------------------------------------------- /postfix/files/virtual_mailbox_domains.cf: -------------------------------------------------------------------------------- 1 | {%- if 'mysql' in salt['pillar.get']('postfix:config:virtual_mailbox_domains', '') %} 2 | {%- set config = salt['pillar.get']('postfix:mysql:virtual_mailbox_domains', {}) -%} 3 | {%- for key,value in salt['pillar.get']('postfix:vmail').items() %} 4 | {{ key }} = {{ value }} 5 | {%- endfor %} 6 | query = SELECT {{ config.select_field|default('1') }} FROM {{ config.table|default('virtual_domains') }} WHERE {{ config.where_field|default('name') }}='%s' 7 | {%- else %} 8 | {% set config = salt['pillar.get']('postfix:vmail', {}) -%} 9 | {% macro set_parameter(parameter, default=None) -%} 10 | {% set value = config.get(parameter, default) -%} 11 | {% if value is not none -%} 12 | {{ parameter }} = {{ value }} 13 | {% endif -%} 14 | {% endmacro -%} 15 | 16 | {# Accept arbitrary parameters -#} 17 | {% for parameter in config -%} 18 | {{ set_parameter(parameter) }} 19 | {% endfor -%} 20 | 21 | {{ set_parameter('table', 'domain') }} 22 | {{ set_parameter('select_field', 'domain') }} 23 | {{ set_parameter('where_field', 'domain') }} 24 | {%- endif %} 25 | -------------------------------------------------------------------------------- /postfix/osfamilymap.yaml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | Arch: 5 | policyd_spf_pkg: python-postfix-policyd-spf 6 | daemon_directory: /usr/lib/postfix/bin 7 | 8 | Debian: 9 | policyd_spf_pkg: postfix-policyd-spf-python 10 | pcre_pkg: postfix-pcre 11 | mysql_pkg: postfix-mysql 12 | daemon_directory: /usr/lib/postfix/sbin 13 | 14 | FreeBSD: 15 | policyd_spf_pkg: py27-postfix-policyd-spf-python 16 | aliases_file: /etc/mail/aliases 17 | xbin_prefix: /usr/local 18 | config_path: /usr/local/etc/postfix 19 | root_grp: wheel 20 | daemon_directory: /usr/local/libexec/postfix 21 | dovecot_deliver: /usr/local/libexec/dovecot/deliver 22 | 23 | Gentoo: 24 | package: mail-mta/postfix 25 | policyd_spf_pkg: mail-filter/pypolicyd-spf 26 | postsrsd_pkg: mail-filter/postsrsd 27 | postgrey_pkg: mail-filter/postgrey 28 | aliases_file: /etc/mail/aliases 29 | dovecot_deliver: /usr/libexec/dovecot/deliver 30 | 31 | RedHat: 32 | policyd_spf_pkg: pypolicyd-spf 33 | 34 | Suse: 35 | setgid_group: maildrop 36 | daemon_directory: /usr/lib/postfix/bin 37 | -------------------------------------------------------------------------------- /test/integration/default/README.md: -------------------------------------------------------------------------------- 1 | # InSpec Profile: `default` 2 | 3 | This shows the implementation of the `default` InSpec [profile](https://github.com/inspec/inspec/blob/master/docs/profiles.md). 4 | 5 | ## Verify a profile 6 | 7 | InSpec ships with built-in features to verify a profile structure. 8 | 9 | ```bash 10 | $ inspec check default 11 | Summary 12 | ------- 13 | Location: default 14 | Profile: profile 15 | Controls: 4 16 | Timestamp: 2019-06-24T23:09:01+00:00 17 | Valid: true 18 | 19 | Errors 20 | ------ 21 | 22 | Warnings 23 | -------- 24 | ``` 25 | 26 | ## Execute a profile 27 | 28 | To run all **supported** controls on a local machine use `inspec exec /path/to/profile`. 29 | 30 | ```bash 31 | $ inspec exec default 32 | .. 33 | 34 | Finished in 0.0025 seconds (files took 0.12449 seconds to load) 35 | 8 examples, 0 failures 36 | ``` 37 | 38 | ## Execute a specific control from a profile 39 | 40 | To run one control from the profile use `inspec exec /path/to/profile --controls name`. 41 | 42 | ```bash 43 | $ inspec exec default --controls package 44 | . 45 | 46 | Finished in 0.0025 seconds (files took 0.12449 seconds to load) 47 | 1 examples, 0 failures 48 | ``` 49 | 50 | See an [example control here](https://github.com/inspec/inspec/blob/master/examples/profile/controls/example.rb). 51 | -------------------------------------------------------------------------------- /pre-commit_semantic-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ############################################################################### 4 | # (A) Update `FORMULA` with `${nextRelease.version}` 5 | ############################################################################### 6 | 7 | sed -i -e "s_^\(version:\).*_\1 ${1}_" FORMULA 8 | 9 | 10 | ############################################################################### 11 | # (B) Update `AUTHORS.md` 12 | ############################################################################### 13 | 14 | maintainer contributor \ 15 | --ignore-contributors dependabot[bot],renovate[bot],semantic-release-bot 16 | 17 | ############################################################################### 18 | # (C) Use `m2r` to convert automatically produced `.md` docs to `.rst` 19 | ############################################################################### 20 | 21 | # Copy and then convert the `.md` docs 22 | cp ./*.md docs/ 23 | cd docs/ || exit 24 | m2r --overwrite ./*.md 25 | 26 | # Change excess `H1` headings to `H2` in converted `CHANGELOG.rst` 27 | sed -i -e '/^=.*$/s/=/-/g' CHANGELOG.rst 28 | sed -i -e '1,4s/-/=/g' CHANGELOG.rst 29 | 30 | # Use for debugging output, when required 31 | # cat AUTHORS.rst 32 | # cat CHANGELOG.rst 33 | 34 | # Return back to the main directory 35 | cd .. 36 | -------------------------------------------------------------------------------- /test/integration/share/README.md: -------------------------------------------------------------------------------- 1 | # InSpec Profile: `share` 2 | 3 | This shows the implementation of the `share` InSpec [profile](https://github.com/inspec/inspec/blob/master/docs/profiles.md). 4 | 5 | Its goal is to share the libraries between all profiles. 6 | 7 | ## Libraries 8 | 9 | ### `system` 10 | 11 | The `system` library provides easy access to system dependent information: 12 | 13 | - `system.platform`: based on `inspec.platform`, modify to values that are more consistent from a SaltStack perspective 14 | - `system.platform[:family]` provide a family name for Arch and Gentoo 15 | - `system.platform[:name]` append `linux` to both `amazon` and `oracle`; ensure Windows platforms are resolved as simply `windows` 16 | - `system.platform[:release]` tweak Arch, Amazon Linux, Gentoo, openSUSE and Windows: 17 | - `Arch` is always `base-latest` 18 | - `Amazon Linux` release `2018` is resolved as `1` 19 | - `Gentoo` release is trimmed to its major version number and then the init system is appended (i.e. `sysv` or `sysd`) 20 | - `openSUSE` is resolved as `tumbleweed` if the `platform[:release]` is in date format 21 | - `Windows` uses the widely-used release number (e.g. `8.1` or `2019-server`) in place of the actual system release version 22 | - `system.platform[:finger]` is the concatenation of the name and the major release number (except for Ubuntu, which gives `ubuntu-20.04` for example) 23 | -------------------------------------------------------------------------------- /release.config.js: -------------------------------------------------------------------------------- 1 | // Commit types appear in the changelog in this order 2 | const commitTypes = [ 3 | { type: 'feat', section: 'Features' }, 4 | { type: 'fix', section: 'Bug Fixes' }, 5 | { type: 'perf', section: 'Performance Improvements' }, 6 | { type: 'revert', section: 'Reversions' }, 7 | { type: 'refactor', section: 'Code Refactoring' }, 8 | { type: 'docs', section: 'Documentation' }, 9 | { type: 'test', section: 'Testing' }, 10 | { type: 'style', section: 'Style Changes' }, 11 | { type: 'ci', section: 'Continuous Integration' }, 12 | { type: 'build', section: 'Build System' }, 13 | { type: 'chore', section: 'Maintenance' } 14 | ] 15 | 16 | // Default rules can be found in `github.com/semantic-release/commit-analyzer/lib/default-release-rules.js` 17 | // that cover feat, fix, perf and breaking. 18 | // Commit types defined above but without release rules do not trigger a release 19 | // but will be incorporated into the next release. 20 | // NOTE: Any changes to commit types or release rules must be reflected in `CONTRIBUTING.rst`. 21 | const releaseRules = [ 22 | { type: 'docs', release: 'patch' }, 23 | { type: 'refactor', release: 'patch' }, 24 | { type: 'revert', release: 'patch' }, 25 | { type: 'style', release: 'patch' }, 26 | { type: 'test', release: 'patch' } 27 | ] 28 | 29 | const config = { 30 | // TODO: remove this when we no longer process releases on GitLab CI 31 | repositoryUrl: 'https://github.com/saltstack-formulas/postfix-formula', 32 | plugins: [ 33 | ['@semantic-release/commit-analyzer', { releaseRules }], 34 | '@semantic-release/release-notes-generator', 35 | ['@semantic-release/changelog', { 36 | changelogFile: 'CHANGELOG.md', 37 | changelogTitle: '# Changelog' 38 | }], 39 | ['@semantic-release/exec', { 40 | // eslint-disable-next-line no-template-curly-in-string 41 | prepareCmd: 'sh ./pre-commit_semantic-release.sh ${nextRelease.version}' 42 | }], 43 | ['@semantic-release/git', { 44 | assets: ['*.md', 'docs/*.rst', 'FORMULA'] 45 | }], 46 | '@semantic-release/github' 47 | ], 48 | preset: 'conventionalcommits', 49 | presetConfig: { 50 | types: commitTypes 51 | } 52 | } 53 | 54 | module.exports = config 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a packager 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .kitchen 49 | .kitchen.local.yml 50 | kitchen.local.yml 51 | junit-*.xml 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | 61 | # Flask stuff: 62 | instance/ 63 | .webassets-cache 64 | 65 | # Scrapy stuff: 66 | .scrapy 67 | 68 | # Sphinx documentation 69 | docs/_build/ 70 | 71 | # PyBuilder 72 | target/ 73 | 74 | # Jupyter Notebook 75 | .ipynb_checkpoints 76 | 77 | # pyenv 78 | .python-version 79 | 80 | # celery beat schedule file 81 | celerybeat-schedule 82 | 83 | # SageMath parsed files 84 | *.sage.py 85 | 86 | # dotenv 87 | .env 88 | 89 | # virtualenv 90 | .venv 91 | venv/ 92 | ENV/ 93 | 94 | # visual studio 95 | .vs/ 96 | 97 | # Spyder project settings 98 | .spyderproject 99 | .spyproject 100 | 101 | # Rope project settings 102 | .ropeproject 103 | 104 | # mkdocs documentation 105 | /site 106 | 107 | # mypy 108 | .mypy_cache/ 109 | 110 | # Bundler 111 | .bundle/ 112 | 113 | # copied `.md` files used for conversion to `.rst` using `m2r` 114 | docs/*.md 115 | 116 | # Vim 117 | *.sw? 118 | 119 | ## Collected when centralising formulas (check and sort) 120 | # `collectd-formula` 121 | .pytest_cache/ 122 | /.idea/ 123 | Dockerfile.*_* 124 | ignore/ 125 | tmp/ 126 | 127 | # `salt-formula` -- Vagrant Specific files 128 | .vagrant 129 | top.sls 130 | !test/salt/pillar/top.sls 131 | 132 | # `suricata-formula` -- Platform binaries 133 | *.rpm 134 | *.deb 135 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners 2 | 3 | # SECTION: Owner(s) for everything in the repo, unless a later match takes precedence 4 | # FILE PATTERN OWNER(S) 5 | * @fzipi 6 | 7 | # SECTION: Owner(s) for specific directories 8 | # FILE PATTERN OWNER(S) 9 | 10 | # SECTION: Owner(s) for files/directories related to `semantic-release` 11 | # FILE PATTERN OWNER(S) 12 | /.github/workflows/ @saltstack-formulas/ssf 13 | /bin/install-hooks @saltstack-formulas/ssf 14 | /bin/kitchen @saltstack-formulas/ssf 15 | /docs/AUTHORS.rst @saltstack-formulas/ssf 16 | /docs/CHANGELOG.rst @saltstack-formulas/ssf 17 | /docs/TOFS_pattern.rst @saltstack-formulas/ssf 18 | /*/_mapdata/ @saltstack-formulas/ssf 19 | /*/libsaltcli.jinja @saltstack-formulas/ssf 20 | /*/libtofs.jinja @saltstack-formulas/ssf 21 | /test/integration/**/_mapdata.rb @saltstack-formulas/ssf 22 | /test/integration/**/libraries/system.rb @saltstack-formulas/ssf 23 | /test/integration/**/inspec.yml @saltstack-formulas/ssf 24 | /test/integration/**/README.md @saltstack-formulas/ssf 25 | /test/salt/pillar/top.sls @saltstack-formulas/ssf 26 | /.gitignore @saltstack-formulas/ssf 27 | /.cirrus.yml @saltstack-formulas/ssf 28 | /.gitlab-ci.yml @saltstack-formulas/ssf 29 | /.pre-commit-config.yaml @saltstack-formulas/ssf 30 | /.rstcheck.cfg @saltstack-formulas/ssf 31 | /.rubocop.yml @saltstack-formulas/ssf 32 | /.salt-lint @saltstack-formulas/ssf 33 | /.travis.yml @saltstack-formulas/ssf 34 | /.yamllint @saltstack-formulas/ssf 35 | /AUTHORS.md @saltstack-formulas/ssf 36 | /CHANGELOG.md @saltstack-formulas/ssf 37 | /CODEOWNERS @saltstack-formulas/ssf 38 | /commitlint.config.js @saltstack-formulas/ssf 39 | /FORMULA @saltstack-formulas/ssf 40 | /Gemfile @saltstack-formulas/ssf 41 | /Gemfile.lock @saltstack-formulas/ssf 42 | /kitchen.yml @saltstack-formulas/ssf 43 | /kitchen.vagrant.yml @saltstack-formulas/ssf 44 | /kitchen.windows.yml @saltstack-formulas/ssf 45 | /pre-commit_semantic-release.sh @saltstack-formulas/ssf 46 | /release-rules.js @saltstack-formulas/ssf 47 | /release.config.js @saltstack-formulas/ssf 48 | 49 | # SECTION: Owner(s) for specific files 50 | # FILE PATTERN OWNER(S) 51 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Test & release 3 | 4 | 'on': 5 | - pull_request 6 | - push 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.ref }} 10 | cancel-in-progress: ${{ github.ref != format('refs/heads/{0}', 11 | github.event.repository.default_branch) }} 12 | 13 | jobs: 14 | should-run: 15 | name: Prep / Should run 16 | runs-on: ubuntu-latest 17 | timeout-minutes: 5 18 | outputs: 19 | should-run: ${{ steps.action.outputs.should-run }} 20 | steps: 21 | - id: action 22 | # yamllint disable-line rule:line-length 23 | uses: techneg-it/should-workflow-run@eff19348eb884f57e05bc6f05ae48ece3af14714 # v1.0.1 24 | pre-commit: 25 | name: Lint / `pre-commit` 26 | needs: should-run 27 | if: fromJSON(needs.should-run.outputs.should-run) 28 | container: techneg/ci-pre-commit:v2.5.19@sha256:64cb1f774a3d6abdd498f6be4b3dbe261f821e1dd088c00c23504f39d0c1cf03 29 | runs-on: ubuntu-latest 30 | timeout-minutes: 10 31 | steps: 32 | - run: | # Needed because of bug #2031 in `actions/checkout` 33 | git config --global --add safe.directory "$GITHUB_WORKSPACE" 34 | - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 35 | with: 36 | fetch-depth: 0 37 | fetch-tags: true 38 | filter: tree:0 39 | - name: Export `CI_CACHE_ID` from container 40 | run: echo "CI_CACHE_ID=$(cat /.ci_cache_id)" >> $GITHUB_ENV 41 | - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 42 | with: 43 | path: ~/.cache/pre-commit 44 | key: "${{ env.CI_CACHE_ID }}|\ 45 | ${{ hashFiles('.pre-commit-config.yaml') }}" 46 | restore-keys: | 47 | ${{ env.CI_CACHE_ID }}| 48 | - name: Build cache 49 | run: | 50 | pre-commit gc 51 | echo "Installing hook environments..." 52 | time -f "Hook installation took %E" pre-commit install-hooks 53 | - name: Run `pre-commit` 54 | run: | 55 | pre-commit run --all-files --color always --verbose 56 | pre-commit run --color always --hook-stage manual --verbose commitlint-ci 57 | results: 58 | name: Release / Collect results 59 | permissions: 60 | contents: write 61 | issues: write 62 | pull-requests: write 63 | checks: read 64 | container: techneg/ci-semantic-release:v1.2.17@sha256:4db8d4b3b1451131ce77bd857254de2f3c5579172955b2a6a2d4ec4326789196 65 | runs-on: ubuntu-latest 66 | timeout-minutes: 15 67 | steps: 68 | - run: | # Needed due to bug actions/checkout#2031 69 | git config --global --add safe.directory "$GITHUB_WORKSPACE" 70 | - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 71 | # yamllint disable-line rule:line-length 72 | - uses: poseidon/wait-for-status-checks@899c768d191b56eef585c18f8558da19e1f3e707 # v0.6.0 73 | with: 74 | ignore: > 75 | Release / Collect results 76 | ignore_pattern: ^GitLab CI 77 | token: ${{ secrets.GITHUB_TOKEN }} 78 | - name: Run `semantic-release` 79 | env: 80 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 81 | MAINTAINER_TOKEN: ${{ secrets.GITHUB_TOKEN }} 82 | run: | 83 | semantic-release --dry-run 84 | - run: echo "::notice ::Workflow success!" 85 | -------------------------------------------------------------------------------- /postfix/init.sls: -------------------------------------------------------------------------------- 1 | {% from "postfix/map.jinja" import postfix with context %} 2 | 3 | {%- if grains.os_family == "Suse" %} 4 | # The existence of this file prevents the system to 5 | # overwrite files from salt when installing. 6 | postfix-init-file-managed-postfix.configured: 7 | file.managed: 8 | - name: /var/adm/postfix.configured 9 | - contents: '' 10 | - mode: '0644' 11 | - user: 'root' 12 | - group: 'root' 13 | - require_in: 14 | - pkg: postfix-init-pkg-installed-postfix 15 | {%- endif %} 16 | 17 | postfix-init-pkg-installed-postfix: 18 | pkg.installed: 19 | - name: {{ postfix.package }} 20 | {%- if grains.os_family == "FreeBSD" %} 21 | - force: True 22 | - batch: True 23 | {%- endif %} 24 | - watch_in: 25 | - service: postfix-init-service-running-postfix 26 | 27 | postfix-init-service-running-postfix: 28 | service.running: 29 | - name: postfix 30 | - enable: {{ salt['pillar.get']('postfix:enable_service', True) }} 31 | - reload: {{ salt['pillar.get']('postfix:reload_service', True) }} 32 | - require: 33 | - pkg: postfix-init-pkg-installed-postfix 34 | - watch: 35 | - pkg: postfix-init-pkg-installed-postfix 36 | 37 | {%- if salt['pillar.get']('postfix:reload_service', True) %} 38 | # Restart postfix if the package was changed. 39 | # This also provides an ID to be used in a watch_in statement. 40 | postfix-init-service-running-postfix-restart: 41 | service.running: 42 | - name: postfix 43 | - watch: 44 | - pkg: postfix-init-pkg-installed-postfix 45 | {%- endif %} 46 | 47 | # manage /etc/aliases if data found in pillar 48 | {% if 'aliases' in pillar.get('postfix', '') %} 49 | {% if salt['pillar.get']('postfix:aliases:use_file', true) == true %} 50 | {%- set need_newaliases = False %} 51 | {%- set file_path = postfix.aliases_file %} 52 | {%- if ':' in file_path %} 53 | {%- set file_type, file_path = postfix.aliases_file.split(':') %} 54 | {%- else %} 55 | {%- set file_type = postfix.default_database_type %} 56 | {%- endif %} 57 | {%- if file_type in ("btree", "cdb", "dbm", "hash", "sdbm") %} 58 | {%- set need_newaliases = True %} 59 | {%- endif %} 60 | postfix-init-file-managed-alias-database: 61 | file.managed: 62 | - name: {{ file_path }} 63 | {% if salt['pillar.get']('postfix:aliases:content', None) is string %} 64 | - contents_pillar: postfix:aliases:content 65 | {% else %} 66 | - source: salt://postfix/files/mapping.j2 67 | {% endif %} 68 | - user: root 69 | - group: {{ postfix.root_grp }} 70 | - mode: '0644' 71 | - template: jinja 72 | - context: 73 | data: {{ salt['pillar.get']('postfix:aliases:present') }} 74 | colon: True 75 | - require: 76 | - pkg: postfix-init-pkg-installed-postfix 77 | 78 | {%- if need_newaliases %} 79 | postfix-init-cmd-run-new-aliases: 80 | cmd.run: 81 | - name: newaliases 82 | - cwd: / 83 | - onchanges: 84 | - file: {{ file_path }} 85 | {%- endif %} 86 | {% else %} 87 | {%- for user, target in salt['pillar.get']('postfix:aliases:present', {}).items() %} 88 | postfix-init-alias-present-{{ user }}: 89 | alias.present: 90 | - name: {{ user }} 91 | - target: {{ target }} 92 | {%- endfor %} 93 | {%- for user in salt['pillar.get']('postfix:aliases:absent', {}) %} 94 | postfix-init-alias-absent-{{ user }}: 95 | alias.absent: 96 | - name: {{ user }} 97 | {%- endfor %} 98 | {% endif %} 99 | {% endif %} 100 | -------------------------------------------------------------------------------- /docs/README.rst: -------------------------------------------------------------------------------- 1 | .. _readme: 2 | 3 | postfix-formula 4 | =============== 5 | 6 | |img_travis| |img_sr| 7 | 8 | .. |img_travis| image:: https://travis-ci.com/saltstack-formulas/postfix-formula.svg?branch=master 9 | :alt: Travis CI Build Status 10 | :scale: 100% 11 | :target: https://travis-ci.com/saltstack-formulas/postfix-formula 12 | .. |img_sr| image:: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg 13 | :alt: Semantic Release 14 | :scale: 100% 15 | :target: https://github.com/semantic-release/semantic-release 16 | 17 | A SaltStack formula to install and configure Postfix mail server. 18 | 19 | .. contents:: **Table of Contents** 20 | 21 | General notes 22 | ------------- 23 | 24 | See the full `SaltStack Formulas installation and usage instructions 25 | `_. 26 | 27 | If you are interested in writing or contributing to formulas, please pay attention to the `Writing Formula Section 28 | `_. 29 | 30 | If you want to use this formula, please pay attention to the ``FORMULA`` file and/or ``git tag``, 31 | which contains the currently released version. This formula is versioned according to `Semantic Versioning `_. 32 | 33 | See `Formula Versioning Section `_ for more details. 34 | 35 | Contributing to this repo 36 | ------------------------- 37 | 38 | **Commit message formatting is significant!!** 39 | 40 | Please see `How to contribute `_ for more details. 41 | 42 | Available states 43 | ---------------- 44 | 45 | .. contents:: 46 | :local: 47 | 48 | ``postfix`` 49 | ^^^^^^^^^^^ 50 | 51 | Installs and starts postfix SMTP server 52 | 53 | ``postfix.config`` 54 | ^^^^^^^^^^^^^^^^^^ 55 | 56 | Manages postfix main.cf and optionally the master.cf configuration file. Generates mappings. 57 | 58 | ``postfix.policyd-spf`` 59 | ^^^^^^^^^^^^^^^^^^^^^^^ 60 | 61 | Installs and configures policyd-spf 62 | 63 | ``postfix.postgrey`` 64 | ^^^^^^^^^^^^^^^^^^^^ 65 | 66 | Installs and starts Postgrey service 67 | 68 | ``postfix.mysql`` 69 | ^^^^^^^^^^^^^^^^^ 70 | 71 | Installs postfix mysql package ( Debian only) 72 | 73 | ``postfix.pcre`` 74 | ^^^^^^^^^^^^^^^^ 75 | 76 | Installs postfix pcre package ( Debian only) 77 | 78 | ``postfix.postsrsd`` 79 | ^^^^^^^^^^^^^^^^^^^^ 80 | 81 | Installs postfix postsrsd package 82 | 83 | 84 | Testing 85 | ------- 86 | 87 | Linux testing is done with ``kitchen-salt``. 88 | 89 | Requirements 90 | ^^^^^^^^^^^^ 91 | 92 | * Ruby 93 | * Docker 94 | 95 | .. code-block:: bash 96 | 97 | $ gem install bundler 98 | $ bundle install 99 | $ bin/kitchen test [platform] 100 | 101 | Where ``[platform]`` is the platform name defined in ``kitchen.yml``, 102 | e.g. ``debian-9-2019-2-py3``. 103 | 104 | ``bin/kitchen converge`` 105 | ^^^^^^^^^^^^^^^^^^^^^^^^ 106 | 107 | Creates the docker instance and runs the main state(s), ready for testing. 108 | 109 | ``bin/kitchen verify`` 110 | ^^^^^^^^^^^^^^^^^^^^^^ 111 | 112 | Runs the ``inspec`` tests on the actual instance. 113 | 114 | ``bin/kitchen destroy`` 115 | ^^^^^^^^^^^^^^^^^^^^^^^ 116 | 117 | Removes the docker instance. 118 | 119 | ``bin/kitchen test`` 120 | ^^^^^^^^^^^^^^^^^^^^ 121 | 122 | Runs all of the stages above in one go: i.e. ``destroy`` + ``converge`` + ``verify`` + ``destroy``. 123 | 124 | ``bin/kitchen login`` 125 | ^^^^^^^^^^^^^^^^^^^^^ 126 | 127 | Gives you SSH access to the instance for manual testing. 128 | 129 | -------------------------------------------------------------------------------- /test/integration/default/controls/postfix_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | control 'Postfix config' do 4 | title 'config is generated correctly' 5 | 6 | describe postfix_conf do 7 | its('biff') { should cmp 'no' } 8 | its('compatibility_level') { should cmp '2' } 9 | its('append_dot_mydomain') { should cmp 'no' } 10 | its('readme_directory') { should cmp 'no' } 11 | its('smtpd_sasl_auth_enable') { should cmp 'yes' } 12 | its('smtpd_sasl_path') { should cmp '/var/run/dovecot/auth-client' } 13 | its('smtpd_sasl_type') { should cmp 'dovecot' } 14 | its('smtpd_sasl_security_options') { should cmp 'noanonymous' } 15 | its('smtpd_sasl_tls_security_options') { should cmp '$smtpd_sasl_security_options' } 16 | its('smtpd_tls_auth_only') { should cmp 'yes' } 17 | its('smtpd_use_tls') { should cmp 'yes' } 18 | its('smtpd_tls_loglevel') { should cmp '1' } 19 | its('smtpd_tls_security_level') { should cmp 'may' } 20 | its('smtp_tls_CApath') { should cmp '/etc/ssl/certs' } 21 | its('smtpd_tls_cert_file') { should cmp '/etc/postfix/ssl/server-cert.crt' } 22 | its('smtpd_tls_key_file') { should cmp '/etc/postfix/ssl/server-cert.key' } 23 | its('smtpd_tls_session_cache_database') do 24 | should cmp 'btree:${data_directory}/smtpd_scache' 25 | end 26 | its('smtpd_tls_mandatory_ciphers') { should cmp 'high' } 27 | its('tls_preempt_cipherlist') { should cmp 'yes' } 28 | its('smtp_tls_loglevel') { should cmp '1' } 29 | its('smtp_tls_security_level') { should cmp 'may' } 30 | its('smtp_tls_session_cache_database') do 31 | should cmp 'btree:${data_directory}/smtp_scache' 32 | end 33 | its('myhostname') { should cmp 'localhost' } 34 | its('alias_maps') { should cmp 'hash:/etc/aliases' } 35 | its('alias_database') { should cmp 'hash:/etc/aliases' } 36 | its('mydestination') { should cmp 'localhost, localhost.localdomain' } 37 | its('relayhost') { should cmp '' } 38 | its('mynetworks') { should cmp '127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128' } 39 | its('mailbox_size_limit') { should cmp '0' } 40 | its('recipient_delimiter') { should cmp '+' } 41 | its('inet_interfaces') { should cmp '127.0.0.1' } 42 | its('inet_protocols') { should cmp 'all' } 43 | its('message_size_limit') { should cmp '41943040' } 44 | its('smtpd_recipient_restrictions') do 45 | should cmp 'permit_mynetworks, ' \ 46 | 'permit_sasl_authenticated, ' \ 47 | 'reject_unauth_destination' 48 | end 49 | its('transport_maps') { should cmp 'hash:/etc/postfix/transport' } 50 | its('smtp_tls_policy_maps') { should cmp 'hash:/etc/postfix/tls_policy' } 51 | its('smtp_sasl_password_maps') { should cmp 'hash:/etc/postfix/sasl_passwd' } 52 | its('sender_canonical_maps') { should cmp 'hash:/etc/postfix/sender_canonical' } 53 | its('relay_recipient_maps') { should cmp 'hash:/etc/postfix/relay_domains' } 54 | its('virtual_alias_maps') { should cmp 'hash:/etc/postfix/virtual' } 55 | its('local_transport') { should cmp 'virtual' } 56 | its('local_recipient_maps') { should cmp '$virtual_mailbox_maps' } 57 | its('smtpd_relay_restrictions') do 58 | should cmp 'permit_mynetworks, ' \ 59 | 'permit_sasl_authenticated, ' \ 60 | 'reject_unauth_destination' 61 | end 62 | its('smtpd_sasl_local_domain') { should cmp '$mydomain' } 63 | its('smtpd_tls_session_cache_timeout') { should cmp '3600s' } 64 | its('relay_domains') { should cmp '$mydestination' } 65 | its('smtp_use_tls') { should cmp 'yes' } 66 | its('smtp_tls_cert_file') do 67 | should cmp '/etc/postfix/ssl/example.com-relay-client-cert.crt' 68 | end 69 | its('smtp_tls_key_file') do 70 | should cmp '/etc/postfix/ssl/example.com-relay-client-cert.key' 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /test/integration/share/libraries/system.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # system.rb -- InSpec resources for system values 4 | # Author: Daniel Dehennin 5 | # Copyright (C) 2020 Daniel Dehennin 6 | 7 | # rubocop:disable Metrics/ClassLength 8 | class SystemResource < Inspec.resource(1) 9 | name 'system' 10 | 11 | attr_reader :platform 12 | 13 | def initialize 14 | super 15 | @platform = build_platform 16 | end 17 | 18 | private 19 | 20 | def build_platform 21 | { 22 | family: build_platform_family, 23 | name: build_platform_name, 24 | release: build_platform_release, 25 | finger: build_platform_finger, 26 | codename: build_platform_codename 27 | } 28 | end 29 | 30 | def build_platform_family 31 | case inspec.platform[:name] 32 | when 'arch', 'gentoo' 33 | inspec.platform[:name] 34 | else 35 | inspec.platform[:family] 36 | end 37 | end 38 | 39 | def build_platform_name 40 | case inspec.platform[:name] 41 | when 'amazon', 'oracle', 'rocky' 42 | "#{inspec.platform[:name]}linux" 43 | when /^windows_/ 44 | inspec.platform[:family] 45 | else 46 | inspec.platform[:name] 47 | end 48 | end 49 | 50 | # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity 51 | def build_platform_release 52 | case inspec.platform[:name] 53 | when 'amazon' 54 | # `2018` relase is named `1` in `kitchen.yml` 55 | inspec.platform[:release].gsub(/2018.*/, '1') 56 | when 'arch' 57 | 'base-latest' 58 | when 'gentoo' 59 | "#{inspec.platform[:release].split('.')[0]}-#{derive_gentoo_init_system}" 60 | when 'mac_os_x' 61 | inspec.command('sw_vers -productVersion').stdout.to_s 62 | when 'opensuse' 63 | # rubocop:disable Style/NumericLiterals,Layout/LineLength 64 | inspec.platform[:release].to_i > 20210101 ? 'tumbleweed' : inspec.platform[:release] 65 | # rubocop:enable Style/NumericLiterals,Layout/LineLength 66 | when 'windows_8.1_pro' 67 | '8.1' 68 | when 'windows_server_2022_datacenter' 69 | '2022-server' 70 | when 'windows_server_2019_datacenter' 71 | '2019-server' 72 | when 'windows_server_2016_datacenter' 73 | '2016-server' 74 | else 75 | inspec.platform[:release] 76 | end 77 | end 78 | # rubocop:enable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity 79 | 80 | def derive_gentoo_init_system 81 | inspec.command('systemctl').exist? ? 'sysd' : 'sysv' 82 | end 83 | 84 | def build_platform_finger 85 | "#{build_platform_name}-#{build_finger_release}" 86 | end 87 | 88 | def build_finger_release 89 | case inspec.platform[:name] 90 | when 'ubuntu' 91 | build_platform_release.split('.').slice(0, 2).join('.') 92 | else 93 | build_platform_release.split('.')[0] 94 | end 95 | end 96 | 97 | # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity 98 | def build_platform_codename 99 | case build_platform_finger 100 | when 'ubuntu-22.04' 101 | 'jammy' 102 | when 'ubuntu-20.04' 103 | 'focal' 104 | when 'ubuntu-18.04' 105 | 'bionic' 106 | when 'debian-11' 107 | 'bullseye' 108 | when 'debian-10' 109 | 'buster' 110 | when 'debian-9' 111 | 'stretch' 112 | when 'almalinux-8' 113 | "AlmaLinux #{build_platform_release} (Arctic Sphynx)" 114 | when 'amazonlinux-2' 115 | 'Amazon Linux 2' 116 | when 'arch-base-latest' 117 | 'Arch Linux' 118 | when 'centos-7' 119 | 'CentOS Linux 7 (Core)' 120 | when 'centos-8' 121 | 'CentOS Stream 8' 122 | when 'opensuse-tumbleweed' 123 | 'openSUSE Tumbleweed' 124 | when 'opensuse-15' 125 | "openSUSE Leap #{build_platform_release}" 126 | when 'oraclelinux-8', 'oraclelinux-7' 127 | "Oracle Linux Server #{build_platform_release}" 128 | when 'gentoo-2-sysd', 'gentoo-2-sysv' 129 | 'Gentoo/Linux' 130 | when 'rockylinux-8' 131 | "Rocky Linux #{build_platform_release} (Green Obsidian)" 132 | else 133 | '' 134 | end 135 | end 136 | # rubocop:enable Metrics/MethodLength,Metrics/CyclomaticComplexity 137 | end 138 | # rubocop:enable Metrics/ClassLength 139 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | # See https://pre-commit.com for more information 5 | # See https://pre-commit.com/hooks.html for more hooks 6 | ci: 7 | autofix_commit_msg: | 8 | ci(pre-commit.ci): apply auto fixes from pre-commit.com hooks 9 | 10 | For more information, see https://pre-commit.ci 11 | autofix_prs: true 12 | autoupdate_branch: '' 13 | autoupdate_commit_msg: | 14 | ci(pre-commit.ci): perform `pre-commit` autoupdate 15 | autoupdate_schedule: quarterly 16 | skip: [] 17 | submodules: false 18 | default_stages: [pre-commit] 19 | repos: 20 | - repo: https://github.com/pre-commit/pre-commit-hooks 21 | rev: v6.0.0 22 | hooks: 23 | - id: check-merge-conflict 24 | name: Check for Git merge conflicts 25 | args: [--assume-in-merge] 26 | exclude: ^docs/AUTHORS.rst$ 27 | - repo: https://github.com/dafyddj/mirrors-commitlint 28 | rev: v19.8.1 29 | hooks: 30 | - id: commitlint 31 | - id: commitlint-ci 32 | - repo: https://github.com/rubocop-hq/rubocop 33 | rev: v1.81.7 34 | hooks: 35 | - id: rubocop 36 | name: Check Ruby files with rubocop 37 | args: [--debug] 38 | - repo: https://github.com/shellcheck-py/shellcheck-py 39 | rev: v0.9.0.6 40 | hooks: 41 | - id: shellcheck 42 | name: Check shell scripts with shellcheck 43 | files: ^.*\.(sh|bash|ksh)$ 44 | types: [] 45 | - repo: https://github.com/adrienverge/yamllint 46 | rev: v1.37.1 47 | hooks: 48 | - id: yamllint 49 | name: Check YAML syntax with yamllint 50 | args: [--strict] 51 | types: [file] 52 | # Files to include 53 | # 1. Obvious YAML files 54 | # 2. `pillar.example` and similar files 55 | # 3. SLS files under directory `test/` which are pillar files 56 | # Files to exclude 57 | # 1. SLS files under directory `test/` which are state files 58 | # 2. `kitchen.vagrant.yml`, which contains Embedded Ruby (ERB) template syntax 59 | # 3. YAML files heavily reliant on Jinja 60 | # 4. `.copier-answers.yml` and its variants which are auto-generated 61 | files: | 62 | (?x)^( 63 | .*\.yaml| 64 | .*\.yml| 65 | \.salt-lint| 66 | \.yamllint| 67 | .*\.example| 68 | test/.*\.sls 69 | )$ 70 | exclude: | 71 | (?x)^( 72 | \.copier-answers(\..+)?\.ya?ml| 73 | kitchen.vagrant.yml| 74 | test/.*/states/.*\.sls 75 | )$ 76 | - repo: https://github.com/warpnet/salt-lint 77 | rev: v0.9.2 78 | hooks: 79 | - id: salt-lint 80 | name: Check Salt files using salt-lint 81 | files: ^.*\.(sls|jinja|j2|tmpl|tst)$ 82 | - repo: https://github.com/rstcheck/rstcheck 83 | rev: v6.2.5 84 | hooks: 85 | - id: rstcheck 86 | name: Check reST files using rstcheck 87 | exclude: 'docs/CHANGELOG.rst' 88 | additional_dependencies: [sphinx==7.2.6] 89 | - repo: https://github.com/saltstack-formulas/mirrors-rst-lint 90 | rev: v1.4.0 91 | hooks: 92 | - id: rst-lint 93 | name: Check reST files using rst-lint 94 | exclude: | 95 | (?x)^( 96 | docs/CHANGELOG.rst| 97 | docs/TOFS_pattern.rst| 98 | docs/CONTRIBUTING_DOCS.rst| 99 | docs/index.rst| 100 | )$ 101 | additional_dependencies: [pygments==2.16.1] 102 | - repo: https://github.com/renovatebot/pre-commit-hooks 103 | rev: 42.29.5 104 | hooks: 105 | - id: renovate-config-validator 106 | name: Check Renovate config with renovate-config-validator 107 | - repo: https://github.com/python-jsonschema/check-jsonschema 108 | rev: 0.35.0 109 | hooks: 110 | - id: check-github-workflows 111 | name: Check GitHub workflows with check-jsonschema 112 | args: [--verbose] 113 | - id: check-gitlab-ci 114 | name: Check GitLab CI config with check-jsonschema 115 | args: [--verbose] 116 | - repo: https://github.com/standard/standard 117 | rev: v17.1.2 118 | hooks: 119 | - id: standard 120 | name: Check JavaScript files using standardJS 121 | -------------------------------------------------------------------------------- /postfix/config.sls: -------------------------------------------------------------------------------- 1 | {% from "postfix/map.jinja" import postfix with context %} 2 | 3 | include: 4 | - postfix 5 | 6 | postfix-config-file-directory-config-path: 7 | file.directory: 8 | - name: {{ postfix.config_path }} 9 | - user: root 10 | - group: {{ postfix.root_grp }} 11 | - dir_mode: '0755' 12 | - file_mode: '0644' 13 | - makedirs: True 14 | 15 | postfix-config-file-managed-main.cf: 16 | file.managed: 17 | - name: {{ postfix.config_path }}/main.cf 18 | - source: salt://postfix/files/main.cf 19 | - user: root 20 | - group: {{ postfix.root_grp }} 21 | - mode: '0644' 22 | - require: 23 | - pkg: postfix-init-pkg-installed-postfix 24 | - watch_in: 25 | - service: postfix-init-service-running-postfix 26 | - template: jinja 27 | - context: 28 | postfix: {{ postfix|tojson }} 29 | 30 | {% if 'vmail' in pillar.get('postfix', '') %} 31 | postfix-config-file-managed-virtual-alias-maps.cf: 32 | file.managed: 33 | - name: {{ postfix.config_path }}/virtual_alias_maps.cf 34 | - source: salt://postfix/files/virtual_alias_maps.cf 35 | - user: root 36 | - group: postfix 37 | - mode: '0640' 38 | - require: 39 | - pkg: postfix-init-pkg-installed-postfix 40 | - watch_in: 41 | - service: postfix-init-service-running-postfix 42 | - template: jinja 43 | 44 | postfix-config-file-managed-virtual-mailbox-domains.cf: 45 | file.managed: 46 | - name: {{ postfix.config_path }}/virtual_mailbox_domains.cf 47 | - source: salt://postfix/files/virtual_mailbox_domains.cf 48 | - user: root 49 | - group: postfix 50 | - mode: '0640' 51 | - require: 52 | - pkg: postfix-init-pkg-installed-postfix 53 | - watch_in: 54 | - service: postfix-init-service-running-postfix 55 | - template: jinja 56 | 57 | postfix-config-file-managed-virtual-mailbox-maps.cf: 58 | file.managed: 59 | - name: {{ postfix.config_path }}/virtual_mailbox_maps.cf 60 | - source: salt://postfix/files/virtual_mailbox_maps.cf 61 | - user: root 62 | - group: postfix 63 | - mode: '0640' 64 | - require: 65 | - pkg: postfix-init-pkg-installed-postfix 66 | - watch_in: 67 | - service: postfix-init-service-running-postfix 68 | - template: jinja 69 | {% endif %} 70 | 71 | {% if salt['pillar.get']('postfix:manage_master_config', True) %} 72 | {% import_yaml "postfix/services.yaml" as postfix_master_services %} 73 | postfix-config-file-managed-master.cf: 74 | file.managed: 75 | - name: {{ postfix.config_path }}/master.cf 76 | - source: salt://postfix/files/master.cf 77 | - user: root 78 | - group: {{ postfix.root_grp }} 79 | - mode: '0644' 80 | - require: 81 | - pkg: postfix-init-pkg-installed-postfix 82 | - watch_in: 83 | - service: postfix-init-service-running-postfix 84 | - template: jinja 85 | - context: 86 | postfix: {{ postfix|tojson }} 87 | postfix_master_services: {{ postfix_master_services|tojson }} 88 | {% endif %} 89 | 90 | {%- for domain in salt['pillar.get']('postfix:certificates', {}).keys() %} 91 | 92 | postfix-config-file-managed-{{ domain }}-ssl-certificate: 93 | file.managed: 94 | - name: {{ postfix.config_path }}/ssl/{{ domain }}.crt 95 | - makedirs: True 96 | - contents_pillar: postfix:certificates:{{ domain }}:public_cert 97 | - watch_in: 98 | - service: postfix-init-service-running-postfix 99 | 100 | postfix-config-file-managed-{{ domain }}-ssl-key: 101 | file.managed: 102 | - name: {{ postfix.config_path }}/ssl/{{ domain }}.key 103 | - mode: '0600' 104 | - makedirs: True 105 | - contents_pillar: postfix:certificates:{{ domain }}:private_key 106 | - watch_in: 107 | - service: postfix-init-service-running-postfix 108 | 109 | {% endfor %} 110 | 111 | # manage various mappings 112 | {% for mapping, data in salt['pillar.get']('postfix:mapping', {}).items() %} 113 | {%- set need_postmap = False %} 114 | {%- set file_path = salt['pillar.get']('postfix:config:' ~ mapping) %} 115 | {%- if file_path.startswith('proxy:') %} 116 | {#- Discard the proxy:-prefix #} 117 | {%- set _, file_type, file_path = file_path.split(':') %} 118 | {%- elif ':' in file_path %} 119 | {%- set file_type, file_path = file_path.split(':') %} 120 | {%- else %} 121 | {%- set file_type = postfix.default_database_type %} 122 | {%- endif %} 123 | {%- if not file_path.startswith('/') %} 124 | {%- set file_path = postfix.config_path ~ '/' ~ file_path %} 125 | {%- endif %} 126 | {%- if file_type in ("btree", "cdb", "cidr", "dbm", "hash", "pcre", "regexp", "sdbm") %} 127 | {%- set need_postmap = True %} 128 | {%- endif %} 129 | postfix-config-file-managed-{{ mapping }}: 130 | file.managed: 131 | - name: {{ file_path }} 132 | - source: salt://postfix/files/mapping.j2 133 | - user: root 134 | - group: {{ postfix.root_grp }} 135 | {%- if mapping.endswith('_sasl_password_maps') %} 136 | - mode: '0600' 137 | {%- else %} 138 | - mode: '0644' 139 | {%- endif %} 140 | - template: jinja 141 | - context: 142 | data: {{ data|json() }} 143 | - require: 144 | - pkg: postfix-init-pkg-installed-postfix 145 | - file: postfix-config-file-managed-main.cf 146 | {%- if need_postmap %} 147 | postfix-config-cmd-run-{{ mapping }}: 148 | cmd.run: 149 | - name: {{ postfix.xbin_prefix }}/sbin/postmap {{ file_path }} 150 | - cwd: / 151 | - onchanges: 152 | - file: postfix-config-file-managed-{{ mapping }} 153 | - watch_in: 154 | - service: postfix-init-service-running-postfix 155 | {%- endif %} 156 | {% endfor %} 157 | -------------------------------------------------------------------------------- /test/salt/pillar/default.sls: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | postfix: 5 | manage_master_config: true 6 | master_config: 7 | # Preferred way of managing services/processes. This allows for finegrained 8 | # control over each service. See postfix/services.yaml for defaults that can 9 | # be overridden. 10 | services: 11 | smtp: 12 | # Limit to no more than 10 smtp processes 13 | maxproc: 10 14 | # Disable oldstyle TLS wrapped SMTP 15 | smtps: 16 | enable: false 17 | # Enable submission service on port 587/tcp with custom options 18 | submission: 19 | enable: true 20 | args: 21 | - "-o smtpd_tls_security_level=encrypt" 22 | - "-o smtpd_sasl_auth_enable=yes" 23 | - "-o smtpd_client_restrictions=permit_sasl_authenticated,reject" 24 | tlsproxy: 25 | enable: true 26 | chroot: true 27 | 28 | # Backwards compatible definition of dovecot delivery in master.cf 29 | enable_dovecot: false 30 | # Backwards compatible definition of submission listener in master.cf 31 | enable_submission: false 32 | 33 | enable_service: true 34 | reload_service: true 35 | 36 | config: 37 | smtpd_banner: $myhostname ESMTP $mail_name 38 | smtp_tls_CApath: /etc/ssl/certs 39 | biff: 'no' 40 | append_dot_mydomain: 'no' 41 | readme_directory: 'no' 42 | myhostname: localhost 43 | mydestination: localhost, localhost.localdomain 44 | relayhost: '' 45 | mynetworks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 46 | mailbox_size_limit: 0 47 | recipient_delimiter: + 48 | # using all has problems in centos with ipv6 49 | inet_interfaces: 127.0.0.1 50 | inet_protocols: all 51 | 52 | # Alias 53 | alias_maps: hash:/etc/aliases 54 | # This is the list of files for the newaliases 55 | # cmd to process (see postconf(5) for details). 56 | # Only local hash/btree/dbm files: 57 | alias_database: hash:/etc/aliases 58 | 59 | local_transport: virtual 60 | local_recipient_maps: $virtual_mailbox_maps 61 | transport_maps: hash:/etc/postfix/transport 62 | 63 | # Other map types 64 | check_client_access_maps: regexp:/etc/postfix/check_client_access 65 | check_cidr_maps: cidr:/etc/postfix/check_cidr 66 | check_pcre_maps: pcre:/etc/postfix/check_pcre 67 | 68 | # SMTP server 69 | smtpd_tls_session_cache_database: btree:${data_directory}/smtpd_scache 70 | smtpd_use_tls: 'yes' 71 | smtpd_sasl_auth_enable: 'yes' 72 | smtpd_sasl_type: dovecot 73 | smtpd_sasl_path: /var/run/dovecot/auth-client 74 | smtpd_recipient_restrictions: >- 75 | permit_mynetworks, 76 | permit_sasl_authenticated, 77 | reject_unauth_destination 78 | smtpd_relay_restrictions: >- 79 | permit_mynetworks, 80 | permit_sasl_authenticated, 81 | reject_unauth_destination 82 | smtpd_sasl_security_options: noanonymous 83 | smtpd_sasl_tls_security_options: $smtpd_sasl_security_options 84 | smtpd_tls_auth_only: 'yes' 85 | smtpd_sasl_local_domain: $mydomain 86 | smtpd_tls_loglevel: 1 87 | smtpd_tls_session_cache_timeout: 3600s 88 | 89 | relay_domains: '$mydestination' 90 | 91 | # SMTP server certificate and key (from pillar data) 92 | smtpd_tls_cert_file: /etc/postfix/ssl/server-cert.crt 93 | smtpd_tls_key_file: /etc/postfix/ssl/server-cert.key 94 | 95 | # SMTP client 96 | smtp_tls_session_cache_database: btree:${data_directory}/smtp_scache 97 | smtp_use_tls: 'yes' 98 | smtp_tls_cert_file: /etc/postfix/ssl/example.com-relay-client-cert.crt 99 | smtp_tls_key_file: /etc/postfix/ssl/example.com-relay-client-cert.key 100 | smtp_tls_policy_maps: hash:/etc/postfix/tls_policy 101 | 102 | smtp_sasl_password_maps: hash:/etc/postfix/sasl_passwd 103 | sender_canonical_maps: hash:/etc/postfix/sender_canonical 104 | relay_recipient_maps: hash:/etc/postfix/relay_domains 105 | virtual_alias_maps: hash:/etc/postfix/virtual 106 | 107 | aliases: 108 | # manage single aliases 109 | # this uses the aliases file defined in the minion config, /etc/aliases by default 110 | use_file: false 111 | present: 112 | root: info@example.com 113 | absent: 114 | - root 115 | 116 | certificates: 117 | server-cert: 118 | public_cert: | 119 | -----BEGIN CERTIFICATE----- 120 | (Your primary SSL certificate: smtp.example.com.crt) 121 | -----END CERTIFICATE----- 122 | -----BEGIN CERTIFICATE----- 123 | (Your intermediate certificate: example-ca.crt) 124 | -----END CERTIFICATE----- 125 | -----BEGIN CERTIFICATE----- 126 | (Your root certificate: trusted-root.crt) 127 | -----END CERTIFICATE----- 128 | private_key: | 129 | -----BEGIN RSA PRIVATE KEY----- 130 | (Your Private key) 131 | -----END RSA PRIVATE KEY----- 132 | 133 | example.com-relay-client-cert: 134 | public_cert: | 135 | -----BEGIN CERTIFICATE----- 136 | (Your primary SSL certificate: smtp.example.com.crt) 137 | -----END CERTIFICATE----- 138 | private_key: | 139 | -----BEGIN RSA PRIVATE KEY----- 140 | (Your Private key) 141 | -----END RSA PRIVATE KEY----- 142 | 143 | mapping: 144 | transport_maps: 145 | - example.com: '10.1.1.1' 146 | 147 | smtp_tls_policy_maps: 148 | - example.com: encrypt 149 | - .example.com: encrypt 150 | 151 | smtp_sasl_password_maps: 152 | - smtp.example.com: myaccount:somepassword 153 | 154 | sender_canonical_maps: 155 | - root: servers@example.com 156 | - nagios: alerts@example.com 157 | 158 | relay_recipient_maps: 159 | - example.com: OK 160 | 161 | virtual_alias_maps: 162 | - groupaliasexample: 163 | - someuser_1@example.com 164 | - someuser_2@example.com 165 | - singlealiasexample: someuser_3@example.com 166 | 167 | check_client_access_maps: 168 | - '/[%!@].*[%!@]/': 169 | - 550 Sender-specified routing rejected 170 | 171 | check_cidr_maps: 172 | - '192.168.1.1': 173 | - OK 174 | - '192.168.0.0/16': 175 | - REJECT 176 | - '2001:db8::1': 177 | - OK 178 | - '2001:db8::/32': 179 | - REJECT 180 | 181 | check_pcre_maps: 182 | - '/^(?!owner-)(.*)-outgoing@(.*)/': 183 | - 550 Use ${1}@${2} instead 184 | -------------------------------------------------------------------------------- /postfix/files/main.cf: -------------------------------------------------------------------------------- 1 | {%- set config = salt['pillar.get']('postfix:config', {}) -%} 2 | 3 | {#- " | list": Python3.6 retuns dict_keys here, which needs to be converted into a list here. -#} 4 | {%- set processed_parameters = salt['pillar.get']('postfix:mapping', {}).keys() | list %} 5 | 6 | {%- macro set_parameter(parameter, default=None) -%} 7 | {% set value = config.get(parameter, default) %} 8 | {%- if value is not none %} 9 | {%- if value is number or value is string -%} 10 | {{ parameter }} = {{ value }} 11 | {%- elif value is iterable -%} 12 | {{ parameter }} = {{ value | join('\n') | indent(parameter | length + 3) }} 13 | {%- endif -%} 14 | {%- do processed_parameters.append(parameter) %} 15 | {%- endif %} 16 | {%- endmacro -%} 17 | 18 | # 19 | # This file is managed by salt. 20 | # Modify the salt pillar in the postfix formula that generates this file instead. 21 | # 22 | # See /usr/share/postfix/main.cf.dist for a commented, more complete version 23 | 24 | 25 | # Debian specific: Specifying a file name will cause the first 26 | # line of that file to be used as the name. The Debian default 27 | # is /etc/mailname. 28 | #myorigin = /etc/mailname 29 | 30 | {{ set_parameter('smtpd_banner', '$myhostname ESMTP $mail_name') }} 31 | {{ set_parameter('biff', 'no') }} 32 | {{ set_parameter('compatibility_level', '2') }} 33 | 34 | # must be set 35 | # See: https://serverfault.com/questions/952776/warning-undefined-parameter-mua-sender-restrictions-when-postconf-n 36 | {{ set_parameter('smtpd_restriction_classes', 'mua_sender_restrictions, mua_client_restrictions, mua_helo_restrictions') }} 37 | {{ set_parameter('mua_client_restrictions', 'permit_sasl_authenticated, reject') }} 38 | {{ set_parameter('mua_sender_restrictions', 'permit_sasl_authenticated, reject') }} 39 | {{ set_parameter('mua_helo_restrictions', 'permit_mynetworks, reject_non_fqdn_hostname, reject_invalid_hostname, permit') }} 40 | 41 | # appending .domain is the MUA's job. 42 | {{ set_parameter('append_dot_mydomain', 'no') }} 43 | 44 | # Uncomment the next line to generate "delayed mail" warnings 45 | #delay_warning_time = 4h 46 | 47 | {{ set_parameter('readme_directory', 'no') }} 48 | 49 | # Apply default setgid_group 50 | {{ set_parameter('setgid_group', postfix.setgid_group) }} 51 | # Set daemon directory 52 | {{ set_parameter('daemon_directory', postfix.daemon_directory) }} 53 | 54 | {%- set relay_restrictions = ['permit_mynetworks'] %} 55 | {%- set recipient_restrictions = ['permit_mynetworks'] %} 56 | 57 | {%- if config.get('smtpd_sasl_auth_enable', 'yes') == 'yes' %} 58 | # SASL parameters (http://www.postfix.org/SASL_README.html) 59 | {%- do relay_restrictions.append('permit_sasl_authenticated') %} 60 | {%- do recipient_restrictions.append('permit_sasl_authenticated') %} 61 | {{ set_parameter('smtpd_sasl_auth_enable', 'yes') }} 62 | {{ set_parameter('smtpd_sasl_path', 'smtpd') }} 63 | {{ set_parameter('smtpd_sasl_type', 'cyrus') }} 64 | {{ set_parameter('smtpd_sasl_security_options', ['noanonymous', 'noplaintext']) }} 65 | {{ set_parameter('smtpd_sasl_tls_security_options', ['noanonymous']) }} 66 | {{ set_parameter('smtpd_tls_auth_only', 'yes') }} 67 | {%- endif %} 68 | 69 | {%- if config.get('smtpd_use_tls', 'yes') == 'yes' %} 70 | # TLS parameters (http://www.postfix.org/TLS_README.html) 71 | # Recipient settings 72 | {{ set_parameter('smtpd_use_tls') }} 73 | {{ set_parameter('smtpd_tls_loglevel', 1) }} 74 | {{ set_parameter('smtpd_tls_security_level', 'may') }} 75 | {{ set_parameter('smtp_tls_CApath', '/etc/ssl/certs') }} 76 | {{ set_parameter('smtpd_tls_cert_file', '/etc/ssl/certs/ssl-cert-snakeoil.pem') }} 77 | {{ set_parameter('smtpd_tls_key_file', '/etc/ssl/private/ssl-cert-snakeoil.key') }} 78 | {{ set_parameter('smtpd_tls_session_cache_database', 'btree:${data_directory}/smtpd_scache') }} 79 | {{ set_parameter('smtpd_tls_mandatory_ciphers', 'high') }} 80 | {{ set_parameter('smtpd_tls_mandatory_exclude_ciphers', ['aNULL', 'MD5']) }} 81 | {{ set_parameter('smtpd_tls_mandatory_protocols', ['!SSLv2', '!SSLv3']) }} 82 | {{ set_parameter('tls_preempt_cipherlist', 'yes') }} 83 | # Relay/Sender settings 84 | {{ set_parameter('smtp_tls_loglevel', 1) }} 85 | {{ set_parameter('smtp_tls_security_level', 'may') }} 86 | {{ set_parameter('smtp_tls_session_cache_database', 'btree:${data_directory}/smtp_scache') }} 87 | {%- endif %} 88 | 89 | {{ set_parameter('myhostname', grains['fqdn']) }} 90 | {#- TODO: The following two may not be the same: #} 91 | {{ set_parameter('alias_maps', 'hash:' ~ postfix.aliases_file) }} 92 | {{ set_parameter('alias_database', 'hash:' ~ postfix.aliases_file) }} 93 | {{ set_parameter('mydestination', [grains['fqdn'], 'localhost', 'localhost.localdomain', grains['domain']]) }} 94 | {{ set_parameter('relayhost', '') }} 95 | {{ set_parameter('mynetworks', ['127.0.0.0/8', '[::ffff:127.0.0.0]/104', '[::1]/128']) }} 96 | {{ set_parameter('mailbox_size_limit', '0') }} 97 | {{ set_parameter('recipient_delimiter', '+') }} 98 | {{ set_parameter('inet_interfaces', 'all') }} 99 | {{ set_parameter('inet_protocols', 'all') }} 100 | {{ set_parameter('message_size_limit', '41943040') }} 101 | 102 | {%- if config.get('relayhost') %} 103 | {% set policyd_spf = salt['pillar.get']('postfix:policyd-spf', {}) %} 104 | {%- if policyd_spf.get('enabled', False) %} 105 | {%- do relay_restrictions.append('check_policy_server unix:private/policyd-spf') %} 106 | policy-spf_time_limit = {{ policyd_spf.get('time_limit', '3600s') }} 107 | {%- endif %} 108 | {%- do relay_restrictions.append('defer_unauth_destination') %} 109 | {{ set_parameter('smtpd_relay_restrictions', relay_restrictions) }} 110 | {%- endif %} 111 | 112 | {#- check_policy_service must be after reject_unauth_destination #} 113 | {%- do recipient_restrictions.append('reject_unauth_destination') %} 114 | {%- set postgrey_config = salt['pillar.get']('postfix:postgrey', {}) %} 115 | {%- if postgrey_config.get('enabled', False) %} 116 | {%- do recipient_restrictions.append('check_policy_service ' ~ postgrey_config.get('location', 'inet:127.0.0.1:10030')) %} 117 | {%- endif %} 118 | {{ set_parameter('smtpd_recipient_restrictions', recipient_restrictions) }} 119 | 120 | {# From init.sls #} 121 | {%- for mapping, data in salt['pillar.get']('postfix:mapping', {}).items() %} 122 | {%- set file_path = salt['pillar.get']('postfix:config:' ~ mapping) %} 123 | {%- if file_path.startswith('proxy:') %} 124 | {#- Discard the proxy:-prefix #} 125 | {%- set _, file_type, file_path = file_path.split(':') %} 126 | {%- elif ':' in file_path %} 127 | {%- set file_type, file_path = file_path.split(':') %} 128 | {%- else %} 129 | {%- set file_type = postfix.default_database_type %} 130 | {%- endif %} 131 | {%- if not file_path.startswith('/') %} 132 | {%- set file_path = postfix.config_path ~ '/' ~ file_path %} 133 | {%- endif %} 134 | 135 | {{ set_parameter(mapping, file_type ~ ':' ~ file_path) }} 136 | {% endfor %} 137 | 138 | {# Accept arbitrary parameters -#} 139 | {% for parameter in config -%} 140 | {% if parameter not in processed_parameters -%} 141 | {{ set_parameter(parameter) }} 142 | {% endif -%} 143 | {% endfor -%} 144 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Authors 2 | 3 | This list is sorted by the number of commits per contributor in _descending_ order. 4 | 5 | Avatar|Contributor|Contributions 6 | :-:|---|:-: 7 | @myii|[@myii](https://github.com/myii)|145 8 | @EvaSDK|[@EvaSDK](https://github.com/EvaSDK)|26 9 | @aboe76|[@aboe76](https://github.com/aboe76)|23 10 | @javierbertoli|[@javierbertoli](https://github.com/javierbertoli)|16 11 | @nmadhok|[@nmadhok](https://github.com/nmadhok)|14 12 | @alxwr|[@alxwr](https://github.com/alxwr)|12 13 | @gravyboat|[@gravyboat](https://github.com/gravyboat)|10 14 | @davidkarlsen|[@davidkarlsen](https://github.com/davidkarlsen)|10 15 | @ixs|[@ixs](https://github.com/ixs)|9 16 | @0xf10e|[@0xf10e](https://github.com/0xf10e)|9 17 | @imran1008|[@imran1008](https://github.com/imran1008)|8 18 | @puneetk|[@puneetk](https://github.com/puneetk)|7 19 | @danoe|[@danoe](https://github.com/danoe)|6 20 | @dafyddj|[@dafyddj](https://github.com/dafyddj)|5 21 | @noelmcloughlin|[@noelmcloughlin](https://github.com/noelmcloughlin)|4 22 | @thatch45|[@thatch45](https://github.com/thatch45)|3 23 | @daks|[@daks](https://github.com/daks)|2 24 | @jeroen92|[@jeroen92](https://github.com/jeroen92)|2 25 | @wwentland|[@wwentland](https://github.com/wwentland)|2 26 | @iamseth|[@iamseth](https://github.com/iamseth)|2 27 | @whiteinge|[@whiteinge](https://github.com/whiteinge)|2 28 | @stp-ip|[@stp-ip](https://github.com/stp-ip)|2 29 | @gtmanfred|[@gtmanfred](https://github.com/gtmanfred)|2 30 | @sylvainfaivre|[@sylvainfaivre](https://github.com/sylvainfaivre)|1 31 | @dependabot[bot]|[@dependabot[bot]](https://github.com/apps/dependabot)|1 32 | @vquie|[@vquie](https://github.com/vquie)|1 33 | @cp-richard|[@cp-richard](https://github.com/cp-richard)|1 34 | @rhertzog|[@rhertzog](https://github.com/rhertzog)|1 35 | @n-rodriguez|[@n-rodriguez](https://github.com/n-rodriguez)|1 36 | @mgomersbach|[@mgomersbach](https://github.com/mgomersbach)|1 37 | @mschiff|[@mschiff](https://github.com/mschiff)|1 38 | @duk3luk3|[@duk3luk3](https://github.com/duk3luk3)|1 39 | @techhat|[@techhat](https://github.com/techhat)|1 40 | @holgerfischerone|[@holgerfischerone](https://github.com/holgerfischerone)|1 41 | @pprkut|[@pprkut](https://github.com/pprkut)|1 42 | @fzipi|[@fzipi](https://github.com/fzipi)|1 43 | @feiming|[@feiming](https://github.com/feiming)|1 44 | @baby-gnu|[@baby-gnu](https://github.com/baby-gnu)|1 45 | @campbellmc|[@campbellmc](https://github.com/campbellmc)|1 46 | @asenci|[@asenci](https://github.com/asenci)|1 47 | 48 | --- 49 | 50 | Auto-generated by a [forked version](https://github.com/myii/maintainer) of [gaocegege/maintainer](https://github.com/gaocegege/maintainer) on 2025-04-10. 51 | -------------------------------------------------------------------------------- /postfix/services.yaml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | # Default Postfix master processes as defined by postfix 5 | # 6 | # The dictionary is keyed off the service name ("smtp", "smtpd", etc.) except 7 | # for the few cases the service name is repeated to illustrate alternative 8 | # options in the file. 9 | # In such a case the second entry has a unique identifier appended, e.g. 10 | # "smtp-unix". The 'service' attribute is used to provide the service name 11 | # that will be rendered thus overriding the usual key to prevent clashes. 12 | # 13 | 14 | defaults: 15 | # Postfix internal services/processes defaults 16 | smtp: 17 | chroot: false 18 | command: smtpd 19 | private: false 20 | type: inet 21 | 22 | smtp-postscreen: 23 | chroot: false 24 | command: postscreen 25 | enable: false 26 | maxproc: 1 27 | private: false 28 | service: smtp 29 | type: inet 30 | 31 | smtpd: 32 | chroot: false 33 | enable: false 34 | type: pass 35 | 36 | dnsblog: 37 | chroot: false 38 | enable: false 39 | maxproc: 0 40 | type: unix 41 | 42 | tlsproxy: 43 | chroot: false 44 | enable: false 45 | maxproc: 0 46 | type: unix 47 | 48 | submission: 49 | args: 50 | - '-o syslog_name=postfix/submission' 51 | - '-o smtpd_tls_security_level=encrypt' 52 | - '-o smtpd_sasl_auth_enable=yes' 53 | - '-o smtpd_reject_unlisted_recipient=no' 54 | - '-o smtpd_client_restrictions=$mua_client_restrictions' 55 | - '-o smtpd_helo_restrictions=$mua_helo_restrictions' 56 | - '-o smtpd_sender_restrictions=$mua_sender_restrictions' 57 | - '-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject' 58 | - '-o milter_macro_daemon_name=ORIGINATING' 59 | chroot: false 60 | command: smtpd 61 | enable: false 62 | private: false 63 | type: inet 64 | 65 | smtps: 66 | args: 67 | - '-o syslog_name=postfix/smtps' 68 | - '-o smtpd_tls_wrappermode=yes' 69 | - '-o smtpd_sasl_auth_enable=yes' 70 | - '-o smtpd_reject_unlisted_recipient=no' 71 | - '-o smtpd_client_restrictions=$mua_client_restrictions' 72 | - '-o smtpd_helo_restrictions=$mua_helo_restrictions' 73 | - '-o smtpd_sender_restrictions=$mua_sender_restrictions' 74 | - '-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject' 75 | - '-o milter_macro_daemon_name=ORIGINATING' 76 | chroot: false 77 | command: smtpd 78 | enable: false 79 | private: false 80 | type: inet 81 | 82 | '628': 83 | chroot: false 84 | command: qmqpd 85 | enable: false 86 | private: false 87 | type: inet 88 | 89 | pickup: 90 | chroot: false 91 | maxproc: 1 92 | private: false 93 | type: unix 94 | wakeup: 60 95 | 96 | cleanup: 97 | chroot: false 98 | maxproc: 0 99 | private: false 100 | type: unix 101 | 102 | qmgr: 103 | chroot: false 104 | maxproc: 1 105 | private: false 106 | type: unix 107 | wakeup: 300 108 | 109 | qmgr-oqmgr: 110 | chroot: false 111 | command: oqmgr 112 | enable: false 113 | maxproc: 1 114 | private: false 115 | service: qmgr 116 | type: unix 117 | wakeup: 300 118 | 119 | tlsmgr: 120 | chroot: false 121 | maxproc: 1 122 | type: unix 123 | wakeup: '1000?' 124 | 125 | rewrite: 126 | chroot: false 127 | command: trivial-rewrite 128 | type: unix 129 | 130 | bounce: 131 | chroot: false 132 | maxproc: 0 133 | type: unix 134 | 135 | defer: 136 | chroot: false 137 | command: bounce 138 | maxproc: 0 139 | type: unix 140 | 141 | trace: 142 | chroot: false 143 | command: bounce 144 | maxproc: 0 145 | type: unix 146 | 147 | smtp-unix: 148 | chroot: false 149 | command: smtp 150 | service: smtp 151 | type: unix 152 | 153 | verify: 154 | chroot: false 155 | maxproc: 1 156 | type: unix 157 | 158 | flush: 159 | chroot: false 160 | maxproc: 0 161 | private: false 162 | type: unix 163 | wakeup: '1000?' 164 | 165 | proxymap: 166 | chroot: false 167 | type: unix 168 | 169 | proxywrite: 170 | chroot: false 171 | command: proxymap 172 | maxproc: 1 173 | type: unix 174 | 175 | relay: 176 | args: 177 | - '# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5' 178 | chroot: false 179 | command: smtp 180 | type: unix 181 | 182 | showq: 183 | chroot: false 184 | private: false 185 | type: unix 186 | 187 | error: 188 | chroot: false 189 | type: unix 190 | 191 | retry: 192 | chroot: false 193 | command: error 194 | type: unix 195 | 196 | discard: 197 | chroot: false 198 | type: unix 199 | 200 | local: 201 | chroot: false 202 | type: unix 203 | unpriv: false 204 | 205 | virtual: 206 | chroot: false 207 | type: unix 208 | unpriv: false 209 | 210 | lmtp: 211 | chroot: false 212 | type: unix 213 | 214 | anvil: 215 | chroot: false 216 | maxproc: 1 217 | type: unix 218 | 219 | scache: 220 | chroot: false 221 | maxproc: 1 222 | type: unix 223 | 224 | # Postfix MDA definitions, these are optional and commented out by default 225 | maildrop: 226 | argv: /usr/local/bin/maildrop 227 | chroot: false 228 | command: pipe 229 | enable: false 230 | extras: '-d ${recipient}' 231 | flags: DRhu 232 | type: unix 233 | unpriv: false 234 | user: vmail 235 | 236 | cyrus: 237 | argv: /cyrus/bin/deliver 238 | chroot: false 239 | command: pipe 240 | enable: false 241 | extras: "-e -r ${sender} -m ${extension} ${user}" 242 | type: unix 243 | unpriv: false 244 | user: cyrus 245 | 246 | old-cyrus: 247 | argv: /cyrus/bin/deliver 248 | chroot: false 249 | command: pipe 250 | enable: false 251 | extras: '-e -m ${extension} ${user}' 252 | flags: R 253 | type: unix 254 | unpriv: false 255 | user: cyrus 256 | 257 | uucp: 258 | argv: uux 259 | chroot: false 260 | command: pipe 261 | enable: false 262 | extras: '-r -n -z -a$sender - $nexthop!rmail ($recipient)' 263 | flags: Fqhu 264 | type: unix 265 | unpriv: false 266 | user: uucp 267 | 268 | ifmail: 269 | argv: /usr/lib/ifmail/ifmail 270 | chroot: false 271 | command: pipe 272 | enable: false 273 | extras: '-r $nexthop ($recipient)' 274 | flags: F 275 | type: unix 276 | unpriv: false 277 | user: ftn 278 | 279 | bsmtp: 280 | argv: /usr/local/sbin/bsmtp 281 | chroot: false 282 | command: pipe 283 | enable: false 284 | extras: '-f $sender $nexthop $recipient' 285 | flags: Fq. 286 | type: unix 287 | unpriv: false 288 | user: bsmtp 289 | 290 | scalemail-backend: 291 | argv: /usr/lib/scalemail/bin/scalemail-store 292 | chroot: false 293 | command: pipe 294 | enable: false 295 | extras: '${nexthop} ${user} ${extension}' 296 | flags: R 297 | maxproc: 2 298 | type: unix 299 | unpriv: false 300 | user: scalemail 301 | 302 | mailman: 303 | argv: /usr/lib/mailman/bin/postfix-to-mailman.py 304 | chroot: false 305 | command: pipe 306 | enable: false 307 | extras: '${nexthop} ${user}' 308 | flags: FR 309 | type: unix 310 | unpriv: false 311 | user: list 312 | 313 | 314 | # Service order inside the master.cf file 315 | order: 316 | - smtp 317 | - smtp-postscreen 318 | - smtpd 319 | - dnsblog 320 | - tlsproxy 321 | - submission 322 | - smtps 323 | - '628' 324 | - pickup 325 | - cleanup 326 | - qmgr 327 | - qmgr-oqmgr 328 | - tlsmgr 329 | - rewrite 330 | - bounce 331 | - defer 332 | - trace 333 | - verify 334 | - flush 335 | - proxymap 336 | - proxywrite 337 | - smtp-unix 338 | - relay 339 | - showq 340 | - error 341 | - retry 342 | - discard 343 | - local 344 | - virtual 345 | - lmtp 346 | - anvil 347 | - scache 348 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | ################################################################################ 5 | # NOTE: This file is UNMAINTAINED; it is provided for references purposes only. 6 | # No guarantees are tendered that this structure will work after 2020. 7 | ################################################################################ 8 | # * https://en.wikipedia.org/wiki/Travis_CI: 9 | # - "... free open-source plans were removed in [sic] the end of 2020" 10 | # - https://blog.travis-ci.com/2020-11-02-travis-ci-new-billing 11 | # - https://ropensci.org/technotes/2020/11/19/moving-away-travis/ 12 | ################################################################################ 13 | ## Machine config 14 | os: 'linux' 15 | arch: 'amd64' 16 | dist: 'bionic' 17 | version: '~> 1.0' 18 | 19 | ## Language and cache config 20 | language: 'ruby' 21 | cache: 'bundler' 22 | 23 | ## Services config 24 | services: 25 | - docker 26 | 27 | ## Script to run for the test stage 28 | script: 29 | - bin/kitchen verify "${INSTANCE}" 30 | 31 | ## Stages and jobs matrix 32 | stages: 33 | - test 34 | # # As part of the switch away from Travis CI, ensure that the `release` stage 35 | # # is not run inadvertently 36 | # - name: 'release' 37 | # if: 'branch = master AND type != pull_request' 38 | jobs: 39 | include: 40 | ## Define the test stage that runs the linters (and testing matrix, if applicable) 41 | 42 | # Run all of the linters in a single job 43 | - language: 'node_js' 44 | node_js: 'lts/*' 45 | env: 'Lint' 46 | name: 'Lint: salt-lint, yamllint, rubocop, shellcheck & commitlint' 47 | before_install: 'skip' 48 | script: 49 | # Install and run `salt-lint` 50 | - pip install --user salt-lint 51 | - git ls-files -- '*.sls' '*.jinja' '*.j2' '*.tmpl' '*.tst' 52 | | xargs salt-lint 53 | # Install and run `yamllint` 54 | # Need at least `v1.17.0` for the `yaml-files` setting 55 | - pip install --user yamllint>=1.17.0 56 | - yamllint -s . 57 | # Install and run `rubocop` 58 | - gem install rubocop 59 | - rubocop -d 60 | # Run `shellcheck` (already pre-installed in Travis) 61 | - shellcheck --version 62 | - git ls-files -- '*.sh' '*.bash' '*.ksh' 63 | | xargs shellcheck 64 | # Install and run `commitlint` 65 | - npm i -D @commitlint/config-conventional 66 | @commitlint/travis-cli 67 | - commitlint-travis 68 | 69 | # Run `pre-commit` linters in a single job 70 | - language: 'python' 71 | env: 'Lint_pre-commit' 72 | name: 'Lint: pre-commit' 73 | before_install: 'skip' 74 | cache: 75 | directories: 76 | - $HOME/.cache/pre-commit 77 | script: 78 | # Install and run `pre-commit` 79 | - pip install pre-commit==2.7.1 80 | - pre-commit run --all-files --color always --verbose 81 | - pre-commit run --color always --hook-stage manual --verbose commitlint-travis 82 | 83 | ## Define the rest of the matrix based on Kitchen testing 84 | # Make sure the instances listed below match up with 85 | # the `platforms` defined in `kitchen.yml` 86 | # - env: INSTANCE=default-debian-11-tiamat-py3 87 | # - env: INSTANCE=default-debian-10-tiamat-py3 88 | # - env: INSTANCE=default-debian-9-tiamat-py3 89 | # - env: INSTANCE=default-ubuntu-2204-tiamat-py3 90 | # - env: INSTANCE=default-ubuntu-2004-tiamat-py3 91 | # - env: INSTANCE=default-ubuntu-1804-tiamat-py3 92 | # - env: INSTANCE=default-centos-stream8-tiamat-py3 93 | # - env: INSTANCE=default-centos-7-tiamat-py3 94 | # - env: INSTANCE=default-amazonlinux-2-tiamat-py3 95 | # - env: INSTANCE=default-oraclelinux-8-tiamat-py3 96 | # - env: INSTANCE=default-oraclelinux-7-tiamat-py3 97 | # - env: INSTANCE=default-almalinux-8-tiamat-py3 98 | # - env: INSTANCE=default-rockylinux-8-tiamat-py3 99 | - env: INSTANCE=default-debian-11-master-py3 100 | - env: INSTANCE=default-debian-10-master-py3 101 | - env: INSTANCE=default-debian-9-master-py3 102 | - env: INSTANCE=default-ubuntu-2204-master-py3 103 | - env: INSTANCE=default-ubuntu-2004-master-py3 104 | - env: INSTANCE=default-ubuntu-1804-master-py3 105 | - env: INSTANCE=default-centos-stream8-master-py3 106 | - env: INSTANCE=default-centos-7-master-py3 107 | - env: INSTANCE=default-fedora-36-master-py3 108 | - env: INSTANCE=default-fedora-35-master-py3 109 | - env: INSTANCE=default-opensuse-leap-153-master-py3 110 | - env: INSTANCE=default-opensuse-tmbl-latest-master-py3 111 | - env: INSTANCE=default-amazonlinux-2-master-py3 112 | - env: INSTANCE=default-oraclelinux-8-master-py3 113 | - env: INSTANCE=default-oraclelinux-7-master-py3 114 | - env: INSTANCE=default-arch-base-latest-master-py3 115 | - env: INSTANCE=default-gentoo-stage3-latest-master-py3 116 | - env: INSTANCE=default-gentoo-stage3-systemd-master-py3 117 | - env: INSTANCE=default-almalinux-8-master-py3 118 | - env: INSTANCE=default-rockylinux-8-master-py3 119 | # - env: INSTANCE=default-debian-11-3004-1-py3 120 | # - env: INSTANCE=default-debian-10-3004-1-py3 121 | # - env: INSTANCE=default-debian-9-3004-1-py3 122 | # - env: INSTANCE=default-ubuntu-2204-3004-1-py3 123 | # - env: INSTANCE=default-ubuntu-2004-3004-1-py3 124 | # - env: INSTANCE=default-ubuntu-1804-3004-1-py3 125 | # - env: INSTANCE=default-centos-stream8-3004-1-py3 126 | # - env: INSTANCE=default-centos-7-3004-1-py3 127 | # - env: INSTANCE=default-fedora-36-3004-1-py3 128 | # - env: INSTANCE=default-fedora-35-3004-1-py3 129 | # - env: INSTANCE=default-amazonlinux-2-3004-1-py3 130 | # - env: INSTANCE=default-oraclelinux-8-3004-1-py3 131 | # - env: INSTANCE=default-oraclelinux-7-3004-1-py3 132 | # - env: INSTANCE=default-arch-base-latest-3004-1-py3 133 | # - env: INSTANCE=default-gentoo-stage3-latest-3004-1-py3 134 | # - env: INSTANCE=default-gentoo-stage3-systemd-3004-1-py3 135 | # - env: INSTANCE=default-almalinux-8-3004-1-py3 136 | # - env: INSTANCE=default-rockylinux-8-3004-1-py3 137 | # - env: INSTANCE=default-opensuse-leap-153-3004-0-py3 138 | # - env: INSTANCE=default-opensuse-tmbl-latest-3004-0-py3 139 | # - env: INSTANCE=default-debian-10-3003-4-py3 140 | # - env: INSTANCE=default-debian-9-3003-4-py3 141 | # - env: INSTANCE=default-ubuntu-2004-3003-4-py3 142 | # - env: INSTANCE=default-ubuntu-1804-3003-4-py3 143 | # - env: INSTANCE=default-centos-stream8-3003-4-py3 144 | # - env: INSTANCE=default-centos-7-3003-4-py3 145 | # - env: INSTANCE=default-amazonlinux-2-3003-4-py3 146 | # - env: INSTANCE=default-oraclelinux-8-3003-4-py3 147 | # - env: INSTANCE=default-oraclelinux-7-3003-4-py3 148 | # - env: INSTANCE=default-almalinux-8-3003-4-py3 149 | 150 | ## Define the release stage that runs `semantic-release` 151 | - stage: 'release' 152 | language: 'node_js' 153 | node_js: 'lts/*' 154 | env: 'Release' 155 | name: 'Run semantic-release inc. file updates to AUTHORS, CHANGELOG & FORMULA' 156 | before_install: 'skip' 157 | script: 158 | # Update `AUTHORS.md` 159 | - export MAINTAINER_TOKEN=${GH_TOKEN} 160 | - go get github.com/myii/maintainer 161 | - maintainer contributor 162 | 163 | # Install all dependencies required for `semantic-release` 164 | - npm i -D @semantic-release/changelog@3 165 | @semantic-release/exec@3 166 | @semantic-release/git@7 167 | deploy: 168 | provider: 'script' 169 | # Opt-in to `dpl v2` to complete the Travis build config validation (beta) 170 | # * https://docs.travis-ci.com/user/build-config-validation 171 | # Deprecated `skip_cleanup` can now be avoided, `cleanup: false` is by default 172 | edge: true 173 | # Run `semantic-release` 174 | script: 'npx semantic-release@15.14' 175 | 176 | # Notification options: `always`, `never` or `change` 177 | notifications: 178 | webhooks: 179 | if: 'repo = saltstack-formulas/postfix-formula' 180 | urls: 181 | - https://saltstack-formulas.zulipchat.com/api/v1/external/travis?api_key=HsIq3o5QmLxdnVCKF9is0FUIpkpAY79P&stream=CI&topic=saltstack-formulas%2Fpostfix-formula&ignore_pull_requests=true 182 | on_success: always # default: always 183 | on_failure: always # default: always 184 | on_start: always # default: never 185 | on_cancel: always # default: always 186 | on_error: always # default: always 187 | -------------------------------------------------------------------------------- /kitchen.yml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | # For help on this file's format, see https://kitchen.ci/ 5 | driver: 6 | name: docker 7 | use_sudo: false 8 | privileged: true 9 | run_command: /usr/lib/systemd/systemd 10 | 11 | provisioner: 12 | name: salt_solo 13 | log_level: debug 14 | salt_install: none 15 | require_chef: false 16 | formula: postfix 17 | salt_copy_filter: 18 | - .kitchen 19 | - .git 20 | pillars_from_directories: 21 | - test/salt/pillar 22 | 23 | transport: 24 | # Avoid lengthy waits when a container does not launch correctly 25 | max_wait_until_ready: 60 26 | 27 | platforms: 28 | ## SALT `master` 29 | - name: debian-12-master 30 | driver: 31 | image: saltimages/salt-master-py3:debian-12 32 | run_command: /lib/systemd/systemd 33 | - name: debian-11-master 34 | driver: 35 | image: saltimages/salt-master-py3:debian-11 36 | run_command: /lib/systemd/systemd 37 | - name: ubuntu-2404-master 38 | driver: 39 | image: saltimages/salt-master-py3:ubuntu-24.04 40 | run_command: /lib/systemd/systemd 41 | - name: ubuntu-2204-master 42 | driver: 43 | image: saltimages/salt-master-py3:ubuntu-22.04 44 | run_command: /lib/systemd/systemd 45 | - name: ubuntu-2004-master 46 | driver: 47 | image: saltimages/salt-master-py3:ubuntu-20.04 48 | run_command: /lib/systemd/systemd 49 | - name: centos-stream9-master 50 | driver: 51 | image: saltimages/salt-master-py3:centos-stream9 52 | - name: opensuse-leap-156-master 53 | driver: 54 | image: saltimages/salt-master-py3:opensuse-leap-15.6 55 | # Workaround to avoid intermittent failures on `opensuse-leap-15.6`: 56 | # => SCP did not finish successfully (255): (Net::SCP::Error) 57 | transport: 58 | max_ssh_sessions: 1 59 | - name: opensuse-tmbl-latest-master 60 | driver: 61 | image: saltimages/salt-master-py3:opensuse-tumbleweed-latest 62 | # Workaround to avoid intermittent failures on `opensuse-tumbleweed`: 63 | # => SCP did not finish successfully (255): (Net::SCP::Error) 64 | transport: 65 | max_ssh_sessions: 1 66 | - name: fedora-41-master 67 | driver: 68 | image: saltimages/salt-master-py3:fedora-41 69 | - name: fedora-40-master 70 | driver: 71 | image: saltimages/salt-master-py3:fedora-40 72 | - name: amazonlinux-2023-master 73 | driver: 74 | image: saltimages/salt-master-py3:amazonlinux-2023 75 | - name: oraclelinux-9-master 76 | driver: 77 | image: saltimages/salt-master-py3:oraclelinux-9 78 | - name: oraclelinux-8-master 79 | driver: 80 | image: saltimages/salt-master-py3:oraclelinux-8 81 | - name: almalinux-9-master 82 | driver: 83 | image: saltimages/salt-master-py3:almalinux-9 84 | - name: almalinux-8-master 85 | driver: 86 | image: saltimages/salt-master-py3:almalinux-8 87 | - name: rockylinux-9-master 88 | driver: 89 | image: saltimages/salt-master-py3:rockylinux-9 90 | - name: rockylinux-8-master 91 | driver: 92 | image: saltimages/salt-master-py3:rockylinux-8 93 | 94 | ## SALT `3007.9` 95 | - name: debian-12-3007-9 96 | driver: 97 | image: saltimages/salt-3007.9-py3:debian-12 98 | run_command: /lib/systemd/systemd 99 | - name: debian-11-3007-9 100 | driver: 101 | image: saltimages/salt-3007.9-py3:debian-11 102 | run_command: /lib/systemd/systemd 103 | - name: ubuntu-2404-3007-9 104 | driver: 105 | image: saltimages/salt-3007.9-py3:ubuntu-24.04 106 | run_command: /lib/systemd/systemd 107 | - name: ubuntu-2204-3007-9 108 | driver: 109 | image: saltimages/salt-3007.9-py3:ubuntu-22.04 110 | run_command: /lib/systemd/systemd 111 | - name: ubuntu-2004-3007-9 112 | driver: 113 | image: saltimages/salt-3007.9-py3:ubuntu-20.04 114 | run_command: /lib/systemd/systemd 115 | - name: centos-stream9-3007-9 116 | driver: 117 | image: saltimages/salt-3007.9-py3:centos-stream9 118 | - name: opensuse-leap-156-3007-9 119 | driver: 120 | image: saltimages/salt-3007.9-py3:opensuse-leap-15.6 121 | # Workaround to avoid intermittent failures on `opensuse-leap-15.6`: 122 | # => SCP did not finish successfully (255): (Net::SCP::Error) 123 | transport: 124 | max_ssh_sessions: 1 125 | - name: opensuse-tmbl-latest-3007-9 126 | driver: 127 | image: saltimages/salt-3007.9-py3:opensuse-tumbleweed-latest 128 | # Workaround to avoid intermittent failures on `opensuse-tumbleweed`: 129 | # => SCP did not finish successfully (255): (Net::SCP::Error) 130 | transport: 131 | max_ssh_sessions: 1 132 | - name: fedora-41-3007-9 133 | driver: 134 | image: saltimages/salt-3007.9-py3:fedora-41 135 | - name: fedora-40-3007-9 136 | driver: 137 | image: saltimages/salt-3007.9-py3:fedora-40 138 | - name: amazonlinux-2023-3007-9 139 | driver: 140 | image: saltimages/salt-3007.9-py3:amazonlinux-2023 141 | - name: amazonlinux-2-3007-9 142 | driver: 143 | image: saltimages/salt-3007.9-py3:amazonlinux-2 144 | - name: oraclelinux-9-3007-9 145 | driver: 146 | image: saltimages/salt-3007.9-py3:oraclelinux-9 147 | - name: oraclelinux-8-3007-9 148 | driver: 149 | image: saltimages/salt-3007.9-py3:oraclelinux-8 150 | - name: almalinux-9-3007-9 151 | driver: 152 | image: saltimages/salt-3007.9-py3:almalinux-9 153 | - name: almalinux-8-3007-9 154 | driver: 155 | image: saltimages/salt-3007.9-py3:almalinux-8 156 | - name: rockylinux-9-3007-9 157 | driver: 158 | image: saltimages/salt-3007.9-py3:rockylinux-9 159 | - name: rockylinux-8-3007-9 160 | driver: 161 | image: saltimages/salt-3007.9-py3:rockylinux-8 162 | 163 | ## SALT `3006.17` 164 | - name: debian-12-3006-17 165 | driver: 166 | image: saltimages/salt-3006.17-py3:debian-12 167 | run_command: /lib/systemd/systemd 168 | - name: debian-11-3006-17 169 | driver: 170 | image: saltimages/salt-3006.17-py3:debian-11 171 | run_command: /lib/systemd/systemd 172 | - name: ubuntu-2404-3006-17 173 | driver: 174 | image: saltimages/salt-3006.17-py3:ubuntu-24.04 175 | run_command: /lib/systemd/systemd 176 | - name: ubuntu-2204-3006-17 177 | driver: 178 | image: saltimages/salt-3006.17-py3:ubuntu-22.04 179 | run_command: /lib/systemd/systemd 180 | - name: ubuntu-2004-3006-17 181 | driver: 182 | image: saltimages/salt-3006.17-py3:ubuntu-20.04 183 | run_command: /lib/systemd/systemd 184 | - name: centos-stream9-3006-17 185 | driver: 186 | image: saltimages/salt-3006.17-py3:centos-stream9 187 | - name: opensuse-tmbl-latest-3006-17 188 | driver: 189 | image: saltimages/salt-3006.17-py3:opensuse-tumbleweed-latest 190 | # Workaround to avoid intermittent failures on `opensuse-tumbleweed`: 191 | # => SCP did not finish successfully (255): (Net::SCP::Error) 192 | transport: 193 | max_ssh_sessions: 1 194 | - name: opensuse-leap-156-3006-17 195 | driver: 196 | image: saltimages/salt-3006.17-py3:opensuse-leap-15.6 197 | # Workaround to avoid intermittent failures on `opensuse-leap-15.6`: 198 | # => SCP did not finish successfully (255): (Net::SCP::Error) 199 | transport: 200 | max_ssh_sessions: 1 201 | - name: fedora-41-3006-17 202 | driver: 203 | image: saltimages/salt-3006.17-py3:fedora-41 204 | - name: fedora-40-3006-17 205 | driver: 206 | image: saltimages/salt-3006.17-py3:fedora-40 207 | - name: amazonlinux-2023-3006-17 208 | driver: 209 | image: saltimages/salt-3006.17-py3:amazonlinux-2023 210 | - name: amazonlinux-2-3006-17 211 | driver: 212 | image: saltimages/salt-3006.17-py3:amazonlinux-2 213 | - name: oraclelinux-9-3006-17 214 | driver: 215 | image: saltimages/salt-3006.17-py3:oraclelinux-9 216 | - name: oraclelinux-8-3006-17 217 | driver: 218 | image: saltimages/salt-3006.17-py3:oraclelinux-8 219 | - name: almalinux-9-3006-17 220 | driver: 221 | image: saltimages/salt-3006.17-py3:almalinux-9 222 | - name: almalinux-8-3006-17 223 | driver: 224 | image: saltimages/salt-3006.17-py3:almalinux-8 225 | - name: rockylinux-9-3006-17 226 | driver: 227 | image: saltimages/salt-3006.17-py3:rockylinux-9 228 | - name: rockylinux-8-3006-17 229 | driver: 230 | image: saltimages/salt-3006.17-py3:rockylinux-8 231 | 232 | ########################################################## 233 | # This file is managed as part of a Copier template. # 234 | # Please make your own changes below this comment. # 235 | ########################################################## 236 | 237 | verifier: 238 | # https://www.inspec.io/ 239 | name: inspec 240 | sudo: true 241 | reporter: 242 | # cli, documentation, html, progress, json, json-min, json-rspec, junit 243 | - cli 244 | 245 | suites: 246 | - name: default 247 | provisioner: 248 | state_top: 249 | base: 250 | '*': 251 | - postfix._mapdata 252 | - postfix 253 | - postfix.config 254 | pillars: 255 | top.sls: 256 | base: 257 | '*': 258 | - default 259 | verifier: 260 | inspec_tests: 261 | - path: test/integration/default 262 | -------------------------------------------------------------------------------- /docs/AUTHORS.rst: -------------------------------------------------------------------------------- 1 | .. role:: raw-html-m2r(raw) 2 | :format: html 3 | 4 | 5 | Authors 6 | ======= 7 | 8 | This list is sorted by the number of commits per contributor in *descending* order. 9 | 10 | .. list-table:: 11 | :header-rows: 1 12 | 13 | * - Avatar 14 | - Contributor 15 | - Contributions 16 | * - :raw-html-m2r:`@myii` 17 | - `@myii `_ 18 | - 145 19 | * - :raw-html-m2r:`@EvaSDK` 20 | - `@EvaSDK `_ 21 | - 26 22 | * - :raw-html-m2r:`@aboe76` 23 | - `@aboe76 `_ 24 | - 23 25 | * - :raw-html-m2r:`@javierbertoli` 26 | - `@javierbertoli `_ 27 | - 16 28 | * - :raw-html-m2r:`@nmadhok` 29 | - `@nmadhok `_ 30 | - 14 31 | * - :raw-html-m2r:`@alxwr` 32 | - `@alxwr `_ 33 | - 12 34 | * - :raw-html-m2r:`@gravyboat` 35 | - `@gravyboat `_ 36 | - 10 37 | * - :raw-html-m2r:`@davidkarlsen` 38 | - `@davidkarlsen `_ 39 | - 10 40 | * - :raw-html-m2r:`@ixs` 41 | - `@ixs `_ 42 | - 9 43 | * - :raw-html-m2r:`@0xf10e` 44 | - `@0xf10e `_ 45 | - 9 46 | * - :raw-html-m2r:`@imran1008` 47 | - `@imran1008 `_ 48 | - 8 49 | * - :raw-html-m2r:`@puneetk` 50 | - `@puneetk `_ 51 | - 7 52 | * - :raw-html-m2r:`@danoe` 53 | - `@danoe `_ 54 | - 6 55 | * - :raw-html-m2r:`@dafyddj` 56 | - `@dafyddj `_ 57 | - 5 58 | * - :raw-html-m2r:`@noelmcloughlin` 59 | - `@noelmcloughlin `_ 60 | - 4 61 | * - :raw-html-m2r:`@thatch45` 62 | - `@thatch45 `_ 63 | - 3 64 | * - :raw-html-m2r:`@daks` 65 | - `@daks `_ 66 | - 2 67 | * - :raw-html-m2r:`@jeroen92` 68 | - `@jeroen92 `_ 69 | - 2 70 | * - :raw-html-m2r:`@wwentland` 71 | - `@wwentland `_ 72 | - 2 73 | * - :raw-html-m2r:`@iamseth` 74 | - `@iamseth `_ 75 | - 2 76 | * - :raw-html-m2r:`@whiteinge` 77 | - `@whiteinge `_ 78 | - 2 79 | * - :raw-html-m2r:`@stp-ip` 80 | - `@stp-ip `_ 81 | - 2 82 | * - :raw-html-m2r:`@gtmanfred` 83 | - `@gtmanfred `_ 84 | - 2 85 | * - :raw-html-m2r:`@sylvainfaivre` 86 | - `@sylvainfaivre `_ 87 | - 1 88 | * - :raw-html-m2r:`@dependabot[bot]` 89 | - `@dependabot[bot] `_ 90 | - 1 91 | * - :raw-html-m2r:`@vquie` 92 | - `@vquie `_ 93 | - 1 94 | * - :raw-html-m2r:`@cp-richard` 95 | - `@cp-richard `_ 96 | - 1 97 | * - :raw-html-m2r:`@rhertzog` 98 | - `@rhertzog `_ 99 | - 1 100 | * - :raw-html-m2r:`@n-rodriguez` 101 | - `@n-rodriguez `_ 102 | - 1 103 | * - :raw-html-m2r:`@mgomersbach` 104 | - `@mgomersbach `_ 105 | - 1 106 | * - :raw-html-m2r:`@mschiff` 107 | - `@mschiff `_ 108 | - 1 109 | * - :raw-html-m2r:`@duk3luk3` 110 | - `@duk3luk3 `_ 111 | - 1 112 | * - :raw-html-m2r:`@techhat` 113 | - `@techhat `_ 114 | - 1 115 | * - :raw-html-m2r:`@holgerfischerone` 116 | - `@holgerfischerone `_ 117 | - 1 118 | * - :raw-html-m2r:`@pprkut` 119 | - `@pprkut `_ 120 | - 1 121 | * - :raw-html-m2r:`@fzipi` 122 | - `@fzipi `_ 123 | - 1 124 | * - :raw-html-m2r:`@feiming` 125 | - `@feiming `_ 126 | - 1 127 | * - :raw-html-m2r:`@baby-gnu` 128 | - `@baby-gnu `_ 129 | - 1 130 | * - :raw-html-m2r:`@campbellmc` 131 | - `@campbellmc `_ 132 | - 1 133 | * - :raw-html-m2r:`@asenci` 134 | - `@asenci `_ 135 | - 1 136 | 137 | 138 | ---- 139 | 140 | Auto-generated by a `forked version `_ of `gaocegege/maintainer `_ on 2025-04-10. 141 | -------------------------------------------------------------------------------- /pillar.example: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | postfix: 5 | manage_master_config: true 6 | master_config: 7 | # Preferred way of managing services/processes. This allows for finegrained 8 | # control over each service. See postfix/services.yaml for defaults that can 9 | # be overridden. 10 | services: 11 | smtp: 12 | # Limit to no more than 10 smtp processes 13 | maxproc: 10 14 | # Enable oldstyle TLS wrapped SMTP 15 | smtps: 16 | enable: true 17 | # Enable submission service on port 587/tcp with custom options 18 | submission: 19 | enable: true 20 | args: 21 | - "-o smtpd_tls_security_level=encrypt" 22 | - "-o smtpd_sasl_auth_enable=yes" 23 | - "-o smtpd_client_restrictions: permit_sasl_authenticated,reject" 24 | tlsproxy: 25 | enable: true 26 | chroot: true 27 | uucp: 28 | enable: true 29 | # Dovecot delivery via deliver binary. For better performance, investigate 30 | # using LMTP instead: 31 | dovecot: 32 | chroot: false 33 | command: pipe 34 | enable: true 35 | extras: '-d ${recipient}' 36 | flags: DRhu 37 | type: unix 38 | unpriv: false 39 | user: vmail:vmail 40 | argv: /usr/lib/dovecot/deliver 41 | # Completely customized mail-delivery-agent entry. Will be appended to the 42 | # master.cf file 43 | custom-mda: 44 | argv: /usr/local/sbin/mail-handler.py 45 | command: pipe 46 | extras: --rcpt ${recipient} 47 | flags: DRhu 48 | user: mail 49 | # Wrap the output in master.cf at 78 chars for better readability 50 | wrap: true 51 | # Avoid user and arvg settings to allow define internal processes 52 | # needed for randomizing relay IP (randmap functionality) 53 | no_args: true 54 | 55 | # Backwards compatible definition of dovecot delivery in master.cf 56 | enable_dovecot: false 57 | # The following are the default values: 58 | dovecot: 59 | user: vmail 60 | group: vmail 61 | flags: DRhu 62 | argv: "/usr/lib/dovecot/deliver" 63 | 64 | # Backwards compatible definition of submission listener in master.cf 65 | enable_submission: false 66 | # To replace the defaults use this: 67 | submission: 68 | smtpd_tls_security_level: encrypt 69 | smtpd_sasl_auth_enable: 'yes' 70 | smtpd_client_restrictions: permit_sasl_authenticated,reject 71 | 72 | enable_service: true 73 | reload_service: true 74 | 75 | postgrey: 76 | enabled: true 77 | enable_service: true 78 | location: inet:172.16.0.5:6379 79 | 80 | policyd-spf: 81 | enabled: true 82 | time_limit: 7200s 83 | 84 | config: 85 | smtpd_banner: $myhostname ESMTP $mail_name 86 | smtp_tls_CApath: /etc/ssl/certs 87 | biff: 'no' 88 | append_dot_mydomain: 'no' 89 | readme_directory: 'no' 90 | myhostname: localhost 91 | mydestination: localhost, localhost.localdomain 92 | relayhost: '' 93 | mynetworks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 94 | mailbox_size_limit: 0 95 | recipient_delimiter: + 96 | inet_interfaces: all 97 | inet_protocols: all 98 | 99 | # postsrsd: 100 | sender_canonical_maps: tcp:127.0.0.1:10001 101 | sender_canonical_classes: envelope_sender 102 | recipient_canonical_maps: tcp:127.0.0.1:10002 103 | recipient_canonical_classes: envelope_recipient 104 | 105 | # Alias 106 | alias_maps: hash:/etc/aliases 107 | # This is the list of files for the newaliases 108 | # cmd to process (see postconf(5) for details). 109 | # Only local hash/btree/dbm files: 110 | alias_database: hash:/etc/aliases 111 | 112 | # Virtual users 113 | virtual_alias_maps: proxy:mysql:/etc/postfix/virtual_alias_maps.cf 114 | virtual_mailbox_domains: proxy:mysql:/etc/postfix/virtual_mailbox_domains.cf 115 | virtual_mailbox_maps: proxy:mysql:/etc/postfix/virtual_mailbox_maps.cf 116 | virtual_mailbox_base: /home/vmail 117 | virtual_mailbox_limit: 512000000 118 | virtual_minimum_uid: 5000 119 | virtual_transport: virtual 120 | virtual_uid_maps: static:5000 121 | virtual_gid_maps: static:5000 122 | 123 | local_transport: virtual 124 | local_recipient_maps: $virtual_mailbox_maps 125 | # Use the `mapping` key to define the map 126 | transport_maps: hash:/etc/postfix/transport 127 | 128 | # SMTP server 129 | smtpd_tls_session_cache_database: btree:${data_directory}/smtpd_scache 130 | smtpd_use_tls: 'yes' 131 | smtpd_sasl_auth_enable: 'yes' 132 | smtpd_sasl_type: dovecot 133 | smtpd_sasl_path: /var/run/dovecot/auth-client 134 | smtpd_recipient_restrictions: >- 135 | permit_mynetworks, 136 | permit_sasl_authenticated, 137 | reject_unauth_destination 138 | smtpd_relay_restrictions: >- 139 | permit_mynetworks, 140 | permit_sasl_authenticated, 141 | reject_unauth_destination 142 | smtpd_sasl_security_options: noanonymous 143 | smtpd_sasl_tls_security_options: $smtpd_sasl_security_options 144 | smtpd_tls_auth_only: 'yes' 145 | smtpd_sasl_local_domain: $mydomain 146 | smtpd_tls_loglevel: 1 147 | smtpd_tls_session_cache_timeout: 3600s 148 | 149 | relay_domains: '$mydestination' 150 | 151 | # SMTP server certificate and key (from pillar data) 152 | smtpd_tls_cert_file: /etc/postfix/ssl/server-cert.crt 153 | smtpd_tls_key_file: /etc/postfix/ssl/server-cert.key 154 | 155 | # SMTP client 156 | smtp_tls_session_cache_database: btree:${data_directory}/smtp_scache 157 | smtp_use_tls: 'yes' 158 | smtp_tls_cert_file: /etc/postfix/ssl/example.com-relay-client-cert.crt 159 | smtp_tls_key_file: /etc/postfix/ssl/example.com-relay-client-cert.key 160 | smtp_tls_policy_maps: hash:/etc/postfix/tls_policy 161 | 162 | smtp_sasl_password_maps: hash:/etc/postfix/sasl_passwd 163 | sender_canonical_maps: hash:/etc/postfix/sender_canonical 164 | relay_recipient_maps: hash:/etc/postfix/relay_domains 165 | virtual_alias_maps: hash:/etc/postfix/virtual 166 | 167 | vmail: 168 | user: postfix_user 169 | password: DB_PASSWD 170 | hosts: DB_HOST 171 | dbname: postfix_db 172 | 173 | # add mysql query to virtual 174 | mysql: 175 | virtual_mailbox_domains: 176 | table: virtual_domains 177 | select_field: 1 178 | where_field: name 179 | virtual_alias_maps: 180 | table: virtual_aliases 181 | select_field: destination 182 | where_field: email 183 | virtual_mailbox_maps: 184 | table: virtual_users 185 | select_field: 1 186 | where_field: email 187 | 188 | aliases: 189 | # manage single aliases 190 | # this uses the aliases file defined in the minion config, /etc/aliases by default 191 | use_file: false 192 | present: 193 | root: info@example.com 194 | absent: 195 | - root 196 | 197 | # manage entire aliases file 198 | use_file: true 199 | content: | 200 | # Forward all local *nix users mail to our admins (via greedy regexp) 201 | /.+/ admins@example.com 202 | 203 | certificates: 204 | server-cert: 205 | public_cert: | 206 | -----BEGIN CERTIFICATE----- 207 | (Your primary SSL certificate: smtp.example.com.crt) 208 | -----END CERTIFICATE----- 209 | -----BEGIN CERTIFICATE----- 210 | (Your intermediate certificate: example-ca.crt) 211 | -----END CERTIFICATE----- 212 | -----BEGIN CERTIFICATE----- 213 | (Your root certificate: trusted-root.crt) 214 | -----END CERTIFICATE----- 215 | private_key: | 216 | -----BEGIN RSA PRIVATE KEY----- 217 | (Your Private key) 218 | -----END RSA PRIVATE KEY----- 219 | 220 | example.com-relay-client-cert: 221 | public_cert: | 222 | -----BEGIN CERTIFICATE----- 223 | (Your primary SSL certificate: smtp.example.com.crt) 224 | -----END CERTIFICATE----- 225 | private_key: | 226 | -----BEGIN RSA PRIVATE KEY----- 227 | (Your Private key) 228 | -----END RSA PRIVATE KEY----- 229 | 230 | mapping: 231 | transport_maps: 232 | - DOMAIN_NAME: ':[IP_ADDRESS]' 233 | 234 | smpt_tls_policy_maps: 235 | - example.com: encrypt 236 | - .example.com: encrypt 237 | 238 | smtp_sasl_password_maps: 239 | - smtp.example.com: myaccount:somepassword 240 | 241 | sender_canonical_maps: 242 | - root: servers@example.com 243 | - nagios: alerts@example.com 244 | 245 | relay_recipient_maps: 246 | - example.com: OK 247 | 248 | virtual_alias_maps: 249 | - groupaliasexample: 250 | - someuser_1@example.com 251 | - someuser_2@example.com 252 | - singlealiasexample: someuser_3@example.com 253 | 254 | 255 | ### 256 | # 257 | # Multiple virtual_alias_maps entries: 258 | # 259 | # You are free to define alternative mapping names 260 | # and use them as 'variables' in your Postfix config: 261 | # (Credit for the idea and the example goes to @roskens.) 262 | 263 | postfix: 264 | config: 265 | virtual_alias_maps: $virtual_alias_1_maps $virtual_alias_2_maps 266 | virtual_alias_1_maps: hash:/etc/postfix/virtual 267 | virtual_alias_2_maps: pcre:/etc/postfix/virtual.pcre 268 | mapping: 269 | virtual_alias_1_maps: 270 | root: 271 | - me 272 | virtual_alias_2_maps: 273 | - '/(\S+)_(devel|preprod|prod)@sub.example.com$/': '$(1)@$(2).sub.example.com' 274 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | --- 4 | ############################################################################### 5 | # Define all YAML node anchors 6 | ############################################################################### 7 | .node_anchors: 8 | # `only` (also used for `except` where applicable) 9 | only_branch_master_parent_repo: &only_branch_master_parent_repo 10 | - 'master@saltstack-formulas/postfix-formula' 11 | # `stage` 12 | stage_cache: &stage_cache 'cache' 13 | stage_lint: &stage_lint 'lint' 14 | stage_release: &stage_release 'release' 15 | stage_test: &stage_test 'test' 16 | # `image` 17 | # yamllint disable rule:line-length 18 | image_commitlint: &image_commitlint 'techneg/ci-commitlint:v1.1.116@sha256:98d5550565bb2563901005fd07aabfa5be206db38c4b195ffce44d297ae2b84c' 19 | image_dindruby: &image_dindruby 'techneg/ci-docker-python-ruby:v2.2.86@sha256:0939b6184329615704d51e984af490c2339cc1a31a5db0cef252684cc6b8f8ea' 20 | image_dindrubybionic: &image_dindrubybionic 'techneg/ci-docker-python-ruby:v2.2.86@sha256:0939b6184329615704d51e984af490c2339cc1a31a5db0cef252684cc6b8f8ea' 21 | image_precommit: &image_precommit 'techneg/ci-pre-commit:v2.5.19@sha256:64cb1f774a3d6abdd498f6be4b3dbe261f821e1dd088c00c23504f39d0c1cf03' 22 | image_rubocop: &image_rubocop 'pipelinecomponents/rubocop:latest@sha256:74850471782195453cdf91f4a5edf62b6fcc3365c124d4d975c7e87a702040d7' 23 | image_semantic-release: &image_semanticrelease 'techneg/ci-semantic-release:v1.2.17@sha256:4db8d4b3b1451131ce77bd857254de2f3c5579172955b2a6a2d4ec4326789196' 24 | # `services` 25 | services_docker_dind: &services_docker_dind 26 | - 'docker:29.1.1-dind@sha256:9b20eb23e1f0443655673efb9db76c4b18cc1b45de1fcf82b3c1b749b9647bdf' 27 | # yamllint enable rule:line-length 28 | # `variables` 29 | # https://forum.gitlab.com/t/gitlab-com-ci-caching-rubygems/5627/3 30 | # https://bundler.io/v2.3/man/bundle-config.1.html 31 | variables_bundler: &variables_bundler 32 | BUNDLE_PATH: '${CI_PROJECT_DIR}/.cache/bundler' 33 | BUNDLE_DEPLOYMENT: 'true' 34 | bundle_install: &bundle_install 35 | - 'bundle version' 36 | - 'bundle config list' 37 | # `--no-cache` means don't bother caching the downloaded .gem files 38 | - 'time bundle install --no-cache' 39 | cache_bundler: &cache_bundler 40 | key: 41 | files: 42 | - 'Gemfile.lock' 43 | prefix: 'bundler' 44 | paths: 45 | - '${BUNDLE_PATH}' 46 | # https://pre-commit.com/#gitlab-ci-example 47 | variables_pre-commit: &variables_pre-commit 48 | PRE_COMMIT_HOME: '${CI_PROJECT_DIR}/.cache/pre-commit' 49 | cache_pre-commit: &cache_pre-commit 50 | key: 51 | files: 52 | - '.pre-commit-config.yaml' 53 | prefix: 'pre-commit' 54 | paths: 55 | - '${PRE_COMMIT_HOME}' 56 | 57 | ############################################################################### 58 | # Define stages and global variables 59 | ############################################################################### 60 | stages: 61 | - *stage_cache 62 | - *stage_lint 63 | - *stage_test 64 | - *stage_release 65 | variables: 66 | DOCKER_DRIVER: 'overlay2' 67 | 68 | 69 | ############################################################################### 70 | # `cache` stage: build up the bundler cache required before the `test` stage 71 | ############################################################################### 72 | build-cache: 73 | stage: *stage_cache 74 | image: *image_dindruby 75 | variables: *variables_bundler 76 | cache: *cache_bundler 77 | script: *bundle_install 78 | 79 | ############################################################################### 80 | # `lint` stage: `commitlint`, `pre-commit` & `rubocop` (latest, failure allowed) 81 | ############################################################################### 82 | .lint_job: 83 | stage: *stage_lint 84 | needs: [] 85 | 86 | commitlint: 87 | extends: '.lint_job' 88 | image: *image_commitlint 89 | script: 90 | # Add `upstream` remote to get access to `upstream/master` 91 | - 'git remote add upstream 92 | https://gitlab.com/saltstack-formulas/postfix-formula.git' 93 | - 'git fetch --all' 94 | # Set default commit hashes for `--from` and `--to` 95 | - 'export COMMITLINT_FROM="$(git merge-base upstream/master HEAD)"' 96 | - 'export COMMITLINT_TO="${CI_COMMIT_SHA}"' 97 | # Run `commitlint` 98 | - 'commitlint --from "${COMMITLINT_FROM}" 99 | --to "${COMMITLINT_TO}" 100 | --verbose' 101 | 102 | pre-commit: 103 | extends: '.lint_job' 104 | image: *image_precommit 105 | # https://pre-commit.com/#gitlab-ci-example 106 | variables: *variables_pre-commit 107 | cache: *cache_pre-commit 108 | script: 109 | - 'pre-commit run --all-files --color always --verbose' 110 | - 'pre-commit run --color always --hook-stage manual commitlint-ci' 111 | 112 | # Use a separate job for `rubocop` other than the one potentially run by `pre-commit` 113 | # - The `pre-commit` check will only be available for formulas that pass the default 114 | # `rubocop` check -- and must continue to do so 115 | # - This job is allowed to fail, so can be used for all formulas 116 | # - Furthermore, this job uses all of the latest `rubocop` features & cops, 117 | # which will help when upgrading the `rubocop` linter used in `pre-commit` 118 | rubocop: 119 | extends: '.lint_job' 120 | allow_failure: true 121 | image: *image_rubocop 122 | script: 123 | - 'rubocop -d -P -S --enable-pending-cops' 124 | 125 | ############################################################################### 126 | # Define `test` template 127 | ############################################################################### 128 | .test_instance: &test_instance 129 | stage: *stage_test 130 | image: *image_dindruby 131 | services: *services_docker_dind 132 | variables: *variables_bundler 133 | cache: 134 | <<: *cache_bundler 135 | policy: 'pull' 136 | before_script: *bundle_install 137 | script: 138 | # Alternative value to consider: `${CI_JOB_NAME}` 139 | - 'bin/kitchen verify "${DOCKER_ENV_CI_JOB_NAME}"' 140 | 141 | ############################################################################### 142 | # Define `test` template (`allow_failure: true`) 143 | ############################################################################### 144 | .test_instance_failure_permitted: 145 | <<: *test_instance 146 | allow_failure: true 147 | 148 | ############################################################################### 149 | # `test` stage: each instance below uses the `test` template above 150 | ############################################################################### 151 | ## Define the rest of the matrix based on Kitchen testing 152 | # Make sure the instances listed below match up with 153 | # the `platforms` defined in `kitchen.yml` 154 | # yamllint disable rule:line-length 155 | # Fedora 41+ will permit failure until this PR is merged into kitchen-docker 156 | # https://github.com/test-kitchen/kitchen-docker/pull/427 is merged 157 | # OpenSUSE master branch will fail until zypperpkg module is back in salt core 158 | # https://github.com/saltstack/great-module-migration/issues/14 159 | # 160 | # The alias states were removed in the great module migration, causing the 161 | # tests to fail with Salt master branch 162 | # See https://github.com/saltstack-formulas/postfix-formula/issues/134 163 | almalinux-9-master: {extends: '.test_instance_failure_permitted'} 164 | almalinux-8-master: {extends: '.test_instance_failure_permitted'} 165 | amazonlinux-2023-master: {extends: '.test_instance_failure_permitted'} 166 | amazonlinux-2-master: {extends: '.test_instance_failure_permitted'} 167 | centos-stream9-master: {extends: '.test_instance_failure_permitted'} 168 | debian-12-master: {extends: '.test_instance_failure_permitted'} 169 | debian-11-master: {extends: '.test_instance_failure_permitted'} 170 | fedora-41-master: {extends: '.test_instance_failure_permitted'} 171 | fedora-40-master: {extends: '.test_instance_failure_permitted'} 172 | opensuse-leap-156-master: {extends: '.test_instance_failure_permitted'} 173 | opensuse-tmbl-latest-master: {extends: '.test_instance_failure_permitted'} 174 | oraclelinux-9-master: {extends: '.test_instance_failure_permitted'} 175 | oraclelinux-8-master: {extends: '.test_instance_failure_permitted'} 176 | rockylinux-9-master: {extends: '.test_instance_failure_permitted'} 177 | rockylinux-8-master: {extends: '.test_instance_failure_permitted'} 178 | ubuntu-2404-master: {extends: '.test_instance_failure_permitted'} 179 | ubuntu-2204-master: {extends: '.test_instance_failure_permitted'} 180 | ubuntu-2004-master: {extends: '.test_instance_failure_permitted'} 181 | almalinux-9-3007: {extends: '.test_instance'} 182 | almalinux-8-3007: {extends: '.test_instance'} 183 | amazonlinux-2023-3007: {extends: '.test_instance'} 184 | amazonlinux-2-3007: {extends: '.test_instance_failure_permitted'} 185 | centos-stream9-3007: {extends: '.test_instance'} 186 | debian-12-3007: {extends: '.test_instance'} 187 | debian-11-3007: {extends: '.test_instance'} 188 | fedora-41-3007: {extends: '.test_instance_failure_permitted'} 189 | fedora-40-3007: {extends: '.test_instance'} 190 | opensuse-leap-156-3007: {extends: '.test_instance'} 191 | opensuse-tmbl-latest-3007: {extends: '.test_instance'} 192 | oraclelinux-9-3007: {extends: '.test_instance'} 193 | oraclelinux-8-3007: {extends: '.test_instance'} 194 | rockylinux-9-3007: {extends: '.test_instance'} 195 | rockylinux-8-3007: {extends: '.test_instance'} 196 | ubuntu-2404-3007: {extends: '.test_instance'} 197 | ubuntu-2204-3007: {extends: '.test_instance'} 198 | ubuntu-2004-3007: {extends: '.test_instance'} 199 | almalinux-9-3006: {extends: '.test_instance'} 200 | almalinux-8-3006: {extends: '.test_instance'} 201 | amazonlinux-2023-3006: {extends: '.test_instance'} 202 | amazonlinux-2-3006: {extends: '.test_instance_failure_permitted'} 203 | centos-stream9-3006: {extends: '.test_instance'} 204 | debian-12-3006: {extends: '.test_instance'} 205 | debian-11-3006: {extends: '.test_instance'} 206 | fedora-41-3006: {extends: '.test_instance_failure_permitted'} 207 | fedora-40-3006: {extends: '.test_instance'} 208 | opensuse-leap-156-3006: {extends: '.test_instance'} 209 | opensuse-tmbl-latest-3006: {extends: '.test_instance'} 210 | oraclelinux-9-3006: {extends: '.test_instance'} 211 | oraclelinux-8-3006: {extends: '.test_instance'} 212 | rockylinux-9-3006: {extends: '.test_instance'} 213 | rockylinux-8-3006: {extends: '.test_instance'} 214 | ubuntu-2404-3006: {extends: '.test_instance'} 215 | ubuntu-2204-3006: {extends: '.test_instance'} 216 | ubuntu-2004-3006: {extends: '.test_instance'} 217 | # yamllint enable rule:line-length 218 | 219 | ############################################################################### 220 | # `release` stage: `semantic-release` 221 | ############################################################################### 222 | semantic-release: 223 | stage: *stage_release 224 | image: *image_semanticrelease 225 | variables: 226 | MAINTAINER_TOKEN: '${GH_TOKEN}' 227 | script: 228 | # Run `semantic-release` 229 | - 'semantic-release' 230 | -------------------------------------------------------------------------------- /postfix/files/master.cf: -------------------------------------------------------------------------------- 1 | {%- set master_config = salt['pillar.get']('postfix:master_config', {}) -%} 2 | {#- 3 | # Handle the case that the pillar data does not provide any service 4 | # configuration but submission parameters are provided in the pillar. 5 | # This is important for backwards compatibility with sites that are using 6 | # the previous enable_submission pillar settings. 7 | -#} 8 | {%- set additional_services = {} -%} 9 | {%- if master_config.get('enable_submission', False) and not salt[ 10 | 'pillar.get']('postfix:master_config:services:submission', False) -%} 11 | {%- do additional_services.update({'submission': {'chroot': False, 12 | 'command': 'smtpd', 13 | 'enable': True, 14 | 'type': 'inet', 15 | 'args': [], 16 | 'private': False}}) -%} 17 | {%- if master_config.get('submission', False) -%} 18 | {%- for parameter, value in master_config.get('submission', {}).items() -%} 19 | {%- if value is number or value is string -%} 20 | {%- do additional_services['submission']['args'].append('-o %s=%s' % ( 21 | parameter, value)) -%} 22 | {%- elif value is iterable -%} 23 | {%- do additional_services['submission']['args'].append('-o %s=%s' % ( 24 | parameter, ','.join(value))) -%} 25 | {%- endif -%} 26 | {%- endfor -%} 27 | {%- else -%} 28 | {%- do additional_services[ 29 | 'submission']['args'].extend(['# -o syslog_name=postfix/submission', 30 | '-o smtpd_tls_security_level=encrypt', 31 | '-o smtpd_sasl_auth_enable=yes', 32 | '# -o smtpd_reject_unlisted_recipient=no', 33 | '# -o smtpd_client_restrictions=$mua_client_restrictions', 34 | '# -o smtpd_helo_restrictions=$mua_helo_restrictions', 35 | '# -o smtpd_sender_restrictions=$mua_sender_restrictions', 36 | '# -o smtpd_recipient_restrictions=', 37 | '# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject', 38 | '# -o milter_macro_daemon_name=ORIGINATING' 39 | ]) -%} 40 | {%- endif -%} 41 | {%- endif -%} 42 | 43 | {#- Format the postfix service parameters correctly -#} 44 | {%- macro service_param(service, service_name, parameter_name, default='-') -%} 45 | {#- Fetch the value from the passed service dictionary or fall back to the 46 | # service defaults by chaining .get() commands. #} 47 | {%- set value = service.get(parameter_name, 48 | postfix_master_services.defaults[service_name].get( 49 | parameter_name, default)) -%} 50 | {%- if value is sameas false -%} 51 | n 52 | {%- elif value is sameas true -%} 53 | y 54 | {%- elif value is number or value is string -%} 55 | {{ value }} 56 | {%- else -%} 57 | - 58 | {%- endif -%} 59 | {%- endmacro -%} 60 | 61 | # 62 | # This file is managed by salt. 63 | # Modify the salt pillar in the postfix formula that generates this file instead. 64 | # 65 | # Postfix master process configuration file. For details on the format 66 | # of the file, see the master(5) manual page (command: "man 5 master" or 67 | # on-line: http://www.postfix.org/master.5.html). 68 | # 69 | # Do not forget to execute "postfix reload" after editing this file. 70 | # 71 | # ========================================================================== 72 | # service type private unpriv chroot wakeup maxproc command + args 73 | # (yes) (yes) (no) (never) (100) 74 | # ========================================================================== 75 | {%- for service_name in postfix_master_services.order %} 76 | {#- Try to get the service configuration from the pillar if present. 77 | # Next try if the service has been dynamically configured and is present in 78 | # the additional_services dictionary. 79 | # If absent, fall back to the defaults provided in services.jinja -#} 80 | {%- set service = salt['pillar.get']('postfix:master_config:services:%s' % ( 81 | service_name,), 82 | additional_services.get(service_name, 83 | postfix_master_services.defaults[service_name])) -%} 84 | {%- if service.get('enable', True) -%} 85 | {%- set comment = '' -%} 86 | {%- else -%} 87 | {%- set comment = '#' -%} 88 | {%- endif %} 89 | {{ "%s%-9s %-5s %-7s %-7s %-7s %-7s %-7s %s" | format(comment, 90 | service_param(service, service_name, 'service', service_name), 91 | service_param(service, service_name, 'type'), 92 | service_param(service, service_name, 'private'), 93 | service_param(service, service_name, 'unpriv'), 94 | service_param(service, service_name, 'chroot'), 95 | service_param(service, service_name, 'wakeup'), 96 | service_param(service, service_name, 'maxproc'), 97 | service_param(service, service_name, 'command', service_name)) -}} 98 | {%- if service.args is not none -%} 99 | {%- for option in service.get('args', postfix_master_services.defaults[ 100 | service_name].get('args', [])) -%} 101 | {%- if option.startswith('#') %} 102 | {{ option }} 103 | {%- else %} 104 | {{ comment }} {{ option }} 105 | {%- endif %} 106 | {%- endfor %} 107 | {%- endif %} 108 | {%- endfor %} 109 | # 110 | {%- set handled_extra_services = [] -%} 111 | {%- macro extra_service(service_name, wrap=False) -%} 112 | {%- do handled_extra_services.append(service_name) -%} 113 | {%- set service = salt['pillar.get']('postfix:master_config:services:%s' % ( 114 | service_name,), 115 | postfix_master_services.defaults[service_name]) -%} 116 | {%- if service.get('enable', True) -%} 117 | {%- set comment = '' -%} 118 | {%- else -%} 119 | {%- set comment = '#' -%} 120 | {%- endif -%} 121 | {{ "%s%-9s %-5s %-7s %-7s %-7s %-7s %-7s %s" | format(comment, 122 | service_param(service, service_name, 'service', service_name), 123 | service_param(service, service_name, 'type'), 124 | service_param(service, service_name, 'private'), 125 | service_param(service, service_name, 'unpriv'), 126 | service_param(service, service_name, 'chroot'), 127 | service_param(service, service_name, 'wakeup'), 128 | service_param(service, service_name, 'maxproc'), 129 | service_param(service, service_name, 'command', service_name)) }} 130 | {%- if 'no_args' in service -%} 131 | {%- set parameter_str = "%s %s" | format(comment,service_param(service, service_name, 'extras', '')) -%} 132 | {%- else -%} 133 | {%- if 'flags' in service or 'flags' in postfix_master_services.defaults[service_name] -%} 134 | {%- set parameter_str = "%s flags=%s user=%s argv=%s %s" | format(comment, 135 | service_param(service, service_name, 'flags'), 136 | service_param(service, service_name, 'user'), 137 | service_param(service, service_name, 'argv'), 138 | service_param(service, service_name, 'extras', '')) -%} 139 | {%- else -%} 140 | {%- set parameter_str = "%s user=%s argv=%s %s" | format(comment, 141 | service_param(service, service_name, 'user'), 142 | service_param(service, service_name, 'argv'), 143 | service_param(service, service_name, 'extras', '')) -%} 144 | {%- endif -%} 145 | {%- endif -%}{# if 'no_args' in service #} 146 | {%- if wrap %} 147 | {{ parameter_str | wordwrap(width=wrap, break_long_words=False, wrapstring='\n%s ' | format(comment)) }} 148 | {%- else %} 149 | {{ parameter_str }} 150 | {%- endif -%} 151 | {%- endmacro -%} 152 | 153 | {#- Handle legacy configuration of services for backwards compatibility 154 | by extending the services dictionary accordingly #} 155 | {%- if salt['pillar.get']('postfix:policyd-spf:enabled', False) %} 156 | {%- do postfix_master_services.defaults.update({'policy-spf': { 157 | 'command': 'spawn', 158 | 'chroot': False, 159 | 'enable': True, 160 | 'type': 'unix', 161 | 'unpriv': False, 162 | 'user': 'nobody', 163 | 'argv': '%s/bin/policyd-spf' | format(postfix.xbin_prefix)}}) %} 164 | {%- endif %} 165 | {%- if master_config.get('enable_dovecot', False) -%} 166 | {%- set dovecot = master_config.get('dovecot', {} )%} 167 | {%- do postfix_master_services.defaults.update({'dovecot': { 168 | 'command': 'pipe', 169 | 'chroot': False, 170 | 'enable': True, 171 | 'extras': '-d ${recipient}', 172 | 'flags': dovecot.get('flags', 'DRhu'), 173 | 'type': 'unix', 174 | 'unpriv': False, 175 | 'user': '%s:%s' | format(dovecot.get('user', 'vmail'), dovecot.get('group', 'vmail')), 176 | 'argv': dovecot.get('argv', postfix.dovecot_deliver) }}) %} 177 | {%- endif %} 178 | # ==================================================================== 179 | # Interfaces to non-Postfix software. Be sure to examine the manual 180 | # pages of the non-Postfix software to find out what options it wants. 181 | # 182 | # Many of the following services use the Postfix pipe(8) delivery 183 | # agent. See the pipe(8) man page for information about ${recipient} 184 | # and other message envelope options. 185 | # ==================================================================== 186 | # 187 | # maildrop. See the Postfix MAILDROP_README file for details. 188 | # Also specify in main.cf: maildrop_destination_recipient_limit=1 189 | # 190 | {{ extra_service('maildrop') }} 191 | # 192 | # ==================================================================== 193 | # 194 | # Recent Cyrus versions can use the existing "lmtp" master.cf entry. 195 | # 196 | # Specify in cyrus.conf: 197 | # lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 198 | # 199 | # Specify in main.cf one or more of the following: 200 | # mailbox_transport = lmtp:inet:localhost 201 | # virtual_transport = lmtp:inet:localhost 202 | # 203 | # ==================================================================== 204 | # 205 | # Cyrus 2.1.5 (Amos Gouaux) 206 | # Also specify in main.cf: cyrus_destination_recipient_limit=1 207 | # 208 | {{ extra_service('cyrus') }} 209 | # 210 | # ==================================================================== 211 | # 212 | # Old example of delivery via Cyrus. 213 | # 214 | {{ extra_service('old-cyrus') }} 215 | # 216 | # ==================================================================== 217 | # 218 | # See the Postfix UUCP_README file for configuration details. 219 | # 220 | {{ extra_service('uucp') }} 221 | # 222 | # ==================================================================== 223 | # 224 | # Other external delivery methods. 225 | # 226 | {{ extra_service('ifmail') }} 227 | # 228 | {{ extra_service('bsmtp') }} 229 | # 230 | {{ extra_service('scalemail-backend', 79) }} 231 | # 232 | {{ extra_service('mailman', 79) }} 233 | {#- Handle custom services configured as pillars by extending the services 234 | dictionary for all defined services that have not been otherwise be 235 | handled yet. -#} 236 | {%- for service in salt['pillar.get']('postfix:master_config:services', []) if not service in handled_extra_services -%} 237 | {%- do postfix_master_services.defaults.update({service: salt['pillar.get']('postfix:master_config:services:%s' % (service,))}) -%} 238 | {%- endfor -%} 239 | {%- for service in postfix_master_services.defaults if not service in handled_extra_services and not service in postfix_master_services.order %} 240 | # 241 | {%- if postfix_master_services.defaults[service].get('wrap', False) %} 242 | {{ extra_service(service, 78) }} 243 | {%- else %} 244 | {{ extra_service(service) }} 245 | {%- endif %} 246 | {%- endfor %} 247 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.3](https://github.com/saltstack-formulas/postfix-formula/compare/v2.0.2...v2.0.3) (2025-04-10) 4 | 5 | 6 | ### Continuous Integration 7 | 8 | * update `pre-commit` configuration inc. for pre-commit.ci [skip ci] ([02e4fb9](https://github.com/saltstack-formulas/postfix-formula/commit/02e4fb91be51bcb3e05f1580aca2a706f4ad17fb)) 9 | * use latest test images ([c48cf63](https://github.com/saltstack-formulas/postfix-formula/commit/c48cf63e5acf2e926dae648b7fb17e55b48a78cd)) 10 | * **kitchen+gitlab:** update for new pre-salted images [skip ci] ([b4b0893](https://github.com/saltstack-formulas/postfix-formula/commit/b4b0893b1191714866e4b1bf7ff22f76d90fadc2)) 11 | 12 | 13 | ### Tests 14 | 15 | * **system:** add `build_platform_codename` [skip ci] ([0d68789](https://github.com/saltstack-formulas/postfix-formula/commit/0d68789640710b01cafff00d60047d161d3cc111)) 16 | * **system.rb:** add support for `mac_os_x` [skip ci] ([842a109](https://github.com/saltstack-formulas/postfix-formula/commit/842a10935d3fc116ae9cb09b000e208c25f6ceef)) 17 | 18 | ## [2.0.2](https://github.com/saltstack-formulas/postfix-formula/compare/v2.0.1...v2.0.2) (2022-02-13) 19 | 20 | 21 | ### Code Refactoring 22 | 23 | * **salt-lint:** fix violations ([6a33d98](https://github.com/saltstack-formulas/postfix-formula/commit/6a33d98d75b7cbce3fa735f9e2c4071da0ce0355)) 24 | 25 | 26 | ### Continuous Integration 27 | 28 | * update linters to latest versions [skip ci] ([62eb687](https://github.com/saltstack-formulas/postfix-formula/commit/62eb687b052a31bc395f53dd9c8259ff643b449e)) 29 | * **gemfile:** allow rubygems proxy to be provided as an env var [skip ci] ([5d167a4](https://github.com/saltstack-formulas/postfix-formula/commit/5d167a403c253e3b9f6c68641e0b871d287d2662)) 30 | * **kitchen+gitlab:** update for new pre-salted images [skip ci] ([008ac83](https://github.com/saltstack-formulas/postfix-formula/commit/008ac83c7a95dc1d29ee388f0d634ff3bd9b0320)) 31 | 32 | ## [2.0.1](https://github.com/saltstack-formulas/postfix-formula/compare/v2.0.0...v2.0.1) (2022-01-25) 33 | 34 | 35 | ### Bug Fixes 36 | 37 | * **config:** set default_database_type; fixes [#118](https://github.com/saltstack-formulas/postfix-formula/issues/118) ([3bd3d1c](https://github.com/saltstack-formulas/postfix-formula/commit/3bd3d1c74e6dd60a984a3f790b8c50fa46ea2ed6)) 38 | 39 | 40 | ### Code Refactoring 41 | 42 | * **config:** add `default_database_type` as default value ([6da70d2](https://github.com/saltstack-formulas/postfix-formula/commit/6da70d21bbfbf613e6f0149c757c5e628ef227fb)) 43 | 44 | 45 | ### Continuous Integration 46 | 47 | * **3003.1:** update inc. AlmaLinux, Rocky & `rst-lint` [skip ci] ([3284d38](https://github.com/saltstack-formulas/postfix-formula/commit/3284d38a367d94ef57c57e88dd6698c88b0affd2)) 48 | * **gemfile+lock:** use `ssf` customised `inspec` repo [skip ci] ([cfed974](https://github.com/saltstack-formulas/postfix-formula/commit/cfed97400047b109a765d5cee95667f6ca1c1fd2)) 49 | * **kitchen:** move `provisioner` block & update `run_command` [skip ci] ([31a3836](https://github.com/saltstack-formulas/postfix-formula/commit/31a3836cd63f09d81ad88f510b61cb831436759c)) 50 | * **kitchen+ci:** update with `3004` pre-salted images/boxes [skip ci] ([dec042a](https://github.com/saltstack-formulas/postfix-formula/commit/dec042aa43e71785bc49247002a16d82af8c1531)) 51 | * **kitchen+ci:** update with latest `3003.2` pre-salted images [skip ci] ([9688f36](https://github.com/saltstack-formulas/postfix-formula/commit/9688f36aa146d584546da71fa89e04525c08aa42)) 52 | * **kitchen+ci:** update with latest CVE pre-salted images [skip ci] ([76134b4](https://github.com/saltstack-formulas/postfix-formula/commit/76134b47c70d98d00dfe1e6d0f3c9cc0095bda69)) 53 | * add `arch-master` to matrix and update `.travis.yml` [skip ci] ([c631eca](https://github.com/saltstack-formulas/postfix-formula/commit/c631eca02e2c1c03e38bcd179c9b443c22ce706d)) 54 | * add Debian 11 Bullseye & update `yamllint` configuration [skip ci] ([c11c07d](https://github.com/saltstack-formulas/postfix-formula/commit/c11c07d6a664da11f11c22ddd416d0501a2cb07e)) 55 | * **kitchen+gitlab:** adjust matrix to add `3003` [skip ci] ([04564a7](https://github.com/saltstack-formulas/postfix-formula/commit/04564a7ad6c803f70cfa487acd92dd1197563469)) 56 | * **kitchen+gitlab:** remove Ubuntu 16.04 & Fedora 32 (EOL) [skip ci] ([d56006f](https://github.com/saltstack-formulas/postfix-formula/commit/d56006f8d2dac568c06c4e1e83b076acfe49a80c)) 57 | 58 | 59 | ### Tests 60 | 61 | * standardise use of `share` suite & `_mapdata` state [skip ci] ([4c394a7](https://github.com/saltstack-formulas/postfix-formula/commit/4c394a76faea4301df4708854edd39d37a13935d)) 62 | 63 | # [2.0.0](https://github.com/saltstack-formulas/postfix-formula/compare/v1.2.2...v2.0.0) (2021-03-15) 64 | 65 | 66 | ### Bug Fixes 67 | 68 | * **resources:** make resources' IDs unique ([03ad48b](https://github.com/saltstack-formulas/postfix-formula/commit/03ad48b8a4b0b05144d449c9caee998ad6d0628f)) 69 | 70 | 71 | ### Continuous Integration 72 | 73 | * **commitlint:** ensure `upstream/master` uses main repo URL [skip ci] ([381b150](https://github.com/saltstack-formulas/postfix-formula/commit/381b150b0f1d0ab41e60f0ac95a7a6163633d701)) 74 | * **gemfile+lock:** use `ssf` customised `kitchen-docker` repo [skip ci] ([c5851e6](https://github.com/saltstack-formulas/postfix-formula/commit/c5851e67a2125c5367b3ab97b46c6407aa66eaf1)) 75 | * **gitlab-ci:** add `rubocop` linter (with `allow_failure`) [skip ci] ([22fa184](https://github.com/saltstack-formulas/postfix-formula/commit/22fa184b14e88a05d4c4284c459a7d887501e404)) 76 | * **gitlab-ci:** use GitLab CI as Travis CI replacement ([890f3ae](https://github.com/saltstack-formulas/postfix-formula/commit/890f3aebc63484d07f887c870f2825797ba504e9)) 77 | * **kitchen+ci:** use latest pre-salted images (after CVE) [skip ci] ([19617a0](https://github.com/saltstack-formulas/postfix-formula/commit/19617a0ad710914c8f4439044d7bf993e1effcc8)) 78 | * **kitchen+gitlab-ci:** use latest pre-salted images [skip ci] ([d65a7a3](https://github.com/saltstack-formulas/postfix-formula/commit/d65a7a36c28e3881b058e9c5b898a0f39c5e1ca7)) 79 | * **pre-commit:** add to formula [skip ci] ([f41392d](https://github.com/saltstack-formulas/postfix-formula/commit/f41392d4504cb60b2fcf2c818cfe97f5487e2844)) 80 | * **pre-commit:** enable/disable `rstcheck` as relevant [skip ci] ([fb5be95](https://github.com/saltstack-formulas/postfix-formula/commit/fb5be9504ec18c86bab4f387bf62ba816b3ffa64)) 81 | * **pre-commit:** finalise `rstcheck` configuration [skip ci] ([75941ed](https://github.com/saltstack-formulas/postfix-formula/commit/75941ed61443c84c27fea864d0529461564d8969)) 82 | * **pre-commit:** update hook for `rubocop` [skip ci] ([c60d58e](https://github.com/saltstack-formulas/postfix-formula/commit/c60d58eb1168c031c12d656c9605f83afebc9fa1)) 83 | 84 | 85 | ### BREAKING CHANGES 86 | 87 | * **resources:** as all resources' IDs changed, other formulas 88 | depending on this formula's resources will need to be modified 89 | accordingly. 90 | 91 | ## [1.2.2](https://github.com/saltstack-formulas/postfix-formula/compare/v1.2.1...v1.2.2) (2020-10-02) 92 | 93 | 94 | ### Styles 95 | 96 | * prepend modes with 0 ([fdc127c](https://github.com/saltstack-formulas/postfix-formula/commit/fdc127c8db7b19fac9be907ca511b17d5f5c4be0)) 97 | * quote modes/numbers ([b9c4fba](https://github.com/saltstack-formulas/postfix-formula/commit/b9c4fbadaf164c1589a27af45fbde7092e6a1d8a)) 98 | 99 | ## [1.2.1](https://github.com/saltstack-formulas/postfix-formula/compare/v1.2.0...v1.2.1) (2020-09-27) 100 | 101 | 102 | ### Styles 103 | 104 | * linting for `yamllint` ([780dc9d](https://github.com/saltstack-formulas/postfix-formula/commit/780dc9d372328f0b7ae08425abf1e1f32ed4b49e)) 105 | 106 | # [1.2.0](https://github.com/saltstack-formulas/postfix-formula/compare/v1.1.0...v1.2.0) (2020-07-20) 107 | 108 | 109 | ### Features 110 | 111 | * **maps:** add more map types and tests ([e3970df](https://github.com/saltstack-formulas/postfix-formula/commit/e3970dfc3eac57b7a4f8911ef48d8652f3a26cd7)) 112 | 113 | # [1.1.0](https://github.com/saltstack-formulas/postfix-formula/compare/v1.0.3...v1.1.0) (2020-07-18) 114 | 115 | 116 | ### Continuous Integration 117 | 118 | * **kitchen:** use `saltimages` Docker Hub where available [skip ci] ([2ddd417](https://github.com/saltstack-formulas/postfix-formula/commit/2ddd417039d8cb6f8241036c60ee0e6d534aab00)) 119 | 120 | 121 | ### Features 122 | 123 | * **config:** run postmap also for regexp maps ([7584fce](https://github.com/saltstack-formulas/postfix-formula/commit/7584fce0aff912b3aeaf44e6eed82a4c9c267535)) 124 | 125 | ## [1.0.3](https://github.com/saltstack-formulas/postfix-formula/compare/v1.0.2...v1.0.3) (2020-06-08) 126 | 127 | 128 | ### Bug Fixes 129 | 130 | * **deps:** fixes ordering where postmap requires sane main.cf ([a28bd05](https://github.com/saltstack-formulas/postfix-formula/commit/a28bd05b852c309e70aa8ff0491c12271ddd4461)) 131 | * **test:** use specific ip to workaround centos bug ([273caf9](https://github.com/saltstack-formulas/postfix-formula/commit/273caf9b6f42a4127025f9d2d862806653b661c2)) 132 | 133 | 134 | ### Tests 135 | 136 | * **default:** add inspec for base and maps ([2a61498](https://github.com/saltstack-formulas/postfix-formula/commit/2a61498fa440b2eef26849c2b0bc2dadf27b2dee)) 137 | 138 | ## [1.0.2](https://github.com/saltstack-formulas/postfix-formula/compare/v1.0.1...v1.0.2) (2020-06-07) 139 | 140 | 141 | ### Bug Fixes 142 | 143 | * **opensuse:** fixes config files generation in opensuse ([067bcf6](https://github.com/saltstack-formulas/postfix-formula/commit/067bcf636face6b3a3cb40418758641354ac2402)) 144 | 145 | ## [1.0.1](https://github.com/saltstack-formulas/postfix-formula/compare/v1.0.0...v1.0.1) (2020-06-07) 146 | 147 | 148 | ### Bug Fixes 149 | 150 | * **main:** fix postconf warning when reloading/starting ([04003c6](https://github.com/saltstack-formulas/postfix-formula/commit/04003c6ee33d5699cc392f7e74f81d27547b5f6e)) 151 | 152 | # [1.0.0](https://github.com/saltstack-formulas/postfix-formula/compare/v0.19.0...v1.0.0) (2020-06-06) 153 | 154 | 155 | ### Code Refactoring 156 | 157 | * **maps:** move tls_policy and transport to mapping section ([06276fd](https://github.com/saltstack-formulas/postfix-formula/commit/06276fd7431e1675795be95c0c8ebb01772ea740)) 158 | 159 | 160 | ### Continuous Integration 161 | 162 | * **kitchen+travis:** use latest pre-salted images ([b364744](https://github.com/saltstack-formulas/postfix-formula/commit/b364744e40b484397fea5c2c1767f77728649de8)) 163 | 164 | 165 | ### BREAKING CHANGES 166 | 167 | * **maps:** `transport` and `tls_policy` keys in `postfix:config` have been moved to the standard `postfix:mapping`. 168 | 169 | # [0.19.0](https://github.com/saltstack-formulas/postfix-formula/compare/v0.18.2...v0.19.0) (2020-05-23) 170 | 171 | 172 | ### Continuous Integration 173 | 174 | * **travis:** add notifications => zulip [skip ci] ([c78c421](https://github.com/saltstack-formulas/postfix-formula/commit/c78c4219846f8c384623da7dd74d4e9a5e419b74)) 175 | 176 | 177 | ### Features 178 | 179 | * **maps:** adds tls_policy map for smtp delivery ([d87da4a](https://github.com/saltstack-formulas/postfix-formula/commit/d87da4adc49d18674f35e40a948ad88fefaf26f6)) 180 | 181 | ## [0.18.2](https://github.com/saltstack-formulas/postfix-formula/compare/v0.18.1...v0.18.2) (2020-05-12) 182 | 183 | 184 | ### Bug Fixes 185 | 186 | * make necessary modifications to get working on `salt-ssh` ([34a112f](https://github.com/saltstack-formulas/postfix-formula/commit/34a112faabba46d95b102afa3add5b797dda2ce1)), closes [/freenode.logbot.info/saltstack-formulas/20200507#c3819526-c3819581](https://github.com//freenode.logbot.info/saltstack-formulas/20200507/issues/c3819526-c3819581) [/freenode.logbot.info/saltstack-formulas/20200508#c3826763-c3826995](https://github.com//freenode.logbot.info/saltstack-formulas/20200508/issues/c3826763-c3826995) 187 | * **release.config.js:** use full commit hash in commit link [skip ci] ([ffbe5aa](https://github.com/saltstack-formulas/postfix-formula/commit/ffbe5aad13e73a4e3aa1c6dbd24488ebd73436ee)) 188 | 189 | 190 | ### Continuous Integration 191 | 192 | * **gemfile:** restrict `train` gem version until upstream fix [skip ci] ([80cdd9d](https://github.com/saltstack-formulas/postfix-formula/commit/80cdd9d202b6dbbc43aa02025bb7d9738aad8ee7)) 193 | * **gemfile.lock:** add to repo with updated `Gemfile` [skip ci] ([497221d](https://github.com/saltstack-formulas/postfix-formula/commit/497221d1de7356cb031f78597781fa05897ca0a9)) 194 | * **kitchen:** avoid using bootstrap for `master` instances [skip ci] ([708b0a5](https://github.com/saltstack-formulas/postfix-formula/commit/708b0a51d9378ef44c0df125f532deea44f07044)) 195 | * **kitchen:** use `debian-10-master-py3` instead of `develop` [skip ci] ([90098c0](https://github.com/saltstack-formulas/postfix-formula/commit/90098c0cdfa856f9e3ca7772e8fb52e014d70d55)) 196 | * **kitchen:** use `develop` image until `master` is ready (`amazonlinux`) [skip ci] ([df76c72](https://github.com/saltstack-formulas/postfix-formula/commit/df76c72dcee4ff87f104b13880ddc32b163e2db6)) 197 | * **kitchen+travis:** remove `master-py2-arch-base-latest` [skip ci] ([46d0f3d](https://github.com/saltstack-formulas/postfix-formula/commit/46d0f3d1d8b9b7373068c9182a593c8ed96e1bcd)) 198 | * **kitchen+travis:** upgrade matrix after `2019.2.2` release [skip ci] ([70fc491](https://github.com/saltstack-formulas/postfix-formula/commit/70fc49122ed6213a4e93fc5280bf5744af969f86)) 199 | * **travis:** apply changes from build config validation [skip ci] ([f25db2d](https://github.com/saltstack-formulas/postfix-formula/commit/f25db2d5f3c2394e29f36cf33d2166c5af73fa40)) 200 | * **travis:** opt-in to `dpl v2` to complete build config validation [skip ci] ([8f4db70](https://github.com/saltstack-formulas/postfix-formula/commit/8f4db70ece851dea547550cfabb4b770eaf0796b)) 201 | * **travis:** quote pathspecs used with `git ls-files` [skip ci] ([6d18d1d](https://github.com/saltstack-formulas/postfix-formula/commit/6d18d1dc93c92c4ba85f340c541d3a69f557d74e)) 202 | * **travis:** run `shellcheck` during lint job [skip ci] ([29efb81](https://github.com/saltstack-formulas/postfix-formula/commit/29efb819fc9d4bf273b57c15d01dfb390642b3d5)) 203 | * **travis:** update `salt-lint` config for `v0.0.10` [skip ci] ([b23168e](https://github.com/saltstack-formulas/postfix-formula/commit/b23168e69ec8823ad9382b6c9c3be8f743d3b8e3)) 204 | * **travis:** use `major.minor` for `semantic-release` version [skip ci] ([964e3ef](https://github.com/saltstack-formulas/postfix-formula/commit/964e3ef0fa6613380c56b1b2044e6f37dd797c6c)) 205 | * **travis:** use build config validation (beta) [skip ci] ([1ab8692](https://github.com/saltstack-formulas/postfix-formula/commit/1ab8692f31bdfcf5a24d7049c254d1b71d090e21)) 206 | * **workflows/commitlint:** add to repo [skip ci] ([43a7353](https://github.com/saltstack-formulas/postfix-formula/commit/43a7353caec2908e1d6aabab11c198c1806412f5)) 207 | 208 | 209 | ### Documentation 210 | 211 | * **contributing:** remove to use org-level file instead [skip ci] ([a33757a](https://github.com/saltstack-formulas/postfix-formula/commit/a33757a6ad445fc7e209f32c6ceb5b2309e11d03)) 212 | * **readme:** update link to `CONTRIBUTING` [skip ci] ([50b9808](https://github.com/saltstack-formulas/postfix-formula/commit/50b9808a3bd094de30439ff788b6f58ea72051ba)) 213 | 214 | 215 | ### Performance Improvements 216 | 217 | * **travis:** improve `salt-lint` invocation [skip ci] ([2ece69c](https://github.com/saltstack-formulas/postfix-formula/commit/2ece69c3c12ffd9696a5836bf3ed7992af58e8ab)) 218 | 219 | ## [0.18.1](https://github.com/saltstack-formulas/postfix-formula/compare/v0.18.0...v0.18.1) (2019-10-11) 220 | 221 | 222 | ### Bug Fixes 223 | 224 | * **rubocop:** add fixes using `rubocop --safe-auto-correct` ([](https://github.com/saltstack-formulas/postfix-formula/commit/87dd217)) 225 | 226 | 227 | ### Continuous Integration 228 | 229 | * **kitchen:** change `log_level` to `debug` instead of `info` ([](https://github.com/saltstack-formulas/postfix-formula/commit/17734cb)) 230 | * **kitchen:** install required packages to bootstrapped `opensuse` [skip ci] ([](https://github.com/saltstack-formulas/postfix-formula/commit/5127bee)) 231 | * **kitchen:** use bootstrapped `opensuse` images until `2019.2.2` [skip ci] ([](https://github.com/saltstack-formulas/postfix-formula/commit/79df4ce)) 232 | * **platform:** add `arch-base-latest` ([](https://github.com/saltstack-formulas/postfix-formula/commit/16e6f58)) 233 | * merge travis matrix, add `salt-lint` & `rubocop` to `lint` job ([](https://github.com/saltstack-formulas/postfix-formula/commit/0c0a228)) 234 | * merge travis matrix, add `salt-lint` & `rubocop` to `lint` job ([](https://github.com/saltstack-formulas/postfix-formula/commit/1ec88a4)) 235 | * use `dist: bionic` & apply `opensuse-leap-15` SCP error workaround ([](https://github.com/saltstack-formulas/postfix-formula/commit/bbbc260)) 236 | * **travis:** merge `rubocop` linter into main `lint` job ([](https://github.com/saltstack-formulas/postfix-formula/commit/508074a)) 237 | * **yamllint:** add rule `empty-values` & use new `yaml-files` setting ([](https://github.com/saltstack-formulas/postfix-formula/commit/c9a4fc7)) 238 | 239 | # [0.18.0](https://github.com/saltstack-formulas/postfix-formula/compare/v0.17.1...v0.18.0) (2019-09-01) 240 | 241 | 242 | ### Continuous Integration 243 | 244 | * **kitchen+travis:** replace EOL pre-salted images ([8996d28](https://github.com/saltstack-formulas/postfix-formula/commit/8996d28)) 245 | 246 | 247 | ### Features 248 | 249 | * **yamllint:** include for this repo and apply rules throughout ([b4fbac2](https://github.com/saltstack-formulas/postfix-formula/commit/b4fbac2)) 250 | 251 | ## [0.17.1](https://github.com/saltstack-formulas/postfix-formula/compare/v0.17.0...v0.17.1) (2019-07-26) 252 | 253 | 254 | ### Bug Fixes 255 | 256 | * **service:** restart service on package change ([75358e0](https://github.com/saltstack-formulas/postfix-formula/commit/75358e0)) 257 | 258 | 259 | ### Continuous Integration 260 | 261 | * **kitchen+travis:** modify matrix to include `develop` platform ([b505a5d](https://github.com/saltstack-formulas/postfix-formula/commit/b505a5d)) 262 | 263 | # [0.17.0](https://github.com/saltstack-formulas/postfix-formula/compare/v0.16.0...v0.17.0) (2019-06-03) 264 | 265 | 266 | ### Features 267 | 268 | * **semantic-release:** implement an automated changelog ([3161504](https://github.com/saltstack-formulas/postfix-formula/commit/3161504)) 269 | -------------------------------------------------------------------------------- /docs/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | 2 | Changelog 3 | ========= 4 | 5 | `2.0.3 `_ (2025-04-10) 6 | --------------------------------------------------------------------------------------------------------- 7 | 8 | Continuous Integration 9 | ^^^^^^^^^^^^^^^^^^^^^^ 10 | 11 | 12 | * update ``pre-commit`` configuration inc. for pre-commit.ci [skip ci] (\ `02e4fb9 `_\ ) 13 | * use latest test images (\ `c48cf63 `_\ ) 14 | * **kitchen+gitlab:** update for new pre-salted images [skip ci] (\ `b4b0893 `_\ ) 15 | 16 | Tests 17 | ^^^^^ 18 | 19 | 20 | * **system:** add ``build_platform_codename`` [skip ci] (\ `0d68789 `_\ ) 21 | * **system.rb:** add support for ``mac_os_x`` [skip ci] (\ `842a109 `_\ ) 22 | 23 | `2.0.2 `_ (2022-02-13) 24 | --------------------------------------------------------------------------------------------------------- 25 | 26 | Code Refactoring 27 | ^^^^^^^^^^^^^^^^ 28 | 29 | 30 | * **salt-lint:** fix violations (\ `6a33d98 `_\ ) 31 | 32 | Continuous Integration 33 | ^^^^^^^^^^^^^^^^^^^^^^ 34 | 35 | 36 | * update linters to latest versions [skip ci] (\ `62eb687 `_\ ) 37 | * **gemfile:** allow rubygems proxy to be provided as an env var [skip ci] (\ `5d167a4 `_\ ) 38 | * **kitchen+gitlab:** update for new pre-salted images [skip ci] (\ `008ac83 `_\ ) 39 | 40 | `2.0.1 `_ (2022-01-25) 41 | --------------------------------------------------------------------------------------------------------- 42 | 43 | Bug Fixes 44 | ^^^^^^^^^ 45 | 46 | 47 | * **config:** set default_database_type; fixes `#118 `_ (\ `3bd3d1c `_\ ) 48 | 49 | Code Refactoring 50 | ^^^^^^^^^^^^^^^^ 51 | 52 | 53 | * **config:** add ``default_database_type`` as default value (\ `6da70d2 `_\ ) 54 | 55 | Continuous Integration 56 | ^^^^^^^^^^^^^^^^^^^^^^ 57 | 58 | 59 | * **3003.1:** update inc. AlmaLinux, Rocky & ``rst-lint`` [skip ci] (\ `3284d38 `_\ ) 60 | * **gemfile+lock:** use ``ssf`` customised ``inspec`` repo [skip ci] (\ `cfed974 `_\ ) 61 | * **kitchen:** move ``provisioner`` block & update ``run_command`` [skip ci] (\ `31a3836 `_\ ) 62 | * **kitchen+ci:** update with ``3004`` pre-salted images/boxes [skip ci] (\ `dec042a `_\ ) 63 | * **kitchen+ci:** update with latest ``3003.2`` pre-salted images [skip ci] (\ `9688f36 `_\ ) 64 | * **kitchen+ci:** update with latest CVE pre-salted images [skip ci] (\ `76134b4 `_\ ) 65 | * add ``arch-master`` to matrix and update ``.travis.yml`` [skip ci] (\ `c631eca `_\ ) 66 | * add Debian 11 Bullseye & update ``yamllint`` configuration [skip ci] (\ `c11c07d `_\ ) 67 | * **kitchen+gitlab:** adjust matrix to add ``3003`` [skip ci] (\ `04564a7 `_\ ) 68 | * **kitchen+gitlab:** remove Ubuntu 16.04 & Fedora 32 (EOL) [skip ci] (\ `d56006f `_\ ) 69 | 70 | Tests 71 | ^^^^^ 72 | 73 | 74 | * standardise use of ``share`` suite & ``_mapdata`` state [skip ci] (\ `4c394a7 `_\ ) 75 | 76 | `2.0.0 `_ (2021-03-15) 77 | --------------------------------------------------------------------------------------------------------- 78 | 79 | Bug Fixes 80 | ^^^^^^^^^ 81 | 82 | 83 | * **resources:** make resources' IDs unique (\ `03ad48b `_\ ) 84 | 85 | Continuous Integration 86 | ^^^^^^^^^^^^^^^^^^^^^^ 87 | 88 | 89 | * **commitlint:** ensure ``upstream/master`` uses main repo URL [skip ci] (\ `381b150 `_\ ) 90 | * **gemfile+lock:** use ``ssf`` customised ``kitchen-docker`` repo [skip ci] (\ `c5851e6 `_\ ) 91 | * **gitlab-ci:** add ``rubocop`` linter (with ``allow_failure``\ ) [skip ci] (\ `22fa184 `_\ ) 92 | * **gitlab-ci:** use GitLab CI as Travis CI replacement (\ `890f3ae `_\ ) 93 | * **kitchen+ci:** use latest pre-salted images (after CVE) [skip ci] (\ `19617a0 `_\ ) 94 | * **kitchen+gitlab-ci:** use latest pre-salted images [skip ci] (\ `d65a7a3 `_\ ) 95 | * **pre-commit:** add to formula [skip ci] (\ `f41392d `_\ ) 96 | * **pre-commit:** enable/disable ``rstcheck`` as relevant [skip ci] (\ `fb5be95 `_\ ) 97 | * **pre-commit:** finalise ``rstcheck`` configuration [skip ci] (\ `75941ed `_\ ) 98 | * **pre-commit:** update hook for ``rubocop`` [skip ci] (\ `c60d58e `_\ ) 99 | 100 | BREAKING CHANGES 101 | ^^^^^^^^^^^^^^^^ 102 | 103 | 104 | * **resources:** as all resources' IDs changed, other formulas 105 | depending on this formula's resources will need to be modified 106 | accordingly. 107 | 108 | `1.2.2 `_ (2020-10-02) 109 | --------------------------------------------------------------------------------------------------------- 110 | 111 | Styles 112 | ^^^^^^ 113 | 114 | 115 | * prepend modes with 0 (\ `fdc127c `_\ ) 116 | * quote modes/numbers (\ `b9c4fba `_\ ) 117 | 118 | `1.2.1 `_ (2020-09-27) 119 | --------------------------------------------------------------------------------------------------------- 120 | 121 | Styles 122 | ^^^^^^ 123 | 124 | 125 | * linting for ``yamllint`` (\ `780dc9d `_\ ) 126 | 127 | `1.2.0 `_ (2020-07-20) 128 | --------------------------------------------------------------------------------------------------------- 129 | 130 | Features 131 | ^^^^^^^^ 132 | 133 | 134 | * **maps:** add more map types and tests (\ `e3970df `_\ ) 135 | 136 | `1.1.0 `_ (2020-07-18) 137 | --------------------------------------------------------------------------------------------------------- 138 | 139 | Continuous Integration 140 | ^^^^^^^^^^^^^^^^^^^^^^ 141 | 142 | 143 | * **kitchen:** use ``saltimages`` Docker Hub where available [skip ci] (\ `2ddd417 `_\ ) 144 | 145 | Features 146 | ^^^^^^^^ 147 | 148 | 149 | * **config:** run postmap also for regexp maps (\ `7584fce `_\ ) 150 | 151 | `1.0.3 `_ (2020-06-08) 152 | --------------------------------------------------------------------------------------------------------- 153 | 154 | Bug Fixes 155 | ^^^^^^^^^ 156 | 157 | 158 | * **deps:** fixes ordering where postmap requires sane main.cf (\ `a28bd05 `_\ ) 159 | * **test:** use specific ip to workaround centos bug (\ `273caf9 `_\ ) 160 | 161 | Tests 162 | ^^^^^ 163 | 164 | 165 | * **default:** add inspec for base and maps (\ `2a61498 `_\ ) 166 | 167 | `1.0.2 `_ (2020-06-07) 168 | --------------------------------------------------------------------------------------------------------- 169 | 170 | Bug Fixes 171 | ^^^^^^^^^ 172 | 173 | 174 | * **opensuse:** fixes config files generation in opensuse (\ `067bcf6 `_\ ) 175 | 176 | `1.0.1 `_ (2020-06-07) 177 | --------------------------------------------------------------------------------------------------------- 178 | 179 | Bug Fixes 180 | ^^^^^^^^^ 181 | 182 | 183 | * **main:** fix postconf warning when reloading/starting (\ `04003c6 `_\ ) 184 | 185 | `1.0.0 `_ (2020-06-06) 186 | ---------------------------------------------------------------------------------------------------------- 187 | 188 | Code Refactoring 189 | ^^^^^^^^^^^^^^^^ 190 | 191 | 192 | * **maps:** move tls_policy and transport to mapping section (\ `06276fd `_\ ) 193 | 194 | Continuous Integration 195 | ^^^^^^^^^^^^^^^^^^^^^^ 196 | 197 | 198 | * **kitchen+travis:** use latest pre-salted images (\ `b364744 `_\ ) 199 | 200 | BREAKING CHANGES 201 | ^^^^^^^^^^^^^^^^ 202 | 203 | 204 | * **maps:** ``transport`` and ``tls_policy`` keys in ``postfix:config`` have been moved to the standard ``postfix:mapping``. 205 | 206 | `0.19.0 `_ (2020-05-23) 207 | ------------------------------------------------------------------------------------------------------------ 208 | 209 | Continuous Integration 210 | ^^^^^^^^^^^^^^^^^^^^^^ 211 | 212 | 213 | * **travis:** add notifications => zulip [skip ci] (\ `c78c421 `_\ ) 214 | 215 | Features 216 | ^^^^^^^^ 217 | 218 | 219 | * **maps:** adds tls_policy map for smtp delivery (\ `d87da4a `_\ ) 220 | 221 | `0.18.2 `_ (2020-05-12) 222 | ------------------------------------------------------------------------------------------------------------ 223 | 224 | Bug Fixes 225 | ^^^^^^^^^ 226 | 227 | 228 | * make necessary modifications to get working on ``salt-ssh`` (\ `34a112f `_\ ), closes `/freenode.logbot.info/saltstack-formulas/20200507#c3819526-c3819581 `_ `/freenode.logbot.info/saltstack-formulas/20200508#c3826763-c3826995 `_ 229 | * **release.config.js:** use full commit hash in commit link [skip ci] (\ `ffbe5aa `_\ ) 230 | 231 | Continuous Integration 232 | ^^^^^^^^^^^^^^^^^^^^^^ 233 | 234 | 235 | * **gemfile:** restrict ``train`` gem version until upstream fix [skip ci] (\ `80cdd9d `_\ ) 236 | * **gemfile.lock:** add to repo with updated ``Gemfile`` [skip ci] (\ `497221d `_\ ) 237 | * **kitchen:** avoid using bootstrap for ``master`` instances [skip ci] (\ `708b0a5 `_\ ) 238 | * **kitchen:** use ``debian-10-master-py3`` instead of ``develop`` [skip ci] (\ `90098c0 `_\ ) 239 | * **kitchen:** use ``develop`` image until ``master`` is ready (\ ``amazonlinux``\ ) [skip ci] (\ `df76c72 `_\ ) 240 | * **kitchen+travis:** remove ``master-py2-arch-base-latest`` [skip ci] (\ `46d0f3d `_\ ) 241 | * **kitchen+travis:** upgrade matrix after ``2019.2.2`` release [skip ci] (\ `70fc491 `_\ ) 242 | * **travis:** apply changes from build config validation [skip ci] (\ `f25db2d `_\ ) 243 | * **travis:** opt-in to ``dpl v2`` to complete build config validation [skip ci] (\ `8f4db70 `_\ ) 244 | * **travis:** quote pathspecs used with ``git ls-files`` [skip ci] (\ `6d18d1d `_\ ) 245 | * **travis:** run ``shellcheck`` during lint job [skip ci] (\ `29efb81 `_\ ) 246 | * **travis:** update ``salt-lint`` config for ``v0.0.10`` [skip ci] (\ `b23168e `_\ ) 247 | * **travis:** use ``major.minor`` for ``semantic-release`` version [skip ci] (\ `964e3ef `_\ ) 248 | * **travis:** use build config validation (beta) [skip ci] (\ `1ab8692 `_\ ) 249 | * **workflows/commitlint:** add to repo [skip ci] (\ `43a7353 `_\ ) 250 | 251 | Documentation 252 | ^^^^^^^^^^^^^ 253 | 254 | 255 | * **contributing:** remove to use org-level file instead [skip ci] (\ `a33757a `_\ ) 256 | * **readme:** update link to ``CONTRIBUTING`` [skip ci] (\ `50b9808 `_\ ) 257 | 258 | Performance Improvements 259 | ^^^^^^^^^^^^^^^^^^^^^^^^ 260 | 261 | 262 | * **travis:** improve ``salt-lint`` invocation [skip ci] (\ `2ece69c `_\ ) 263 | 264 | `0.18.1 `_ (2019-10-11) 265 | ------------------------------------------------------------------------------------------------------------ 266 | 267 | Bug Fixes 268 | ^^^^^^^^^ 269 | 270 | 271 | * **rubocop:** add fixes using ``rubocop --safe-auto-correct`` (\ ` `_\ ) 272 | 273 | Continuous Integration 274 | ^^^^^^^^^^^^^^^^^^^^^^ 275 | 276 | 277 | * **kitchen:** change ``log_level`` to ``debug`` instead of ``info`` (\ ` `_\ ) 278 | * **kitchen:** install required packages to bootstrapped ``opensuse`` [skip ci] (\ ` `_\ ) 279 | * **kitchen:** use bootstrapped ``opensuse`` images until ``2019.2.2`` [skip ci] (\ ` `_\ ) 280 | * **platform:** add ``arch-base-latest`` (\ ` `_\ ) 281 | * merge travis matrix, add ``salt-lint`` & ``rubocop`` to ``lint`` job (\ ` `_\ ) 282 | * merge travis matrix, add ``salt-lint`` & ``rubocop`` to ``lint`` job (\ ` `_\ ) 283 | * use ``dist: bionic`` & apply ``opensuse-leap-15`` SCP error workaround (\ ` `_\ ) 284 | * **travis:** merge ``rubocop`` linter into main ``lint`` job (\ ` `_\ ) 285 | * **yamllint:** add rule ``empty-values`` & use new ``yaml-files`` setting (\ ` `_\ ) 286 | 287 | `0.18.0 `_ (2019-09-01) 288 | ------------------------------------------------------------------------------------------------------------ 289 | 290 | Continuous Integration 291 | ^^^^^^^^^^^^^^^^^^^^^^ 292 | 293 | 294 | * **kitchen+travis:** replace EOL pre-salted images (\ `8996d28 `_\ ) 295 | 296 | Features 297 | ^^^^^^^^ 298 | 299 | 300 | * **yamllint:** include for this repo and apply rules throughout (\ `b4fbac2 `_\ ) 301 | 302 | `0.17.1 `_ (2019-07-26) 303 | ------------------------------------------------------------------------------------------------------------ 304 | 305 | Bug Fixes 306 | ^^^^^^^^^ 307 | 308 | 309 | * **service:** restart service on package change (\ `75358e0 `_\ ) 310 | 311 | Continuous Integration 312 | ^^^^^^^^^^^^^^^^^^^^^^ 313 | 314 | 315 | * **kitchen+travis:** modify matrix to include ``develop`` platform (\ `b505a5d `_\ ) 316 | 317 | `0.17.0 `_ (2019-06-03) 318 | ------------------------------------------------------------------------------------------------------------ 319 | 320 | Features 321 | ^^^^^^^^ 322 | 323 | 324 | * **semantic-release:** implement an automated changelog (\ `3161504 `_\ ) 325 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GIT 2 | remote: https://github.com/test-kitchen/kitchen-docker 3 | revision: 511e4ad36856b9e2eccceb56603586e6cebd296a 4 | ref: 511e4ad36856b9e2eccceb56603586e6cebd296a 5 | specs: 6 | kitchen-docker (3.0.0) 7 | test-kitchen (>= 1.0.0, < 4.0) 8 | 9 | GIT 10 | remote: https://gitlab.com/saltstack-formulas/infrastructure/inspec 11 | revision: a0c6295303f7d7a4d2a6164b5e77868560b04945 12 | branch: ssf 13 | specs: 14 | inspec (5.21.15) 15 | cookstyle 16 | faraday_middleware (>= 0.12.2, < 1.1) 17 | inspec-core (= 5.21.15) 18 | mongo (= 2.13.2) 19 | progress_bar (~> 1.3.3) 20 | rake 21 | roo (~> 2.9.0) 22 | roo-xls 23 | train (~> 3.10) 24 | train-aws (~> 0.2) 25 | train-habitat (~> 0.1) 26 | train-winrm (~> 0.2) 27 | inspec-core (5.21.15) 28 | addressable (~> 2.4) 29 | chef-telemetry (~> 1.0, >= 1.0.8) 30 | faraday (>= 1, < 3) 31 | faraday-follow_redirects (~> 0.3) 32 | hashie (>= 3.4, < 5.0) 33 | license-acceptance (>= 0.2.13, < 3.0) 34 | method_source (>= 0.8, < 2.0) 35 | mixlib-log (~> 3.0) 36 | multipart-post (~> 2.0) 37 | parallel (~> 1.9) 38 | parslet (>= 1.5, < 2.0) 39 | pry (~> 0.13) 40 | rspec (>= 3.9, <= 3.11) 41 | rspec-its (~> 1.2) 42 | rubyzip (>= 1.2.2, < 3.0) 43 | semverse (~> 3.0) 44 | sslshake (~> 1.2) 45 | thor (>= 0.20, < 2.0) 46 | tomlrb (>= 1.2, < 2.1) 47 | train-core (~> 3.10) 48 | tty-prompt (~> 0.17) 49 | tty-table (~> 0.10) 50 | 51 | GEM 52 | remote: https://rubygems.org/ 53 | specs: 54 | activesupport (7.1.5.1) 55 | base64 56 | benchmark (>= 0.3) 57 | bigdecimal 58 | concurrent-ruby (~> 1.0, >= 1.0.2) 59 | connection_pool (>= 2.2.5) 60 | drb 61 | i18n (>= 1.6, < 2) 62 | logger (>= 1.4.2) 63 | minitest (>= 5.1) 64 | mutex_m 65 | securerandom (>= 0.3) 66 | tzinfo (~> 2.0) 67 | addressable (2.8.7) 68 | public_suffix (>= 2.0.2, < 7.0) 69 | ast (2.4.3) 70 | aws-eventstream (1.3.2) 71 | aws-partitions (1.863.0) 72 | aws-sdk-accessanalyzer (1.44.0) 73 | aws-sdk-core (~> 3, >= 3.188.0) 74 | aws-sigv4 (~> 1.1) 75 | aws-sdk-account (1.20.0) 76 | aws-sdk-core (~> 3, >= 3.188.0) 77 | aws-sigv4 (~> 1.1) 78 | aws-sdk-alexaforbusiness (1.67.0) 79 | aws-sdk-core (~> 3, >= 3.188.0) 80 | aws-sigv4 (~> 1.1) 81 | aws-sdk-amplify (1.54.0) 82 | aws-sdk-core (~> 3, >= 3.188.0) 83 | aws-sigv4 (~> 1.1) 84 | aws-sdk-apigateway (1.90.0) 85 | aws-sdk-core (~> 3, >= 3.188.0) 86 | aws-sigv4 (~> 1.1) 87 | aws-sdk-apigatewayv2 (1.53.0) 88 | aws-sdk-core (~> 3, >= 3.188.0) 89 | aws-sigv4 (~> 1.1) 90 | aws-sdk-applicationautoscaling (1.79.0) 91 | aws-sdk-core (~> 3, >= 3.188.0) 92 | aws-sigv4 (~> 1.1) 93 | aws-sdk-athena (1.79.0) 94 | aws-sdk-core (~> 3, >= 3.188.0) 95 | aws-sigv4 (~> 1.1) 96 | aws-sdk-autoscaling (1.102.0) 97 | aws-sdk-core (~> 3, >= 3.188.0) 98 | aws-sigv4 (~> 1.1) 99 | aws-sdk-batch (1.79.0) 100 | aws-sdk-core (~> 3, >= 3.188.0) 101 | aws-sigv4 (~> 1.1) 102 | aws-sdk-budgets (1.62.0) 103 | aws-sdk-core (~> 3, >= 3.188.0) 104 | aws-sigv4 (~> 1.1) 105 | aws-sdk-cloudformation (1.97.0) 106 | aws-sdk-core (~> 3, >= 3.188.0) 107 | aws-sigv4 (~> 1.1) 108 | aws-sdk-cloudfront (1.86.1) 109 | aws-sdk-core (~> 3, >= 3.188.0) 110 | aws-sigv4 (~> 1.1) 111 | aws-sdk-cloudhsm (1.50.0) 112 | aws-sdk-core (~> 3, >= 3.188.0) 113 | aws-sigv4 (~> 1.1) 114 | aws-sdk-cloudhsmv2 (1.53.0) 115 | aws-sdk-core (~> 3, >= 3.188.0) 116 | aws-sigv4 (~> 1.1) 117 | aws-sdk-cloudtrail (1.74.0) 118 | aws-sdk-core (~> 3, >= 3.188.0) 119 | aws-sigv4 (~> 1.1) 120 | aws-sdk-cloudwatch (1.83.0) 121 | aws-sdk-core (~> 3, >= 3.188.0) 122 | aws-sigv4 (~> 1.1) 123 | aws-sdk-cloudwatchevents (1.69.0) 124 | aws-sdk-core (~> 3, >= 3.188.0) 125 | aws-sigv4 (~> 1.1) 126 | aws-sdk-cloudwatchlogs (1.77.0) 127 | aws-sdk-core (~> 3, >= 3.188.0) 128 | aws-sigv4 (~> 1.1) 129 | aws-sdk-codecommit (1.62.0) 130 | aws-sdk-core (~> 3, >= 3.188.0) 131 | aws-sigv4 (~> 1.1) 132 | aws-sdk-codedeploy (1.62.0) 133 | aws-sdk-core (~> 3, >= 3.188.0) 134 | aws-sigv4 (~> 1.1) 135 | aws-sdk-codepipeline (1.67.0) 136 | aws-sdk-core (~> 3, >= 3.188.0) 137 | aws-sigv4 (~> 1.1) 138 | aws-sdk-cognitoidentity (1.51.0) 139 | aws-sdk-core (~> 3, >= 3.188.0) 140 | aws-sigv4 (~> 1.1) 141 | aws-sdk-cognitoidentityprovider (1.85.0) 142 | aws-sdk-core (~> 3, >= 3.188.0) 143 | aws-sigv4 (~> 1.1) 144 | aws-sdk-configservice (1.103.0) 145 | aws-sdk-core (~> 3, >= 3.188.0) 146 | aws-sigv4 (~> 1.1) 147 | aws-sdk-core (3.190.3) 148 | aws-eventstream (~> 1, >= 1.3.0) 149 | aws-partitions (~> 1, >= 1.651.0) 150 | aws-sigv4 (~> 1.8) 151 | jmespath (~> 1, >= 1.6.1) 152 | aws-sdk-costandusagereportservice (1.53.0) 153 | aws-sdk-core (~> 3, >= 3.188.0) 154 | aws-sigv4 (~> 1.1) 155 | aws-sdk-databasemigrationservice (1.91.0) 156 | aws-sdk-core (~> 3, >= 3.188.0) 157 | aws-sigv4 (~> 1.1) 158 | aws-sdk-dynamodb (1.98.0) 159 | aws-sdk-core (~> 3, >= 3.188.0) 160 | aws-sigv4 (~> 1.1) 161 | aws-sdk-ec2 (1.429.0) 162 | aws-sdk-core (~> 3, >= 3.188.0) 163 | aws-sigv4 (~> 1.1) 164 | aws-sdk-ecr (1.68.0) 165 | aws-sdk-core (~> 3, >= 3.188.0) 166 | aws-sigv4 (~> 1.1) 167 | aws-sdk-ecrpublic (1.25.0) 168 | aws-sdk-core (~> 3, >= 3.188.0) 169 | aws-sigv4 (~> 1.1) 170 | aws-sdk-ecs (1.135.0) 171 | aws-sdk-core (~> 3, >= 3.188.0) 172 | aws-sigv4 (~> 1.1) 173 | aws-sdk-efs (1.71.0) 174 | aws-sdk-core (~> 3, >= 3.188.0) 175 | aws-sigv4 (~> 1.1) 176 | aws-sdk-eks (1.95.0) 177 | aws-sdk-core (~> 3, >= 3.188.0) 178 | aws-sigv4 (~> 1.1) 179 | aws-sdk-elasticache (1.95.0) 180 | aws-sdk-core (~> 3, >= 3.188.0) 181 | aws-sigv4 (~> 1.1) 182 | aws-sdk-elasticbeanstalk (1.63.0) 183 | aws-sdk-core (~> 3, >= 3.188.0) 184 | aws-sigv4 (~> 1.1) 185 | aws-sdk-elasticloadbalancing (1.51.0) 186 | aws-sdk-core (~> 3, >= 3.188.0) 187 | aws-sigv4 (~> 1.1) 188 | aws-sdk-elasticloadbalancingv2 (1.96.0) 189 | aws-sdk-core (~> 3, >= 3.188.0) 190 | aws-sigv4 (~> 1.1) 191 | aws-sdk-elasticsearchservice (1.79.0) 192 | aws-sdk-core (~> 3, >= 3.188.0) 193 | aws-sigv4 (~> 1.1) 194 | aws-sdk-emr (1.81.0) 195 | aws-sdk-core (~> 3, >= 3.188.0) 196 | aws-sigv4 (~> 1.1) 197 | aws-sdk-eventbridge (1.54.0) 198 | aws-sdk-core (~> 3, >= 3.188.0) 199 | aws-sigv4 (~> 1.1) 200 | aws-sdk-firehose (1.60.0) 201 | aws-sdk-core (~> 3, >= 3.188.0) 202 | aws-sigv4 (~> 1.1) 203 | aws-sdk-glue (1.165.0) 204 | aws-sdk-core (~> 3, >= 3.188.0) 205 | aws-sigv4 (~> 1.1) 206 | aws-sdk-guardduty (1.85.0) 207 | aws-sdk-core (~> 3, >= 3.188.0) 208 | aws-sigv4 (~> 1.1) 209 | aws-sdk-iam (1.92.0) 210 | aws-sdk-core (~> 3, >= 3.188.0) 211 | aws-sigv4 (~> 1.1) 212 | aws-sdk-kafka (1.67.0) 213 | aws-sdk-core (~> 3, >= 3.188.0) 214 | aws-sigv4 (~> 1.1) 215 | aws-sdk-kinesis (1.54.0) 216 | aws-sdk-core (~> 3, >= 3.188.0) 217 | aws-sigv4 (~> 1.1) 218 | aws-sdk-kms (1.76.0) 219 | aws-sdk-core (~> 3, >= 3.188.0) 220 | aws-sigv4 (~> 1.1) 221 | aws-sdk-lambda (1.113.0) 222 | aws-sdk-core (~> 3, >= 3.188.0) 223 | aws-sigv4 (~> 1.1) 224 | aws-sdk-macie2 (1.64.0) 225 | aws-sdk-core (~> 3, >= 3.188.0) 226 | aws-sigv4 (~> 1.1) 227 | aws-sdk-mq (1.58.0) 228 | aws-sdk-core (~> 3, >= 3.188.0) 229 | aws-sigv4 (~> 1.1) 230 | aws-sdk-networkfirewall (1.39.0) 231 | aws-sdk-core (~> 3, >= 3.188.0) 232 | aws-sigv4 (~> 1.1) 233 | aws-sdk-networkmanager (1.40.0) 234 | aws-sdk-core (~> 3, >= 3.188.0) 235 | aws-sigv4 (~> 1.1) 236 | aws-sdk-organizations (1.83.0) 237 | aws-sdk-core (~> 3, >= 3.188.0) 238 | aws-sigv4 (~> 1.1) 239 | aws-sdk-ram (1.52.0) 240 | aws-sdk-core (~> 3, >= 3.188.0) 241 | aws-sigv4 (~> 1.1) 242 | aws-sdk-rds (1.208.0) 243 | aws-sdk-core (~> 3, >= 3.188.0) 244 | aws-sigv4 (~> 1.1) 245 | aws-sdk-redshift (1.107.0) 246 | aws-sdk-core (~> 3, >= 3.188.0) 247 | aws-sigv4 (~> 1.1) 248 | aws-sdk-route53 (1.83.0) 249 | aws-sdk-core (~> 3, >= 3.188.0) 250 | aws-sigv4 (~> 1.1) 251 | aws-sdk-route53domains (1.54.0) 252 | aws-sdk-core (~> 3, >= 3.188.0) 253 | aws-sigv4 (~> 1.1) 254 | aws-sdk-route53resolver (1.51.0) 255 | aws-sdk-core (~> 3, >= 3.188.0) 256 | aws-sigv4 (~> 1.1) 257 | aws-sdk-s3 (1.141.0) 258 | aws-sdk-core (~> 3, >= 3.189.0) 259 | aws-sdk-kms (~> 1) 260 | aws-sigv4 (~> 1.8) 261 | aws-sdk-s3control (1.74.0) 262 | aws-sdk-core (~> 3, >= 3.188.0) 263 | aws-sigv4 (~> 1.1) 264 | aws-sdk-secretsmanager (1.87.0) 265 | aws-sdk-core (~> 3, >= 3.188.0) 266 | aws-sigv4 (~> 1.1) 267 | aws-sdk-securityhub (1.98.0) 268 | aws-sdk-core (~> 3, >= 3.188.0) 269 | aws-sigv4 (~> 1.1) 270 | aws-sdk-servicecatalog (1.90.0) 271 | aws-sdk-core (~> 3, >= 3.188.0) 272 | aws-sigv4 (~> 1.1) 273 | aws-sdk-ses (1.58.0) 274 | aws-sdk-core (~> 3, >= 3.188.0) 275 | aws-sigv4 (~> 1.1) 276 | aws-sdk-shield (1.60.0) 277 | aws-sdk-core (~> 3, >= 3.188.0) 278 | aws-sigv4 (~> 1.1) 279 | aws-sdk-signer (1.50.0) 280 | aws-sdk-core (~> 3, >= 3.188.0) 281 | aws-sigv4 (~> 1.1) 282 | aws-sdk-simpledb (1.42.0) 283 | aws-sdk-core (~> 3, >= 3.188.0) 284 | aws-sigv2 (~> 1.0) 285 | aws-sdk-sms (1.52.0) 286 | aws-sdk-core (~> 3, >= 3.188.0) 287 | aws-sigv4 (~> 1.1) 288 | aws-sdk-sns (1.70.0) 289 | aws-sdk-core (~> 3, >= 3.188.0) 290 | aws-sigv4 (~> 1.1) 291 | aws-sdk-sqs (1.69.0) 292 | aws-sdk-core (~> 3, >= 3.188.0) 293 | aws-sigv4 (~> 1.1) 294 | aws-sdk-ssm (1.162.0) 295 | aws-sdk-core (~> 3, >= 3.188.0) 296 | aws-sigv4 (~> 1.1) 297 | aws-sdk-states (1.63.0) 298 | aws-sdk-core (~> 3, >= 3.188.0) 299 | aws-sigv4 (~> 1.1) 300 | aws-sdk-synthetics (1.39.0) 301 | aws-sdk-core (~> 3, >= 3.188.0) 302 | aws-sigv4 (~> 1.1) 303 | aws-sdk-transfer (1.86.0) 304 | aws-sdk-core (~> 3, >= 3.188.0) 305 | aws-sigv4 (~> 1.1) 306 | aws-sdk-waf (1.58.0) 307 | aws-sdk-core (~> 3, >= 3.188.0) 308 | aws-sigv4 (~> 1.1) 309 | aws-sdk-wafv2 (1.74.0) 310 | aws-sdk-core (~> 3, >= 3.188.0) 311 | aws-sigv4 (~> 1.1) 312 | aws-sigv2 (1.2.0) 313 | aws-sigv4 (1.11.0) 314 | aws-eventstream (~> 1, >= 1.0.2) 315 | azure_graph_rbac (0.17.2) 316 | ms_rest_azure (~> 0.12.0) 317 | azure_mgmt_key_vault (0.17.7) 318 | ms_rest_azure (~> 0.12.0) 319 | azure_mgmt_resources (0.18.2) 320 | ms_rest_azure (~> 0.12.0) 321 | azure_mgmt_security (0.19.0) 322 | ms_rest_azure (~> 0.12.0) 323 | azure_mgmt_storage (0.23.0) 324 | ms_rest_azure (~> 0.12.0) 325 | base64 (0.3.0) 326 | bcrypt_pbkdf (1.1.1) 327 | bcrypt_pbkdf (1.1.1-x64-mingw-ucrt) 328 | benchmark (0.4.0) 329 | bigdecimal (3.3.1) 330 | bson (4.15.0) 331 | builder (3.3.0) 332 | cgi (0.5.0) 333 | chef-config (18.7.6) 334 | addressable 335 | chef-utils (= 18.7.6) 336 | fuzzyurl 337 | mixlib-config (>= 2.2.12, < 4.0) 338 | mixlib-shellout (>= 2.0, < 4.0) 339 | tomlrb (~> 1.2) 340 | chef-gyoku (1.4.5) 341 | builder (>= 2.1.2) 342 | rexml (~> 3.4) 343 | chef-telemetry (1.1.1) 344 | chef-config 345 | concurrent-ruby (~> 1.0) 346 | chef-utils (18.7.6) 347 | concurrent-ruby 348 | chef-winrm (2.3.12) 349 | builder (>= 2.1.2) 350 | chef-gyoku (~> 1.4.0, <= 1.4.5) 351 | erubi (~> 1.8) 352 | ffi (>= 1.15.5, < 1.17.0) 353 | gssapi (~> 1.2) 354 | httpclient (~> 2.2, >= 2.2.0.2) 355 | logging (>= 1.6.1, < 3.0) 356 | nori (= 2.7.0) 357 | rexml (~> 3.3) 358 | rubyntlm (~> 0.6.0, >= 0.6.3) 359 | chef-winrm-elevated (1.2.5) 360 | chef-winrm (>= 2.3.11) 361 | chef-winrm-fs (>= 1.3.7) 362 | erubi (~> 1.8) 363 | chef-winrm-fs (1.3.7) 364 | chef-winrm (>= 2.3.11) 365 | erubi (>= 1.7) 366 | logging (>= 1.6.1, < 3.0) 367 | rubyzip (~> 2.0) 368 | coderay (1.1.3) 369 | concurrent-ruby (1.3.5) 370 | connection_pool (2.5.3) 371 | cookstyle (8.1.2) 372 | rubocop (= 1.75.5) 373 | csv (3.3.5) 374 | date (3.5.0) 375 | declarative (0.0.20) 376 | diff-lcs (1.6.2) 377 | docker-api (2.4.0) 378 | excon (>= 0.64.0) 379 | multi_json 380 | domain_name (0.6.20240107) 381 | drb (2.2.1) 382 | ed25519 (1.4.0) 383 | erb (4.0.4) 384 | cgi (>= 0.3.3) 385 | erubi (1.13.1) 386 | excon (1.2.5) 387 | logger 388 | faraday (1.10.4) 389 | faraday-em_http (~> 1.0) 390 | faraday-em_synchrony (~> 1.0) 391 | faraday-excon (~> 1.1) 392 | faraday-httpclient (~> 1.0) 393 | faraday-multipart (~> 1.0) 394 | faraday-net_http (~> 1.0) 395 | faraday-net_http_persistent (~> 1.0) 396 | faraday-patron (~> 1.0) 397 | faraday-rack (~> 1.0) 398 | faraday-retry (~> 1.0) 399 | ruby2_keywords (>= 0.0.4) 400 | faraday-cookie_jar (0.0.7) 401 | faraday (>= 0.8.0) 402 | http-cookie (~> 1.0.0) 403 | faraday-em_http (1.0.0) 404 | faraday-em_synchrony (1.0.0) 405 | faraday-excon (1.1.0) 406 | faraday-follow_redirects (0.3.0) 407 | faraday (>= 1, < 3) 408 | faraday-httpclient (1.0.1) 409 | faraday-multipart (1.1.0) 410 | multipart-post (~> 2.0) 411 | faraday-net_http (1.0.2) 412 | faraday-net_http_persistent (1.2.0) 413 | faraday-patron (1.0.0) 414 | faraday-rack (1.0.0) 415 | faraday-retry (1.0.3) 416 | faraday_middleware (1.0.0) 417 | faraday (~> 1.0) 418 | ffi (1.16.3) 419 | ffi (1.16.3-x64-mingw-ucrt) 420 | ffi-win32-extensions (1.0.4) 421 | ffi 422 | fuzzyurl (0.9.0) 423 | google-apis-admin_directory_v1 (0.46.0) 424 | google-apis-core (>= 0.11.0, < 2.a) 425 | google-apis-cloudkms_v1 (0.41.0) 426 | google-apis-core (>= 0.11.0, < 2.a) 427 | google-apis-cloudresourcemanager_v1 (0.35.0) 428 | google-apis-core (>= 0.11.0, < 2.a) 429 | google-apis-compute_v1 (0.83.0) 430 | google-apis-core (>= 0.11.0, < 2.a) 431 | google-apis-core (0.11.3) 432 | addressable (~> 2.5, >= 2.5.1) 433 | googleauth (>= 0.16.2, < 2.a) 434 | httpclient (>= 2.8.1, < 3.a) 435 | mini_mime (~> 1.0) 436 | representable (~> 3.0) 437 | retriable (>= 2.0, < 4.a) 438 | rexml 439 | google-apis-iam_v1 (0.50.0) 440 | google-apis-core (>= 0.11.0, < 2.a) 441 | google-apis-monitoring_v3 (0.51.0) 442 | google-apis-core (>= 0.11.0, < 2.a) 443 | google-apis-storage_v1 (0.30.0) 444 | google-apis-core (>= 0.11.0, < 2.a) 445 | googleauth (1.8.1) 446 | faraday (>= 0.17.3, < 3.a) 447 | jwt (>= 1.4, < 3.0) 448 | multi_json (~> 1.11) 449 | os (>= 0.9, < 2.0) 450 | signet (>= 0.16, < 2.a) 451 | gssapi (1.3.1) 452 | ffi (>= 1.0.1) 453 | gyoku (1.4.0) 454 | builder (>= 2.1.2) 455 | rexml (~> 3.0) 456 | hashie (4.1.0) 457 | highline (3.1.2) 458 | reline 459 | http-cookie (1.0.8) 460 | domain_name (~> 0.5) 461 | httpclient (2.9.0) 462 | mutex_m 463 | i18n (1.14.7) 464 | concurrent-ruby (~> 1.0) 465 | inifile (3.0.0) 466 | io-console (0.8.0) 467 | irb (1.15.3) 468 | pp (>= 0.6.0) 469 | rdoc (>= 4.0.0) 470 | reline (>= 0.4.2) 471 | jmespath (1.6.2) 472 | json (2.12.0) 473 | jwt (2.10.1) 474 | base64 475 | kitchen-inspec (3.0.0) 476 | hashie (>= 3.4, <= 5.0) 477 | inspec (>= 2.2.64, < 7.0) 478 | test-kitchen (>= 2.7, < 4) 479 | kitchen-salt (0.7.2) 480 | hashie (>= 3.5) 481 | test-kitchen (>= 1.4) 482 | language_server-protocol (3.17.0.5) 483 | license-acceptance (2.1.13) 484 | pastel (~> 0.7) 485 | tomlrb (>= 1.2, < 3.0) 486 | tty-box (~> 0.6) 487 | tty-prompt (~> 0.20) 488 | lint_roller (1.1.0) 489 | little-plugger (1.1.4) 490 | logger (1.7.0) 491 | logging (2.4.0) 492 | little-plugger (~> 1.1) 493 | multi_json (~> 1.14) 494 | method_source (1.1.0) 495 | mini_mime (1.1.5) 496 | mini_portile2 (2.8.9) 497 | minitest (5.25.5) 498 | mixlib-config (3.0.27) 499 | tomlrb 500 | mixlib-install (3.12.30) 501 | mixlib-shellout 502 | mixlib-versioning 503 | thor 504 | mixlib-log (3.2.3) 505 | ffi (>= 1.15.5) 506 | mixlib-shellout (3.3.9) 507 | chef-utils 508 | mixlib-shellout (3.3.9-x64-mingw-ucrt) 509 | chef-utils 510 | ffi-win32-extensions (~> 1.0.3) 511 | win32-process (~> 0.9) 512 | wmi-lite (~> 1.0) 513 | mixlib-versioning (1.2.12) 514 | mongo (2.13.2) 515 | bson (>= 4.8.2, < 5.0.0) 516 | ms_rest (0.7.6) 517 | concurrent-ruby (~> 1.0) 518 | faraday (>= 0.9, < 2.0.0) 519 | timeliness (~> 0.3.10) 520 | ms_rest_azure (0.12.0) 521 | concurrent-ruby (~> 1.0) 522 | faraday (>= 0.9, < 2.0.0) 523 | faraday-cookie_jar (~> 0.0.6) 524 | ms_rest (~> 0.7.6) 525 | multi_json (1.17.0) 526 | multipart-post (2.4.1) 527 | mutex_m (0.3.0) 528 | net-scp (4.1.0) 529 | net-ssh (>= 2.6.5, < 8.0.0) 530 | net-ssh (7.3.0) 531 | net-ssh-gateway (2.0.0) 532 | net-ssh (>= 4.0.0) 533 | nokogiri (1.18.9) 534 | mini_portile2 (~> 2.8.2) 535 | racc (~> 1.4) 536 | nokogiri (1.18.9-x64-mingw-ucrt) 537 | racc (~> 1.4) 538 | nori (2.7.0) 539 | bigdecimal 540 | options (2.3.2) 541 | os (1.1.4) 542 | ostruct (0.6.3) 543 | parallel (1.27.0) 544 | parser (3.3.8.0) 545 | ast (~> 2.4.1) 546 | racc 547 | parslet (1.8.2) 548 | pastel (0.8.0) 549 | tty-color (~> 0.5) 550 | pp (0.6.3) 551 | prettyprint 552 | prettyprint (0.2.0) 553 | prism (1.4.0) 554 | progress_bar (1.3.4) 555 | highline (>= 1.6) 556 | options (~> 2.3.0) 557 | pry (0.15.2) 558 | coderay (~> 1.1) 559 | method_source (~> 1.0) 560 | psych (5.2.6) 561 | date 562 | stringio 563 | public_suffix (6.0.2) 564 | racc (1.8.1) 565 | rainbow (3.1.1) 566 | rake (13.2.1) 567 | rdoc (6.16.1) 568 | erb 569 | psych (>= 4.0.0) 570 | tsort 571 | regexp_parser (2.10.0) 572 | reline (0.6.1) 573 | io-console (~> 0.5) 574 | representable (3.2.0) 575 | declarative (< 0.1.0) 576 | trailblazer-option (>= 0.1.1, < 0.2.0) 577 | uber (< 0.2.0) 578 | retriable (3.1.2) 579 | rexml (3.4.4) 580 | roo (2.9.0) 581 | nokogiri (~> 1) 582 | rubyzip (>= 1.3.0, < 3.0.0) 583 | roo-xls (1.2.0) 584 | nokogiri 585 | roo (>= 2.0.0, < 3) 586 | spreadsheet (> 0.9.0) 587 | rspec (3.11.0) 588 | rspec-core (~> 3.11.0) 589 | rspec-expectations (~> 3.11.0) 590 | rspec-mocks (~> 3.11.0) 591 | rspec-core (3.11.0) 592 | rspec-support (~> 3.11.0) 593 | rspec-expectations (3.11.1) 594 | diff-lcs (>= 1.2.0, < 2.0) 595 | rspec-support (~> 3.11.0) 596 | rspec-its (1.3.1) 597 | rspec-core (>= 3.0.0) 598 | rspec-expectations (>= 3.0.0) 599 | rspec-mocks (3.11.2) 600 | diff-lcs (>= 1.2.0, < 2.0) 601 | rspec-support (~> 3.11.0) 602 | rspec-support (3.11.1) 603 | rubocop (1.75.5) 604 | json (~> 2.3) 605 | language_server-protocol (~> 3.17.0.2) 606 | lint_roller (~> 1.1.0) 607 | parallel (~> 1.10) 608 | parser (>= 3.3.0.2) 609 | rainbow (>= 2.2.2, < 4.0) 610 | regexp_parser (>= 2.9.3, < 3.0) 611 | rubocop-ast (>= 1.44.0, < 2.0) 612 | ruby-progressbar (~> 1.7) 613 | unicode-display_width (>= 2.4.0, < 4.0) 614 | rubocop-ast (1.44.1) 615 | parser (>= 3.3.7.2) 616 | prism (~> 1.4) 617 | ruby-ole (1.2.13.1) 618 | ruby-progressbar (1.13.0) 619 | ruby2_keywords (0.0.5) 620 | rubyntlm (0.6.5) 621 | base64 622 | rubyzip (2.4.1) 623 | securerandom (0.4.1) 624 | semverse (3.0.2) 625 | signet (0.20.0) 626 | addressable (~> 2.8) 627 | faraday (>= 0.17.5, < 3.a) 628 | jwt (>= 1.5, < 3.0) 629 | multi_json (~> 1.10) 630 | spreadsheet (1.3.4) 631 | bigdecimal 632 | logger 633 | ruby-ole 634 | sslshake (1.3.1) 635 | stringio (3.1.8) 636 | strings (0.2.1) 637 | strings-ansi (~> 0.2) 638 | unicode-display_width (>= 1.5, < 3.0) 639 | unicode_utils (~> 1.4) 640 | strings-ansi (0.2.0) 641 | syslog (0.3.0) 642 | logger 643 | test-kitchen (3.9.0) 644 | bcrypt_pbkdf (~> 1.0) 645 | chef-utils (>= 16.4.35) 646 | csv (~> 3.3) 647 | ed25519 (~> 1.3) 648 | irb (~> 1.15) 649 | license-acceptance (>= 1.0.11, < 3.0) 650 | mixlib-install (~> 3.6) 651 | mixlib-shellout (>= 1.2, < 4.0) 652 | net-scp (>= 1.1, < 5.0) 653 | net-ssh (>= 2.9, < 8.0) 654 | net-ssh-gateway (>= 1.2, < 3.0) 655 | ostruct (~> 0.6) 656 | syslog (~> 0.3) 657 | thor (>= 0.19, < 2.0) 658 | winrm (~> 2.0) 659 | winrm-elevated (~> 1.0) 660 | winrm-fs (~> 1.1) 661 | thor (1.4.0) 662 | timeliness (0.3.10) 663 | tomlrb (1.3.0) 664 | trailblazer-option (0.1.2) 665 | train (3.12.13) 666 | activesupport (>= 6.0.3.1, < 7.2.0) 667 | azure_graph_rbac (~> 0.16) 668 | azure_mgmt_key_vault (~> 0.17) 669 | azure_mgmt_resources (~> 0.15) 670 | azure_mgmt_security (~> 0.18) 671 | azure_mgmt_storage (~> 0.18) 672 | docker-api (>= 1.26, < 3.0) 673 | google-apis-admin_directory_v1 (~> 0.46.0) 674 | google-apis-cloudkms_v1 (~> 0.41.0) 675 | google-apis-cloudresourcemanager_v1 (~> 0.35.0) 676 | google-apis-compute_v1 (~> 0.83.0) 677 | google-apis-iam_v1 (~> 0.50.0) 678 | google-apis-monitoring_v3 (~> 0.51.0) 679 | google-apis-storage_v1 (~> 0.30.0) 680 | googleauth (>= 0.16.2, < 1.9.0) 681 | inifile (~> 3.0) 682 | train-core (= 3.12.13) 683 | train-winrm (~> 0.2.19) 684 | train-aws (0.2.41) 685 | aws-partitions (~> 1.863.0) 686 | aws-sdk-accessanalyzer (~> 1.44.0) 687 | aws-sdk-account (~> 1.20.0) 688 | aws-sdk-alexaforbusiness (~> 1.67.0) 689 | aws-sdk-amplify (~> 1.54.0) 690 | aws-sdk-apigateway (~> 1.90.0) 691 | aws-sdk-apigatewayv2 (~> 1.53.0) 692 | aws-sdk-applicationautoscaling (~> 1.79.0) 693 | aws-sdk-athena (>= 1.78, < 1.80) 694 | aws-sdk-autoscaling (= 1.102.0) 695 | aws-sdk-batch (~> 1.79.0) 696 | aws-sdk-budgets (~> 1.62.0) 697 | aws-sdk-cloudformation (>= 1.96, < 1.98) 698 | aws-sdk-cloudfront (~> 1.86.0) 699 | aws-sdk-cloudhsm (~> 1.50.0) 700 | aws-sdk-cloudhsmv2 (~> 1.53.0) 701 | aws-sdk-cloudtrail (~> 1.74.0) 702 | aws-sdk-cloudwatch (~> 1.83.0) 703 | aws-sdk-cloudwatchevents (~> 1.69.0) 704 | aws-sdk-cloudwatchlogs (~> 1.75) 705 | aws-sdk-codecommit (~> 1.62.0) 706 | aws-sdk-codedeploy (~> 1.62.0) 707 | aws-sdk-codepipeline (~> 1.67.0) 708 | aws-sdk-cognitoidentity (~> 1.51.0) 709 | aws-sdk-cognitoidentityprovider (~> 1.84) 710 | aws-sdk-configservice (~> 1.103.0) 711 | aws-sdk-core (~> 3.190.0) 712 | aws-sdk-costandusagereportservice (~> 1.53.0) 713 | aws-sdk-databasemigrationservice (~> 1.91.0) 714 | aws-sdk-dynamodb (~> 1.98.0) 715 | aws-sdk-ec2 (>= 1.427, < 1.430) 716 | aws-sdk-ecr (~> 1.68.0) 717 | aws-sdk-ecrpublic (~> 1.25.0) 718 | aws-sdk-ecs (~> 1.135.0) 719 | aws-sdk-efs (~> 1.71.0) 720 | aws-sdk-eks (~> 1.95.0) 721 | aws-sdk-elasticache (~> 1.95.0) 722 | aws-sdk-elasticbeanstalk (~> 1.63.0) 723 | aws-sdk-elasticloadbalancing (~> 1.51.0) 724 | aws-sdk-elasticloadbalancingv2 (~> 1.96.0) 725 | aws-sdk-elasticsearchservice (~> 1.79.0) 726 | aws-sdk-emr (~> 1.81.0) 727 | aws-sdk-eventbridge (~> 1.54.0) 728 | aws-sdk-firehose (~> 1.60.0) 729 | aws-sdk-glue (~> 1.164) 730 | aws-sdk-guardduty (~> 1.85.0) 731 | aws-sdk-iam (~> 1.92.0) 732 | aws-sdk-kafka (~> 1.67.0) 733 | aws-sdk-kinesis (~> 1.54.0) 734 | aws-sdk-kms (~> 1.74) 735 | aws-sdk-lambda (~> 1.113.0) 736 | aws-sdk-macie2 (~> 1.64.0) 737 | aws-sdk-mq (~> 1.58.0) 738 | aws-sdk-networkfirewall (~> 1.39.0) 739 | aws-sdk-networkmanager (~> 1.40.0) 740 | aws-sdk-organizations (~> 1.83.0) 741 | aws-sdk-ram (~> 1.52.0) 742 | aws-sdk-rds (~> 1.208.0) 743 | aws-sdk-redshift (~> 1.107.0) 744 | aws-sdk-route53 (~> 1.83.0) 745 | aws-sdk-route53domains (~> 1.54.0) 746 | aws-sdk-route53resolver (~> 1.51.0) 747 | aws-sdk-s3 (~> 1.141.0) 748 | aws-sdk-s3control (~> 1.74.0) 749 | aws-sdk-secretsmanager (~> 1.87.0) 750 | aws-sdk-securityhub (~> 1.98.0) 751 | aws-sdk-servicecatalog (~> 1.90.0) 752 | aws-sdk-ses (~> 1.58.0) 753 | aws-sdk-shield (~> 1.60.0) 754 | aws-sdk-signer (~> 1.50.0) 755 | aws-sdk-simpledb (~> 1.42.0) 756 | aws-sdk-sms (~> 1.52.0) 757 | aws-sdk-sns (~> 1.70.0) 758 | aws-sdk-sqs (~> 1.69.0) 759 | aws-sdk-ssm (~> 1.162.0) 760 | aws-sdk-states (~> 1.63.0) 761 | aws-sdk-synthetics (~> 1.39.0) 762 | aws-sdk-transfer (~> 1.86.0) 763 | aws-sdk-waf (~> 1.58.0) 764 | aws-sdk-wafv2 (~> 1.74.0) 765 | train-core (3.12.13) 766 | addressable (~> 2.5) 767 | ffi (!= 1.13.0) 768 | json (>= 1.8, < 3.0) 769 | mixlib-shellout (>= 2.0, < 4.0) 770 | net-scp (>= 1.2, < 5.0) 771 | net-ssh (>= 2.9, < 8.0) 772 | train-habitat (0.2.22) 773 | train-winrm (0.2.19) 774 | chef-winrm (~> 2.3.12) 775 | chef-winrm-elevated (~> 1.2.5) 776 | chef-winrm-fs (~> 1.3.7) 777 | tsort (0.2.0) 778 | tty-box (0.7.0) 779 | pastel (~> 0.8) 780 | strings (~> 0.2.0) 781 | tty-cursor (~> 0.7) 782 | tty-color (0.6.0) 783 | tty-cursor (0.7.1) 784 | tty-prompt (0.23.1) 785 | pastel (~> 0.8) 786 | tty-reader (~> 0.8) 787 | tty-reader (0.9.0) 788 | tty-cursor (~> 0.7) 789 | tty-screen (~> 0.8) 790 | wisper (~> 2.0) 791 | tty-screen (0.8.2) 792 | tty-table (0.12.0) 793 | pastel (~> 0.8) 794 | strings (~> 0.2.0) 795 | tty-screen (~> 0.8) 796 | tzinfo (2.0.6) 797 | concurrent-ruby (~> 1.0) 798 | uber (0.1.0) 799 | unicode-display_width (2.6.0) 800 | unicode_utils (1.4.0) 801 | win32-process (0.10.0) 802 | ffi (>= 1.0.0) 803 | winrm (2.3.8) 804 | builder (>= 2.1.2) 805 | erubi (~> 1.8) 806 | gssapi (~> 1.2) 807 | gyoku (~> 1.0) 808 | httpclient (~> 2.2, >= 2.2.0.2) 809 | logging (>= 1.6.1, < 3.0) 810 | nori (~> 2.0) 811 | rexml (~> 3.0) 812 | rubyntlm (~> 0.6.0, >= 0.6.3) 813 | winrm-elevated (1.2.3) 814 | erubi (~> 1.8) 815 | winrm (~> 2.0) 816 | winrm-fs (~> 1.0) 817 | winrm-fs (1.3.5) 818 | erubi (~> 1.8) 819 | logging (>= 1.6.1, < 3.0) 820 | rubyzip (~> 2.0) 821 | winrm (~> 2.0) 822 | wisper (2.0.1) 823 | wmi-lite (1.0.7) 824 | 825 | PLATFORMS 826 | ruby 827 | x64-mingw-ucrt 828 | 829 | DEPENDENCIES 830 | inspec! 831 | kitchen-docker! 832 | kitchen-inspec (= 3.0.0) 833 | kitchen-salt (= 0.7.2) 834 | net-ssh (>= 7.0.0) 835 | test-kitchen (= 3.9.0) 836 | 837 | BUNDLED WITH 838 | 2.3.7 839 | --------------------------------------------------------------------------------