0

Push value

by
Published today

Push a value to a trapper item (Zabbix 7.0+) to raise an alarm.

Script zabbix Verified

The script

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

3
/**
4
 * Push value
5
 * Push a value to a Zabbix trapper item (history.push, Zabbix 7.0+), identified by itemid or by technical host name + item key, e.g. to raise an alarm when a workflow fails. The trapper item and its trigger must already exist; if the item restricts Allowed hosts, include the Zabbix web frontend's IP. Minimal setup: a trapper item with key "trap" (numeric) and a trigger like last(/<host>/trap)>0; push 1 on failure and 0 to recover. Throws if Zabbix rejects the push (unknown item, no permission, source not in Allowed hosts). A value that doesn't fit the item's type is accepted, then makes the item unsupported.
6
 */
7
export async function main(
8
  auth: RT.Zabbix,
9
  value: string,
10
  itemid: string | undefined,
11
  host: string | undefined,
12
  key: string | undefined,
13
  clock: string | undefined
14
) {
15
  const params: { [key: string]: any } = { value }
16
  if (itemid && (host || key)) {
17
    throw new Error("Provide itemid, or host and key, not both")
18
  }
19
  if (itemid) {
20
    params.itemid = itemid
21
  } else if (host && key) {
22
    params.host = host
23
    params.key = key
24
  } else {
25
    throw new Error("Provide itemid, or both host and key")
26
  }
27
  if (clock) {
28
    const seconds = Math.floor(new Date(clock).getTime() / 1000)
29
    if (Number.isNaN(seconds)) {
30
      throw new Error(`Invalid clock: ${clock}`)
31
    }
32
    params.clock = seconds
33
  }
34

35
  const result = await call(auth, "history.push", params)
36
  const failed = (result.data ?? []).filter((d: any) => d.error)
37
  if (failed.length) {
38
    throw new Error(
39
      `history.push rejected the value: ${failed.map((d: any) => d.error).join("; ")}`
40
    )
41
  }
42
  return result
43
}
44

45
async function call(auth: RT.Zabbix, method: string, params: any) {
46
  const response = await fetch(
47
    `${auth.base_url.replace(/\/+$/, "").replace(/\/api_jsonrpc\.php$/, "")}/api_jsonrpc.php`,
48
    {
49
      method: "POST",
50
      headers: {
51
        Authorization: `Bearer ${auth.token}`,
52
        "Content-Type": "application/json-rpc",
53
        Accept: "application/json",
54
      },
55
      body: JSON.stringify({ jsonrpc: "2.0", method, params, id: 1 }),
56
    }
57
  )
58

59
  if (!response.ok) {
60
    throw new Error(`${response.status} ${await response.text()}`)
61
  }
62

63
  const text = await response.text()
64
  let data: any
65
  try {
66
    data = JSON.parse(text)
67
  } catch {
68
    throw new Error(
69
      `Not a JSON-RPC response (check base_url): ${text.slice(0, 300)}`
70
    )
71
  }
72
  if (data.error) {
73
    throw new Error(
74
      `${data.error.code} ${data.error.message} ${data.error.data ?? ""}`
75
    )
76
  }
77
  return data.result
78
}
79