state: applied-config snapshots + per-field pending diffs

- lib/common: stamp_applied() now records a _last_applied_config
  snapshot alongside the hash; strip_apply_meta() centralizes
  bookkeeping-key stripping; deep_diff() reports field-level changes
- state collectors (dnsmasq/nginx/wireguard/networkd) expose
  pending_diff so the dashboard can show exactly which fields
  changed since the last apply (wireguard diff excludes
  private_key paths)
- dashboard pending-changes card renders per-change lines with a
  generic fallback when no snapshot is recorded
- firewall: firewalld built-in zones no longer flagged as
  unmanaged; public-zone masquerade skipped in pending changes
  since apply drives it via nftables propagation
- schema: PendingChange TypedDict; pending_diff on DnsmasqStatus /
  WgStatus; tests in test_common.py, test_firewall.py, test_state.py
This commit is contained in:
2026-08-21 00:59:19 +00:00
parent a77cee821b
commit 30b51ad7d3
14 changed files with 525 additions and 62 deletions
+30
View File
@@ -702,6 +702,36 @@ body {
flex: 1;
}
/* Pending changes summary list */
.pending-list {
list-style: none;
padding: 0;
margin: 0 0 12px;
}
.pending-list > li {
padding: 6px 0;
border-bottom: 1px solid var(--border);
}
.pending-list > li:last-child {
border-bottom: none;
}
.pending-list > li > strong {
display: block;
margin-bottom: 4px;
}
.pending-list > li > ul {
margin: 0;
padding-left: 18px;
}
.pending-list li li {
padding: 1px 0;
}
/* Service status inline badge */
.service-status {
display: inline-flex;