feat(topology): add pre-deploy validator and wire into deploy_topology
MazeNET phase 2 step 3. Blocks deploys of hand-authored topologies that would fail mid-bring-up (orphan deckies, duplicate IPs, overlapping subnets, unknown services) with a structured error list instead of a docker error at startup. Rules (one function each, composable by the editor for inline hints): - exactly one DMZ - every LAN has a bridge chain to the DMZ (BFS via multi-homed deckies) - no orphan deckies - unique LAN and decky names per topology - no IP collisions + IPs inside their LAN's subnet - no LAN subnet overlaps - every service in decnet.fleet.all_service_names() - service_config keys match the decky's declared services deploy_topology runs the validator after hydrate, before any status transition or Docker call; errors raise ValidationError and status stays at pending.
This commit is contained in:
@@ -35,6 +35,7 @@ from decnet.topology.compose import (
|
||||
)
|
||||
from decnet.topology.persistence import hydrate, transition_status
|
||||
from decnet.topology.status import TopologyStatus
|
||||
from decnet.topology.validate import ValidationError, errors as _validation_errors, validate as _validate_topology
|
||||
|
||||
log = get_logger("engine")
|
||||
console = Console()
|
||||
@@ -318,6 +319,12 @@ async def deploy_topology(repo, topology_id: str, *, dry_run: bool = False) -> N
|
||||
if hydrated is None:
|
||||
raise ValueError(f"topology {topology_id!r} not found")
|
||||
|
||||
# Precondition: validate before any status transition or Docker call.
|
||||
# Errors bubble up as ValidationError and leave status untouched.
|
||||
issues = _validate_topology(hydrated)
|
||||
if _validation_errors(issues):
|
||||
raise ValidationError(issues)
|
||||
|
||||
lans = hydrated["lans"]
|
||||
compose_path = _topology_compose_path(topology_id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user