0

List security rules

by
Published today

List the security policy rules of a firewall vsys, or the pre or post rules of a Panorama device group or the shared location (PAN-OS REST API), in rulebase order. PAN-OS returns every rule of the rulebase in one response; the API does not paginate.

Script palo_alto_panos Verified

The script

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

3
/**
4
 * List security rules
5
 * List the security policy rules of a firewall vsys, or the pre or post rules of a Panorama device group or the shared location (PAN-OS REST API), in rulebase order. PAN-OS returns every rule of the rulebase in one response; the API does not paginate.
6
 */
7
export async function main(
8
  auth: RT.PaloAltoPanos,
9
  location: "vsys" | "device-group" | "shared" | undefined,
10
  vsys: string | undefined,
11
  device_group: string | undefined,
12
  rulebase: "pre" | "post" | undefined
13
) {
14
  const version = await restApiVersion(auth)
15
  const url = new URL(
16
    `/restapi/${version}/Policies/${ruleResource(location, rulebase)}`,
17
    auth.base_url
18
  )
19
  setLocation(url, location, vsys, device_group)
20

21
  const response = await fetch(url, {
22
    headers: { "X-PAN-KEY": auth.api_key, Accept: "application/json" },
23
  })
24
  const text = await response.text()
25
  if (!response.ok) {
26
    throw new Error(`${response.status} ${text}`)
27
  }
28
  const data = JSON.parse(text)
29
  if (data["@status"] !== "success") {
30
    throw new Error(`${response.status} ${text}`)
31
  }
32
  return data
33
}
34

35
// A firewall vsys has one rulebase (SecurityRules); Panorama has pre and post rulebases.
36
function ruleResource(
37
  location: string | undefined,
38
  rulebase: string | undefined
39
) {
40
  if ((location || "vsys") === "vsys") return "SecurityRules"
41
  return rulebase === "post" ? "SecurityPostRules" : "SecurityPreRules"
42
}
43

44
function setLocation(
45
  url: URL,
46
  location: string | undefined,
47
  vsys: string | undefined,
48
  device_group: string | undefined
49
) {
50
  const loc = location || "vsys"
51
  url.searchParams.set("location", loc)
52
  if (loc === "vsys") {
53
    url.searchParams.set("vsys", vsys || "vsys1")
54
  } else if (loc === "device-group") {
55
    if (!device_group) {
56
      throw new Error("device_group is required when location is device-group")
57
    }
58
    url.searchParams.set("device-group", device_group)
59
  }
60
}
61

62
async function restApiVersion(auth: RT.PaloAltoPanos) {
63
  if (auth.rest_api_version) return auth.rest_api_version
64
  const url = new URL("/api/", auth.base_url)
65
  url.searchParams.set("type", "op")
66
  url.searchParams.set("cmd", "<show><system><info></info></system></show>")
67
  const response = await fetch(url, { headers: { "X-PAN-KEY": auth.api_key } })
68
  const text = await response.text()
69
  if (!response.ok || text.includes('status="error"')) {
70
    throw new Error(`${response.status} ${text}`)
71
  }
72
  const match = text.match(/<sw-version>(\d+)\.(\d+)/)
73
  if (!match) {
74
    throw new Error(
75
      `Could not read sw-version from show system info; set rest_api_version on the resource. ${text}`
76
    )
77
  }
78
  return `v${match[1]}.${match[2]}`
79
}
80