unifi: list networks and set the DNS their DHCP hands out

Which DNS server the home network's DHCP hands out could be changed only
in the controller's own interface or by hand against its API (novox/hq
issue 198).
This commit is contained in:
2026-10-02 11:53:16 +02:00
parent 3020cd2312
commit d1f8ab86d1
2 changed files with 73 additions and 2 deletions
+24
View File
@@ -23,6 +23,19 @@ export interface UnifiPortForward {
site_id?: string;
}
export interface UnifiNetwork {
_id: string;
name: string;
purpose: string;
ip_subnet?: string;
dhcpd_enabled?: boolean;
dhcpd_dns_enabled?: boolean;
dhcpd_dns_1?: string;
dhcpd_dns_2?: string;
dhcpd_dns_3?: string;
dhcpd_dns_4?: string;
}
export interface UnifiDevice {
_id: string;
name: string;
@@ -232,6 +245,17 @@ export class UnifiApiClient {
await this.request<unknown>("DELETE", `/api/s/${this.site}/rest/portforward/${id}`);
}
// --- Networks ---
async listNetworks(): Promise<UnifiNetwork[]> {
return this.request<UnifiNetwork>("GET", `/api/s/${this.site}/rest/networkconf`);
}
async updateNetwork(id: string, fields: Partial<UnifiNetwork>): Promise<UnifiNetwork> {
const result = await this.request<UnifiNetwork>("PUT", `/api/s/${this.site}/rest/networkconf/${id}`, fields);
return result[0];
}
// --- Devices ---
async listDevices(): Promise<UnifiDevice[]> {
+49 -2
View File
@@ -1,10 +1,23 @@
// unifi's tools — its own code (novox/hq ADR 0039), importing unifi's own client. They return
// structured data; the mesh serves them through the sdk's tool harness. unifi is tools-only (no
// events entrypoint): the controller does not push lifecycle events the mesh consumes, so this
// module reads its resources — port forwards, devices, clients — and exposes them, and stops there.
// module reads its resources — port forwards, networks, devices, clients — and exposes them, and stops there.
import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools";
import { UnifiApiClient, type UnifiPortForward } from "../client.js";
import { UnifiApiClient, type UnifiNetwork, type UnifiPortForward } from "../client.js";
function summarizeNetwork(n: UnifiNetwork): Record<string, unknown> {
const dns = [n.dhcpd_dns_1, n.dhcpd_dns_2, n.dhcpd_dns_3, n.dhcpd_dns_4].filter((s): s is string => !!s);
return {
id: n._id,
name: n.name,
purpose: n.purpose,
subnet: n.ip_subnet ?? null,
dhcp: n.dhcpd_enabled ?? null,
// What DHCP hands out as DNS: the listed servers when set, otherwise the gateway itself.
dhcp_dns: n.dhcpd_dns_enabled ? dns : "the gateway",
};
}
function summarizePortForward(r: UnifiPortForward): Record<string, unknown> {
return {
@@ -88,6 +101,40 @@ export function getUnifiTools(unifi: UnifiApiClient): ToolDefinition[] {
return { deleted: true, id: String(args.id) };
},
},
{
name: "unifi_list_networks",
description: "List the networks the UniFi controller manages, with the DNS servers each one's DHCP hands out.",
input: {},
run: async () => {
const nets = await unifi.listNetworks();
return { count: nets.length, networks: nets.map(summarizeNetwork) };
},
},
{
name: "unifi_set_network_dns",
description:
"Set the DNS servers a network's DHCP hands out to its devices (see unifi_list_networks for ids). " +
"Up to four addresses, comma-separated; \"gateway\" hands out the gateway itself. Devices pick it up when they renew.",
input: {
id: { type: "string", description: "the network id" },
dns: { type: "string", description: "comma-separated DNS server addresses, or \"gateway\"" },
},
run: async (args) => {
const asked = String(args.dns ?? "").trim();
if (!asked) return { updated: false, reason: "say dns: addresses, or \"gateway\"" };
const servers = asked === "gateway" ? [] : asked.split(",").map((s) => s.trim()).filter(Boolean);
if (servers.length > 4) return { updated: false, reason: "DHCP hands out at most four DNS servers" };
const fields: Partial<UnifiNetwork> = {
dhcpd_dns_enabled: servers.length > 0,
dhcpd_dns_1: servers[0] ?? "",
dhcpd_dns_2: servers[1] ?? "",
dhcpd_dns_3: servers[2] ?? "",
dhcpd_dns_4: servers[3] ?? "",
};
const net = await unifi.updateNetwork(String(args.id), fields);
return { updated: summarizeNetwork(net) };
},
},
{
name: "unifi_list_devices",
description: "List the network devices (APs, switches, gateways) the UniFi controller manages.",