From d7a96f06ee06ea5eb57459eb8832ac512d6fed80 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Mon, 18 May 2020 11:37:22 +0300 Subject: [PATCH] Zabbix API: add types --- src/datasource-zabbix/datasource.ts | 2 + .../zabbix/connectors/zabbix_api/types.ts | 42 +++++++++++++++++++ .../zabbix_api/zabbixAPIConnector.ts | 28 ++++++------- .../connectors/zabbix_api/zabbixAPICore.ts | 26 +++++------- src/datasource-zabbix/zabbix/zabbix.ts | 21 ++++++---- tsconfig.json | 5 +-- 6 files changed, 83 insertions(+), 41 deletions(-) create mode 100644 src/datasource-zabbix/zabbix/connectors/zabbix_api/types.ts diff --git a/src/datasource-zabbix/datasource.ts b/src/datasource-zabbix/datasource.ts index d3731ee..e648faa 100644 --- a/src/datasource-zabbix/datasource.ts +++ b/src/datasource-zabbix/datasource.ts @@ -165,6 +165,8 @@ export class ZabbixDatasource { return this.queryNumericData(target, timeRange, useTrends, options); } else if (target.queryType === c.MODE_TEXT) { return this.queryTextData(target, timeRange); + } else { + return []; } } else if (target.queryType === c.MODE_ITEMID) { // Item ID query diff --git a/src/datasource-zabbix/zabbix/connectors/zabbix_api/types.ts b/src/datasource-zabbix/zabbix/connectors/zabbix_api/types.ts new file mode 100644 index 0000000..007d592 --- /dev/null +++ b/src/datasource-zabbix/zabbix/connectors/zabbix_api/types.ts @@ -0,0 +1,42 @@ +export interface JSONRPCRequest { + jsonrpc: '2.0' | string; + method: string; + id: number; + auth?: string | null; + params?: JSONRPCRequestParams; +} + +export interface JSONRPCResponse { + 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; +} + +export type ZabbixAPIResponse = T; + +export type APILoginResponse = string; diff --git a/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts b/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts index 89fdb7b..bdc24cd 100644 --- a/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts +++ b/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts @@ -5,6 +5,7 @@ import * as utils from '../../../utils'; import { ZabbixAPICore } from './zabbixAPICore'; 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 { JSONRPCRequestParams } from './types'; 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. */ export class ZabbixAPIConnector { - url: any; - username: any; - password: any; + url: string; + username: string; + password: string; auth: string; - requestOptions: { basicAuth: any; withCredentials: any; }; - loginPromise: any; + requestOptions: { basicAuth: any; withCredentials: boolean; }; + loginPromise: Promise; loginErrorCount: number; maxLoginAttempts: number; zabbixAPICore: ZabbixAPICore; getTrend: (items: any, timeFrom: any, timeTill: any) => Promise; - version: any; - getVersionPromise: any; + version: string; + getVersionPromise: Promise; - constructor(api_url, username, password, basicAuth, withCredentials) { + constructor(api_url: string, username: string, password: string, basicAuth: any, withCredentials: boolean) { this.url = api_url; this.username = username; this.password = password; @@ -54,7 +55,7 @@ export class ZabbixAPIConnector { // Core method wrappers // ////////////////////////// - request(method, params) { + request(method: string, params: JSONRPCRequestParams): Promise { if (!this.version) { 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() * 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). - * @return login promise */ - loginOnce() { + loginOnce(): Promise { if (!this.loginPromise) { this.loginPromise = Promise.resolve( this.login().then(auth => { @@ -99,7 +99,7 @@ export class ZabbixAPIConnector { /** * Get authentication token. */ - login() { + login(): Promise { 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); } - initVersion() { + initVersion(): Promise { if (!this.getVersionPromise) { this.getVersionPromise = Promise.resolve( this.getVersion().then(version => { @@ -166,7 +166,7 @@ export class ZabbixAPIConnector { return this.request('host.get', params); } - getApps(hostids) { + getApps(hostids): Promise { const params = { output: 'extend', hostids: hostids diff --git a/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPICore.ts b/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPICore.ts index 4d4e5f5..802f7fc 100644 --- a/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPICore.ts +++ b/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPICore.ts @@ -2,19 +2,15 @@ * General Zabbix API methods */ import { getBackendSrv } from '@grafana/runtime'; +import { JSONRPCRequest, ZabbixRequestResponse, JSONRPCError, APILoginResponse, GFHTTPRequest, GFRequestOptions } from './types'; export class ZabbixAPICore { - - /** @ngInject */ - constructor() { - } - /** * Request data from Zabbix API * @return {object} response.result */ - request(api_url, method, params, options, auth?) { - const requestData: any = { + request(api_url: string, method: string, params: any, options: GFRequestOptions, auth?: string) { + const requestData: JSONRPCRequest = { jsonrpc: '2.0', method: method, params: params, @@ -29,7 +25,7 @@ export class ZabbixAPICore { requestData.auth = auth; } - const requestOptions: any = { + const requestOptions: GFHTTPRequest = { method: 'POST', url: api_url, data: requestData, @@ -51,7 +47,7 @@ export class ZabbixAPICore { datasourceRequest(requestOptions) { return getBackendSrv().datasourceRequest(requestOptions) - .then((response) => { + .then((response: ZabbixRequestResponse) => { if (!response?.data) { return Promise.reject(new ZabbixAPIError({data: "General Error, no data"})); } else if (response?.data.error) { @@ -69,7 +65,7 @@ export class ZabbixAPICore { * Get authentication token. * @return {string} auth token */ - login(api_url, username, password, options) { + login(api_url: string, username: string, password: string, options: GFRequestOptions): Promise { const params = { user: username, password: password @@ -81,7 +77,7 @@ export class ZabbixAPICore { * Get Zabbix API version * Matches the version of Zabbix starting from Zabbix 2.0.4 */ - getVersion(api_url, options) { + getVersion(api_url: string, options: GFRequestOptions): Promise { return this.request(api_url, 'apiinfo.version', [], options).catch(err => { console.error(err); return undefined; @@ -91,12 +87,12 @@ export class ZabbixAPICore { // Define zabbix API exception type export class ZabbixAPIError { - code: any; - name: any; - data: any; + code: number; + name: string; + data: string; message: string; - constructor(error) { + constructor(error: JSONRPCError) { this.code = error.code || null; this.name = error.message || ""; this.data = error.data || ""; diff --git a/src/datasource-zabbix/zabbix/zabbix.ts b/src/datasource-zabbix/zabbix/zabbix.ts index fca8d7c..3068141 100644 --- a/src/datasource-zabbix/zabbix/zabbix.ts +++ b/src/datasource-zabbix/zabbix/zabbix.ts @@ -10,6 +10,11 @@ import { InfluxDBConnector } from './connectors/influxdb/influxdbConnector'; import { ZabbixConnector } from './types'; import { joinTriggersWithProblems } from '../problemsHandler'; +interface AppsResponse extends Array { + appFilterEmpty?: boolean; + hostids?: any[]; +} + const REQUESTS_TO_PROXYFY = [ 'getHistory', 'getTrend', 'getGroups', 'getHosts', 'getApps', 'getItems', 'getMacros', 'getItemsByIDs', 'getEvents', 'getAlerts', 'getHostAlerts', 'getAcknowledges', 'getITService', 'getSLA', 'getVersion', 'getProxies', @@ -178,9 +183,9 @@ export class Zabbix implements ZabbixConnector { return Promise.all([ this.getHosts(...filters), this.getApps(...filters), - ]).then((results) => { - // tslint:disable-next-line: prefer-const - let [hosts, apps] = results; + ]).then(results => { + const hosts = results[0]; + let apps: AppsResponse = results[1]; if (apps.appFilterEmpty) { apps = []; } @@ -224,7 +229,7 @@ export class Zabbix implements ZabbixConnector { }); } - getApps(groupFilter?, hostFilter?, appFilter?) { + getApps(groupFilter?, hostFilter?, appFilter?): Promise { return this.getHosts(groupFilter, hostFilter) .then(hosts => { const hostids = _.map(hosts, 'hostid'); @@ -232,10 +237,10 @@ export class Zabbix implements ZabbixConnector { return this.zabbixAPI.getApps(hostids) .then(apps => filterByQuery(apps, appFilter)); } else { - return { - appFilterEmpty: true, - hostids: hostids - }; + const appsResponse: AppsResponse = hostids; + appsResponse.hostids = hostids; + appsResponse.appFilterEmpty = true; + return Promise.resolve(appsResponse); } }); } diff --git a/tsconfig.json b/tsconfig.json index 999b8b9..541b295 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,10 +2,7 @@ "compilerOptions": { "moduleResolution": "node", "target": "es5", - "lib": [ - "es6", - "dom" - ], + "lib": [ "es6", "dom", "es2017" ], "rootDir": "./src", "jsx": "react", "module": "esnext",