85 lines
4.0 KiB
Python
85 lines
4.0 KiB
Python
"""DHCP server tools: leases, server config, static mappings."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
from mcp.server.fastmcp import FastMCP
|
|
|
|
from pfsense_mcp.audit import audit_log
|
|
from pfsense_mcp.client import get_client
|
|
from pfsense_mcp.config import settings
|
|
from pfsense_mcp.guards import is_dry_run_response, require_writes
|
|
|
|
|
|
def register(mcp: FastMCP) -> None:
|
|
@mcp.tool()
|
|
def pfsense_list_dhcp_leases(limit: int = 200, offset: int = 0, query: str = "", target: str = "", url: str = "", api_key: str = "", verify_ssl: bool | None = None) -> str:
|
|
"""List DHCP leases. query example: 'hostname__contains=nas' or 'ip__contains=10.77'."""
|
|
client = get_client(target=target, url=url, api_key=api_key, verify_ssl=verify_ssl)
|
|
result = client.get(
|
|
"status/dhcp_server/leases", params=client.list_params(limit, offset, query)
|
|
)
|
|
return json.dumps(result, indent=2, default=str)
|
|
|
|
@mcp.tool()
|
|
def pfsense_list_dhcp_servers(limit: int = 50, offset: int = 0, target: str = "", url: str = "", api_key: str = "", verify_ssl: bool | None = None) -> str:
|
|
"""List DHCP server configurations per interface (ranges, options, enabled state)."""
|
|
client = get_client(target=target, url=url, api_key=api_key, verify_ssl=verify_ssl)
|
|
result = client.get("services/dhcp_servers", params={"limit": limit, "offset": offset})
|
|
return json.dumps(result, indent=2, default=str)
|
|
|
|
@mcp.tool()
|
|
def pfsense_list_dhcp_static_mappings(
|
|
interface_id: str, limit: int = 200, offset: int = 0,
|
|
target: str = "", url: str = "", api_key: str = "", verify_ssl: bool | None = None,
|
|
) -> str:
|
|
"""List DHCP static mappings (reservations) for a DHCP server. interface_id: parent interface (e.g. 'lan')."""
|
|
client = get_client(target=target, url=url, api_key=api_key, verify_ssl=verify_ssl)
|
|
result = client.get(
|
|
"services/dhcp_server/static_mappings",
|
|
params={"parent_id": interface_id, "limit": limit, "offset": offset},
|
|
)
|
|
return json.dumps(result, indent=2, default=str)
|
|
|
|
@mcp.tool()
|
|
def pfsense_add_dhcp_static_mapping(
|
|
interface_id: str,
|
|
mac: str,
|
|
ip: str,
|
|
hostname: str = "",
|
|
description: str = "",
|
|
target: str = "",
|
|
url: str = "",
|
|
api_key: str = "",
|
|
verify_ssl: bool | None = None,
|
|
) -> str:
|
|
"""Add a DHCP static mapping (reservation) on an interface's DHCP server."""
|
|
payload: dict[str, Any] = {
|
|
"parent_id": interface_id,
|
|
"mac": mac,
|
|
"ipaddr": ip,
|
|
"hostname": hostname,
|
|
"descr": description,
|
|
}
|
|
if settings.dry_run:
|
|
return json.dumps(is_dry_run_response("add_dhcp_static_mapping", payload), indent=2)
|
|
require_writes("add_dhcp_static_mapping", payload)
|
|
client = get_client(target=target, url=url, api_key=api_key, verify_ssl=verify_ssl)
|
|
result = client.post("services/dhcp_server/static_mapping", data=payload)
|
|
audit_log("add_dhcp_static_mapping", payload | {"result": result})
|
|
return json.dumps(result, indent=2, default=str)
|
|
|
|
@mcp.tool()
|
|
def pfsense_delete_dhcp_static_mapping(interface_id: str, mapping_id: int, target: str = "", url: str = "", api_key: str = "", verify_ssl: bool | None = None) -> str:
|
|
"""Delete a DHCP static mapping by id."""
|
|
payload = {"parent_id": interface_id, "id": mapping_id}
|
|
if settings.dry_run:
|
|
return json.dumps(is_dry_run_response("delete_dhcp_static_mapping", payload), indent=2)
|
|
require_writes("delete_dhcp_static_mapping", payload)
|
|
client = get_client(target=target, url=url, api_key=api_key, verify_ssl=verify_ssl)
|
|
result = client.delete("services/dhcp_server/static_mapping", params=payload)
|
|
audit_log("delete_dhcp_static_mapping", payload | {"result": result})
|
|
return json.dumps(result, indent=2, default=str)
|