Merge pull request 'unifi: list networks and set the DNS their DHCP hands out (hq issue 198)' (#215) from jschoubben/unifi-network-dns into main
This commit was merged in pull request #215.
This commit is contained in:
@@ -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[]> {
|
||||
|
||||
@@ -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.",
|
||||
|
||||
Reference in New Issue
Block a user