Auto-detect zabbix version, closes #727

This commit is contained in:
Alexander Zobnin
2020-05-14 18:26:29 +03:00
parent d4e5ee9a69
commit 93b1468000
10 changed files with 42 additions and 64 deletions

View File

@@ -77,6 +77,7 @@
"react-transition-group": "^2.5.2", "react-transition-group": "^2.5.2",
"rst2html": "github:thoward/rst2html#990cb89", "rst2html": "github:thoward/rst2html#990cb89",
"sass-loader": "7.1.0", "sass-loader": "7.1.0",
"semver": "^7.3.2",
"style-loader": "^0.23.1", "style-loader": "^0.23.1",
"tether-drop": "^1.4.2", "tether-drop": "^1.4.2",
"ts-jest": "^24.2.0", "ts-jest": "^24.2.0",

View File

@@ -4,12 +4,6 @@ import { migrateDSConfig } from './migrations';
const SUPPORTED_SQL_DS = ['mysql', 'postgres', 'influxdb']; 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 = { const defaultConfig = {
trends: false, trends: false,
dbConnectionEnable: false, dbConnectionEnable: false,
@@ -18,7 +12,6 @@ const defaultConfig = {
addThresholds: false, addThresholds: false,
alertingMinSeverity: 3, alertingMinSeverity: 3,
disableReadOnlyUsersAck: false, disableReadOnlyUsersAck: false,
zabbixVersion: 3,
}; };
export class ZabbixDSConfigController { export class ZabbixDSConfigController {
@@ -30,8 +23,6 @@ export class ZabbixDSConfigController {
this.dbConnectionDatasourceId = this.current.jsonData.dbConnectionDatasourceId; this.dbConnectionDatasourceId = this.current.jsonData.dbConnectionDatasourceId;
this.dbDataSources = this.getSupportedDBDataSources(); this.dbDataSources = this.getSupportedDBDataSources();
this.zabbixVersions = _.cloneDeep(zabbixVersions);
this.autoDetectZabbixVersion();
if (!this.dbConnectionDatasourceId) { if (!this.dbConnectionDatasourceId) {
this.loadCurrentDBDatasource(); 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() { onDBConnectionDatasourceChange() {
this.current.jsonData.dbConnectionDatasourceId = this.dbConnectionDatasourceId; this.current.jsonData.dbConnectionDatasourceId = this.dbConnectionDatasourceId;
} }

View File

@@ -13,8 +13,6 @@ import { Zabbix } from './zabbix/zabbix';
import { ZabbixAPIError } from './zabbix/connectors/zabbix_api/zabbixAPICore'; import { ZabbixAPIError } from './zabbix/connectors/zabbix_api/zabbixAPICore';
import { VariableQueryTypes, ShowProblemTypes } from './types'; import { VariableQueryTypes, ShowProblemTypes } from './types';
const DEFAULT_ZABBIX_VERSION = 3;
export class ZabbixDatasource { export class ZabbixDatasource {
name: string; name: string;
url: string; url: string;
@@ -31,7 +29,6 @@ export class ZabbixDatasource {
addThresholds: boolean; addThresholds: boolean;
alertingMinSeverity: string; alertingMinSeverity: string;
disableReadOnlyUsersAck: boolean; disableReadOnlyUsersAck: boolean;
zabbixVersion: string;
enableDirectDBConnection: boolean; enableDirectDBConnection: boolean;
dbConnectionDatasourceId: number; dbConnectionDatasourceId: number;
dbConnectionDatasourceName: string; dbConnectionDatasourceName: string;
@@ -79,7 +76,6 @@ export class ZabbixDatasource {
// Other options // Other options
this.disableReadOnlyUsersAck = jsonData.disableReadOnlyUsersAck; this.disableReadOnlyUsersAck = jsonData.disableReadOnlyUsersAck;
this.zabbixVersion = jsonData.zabbixVersion || DEFAULT_ZABBIX_VERSION;
// Direct DB Connection options // Direct DB Connection options
this.enableDirectDBConnection = jsonData.dbConnectionEnable || false; this.enableDirectDBConnection = jsonData.dbConnectionEnable || false;
@@ -93,7 +89,6 @@ export class ZabbixDatasource {
password: this.password, password: this.password,
basicAuth: this.basicAuth, basicAuth: this.basicAuth,
withCredentials: this.withCredentials, withCredentials: this.withCredentials,
zabbixVersion: this.zabbixVersion,
cacheTTL: this.cacheTTL, cacheTTL: this.cacheTTL,
enableDirectDBConnection: this.enableDirectDBConnection, enableDirectDBConnection: this.enableDirectDBConnection,
dbConnectionDatasourceId: this.dbConnectionDatasourceId, 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 // // Templating //
//////////////// ////////////////

View File

@@ -73,15 +73,6 @@
placeholder="1h"> placeholder="1h">
</input> </input>
</div> </div>
<div class="gf-form max-width-20">
<span class="gf-form-label width-12">Zabbix version</span>
<div class="gf-form-select-wrapper max-width-7">
<select class="gf-form-input" ng-model="ctrl.current.jsonData.zabbixVersion"
ng-options="s.value as s.name for s in ctrl.zabbixVersions">
</select>
</div>
</div>
</div> </div>
<div class="gf-form-group"> <div class="gf-form-group">

View File

@@ -315,7 +315,7 @@ export function isValidVersion(version) {
return versionPattern.exec(version); return versionPattern.exec(version);
} }
export function parseVersion(version) { export function parseVersion(version: string) {
const match = versionPattern.exec(version); const match = versionPattern.exec(version);
if (!match) { if (!match) {
return null; return null;

View File

@@ -1,22 +1,24 @@
import _ from 'lodash'; import _ from 'lodash';
import semver from 'semver';
import kbn from 'grafana/app/core/utils/kbn'; import kbn from 'grafana/app/core/utils/kbn';
import * as utils from '../../../utils'; 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 } from '../../../types'; import { ShowProblemTypes } from '../../../types';
const DEFAULT_ZABBIX_VERSION = '3.0.0';
/** /**
* Zabbix API Wrapper. * Zabbix API Wrapper.
* Creates Zabbix API instance with given parameters (url, credentials and other). * Creates Zabbix API instance with given parameters (url, credentials and other).
* Wraps API calls and provides high-level methods. * Wraps API calls and provides high-level methods.
*/ */
export class ZabbixAPIConnector { export class ZabbixAPIConnector {
constructor(api_url, username, password, version, basicAuth, withCredentials) { constructor(api_url, username, password, basicAuth, withCredentials) {
this.url = api_url; this.url = api_url;
this.username = username; this.username = username;
this.password = password; this.password = password;
this.auth = ''; this.auth = '';
this.version = version;
this.requestOptions = { this.requestOptions = {
basicAuth: basicAuth, basicAuth: basicAuth,
@@ -31,6 +33,8 @@ export class ZabbixAPIConnector {
this.getTrend = this.getTrend_ZBXNEXT1193; this.getTrend = this.getTrend_ZBXNEXT1193;
//getTrend = getTrend_30; //getTrend = getTrend_30;
this.initVersion();
} }
////////////////////////// //////////////////////////
@@ -38,6 +42,10 @@ export class ZabbixAPIConnector {
////////////////////////// //////////////////////////
request(method, params) { 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) return this.zabbixAPICore.request(this.url, method, params, this.requestOptions, this.auth)
.catch(error => { .catch(error => {
if (isNotAuthorized(error.data)) { if (isNotAuthorized(error.data)) {
@@ -89,12 +97,31 @@ export class ZabbixAPIConnector {
return this.zabbixAPICore.getVersion(this.url, this.requestOptions); 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 // // Zabbix API method wrappers //
//////////////////////////////// ////////////////////////////////
acknowledgeEvent(eventid, message) { 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 = { const params = {
eventids: eventid, eventids: eventid,
message: message, message: message,

View File

@@ -82,7 +82,10 @@ export class ZabbixAPICore {
* 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, options) {
return this.request(api_url, 'apiinfo.version', [], options); return this.request(api_url, 'apiinfo.version', [], options).catch(err => {
console.error(err);
return undefined;
});
} }
} }

View File

@@ -32,7 +32,6 @@ export class Zabbix {
password, password,
basicAuth, basicAuth,
withCredentials, withCredentials,
zabbixVersion,
cacheTTL, cacheTTL,
enableDirectDBConnection, enableDirectDBConnection,
dbConnectionDatasourceId, dbConnectionDatasourceId,
@@ -49,7 +48,7 @@ export class Zabbix {
}; };
this.cachingProxy = new CachingProxy(cacheOptions); 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.proxyfyRequests();
this.cacheRequests(); this.cacheRequests();

View File

@@ -8,7 +8,6 @@ describe('Zabbix', () => {
url: 'http://localhost', url: 'http://localhost',
username: 'zabbix', username: 'zabbix',
password: 'zabbix', password: 'zabbix',
zabbixVersion: 4,
}; };
beforeEach(() => { beforeEach(() => {

View File

@@ -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" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== 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: semver@~5.3.0:
version "5.3.0" version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"