UNPKG

zabbix-utils

Version:

TypeScript port of zabbix-utils - Python library for working with Zabbix API, Sender, and Getter protocols

311 lines 9.82 kB
"use strict"; // zabbix_utils // // Copyright (C) 2001-2023 Zabbix SIA (Original Python library) // Copyright (C) 2024-2025 Han Yong Lim <hanyong.lim@gmail.com> (TypeScript adaptation) // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, // merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software // is furnished to do so, subject to the following conditions: Object.defineProperty(exports, "__esModule", { value: true }); exports.AgentResponse = exports.Cluster = exports.Node = exports.ItemValue = exports.TrapperResponse = exports.APIVersion = void 0; // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. const exceptions_1 = require("./exceptions"); const version_1 = require("./version"); class APIVersion { constructor(apiver) { this.__raw = apiver; const [first, second, third] = this.__parseVersion(this.__raw); this.__first = first; this.__second = second; this.__third = third; } /** * Get a symbol from the raw version string by index * For compatibility with using Zabbix version as a string */ [Symbol.iterator]() { return this.__raw[Symbol.iterator](); } charAt(index) { return this.__raw.charAt(index); } /** * Check if the current version is LTS. * * @returns true if the current version is LTS. */ isLts() { return this.__second === 0; } /** * Get major version number. * * @returns A major version number. */ get major() { return parseFloat(`${this.__first}.${this.__second}`); } /** * Get minor version number. * * @returns A minor version number. */ get minor() { return this.__third; } __parseVersion(ver) { // Parse the version string into a list of integers. const match = ver.match(/^(\d+)\.(\d+)\.(\d+)$/); if (!match) { throw new Error(`Unable to parse version of Zabbix API: ${ver}. ` + `Default '${version_1.__max_supported__}.0' format is expected.`); } return [parseInt(match[1]), parseInt(match[2]), parseInt(match[3])]; } toString() { return this.__raw; } valueOf() { return this.__raw; } equals(other) { if (typeof other === 'number') { return this.major === other; } if (typeof other === 'string') { const [first, second, third] = this.__parseVersion(other); return this.__first === first && this.__second === second && this.__third === third; } throw new TypeError(`'equals' not supported between instances of '${this.constructor.name}' and ` + `'${typeof other}', only 'number' or 'string' is expected`); } greaterThan(other) { if (typeof other === 'number') { return this.major > other; } if (typeof other === 'string') { const [first, second, third] = this.__parseVersion(other); return [this.__first, this.__second, this.__third] > [first, second, third]; } throw new TypeError(`'>' not supported between instances of '${this.constructor.name}' and ` + `'${typeof other}', only 'number' or 'string' is expected`); } lessThan(other) { if (typeof other === 'number') { return this.major < other; } if (typeof other === 'string') { const [first, second, third] = this.__parseVersion(other); return [this.__first, this.__second, this.__third] < [first, second, third]; } throw new TypeError(`'<' not supported between instances of '${this.constructor.name}' and ` + `'${typeof other}', only 'number' or 'string' is expected`); } notEquals(other) { return !this.equals(other); } greaterThanOrEqual(other) { return !this.lessThan(other); } lessThanOrEqual(other) { return !this.greaterThan(other); } } exports.APIVersion = APIVersion; class TrapperResponse { constructor(chunk = 1) { /** * Contains response from Zabbix server/proxy. * * @param chunk - Current chunk number. Defaults to 1. */ this.__processed = 0; this.__failed = 0; this.__total = 0; this.__time = 0; this.details = null; this.__chunk = chunk; } toString() { const result = {}; for (const [key, value] of Object.entries(this)) { if (key === 'details') { continue; } const cleanKey = key.replace(/^_+TrapperResponse_+/, '').replace(/^_+/, ''); result[cleanKey] = typeof value === 'number' ? value.toString() : value; } return JSON.stringify(result); } /** * Parse response from Zabbix. * * @param response - Raw response from Zabbix. * @throws ProcessingError if unexpected response received */ parse(response) { const fields = { "processed": ['[Pp]rocessed', '\\d+'], "failed": ['[Ff]ailed', '\\d+'], "total": ['[Tt]otal', '\\d+'], "time": ['[Ss]econds spent', '\\d+\\.\\d+'] }; const patternParts = Object.entries(fields).map(([k, [r0, r1]]) => `${r0}:\\s+?(?<${k}>${r1})`); const pattern = new RegExp(patternParts.join(';\\s+?')); const info = response.info; if (!info) { throw new exceptions_1.ProcessingError(`Received unexpected response: ${JSON.stringify(response)}`); } const match = pattern.exec(info); if (!match || !match.groups) { throw new exceptions_1.ProcessingError(`Failed to parse response: ${info}`); } return match.groups; } /** * Add and merge response data from Zabbix. * * @param response - Raw response from Zabbix. * @param chunk - Chunk number. Defaults to null. */ add(response, chunk) { const resp = this.parse(response); this.__processed += parseInt(resp.processed); this.__failed += parseInt(resp.failed); this.__total += parseInt(resp.total); this.__time += parseFloat(resp.time); if (chunk !== undefined) { this.__chunk = chunk; } this.details = response; } /** * Get processed count */ get processed() { return this.__processed; } /** * Get failed count */ get failed() { return this.__failed; } /** * Get total count */ get total() { return this.__total; } /** * Get time spent */ get time() { return this.__time; } /** * Get chunk number */ get chunk() { return this.__chunk; } } exports.TrapperResponse = TrapperResponse; class ItemValue { constructor(host, key, value, clock, ns) { this.host = host; this.key = key; this.value = value; this.clock = clock || Math.floor(Date.now() / 1000); this.ns = ns; } toString() { return JSON.stringify(this.toJson()); } valueOf() { return this.toString(); } toJson() { const result = { host: this.host, key: this.key, value: this.value, clock: this.clock }; if (this.ns !== undefined) { result.ns = this.ns; } return result; } } exports.ItemValue = ItemValue; class Node { constructor(addr, port) { this.addr = addr; this.port = typeof port === 'string' ? parseInt(port) : port; } toString() { return `${this.addr}:${this.port}`; } valueOf() { return this.toString(); } } exports.Node = Node; class Cluster { constructor(addr) { this.nodes = this.__parseHaNode(addr); } __parseHaNode(nodeList) { const nodes = []; for (const node of nodeList) { const [addr, port] = node.split(':'); nodes.push(new Node(addr, port || '10051')); } return nodes; } toString() { return this.nodes.map(node => node.toString()).join(','); } valueOf() { return this.toString(); } } exports.Cluster = Cluster; class AgentResponse { constructor(response) { this.raw = response; if (response.startsWith('ZBXD')) { // Handle binary protocol response this.value = response.slice(13); // Skip header } else if (response.startsWith('ZBX_NOTSUPPORTED')) { this.error = response.slice(17); // Remove "ZBX_NOTSUPPORTED\0" } else { this.value = response; } } toString() { return this.raw; } valueOf() { return this.toString(); } } exports.AgentResponse = AgentResponse; //# sourceMappingURL=types.js.map