stage-net-c network view: transitive fetcher + admin data endpoint

This commit is contained in:
m17hr1l
2026-06-07 00:37:32 +02:00
parent 6dcaae39c3
commit 5ff6d80333

View File

@@ -322,6 +322,38 @@ def register(app: FastAPI, TEMPLATES: Jinja2Templates) -> None:
}, },
) )
# ---------- admin: federation network view ----------------------
@app.get("/admin/federation/network", response_class=HTMLResponse)
def admin_federation_network(request: Request) -> HTMLResponse:
"""Cockpit page — force-directed federation map. Data lives at /data."""
if not _admin_ok(request):
return RedirectResponse("/admin", status_code=303)
# Build local stats up front so the header card renders even if the
# JS data-endpoint fetch fails (defensive — never give the operator a
# blank page).
view = network_view.build_local_view()
return TEMPLATES.TemplateResponse(
request,
"admin_federation_network.html",
{
"fingerprint": federation.node_fingerprint(),
"stats": view.stats,
},
)
@app.get("/admin/federation/network/data")
def admin_federation_network_data(request: Request) -> JSONResponse:
"""Full admin view — includes unknown/blocked peers + transitive peers.
Public /federation/network filters those out; this surface does not,
because it sits behind the admin gate and the operator needs to see
the real shape of the federation including the parts being ignored.
"""
if not _admin_ok(request):
raise HTTPException(status_code=403, detail="admin session required")
return JSONResponse(network_view.build_admin_view(include_transitive=True))
# ---------- admin: quorum config + per-peer/per-hash view ------- # ---------- admin: quorum config + per-peer/per-hash view -------
@app.get("/admin/federation/quorum", response_class=HTMLResponse) @app.get("/admin/federation/quorum", response_class=HTMLResponse)