WireGuard access classes, firewall nftables fixes, network sync event refactor
- WireGuard: refactor to multi-interface 'access classes' model; extract config generation and helpers into lib/wireguard.py; add per-class up/down endpoints and API routes; update UI with class management pages and QR code component - Firewall: fix zone creation with --new-zone before --set-target; skip masquerade on public zone; add masquerade propagation for nftables backend so NAT works when internal zones exit via public - Network: rename sync event subsystem 'network' -> 'networkd'; always stamp config hash even when deployment fails (fixes pending-changes detection) - DHCP: add new API endpoint and update frontend page - State/Sync: update state collectors and sync buses for new subsystems - Docs: update API and config documentation for new endpoints and schemas
This commit is contained in:
+12
-10
@@ -214,16 +214,18 @@ def save_interface(_request: Any, body: dict[str, Any] | None) -> dict[str, Any]
|
||||
)
|
||||
|
||||
logger.info("Interface '%s' config saved (applied=%s)", name, deployed)
|
||||
if deployed:
|
||||
cfg_after = get_config()
|
||||
cfg_after[_APPLY_HASH_KEY] = config_hash(cfg_after)
|
||||
save_config(cfg_after)
|
||||
# Always stamp the hash so pending-changes detection stays current
|
||||
# even when deployment fails (e.g. in containerized environments).
|
||||
# The hash represents the JSON config state, not the system state.
|
||||
cfg_after = get_config()
|
||||
cfg_after[_APPLY_HASH_KEY] = config_hash(cfg_after)
|
||||
save_config(cfg_after)
|
||||
sync_result = bus.emit(
|
||||
SyncEvent(
|
||||
"network", "config_saved", {"action": "interface_saved", "interface": name}
|
||||
"networkd", "config_saved", {"action": "interface_saved", "interface": name}
|
||||
)
|
||||
)
|
||||
refresh_state(["network", *sync_result.affected_subsystems])
|
||||
refresh_state(["networkd", *sync_result.affected_subsystems])
|
||||
return {
|
||||
"name": name,
|
||||
"applied": deployed,
|
||||
@@ -296,9 +298,9 @@ def apply_all(_request: Any, _body: Any) -> dict[str, Any]:
|
||||
cfg_after[_APPLY_HASH_KEY] = config_hash(cfg_after)
|
||||
save_config(cfg_after)
|
||||
sync_result = bus.emit(
|
||||
SyncEvent("network", "config_saved", {"action": "config_applied"})
|
||||
SyncEvent("networkd", "config_saved", {"action": "config_applied"})
|
||||
)
|
||||
refresh_state(["network", *sync_result.affected_subsystems])
|
||||
refresh_state(["networkd", *sync_result.affected_subsystems])
|
||||
|
||||
logger.info(
|
||||
"Network config applied: %d interfaces, %d stale cleaned",
|
||||
@@ -364,7 +366,7 @@ def set_sysctl(_request: Any, body: dict[str, Any] | None) -> dict[str, Any]:
|
||||
|
||||
logger.info("sysctl %s set to %s", name, value)
|
||||
sync_result = bus.emit(
|
||||
SyncEvent("network", "config_saved", {"action": "sysctl_set", "name": name})
|
||||
SyncEvent("networkd", "config_saved", {"action": "sysctl_set", "name": name})
|
||||
)
|
||||
refresh_state(["network", *sync_result.affected_subsystems])
|
||||
refresh_state(["networkd", *sync_result.affected_subsystems])
|
||||
return {"name": name, "value": value}
|
||||
|
||||
Reference in New Issue
Block a user