1 | |
2 |
|
3 | function wapiUrl(auth: RT.InfobloxNios, path: string) { |
4 | const host = auth.host |
5 | .trim() |
6 | .replace(/^https?:\/\//, "") |
7 | .replace(/\/+$/, "") |
8 | const version = auth.wapi_version.trim().replace(/^v/, "") |
9 | return new URL(`https://${host}/wapi/v${version}/${path}`) |
10 | } |
11 |
|
12 | function refUrl(auth: RT.InfobloxNios, ref: string, type: string) { |
13 | |
14 | const segments = ref.split("/") |
15 | if ( |
16 | segments[0] !== type || |
17 | segments.length < 2 || |
18 | segments.some((s) => s === "." || s === "..") |
19 | ) { |
20 | throw new Error(`Expected a ${type} reference, got: ${ref}`) |
21 | } |
22 | return wapiUrl( |
23 | auth, |
24 | segments.map((s) => encodeURIComponent(s).replace(/%3A/gi, ":")).join("/") |
25 | ) |
26 | } |
27 |
|
28 | function basicAuth(auth: RT.InfobloxNios) { |
29 | const bytes = new TextEncoder().encode(`${auth.username}:${auth.password}`) |
30 | return `Basic ${btoa(String.fromCharCode(...bytes))}` |
31 | } |
32 |
|
33 | |
34 | * Delete fixed address |
35 | * Delete a static DHCP reservation, identified by its _ref or by its MAC address (optionally narrowed by network_view). Fails without deleting anything when the MAC matches zero or several reservations. Returns the _ref of the deleted reservation. |
36 | */ |
37 | export async function main( |
38 | auth: RT.InfobloxNios, |
39 | ref: string | undefined, |
40 | mac: string | undefined, |
41 | network_view: string | undefined |
42 | ) { |
43 | if (!ref === !mac) { |
44 | throw new Error("Set exactly one of ref or mac") |
45 | } |
46 |
|
47 | let target = ref |
48 | if (!target) { |
49 | const lookup = wapiUrl(auth, "fixedaddress") |
50 | lookup.searchParams.append("mac", mac!) |
51 | if (network_view) lookup.searchParams.append("network_view", network_view) |
52 | lookup.searchParams.append("_return_as_object", "1") |
53 |
|
54 | const lookupResponse = await fetch(lookup, { |
55 | headers: { |
56 | Authorization: basicAuth(auth), |
57 | Accept: "application/json", |
58 | }, |
59 | }) |
60 | if (!lookupResponse.ok) { |
61 | throw new Error(`${lookupResponse.status} ${await lookupResponse.text()}`) |
62 | } |
63 | const { result } = (await lookupResponse.json()) as { |
64 | result: { _ref: string; ipv4addr: string; network_view: string }[] |
65 | } |
66 | if (result.length === 0) { |
67 | throw new Error(`No fixed address found for MAC ${mac}`) |
68 | } |
69 | if (result.length > 1) { |
70 | throw new Error( |
71 | `MAC ${mac} matches ${result.length} fixed addresses; pass the ref of one: ${result.map((r) => r._ref).join(", ")}` |
72 | ) |
73 | } |
74 | target = result[0]._ref |
75 | } |
76 |
|
77 | const url = refUrl(auth, target!, "fixedaddress") |
78 | url.searchParams.append("_return_as_object", "1") |
79 |
|
80 | const response = await fetch(url, { |
81 | method: "DELETE", |
82 | headers: { |
83 | Authorization: basicAuth(auth), |
84 | Accept: "application/json", |
85 | }, |
86 | }) |
87 |
|
88 | if (!response.ok) { |
89 | throw new Error(`${response.status} ${await response.text()}`) |
90 | } |
91 |
|
92 | return await response.json() |
93 | } |
94 |
|