From 93b146800032bdca1289f6d361c0a5aeee4bc36b Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Thu, 14 May 2020 18:26:29 +0300 Subject: [PATCH] Auto-detect zabbix version, closes #727 --- package.json | 1 + src/datasource-zabbix/config.controller.js | 28 ---------------- src/datasource-zabbix/datasource.ts | 19 ----------- src/datasource-zabbix/partials/config.html | 9 ----- src/datasource-zabbix/utils.ts | 2 +- .../zabbix_api/zabbixAPIConnector.js | 33 +++++++++++++++++-- .../connectors/zabbix_api/zabbixAPICore.js | 5 ++- src/datasource-zabbix/zabbix/zabbix.js | 3 +- src/datasource-zabbix/zabbix/zabbix.test.js | 1 - yarn.lock | 5 +++ 10 files changed, 42 insertions(+), 64 deletions(-) diff --git a/package.json b/package.json index 87cf2dc..b7ae5af 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "react-transition-group": "^2.5.2", "rst2html": "github:thoward/rst2html#990cb89", "sass-loader": "7.1.0", + "semver": "^7.3.2", "style-loader": "^0.23.1", "tether-drop": "^1.4.2", "ts-jest": "^24.2.0", diff --git a/src/datasource-zabbix/config.controller.js b/src/datasource-zabbix/config.controller.js index 68b692e..c160d29 100644 --- a/src/datasource-zabbix/config.controller.js +++ b/src/datasource-zabbix/config.controller.js @@ -4,12 +4,6 @@ import { migrateDSConfig } from './migrations'; const SUPPORTED_SQL_DS = ['mysql', 'postgres', 'influxdb']; -const zabbixVersions = [ - { name: '2.x', value: 2 }, - { name: '3.x', value: 3 }, - { name: '4.x', value: 4 }, -]; - const defaultConfig = { trends: false, dbConnectionEnable: false, @@ -18,7 +12,6 @@ const defaultConfig = { addThresholds: false, alertingMinSeverity: 3, disableReadOnlyUsersAck: false, - zabbixVersion: 3, }; export class ZabbixDSConfigController { @@ -30,8 +23,6 @@ export class ZabbixDSConfigController { this.dbConnectionDatasourceId = this.current.jsonData.dbConnectionDatasourceId; this.dbDataSources = this.getSupportedDBDataSources(); - this.zabbixVersions = _.cloneDeep(zabbixVersions); - this.autoDetectZabbixVersion(); if (!this.dbConnectionDatasourceId) { this.loadCurrentDBDatasource(); } @@ -60,25 +51,6 @@ export class ZabbixDSConfigController { }); } - autoDetectZabbixVersion() { - if (!this.current.id) { - return; - } - - getDataSourceSrv().loadDatasource(this.current.name) - .then(ds => { - return ds.getVersion(); - }) - .then(version => { - if (version) { - if (!_.find(zabbixVersions, ['value', version])) { - this.zabbixVersions.push({ name: version + '.x', value: version }); - } - this.current.jsonData.zabbixVersion = version; - } - }); - } - onDBConnectionDatasourceChange() { this.current.jsonData.dbConnectionDatasourceId = this.dbConnectionDatasourceId; } diff --git a/src/datasource-zabbix/datasource.ts b/src/datasource-zabbix/datasource.ts index c163fb0..19335b0 100644 --- a/src/datasource-zabbix/datasource.ts +++ b/src/datasource-zabbix/datasource.ts @@ -13,8 +13,6 @@ import { Zabbix } from './zabbix/zabbix'; import { ZabbixAPIError } from './zabbix/connectors/zabbix_api/zabbixAPICore'; import { VariableQueryTypes, ShowProblemTypes } from './types'; -const DEFAULT_ZABBIX_VERSION = 3; - export class ZabbixDatasource { name: string; url: string; @@ -31,7 +29,6 @@ export class ZabbixDatasource { addThresholds: boolean; alertingMinSeverity: string; disableReadOnlyUsersAck: boolean; - zabbixVersion: string; enableDirectDBConnection: boolean; dbConnectionDatasourceId: number; dbConnectionDatasourceName: string; @@ -79,7 +76,6 @@ export class ZabbixDatasource { // Other options this.disableReadOnlyUsersAck = jsonData.disableReadOnlyUsersAck; - this.zabbixVersion = jsonData.zabbixVersion || DEFAULT_ZABBIX_VERSION; // Direct DB Connection options this.enableDirectDBConnection = jsonData.dbConnectionEnable || false; @@ -93,7 +89,6 @@ export class ZabbixDatasource { password: this.password, basicAuth: this.basicAuth, withCredentials: this.withCredentials, - zabbixVersion: this.zabbixVersion, cacheTTL: this.cacheTTL, enableDirectDBConnection: this.enableDirectDBConnection, dbConnectionDatasourceId: this.dbConnectionDatasourceId, @@ -504,20 +499,6 @@ export class ZabbixDatasource { }); } - /** - * Get Zabbix version - */ - getVersion() { - return this.zabbix.getVersion() - .then(version => { - const zabbixVersion = utils.parseVersion(version); - if (!zabbixVersion) { - return null; - } - return zabbixVersion.major; - }); - } - //////////////// // Templating // //////////////// diff --git a/src/datasource-zabbix/partials/config.html b/src/datasource-zabbix/partials/config.html index 6b389f3..83c5ed9 100644 --- a/src/datasource-zabbix/partials/config.html +++ b/src/datasource-zabbix/partials/config.html @@ -73,15 +73,6 @@ placeholder="1h"> - -
- Zabbix version -
- -
-
diff --git a/src/datasource-zabbix/utils.ts b/src/datasource-zabbix/utils.ts index 5eb89af..a474395 100644 --- a/src/datasource-zabbix/utils.ts +++ b/src/datasource-zabbix/utils.ts @@ -315,7 +315,7 @@ export function isValidVersion(version) { return versionPattern.exec(version); } -export function parseVersion(version) { +export function parseVersion(version: string) { const match = versionPattern.exec(version); if (!match) { return null; diff --git a/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.js b/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.js index 3264a95..27ab808 100644 --- a/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.js +++ b/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPIConnector.js @@ -1,22 +1,24 @@ import _ from 'lodash'; +import semver from 'semver'; import kbn from 'grafana/app/core/utils/kbn'; 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 } from '../../../types'; +const DEFAULT_ZABBIX_VERSION = '3.0.0'; + /** * Zabbix API Wrapper. * Creates Zabbix API instance with given parameters (url, credentials and other). * Wraps API calls and provides high-level methods. */ export class ZabbixAPIConnector { - constructor(api_url, username, password, version, basicAuth, withCredentials) { + constructor(api_url, username, password, basicAuth, withCredentials) { this.url = api_url; this.username = username; this.password = password; this.auth = ''; - this.version = version; this.requestOptions = { basicAuth: basicAuth, @@ -31,6 +33,8 @@ export class ZabbixAPIConnector { this.getTrend = this.getTrend_ZBXNEXT1193; //getTrend = getTrend_30; + + this.initVersion(); } ////////////////////////// @@ -38,6 +42,10 @@ export class ZabbixAPIConnector { ////////////////////////// request(method, params) { + if (!this.version) { + return this.initVersion().then(() => this.request(method, params)); + } + return this.zabbixAPICore.request(this.url, method, params, this.requestOptions, this.auth) .catch(error => { if (isNotAuthorized(error.data)) { @@ -89,12 +97,31 @@ export class ZabbixAPIConnector { return this.zabbixAPICore.getVersion(this.url, this.requestOptions); } + initVersion() { + if (!this.getVersionPromise) { + this.getVersionPromise = Promise.resolve( + this.getVersion().then(version => { + if (version) { + console.log(`Zabbix version detected: ${version}`); + } else { + console.log(`Failed to detect Zabbix version, use default ${DEFAULT_ZABBIX_VERSION}`); + } + + this.version = version || DEFAULT_ZABBIX_VERSION; + this.getVersionPromise = null; + return version; + }) + ); + } + return this.getVersionPromise; + } + //////////////////////////////// // Zabbix API method wrappers // //////////////////////////////// acknowledgeEvent(eventid, message) { - const action = this.version >= 4 ? ZBX_ACK_ACTION_ACK + ZBX_ACK_ACTION_ADD_MESSAGE : ZBX_ACK_ACTION_NONE; + const action = semver.gte(this.version, '4.0.0') ? ZBX_ACK_ACTION_ACK + ZBX_ACK_ACTION_ADD_MESSAGE : ZBX_ACK_ACTION_NONE; const params = { eventids: eventid, message: message, diff --git a/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPICore.js b/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPICore.js index f8b3aa9..8c7e1d8 100644 --- a/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPICore.js +++ b/src/datasource-zabbix/zabbix/connectors/zabbix_api/zabbixAPICore.js @@ -82,7 +82,10 @@ export class ZabbixAPICore { * Matches the version of Zabbix starting from Zabbix 2.0.4 */ getVersion(api_url, options) { - return this.request(api_url, 'apiinfo.version', [], options); + return this.request(api_url, 'apiinfo.version', [], options).catch(err => { + console.error(err); + return undefined; + }); } } diff --git a/src/datasource-zabbix/zabbix/zabbix.js b/src/datasource-zabbix/zabbix/zabbix.js index 2176649..64950ba 100644 --- a/src/datasource-zabbix/zabbix/zabbix.js +++ b/src/datasource-zabbix/zabbix/zabbix.js @@ -32,7 +32,6 @@ export class Zabbix { password, basicAuth, withCredentials, - zabbixVersion, cacheTTL, enableDirectDBConnection, dbConnectionDatasourceId, @@ -49,7 +48,7 @@ export class Zabbix { }; this.cachingProxy = new CachingProxy(cacheOptions); - this.zabbixAPI = new ZabbixAPIConnector(url, username, password, zabbixVersion, basicAuth, withCredentials); + this.zabbixAPI = new ZabbixAPIConnector(url, username, password, basicAuth, withCredentials); this.proxyfyRequests(); this.cacheRequests(); diff --git a/src/datasource-zabbix/zabbix/zabbix.test.js b/src/datasource-zabbix/zabbix/zabbix.test.js index 71c74e3..de63bf2 100644 --- a/src/datasource-zabbix/zabbix/zabbix.test.js +++ b/src/datasource-zabbix/zabbix/zabbix.test.js @@ -8,7 +8,6 @@ describe('Zabbix', () => { url: 'http://localhost', username: 'zabbix', password: 'zabbix', - zabbixVersion: 4, }; beforeEach(() => { diff --git a/yarn.lock b/yarn.lock index 5800def..b34860c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8671,6 +8671,11 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"