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 | * Update host record |
35 | * Rename a host record, change its TTL or comment, or replace its IPv4 address list with a single address (and optional MAC), identified by its _ref (from Search records). Empty inputs are left unchanged. |
36 | */ |
37 | export async function main( |
38 | auth: RT.InfobloxNios, |
39 | ref: string, |
40 | name: string | undefined, |
41 | ipv4addr: string | undefined, |
42 | mac: string | undefined, |
43 | ttl: number | undefined, |
44 | comment: string | undefined |
45 | ) { |
46 | if (mac && !ipv4addr) { |
47 | throw new Error( |
48 | "mac is set together with ipv4addr, which replaces the address list" |
49 | ) |
50 | } |
51 |
|
52 | const body: { [key: string]: any } = {} |
53 | if (name) body.name = name |
54 | if (ipv4addr) body.ipv4addrs = [mac ? { ipv4addr, mac } : { ipv4addr }] |
55 | if (ttl != null) { |
56 | body.ttl = ttl |
57 | body.use_ttl = true |
58 | } |
59 | if (comment) body.comment = comment |
60 | if (Object.keys(body).length === 0) { |
61 | throw new Error("Nothing to update: set at least one field") |
62 | } |
63 |
|
64 | const url = refUrl(auth, ref, "record:host") |
65 | url.searchParams.append( |
66 | "_return_fields+", |
67 | "name,ipv4addrs,view,aliases,ttl,comment" |
68 | ) |
69 | url.searchParams.append("_return_as_object", "1") |
70 |
|
71 | const response = await fetch(url, { |
72 | method: "PUT", |
73 | headers: { |
74 | Authorization: basicAuth(auth), |
75 | "Content-Type": "application/json", |
76 | Accept: "application/json", |
77 | }, |
78 | body: JSON.stringify(body), |
79 | }) |
80 |
|
81 | if (!response.ok) { |
82 | throw new Error(`${response.status} ${await response.text()}`) |
83 | } |
84 |
|
85 | return await response.json() |
86 | } |
87 |
|