docs: add comprehensive docstrings and inline comments
Add docstrings to all handler functions in daemon/handlers/firewall.py, covering params, return values, and raised exceptions. Add inline comments to _config_apply() reconciliation steps and the request body merge order. Add docstrings across lib/ modules for emit helpers (_emit_str, _emit_int, etc.), volatile stripping logic, two-layer diff strategy, sync event dispatch, and all cross-subsystem sync subscribers (DnsToFirewall, WgToFirewall, FirewallToDhcp, NetworkToAllSync). Document WireGuard/networkd config parsers and key-value mappers in system_import.py. Add docstrings to _ep(), Registry.decorator, setup_logging, and _replace helper across daemon/ and lib/.
This commit is contained in:
+77
@@ -147,10 +147,14 @@ class EventBus:
|
||||
"""Core dispatch logic (called within try/finally of _dispatch)."""
|
||||
result = SyncResult()
|
||||
|
||||
# Iterate subscribers for this (subsystem, action) pair.
|
||||
# Each subscriber is called in registration order.
|
||||
for handler in self._subscribers.get((event.subsystem, event.action), []):
|
||||
try:
|
||||
sub_result = handler(event)
|
||||
except Exception:
|
||||
# Error containment: subscriber failures are logged, never abort
|
||||
# the originating handler or other subscribers.
|
||||
logger.warning(
|
||||
"Sync subscriber %s failed for %s.%s",
|
||||
_safe_name(handler),
|
||||
@@ -163,10 +167,14 @@ class EventBus:
|
||||
if sub_result is None:
|
||||
continue
|
||||
|
||||
# Accumulate results from this subscriber into the aggregate.
|
||||
result.affected_subsystems.extend(sub_result.affected_subsystems)
|
||||
result.changes.extend(sub_result.changes)
|
||||
result.applied = result.applied or sub_result.applied
|
||||
|
||||
# Cascade: for each affected subsystem (that isn't the source),
|
||||
# emit a new event so downstream subscribers react. The cascade
|
||||
# event carries _cascade=source so subscribers can detect loops.
|
||||
for affected in sub_result.affected_subsystems:
|
||||
if affected == event.subsystem:
|
||||
continue
|
||||
@@ -180,6 +188,8 @@ class EventBus:
|
||||
result.changes.extend(cascaded.changes)
|
||||
result.applied = result.applied or cascaded.applied
|
||||
|
||||
# Dedupe affected list before returning (cascade events may cause
|
||||
# the same subsystem to appear multiple times).
|
||||
result.affected_subsystems = _dedupe(result.affected_subsystems)
|
||||
return result
|
||||
|
||||
@@ -247,6 +257,25 @@ class DnsToFirewallSync:
|
||||
|
||||
@classmethod
|
||||
def on_dnsmasq_config_saved(cls, event: SyncEvent) -> SyncResult | None:
|
||||
"""Sync subscriber: dnsmasq config_saved → update firewall zone services.
|
||||
|
||||
When DHCP ranges are added/removed on interfaces, this subscriber
|
||||
ensures the corresponding firewall zones have ``dhcp`` and ``dns``
|
||||
services enabled/disabled to match. Back-propagates: ensures
|
||||
DHCP ranges carry the gateway (interface IP) so clients get
|
||||
their default route.
|
||||
|
||||
Skips processing if event originated as a cascade from ``firewall``
|
||||
to prevent infinite loops.
|
||||
|
||||
Args:
|
||||
event: Sync event with ``config_saved`` action from dnsmasq.
|
||||
|
||||
Returns:
|
||||
SyncResult listing firewall and dnsmasq as affected subsystems,
|
||||
with human-readable change descriptions. ``None`` if skipped
|
||||
due to cascade guard.
|
||||
"""
|
||||
if event.payload.get("_cascade") == "firewall":
|
||||
return None
|
||||
|
||||
@@ -438,6 +467,23 @@ class WgToFirewallSync:
|
||||
|
||||
@classmethod
|
||||
def on_wireguard_config_saved(cls, event: SyncEvent) -> SyncResult | None:
|
||||
"""Sync subscriber: wireguard config_saved → update firewall config.
|
||||
|
||||
When WireGuard is active (has peers and interface), this subscriber
|
||||
ensures the ``vpn`` zone exists with the WG interface assigned,
|
||||
masquerade enabled, UDP 51820 accept rule, and inter-zone rich rules
|
||||
for peer allowed_ips subnets. When WireGuard becomes inactive,
|
||||
cleans up WireGuard-created entries from the vpn zone.
|
||||
|
||||
Skips processing if event originated as a cascade from ``firewall``.
|
||||
|
||||
Args:
|
||||
event: Sync event with ``config_saved`` action from wireguard.
|
||||
|
||||
Returns:
|
||||
SyncResult listing firewall as affected subsystem with change
|
||||
descriptions. ``None`` if skipped due to cascade guard.
|
||||
"""
|
||||
if event.payload.get("_cascade") == "firewall":
|
||||
return None
|
||||
|
||||
@@ -556,6 +602,23 @@ class FirewallToDhcpSync:
|
||||
|
||||
@classmethod
|
||||
def on_firewall_config_saved(cls, event: SyncEvent) -> SyncResult | None:
|
||||
"""Sync subscriber: firewall config_saved → sync dnsmasq DHCP ranges.
|
||||
|
||||
Removes DHCP ranges whose interface no longer belongs to any firewall
|
||||
zone. When masquerade is enabled on a zone, ensures DHCP ranges on
|
||||
that zone's interfaces carry the gateway (interface IP). Logs warnings
|
||||
for zones with dhcp service but no range.
|
||||
|
||||
Skips processing if event originated as a cascade from ``dnsmasq``.
|
||||
|
||||
Args:
|
||||
event: Sync event with ``config_saved`` action from firewall.
|
||||
|
||||
Returns:
|
||||
SyncResult listing dnsmasq as affected subsystem when ranges were
|
||||
modified, with change descriptions. ``None`` if skipped due to
|
||||
cascade guard.
|
||||
"""
|
||||
if event.payload.get("_cascade") == "dnsmasq":
|
||||
return None
|
||||
|
||||
@@ -665,6 +728,20 @@ class NetworkToAllSync:
|
||||
|
||||
@classmethod
|
||||
def on_network_config_saved(cls, event: SyncEvent) -> SyncResult | None:
|
||||
"""Sync subscriber: network config_saved → update firewall zone interfaces.
|
||||
|
||||
Suggests DHCP ranges for static-IP interfaces without ranges.
|
||||
Removes interfaces from firewall zones that are no longer present
|
||||
in the network config. Logs warnings for interfaces not assigned
|
||||
to any zone.
|
||||
|
||||
Args:
|
||||
event: Sync event with ``config_saved`` action from network.
|
||||
|
||||
Returns:
|
||||
SyncResult listing firewall as affected subsystem when zone
|
||||
interfaces were modified, with change descriptions.
|
||||
"""
|
||||
try:
|
||||
from lib.dnsmasq import get_config as _get_dnsmasq_cfg
|
||||
from lib.firewall import get_config as _get_fw_cfg
|
||||
|
||||
Reference in New Issue
Block a user