feat: write timestamped blocklist change reports on firewall sync
This commit is contained in:
1 parent
48c5629b4b
commit
80a67635de
4 files changed
+110
-3
No files matched your search
@@ -18,8 +18,12 @@ import ipaddress
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from typing import Any, Iterable
|
||||
|
||||
from .files import write_json
|
||||
from .reporting import timestamp_name
|
||||
|
||||
#: A ``+ 1.2.3.4/32`` added line in a git patch; ``+++ b/...`` is the file
|
||||
#: header and is excluded by the negative lookahead.
|
||||
_ADDED_LINE_RE = re.compile(r"^\+(?!\+)(.*)$")
|
||||
@@ -117,3 +121,66 @@ def compute_changes(current_v4: set[str], current_v6: set[str],
|
||||
"removed_ipv4": sorted(current_v4 - complete_v4),
|
||||
"removed_ipv6": sorted(current_v6 - complete_v6),
|
||||
}
|
||||
|
||||
|
||||
def blocklist_delta(history_v4: set[str], history_v6: set[str],
|
||||
prev_v4: set[str], prev_v6: set[str],
|
||||
complete_v4: set[str], complete_v6: set[str],
|
||||
) -> dict[str, list[str]]:
|
||||
"""Complete-set delta between the previous and current blocklist state.
|
||||
|
||||
``added`` are entries newly part of the blocklist (this run's targets not
|
||||
blocked before); ``removed`` are entries no longer part of it — normally
|
||||
empty in the cumulative model.
|
||||
"""
|
||||
before_v4 = history_v4 | prev_v4
|
||||
before_v6 = history_v6 | prev_v6
|
||||
return {
|
||||
"added_ipv4": sorted(complete_v4 - before_v4),
|
||||
"added_ipv6": sorted(complete_v6 - before_v6),
|
||||
"removed_ipv4": sorted(before_v4 - complete_v4),
|
||||
"removed_ipv6": sorted(before_v6 - complete_v6),
|
||||
}
|
||||
|
||||
|
||||
def write_blocklist_report(report_dir: str,
|
||||
*,
|
||||
history_v4: set[str], history_v6: set[str],
|
||||
prev_v4: set[str], prev_v6: set[str],
|
||||
complete_v4: set[str], complete_v6: set[str],
|
||||
firewall_changes: dict | None = None,
|
||||
dry_run: bool = False,
|
||||
errors: Iterable[str] = (),
|
||||
) -> str:
|
||||
"""Write the timestamped blocklist report to ``<report_dir>/app/``.
|
||||
|
||||
Records the complete-set delta (added/removed) plus the full cumulative
|
||||
blocked list (git history | working files | scan targets), and — when
|
||||
supplied — the router sync changes. Returns the written file path.
|
||||
"""
|
||||
delta = blocklist_delta(
|
||||
history_v4, history_v6, prev_v4, prev_v6, complete_v4, complete_v6)
|
||||
payload = {
|
||||
"generated_at": datetime.now().astimezone().isoformat(
|
||||
timespec="seconds"),
|
||||
"report_dir": report_dir,
|
||||
"dry_run": dry_run,
|
||||
"summary": {
|
||||
"added": len(delta["added_ipv4"]) + len(delta["added_ipv6"]),
|
||||
"removed": len(delta["removed_ipv4"]) + len(delta["removed_ipv6"]),
|
||||
"total_blocked": len(complete_v4) + len(complete_v6),
|
||||
},
|
||||
"added_ipv4": delta["added_ipv4"],
|
||||
"added_ipv6": delta["added_ipv6"],
|
||||
"removed_ipv4": delta["removed_ipv4"],
|
||||
"removed_ipv6": delta["removed_ipv6"],
|
||||
"blocked_ipv4": sorted(complete_v4),
|
||||
"blocked_ipv6": sorted(complete_v6),
|
||||
"firewall_changes": firewall_changes,
|
||||
"errors": list(errors),
|
||||
}
|
||||
app_dir = os.path.join(report_dir, "app")
|
||||
os.makedirs(app_dir, exist_ok=True)
|
||||
path = os.path.join(app_dir, f"{timestamp_name()}.json")
|
||||
write_json(path, payload)
|
||||
return path
|
||||
Reference in new issue
Block a user