From 2d1906b391362c507a842f36c78f3763e3245c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Tarti=C3=A8re?= Date: Wed, 3 Feb 2021 03:03:36 -1000 Subject: [PATCH] Add FreeBSD support (#288) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Do not hardcode /etc/postfix In order to bring support for FreeBSD, do not use the hardcoded /etc/postfix path for the directory containing Postfix configuration: FreeBSD ports are installed with a /usr/local/ prefix (by default) so the configuration files on FreeBSD are stored in the /usr/local/etc/postfix directory. * Add support for FreeBSD * Make it possible to tune the "root" group FreeBSD does not have a "root" group. The corresponding group is named "wheel". Allow to setup a custom "root_group", and adjust FreeBSD configuration to set it to "wheel". * Adjust the test suite so that it pass on FreeBSD * Do not depend on $postfix::* before including postfix Some resources parameters depend on the value of variable from the postfix class. Ensure these values are substitued only after including postfix. * Move default values from hiera to init.pp These values are system-dependent, but this helps seeing the usual default value when genering references. * Move $manage_mailname parameter * Explicitely mark internal classes as private * Remove redundant postfix::params inclusion Co-authored-by: Raphaël Pinson Co-authored-by: Raphaël Pinson --- data/os/FreeBSD.yaml | 8 ++ manifests/canonical.pp | 9 +- manifests/conffile.pp | 8 +- manifests/config.pp | 5 +- manifests/files.pp | 24 ++-- manifests/init.pp | 5 +- manifests/ldap.pp | 4 +- manifests/mailman.pp | 9 +- manifests/map.pp | 13 ++- manifests/mta.pp | 29 +++-- manifests/packages.pp | 2 +- manifests/satellite.pp | 17 ++- manifests/service.pp | 1 + manifests/transport.pp | 11 +- manifests/virtual.pp | 11 +- metadata.json | 7 ++ spec/classes/postfix_spec.rb | 66 +++++++---- spec/defines/postfix_config_spec.rb | 12 +- spec/defines/postfix_map_spec.rb | 9 +- spec/defines/postfix_transport_spec.rb | 16 ++- spec/defines/postfix_virtual_spec.rb | 16 ++- templates/master.cf.FreeBSD.erb | 146 +++++++++++++++++++++++++ 22 files changed, 342 insertions(+), 86 deletions(-) create mode 100644 data/os/FreeBSD.yaml create mode 100644 templates/master.cf.FreeBSD.erb diff --git a/data/os/FreeBSD.yaml b/data/os/FreeBSD.yaml new file mode 100644 index 00000000..be82dfce --- /dev/null +++ b/data/os/FreeBSD.yaml @@ -0,0 +1,8 @@ +--- +postfix::confdir: "/usr/local/etc/postfix" +postfix::manage_mailname: false +postfix::manage_mailx: false +postfix::root_group: "wheel" +postfix::params::master_os_template: "postfix/master.cf.FreeBSD.erb" +postfix::params::restart_cmd: "/usr/local/etc/rc.d/postfix reload" +... diff --git a/manifests/canonical.pp b/manifests/canonical.pp index 17543f86..f8b9f159 100644 --- a/manifests/canonical.pp +++ b/manifests/canonical.pp @@ -35,11 +35,14 @@ # define postfix::canonical ( $destination, - $file='/etc/postfix/canonical', + $file=undef, $ensure='present' ) { + include postfix include ::postfix::augeas + $_file = pick($file, "${postfix::confdir}/canonical") + case $ensure { 'present': { $changes = [ @@ -58,10 +61,10 @@ } augeas {"Postfix canonical - ${name}": - incl => $file, + incl => $_file, lens => 'Postfix_Canonical.lns', changes => $changes, require => [Package['postfix'], Augeas::Lens['postfix_canonical']], - notify => Exec["generate ${file}.db"], + notify => Exec["generate ${_file}.db"], } } diff --git a/manifests/conffile.pp b/manifests/conffile.pp index 2b823523..fab382fd 100644 --- a/manifests/conffile.pp +++ b/manifests/conffile.pp @@ -50,12 +50,14 @@ Enum['present', 'absent', 'directory'] $ensure = 'present', Variant[Array[String], String, Undef] $source = undef, Optional[String] $content = undef, - Stdlib::Absolutepath $path = "/etc/postfix/${name}", + Optional[Stdlib::Absolutepath] $path = undef, String $mode = '0640', Hash $options = {}, Boolean $show_diff = true, ) { - include ::postfix::params + include postfix + + $_path = pick($path, "${postfix::confdir}/${name}") if (!defined(Class['postfix'])) { fail 'You must define class postfix before using postfix::config!' @@ -84,7 +86,7 @@ file { "postfix conffile ${name}": ensure => $ensure, - path => $path, + path => $_path, mode => $mode, owner => 'root', group => 'postfix', diff --git a/manifests/config.pp b/manifests/config.pp index 2aceee72..3c550aa5 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -31,6 +31,7 @@ Optional[String] $value = undef, Enum['present', 'absent', 'blank'] $ensure = 'present', ) { + include postfix if ($ensure == 'present') { assert_type(Pattern[/^.+$/], $value) |$e, $a| { @@ -58,10 +59,10 @@ } augeas { "manage postfix '${title}'": - incl => '/etc/postfix/main.cf', + incl => "${postfix::confdir}/main.cf", lens => 'Postfix_Main.lns', changes => $changes, - require => File['/etc/postfix/main.cf'], + require => File["${postfix::confdir}/main.cf"], } Postfix::Config[$title] ~> Class['postfix::service'] diff --git a/manifests/files.pp b/manifests/files.pp index 2d5a3941..d504622a 100644 --- a/manifests/files.pp +++ b/manifests/files.pp @@ -1,5 +1,6 @@ class postfix::files { - include ::postfix::params + assert_private() + $alias_maps = $postfix::all_alias_maps $amavis_procs = $postfix::amavis_procs @@ -18,6 +19,7 @@ $master_bounce_command = $postfix::master_bounce_command $master_defer_command = $postfix::master_defer_command $myorigin = $postfix::myorigin + $manage_mailname = $postfix::manage_mailname $manage_aliases = $postfix::manage_aliases $manage_root_alias = $postfix::manage_root_alias $root_mail_recipient = $postfix::root_mail_recipient @@ -41,11 +43,13 @@ replace => $manage_conffiles, } - file { '/etc/mailname': - ensure => 'file', - content => "${::fqdn}\n", - mode => '0644', - seltype => $postfix::params::seltype, + if $manage_mailname { + file { '/etc/mailname': + ensure => 'file', + content => "${::fqdn}\n", + mode => '0644', + seltype => $postfix::params::seltype, + } } # Aliases @@ -73,10 +77,10 @@ ) } - file { '/etc/postfix/master.cf': + file { "${postfix::confdir}/master.cf": ensure => 'file', content => $_mastercf_content, - group => 'root', + group => $postfix::root_group, mode => '0644', owner => 'root', seltype => $postfix::params::seltype, @@ -84,9 +88,9 @@ } # Config files - file { '/etc/postfix/main.cf': + file { "${postfix::confdir}/main.cf": ensure => 'file', - group => 'root', + group => $postfix::root_group, mode => '0644', owner => 'root', replace => false, diff --git a/manifests/init.pp b/manifests/init.pp index 45e927a8..cf832242 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -93,6 +93,8 @@ # } # class postfix ( + Stdlib::Absolutepath $confdir = '/etc/postfix', + String $root_group = 'root', String $alias_maps = 'hash:/etc/aliases', Optional[Hash] $configs = {}, Integer $amavis_procs = 2, @@ -106,6 +108,7 @@ Boolean $mailman = false, String $maincf_source = "puppet:///modules/${module_name}/main.cf", Boolean $manage_conffiles = true, + Boolean $manage_mailname = true, Boolean $manage_mailx = true, Optional[String] $mastercf_source = undef, Optional[String] $mastercf_content = undef, @@ -151,7 +154,7 @@ $all_alias_maps = $ldap ? { false => $alias_maps, - true => "${alias_maps}, ldap:/etc/postfix/ldap-aliases.cf", + true => "${alias_maps}, ldap:${confdir}/ldap-aliases.cf", } create_resources('::postfix::config', $configs) diff --git a/manifests/ldap.pp b/manifests/ldap.pp index 7dd83849..9a162916 100644 --- a/manifests/ldap.pp +++ b/manifests/ldap.pp @@ -21,7 +21,7 @@ if $::osfamily == 'Debian' { package {'postfix-ldap': - before => File['/etc/postfix/ldap-aliases.cf'], + before => File["${postfix::confdir}/ldap-aliases.cf"], } } @@ -39,7 +39,7 @@ default => $postfix::ldap_options, } - file {'/etc/postfix/ldap-aliases.cf': + file {"${postfix::confdir}/ldap-aliases.cf": ensure => 'file', owner => 'root', group => 'postfix', diff --git a/manifests/mailman.pp b/manifests/mailman.pp index 5d3f2dd6..41fcb0f7 100644 --- a/manifests/mailman.pp +++ b/manifests/mailman.pp @@ -12,21 +12,22 @@ # mailman => true, # } class postfix::mailman { + include postfix postfix::config { 'virtual_alias_maps': - value => 'hash:/etc/postfix/virtual'; + value => "hash:${postfix::confdir}/virtual"; 'transport_maps': - value => 'hash:/etc/postfix/transport'; + value => "hash:${postfix::confdir}/transport"; 'mailman_destination_recipient_limit': value => '1'; } - postfix::hash { '/etc/postfix/virtual': + postfix::hash { "${postfix::confdir}/virtual": ensure => 'present', } - postfix::hash { '/etc/postfix/transport': + postfix::hash { "${postfix::confdir}/transport": ensure => 'present', } diff --git a/manifests/map.pp b/manifests/map.pp index f947c700..344d86de 100644 --- a/manifests/map.pp +++ b/manifests/map.pp @@ -32,11 +32,14 @@ Variant[Array[String], String, Undef] $source = undef, Optional[Variant[Sensitive[String],String]] $content = undef, String $type = 'hash', - Stdlib::Absolutepath $path = "/etc/postfix/${name}", + Optional[Stdlib::Absolutepath] $path = undef, String[4,4] $mode = '0640' ) { + include postfix include ::postfix::params + $_path = pick($path, "${postfix::confdir}/${name}") + if (!defined(Class['postfix'])) { fail 'You must define class postfix before using postfix::config!' } @@ -58,7 +61,7 @@ file { "postfix map ${name}": ensure => $ensure, - path => $path, + path => $_path, source => $source, content => $content, owner => 'root', @@ -71,7 +74,7 @@ if $type !~ /^(cidr|pcre)$/ { file {"postfix map ${name}.db": ensure => $ensure, - path => "${path}.db", + path => "${_path}.db", owner => 'root', group => 'postfix', mode => $mode, @@ -81,8 +84,8 @@ } $generate_cmd = $ensure ? { - 'absent' => "rm ${path}.db", - 'present' => "postmap ${path}", + 'absent' => "rm ${_path}.db", + 'present' => "postmap ${_path}", } exec {"generate ${name}.db": diff --git a/manifests/mta.pp b/manifests/mta.pp index ee4ae0d7..48f46b60 100644 --- a/manifests/mta.pp +++ b/manifests/mta.pp @@ -26,36 +26,41 @@ # } # class postfix::mta ( - Pattern[/^\S+(?:,\s*\S+)*$/] $mydestination = $postfix::mydestination, - Pattern[/^(?:\S+?(?:(?:,\s+)|(?:\s+))?)*$/] $mynetworks = $postfix::mynetworks, - Pattern[/^\S+$/] $relayhost = $postfix::relayhost, + Optional[Pattern[/^\S+(?:,\s*\S+)*$/]] $mydestination = undef, + Optional[Pattern[/^(?:\S+?(?:(?:,\s+)|(?:\s+))?)*$/]] $mynetworks = undef, + Optional[Pattern[/^\S+$/]] $relayhost = undef, ) { + include postfix + + $_mydestination = pick($mydestination, $postfix::mydestination) + $_mynetworks = pick($mynetworks, $postfix::mynetworks) + $_relayhost = pick($relayhost, $postfix::relayhost) # If direct is specified then relayhost should be blank - if ($relayhost == 'direct') { + if ($_relayhost == 'direct') { postfix::config { 'relayhost': ensure => 'blank' } } else { - postfix::config { 'relayhost': value => $relayhost } + postfix::config { 'relayhost': value => $_relayhost } } - if ($mydestination == 'blank') { + if ($_mydestination == 'blank') { postfix::config { 'mydestination': ensure => 'blank' } } else { - postfix::config { 'mydestination': value => $mydestination } + postfix::config { 'mydestination': value => $_mydestination } } postfix::config { - 'mynetworks': value => $mynetworks; - 'virtual_alias_maps': value => 'hash:/etc/postfix/virtual'; - 'transport_maps': value => 'hash:/etc/postfix/transport'; + 'mynetworks': value => $_mynetworks; + 'virtual_alias_maps': value => "hash:${postfix::confdir}/virtual"; + 'transport_maps': value => "hash:${postfix::confdir}/transport"; } - postfix::hash { '/etc/postfix/virtual': + postfix::hash { "${postfix::confdir}/virtual": ensure => 'present', } - postfix::hash { '/etc/postfix/transport': + postfix::hash { "${postfix::confdir}/transport": ensure => 'present', } diff --git a/manifests/packages.pp b/manifests/packages.pp index ecbcb937..f77b8fcb 100644 --- a/manifests/packages.pp +++ b/manifests/packages.pp @@ -1,5 +1,5 @@ class postfix::packages { - include ::postfix::params + assert_private() package { 'postfix': ensure => $postfix::postfix_ensure, diff --git a/manifests/satellite.pp b/manifests/satellite.pp index 4e98b5e3..60c8637a 100644 --- a/manifests/satellite.pp +++ b/manifests/satellite.pp @@ -23,17 +23,22 @@ # } # class postfix::satellite ( - $mydestination = $postfix::mydestination, - $mynetworks = $postfix::mynetworks, - $relayhost = $postfix::relayhost, + $mydestination = undef, + $mynetworks = undef, + $relayhost = undef, ) { + include postfix assert_type(Pattern[/^\S+$/], $postfix::myorigin) + $_mydestination = pick($mydestination, $postfix::mydestination) + $_mynetworks = pick($mynetworks, $postfix::mynetworks) + $_relayhost = pick($relayhost, $postfix::relayhost) + class { '::postfix::mta': - mydestination => $mydestination, - mynetworks => $mynetworks, - relayhost => $relayhost, + mydestination => $_mydestination, + mynetworks => $_mynetworks, + relayhost => $_relayhost, } postfix::virtual { "@${postfix::myorigin}": diff --git a/manifests/service.pp b/manifests/service.pp index b12a5908..025a5ffa 100644 --- a/manifests/service.pp +++ b/manifests/service.pp @@ -1,4 +1,5 @@ class postfix::service { + assert_private() $manage_aliases = $postfix::manage_aliases diff --git a/manifests/transport.pp b/manifests/transport.pp index 35aeb4cc..3e08a34d 100644 --- a/manifests/transport.pp +++ b/manifests/transport.pp @@ -44,11 +44,14 @@ define postfix::transport ( Optional[String] $destination = undef, Optional[String] $nexthop=undef, - Stdlib::Absolutepath $file='/etc/postfix/transport', + Optional[Stdlib::Absolutepath] $file=undef, Enum['present', 'absent'] $ensure='present' ) { + include postfix include ::postfix::augeas + $_file = pick($file, "${postfix::confdir}/transport") + $smtp_nexthop = (String($nexthop) =~ /\[.*\]/) case $ensure { @@ -104,7 +107,7 @@ augeas {"Postfix transport - ${name}": lens => 'Postfix_Transport.lns', - incl => $file, + incl => $_file, changes => $changes, require => Augeas::Lens['postfix_transport'], } @@ -113,7 +116,7 @@ Package['postfix'] -> Postfix::Transport[$title] } - if defined(Postfix::Hash[$file]) { - Postfix::Transport[$title] ~> Postfix::Hash[$file] + if defined(Postfix::Hash[$_file]) { + Postfix::Transport[$title] ~> Postfix::Hash[$_file] } } diff --git a/manifests/virtual.pp b/manifests/virtual.pp index aaf67ca5..4bd8bbab 100644 --- a/manifests/virtual.pp +++ b/manifests/virtual.pp @@ -40,11 +40,14 @@ define postfix::virtual ( Variant[String, Array[String]] $destination, - Stdlib::Absolutepath $file='/etc/postfix/virtual', + Optional[Stdlib::Absolutepath] $file=undef, Enum['present', 'absent'] $ensure='present' ) { + include postfix include ::postfix::augeas + $_file = pick($file, "${postfix::confdir}/virtual") + $dest_sets = [$destination].flatten.map |$i, $d| { $idx = $i+1 "set \$entry/destination[${idx}] '${d}'" @@ -69,7 +72,7 @@ } augeas {"Postfix virtual - ${name}": - incl => $file, + incl => $_file, lens => 'Postfix_Virtual.lns', changes => $changes, require => Augeas::Lens['postfix_virtual'], @@ -79,7 +82,7 @@ Package['postfix'] -> Postfix::Virtual[$title] } - if defined(Postfix::Hash[$file]) { - Postfix::Virtual[$title] ~> Postfix::Hash[$file] + if defined(Postfix::Hash[$_file]) { + Postfix::Virtual[$title] ~> Postfix::Hash[$_file] } } diff --git a/metadata.json b/metadata.json index 1a497678..4044d4a2 100644 --- a/metadata.json +++ b/metadata.json @@ -60,6 +60,13 @@ "29", "30" ] + }, + { + "operatingsystem": "FreeBSD", + "operatingsystemrelease": [ + "11", + "12" + ] } ], "requirements": [ diff --git a/spec/classes/postfix_spec.rb b/spec/classes/postfix_spec.rb index 0809cfe3..dad7e1e9 100644 --- a/spec/classes/postfix_spec.rb +++ b/spec/classes/postfix_spec.rb @@ -3,6 +3,31 @@ describe 'postfix' do on_supported_os.each do |os, facts| context "on #{os}" do + let(:postfix_main_cf_path) do + case facts[:osfamily] + when 'FreeBSD' then '/usr/local/etc/postfix/main.cf' + else '/etc/postfix/main.cf' + end + end + let(:postfix_master_cf_path) do + case facts[:osfamily] + when 'FreeBSD' then '/usr/local/etc/postfix/master.cf' + else '/etc/postfix/master.cf' + end + end + let(:postfix_transport_path) do + case facts[:osfamily] + when 'FreeBSD' then '/usr/local/etc/postfix/transport' + else '/etc/postfix/transport' + end + end + let(:postfix_virtual_path) do + case facts[:osfamily] + when 'FreeBSD' then '/usr/local/etc/postfix/virtual' + else '/etc/postfix/virtual' + end + end + let(:facts) do facts.merge(augeasversion: '1.2.0', puppetversion: Puppet.version) @@ -10,7 +35,6 @@ context 'when using defaults' do it { is_expected.to contain_package('postfix') } - it { is_expected.to contain_package('mailx') } it { is_expected.to contain_exec('newaliases').with_refreshonly('true') } it { is_expected.to contain_postfix__config('myorigin').with_value('foo.example.com') } it { is_expected.to contain_postfix__config('alias_maps').with_value('hash:/etc/aliases') } @@ -19,10 +43,11 @@ it { is_expected.to contain_mailalias('root').with_recipient('nobody') } context 'when on Debian family', excl: facts[:osfamily] != 'Debian' do + it { is_expected.to contain_package('mailx') } it { is_expected.to contain_file('/etc/mailname').without('seltype').with_content("foo.example.com\n") } it { is_expected.to contain_file('/etc/aliases').without('seltype').with_content("# file managed by puppet\n") } - it { is_expected.to contain_file('/etc/postfix/master.cf').without('seltype') } - it { is_expected.to contain_file('/etc/postfix/main.cf').without('seltype') } + it { is_expected.to contain_file(postfix_master_cf_path).without('seltype') } + it { is_expected.to contain_file(postfix_main_cf_path).without('seltype') } it { is_expected.to contain_service('postfix').with( @@ -35,9 +60,10 @@ end context 'when on RedHat family', excl: facts[:osfamily] != 'RedHat' do + it { is_expected.to contain_package('mailx') } it { is_expected.to contain_file('/etc/mailname').with_seltype('postfix_etc_t').with_content("foo.example.com\n") } - it { is_expected.to contain_file('/etc/postfix/master.cf').with_seltype('postfix_etc_t') } - it { is_expected.to contain_file('/etc/postfix/main.cf').with_seltype('postfix_etc_t') } + it { is_expected.to contain_file(postfix_master_cf_path).with_seltype('postfix_etc_t') } + it { is_expected.to contain_file(postfix_main_cf_path).with_seltype('postfix_etc_t') } it { is_expected.to contain_postfix__config('sendmail_path') } it { is_expected.to contain_postfix__config('newaliases_path') } @@ -91,7 +117,9 @@ end context('when on other', excl: (facts[:osfamily] != 'RedHat' || facts[:operatingsystem] == 'Fedora' || ['6', '7', '8'].include?(facts[:operatingsystemmajrelease]))) do - it { is_expected.to contain_file('/etc/aliases').with_seltype('postfix_etc_t').with_content("# file managed by puppet\n") } + context('on Linux', excl: facts[:osfamily] != 'Linux') do + it { is_expected.to contain_file('/etc/aliases').with_seltype('postfix_etc_t').with_content("# file managed by puppet\n") } + end it { is_expected.to contain_service('postfix').with( ensure: 'running', @@ -134,7 +162,7 @@ it { is_expected.to contain_file('/etc/aliases').without('seltype').with_content("# file managed by puppet\n") } it { is_expected.to contain_exec('newaliases').with_refreshonly('true') } it { - is_expected.to contain_file('/etc/postfix/master.cf').without('seltype').with_content( + is_expected.to contain_file(postfix_master_cf_path).without('seltype').with_content( %r{smtp inet n - - - - smtpd}, ).with_content( %r{amavis unix}, @@ -154,7 +182,7 @@ %r{^submission inet n}, ) } - it { is_expected.to contain_file('/etc/postfix/main.cf').without('seltype') } + it { is_expected.to contain_file(postfix_main_cf_path).without('seltype') } it { is_expected.to contain_postfix__config('myorigin').with_value('localhost') } it { is_expected.to contain_postfix__config('alias_maps').with_value('hash:/etc/aliases') } @@ -196,7 +224,7 @@ end it 'adjusts the content of /etc/postfix/master.cf specifying the user' do - is_expected.to contain_file('/etc/postfix/master.cf').with_seltype('postfix_etc_t').with_content(%r{user=bar}) + is_expected.to contain_file(postfix_master_cf_path).with_content(%r{user=bar}) end end context 'when mailman is true' do @@ -301,7 +329,7 @@ end it 'updates master.cf with the specified flags to smtp' do - is_expected.to contain_file('/etc/postfix/master.cf').with_seltype('postfix_etc_t').with_content( + is_expected.to contain_file(postfix_master_cf_path).with_content( %r{smtp inet n - - - - smtpd}, ).with_content( %r{^smtp.*\n.*smtpd_client_restrictions=check_client_access,hash:}, @@ -316,7 +344,7 @@ end it 'updates master.cf with the specified flags to smtps' do - is_expected.to contain_file('/etc/postfix/master.cf').with_content(%r{^smtps inet n}) + is_expected.to contain_file(postfix_master_cf_path).with_content(%r{^smtps inet n}) end end context 'when mta is enabled' do @@ -326,8 +354,8 @@ is_expected.to contain_postfix__config('mydestination').with_value('1.2.3.4') is_expected.to contain_postfix__config('mynetworks').with_value('127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128') is_expected.to contain_postfix__config('relayhost').with_value('2.3.4.5') - is_expected.to contain_postfix__config('virtual_alias_maps').with_value('hash:/etc/postfix/virtual') - is_expected.to contain_postfix__config('transport_maps').with_value('hash:/etc/postfix/transport') + is_expected.to contain_postfix__config('virtual_alias_maps').with_value("hash:#{postfix_virtual_path}") + is_expected.to contain_postfix__config('transport_maps').with_value("hash:#{postfix_transport_path}") end it { is_expected.to contain_class('postfix::mta') } context 'and satellite is also enabled' do @@ -377,8 +405,8 @@ is_expected.to contain_postfix__config('mydestination').with_value('1.2.3.4') is_expected.to contain_postfix__config('mynetworks').with_value('127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128') is_expected.to contain_postfix__config('relayhost').with_value('2.3.4.5') - is_expected.to contain_postfix__config('virtual_alias_maps').with_value('hash:/etc/postfix/virtual') - is_expected.to contain_postfix__config('transport_maps').with_value('hash:/etc/postfix/transport') + is_expected.to contain_postfix__config('virtual_alias_maps').with_value("hash:#{postfix_virtual_path}") + is_expected.to contain_postfix__config('transport_maps').with_value("hash:#{postfix_transport_path}") end context 'and mta is also enabled' do let(:params) { { mta: true, satellite: true, mydestination: '1.2.3.4', relayhost: '2.3.4.5' } } @@ -399,28 +427,28 @@ let(:params) { { use_amavisd: true } } it 'updates master.cf with the specified flags to amavis' do - is_expected.to contain_file('/etc/postfix/master.cf').with_content(%r{amavis unix}) + is_expected.to contain_file(postfix_master_cf_path).with_content(%r{amavis unix}) end end context 'when use_dovecot_lda is true' do let(:params) { { use_dovecot_lda: true } } it 'updates master.cf with the specified flags to dovecot' do - is_expected.to contain_file('/etc/postfix/master.cf').with_content(%r{dovecot.*\n.* user=vmail:vmail }) + is_expected.to contain_file(postfix_master_cf_path).with_content(%r{dovecot.*\n.* user=vmail:vmail }) end end context 'when use_schleuder is true' do let(:params) { { use_schleuder: true } } it 'updates master.cf with the specified flags to schleuder' do - is_expected.to contain_file('/etc/postfix/master.cf').with_content(%r{schleuder}) + is_expected.to contain_file(postfix_master_cf_path).with_content(%r{schleuder}) end end context 'when use_sympa is true' do let(:params) { { use_sympa: true } } it 'updates master.cf to include sympa' do - is_expected.to contain_file('/etc/postfix/master.cf').with_content(%r{sympa}) + is_expected.to contain_file(postfix_master_cf_path).with_content(%r{sympa}) end end context 'when manage_root_alias is false' do diff --git a/spec/defines/postfix_config_spec.rb b/spec/defines/postfix_config_spec.rb index f7809d78..db8b311f 100644 --- a/spec/defines/postfix_config_spec.rb +++ b/spec/defines/postfix_config_spec.rb @@ -9,6 +9,12 @@ on_supported_os.each do |os, facts| context "on #{os}" do + let(:postfix_main_cf_path) do + case facts[:osfamily] + when 'FreeBSD' then '/usr/local/etc/postfix/main.cf' + else '/etc/postfix/main.cf' + end + end let(:facts) do facts end @@ -75,7 +81,7 @@ it { is_expected.to contain_augeas("manage postfix 'foo'").with( - incl: '/etc/postfix/main.cf', + incl: postfix_main_cf_path, lens: 'Postfix_Main.lns', changes: "set foo 'bar'", ) @@ -92,7 +98,7 @@ it { is_expected.to contain_augeas("manage postfix 'foo'").with( - incl: '/etc/postfix/main.cf', + incl: postfix_main_cf_path, lens: 'Postfix_Main.lns', changes: 'rm foo', ) @@ -109,7 +115,7 @@ it { is_expected.to contain_augeas("manage postfix 'foo'").with( - incl: '/etc/postfix/main.cf', + incl: postfix_main_cf_path, lens: 'Postfix_Main.lns', changes: 'clear foo', ) diff --git a/spec/defines/postfix_map_spec.rb b/spec/defines/postfix_map_spec.rb index e08274ef..15cc98b4 100644 --- a/spec/defines/postfix_map_spec.rb +++ b/spec/defines/postfix_map_spec.rb @@ -9,6 +9,13 @@ on_supported_os.each do |os, facts| context "on #{os}" do + let(:postfix_foo_db_path) do + case facts[:osfamily] + when 'FreeBSD' then '/usr/local/etc/postfix/foo.db' + else '/etc/postfix/foo.db' + end + end + let(:facts) do facts end @@ -110,7 +117,7 @@ it { is_expected.to contain_file('postfix map foo').with_ensure('absent') } it { is_expected.to contain_file('postfix map foo').without_notify } it { is_expected.to contain_file('postfix map foo.db').with_ensure('absent') } - it { is_expected.to contain_exec('generate foo.db').with(command: 'rm /etc/postfix/foo.db') } + it { is_expected.to contain_exec('generate foo.db').with(command: "rm #{postfix_foo_db_path}") } end context 'when using pcre type' do diff --git a/spec/defines/postfix_transport_spec.rb b/spec/defines/postfix_transport_spec.rb index fecef36f..34c19c1d 100644 --- a/spec/defines/postfix_transport_spec.rb +++ b/spec/defines/postfix_transport_spec.rb @@ -4,11 +4,21 @@ let(:title) { 'foo' } let :pre_condition do - "class { '::augeas': }" + <<-EOT + class { '::augeas': } + class { '::postfix': } + EOT end on_supported_os.each do |os, facts| context "on #{os}" do + let(:postfix_transport_path) do + case facts[:osfamily] + when 'FreeBSD' then '/usr/local/etc/postfix/transport' + else '/etc/postfix/transport' + end + end + let(:facts) do facts.merge(augeasversion: '1.2.0', puppetversion: Puppet.version) @@ -107,7 +117,7 @@ it { is_expected.to contain_class('postfix::augeas') } it { is_expected.to contain_augeas('Postfix transport - foo').with( - incl: '/etc/postfix/transport', + incl: postfix_transport_path, lens: 'Postfix_Transport.lns', changes: [ "set pattern[. = 'foo'] 'foo'", @@ -183,7 +193,7 @@ it { is_expected.to contain_class('postfix::augeas') } it { is_expected.to contain_augeas('Postfix transport - foo').with( - incl: '/etc/postfix/transport', + incl: postfix_transport_path, lens: 'Postfix_Transport.lns', changes: [ "rm pattern[. = 'foo']", diff --git a/spec/defines/postfix_virtual_spec.rb b/spec/defines/postfix_virtual_spec.rb index c1cc8444..69a571c2 100644 --- a/spec/defines/postfix_virtual_spec.rb +++ b/spec/defines/postfix_virtual_spec.rb @@ -4,11 +4,21 @@ let(:title) { 'foo' } let :pre_condition do - "class { '::augeas': }" + <<-EOT + class { '::augeas': } + class { '::postfix': } + EOT end on_supported_os.each do |os, facts| context "on #{os}" do + let(:postfix_virutal_path) do + case facts[:osfamily] + when 'FreeBSD' then '/usr/local/etc/postfix/virtual' + else '/etc/postfix/virtual' + end + end + let(:facts) do facts.merge(augeasversion: '1.2.0', puppetversion: Puppet.version) @@ -106,7 +116,7 @@ it { is_expected.to contain_class('postfix::augeas') } it { is_expected.to contain_augeas('Postfix virtual - foo').with( - incl: '/etc/postfix/virtual', + incl: postfix_virutal_path, lens: 'Postfix_Virtual.lns', changes: [ "defnode entry pattern[. = 'foo'] 'foo'", @@ -175,7 +185,7 @@ it { is_expected.to contain_class('postfix::augeas') } it { is_expected.to contain_augeas('Postfix virtual - foo').with( - incl: '/etc/postfix/virtual', + incl: postfix_virutal_path, lens: 'Postfix_Virtual.lns', changes: [ "rm pattern[. = 'foo']", diff --git a/templates/master.cf.FreeBSD.erb b/templates/master.cf.FreeBSD.erb new file mode 100644 index 00000000..7f2899fa --- /dev/null +++ b/templates/master.cf.FreeBSD.erb @@ -0,0 +1,146 @@ +# file managed by puppet +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master" or +# on-line: http://www.postfix.org/master.5.html). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (no) (never) (100) +# ========================================================================== +<% if @master_smtp -%> +<%= @master_smtp %> +<% elsif @smtp_listen == 'all' -%> +smtp inet n - <%= @jail %> - - smtpd +<% else -%> +<%= @smtp_listen %>:smtp inet n - <%= @jail %> - - smtpd +<% end -%> +<% if @master_submission -%> +<%= @master_submission %> +<% end -%> +<% if @master_smtps -%> +<%= @master_smtps %> +<% end -%> +#smtp inet n - n - 1 postscreen +#smtpd pass - - n - - smtpd +#dnsblog unix - - n - 0 dnsblog +#tlsproxy unix - - n - 0 tlsproxy +#submission inet n - n - - smtpd +# -o syslog_name=postfix/submission +# -o smtpd_tls_security_level=encrypt +# -o smtpd_sasl_auth_enable=yes +# -o smtpd_tls_auth_only=yes +# -o smtpd_reject_unlisted_recipient=no +# -o smtpd_client_restrictions=$mua_client_restrictions +# -o smtpd_helo_restrictions=$mua_helo_restrictions +# -o smtpd_sender_restrictions=$mua_sender_restrictions +# -o smtpd_recipient_restrictions= +# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING +#smtps inet n - n - - smtpd +# -o syslog_name=postfix/smtps +# -o smtpd_tls_wrappermode=yes +# -o smtpd_sasl_auth_enable=yes +# -o smtpd_reject_unlisted_recipient=no +# -o smtpd_client_restrictions=$mua_client_restrictions +# -o smtpd_helo_restrictions=$mua_helo_restrictions +# -o smtpd_sender_restrictions=$mua_sender_restrictions +# -o smtpd_recipient_restrictions= +# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING +#628 inet n - n - - qmqpd +pickup unix n - <%= @jail %> 60 1 pickup +cleanup unix n - <%= @jail %> - 0 cleanup +qmgr unix n - n 300 1 qmgr +#qmgr unix n - n 300 1 oqmgr +tlsmgr unix - - <%= @jail %> 1000? 1 tlsmgr +rewrite unix - - <%= @jail %> - - trivial-rewrite +bounce unix - - <%= @jail %> - 0 <%= @master_bounce_command %> +defer unix - - <%= @jail %> - 0 <%= @master_defer_command %> +trace unix - - <%= @jail %> - 0 bounce +verify unix - - <%= @jail %> - 1 verify +flush unix n - <%= @jail %> 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - <%= @jail %> - - smtp +relay unix - - <%= @jail %> - - smtp + -o syslog_name=postfix/$service_name +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - <%= @jail %> - - showq +error unix - - <%= @jail %> - - error +retry unix - - <%= @jail %> - - error +discard unix - - <%= @jail %> - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - <%= @jail %> - - lmtp +anvil unix - - <%= @jail %> - 1 anvil +scache unix - - <%= @jail %> - 1 scache +postlog unix-dgram n - <%= @jail %> - 1 postlogd +# +# ==================================================================== +# Interfaces to non-Postfix software. Be sure to examine the manual +# pages of the non-Postfix software to find out what options it wants. +# +# Many of the following services use the Postfix pipe(8) delivery +# agent. See the pipe(8) man page for information about ${recipient} +# and other message envelope options. +# ==================================================================== +# +# maildrop. See the Postfix MAILDROP_README file for details. +# Also specify in main.cf: maildrop_destination_recipient_limit=1 +# +#maildrop unix - n n - - pipe +# flags=DRXhu user=<%= @mail_user %> argv=/usr/local/bin/maildrop -d ${recipient} +# +# ==================================================================== +# +# Recent Cyrus versions can use the existing "lmtp" master.cf entry. +# +# Specify in cyrus.conf: +# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 +# +# Specify in main.cf one or more of the following: +# mailbox_transport = lmtp:inet:localhost +# virtual_transport = lmtp:inet:localhost +# +# ==================================================================== +# +# Cyrus 2.1.5 (Amos Gouaux) +# Also specify in main.cf: cyrus_destination_recipient_limit=1 +# +#cyrus unix - n n - - pipe +# flags=DRX user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} +# +# ==================================================================== +# +# Old example of delivery via Cyrus. +# +#old-cyrus unix - n n - - pipe +# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user} +# +# ==================================================================== +# +# See the Postfix UUCP_README file for configuration details. +# +#uucp unix - n n - - pipe +# flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) +# +# ==================================================================== +# +# Other external delivery methods. +# +#ifmail unix - n n - - pipe +# flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) +# +#bsmtp unix - n n - - pipe +# flags=Fq. user=bsmtp argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient +# +#scalemail-backend unix - n n - 2 pipe +# flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store +# ${nexthop} ${user} ${extension} +# +#mailman unix - n n - - pipe +# flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py +# ${nexthop} ${user}