refactor: update all API blueprints (certs, dhcp, firewall, logs, network, proxy, wireguard)

This commit is contained in:
2026-06-16 03:36:51 +00:00
parent 4fc0fb3f72
commit 708b8b5d15
7 changed files with 199 additions and 149 deletions
+42 -21
View File
@@ -8,6 +8,27 @@ import logging
from flask import Blueprint, request
from daemon.client import BadRequest, NotFound, delete, get, patch, post
from daemon.iface import (
DELETE_FIREWALL_FORWARD_PORT_REMOVE,
DELETE_FIREWALL_RICH_RULES_REMOVE,
DELETE_FIREWALL_ZONES_DELETE,
GET_FIREWALL_CONFIG,
GET_FIREWALL_CONFIG_PENDING,
GET_FIREWALL_INTERFACES,
GET_FIREWALL_RICH_RULES,
GET_FIREWALL_SERVICES,
GET_FIREWALL_ZONES,
GET_FIREWALL_ZONES_INFO,
PATCH_FIREWALL_CONFIG,
POST_FIREWALL_CONFIG,
POST_FIREWALL_CONFIG_APPLY,
POST_FIREWALL_FORWARD_PORT_ADD,
POST_FIREWALL_MASQUERADE,
POST_FIREWALL_RICH_RULES_ADD,
POST_FIREWALL_ZONES_CREATE,
POST_FIREWALL_ZONES_INTERFACES,
POST_FIREWALL_ZONES_SERVICES,
)
from webui.api.common import _error, _ok
logger = logging.getLogger(__name__)
@@ -32,7 +53,7 @@ def config_list():
JSON response with the config data or an error message.
"""
try:
return _ok(get("/firewall/config"))
return _ok(get(GET_FIREWALL_CONFIG))
except RuntimeError as exc:
logger.error("Failed to read firewall config: %s", exc)
return _error(str(exc), 500)
@@ -60,9 +81,9 @@ def config_save():
if not isinstance(body["zones"], dict):
return _error("'zones' must be a dict", 400)
try:
post("/firewall/config", body)
post(POST_FIREWALL_CONFIG, body)
try:
pending = get("/firewall/config/pending")
pending = get(GET_FIREWALL_CONFIG_PENDING)
pending_data = {
"pending": pending.get("pending", []),
"needs_apply": pending.get("needs_apply", False),
@@ -106,9 +127,9 @@ def patch_config():
if not isinstance(body, dict):
return _error("Request body must be a JSON object", 400)
try:
patch("/firewall/config", body)
patch(PATCH_FIREWALL_CONFIG, body)
try:
pending = get("/firewall/config/pending")
pending = get(GET_FIREWALL_CONFIG_PENDING)
pending_data = {
"pending": pending.get("pending", []),
"needs_apply": pending.get("needs_apply", False),
@@ -145,7 +166,7 @@ def config_apply_bp():
JSON with ``applied_zones`` list or an error message.
"""
try:
result = post("/firewall/config/apply")
result = post(POST_FIREWALL_CONFIG_APPLY)
logger.info("Firewall config applied: %s", result.get("applied_zones", []))
return _ok(result)
except RuntimeError as exc:
@@ -167,7 +188,7 @@ def config_pending_bp():
JSON with pending changes and apply status.
"""
try:
return _ok(get("/firewall/config/pending"))
return _ok(get(GET_FIREWALL_CONFIG_PENDING))
except RuntimeError as exc:
logger.error("Failed to check pending config: %s", exc)
return _error(str(exc), 500)
@@ -189,7 +210,7 @@ def list_zones():
JSON with ``active`` zones dict and ``available`` zones list.
"""
try:
data = get("/firewall/zones")
data = get(GET_FIREWALL_ZONES)
return _ok(
{"active": data.get("active", {}), "available": data.get("available", [])}
)
@@ -212,7 +233,7 @@ def zone_details(name: str):
JSON with zone configuration details or 404 error.
"""
try:
info = get("/firewall/zones/info", {"zone": name})
info = get(GET_FIREWALL_ZONES_INFO, {"zone": name})
return _ok(info)
except NotFound as exc:
logger.info("Zone '%s' not found: %s", name, exc)
@@ -241,7 +262,7 @@ def create_zone_bp():
if not zone_name:
return _error("Zone name is required", 400)
try:
post("/firewall/zones/create", {"name": zone_name, "target": target})
post(POST_FIREWALL_ZONES_CREATE, {"name": zone_name, "target": target})
logger.info("Zone '%s' created via API", zone_name)
return _ok(None)
except BadRequest as exc:
@@ -266,7 +287,7 @@ def delete_zone_bp(name: str):
JSON confirmation or 404 if the zone does not exist.
"""
try:
delete("/firewall/zones/delete", {"zone": name})
delete(DELETE_FIREWALL_ZONES_DELETE, {"zone": name})
logger.info("Zone '%s' deleted via API", name)
return _ok(None)
except NotFound as exc:
@@ -303,7 +324,7 @@ def set_zone_interfaces_bp(name: str):
if not isinstance(interfaces, list):
return _error("'interfaces' must be a list", 400)
try:
post("/firewall/zones/interfaces", {"zone": name, "interfaces": interfaces})
post(POST_FIREWALL_ZONES_INTERFACES, {"zone": name, "interfaces": interfaces})
logger.info("Zone '%s' interfaces updated: %s", name, interfaces)
return _ok({"zone": name, "interfaces": interfaces})
except BadRequest as exc:
@@ -343,7 +364,7 @@ def set_zone_services_bp(name: str):
if not isinstance(services, list):
return _error("'services' must be a list", 400)
try:
post("/firewall/zones/services", {"zone": name, "services": services})
post(POST_FIREWALL_ZONES_SERVICES, {"zone": name, "services": services})
return _ok({"zone": name, "services": services})
except BadRequest as exc:
logger.info("Set services for zone '%s' rejected: %s", name, exc)
@@ -372,7 +393,7 @@ def list_services():
JSON with the list of available service names.
"""
try:
return _ok(get("/firewall/services"))
return _ok(get(GET_FIREWALL_SERVICES))
except RuntimeError as exc:
logger.error("Failed to list services: %s", exc)
return _error(str(exc), 500)
@@ -389,7 +410,7 @@ def list_interfaces():
JSON with the list of available interface names.
"""
try:
return _ok(get("/firewall/interfaces"))
return _ok(get(GET_FIREWALL_INTERFACES))
except RuntimeError as exc:
logger.error("Failed to list interfaces: %s", exc)
return _error(str(exc), 500)
@@ -419,7 +440,7 @@ def add_rich_rule_bp():
if not zone or not rule:
return _error("Both 'zone' and 'rule' are required", 400)
try:
entry = post("/firewall/rich-rules/add", {"zone": zone, "rule": rule})
entry = post(POST_FIREWALL_RICH_RULES_ADD, {"zone": zone, "rule": rule})
logger.info("Rich rule added to zone '%s': %s", zone, rule[:80])
return _ok({"zone": zone, "id": entry["id"], "rule": rule})
except BadRequest as exc:
@@ -444,7 +465,7 @@ def list_rich_rules(zone: str):
JSON with list of rich rule entries for the zone.
"""
try:
return _ok(get("/firewall/rich-rules", {"zone": zone}))
return _ok(get(GET_FIREWALL_RICH_RULES, {"zone": zone}))
except RuntimeError as exc:
logger.error("Failed to get rich rules for zone '%s': %s", zone, exc)
return _error(str(exc), 500)
@@ -465,7 +486,7 @@ def remove_rich_rule_bp(zone: str, rule_id: str):
JSON confirmation or 404 if the rule does not exist.
"""
try:
delete("/firewall/rich-rules/remove", {"zone": zone, "id": rule_id})
delete(DELETE_FIREWALL_RICH_RULES_REMOVE, {"zone": zone, "id": rule_id})
logger.info("Rich rule '%s' removed from zone '%s'", rule_id, zone)
return _ok({"zone": zone, "id": rule_id})
except NotFound as exc:
@@ -500,7 +521,7 @@ def set_masquerade_bp():
if not zone or enable is None:
return _error("'zone' and 'enable' (bool) are required", 400)
try:
post("/firewall/masquerade", {"zone": zone, "enable": bool(enable)})
post(POST_FIREWALL_MASQUERADE, {"zone": zone, "enable": bool(enable)})
logger.info(
"Masquerade %s on zone '%s' via API",
"enabled" if enable else "disabled",
@@ -555,7 +576,7 @@ def add_forward_port_bp():
toaddr_str = str(toaddr) if toaddr else None
try:
entry = post(
"/firewall/forward-port/add",
POST_FIREWALL_FORWARD_PORT_ADD,
{
"zone": zone,
"port": port_int,
@@ -590,7 +611,7 @@ def remove_forward_port_bp(zone: str, port: int, proto: str):
"""
try:
delete(
"/firewall/forward-port/remove",
DELETE_FIREWALL_FORWARD_PORT_REMOVE,
{"zone": zone, "port": port, "proto": proto},
)
logger.info("Forward port %s/%s removed from zone '%s'", port, proto, zone)