"""Network management API blueprint. Exposes /api/network/* and delegates to vacuum-walld for interface IP configuration via systemd-networkd. """ from typing import Any from flask import Blueprint from daemon.client import ( # noqa: F401 (resolved via module globals at dispatch) get, post, ) from daemon.iface import ( GET_NETWORK_INFER_DHCP_RANGES, GET_NETWORK_INFER_ZONES, GET_NETWORK_INTERFACE_NAME, GET_NETWORK_INTERFACES, POST_NETWORK_APPLY, POST_NETWORK_INTERFACE_NAME, POST_NETWORK_INTERFACE_RELOAD, ) from lib.common import validate_interface_name from webui.api.common import daemon_route bp = Blueprint("network", __name__) def _check_iface(_json: Any, view_args: dict[str, Any]) -> None: """Validate the interface name path param (400 on a bad name).""" validate_interface_name(view_args["name"]) def _applied(_data: Any, view_args: dict[str, Any], _sent: Any) -> Any: return {"name": view_args["name"], "applied": True} def _reloaded(_data: Any, view_args: dict[str, Any], _sent: Any) -> Any: return {"name": view_args["name"], "reloaded": True} @daemon_route(GET_NETWORK_INTERFACES, bp) def list_interfaces(): """GET /api/network/interfaces — List interfaces with config + runtime state.""" @daemon_route(GET_NETWORK_INTERFACE_NAME, bp, precheck=_check_iface) def get_interface(): """GET /api/network/interfaces/ — Config + runtime state for one interface.""" @daemon_route( POST_NETWORK_INTERFACE_NAME, bp, precheck=_check_iface, transform=_applied ) def save_interface(): """POST /api/network/interfaces/ — Save and apply an interface's config.""" @daemon_route( POST_NETWORK_INTERFACE_RELOAD, bp, precheck=_check_iface, body={}, transform=_reloaded, ) def reload_interface(): """POST /api/network/interfaces//reload — Reload networkd for one interface.""" @daemon_route(POST_NETWORK_APPLY, bp) def apply_all(): """POST /api/network/apply — Apply network config for ALL interfaces.""" @daemon_route(GET_NETWORK_INFER_DHCP_RANGES, bp) def infer_dhcp_ranges(): """GET /api/network/infer-dhcp-ranges — Suggest candidate DHCP ranges.""" @daemon_route(GET_NETWORK_INFER_ZONES, bp) def infer_zones(): """GET /api/network/infer-zones — Suggest firewalld zone assignments."""