Compare commits

...

12 commits
v1.0.0 ... main

20 changed files with 270 additions and 161 deletions

View file

@ -0,0 +1,18 @@
---
on: [push]
jobs:
lint:
runs-on: docker
container:
image: code.waks.be/nishiki/molecule:docker
steps:
- uses: actions/checkout@v3
- run: ansible-lint .
- run: yamllint .
molecule:
runs-on: docker
container:
image: code.waks.be/nishiki/molecule:docker
steps:
- uses: actions/checkout@v3
- run: molecule test

2
.gitignore vendored
View file

@ -1,2 +1,2 @@
.kitchen/*
*.pyc

10
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,10 @@
---
image: nishiki/molecule:docker
before_script:
- molecule --version
molecule:
stage: test
script:
- molecule test

View file

@ -1,27 +0,0 @@
---
driver:
name: docker_cli
transport:
name: docker_cli
provisioner:
name: ansible_playbook
hosts: localhost
require_ansible_repo: false
require_ansible_omnibus: false
require_chef_for_busser: true
ansible_verbose: false
ansible_inventory: ./test/integration/inventory
platforms:
- name: debian-9
driver_config:
image: "nishiki/debian9:ansible-<%= ENV['ANSIBLE_VERSION'] ? ENV['ANSIBLE_VERSION'] : '2.7' %>"
command: /bin/systemd
volume:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
security_opt: seccomp=unconfined
suites:
- name: default

View file

@ -1,38 +0,0 @@
---
AllCops:
Exclude:
- db/**/*
- config/**/*
- Vagrantfile
TargetRubyVersion: 2.4
Naming/AccessorMethodName:
Enabled: false
Lint/RescueWithoutErrorClass:
Enabled: false
Metrics/LineLength:
Max: 120
Metrics/CyclomaticComplexity:
Enabled: false
Metrics/PerceivedComplexity:
Enabled: false
Metrics/MethodLength:
Enabled: false
Metrics/BlockLength:
Enabled: false
Metrics/ClassLength:
Enabled: false
Metrics/AbcSize:
Enabled: false
Style/NumericLiteralPrefix:
Enabled: false
Style/FrozenStringLiteralComment:
Enabled: false
Style/CommandLiteral:
Enabled: true
EnforcedStyle: percent_x
Style/Documentation:
Enabled: false

View file

@ -5,5 +5,32 @@ Which is based on [Keep A Changelog](http://keepachangelog.com/)
## [Unreleased]
## [v1.0.0] - 2019-03-07
### Changed
- test: use personal docker registry
## v2.0.0 - 2021-08-20
### Breaked
- use new variable postfix_config
### Added
- test: add suport debian 10 and 11
- feat: add bsd-mailx package
- feat: add transport map
- feat: add aliases
### Changed
- chore: use FQCN for module name
- test: replace kitchen to molecule
### Removed
- test: remove support debian 9
## v1.0.0 - 2019-03-07
- first version

View file

@ -1,20 +1,53 @@
# Ansible role: Postfix MTA
[![Version](https://img.shields.io/badge/latest_version-1.0.0-green.svg)](https://git.yaegashi.fr/nishiki/ansible-role-postfix_mta/releases)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://git.yaegashi.fr/nishiki/ansible-role-postfix_mta/src/branch/master/LICENSE)
[![Version](https://img.shields.io/badge/latest_version-2.0.0-green.svg)](https://code.waks.be/nishiki/ansible-role-postfix_mta/releases)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://code.waks.be/nishiki/ansible-role-postfix_mta/src/branch/main/LICENSE)
[![Build](https://code.waks.be/nishiki/ansible-role-postfix_mta/actions/workflows/molecule.yml/badge.svg?branch=main)](https://code.waks.be/nishiki/ansible-role-postfix_mta/actions?workflow=molecule.yml)
Install and configure an simple mta with postfix
## Requirements
* Ansible >= 2.7
* Debian Stretch
- Ansible >= 2.9
- Debian
- Bullseye
- Bookworm
## Role variables
- `postfix_config` - hash with config
* `postfix_hostname` - the server hostname (default: `ansible_fqdn`)
* `postfix_origin` - the domain to send mail (default: `$myhostname`)
* `postfix_protocols` - protocols to listen (default: `all`)
```
smtpd_banner: $myhostname ESMTP $mail_name (Debian/GNU)
biff: 'no'
append_dot_mydomain: 'no'
readme_directory: 'no'
compatibility_level: 2
myhostname: '{{ ansible_fqdn }}'
myorigin: $myhostname
mydestination: $myhostname, localhost
default_transport: smtp
mynetworks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit: '0'
recipient_delimiter: '+'
inet_interfaces: localhost
inet_protocols: all
```
- `postfix_transports` - hash with the transport configuration
```
google.com: smtp:127.0.0.1
```
- `postfix_aliases` - hash with the aliases
```
root:
- abuse
- admin
admin: root@local.loc
```
## How to use
@ -25,25 +58,21 @@ Install and configure an simple mta with postfix
```
## Development
### Test syntax with yamllint
* install `python` and `python-pip`
* install yamllint `pip install yamllint`
* run `yamllint .`
### Test with molecule and docker
### Test syntax with ansible-lint
* install `python` and `python-pip`
* install yamllint `pip install ansible-lint`
* run `ansible-lint .`
- install [docker](https://docs.docker.com/engine/installation/)
- install `python3` and `python3-pip`
- install molecule and dependencies `pip3 install molecule molecule-docker docker ansible-lint pytest-testinfra yamllint`
- run `molecule test`
### Tests with docker
* install [docker](https://docs.docker.com/engine/installation/)
* install ruby
* install bundler `gem install bundler`
* install dependencies `bundle install`
* run the tests `kitchen test`
- install [docker](https://docs.docker.com/engine/installation/)
- install ruby
- install bundler `gem install bundler`
- install dependencies `bundle install`
- run the tests `kitchen test`
## License

View file

@ -1,4 +1,22 @@
---
postfix_hostname: '{{ ansible_fqdn }}'
postfix_origin: '$myhostname'
postfix_protocols: all
postfix_hostname: "{{ ansible_fqdn }}"
postfix_origin: "$myhostname"
postfix_config: {}
postfix_default_config:
smtpd_banner: $myhostname ESMTP $mail_name (Debian/GNU)
biff: "no"
append_dot_mydomain: "no"
readme_directory: "no"
compatibility_level: 2
myhostname: "{{ ansible_fqdn }}"
myorigin: $myhostname
mydestination: $myhostname, localhost
default_transport: smtp
mynetworks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit: "0"
recipient_delimiter: "+"
inet_interfaces: localhost
inet_protocols: all
postfix_full_config: "{{ postfix_default_config | combine(postfix_config) }}"
postfix_transports: {}
postfix_aliases: {}

View file

@ -1,5 +1,11 @@
---
- name: reload postfix
systemd:
- name: Reload postfix
ansible.builtin.service:
name: postfix
state: reloaded
- name: Map transport # noqa no-changed-when
ansible.builtin.command: postmap /etc/postfix/transport
- name: Map aliases # noqa no-changed-when
ansible.builtin.command: postalias /etc/postfix/aliases

View file

@ -1,16 +1,18 @@
---
galaxy_info:
role_name: postfix-mta
role_name: postfix_mta
namespace: nishiki
author: Adrien Waksberg
company: Adrien Waksberg
description: Install and configure a simple mta with postfix
license: Apache2
min_ansible_version: 2.7
min_ansible_version: "2.9"
platforms:
- name: Debian
versions:
- stretch
- bullseye
- bookworm
galaxy_tags:
- postfix

View file

@ -0,0 +1,22 @@
---
- name: Converge
hosts: all
roles:
- ansible-role-postfix_mta
vars:
postfix_config:
inet_protocols: ipv4
transport_maps: hash:/etc/postfix/transport
aliases_maps: hash:/etc/postfix/aliases
postfix_transports:
google.com: smtp:127.0.0.1
postfix_aliases:
root:
- admin
- abuse
admin: admin@localhost.loc
pre_tasks:
- name: update apt cache
ansible.builtin.apt:
update_cache: true

View file

@ -0,0 +1,28 @@
---
driver:
name: docker
platforms:
- name: debian12
image: code.waks.be/nishiki/molecule:debian12
privileged: true
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
command: /bin/systemd
capabilities:
- SYS_ADMIN
- name: debian11
image: code.waks.be/nishiki/molecule:debian11
privileged: true
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
command: /bin/systemd
capabilities:
- SYS_ADMIN
lint: |
set -e
yamllint .
ansible-lint .
verifier:
name: testinfra

View file

@ -0,0 +1,42 @@
import testinfra.utils.ansible_runner
def test_packages(host):
for package_name in ['postfix', 'bsd-mailx']:
package = host.package(package_name)
assert package.is_installed
def test_config_file(host):
path = host.file('/etc/postfix/main.cf')
assert path.exists
assert path.is_file
assert path.user == 'root'
assert path.group == 'root'
assert path.mode == 0o644
assert path.contains('inet_protocols = ipv4')
def test_transport_file(host):
path = host.file('/etc/postfix/transport')
assert path.exists
assert path.is_file
assert path.user == 'root'
assert path.group == 'root'
assert path.mode == 0o644
assert path.contains('google.com smtp:127.0.0.1')
def test_aliases_file(host):
path = host.file('/etc/postfix/aliases')
assert path.exists
assert path.is_file
assert path.user == 'root'
assert path.group == 'root'
assert path.mode == 0o644
assert path.contains('root: admin,abuse')
def test_service(host):
service = host.service('postfix')
assert service.is_running
assert service.is_enabled
def test_socket(host):
socket = host.socket('tcp://127.0.0.1:25')
assert socket.is_listening

View file

@ -1,22 +1,31 @@
---
- name: install package
apt:
name: postfix
- name: Install packages
ansible.builtin.package:
name:
- postfix
- bsd-mailx
tags: postfix
- name: copy file configuration
template:
src: main.cf.j2
dest: /etc/postfix/main.cf
- name: Copy file configuration
ansible.builtin.template:
src: '{{ item }}.j2'
dest: '/etc/postfix/{{ item }}'
owner: root
group: root
mode: 0644
notify: reload postfix
loop:
- main.cf
- aliases
- transport
notify:
- Reload postfix
- Map aliases
- Map transport
tags: postfix
- name: enable and start service
systemd:
- name: Enable and start service
ansible.builtin.service:
name: postfix
enabled: yes
enabled: true
state: started
tags: postfix

9
templates/aliases.j2 Normal file
View file

@ -0,0 +1,9 @@
# {{ ansible_managed }}
{% for alias, redirect in postfix_aliases.items() %}
{% if redirect is string %}
{{ alias }}: {{ redirect }}
{% else %}
{{ alias }}: {{ redirect|join(',') }}
{% endif %}
{% endfor %}

View file

@ -1,16 +1,5 @@
# {{ ansible_managed }}
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 2
myhostname = {{ postfix_hostname }}
myorigin = {{ postfix_origin }}
mydestination = $myhostname, localhost
default_transport = smtp
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = localhost
inet_protocols = {{ postfix_protocols }}
{% for option, value in postfix_full_config.items() %}
{{ option }} = {{ value }}
{% endfor %}

5
templates/transport.j2 Normal file
View file

@ -0,0 +1,5 @@
# {{ ansible_managed }}
{% for domain, transport in postfix_transports.items() %}
{{ domain }} {{ transport }}
{% endfor %}

View file

@ -1,8 +0,0 @@
---
- hosts: default
connection: local
vars:
postfix_protocols: ipv4
roles:
- ansible-role-postfix-mta

View file

@ -1,30 +0,0 @@
require 'serverspec'
set :backend, :exec
puts
puts '================================'
puts %x(ansible --version)
puts '================================'
describe package('postfix') do
it { should be_installed }
end
describe file('/etc/postfix/main.cf') do
it { should be_file }
it { should be_mode 644 }
it { should be_owned_by 'root' }
it { should be_grouped_into 'root' }
it { should contain 'protocols = ipv4' }
end
describe service('postfix') do
it { should be_enabled }
it { should be_running }
it { should be_running.under('systemd') }
end
describe port(25) do
it { should be_listening }
end

View file

@ -1,2 +0,0 @@
[default]
localhost