Zabbix API: add types

This commit is contained in:
Alexander Zobnin
2020-05-18 11:37:22 +03:00
parent a3f45f1bb8
commit d7a96f06ee
6 changed files with 83 additions and 41 deletions

View File

@@ -165,6 +165,8 @@ export class ZabbixDatasource {
return this.queryNumericData(target, timeRange, useTrends, options); return this.queryNumericData(target, timeRange, useTrends, options);
} else if (target.queryType === c.MODE_TEXT) { } else if (target.queryType === c.MODE_TEXT) {
return this.queryTextData(target, timeRange); return this.queryTextData(target, timeRange);
} else {
return [];
} }
} else if (target.queryType === c.MODE_ITEMID) { } else if (target.queryType === c.MODE_ITEMID) {
// Item ID query // Item ID query

View File

@@ -0,0 +1,42 @@
export interface JSONRPCRequest {
jsonrpc: '2.0' | string;
method: string;
id: number;
auth?: string | null;
params?: JSONRPCRequestParams;
}
export interface JSONRPCResponse<T> {
jsonrpc: '2.0' | string;
id: number;
result?: T;
error?: JSONRPCError;
}
export interface JSONRPCError {
code?: number;
message?: string;
data?: string;
}
export interface GFHTTPRequest {
method: HTTPMethod;
url: string;
data?: any;
headers?: {[key: string]: string};
withCredentials?: boolean;
}
export type JSONRPCRequestParams = {[key: string]: any};
export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'CONNECT' | 'OPTIONS' | 'TRACE';
export type GFRequestOptions = {[key: string]: any};
export interface ZabbixRequestResponse {
data?: JSONRPCResponse<any>;
}
export type ZabbixAPIResponse<T> = T;
export type APILoginResponse = string;

View File

@@ -5,6 +5,7 @@ import * as utils from '../../../utils';
import { ZabbixAPICore } from './zabbixAPICore'; import { ZabbixAPICore } from './zabbixAPICore';
import { ZBX_ACK_ACTION_NONE, ZBX_ACK_ACTION_ACK, ZBX_ACK_ACTION_ADD_MESSAGE, MIN_SLA_INTERVAL } from '../../../constants'; import { ZBX_ACK_ACTION_NONE, ZBX_ACK_ACTION_ACK, ZBX_ACK_ACTION_ADD_MESSAGE, MIN_SLA_INTERVAL } from '../../../constants';
import { ShowProblemTypes, ZBXProblem } from '../../../types'; import { ShowProblemTypes, ZBXProblem } from '../../../types';
import { JSONRPCRequestParams } from './types';
const DEFAULT_ZABBIX_VERSION = '3.0.0'; const DEFAULT_ZABBIX_VERSION = '3.0.0';
@@ -14,20 +15,20 @@ const DEFAULT_ZABBIX_VERSION = '3.0.0';
* Wraps API calls and provides high-level methods. * Wraps API calls and provides high-level methods.
*/ */
export class ZabbixAPIConnector { export class ZabbixAPIConnector {
url: any; url: string;
username: any; username: string;
password: any; password: string;
auth: string; auth: string;
requestOptions: { basicAuth: any; withCredentials: any; }; requestOptions: { basicAuth: any; withCredentials: boolean; };
loginPromise: any; loginPromise: Promise<string>;
loginErrorCount: number; loginErrorCount: number;
maxLoginAttempts: number; maxLoginAttempts: number;
zabbixAPICore: ZabbixAPICore; zabbixAPICore: ZabbixAPICore;
getTrend: (items: any, timeFrom: any, timeTill: any) => Promise<any[]>; getTrend: (items: any, timeFrom: any, timeTill: any) => Promise<any[]>;
version: any; version: string;
getVersionPromise: any; getVersionPromise: Promise<string>;
constructor(api_url, username, password, basicAuth, withCredentials) { constructor(api_url: string, username: string, password: string, basicAuth: any, withCredentials: boolean) {
this.url = api_url; this.url = api_url;
this.username = username; this.username = username;
this.password = password; this.password = password;
@@ -54,7 +55,7 @@ export class ZabbixAPIConnector {
// Core method wrappers // // Core method wrappers //
////////////////////////// //////////////////////////
request(method, params) { request(method: string, params: JSONRPCRequestParams): Promise<any> {
if (!this.version) { if (!this.version) {
return this.initVersion().then(() => this.request(method, params)); return this.initVersion().then(() => this.request(method, params));
} }
@@ -81,9 +82,8 @@ export class ZabbixAPIConnector {
* When API unauthenticated or auth token expired each request produce login() * When API unauthenticated or auth token expired each request produce login()
* call. But auth token is common to all requests. This function wraps login() method * call. But auth token is common to all requests. This function wraps login() method
* and call it once. If login() already called just wait for it (return its promise). * and call it once. If login() already called just wait for it (return its promise).
* @return login promise
*/ */
loginOnce() { loginOnce(): Promise<string> {
if (!this.loginPromise) { if (!this.loginPromise) {
this.loginPromise = Promise.resolve( this.loginPromise = Promise.resolve(
this.login().then(auth => { this.login().then(auth => {
@@ -99,7 +99,7 @@ export class ZabbixAPIConnector {
/** /**
* Get authentication token. * Get authentication token.
*/ */
login() { login(): Promise<string> {
return this.zabbixAPICore.login(this.url, this.username, this.password, this.requestOptions); return this.zabbixAPICore.login(this.url, this.username, this.password, this.requestOptions);
} }
@@ -110,7 +110,7 @@ export class ZabbixAPIConnector {
return this.zabbixAPICore.getVersion(this.url, this.requestOptions); return this.zabbixAPICore.getVersion(this.url, this.requestOptions);
} }
initVersion() { initVersion(): Promise<string> {
if (!this.getVersionPromise) { if (!this.getVersionPromise) {
this.getVersionPromise = Promise.resolve( this.getVersionPromise = Promise.resolve(
this.getVersion().then(version => { this.getVersion().then(version => {
@@ -166,7 +166,7 @@ export class ZabbixAPIConnector {
return this.request('host.get', params); return this.request('host.get', params);
} }
getApps(hostids) { getApps(hostids): Promise<any[]> {
const params = { const params = {
output: 'extend', output: 'extend',
hostids: hostids hostids: hostids

View File

@@ -2,19 +2,15 @@
* General Zabbix API methods * General Zabbix API methods
*/ */
import { getBackendSrv } from '@grafana/runtime'; import { getBackendSrv } from '@grafana/runtime';
import { JSONRPCRequest, ZabbixRequestResponse, JSONRPCError, APILoginResponse, GFHTTPRequest, GFRequestOptions } from './types';
export class ZabbixAPICore { export class ZabbixAPICore {
/** @ngInject */
constructor() {
}
/** /**
* Request data from Zabbix API * Request data from Zabbix API
* @return {object} response.result * @return {object} response.result
*/ */
request(api_url, method, params, options, auth?) { request(api_url: string, method: string, params: any, options: GFRequestOptions, auth?: string) {
const requestData: any = { const requestData: JSONRPCRequest = {
jsonrpc: '2.0', jsonrpc: '2.0',
method: method, method: method,
params: params, params: params,
@@ -29,7 +25,7 @@ export class ZabbixAPICore {
requestData.auth = auth; requestData.auth = auth;
} }
const requestOptions: any = { const requestOptions: GFHTTPRequest = {
method: 'POST', method: 'POST',
url: api_url, url: api_url,
data: requestData, data: requestData,
@@ -51,7 +47,7 @@ export class ZabbixAPICore {
datasourceRequest(requestOptions) { datasourceRequest(requestOptions) {
return getBackendSrv().datasourceRequest(requestOptions) return getBackendSrv().datasourceRequest(requestOptions)
.then((response) => { .then((response: ZabbixRequestResponse) => {
if (!response?.data) { if (!response?.data) {
return Promise.reject(new ZabbixAPIError({data: "General Error, no data"})); return Promise.reject(new ZabbixAPIError({data: "General Error, no data"}));
} else if (response?.data.error) { } else if (response?.data.error) {
@@ -69,7 +65,7 @@ export class ZabbixAPICore {
* Get authentication token. * Get authentication token.
* @return {string} auth token * @return {string} auth token
*/ */
login(api_url, username, password, options) { login(api_url: string, username: string, password: string, options: GFRequestOptions): Promise<APILoginResponse> {
const params = { const params = {
user: username, user: username,
password: password password: password
@@ -81,7 +77,7 @@ export class ZabbixAPICore {
* Get Zabbix API version * Get Zabbix API version
* Matches the version of Zabbix starting from Zabbix 2.0.4 * Matches the version of Zabbix starting from Zabbix 2.0.4
*/ */
getVersion(api_url, options) { getVersion(api_url: string, options: GFRequestOptions): Promise<string> {
return this.request(api_url, 'apiinfo.version', [], options).catch(err => { return this.request(api_url, 'apiinfo.version', [], options).catch(err => {
console.error(err); console.error(err);
return undefined; return undefined;
@@ -91,12 +87,12 @@ export class ZabbixAPICore {
// Define zabbix API exception type // Define zabbix API exception type
export class ZabbixAPIError { export class ZabbixAPIError {
code: any; code: number;
name: any; name: string;
data: any; data: string;
message: string; message: string;
constructor(error) { constructor(error: JSONRPCError) {
this.code = error.code || null; this.code = error.code || null;
this.name = error.message || ""; this.name = error.message || "";
this.data = error.data || ""; this.data = error.data || "";

View File

@@ -10,6 +10,11 @@ import { InfluxDBConnector } from './connectors/influxdb/influxdbConnector';
import { ZabbixConnector } from './types'; import { ZabbixConnector } from './types';
import { joinTriggersWithProblems } from '../problemsHandler'; import { joinTriggersWithProblems } from '../problemsHandler';
interface AppsResponse extends Array<any> {
appFilterEmpty?: boolean;
hostids?: any[];
}
const REQUESTS_TO_PROXYFY = [ const REQUESTS_TO_PROXYFY = [
'getHistory', 'getTrend', 'getGroups', 'getHosts', 'getApps', 'getItems', 'getMacros', 'getItemsByIDs', 'getHistory', 'getTrend', 'getGroups', 'getHosts', 'getApps', 'getItems', 'getMacros', 'getItemsByIDs',
'getEvents', 'getAlerts', 'getHostAlerts', 'getAcknowledges', 'getITService', 'getSLA', 'getVersion', 'getProxies', 'getEvents', 'getAlerts', 'getHostAlerts', 'getAcknowledges', 'getITService', 'getSLA', 'getVersion', 'getProxies',
@@ -178,9 +183,9 @@ export class Zabbix implements ZabbixConnector {
return Promise.all([ return Promise.all([
this.getHosts(...filters), this.getHosts(...filters),
this.getApps(...filters), this.getApps(...filters),
]).then((results) => { ]).then(results => {
// tslint:disable-next-line: prefer-const const hosts = results[0];
let [hosts, apps] = results; let apps: AppsResponse = results[1];
if (apps.appFilterEmpty) { if (apps.appFilterEmpty) {
apps = []; apps = [];
} }
@@ -224,7 +229,7 @@ export class Zabbix implements ZabbixConnector {
}); });
} }
getApps(groupFilter?, hostFilter?, appFilter?) { getApps(groupFilter?, hostFilter?, appFilter?): Promise<AppsResponse> {
return this.getHosts(groupFilter, hostFilter) return this.getHosts(groupFilter, hostFilter)
.then(hosts => { .then(hosts => {
const hostids = _.map(hosts, 'hostid'); const hostids = _.map(hosts, 'hostid');
@@ -232,10 +237,10 @@ export class Zabbix implements ZabbixConnector {
return this.zabbixAPI.getApps(hostids) return this.zabbixAPI.getApps(hostids)
.then(apps => filterByQuery(apps, appFilter)); .then(apps => filterByQuery(apps, appFilter));
} else { } else {
return { const appsResponse: AppsResponse = hostids;
appFilterEmpty: true, appsResponse.hostids = hostids;
hostids: hostids appsResponse.appFilterEmpty = true;
}; return Promise.resolve(appsResponse);
} }
}); });
} }

View File

@@ -2,10 +2,7 @@
"compilerOptions": { "compilerOptions": {
"moduleResolution": "node", "moduleResolution": "node",
"target": "es5", "target": "es5",
"lib": [ "lib": [ "es6", "dom", "es2017" ],
"es6",
"dom"
],
"rootDir": "./src", "rootDir": "./src",
"jsx": "react", "jsx": "react",
"module": "esnext", "module": "esnext",