sync: add cross-subsystem event bus for config consistency
Add EventBus with loop guards to keep firewall, dnsmasq, wireguard, and network configs consistent. Handlers emit SyncEvent after mutations; subscribers compute diffs and write JSON without manual cascade loops.
This commit is contained in:
@@ -105,6 +105,46 @@ Poll intervals are configurable via `VACUUM_WALL_POLL_INTERVALS` env var (`firew
|
||||
|
||||
On collector failure during a poll, no broadcast is sent (avoids noisy ticks). State data is set to `None`.
|
||||
|
||||
## Cross-Subsystem Sync Event Bus
|
||||
|
||||
When a subsystem's configuration changes, related subsystems are automatically
|
||||
updated to stay consistent. An in-process event bus (`lib/sync.py`) decouples
|
||||
subsystems — no handler calls into another handler's logic directly.
|
||||
|
||||
### How It Works
|
||||
|
||||
1. A mutation handler saves its config (e.g., adding a DHCP range).
|
||||
2. The handler emits a `SyncEvent` on the event bus.
|
||||
3. Subscribers react by updating related subsystem configs:
|
||||
- **DnsToFirewallSync**: Adds `dhcp`, `dns` services and `masquerade` to the
|
||||
firewall zone for each interface serving a DHCP range.
|
||||
- **WgToFirewallSync**: Creates or updates a `vpn` firewall zone with
|
||||
WireGuard interface and UDP 51820 rich rule.
|
||||
- **FirewallToDhcpSync**: Detects stale DHCP ranges for interfaces not in
|
||||
any zone (logs warnings, does not auto-remove).
|
||||
- **NetworkToAllSync**: Suggests DHCP ranges and syncs firewall zone
|
||||
interface assignments when network config changes.
|
||||
4. The handler refreshes state for the originating subsystem plus all
|
||||
transitively affected subsystems.
|
||||
|
||||
### Guard Rails
|
||||
|
||||
- **Idempotency**: Each subscriber reads current state, computes desired state,
|
||||
writes the diff. Running twice is safe.
|
||||
- **No loops**: The event bus tracks `(subsystem, action)` per dispatch cycle.
|
||||
Re-entrant emits for the same key are silently dropped.
|
||||
- **Firewall-cmd separation**: Sync subscribers only write JSON config. They
|
||||
do NOT call `firewall-cmd`. The user clicks "Apply" on the firewall page to
|
||||
push to firewalld.
|
||||
- **Error handling**: Subscriber exceptions are caught, logged as warnings,
|
||||
and do NOT abort the originating handler.
|
||||
|
||||
### Frontend Impact
|
||||
|
||||
Minimal. The sync happens transparently in the backend. The "pending changes"
|
||||
indicator on the firewall page will show pending when DHCP or WireGuard saves
|
||||
(since sync writes JSON but does not call firewall-cmd).
|
||||
|
||||
## Directory Structure
|
||||
|
||||
### Config — Declarative Settings
|
||||
|
||||
Reference in New Issue
Block a user