Add run.sh

This commit is contained in:
2026-07-07 16:57:37 +00:00
parent c05bc76301
commit 8239761590
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/env bash
#
# run.sh — End-to-end IEC 62443-3-3 SL2 compliance test runner
#
# Orchestrates three phases:
# 1. Run ansible-playbook against the inventory (all FR suites)
# 2. Find the latest JSON report in reports/
# 3. Render it with Python (or Go, or fallback Python one-liner)
#
# Usage:
# ./run.sh # runs against all hosts
# ./run.sh --limit plc-rack01 -K # single host, ask sudo password
# ./run.sh --limit localhost -K # test locally
#
# Environment:
# INVENTORY — path to inventory file (default: ./inventory.ini)
# LIMIT — ansible --limit pattern (default: all)
#
# All extra arguments are forwarded to ansible-playbook:
# ./run.sh -vvv --limit localhost
#
# Output:
# reports/<hostname>-<date>.json — raw JSON test data
# stdout — formatted report (terminal or md)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
INVENTORY="${INVENTORY:-$SCRIPT_DIR/inventory.ini}"
LIMIT="${LIMIT:-all}"
echo "=== IEC 62443-3-3 SL2 Compliance Validation ==="
echo ""
# ── Phase 1: Run Ansible tests ──────────────────────────────────
echo "[1/3] Running compliance tests..."
ansible-playbook -i "$INVENTORY" "$SCRIPT_DIR/playbooks/site.yml" \
--limit "$LIMIT" \
"$@"
# ── Phase 2: Find latest report ─────────────────────────────────
REPORT_DIR="$SCRIPT_DIR/reports"
LATEST_JSON=$(ls -t "$REPORT_DIR"/*.json 2>/dev/null | head -1)
if [ -z "$LATEST_JSON" ]; then
echo ""
echo "✗ No JSON report generated. Check Ansible output above."
exit 1
fi
echo ""
echo "[2/3] Latest report: $(basename "$LATEST_JSON")"
# ── Phase 3: Render with Go template ────────────────────────────
echo "[3/3] Rendering report with Go template..."
echo ""
cd "$REPORT_DIR"
if ! go run render.go "$LATEST_JSON" report.gohtml 2>/dev/null; then
# Fallback: if Go isn't available, just cat the JSON
echo "---"
echo "(Go not available; showing raw JSON summary)"
python3 -c "
import json, sys
with open('$(basename "$LATEST_JSON")') as f:
r = json.load(f)
s = r['summary']
print(f'Total: {s[\"total\"]} | Passed: {s[\"passed\"]} | Failed: {s[\"failed\"]} | Rate: {s[\"passed\"]/s[\"total\"]*100:.1f}%')
print()
for t in r['results']:
icon = '✅' if t['passed'] == True else ('❌' if t['passed'] == False else '🔍')
print(f' {icon} [{t[\"test_id\"]}] {t[\"description\"]}')
print()
print('Failures:')
for f in r['failures']:
print(f' ❌ {f[\"test_id\"]}: {f[\"description\"]} (Severity: {f[\"severity\"]})')
print(f' Expected: {f[\"expected\"]}')
print(f' Actual: {f[\"actual\"]}')
print(f' Fix: {f[\"remediation\"]}')
" 2>/dev/null || cat "$LATEST_JSON"
fi
echo ""
echo "=== Done ==="