Correctly fix aliases quoting logic (#206)

We were previously incorrectly adding double quotes for the alias values.
According to the man page it's not required. However, there is a requirement if
its a command being pipe.

In addition, the man page mentions this for the alias name:

  The  name  is  a  local  address (no domain part).  Use double quotes when the
  name contains any special characters such as whitespace, `#', `:', or `@'. The
  name is folded to lowercase, in order to make database lookups case
  insensitive.

This includes logic to support this automatically.

- Add new tests for aliases testing all types
- Convert all serverspec tests to inspec
- Add Github actions
- Update platforms to test

Signed-off-by: Lance Albertson <lance@osuosl.org>
This commit is contained in:
Lance Albertson 2025-01-29 14:51:57 -08:00 committed by GitHub
parent 6cb80c3be7
commit 1cd55ab40d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 224 additions and 250 deletions

60
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,60 @@
---
name: ci
"on":
pull_request:
push:
branches:
- main
jobs:
lint-unit:
uses: sous-chefs/.github/.github/workflows/lint-unit.yml@3.0.0
permissions:
actions: write
checks: write
pull-requests: write
statuses: write
integration:
needs: 'lint-unit'
runs-on: ubuntu-latest
strategy:
matrix:
os:
- almalinux-8
- almalinux-9
- amazonlinux-2023
- centos-stream-9
- debian-11
- debian-12
- opensuse-leap-15
- rockylinux-8
- rockylinux-9
- ubuntu-2004
- ubuntu-2204
- ubuntu-2404
suite:
- default
- aliases
- client
- server
- canonical
- sasl-auth-none
- sasl-auth-multiple
- sasl-auth-one
fail-fast: false
steps:
- name: Check out code
uses: actions/checkout@v4 # v4
- name: Install Chef
uses: actionshub/chef-install@2.0.4
- name: Dokken
uses: actionshub/test-kitchen@2.1.0
env:
CHEF_LICENSE: accept-no-persist
KITCHEN_LOCAL_YAML: kitchen.dokken.yml
with:
suite: ${{ matrix.suite }}
os: ${{ matrix.os }}

View File

@ -4,25 +4,24 @@ This file is used to list changes made in each version of the postfix cookbook.
## Unreleased
- Correctly fix aliases quoting logic
- Convert all serverspec tests to inspec
- Add Github actions
- Update platforms to test
## 6.0.29 - *2024-11-18*
Standardise files with files in sous-chefs/repo-management
Standardise files with files in sous-chefs/repo-management
- Standardise files with files in sous-chefs/repo-management
## 6.0.28 - *2024-07-15*
Standardise files with files in sous-chefs/repo-management
Standardise files with files in sous-chefs/repo-management
Standardise files with files in sous-chefs/repo-management
- Standardise files with files in sous-chefs/repo-management
## 6.0.27 - *2024-05-06*
## 6.0.26 - *2023-10-03*
- add installation of postfix addon packages for RHEL 8
- Add installation of postfix addon packages for RHEL 8
## 6.0.25 - *2023-10-03*

View File

@ -14,16 +14,18 @@ verifier:
platforms:
- name: almalinux-8
- name: amazonlinux-2
- name: centos-7
- name: centos-stream-8
- name: debian-10
- name: almalinux-9
- name: amazonlinux-2023
- name: centos-stream-9
- name: debian-11
- name: debian-12
- name: fedora-latest
- name: opensuse-leap-15
- name: rockylinux-8
- name: ubuntu-18.04
- name: rockylinux-9
- name: ubuntu-20.04
- name: ubuntu-22.04
- name: ubuntu-24.04
suites:
- name: default
@ -33,6 +35,17 @@ suites:
- name: aliases
run_list:
- recipe[postfix::aliases]
attributes:
postfix:
aliases:
foo1: bar
foo@bar: foo
foo2: "|/usr/bin/bar"
foo3: foo,bar
foo4: foo@example.com
foo5:
- foo
- bar
- name: client
run_list:

View File

@ -6,5 +6,5 @@
postmaster: root
<% node['postfix']['aliases'].each do |name, value| %>
<%= name %>: <%= [value].flatten.map{|x| if (x.include?("@")) then x else %Q("#{x}") end}.join(', ') %>
<%= name.match?(/[\s#:@]/) ? "\"#{name}\"" : name %>: <%= [value].flatten.map{|x| x.include?("|") ? "\"#{x}\"" : x}.join(',') %>
<% end unless node['postfix']['aliases'].nil? %>

View File

@ -1,3 +1,6 @@
# sysctl missing on SUSE
package 'procps' if platform_family?('suse')
sysctl 'net.ipv6.conf.lo.disable_ipv6' do
value 0
end

View File

@ -0,0 +1,21 @@
control 'aliases' do
describe file '/etc/aliases' do
its('content') do
should cmp <<~EOF
#
# Auto-generated by Chef.
# Local modifications will be overwritten.
#
# See man 5 aliases for format
postmaster: root
foo1: bar
"foo@bar": foo
foo2: "|/usr/bin/bar"
foo3: foo,bar
foo4: foo@example.com
foo5: foo,bar
EOF
end
end
end

View File

@ -0,0 +1 @@
name: aliases

View File

@ -1,24 +0,0 @@
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative './spec_helper'
describe 'postfix::aliases' do
context 'configures' do
describe file('/etc/aliases') do
its(:content) { should match(/^# Auto-generated by Chef/) }
end
end
end

View File

@ -0,0 +1,17 @@
recipient_canonical =
case os.family
when 'suse'
'/etc/postfix/recipient_canonical.lmdb'
else
'/etc/postfix/recipient_canonical.db'
end
control 'canonical' do
describe file recipient_canonical do
it { should be_file }
end
describe file '/etc/postfix/main.cf' do
its('content') { should match(%r{^\s*recipient_canonical_maps\s*=.*\/etc\/postfix\/recipient_canonical\s*$}) }
end
end

View File

@ -0,0 +1 @@
name: canonical

View File

@ -1,23 +0,0 @@
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative './spec_helper'
describe file('/etc/postfix/recipient_canonical.db') do
it { should be_file }
end
describe file('/etc/postfix/main.cf') do
its(:content) { should match(%r{^\s*recipient_canonical_maps\s*=.*\/etc\/postfix\/recipient_canonical\s*$}) }
end

View File

@ -0,0 +1,7 @@
include_controls 'default'
control 'client' do
describe file '/etc/postfix/main.cf' do
its('content') { should match /Configured as client/ }
end
end

View File

@ -0,0 +1,4 @@
name: client
depends:
- name: default
path: test/integration/default

View File

@ -1,22 +0,0 @@
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative './spec_helper'
describe 'postfix::client' do
it 'doesnt configure postfix because solo is unsupported' do
pending 'Postfix may be set up by default on the system, but not configured by Chef because this test assumes it is run under Chef Solo'
end
end

View File

@ -0,0 +1,14 @@
control 'default' do
describe package 'postfix' do
it { should be_installed }
end
describe service 'postfix' do
it { should be_enabled }
it { should be_running }
end
describe file '/etc/postfix/main.cf' do
its('content') { should match(/^# Auto-generated by Chef/) }
end
end

View File

@ -0,0 +1 @@
name: default

View File

@ -1,33 +0,0 @@
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative './spec_helper'
describe 'postfix::default' do
describe package('postfix') do
it { should be_installed }
end
describe service('postfix') do
it { should be_enabled }
it { should be_running }
end
context 'configures' do
describe file("#{postfix_conf_path}/main.cf") do
its(:content) { should match(/^# Auto-generated by Chef/) }
end
end
end

View File

@ -1,19 +0,0 @@
require 'serverspec'
set :backend, :exec
set :path, '/sbin:/usr/local/sbin:$PATH'
def family
fam = 'solaris2'
return fam unless File.exist? '/etc/release'
fam = 'omnios' if File.read('/etc/release') =~ /^\s*(OmniOS)/
fam
end
def postfix_conf_path
if os[:family] == 'solaris' && family == 'omnios'
'/opt/omni/etc/postfix/'
else
'/etc/postfix'
end
end

View File

@ -0,0 +1,19 @@
control 'sasl_auth_multiple' do
describe file '/etc/postfix/sasl_passwd' do
its('content') do
should cmp <<~EOF
# Auto-generated by Chef.
# Local modifications will be overwritten.
relayhost1 kitchenuser:not-a-real-thing
relayhost2 anotherkitchenuser:yet-not-a-real-thing
smtp_sasl_passwd :
smtp_sasl_user_name :
EOF
end
end
describe postfix_conf '/etc/postfix/main.cf' do
its('smtp_sasl_password_maps') { should eq 'hash:/etc/postfix/sasl_passwd' }
end
end

View File

@ -0,0 +1 @@
name: sasl_auth_multiple

View File

@ -1,31 +0,0 @@
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative './spec_helper'
describe 'postfix::sasl_auth' do
let(:sasl_passwd_file) { '/etc/postfix/sasl_passwd' }
it 'manages postfix sasl_passwd' do
expect(file(sasl_passwd_file).content).to match(/^# This file is generated by Chef for/)
end
it 'configures postfix to use the sasl_passwd file' do
expect(file('/etc/postfix/main.cf').content).to match(/^\s*smtp_sasl_password_maps\s*=.*#{sasl_passwd_file}\s*$/)
end
it 'configures postfix sasl_passwd with multiple entries' do
expect(file(sasl_passwd_file).content).to match(/^# This file is generated by Chef for .*\nrelayhost1 kitchenuser:not-a-real-thing\nrelayhost2 anotherkitchenuser:yet-not-a-real-thing\n/)
end
end

View File

@ -0,0 +1,17 @@
control 'sasl_auth_none' do
describe file '/etc/postfix/sasl_passwd' do
its('content') do
should cmp <<~EOF
# Auto-generated by Chef.
# Local modifications will be overwritten.
smtp_sasl_passwd :
smtp_sasl_user_name :
EOF
end
end
describe postfix_conf '/etc/postfix/main.cf' do
its('smtp_sasl_password_maps') { should eq 'hash:/etc/postfix/sasl_passwd' }
end
end

View File

@ -0,0 +1 @@
name: sasl_auth_none

View File

@ -1,31 +0,0 @@
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative './spec_helper'
describe 'postfix::sasl_auth' do
let(:sasl_passwd_file) { '/etc/postfix/sasl_passwd' }
it 'manages postfix sasl_passwd' do
expect(file(sasl_passwd_file).content).to match(/^# Auto-generated by Chef/)
end
it 'configures postfix to use the sasl_passwd file' do
expect(file('/etc/postfix/main.cf').content).to match(/^\s*smtp_sasl_password_maps\s*=.*#{sasl_passwd_file}\s*$/)
end
it 'configures postfix sasl_passwd with nothing in it' do
expect(file(sasl_passwd_file).content).to match(/^# This file is generated by Chef for .*\n/)
end
end

View File

@ -0,0 +1,18 @@
control 'sasl_auth_one' do
describe file '/etc/postfix/sasl_passwd' do
its('content') do
should cmp <<~EOF
# Auto-generated by Chef.
# Local modifications will be overwritten.
relayhost kitchenuser:not-a-real-thing
smtp_sasl_passwd :
smtp_sasl_user_name :
EOF
end
end
describe postfix_conf '/etc/postfix/main.cf' do
its('smtp_sasl_password_maps') { should eq 'hash:/etc/postfix/sasl_passwd' }
end
end

View File

@ -0,0 +1 @@
name: sasl_auth_one

View File

@ -1,31 +0,0 @@
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative './spec_helper'
describe 'postfix::sasl_auth' do
let(:sasl_passwd_file) { '/etc/postfix/sasl_passwd' }
it 'manages postfix sasl_passwd' do
expect(file(sasl_passwd_file).content).to match(/^# This file is generated by Chef for/)
end
it 'configures postfix to use the sasl_passwd file' do
expect(file('/etc/postfix/main.cf').content).to match(/^\s*smtp_sasl_password_maps\s*=.*#{sasl_passwd_file}\s*$/)
end
it 'configures postfix sasl_passwd with one entry' do
expect(file(sasl_passwd_file).content).to match(/^# This file is generated by Chef for .*\nrelayhost kitchenuser:not-a-real-thing\n/)
end
end

View File

@ -0,0 +1,7 @@
include_controls 'default'
control 'server' do
describe file '/etc/postfix/main.cf' do
its('content') { should match /Configured as master/ }
end
end

View File

@ -0,0 +1,4 @@
name: server
depends:
- name: default
path: test/integration/default

View File

@ -1,21 +0,0 @@
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative './spec_helper'
describe 'postfix::server' do
it 'doesnt configure postfix because solo is unsupported' do
pending 'Postfix may be set up by default on the system, but not configured by Chef because this test assumes it is run under Chef Solo'
end
end