From 7d1f610a231a95ffd9a9840e90a2507a46582d6b Mon Sep 17 00:00:00 2001 From: oval Date: Tue, 7 Jul 2026 16:57:37 +0000 Subject: [PATCH] Add playbooks/library/report.yml --- playbooks/library/report.yml | 64 ++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 playbooks/library/report.yml diff --git a/playbooks/library/report.yml b/playbooks/library/report.yml new file mode 100644 index 0000000..a57a26a --- /dev/null +++ b/playbooks/library/report.yml @@ -0,0 +1,64 @@ +--- +# library/report.yml +# +# Included last in every playbook run by site.yml. Aggregates the +# shared test_results[] list into a structured JSON compliance report. +# +# What it does: +# 1. Assembles __report dict with meta, summary, by_category, +# by_severity, failures, and the full results list +# 2. Prints a boxed summary to the Ansible console +# 3. Writes JSON to reports/-.json +# (delegated to localhost so reports land on the control node) +# +# The JSON schema is documented in README.md § "JSON Output Schema". + +- name: "REPORT: Assemble compliance report" + ansible.builtin.set_fact: + __report: "{{ { + 'meta': { + 'standard': 'IEC 62443-3-3', + 'security_level': 'SL2', + 'target': inventory_hostname, + 'timestamp': ansible_date_time.iso8601, + 'executed_by': ansible_user_id + }, + 'summary': { + 'total': test_results | length, + 'passed': test_results | selectattr('passed', 'equalto', true) | list | length, + 'failed': test_results | selectattr('passed', 'equalto', false) | list | length, + 'skipped': test_results | selectattr('passed', 'equalto', 'skipped') | list | length + }, + 'by_category': test_results | groupby('category') | map( + 'regex_replace', '^(.*)$', '\\1' + ) | list, + 'by_severity': { + 'critical': test_results | selectattr('severity', 'equalto', 'critical') | list, + 'high': test_results | selectattr('severity', 'equalto', 'high') | list, + 'medium': test_results | selectattr('severity', 'equalto', 'medium') | list, + 'low': test_results | selectattr('severity', 'equalto', 'low') | list + }, + 'failures': test_results | selectattr('passed', 'equalto', false) | list, + 'results': test_results + } }}" + +- name: "REPORT: Display summary to console" + ansible.builtin.debug: + msg: | + ╔══════════════════════════════════════════════════════════════╗ + ║ IEC 62443-3-3 SL2 Compliance Report — {{ inventory_hostname }} + ╠══════════════════════════════════════════════════════════════╣ + ║ Total: {{ __report.summary.total }} Passed: {{ __report.summary.passed }} Failed: {{ __report.summary.failed }} Skipped: {{ __report.summary.skipped }} + ╚══════════════════════════════════════════════════════════════╝ + {% for f in __report.failures %} + ✗ {{ f.test_id }}: {{ f.description }} + Expected: {{ f.expected }} + Actual: {{ f.actual }} + {% endfor %} + +- name: "REPORT: Write JSON to local file" + ansible.builtin.copy: + content: "{{ __report | to_nice_json(indent=2) }}" + dest: "./reports/{{ inventory_hostname }}-{{ ansible_date_time.date }}.json" + delegate_to: localhost + run_once: true