1 | |
2 |
|
3 | const READ_COMMANDS = [ |
4 | "aggregate", |
5 | "calc", |
6 | "check", |
7 | "count", |
8 | "cseries", |
9 | "get", |
10 | "list", |
11 | "mcalc", |
12 | "mget", |
13 | "mgroup", |
14 | "mlist", |
15 | "mtime", |
16 | "mtype", |
17 | "netmask", |
18 | "rget", |
19 | "series", |
20 | "tf", |
21 | "tget", |
22 | "top", |
23 | "tz", |
24 | ] |
25 |
|
26 | |
27 | * Run DB query |
28 | * Run one read-only AKIPS api-db command (e.g. `mget text * sys /ip.addr/`, `mlist interface swt250 *`) and parse each output line into tokens and, for `... = value` lines, the entity path and value. |
29 | */ |
30 | export async function main(auth: RT.Akips, command: string) { |
31 | const cmd = command.trim() |
32 | const verb = cmd.split(/\s+/)[0] |
33 | if (!READ_COMMANDS.includes(verb)) { |
34 | throw new Error( |
35 | `"${verb}" is not a read-only api-db command. Allowed: ${READ_COMMANDS.join(", ")}` |
36 | ) |
37 | } |
38 |
|
39 | |
40 | if (/[\r\n]/.test(cmd)) throw new Error("api-db command must be a single line") |
41 |
|
42 | |
43 | const url = new URL(`${auth.base_url}/api-db`) |
44 | url.searchParams.append("username", auth.username) |
45 | url.searchParams.append("password", auth.password) |
46 | const response = await fetch(url, { |
47 | method: "POST", |
48 | headers: { "Content-Type": "application/x-www-form-urlencoded" }, |
49 | body: new URLSearchParams({ cmds: cmd }), |
50 | }).catch((e) => { |
51 | |
52 | throw new Error(String(e).replaceAll(url.search, "")) |
53 | }) |
54 | const text = await response.text() |
55 | if (!response.ok || text.startsWith("ERROR:")) { |
56 | throw new Error(`${response.status} ${text}`) |
57 | } |
58 |
|
59 | const lines = text.split("\n").filter((line) => line.trim() !== "") |
60 | const rows = lines.map((line) => { |
61 | const eq = line.indexOf(" = ") |
62 | if (eq === -1) { |
63 | return { raw: line, tokens: line.trim().split(/\s+/) } |
64 | } |
65 | const entity = line.slice(0, eq).trim().split(/\s+/) |
66 | return { |
67 | raw: line, |
68 | tokens: entity, |
69 | parent: entity[0], |
70 | child: entity[1], |
71 | attribute: entity[2], |
72 | value: line.slice(eq + 3), |
73 | } |
74 | }) |
75 |
|
76 | return { command: cmd, count: rows.length, rows } |
77 | } |
78 |
|