mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-23 05:10:22 -07:00
New module: iptables_state (#271)
* restart from last state * test (sanity) doc fragment placeholder * test (sanity) remove doc fragment placeholder * remove internal params from DOCUMENTATION * update ignore-2.10.txt * doc: add changelog fragment * shorten changelog fragment * Revert "shorten changelog fragment" This reverts commit f9aea0d1eaefda139fd5b79bd0eb127c09a433fb. * test with posix/group1 * test with posix/group3 * test with posix/group5 * test with posix/group4 * test with posix/group3 * New modules/action plugins automatically get a changelog entry * fix: styles * Revert "remove internal params from DOCUMENTATION" This reverts commit 7d5fcf4b17e4cd5b0afc08fd1bd3fcef5fcaee26. * drop neutral/informative/stateless behaviour * update tasks after changes in module * use FQCN in EXAMPLES * add tests to validate error handling about required params * doc: remove outdated sentence * do not document internal parameters * display timeout value in failure message * remove inapropriate comment * merge results and clean them up only once * conditionally remove tmp path * at least one iteration is required * remove deprecated code * move variables declaration to conditional block * dissociate async and connection timeout * improve warnings (conditions + values) * remove ANSIBLE_METADATA (no more needed); fix typo * update DOCUMENTATION * Drop field 'version_added' (no more needed). * Add a note about check_mode support. * catch early errors before resetting connection and processing the loop * fix typo * change posix group (due to xtables locks); add 'version_added' in doc * update deprecation (replace Ansible 2.12 by community.general 2.0.0) * bump version_added to 1.0.0 * update ignore-2.11.txt * ignore errors for 2.9 as for 2.10 & 2.11 * move action plugin to system/ and replace it by a symlink * remove action-plugin-docs override in tests/sanity/ignore*.txt * update action plugin docstrings * bump version_added to 1.1.0 * use lowercase booleans * extend usage of namespaces to ansible builtin modules
This commit is contained in:
parent
05556dc671
commit
92242d898d
14 changed files with 1682 additions and 0 deletions
29
tests/integration/targets/iptables_state/tasks/main.yml
Normal file
29
tests/integration/targets/iptables_state/tasks/main.yml
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
- name: ensure iptables package is installed
|
||||
package:
|
||||
name:
|
||||
- iptables
|
||||
become: yes
|
||||
|
||||
|
||||
- name: include tasks
|
||||
vars:
|
||||
iptables_saved: "/tmp/test_iptables_state.saved"
|
||||
iptables_tests: "/tmp/test_iptables_state.tests"
|
||||
|
||||
block:
|
||||
- name: include tasks to perform basic tests (check_mode, async, idempotency)
|
||||
include_tasks: tests/00-basic.yml
|
||||
|
||||
- name: include tasks to test tables handling
|
||||
include_tasks: tests/01-tables.yml
|
||||
when:
|
||||
- xtables_lock is undefined
|
||||
|
||||
- name: include tasks to test rollbacks
|
||||
include_tasks: tests/10-rollback.yml
|
||||
when:
|
||||
- xtables_lock is undefined
|
||||
- ansible_connection in ['ssh', 'paramiko', 'smart']
|
||||
|
||||
become: yes
|
|
@ -0,0 +1,316 @@
|
|||
---
|
||||
- name: "ensure our next backup is not there (file)"
|
||||
file:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: absent
|
||||
|
||||
- name: "ensure our next rule is not there (iptables)"
|
||||
iptables:
|
||||
chain: OUTPUT
|
||||
jump: ACCEPT
|
||||
state: absent
|
||||
|
||||
|
||||
#
|
||||
# Basic checks about invalid param/value handling.
|
||||
#
|
||||
- name: "trigger error about invalid param"
|
||||
iptables_state:
|
||||
name: foobar
|
||||
register: iptables_state
|
||||
ignore_errors: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
- iptables_state.msg is match("Invalid options")
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "trigger error about missing param 'state'"
|
||||
iptables_state:
|
||||
path: foobar
|
||||
register: iptables_state
|
||||
ignore_errors: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
- iptables_state.msg is match("missing required arguments")
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "trigger error about missing param 'path'"
|
||||
iptables_state:
|
||||
state: saved
|
||||
register: iptables_state
|
||||
ignore_errors: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
- iptables_state.msg is match("missing required arguments")
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "trigger error about invalid value for param 'state'"
|
||||
iptables_state:
|
||||
path: foobar
|
||||
state: present
|
||||
register: iptables_state
|
||||
ignore_errors: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
- iptables_state.msg is match("value of state must be one of")
|
||||
quiet: yes
|
||||
|
||||
|
||||
#
|
||||
# Play with the current state first. We will create a file to store it in, but
|
||||
# no more. These tests are for:
|
||||
# - idempotency
|
||||
# - check_mode
|
||||
#
|
||||
- name: "save state (check_mode, must report a change)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: saved
|
||||
register: iptables_state
|
||||
check_mode: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is changed
|
||||
- iptables_state.initial_state == iptables_state.saved
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "save state (must report a change)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: saved
|
||||
register: iptables_state
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is changed
|
||||
- iptables_state.initial_state == iptables_state.saved
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "save state (idempotency, must NOT report a change)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: saved
|
||||
register: iptables_state
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
- iptables_state.initial_state == iptables_state.saved
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "save state (check_mode, must NOT report a change)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: saved
|
||||
register: iptables_state
|
||||
check_mode: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
- iptables_state.initial_state == iptables_state.saved
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
# We begin with 'state=restored' by restoring the current state on itself.
|
||||
# This at least ensures the file produced with state=saved is suitable for
|
||||
# state=restored.
|
||||
|
||||
- name: "state=restored check_mode=true changed=false"
|
||||
block:
|
||||
- name: "restore state (check_mode, must NOT report a change, no warning)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
check_mode: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
- iptables_state.initial_state == iptables_state.restored
|
||||
quiet: yes
|
||||
|
||||
rescue:
|
||||
- name: "assert that results are not as expected for only one reason (xtables lock)"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
- iptables_state.stderr is search('xtables lock')
|
||||
quiet: yes
|
||||
register: xtables_lock
|
||||
|
||||
|
||||
|
||||
- name: "state=restored changed=false"
|
||||
block:
|
||||
- name: "restore state (must NOT report a change, warning about rollback & async)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
- iptables_state.initial_state == iptables_state.restored
|
||||
quiet: yes
|
||||
|
||||
rescue:
|
||||
- name: "assert that results are not as expected for only one reason (xtables lock)"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
- iptables_state.stderr is search('xtables lock')
|
||||
quiet: yes
|
||||
register: xtables_lock
|
||||
|
||||
|
||||
|
||||
- name: "change iptables state (iptables)"
|
||||
iptables:
|
||||
chain: OUTPUT
|
||||
jump: ACCEPT
|
||||
|
||||
|
||||
|
||||
- name: "state=restored changed=true"
|
||||
block:
|
||||
- name: "restore state (check_mode, must report a change)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
check_mode: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is changed
|
||||
- iptables_state.initial_state != iptables_state.restored
|
||||
quiet: yes
|
||||
|
||||
rescue:
|
||||
- name: "assert that results are not as expected for only one reason (xtables lock)"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
- iptables_state.stderr is search('xtables lock')
|
||||
quiet: yes
|
||||
register: xtables_lock
|
||||
|
||||
|
||||
|
||||
- name: "state=restored changed=true"
|
||||
block:
|
||||
- name: "restore state (must report a change, async, no warning)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is changed
|
||||
- iptables_state.initial_state != iptables_state.restored
|
||||
- iptables_state.applied
|
||||
quiet: yes
|
||||
|
||||
rescue:
|
||||
- name: "assert that results are not as expected for only one reason (xtables lock)"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
- iptables_state.stderr is search('xtables lock')
|
||||
quiet: yes
|
||||
register: xtables_lock
|
||||
|
||||
|
||||
|
||||
- name: "state=restored changed=false"
|
||||
block:
|
||||
- name: "restore state (must NOT report a change, async, no warning)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
- iptables_state.initial_state == iptables_state.restored
|
||||
quiet: yes
|
||||
|
||||
rescue:
|
||||
- name: "assert that results are not as expected for only one reason (xtables lock)"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
- iptables_state.stderr is search('xtables lock')
|
||||
quiet: yes
|
||||
register: xtables_lock
|
||||
|
||||
|
||||
|
||||
- name: "state=restored changed=false"
|
||||
block:
|
||||
- name: "restore state (check_mode=yes, must NOT report a change, no warning)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
check_mode: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
- iptables_state.initial_state == iptables_state.restored
|
||||
quiet: yes
|
||||
|
||||
rescue:
|
||||
- name: "assert that results are not as expected for only one reason (xtables lock)"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
- iptables_state.stderr is search('xtables lock')
|
||||
quiet: yes
|
||||
register: xtables_lock
|
|
@ -0,0 +1,299 @@
|
|||
---
|
||||
- name: "ensure our next rule is not there (iptables)"
|
||||
iptables:
|
||||
table: nat
|
||||
chain: INPUT
|
||||
jump: ACCEPT
|
||||
state: absent
|
||||
|
||||
- name: "get state (table filter)"
|
||||
iptables_state:
|
||||
table: filter
|
||||
state: saved
|
||||
path: "{{ iptables_saved }}"
|
||||
register: iptables_state
|
||||
changed_when: false
|
||||
check_mode: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- "'*filter' in iptables_state.initial_state"
|
||||
- iptables_state.tables.filter is defined
|
||||
- iptables_state.tables.nat is undefined
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "get state (table nat)"
|
||||
iptables_state:
|
||||
table: nat
|
||||
state: saved
|
||||
path: "{{ iptables_saved }}"
|
||||
register: iptables_state
|
||||
changed_when: false
|
||||
check_mode: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- "'*nat' in iptables_state.initial_state"
|
||||
- "'*filter' in iptables_state.initial_state"
|
||||
- iptables_state.tables.nat is defined
|
||||
- iptables_state.tables.filter is undefined
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "save state (table filter)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: saved
|
||||
table: filter
|
||||
register: iptables_state
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- "'*filter' in iptables_state.initial_state"
|
||||
- "'*filter' in iptables_state.saved"
|
||||
- "'*nat' in iptables_state.initial_state"
|
||||
- "'*nat' not in iptables_state.saved"
|
||||
- iptables_state.tables.filter is defined
|
||||
- iptables_state.tables.nat is undefined
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "save state (table nat)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: saved
|
||||
table: nat
|
||||
register: iptables_state
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is changed
|
||||
- "'*nat' in iptables_state.initial_state"
|
||||
- "'*nat' in iptables_state.saved"
|
||||
- "'*filter' in iptables_state.initial_state"
|
||||
- "'*filter' not in iptables_state.saved"
|
||||
- iptables_state.tables.nat is defined
|
||||
- iptables_state.tables.filter is undefined
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "save state (any table)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: saved
|
||||
register: iptables_state
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is changed
|
||||
- "'*filter' in iptables_state.initial_state"
|
||||
- "'*filter' in iptables_state.saved"
|
||||
- "'*nat' in iptables_state.initial_state"
|
||||
- "'*nat' in iptables_state.saved"
|
||||
- iptables_state.tables.filter is defined
|
||||
- iptables_state.tables.nat is defined
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "restore state (table nat, must NOT report a change, no warning)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: restored
|
||||
table: nat
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- "'*nat' in iptables_state.initial_state"
|
||||
- "'*nat' in iptables_state.restored"
|
||||
- "'*filter' in iptables_state.initial_state"
|
||||
- "'*filter' not in iptables_state.restored"
|
||||
- iptables_state.tables.nat is defined
|
||||
- iptables_state.tables.filter is undefined
|
||||
- iptables_state is not changed
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "change NAT table (iptables)"
|
||||
iptables:
|
||||
table: nat
|
||||
chain: INPUT
|
||||
jump: ACCEPT
|
||||
state: present
|
||||
|
||||
|
||||
|
||||
- name: "restore state (table nat, must report a change, no warning)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: restored
|
||||
table: nat
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- "'*nat' in iptables_state.initial_state"
|
||||
- "'*nat' in iptables_state.restored"
|
||||
- "'*filter' in iptables_state.initial_state"
|
||||
- "'*filter' not in iptables_state.restored"
|
||||
- iptables_state.tables.nat is defined
|
||||
- "'-A INPUT -j ACCEPT' in iptables_state.tables.nat"
|
||||
- "'-A INPUT -j ACCEPT' not in iptables_state.restored"
|
||||
- iptables_state.tables.filter is undefined
|
||||
- iptables_state is changed
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "get security, raw and mangle tables states"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: saved
|
||||
table: "{{ item }}"
|
||||
loop:
|
||||
- security
|
||||
- raw
|
||||
- mangle
|
||||
changed_when: false
|
||||
check_mode: yes
|
||||
|
||||
|
||||
|
||||
- name: "save state (any table)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: saved
|
||||
register: iptables_state
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- "'filter' in iptables_state.tables"
|
||||
- "'*filter' in iptables_state.saved"
|
||||
- "'mangle' in iptables_state.tables"
|
||||
- "'*mangle' in iptables_state.saved"
|
||||
- "'nat' in iptables_state.tables"
|
||||
- "'*nat' in iptables_state.saved"
|
||||
- "'raw' in iptables_state.tables"
|
||||
- "'*raw' in iptables_state.saved"
|
||||
- "'security' in iptables_state.tables"
|
||||
- "'*security' in iptables_state.saved"
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "save filter table into a test file"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
table: filter
|
||||
state: saved
|
||||
|
||||
- name: "add a table header in comments (# *mangle)"
|
||||
lineinfile:
|
||||
path: "{{ iptables_tests }}"
|
||||
line: "# *mangle"
|
||||
|
||||
|
||||
|
||||
- name: "restore state (table filter, must NOT report a change, no warning)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
table: filter
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- "'*filter' in iptables_state.initial_state"
|
||||
- "'*mangle' in iptables_state.initial_state"
|
||||
- "'*nat' in iptables_state.initial_state"
|
||||
- "'*raw' in iptables_state.initial_state"
|
||||
- "'*security' in iptables_state.initial_state"
|
||||
- "'filter' in iptables_state.tables"
|
||||
- "'mangle' not in iptables_state.tables"
|
||||
- "'nat' not in iptables_state.tables"
|
||||
- "'raw' not in iptables_state.tables"
|
||||
- "'security' not in iptables_state.tables"
|
||||
- "'*filter' in iptables_state.restored"
|
||||
- "'*mangle' not in iptables_state.restored"
|
||||
- "'*nat' not in iptables_state.restored"
|
||||
- "'*raw' not in iptables_state.restored"
|
||||
- "'*security' not in iptables_state.restored"
|
||||
- iptables_state is not changed
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "restore state (any table, must NOT report a change, no warning)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- "'*filter' in iptables_state.initial_state"
|
||||
- "'*mangle' in iptables_state.initial_state"
|
||||
- "'*nat' in iptables_state.initial_state"
|
||||
- "'*raw' in iptables_state.initial_state"
|
||||
- "'*security' in iptables_state.initial_state"
|
||||
- "'filter' in iptables_state.tables"
|
||||
- "'mangle' in iptables_state.tables"
|
||||
- "'nat' in iptables_state.tables"
|
||||
- "'raw' in iptables_state.tables"
|
||||
- "'security' in iptables_state.tables"
|
||||
- "'*filter' in iptables_state.restored"
|
||||
- "'*mangle' in iptables_state.restored"
|
||||
- "'*nat' in iptables_state.restored"
|
||||
- "'*raw' in iptables_state.restored"
|
||||
- "'*security' in iptables_state.restored"
|
||||
- iptables_state is not changed
|
||||
quiet: yes
|
||||
|
||||
|
||||
|
||||
- name: "restore state (table mangle, must fail, no warning)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
table: mangle
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
ignore_errors: yes
|
||||
|
||||
- name: "explain expected failure"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
- "iptables_state.msg == 'Table mangle to restore not defined in {{ iptables_tests }}'"
|
||||
success_msg: >-
|
||||
The previous error has been triggered by trying to restore a table
|
||||
that is missing in the file provided to iptables-restore.
|
||||
fail_msg: >-
|
||||
The previous task should have failed due to a missing table (mangle)
|
||||
in the file to restore iptables state from.
|
|
@ -0,0 +1,199 @@
|
|||
---
|
||||
- name: "create a blocking ruleset with a DROP policy"
|
||||
copy:
|
||||
dest: "{{ iptables_tests }}"
|
||||
content: |
|
||||
*filter
|
||||
:INPUT DROP
|
||||
COMMIT
|
||||
|
||||
|
||||
|
||||
- name: "restore state from the test file (check_mode, must report a change)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
check_mode: yes
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is changed
|
||||
|
||||
|
||||
|
||||
- name: "fail to restore state from the test file"
|
||||
block:
|
||||
- name: "restore state from the test file (bad policies, expected error -> rollback)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
rescue:
|
||||
- name: "explain expected failure"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
- not iptables_state.applied
|
||||
success_msg: >-
|
||||
The previous error has been triggered to test the rollback. If you
|
||||
are there, it means that 1) connection has been lost right after the
|
||||
bad rules have been restored; 2) a rollback happened, so the bad
|
||||
rules are not applied, finally; 3) module failed because it didn't
|
||||
reach the wanted state, but at least host is not lost !!!
|
||||
fail_msg: >-
|
||||
The previous error has been triggered but its results are not as
|
||||
expected.
|
||||
|
||||
- name: "check that the expected failure happened"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
|
||||
|
||||
|
||||
- name: "fail to restore state from the test file (again)"
|
||||
block:
|
||||
- name: "try again, with a higher timeout (bad policies, same expected error)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
vars:
|
||||
ansible_timeout: "{{ max_delay | d(300) }}"
|
||||
|
||||
rescue:
|
||||
- name: "explain expected failure"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
- not iptables_state.applied
|
||||
success_msg: >-
|
||||
The previous error has been triggered to test the rollback. If you
|
||||
are there, it means that 1) connection has been lost right after the
|
||||
bad rules have been restored; 2) a rollback happened, so the bad
|
||||
rules are not applied, finally; 3) module failed because it didn't
|
||||
reach the wanted state, but at least host is not lost !!!
|
||||
fail_msg: >-
|
||||
The previous error has been triggered but its results are not as
|
||||
expected.
|
||||
|
||||
- name: "check that the expected failure happened"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
|
||||
|
||||
|
||||
- name: "restore state from backup (must NOT report a change)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
|
||||
|
||||
|
||||
- name: "restore state from backup (mangle, must NOT report a change)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_saved }}"
|
||||
table: mangle
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
- name: "assert that results are as expected"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
|
||||
|
||||
|
||||
- name: "create a blocking ruleset with a REJECT rule"
|
||||
copy:
|
||||
dest: "{{ iptables_tests }}"
|
||||
content: |
|
||||
*filter
|
||||
-A INPUT -j REJECT
|
||||
COMMIT
|
||||
|
||||
|
||||
|
||||
- name: "fail to restore state from the test file (again)"
|
||||
block:
|
||||
- name: "restore state from the test file (bad rules, expected error -> rollback)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
rescue:
|
||||
- name: "explain expected failure"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
- not iptables_state.applied
|
||||
success_msg: >-
|
||||
The previous error has been triggered to test the rollback. If you
|
||||
are there, it means that 1) connection has been lost right after the
|
||||
bad rules have been restored; 2) a rollback happened, so the bad
|
||||
rules are not applied, finally; 3) module failed because it didn't
|
||||
reach the wanted state, but at least host is not lost !!!
|
||||
fail_msg: >-
|
||||
The previous error has been triggered but its results are not as
|
||||
expected.
|
||||
|
||||
- name: "check that the expected failure happened"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
||||
|
||||
|
||||
|
||||
- name: "fail to restore state from the test file (again)"
|
||||
block:
|
||||
- name: "try again, with a higher timeout (bad rules, same expected error)"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
vars:
|
||||
ansible_timeout: "{{ max_delay | d(300) }}"
|
||||
|
||||
rescue:
|
||||
- name: "explain expected failure"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
- not iptables_state.applied
|
||||
success_msg: >-
|
||||
The previous error has been triggered to test the rollback. If you
|
||||
are there, it means that 1) connection has been lost right after the
|
||||
bad rules have been restored; 2) a rollback happened, so the bad
|
||||
rules are not applied, finally; 3) module failed because it didn't
|
||||
reach the wanted state, but at least host is not lost !!!
|
||||
fail_msg: >-
|
||||
The previous error has been triggered but its results are not as
|
||||
expected.
|
||||
|
||||
- name: "check that the expected failure happened"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is failed
|
Loading…
Add table
Add a link
Reference in a new issue