0

Get next available IP

by
Published today

Return the next free IPv4 address(es) of a network, given its CIDR (e.g. 10.20.0.0/24). Nothing is reserved: to allocate atomically, create the host record or fixed address with next_available_in_network instead.

Script infoblox_nios Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 7 hours ago
1
//native
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 basicAuth(auth: RT.InfobloxNios) {
13
  const bytes = new TextEncoder().encode(`${auth.username}:${auth.password}`)
14
  return `Basic ${btoa(String.fromCharCode(...bytes))}`
15
}
16

17
/**
18
 * Get next available IP
19
 * Return the next free IPv4 address(es) of a network, given its CIDR (e.g. 10.20.0.0/24). Nothing is reserved: to allocate atomically, create the host record or fixed address with next_available_in_network instead.
20
 */
21
export async function main(
22
  auth: RT.InfobloxNios,
23
  network: string,
24
  network_view: string | undefined,
25
  num: number | undefined,
26
  exclude: string[] | undefined
27
) {
28
  const lookup = wapiUrl(auth, "network")
29
  lookup.searchParams.append("network", network)
30
  if (network_view) lookup.searchParams.append("network_view", network_view)
31
  lookup.searchParams.append("_return_as_object", "1")
32

33
  const lookupResponse = await fetch(lookup, {
34
    headers: {
35
      Authorization: basicAuth(auth),
36
      Accept: "application/json",
37
    },
38
  })
39
  if (!lookupResponse.ok) {
40
    throw new Error(`${lookupResponse.status} ${await lookupResponse.text()}`)
41
  }
42
  const { result: networks } = (await lookupResponse.json()) as {
43
    result: { _ref: string; network: string; network_view: string }[]
44
  }
45
  if (networks.length === 0) {
46
    throw new Error(`Network ${network} not found`)
47
  }
48
  if (networks.length > 1) {
49
    throw new Error(
50
      `Network ${network} exists in several network views (${networks.map((n) => n.network_view).join(", ")}); set network_view`
51
    )
52
  }
53

54
  const url = wapiUrl(auth, networks[0]._ref)
55
  url.searchParams.append("_function", "next_available_ip")
56
  url.searchParams.append("_return_as_object", "1")
57

58
  const body: { [key: string]: any } = { num: num || 1 }
59
  if (exclude?.length) body.exclude = exclude
60

61
  const response = await fetch(url, {
62
    method: "POST",
63
    headers: {
64
      Authorization: basicAuth(auth),
65
      "Content-Type": "application/json",
66
      Accept: "application/json",
67
    },
68
    body: JSON.stringify(body),
69
  })
70

71
  if (!response.ok) {
72
    throw new Error(`${response.status} ${await response.text()}`)
73
  }
74

75
  const data = await response.json()
76
  return { network_ref: networks[0]._ref, ips: data.result.ips }
77
}
78