-
Notifications
You must be signed in to change notification settings - Fork 24
feat: Argument spec implementation for postfix role #258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
richm
merged 4 commits into
linux-system-roles:main
from
DonatSzabo:argument_spec_implementation-dszabo
Sep 10, 2026
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | ||
|
|
||
| - 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 | ||
|
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 | ||
|
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 | ||
|
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 | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.