Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions meta/argument_specs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# SPDX-License-Identifier: MIT
---
argument_specs:
main:
short_description: The postfix role.
description: >
The postfix role allows you to install, configure, and start the
Postfix mail transfer agent. It can apply `main.cf` settings,
deploy additional lookup table files under `/etc/postfix`, and
optionally manage firewall and SELinux policy for SMTP-related
ports.
options:
postfix_conf:
type: dict
default: {}
description: >
Dictionary of Postfix `main.cf` parameter names and values.
Keys not supported by the installed Postfix are ignored.
Set `previous` to `replaced` to reinstall Postfix and apply
configuration on a clean installation.
postfix_files:
type: list
elements: dict
default: []
description: >
List of additional files to place in `/etc/postfix`. Each
entry may optionally be converted to a Postfix lookup table
with `postmap`.
options:
name:
type: str
required: true
description: >
Base file name under `/etc/postfix` for the file content.
content:
type: str
required: true
description: >
File content to write under `/etc/postfix/`.
postmap:
type: bool
default: false
description: >
Whether to run `postmap` on the file after it is created
or updated.
postfix_check:
type: bool
default: true
description: >
Whether to run `postfix check` before Postfix is restarted
when the configuration has changed.
postfix_backup:
type: bool
default: false
description: >
Whether to make a single backup copy of `main.cf` before
applying changes. When `postfix_backup_multiple` is `true`,
timestamped backups are used instead.
postfix_backup_multiple:
type: bool
default: true
description: >
Whether to make timestamped backup copies of `main.cf`
before applying changes. When `true`, this overrides
`postfix_backup`.
postfix_manage_firewall:
type: bool
default: false
description: >
Whether to open SMTP-related ports (`25/tcp`, `465/tcp`, and
`587/tcp`) using the firewall role.
postfix_manage_selinux:
type: bool
default: false
description: >
Whether to assign `smtp_port_t` to SMTP-related ports using
the selinux role.
postfix_secure_logging:
type: bool
default: true
description: >
Whether to suppress potentially sensitive task output by
setting `no_log` on tasks that handle credentials and other
secrets.
10 changes: 10 additions & 0 deletions tasks/assert_role_vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SPDX-License-Identifier: MIT
---
- name: Assert postfix_conf previous is replaced when set
ansible.builtin.assert:
that:
- postfix_conf.previous == 'replaced'
fail_msg: >-
postfix_conf.previous must be 'replaced' when set,
got {{ postfix_conf.previous }}
when: postfix_conf.previous is defined
3 changes: 3 additions & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
---
- name: Validate role parameters
ansible.builtin.include_tasks: assert_role_vars.yml

- name: Ensure ansible_facts required by role
include_tasks: set_facts.yml

Expand Down
234 changes: 234 additions & 0 deletions tests/tests_invalid_input.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
# SPDX-License-Identifier: MIT
---
- name: Verify invalid parameters are rejected
hosts: all
tasks:
- name: Run invalid input tests
block:
# ====================================================
# Section 1: Verify role works with valid defaults
# ====================================================
- name: Run role with valid defaults
ansible.builtin.include_tasks: tasks/run_role_with_clear_facts.yml
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Assert postfix service is running after valid defaults
ansible.builtin.service:
name: postfix
state: started
register: __postfix_service
failed_when: __postfix_service is changed # noqa no-handler
Comment thread
richm marked this conversation as resolved.

# ====================================================
# Section 2: argument_specs validation (Ansible 2.11+)
# ====================================================
- name: Run argument specs validation tests
when: ansible_version.full is version("2.11", ">=")
block:
# --- Test: invalid bool postfix_check ---
- name: Argument specs reject non-bool postfix_check
block:
- name: Run role with non-bool postfix_check
ansible.builtin.include_tasks: tasks/run_role_with_clear_facts.yml
vars:
postfix_check: not_a_bool
rescue:
- name: Mark invalid postfix_check type rejected
ansible.builtin.set_fact:
__invalid_input_postfix_check_type_failed: true
Comment thread
coderabbitai[bot] marked this conversation as resolved.
when: >-
'postfix_check' in
(ansible_failed_result | default({}) | to_json)
and 'bool' in
(ansible_failed_result | default({}) | to_json | lower)

- name: Assert invalid postfix_check type was rejected
ansible.builtin.assert:
that:
- >-
__invalid_input_postfix_check_type_failed
| default(false)
fail_msg: >-
argument_specs should reject postfix_check with a
non-boolean value

# --- Test: invalid bool postfix_secure_logging ---
- name: Argument specs reject non-bool postfix_secure_logging
block:
- name: Run role with non-bool postfix_secure_logging
ansible.builtin.include_tasks: tasks/run_role_with_clear_facts.yml
vars:
postfix_secure_logging: not_a_bool
rescue:
- name: Mark invalid postfix_secure_logging type rejected
ansible.builtin.set_fact:
__invalid_input_postfix_secure_logging_type_failed: true
when: >-
'postfix_secure_logging' in
(ansible_failed_result | default({}) | to_json)
and 'bool' in
(ansible_failed_result | default({}) | to_json | lower)

- name: Assert invalid postfix_secure_logging type was rejected
ansible.builtin.assert:
that:
- >-
__invalid_input_postfix_secure_logging_type_failed
| default(false)
fail_msg: >-
argument_specs should reject postfix_secure_logging
with a non-boolean value

# --- Test: invalid type postfix_conf ---
- name: Argument specs reject non-dict postfix_conf
block:
- name: Run role with non-dict postfix_conf
ansible.builtin.include_tasks: tasks/run_role_with_clear_facts.yml
vars:
postfix_conf: not_a_dict
rescue:
- name: Mark invalid postfix_conf type rejected
ansible.builtin.set_fact:
__invalid_input_postfix_conf_type_failed: true
when: >-
'postfix_conf' in
(ansible_failed_result | default({}) | to_json)
and 'dict' in
(ansible_failed_result | default({}) | to_json | lower)

- name: Assert invalid postfix_conf type was rejected
ansible.builtin.assert:
that:
- >-
__invalid_input_postfix_conf_type_failed
| default(false)
fail_msg: >-
argument_specs should reject postfix_conf with a
non-dictionary value

# --- Test: invalid type postfix_files ---
- name: Argument specs reject non-list postfix_files
block:
- name: Run role with non-list postfix_files
ansible.builtin.include_tasks: tasks/run_role_with_clear_facts.yml
vars:
postfix_files: not_a_list
rescue:
- name: Mark invalid postfix_files type rejected
ansible.builtin.set_fact:
__invalid_input_postfix_files_type_failed: true
when: >-
'postfix_files' in
(ansible_failed_result | default({}) | to_json)

- name: Assert invalid postfix_files type was rejected
ansible.builtin.assert:
that:
- >-
__invalid_input_postfix_files_type_failed
| default(false)
fail_msg: >-
argument_specs should reject postfix_files with a
non-list value

# --- Test: missing required name in postfix_files ---
- name: Argument specs reject postfix_files missing name
block:
- name: Run role without required name in postfix_files
ansible.builtin.include_tasks: tasks/run_role_with_clear_facts.yml
vars:
postfix_files:
- content: example content
rescue:
- name: Mark missing postfix_files name rejected
ansible.builtin.set_fact:
__invalid_input_postfix_files_missing_name_failed: true
when: >-
'missing required arguments' in
(ansible_failed_result | default({}) | to_json)
and 'name found in postfix_files' in
(ansible_failed_result | default({}) | to_json)

- name: Assert missing postfix_files name was rejected
ansible.builtin.assert:
that:
- >-
__invalid_input_postfix_files_missing_name_failed
| default(false)
fail_msg: >-
argument_specs should reject postfix_files entries
missing the required name field

# --- Test: missing required content in postfix_files ---
- name: Argument specs reject postfix_files missing content
block:
- name: Run role without required content in postfix_files
ansible.builtin.include_tasks: tasks/run_role_with_clear_facts.yml
vars:
postfix_files:
- name: test_file
rescue:
- name: Mark missing postfix_files content rejected
ansible.builtin.set_fact:
__invalid_input_postfix_files_missing_content_failed: true
when: >-
'missing required arguments' in
(ansible_failed_result | default({}) | to_json)
and 'content found in postfix_files' in
(ansible_failed_result | default({}) | to_json)

- name: Assert missing postfix_files content was rejected
ansible.builtin.assert:
that:
- >-
__invalid_input_postfix_files_missing_content_failed
| default(false)
fail_msg: >-
argument_specs should reject postfix_files entries
missing the required content field

# ====================================================
# Section 3: assert_role_vars validation (all versions)
# ====================================================

- name: Run role with valid postfix_conf previous replaced
ansible.builtin.include_tasks: tasks/run_role_with_clear_facts.yml
vars:
postfix_conf:
previous: replaced

- name: Assert rejects invalid postfix_conf previous value
block:
- name: Run role with invalid postfix_conf previous
ansible.builtin.include_tasks: tasks/run_role_with_clear_facts.yml
vars:
postfix_conf:
previous: not_replaced
Comment thread
coderabbitai[bot] marked this conversation as resolved.
rescue:
- name: Mark invalid postfix_conf previous rejected
ansible.builtin.set_fact:
__invalid_input_postfix_conf_previous_failed: true
when: >-
'postfix_conf.previous must be' in
(ansible_failed_result | default({}) | to_json)

- name: Assert invalid postfix_conf previous was rejected
ansible.builtin.assert:
that:
- >-
__invalid_input_postfix_conf_previous_failed
| default(false)
fail_msg: >-
assert_role_vars should reject postfix_conf.previous
when it is not 'replaced'

always:
- name: Clear test facts
ansible.builtin.set_fact:
__invalid_input_postfix_check_type_failed:
__invalid_input_postfix_secure_logging_type_failed:
__invalid_input_postfix_conf_type_failed:
__invalid_input_postfix_files_type_failed:
__invalid_input_postfix_files_missing_name_failed:
__invalid_input_postfix_files_missing_content_failed:
__invalid_input_postfix_conf_previous_failed:
tags: tests::cleanup