0

Get device interfaces

by
Published today

Get the interfaces of a device with their IF-MIB attributes (description, alias, admin/oper status, speed).

Script akips Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 6 hours ago
1
//native
2

3
/**
4
 * Get device interfaces
5
 * Get the interfaces of one device with their IF-MIB attributes (ifDescr, ifAlias, ifAdminStatus, ifOperStatus, ifSpeed, ...). Optionally narrow to one interface name or /regex/.
6
 */
7
export async function main(
8
  auth: RT.Akips,
9
  device: string,
10
  interface_name: string | undefined
11
) {
12
  const cmd = `mget * ${device} ${interface_name || "*"} /^IF-MIB\\./`
13

14
  // A line break starts a second api-db command (§4.5.2 data), so inputs must stay on one line.
15
  if (/[\r\n]/.test(cmd)) throw new Error("api-db command must be a single line")
16

17
  // Documented form (API guide §4.5.2): password in the URL, commands in the POST body.
18
  const url = new URL(`${auth.base_url}/api-db`)
19
  url.searchParams.append("username", auth.username)
20
  url.searchParams.append("password", auth.password)
21
  const response = await fetch(url, {
22
    method: "POST",
23
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
24
    body: new URLSearchParams({ cmds: cmd }),
25
  }).catch((e) => {
26
    // Network errors quote the full URL: drop the query string, which holds the password.
27
    throw new Error(String(e).replaceAll(url.search, ""))
28
  })
29
  const text = await response.text()
30
  if (!response.ok || text.startsWith("ERROR:")) {
31
    throw new Error(`${response.status} ${text}`)
32
  }
33

34
  // Each line: "{device} {interface} IF-MIB.{attribute} = {value}"
35
  const byInterface = new Map<string, { [key: string]: string }>()
36
  for (const line of text.split("\n")) {
37
    const match = line.match(/^(\S+)\s+(\S+)\s+IF-MIB\.(\S+)\s+=\s?(.*)$/)
38
    if (!match) continue
39
    const [, , name, attribute, value] = match
40
    if (!byInterface.has(name)) byInterface.set(name, {})
41
    byInterface.get(name)![attribute] = value
42
  }
43

44
  // Enum values are "{number},{text},{created},{modified}[,{child description}]"
45
  const enumText = (v: string | undefined) =>
46
    v == null ? undefined : v.split(",")[1]
47

48
  const interfaces = [...byInterface.entries()].map(([name, a]) => ({
49
    name,
50
    descr: a["ifDescr"],
51
    alias: a["ifAlias"],
52
    admin_status: enumText(a["ifAdminStatus"]),
53
    oper_status: enumText(a["ifOperStatus"]),
54
    attributes: a,
55
  }))
56

57
  return { device, count: interfaces.length, interfaces }
58
}
59