1 | |
2 |
|
3 | async function adb(auth: RT.Akips, cmd: string) { |
4 | |
5 | if (/[\r\n]/.test(cmd)) throw new Error("api-db command must be a single line") |
6 |
|
7 | |
8 | const url = new URL(`${auth.base_url}/api-db`) |
9 | url.searchParams.append("username", auth.username) |
10 | url.searchParams.append("password", auth.password) |
11 | const response = await fetch(url, { |
12 | method: "POST", |
13 | headers: { "Content-Type": "application/x-www-form-urlencoded" }, |
14 | body: new URLSearchParams({ cmds: cmd }), |
15 | }).catch((e) => { |
16 | |
17 | throw new Error(String(e).replaceAll(url.search, "")) |
18 | }) |
19 | const text = await response.text() |
20 | if (!response.ok || text.startsWith("ERROR:")) { |
21 | throw new Error(`${response.status} ${text}`) |
22 | } |
23 | return text.split("\n").filter((line) => line.trim() !== "") |
24 | } |
25 |
|
26 | |
27 | * List devices |
28 | * List monitored devices with their IP addresses and SNMP system info (sysName, sysDescr, sysLocation, sysContact). Filter by device name/regex or device group. AKIPS returns all matches at once; limit/offset page through them. |
29 | */ |
30 | export async function main( |
31 | auth: RT.Akips, |
32 | device: string | undefined, |
33 | group: string | undefined, |
34 | limit: number | undefined, |
35 | offset: number | undefined |
36 | ) { |
37 | const selector = device || "*" |
38 | const groupFilter = group ? ` any group ${group}` : "" |
39 |
|
40 | |
41 | |
42 | const names = [ |
43 | ...new Set( |
44 | (await adb(auth, `mget device ${selector}${groupFilter}`)).map( |
45 | (line) => line.trim().split(/\s+/)[0] |
46 | ) |
47 | ), |
48 | ].sort() |
49 |
|
50 | const start = offset || 0 |
51 | const size = limit || 500 |
52 | const page = names.slice(start, start + size) |
53 |
|
54 | |
55 | const attributes = new Map<string, { [key: string]: string }>() |
56 | if (page.length > 0) { |
57 | const lines = await adb( |
58 | auth, |
59 | `mget text ${selector} sys /^(ip4addr|ip6addr|SNMPv2-MIB\\.sysName|SNMPv2-MIB\\.sysDescr|SNMPv2-MIB\\.sysLocation|SNMPv2-MIB\\.sysContact)$/${groupFilter}` |
60 | ) |
61 | for (const line of lines) { |
62 | const match = line.match(/^(\S+)\s+\S+\s+(\S+)\s+=\s?(.*)$/) |
63 | if (!match) continue |
64 | const [, name, attribute, value] = match |
65 | if (!attributes.has(name)) attributes.set(name, {}) |
66 | attributes.get(name)![attribute] = value |
67 | } |
68 | } |
69 |
|
70 | const devices = page.map((name) => { |
71 | const a = attributes.get(name) ?? {} |
72 | return { |
73 | name, |
74 | ip4addr: a["ip4addr"], |
75 | ip6addr: a["ip6addr"], |
76 | sys_name: a["SNMPv2-MIB.sysName"], |
77 | sys_descr: a["SNMPv2-MIB.sysDescr"], |
78 | sys_location: a["SNMPv2-MIB.sysLocation"], |
79 | sys_contact: a["SNMPv2-MIB.sysContact"], |
80 | } |
81 | }) |
82 |
|
83 | return { |
84 | total: names.length, |
85 | offset: start, |
86 | limit: size, |
87 | next_offset: start + size < names.length ? start + size : null, |
88 | devices, |
89 | } |
90 | } |
91 |
|