diff --git a/CHANGELOG.md b/CHANGELOG.md index 2057225..de28e94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,11 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). required, instead of the aspirational "defaults to [https] if omitted" (no default was ever implemented — `subelements('schemes')` hard-fails on entries missing the field). +- Failure output is now a firewall-rule punch list. Each failed probe + prints the corresponding `allow tcp/ to ` rule beneath it, + and the end of the play prints a deduplicated list of every rule the + customer needs to add. Failure exit code is unchanged (non-zero on + any miss). - Replaced the dual port-80 / port-443 loop in `playbooks/main.yml` with a single per-scheme loop driven by each entry's `schemes` field. - `playbooks/files/websites.yml` reorganized around the new schema. diff --git a/playbooks/main.yml b/playbooks/main.yml index 94a22bf..66eef57 100644 --- a/playbooks/main.yml +++ b/playbooks/main.yml @@ -31,6 +31,9 @@ {{ probe_results.results | selectattr('failed', 'equalto', true) | list }} + scheme_to_port: + http: 80 + https: 443 - name: Show summary ansible.builtin.debug: @@ -38,19 +41,36 @@ {{ (probe_results.results | length) - (url_failures | length) }} of {{ probe_results.results | length }} URL probes passed. - - name: Show failed URLs + - name: Show failed URLs with firewall hint when: url_failures | length > 0 ansible.builtin.debug: - msg: >- - FAIL: {{ item.item.1 }}://{{ item.item.0.url }} - ({{ item.item.0.method }}) - expected {{ item.item.0.status }} - got {{ item.status | default('no response') }} - {{ '- ' ~ item.msg if item.msg is defined else '' }} + msg: |- + FAIL: {{ item.item.1 }}://{{ item.item.0.url }} ({{ item.item.0.method }}) + expected {{ item.item.0.status }} got {{ item.status | default('no response') }}{{ ' - ' ~ item.msg if item.msg is defined else '' }} + -> Add egress rule: allow tcp/{{ scheme_to_port[item.item.1] }} to {{ item.item.0.url.split('/') | first }} + loop: "{{ url_failures }}" + loop_control: + label: "{{ item.item.1 }}://{{ item.item.0.url }}" + + - name: Build deduplicated firewall rule list + when: url_failures | length > 0 + ansible.builtin.set_fact: + firewall_rules: "{{ (firewall_rules | default([])) + [rule] }}" + vars: + rule: "allow tcp/{{ scheme_to_port[item.item.1] }} to {{ item.item.0.url.split('/') | first }}" loop: "{{ url_failures }}" loop_control: label: "{{ item.item.1 }}://{{ item.item.0.url }}" + - name: Show firewall rules to add + when: url_failures | length > 0 + ansible.builtin.debug: + msg: |- + Firewall rules to add ({{ firewall_rules | unique | length }} unique): + {% for r in firewall_rules | unique | sort %} + - {{ r }} + {% endfor %} + - name: Fail the play if any URL probe failed when: url_failures | length > 0 ansible.builtin.fail: