from fastapi import APIRouter, HTTPException, Depends from pydantic import BaseModel from config import settings from routes.auth import require_auth from services.load_balancer import lb from services.multicast_detector import multicast_detector router = APIRouter(prefix="/api/nodes", tags=["nodes"]) class NodeUpdate(BaseModel): weight: int enabled: bool | None = None class StrategyUpdate(BaseModel): strategy: str multicast_enabled: bool | None = None @router.get("") async def list_nodes(_: bool = Depends(require_auth)): nodes = [] for n in settings.edge_nodes: nodes.append({ "id": n["id"], "name": n["name"], "host": n["host"], "hls_port": n["hls_port"], "api_port": n["api_port"], "weight": n["weight"], "enabled": n.get("enabled", True), }) return nodes @router.get("/strategy") async def get_strategy(_: bool = Depends(require_auth)): return { "strategy": settings.load_balance_strategy, "multicast_enabled": settings.multicast_enabled, "multicast_available": multicast_detector.is_available(), } @router.put("/strategy") async def update_strategy(body: StrategyUpdate, _: bool = Depends(require_auth)): if body.strategy in ("round-robin", "weighted", "least-conn"): settings.load_balance_strategy = body.strategy if body.multicast_enabled is not None: settings.multicast_enabled = body.multicast_enabled return {"ok": True} @router.put("/{node_id}") async def update_node(node_id: str, body: NodeUpdate, _: bool = Depends(require_auth)): found = False for n in settings.edge_nodes: if n["id"] == node_id: n["weight"] = body.weight if body.enabled is not None: n["enabled"] = body.enabled found = True break if not found: raise HTTPException(status_code=404, detail="Node not found") return {"ok": True}