"""Aggregate status API blueprint. Exposed at /api/status/* and delegates all operations to vacuum-walld. """ from __future__ import annotations import logging from flask import Blueprint, request from daemon.client import get, post from daemon.iface import ( GET_STATUS_PENDING, GET_SYSTEM_METRICS, POST_STATUS_APPLY_ALL, POST_STATUS_REFRESH, ) from webui.api.common import _error, _ok logger = logging.getLogger(__name__) bp = Blueprint("status", __name__) @bp.route("/pending", methods=["GET"]) def pending(): """Retrieve aggregate pending changes across all subsystems. Endpoint: GET /api/status/pending Returns: JSON response with per-subsystem pending status and total change count. """ try: return _ok(get(GET_STATUS_PENDING)) except RuntimeError as exc: logger.error("Failed to get pending status: %s", exc) return _error(str(exc), 500) @bp.route("/apply-all", methods=["POST"]) def apply_all(): """Apply pending changes for all subsystems in dependency order. Endpoint: POST /api/status/apply-all Returns: JSON response with applied subsystems list and any errors encountered. """ try: return _ok(post(POST_STATUS_APPLY_ALL)) except RuntimeError as exc: logger.error("Failed to apply all pending changes: %s", exc) return _error(str(exc), 500) @bp.route("/refresh", methods=["POST"]) def refresh(): """Re-collect state from the daemon, optionally filtered by subsystem. Endpoint: POST /api/status/refresh Body: {"subsystems": ["firewall"]} or {} for all. """ body = request.get_json(silent=True) or {} try: return _ok(post(POST_STATUS_REFRESH, body)) except RuntimeError as exc: logger.error("Failed to refresh state: %s", exc) return _error(str(exc), 500) @bp.route("/system-metrics", methods=["GET"]) def system_metrics(): """Retrieve system-wide metrics. Endpoint: GET /api/status/system-metrics Returns: JSON response with CPU load, memory usage, and network traffic stats. """ try: return _ok(get(GET_SYSTEM_METRICS)) except RuntimeError as exc: logger.error("Failed to get system metrics: %s", exc) return _error(str(exc), 500)