0

Create PTR record

Published today

Create a DNS PTR record (record:ptr) pointing an IPv4 address (in its reverse zone) to the domain name ptrdname. Set name instead of ipv4addr for a PTR in a forward zone or an explicit reverse name (e.g. 5.0.20.10.in-addr.arpa). extattrs takes {"Site": "East"} or the WAPI shape {"Site": {"value": "East"}}. Returns the created record with its _ref.

Script infoblox_nios Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 2 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
async function wapiError(response: Response) {
18
  const text = await response.text()
19
  if (response.status === 401) {
20
    return new Error(
21
      "401 Unauthorized: wrong username or password, or the user's admin group has no API access"
22
    )
23
  }
24
  try {
25
    // WAPI errors are JSON: {"Error": "AdmConDataNotFoundError: ...", "code": "Client.Ibap.Data.NotFound", "text": "..."}
26
    const { Error: error, code, text: detail } = JSON.parse(text)
27
    if (error) {
28
      const message =
29
        detail && !error.includes(detail) ? `${error}: ${detail}` : error
30
      return new Error(
31
        `${response.status} ${message}${code ? ` (${code})` : ""}`
32
      )
33
    }
34
  } catch {}
35
  return new Error(`${response.status} ${text}`)
36
}
37

38
// Accept {"Site": "East"} as well as the WAPI shape {"Site": {"value": "East"}}.
39
function toExtattrs(extattrs: { [key: string]: any }) {
40
  return Object.fromEntries(
41
    Object.entries(extattrs).map(([name, v]) => [
42
      name,
43
      v !== null && typeof v === "object" && !Array.isArray(v)
44
        ? v
45
        : { value: v },
46
    ])
47
  )
48
}
49

50
/**
51
 * Create PTR record
52
 * Create a DNS PTR record (record:ptr) pointing an IPv4 address (in its reverse zone) to the domain name ptrdname. Set name instead of ipv4addr for a PTR in a forward zone or an explicit reverse name (e.g. 5.0.20.10.in-addr.arpa). extattrs takes {"Site": "East"} or the WAPI shape {"Site": {"value": "East"}}. Returns the created record with its _ref.
53
 */
54
export async function main(
55
  auth: RT.InfobloxNios,
56
  ptrdname: string,
57
  ipv4addr: string | undefined,
58
  name: string | undefined,
59
  view: string | undefined,
60
  ttl: number | undefined,
61
  comment: string | undefined,
62
  extattrs: { [key: string]: any } | undefined
63
) {
64
  if (!ipv4addr && !name) {
65
    throw new Error("Set ipv4addr or name")
66
  }
67

68
  const body: { [key: string]: any } = { ptrdname }
69
  if (ipv4addr) body.ipv4addr = ipv4addr
70
  if (name) body.name = name
71
  if (view) body.view = view
72
  if (ttl != null) {
73
    body.ttl = ttl
74
    body.use_ttl = true
75
  }
76
  if (comment) body.comment = comment
77
  if (extattrs && Object.keys(extattrs).length > 0)
78
    body.extattrs = toExtattrs(extattrs)
79

80
  const url = wapiUrl(auth, "record:ptr")
81
  url.searchParams.append(
82
    "_return_fields+",
83
    "name,ipv4addr,ptrdname,view,zone,ttl,comment"
84
  )
85
  url.searchParams.append("_return_as_object", "1")
86

87
  const response = await fetch(url, {
88
    method: "POST",
89
    headers: {
90
      Authorization: basicAuth(auth),
91
      "Content-Type": "application/json",
92
      Accept: "application/json",
93
    },
94
    body: JSON.stringify(body),
95
  })
96

97
  if (!response.ok) {
98
    throw await wapiError(response)
99
  }
100

101
  return await response.json()
102
}
103