fix(topology): remove DMZ gateway auto-attach on LAN create
POST /topologies/{id}/lans previously called _auto_attach_gateway()
whenever a non-DMZ LAN was created, which wired the DMZ gateway decky
to every new subnet. That's why a deployed gateway ended up with
eth0..ethN on every LAN regardless of what the user drew in MazeNET.
Drop the auto-attach helper entirely. The DMZ_ORPHAN deploy-time
validator (decnet/topology/validate.py:65-110) stays strict — users
must explicitly wire the gateway to each subnet they want bridged,
which is the whole point of having a topology editor.
useMazeApi.ts: drop stale auto-bridge reference from comment.
This commit is contained in:
@@ -77,59 +77,9 @@ async def api_create_lan(
|
|||||||
if row is None: # pragma: no cover — would mean insert vanished
|
if row is None: # pragma: no cover — would mean insert vanished
|
||||||
raise HTTPException(status_code=500, detail="LAN insert vanished")
|
raise HTTPException(status_code=500, detail="LAN insert vanished")
|
||||||
|
|
||||||
# Auto-bridge: if this is a non-DMZ LAN, attach the topology's
|
|
||||||
# DMZ gateway (the decky with forwards_l3=True that lives on the
|
|
||||||
# DMZ LAN) to it. Satisfies the DMZ_ORPHAN invariant by
|
|
||||||
# construction — every internal LAN always has a bridge path.
|
|
||||||
if not body.is_dmz:
|
|
||||||
try:
|
|
||||||
await _auto_attach_gateway(topology_id, lan_id)
|
|
||||||
except Exception as exc:
|
|
||||||
# Best-effort: if the gateway is missing or the edge can't
|
|
||||||
# be written, the deploy-time validator will surface it.
|
|
||||||
log.warning(
|
|
||||||
"auto-bridge skipped for LAN %s in topology %s: %s",
|
|
||||||
lan_id, topology_id, exc,
|
|
||||||
)
|
|
||||||
|
|
||||||
return LANRow(**row)
|
return LANRow(**row)
|
||||||
|
|
||||||
|
|
||||||
async def _auto_attach_gateway(topology_id: str, new_lan_id: str) -> None:
|
|
||||||
"""Attach the topology's DMZ gateway to a newly created non-DMZ LAN."""
|
|
||||||
lans = await repo.list_lans_for_topology(topology_id)
|
|
||||||
dmz = next((lan for lan in lans if lan.get("is_dmz")), None)
|
|
||||||
if dmz is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
edges = await repo.list_topology_edges(topology_id)
|
|
||||||
gateway_uuid: str | None = None
|
|
||||||
for e in edges:
|
|
||||||
if e["lan_id"] != dmz["id"]:
|
|
||||||
continue
|
|
||||||
if e.get("forwards_l3"):
|
|
||||||
gateway_uuid = e["decky_uuid"]
|
|
||||||
break
|
|
||||||
if gateway_uuid is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
if any(
|
|
||||||
e["decky_uuid"] == gateway_uuid and e["lan_id"] == new_lan_id
|
|
||||||
for e in edges
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
await repo.add_topology_edge(
|
|
||||||
{
|
|
||||||
"topology_id": topology_id,
|
|
||||||
"decky_uuid": gateway_uuid,
|
|
||||||
"lan_id": new_lan_id,
|
|
||||||
"is_bridge": True,
|
|
||||||
"forwards_l3": True,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@router.patch(
|
@router.patch(
|
||||||
"/{topology_id}/lans/{lan_id}",
|
"/{topology_id}/lans/{lan_id}",
|
||||||
tags=["MazeNET Topologies"],
|
tags=["MazeNET Topologies"],
|
||||||
|
|||||||
@@ -89,9 +89,8 @@ export function adaptTopology(detail: TopologyDetail): HydratedTopology {
|
|||||||
|
|
||||||
// Home LAN = first edge; a multi-homed gateway is drawn inside its
|
// Home LAN = first edge; a multi-homed gateway is drawn inside its
|
||||||
// home LAN, membership in others is expressed via the edge list.
|
// home LAN, membership in others is expressed via the edge list.
|
||||||
// Gateways (forwards_l3) MUST render inside a DMZ — auto-bridge adds
|
// Gateways (forwards_l3) MUST render inside a DMZ — edge ordering from
|
||||||
// subnet edges after the original DMZ edge, but edge ordering from the
|
// the backend is not guaranteed, so we pick the DMZ edge explicitly.
|
||||||
// backend is not guaranteed, so we pick DMZ explicitly for gateways.
|
|
||||||
const dmzIds = new Set(detail.lans.filter((l) => l.is_dmz).map((l) => l.id));
|
const dmzIds = new Set(detail.lans.filter((l) => l.is_dmz).map((l) => l.id));
|
||||||
const gatewayUuids = new Set(
|
const gatewayUuids = new Set(
|
||||||
detail.edges.filter((e) => e.forwards_l3).map((e) => e.decky_uuid),
|
detail.edges.filter((e) => e.forwards_l3).map((e) => e.decky_uuid),
|
||||||
|
|||||||
Reference in New Issue
Block a user