diff --git a/.gitignore b/.gitignore index 20d58b0..1028d12 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ *.sublime-workspace *.sublime-project -.idea/ \ No newline at end of file +.idea/ + +*.bat diff --git a/zabbix/datasource.js b/zabbix/datasource.js index 5e79d6a..d62b75b 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -2,6 +2,7 @@ define([ 'angular', 'lodash', 'kbn', + './zabbixAPIWrapper', './queryCtrl' ], function (angular, _, kbn) { @@ -9,7 +10,7 @@ function (angular, _, kbn) { var module = angular.module('grafana.services'); - module.factory('ZabbixAPIDatasource', function($q, backendSrv, templateSrv) { + module.factory('ZabbixAPIDatasource', function($q, backendSrv, templateSrv, zabbix) { /** * Datasource initialization. Calls when you refresh page, add @@ -31,6 +32,9 @@ function (angular, _, kbn) { // Limit metrics per panel for templated request this.limitmetrics = datasource.meta.limitmetrics || 50; + + // Initialize Zabbix API + zabbix.init(this.url, this.username, this.password); } @@ -79,7 +83,7 @@ function (angular, _, kbn) { // Find items by item names and perform queries var self = this; - return this.itemFindQuery(groups, hosts, apps) + return zabbix.itemFindQuery(groups, hosts, apps) .then(function (items) { // Filter hosts by regex @@ -100,7 +104,7 @@ function (angular, _, kbn) { if (target.itemFilter) { var item_pattern = new RegExp(target.itemFilter); return _.filter(items, function (item) { - return item_pattern.test(expandItemName(item)); + return item_pattern.test(zabbix.expandItemName(item)); }); } else { return items; @@ -109,7 +113,7 @@ function (angular, _, kbn) { // Filtering items return _.filter(items, function (item) { - return _.contains(itemnames, expandItemName(item)); + return _.contains(itemnames, zabbix.expandItemName(item)); }); } }).then(function (items) { @@ -123,10 +127,10 @@ function (angular, _, kbn) { var alias = target.item.name === 'All' ? undefined : templateSrv.replace(target.alias); if ((from < useTrendsFrom) && self.trends) { - return self.getTrends(items, from, to) + return zabbix.getTrends(items, from, to) .then(_.partial(self.handleTrendResponse, items, alias, target.scale)); } else { - return self.performTimeSeriesQuery(items, from, to) + return zabbix.getHistory(items, from, to) .then(_.partial(self.handleHistoryResponse, items, alias, target.scale)); } } @@ -139,71 +143,6 @@ function (angular, _, kbn) { }; - /** - * Perform history query from Zabbix API - * - * @param {Array} items Array of Zabbix item objects - * @param {Number} start Time in seconds - * @param {Number} end Time in seconds - * - * @return {Array} Array of Zabbix history objects - */ - ZabbixAPIDatasource.prototype.performTimeSeriesQuery = function(items, start, end) { - // Group items by value type - var grouped_items = _.groupBy(items, 'value_type'); - - // Perform request for each value type - return $q.all(_.map(grouped_items, function (items, value_type) { - var itemids = _.map(items, 'itemid'); - var params = { - output: 'extend', - history: value_type, - itemids: itemids, - sortfield: 'clock', - sortorder: 'ASC', - time_from: start - }; - - // Relative queries (e.g. last hour) don't include an end time - if (end) { - params.time_till = end; - } - - return this.performZabbixAPIRequest('history.get', params); - }, this)).then(function (results) { - return _.flatten(results); - }); - }; - - - ZabbixAPIDatasource.prototype.getTrends = function(items, start, end) { - // Group items by value type - var grouped_items = _.groupBy(items, 'value_type'); - - // Perform request for each value type - return $q.all(_.map(grouped_items, function (items, value_type) { - var itemids = _.map(items, 'itemid'); - var params = { - output: 'extend', - trend: value_type, - itemids: itemids, - sortfield: 'clock', - sortorder: 'ASC', - time_from: start - }; - - // Relative queries (e.g. last hour) don't include an end time - if (end) { - params.time_till = end; - } - - return this.performZabbixAPIRequest('trend.get', params); - }, this)).then(function (results) { - return _.flatten(results); - }); - }; - - ZabbixAPIDatasource.prototype.handleTrendResponse = function(items, alias, scale, trends) { // Group items and trends by itemid @@ -213,7 +152,7 @@ function (angular, _, kbn) { return $q.when(_.map(grouped_history, function (trends, itemid) { var item = indexed_items[itemid]; var series = { - target: (item.hosts ? item.hosts[0].name+': ' : '') + (alias ? alias : expandItemName(item)), + target: (item.hosts ? item.hosts[0].name+': ' : '') + (alias ? alias : zabbix.expandItemName(item)), datapoints: _.map(trends, function (p) { // Value must be a number for properly work @@ -267,7 +206,7 @@ function (angular, _, kbn) { return $q.when(_.map(grouped_history, function (history, itemid) { var item = indexed_items[itemid]; var series = { - target: (item.hosts ? item.hosts[0].name+': ' : '') + (alias ? alias : expandItemName(item)), + target: (item.hosts ? item.hosts[0].name+': ' : '') + (alias ? alias : zabbix.expandItemName(item)), datapoints: _.map(history, function (p) { // Value must be a number for properly work @@ -287,241 +226,6 @@ function (angular, _, kbn) { }; - /** - * Request data from Zabbix API - * - * @param {string} method Zabbix API method name - * @param {object} params method params - * - * @return {object} data.result field or [] - */ - ZabbixAPIDatasource.prototype.performZabbixAPIRequest = function(method, params) { - var options = { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - url: this.url, - data: { - jsonrpc: '2.0', - method: method, - params: params, - auth: this.auth, - id: 1 - } - }; - - var self = this; - return backendSrv.datasourceRequest(options).then(function (response) { - if (!response.data) { - return []; - } - // Handle Zabbix API errors - else if (response.data.error) { - - // Handle auth errors - if (response.data.error.data == "Session terminated, re-login, please." || - response.data.error.data == "Not authorised." || - response.data.error.data == "Not authorized") { - return self.performZabbixAPILogin().then(function (response) { - self.auth = response; - return self.performZabbixAPIRequest(method, params); - }); - } - } - return response.data.result; - }); - }; - - - // Get authentication token - ZabbixAPIDatasource.prototype.performZabbixAPILogin = function() { - var options = { - url : this.url, - method : 'POST', - data: { - jsonrpc: '2.0', - method: 'user.login', - params: { - user: this.username, - password: this.password - }, - auth: null, - id: 1 - }, - }; - - return backendSrv.datasourceRequest(options).then(function (result) { - if (!result.data) { - return null; - } - return result.data.result; - }); - }; - - - // Get the list of host groups - ZabbixAPIDatasource.prototype.performHostGroupSuggestQuery = function() { - var params = { - output: ['name'], - sortfield: 'name', - // Return only host groups that contain hosts - real_hosts: true, - // Return only host groups that contain monitored hosts. - monitored_hosts: true - }; - - return this.performZabbixAPIRequest('hostgroup.get', params); - }; - - - // Get the list of hosts - ZabbixAPIDatasource.prototype.performHostSuggestQuery = function(groupids) { - var params = { - output: ['name', 'host'], - sortfield: 'name', - // Return only hosts that have items with numeric type of information. - with_simple_graph_items: true, - // Return only monitored hosts. - monitored_hosts: true - }; - // Return only hosts in given group - if (groupids) { - params.groupids = groupids; - } - return this.performZabbixAPIRequest('host.get', params); - }; - - - // Get the list of applications - ZabbixAPIDatasource.prototype.performAppSuggestQuery = function(hostids, /* optional */ groupids) { - var params = { - output: ['name'], - sortfield: 'name' - }; - if (hostids) { - params.hostids = hostids; - } - else if (groupids) { - params.groupids = groupids; - } - - return this.performZabbixAPIRequest('application.get', params); - }; - - - /** - * Items request - * - * @param {string or Array} hostids /////////////////////////// - * @param {string or Array} applicationids // Zabbix API parameters // - * @param {string or Array} groupids /////////////////////////// - * - * @return {string or Array} Array of Zabbix API item objects - */ - ZabbixAPIDatasource.prototype.performItemSuggestQuery = function(hostids, applicationids, /* optional */ groupids) { - var params = { - output: ['name', 'key_', 'value_type', 'delay'], - sortfield: 'name', - //Include web items in the result - webitems: true, - // Return only numeric items - filter: { - value_type: [0,3] - }, - // Return only enabled items - monitored: true, - searchByAny: true - }; - - // Filter by hosts or by groups - if (hostids) { - params.hostids = hostids; - } else if (groupids) { - params.groupids = groupids; - } - - // If application selected return only relative items - if (applicationids) { - params.applicationids = applicationids; - } - - // Return host property for multiple hosts - if (!hostids || (_.isArray(hostids) && hostids.length > 1)) { - params.selectHosts = ['name']; - } - - return this.performZabbixAPIRequest('item.get', params); - }; - - - /** - * Find groups by names - * - * @param {string or array} group group names - * @return {array} array of Zabbix API hostgroup objects - */ - ZabbixAPIDatasource.prototype.findZabbixGroup = function (group) { - var params = { - output: ['name'], - searchByAny: true - }; - if (group != '*') { - if (_.isArray(group)) { - params.filter = { - name: group - }; - } else { - params.search = { - name: group - }; - params.searchWildcardsEnabled = true; - } - } - return this.performZabbixAPIRequest('hostgroup.get', params); - }; - - - /** - * Find hosts by names - * - * @param {string or array} hostnames hosts names - * @return {array} array of Zabbix API host objects - */ - ZabbixAPIDatasource.prototype.findZabbixHost = function (hostnames) { - var params = { - output: ['host', 'name'], - searchByAny: true - }; - if (hostnames != '*') { - params.filter = { - name: hostnames - }; - } - return this.performZabbixAPIRequest('host.get', params); - }; - - - /** - * Find applications by names - * - * @param {string or array} application applications names - * @return {array} array of Zabbix API application objects - */ - ZabbixAPIDatasource.prototype.findZabbixApp = function (application) { - var params = { - output: ['name'], - searchByAny: true - } - if (application != '*') { - params.filter = { - name: application - }; - }; - return this.performZabbixAPIRequest('application.get', params); - }; - - /** * For templated query. * Find metrics from templated request. @@ -548,9 +252,9 @@ function (angular, _, kbn) { // Get items if (parts.length === 4) { - return this.itemFindQuery(template.group, template.host, template.app).then(function (result) { + return zabbix.itemFindQuery(template.group, template.host, template.app).then(function (result) { return _.map(result, function (item) { - var itemname = expandItemName(item) + var itemname = zabbix.expandItemName(item) return { text: itemname, expandable: false @@ -560,7 +264,7 @@ function (angular, _, kbn) { } // Get applications else if (parts.length === 3) { - return this.appFindQuery(template.host, template.group).then(function (result) { + return zabbix.appFindQuery(template.host, template.group).then(function (result) { return _.map(result, function (app) { return { text: app.name, @@ -571,7 +275,7 @@ function (angular, _, kbn) { } // Get hosts else if (parts.length === 2) { - return this.hostFindQuery(template.group).then(function (result) { + return zabbix.hostFindQuery(template.group).then(function (result) { return _.map(result, function (host) { return { text: host.name, @@ -582,7 +286,7 @@ function (angular, _, kbn) { } // Get groups else if (parts.length === 1) { - return this.findZabbixGroup(template.group).then(function (result) { + return zabbix.getGroupByName(template.group).then(function (result) { return _.map(result, function (hostgroup) { return { text: hostgroup.name, @@ -600,114 +304,6 @@ function (angular, _, kbn) { }; - /** - * Find items belongs to passed groups, hosts and - * applications - * - * @param {string or array} groups - * @param {string or array} hosts - * @param {string or array} apps - * - * @return {array} array of Zabbix API item objects - */ - ZabbixAPIDatasource.prototype.itemFindQuery = function(groups, hosts, apps) { - var promises = []; - - // Get hostids from names - if (hosts && hosts != '*') { - promises.push(this.findZabbixHost(hosts)); - } - // Get groupids from names - else if (groups) { - promises.push(this.findZabbixGroup(groups)); - } - // Get applicationids from names - if (apps) { - promises.push(this.findZabbixApp(apps)); - } - - var self = this; - return $q.all(promises).then(function (results) { - results = _.flatten(results); - if (groups) { - var groupids = _.map(_.filter(results, function (object) { - return object.groupid; - }), 'groupid'); - } - if (hosts && hosts != '*') { - var hostids = _.map(_.filter(results, function (object) { - return object.hostid; - }), 'hostid'); - } - if (apps) { - var applicationids = _.map(_.filter(results, function (object) { - return object.applicationid; - }), 'applicationid'); - } - - return self.performItemSuggestQuery(hostids, applicationids, groupids); - }); - }; - - - /** - * Find applications belongs to passed groups and hosts - * - * @param {string or array} hosts - * @param {string or array} groups - * - * @return {array} array of Zabbix API application objects - */ - ZabbixAPIDatasource.prototype.appFindQuery = function(hosts, groups) { - var promises = []; - - // Get hostids from names - if (hosts && hosts != '*') { - promises.push(this.findZabbixHost(hosts)); - } - // Get groupids from names - else if (groups) { - promises.push(this.findZabbixGroup(groups)); - } - - var self = this; - return $q.all(promises).then(function (results) { - results = _.flatten(results); - if (groups) { - var groupids = _.map(_.filter(results, function (object) { - return object.groupid; - }), 'groupid'); - } - if (hosts && hosts != '*') { - var hostids = _.map(_.filter(results, function (object) { - return object.hostid; - }), 'hostid'); - } - - return self.performAppSuggestQuery(hostids, groupids); - }); - }; - - - /** - * Find hosts belongs to passed groups - * - * @param {string or array} groups - * @return {array} array of Zabbix API host objects - */ - ZabbixAPIDatasource.prototype.hostFindQuery = function(groups) { - var self = this; - return this.findZabbixGroup(groups).then(function (results) { - results = _.flatten(results); - var groupids = _.map(_.filter(results, function (object) { - return object.groupid; - }), 'groupid'); - - return self.performHostSuggestQuery(groupids); - }); - }; - - ///////////////// // Annotations // ///////////////// @@ -783,29 +379,6 @@ function splitMetrics(metrics) { } -/** - * Expand item parameters, for example: - * CPU $2 time ($3) --> CPU system time (avg1) - * - * @param item: zabbix api item object - * @return: expanded item name (string) - */ -function expandItemName(item) { - var name = item.name; - var key = item.key_; - - // extract params from key: - // "system.cpu.util[,system,avg1]" --> ["", "system", "avg1"] - var key_params = key.substring(key.indexOf('[') + 1, key.lastIndexOf(']')).split(','); - - // replace item parameters - for (var i = key_params.length; i >= 1; i--) { - name = name.replace('$' + i, key_params[i - 1]); - }; - return name; -} - - /** * Convert Date object to local time in format * YYYY-MM-DD HH:mm:ss diff --git a/zabbix/queryCtrl.js b/zabbix/queryCtrl.js index ce9f52d..4f847c9 100644 --- a/zabbix/queryCtrl.js +++ b/zabbix/queryCtrl.js @@ -1,6 +1,7 @@ define([ 'angular', - 'lodash' + 'lodash', + './zabbixAPIWrapper' ], function (angular, _) { 'use strict'; @@ -8,7 +9,7 @@ function (angular, _) { var module = angular.module('grafana.controllers'); var targetLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - module.controller('ZabbixAPIQueryCtrl', function($scope, $sce, templateSrv) { + module.controller('ZabbixAPIQueryCtrl', function($scope, $sce, templateSrv, zabbix) { $scope.init = function() { $scope.targetLetters = targetLetters; @@ -36,7 +37,7 @@ function (angular, _) { */ function setItemAlias() { if (!$scope.target.alias && $scope.target.item) { - $scope.target.alias = expandItemName($scope.target.item); + $scope.target.alias = $scope.target.item.name; } }; @@ -131,7 +132,7 @@ function (angular, _) { $scope.metric.groupList = [{name: '*', visible_name: 'All'}]; addTemplatedVariables($scope.metric.groupList); - $scope.datasource.performHostGroupSuggestQuery().then(function (groups) { + zabbix.performHostGroupSuggestQuery().then(function (groups) { $scope.metric.groupList = $scope.metric.groupList.concat(groups); }); }; @@ -145,7 +146,7 @@ function (angular, _) { addTemplatedVariables($scope.metric.hostList); var groups = $scope.target.group ? splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined; - $scope.datasource.hostFindQuery(groups).then(function (hosts) { + zabbix.hostFindQuery(groups).then(function (hosts) { $scope.metric.hostList = $scope.metric.hostList.concat(hosts); }); }; @@ -160,8 +161,7 @@ function (angular, _) { var groups = $scope.target.group ? splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined; var hosts = $scope.target.host ? splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined; - $scope.datasource.appFindQuery(hosts, groups).then(function (apps) { - // TODO: work with app names, not objects + zabbix.appFindQuery(hosts, groups).then(function (apps) { var apps = _.map(_.uniq(_.map(apps, 'name')), function (appname) { return {name: appname}; }); @@ -180,12 +180,12 @@ function (angular, _) { var groups = $scope.target.group ? splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined; var hosts = $scope.target.host ? splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined; var apps = $scope.target.application ? splitMetrics(templateSrv.replace($scope.target.application.name)) : undefined; - $scope.datasource.itemFindQuery(groups, hosts, apps).then(function (items) { + zabbix.itemFindQuery(groups, hosts, apps).then(function (items) { // Show only unique item names var uniq_items = _.map(_.uniq(items, function (item) { - return expandItemName(item); + return zabbix.expandItemName(item); }), function (item) { - return {name: expandItemName(item)} + return {name: zabbix.expandItemName(item)} }); $scope.metric.itemList = $scope.metric.itemList.concat(uniq_items); }); @@ -207,31 +207,6 @@ function (angular, _) { }; - /** - * Expand item parameters, for example: - * CPU $2 time ($3) --> CPU system time (avg1) - * - * @param {Object} item Zabbix item object - * @return {string} expanded item name - */ - function expandItemName(item) { - var name = item.name; - var key = item.key_; - - if (key) { - // extract params from key: - // "system.cpu.util[,system,avg1]" --> ["", "system", "avg1"] - var key_params = key.substring(key.indexOf('[') + 1, key.lastIndexOf(']')).split(','); - - // replace item parameters - for (var i = key_params.length; i >= 1; i--) { - name = name.replace('$' + i, key_params[i - 1]); - }; - } - return name; - }; - - ////////////////////////////// // VALIDATION ////////////////////////////// @@ -258,4 +233,4 @@ function splitMetrics(metrics) { var remove_brackets_pattern = /^{|}$/g; var metric_split_pattern = /,(?!\s)/g; return metrics.replace(remove_brackets_pattern, '').split(metric_split_pattern) -} \ No newline at end of file +} diff --git a/zabbix/zabbixAPIWrapper.js b/zabbix/zabbixAPIWrapper.js new file mode 100644 index 0000000..eae7ea5 --- /dev/null +++ b/zabbix/zabbixAPIWrapper.js @@ -0,0 +1,495 @@ +define([ + 'angular', + 'lodash', +], +function (angular, _) { + 'use strict'; + + var module = angular.module('grafana.services'); + + module.service('zabbix', function($q, backendSrv) { + + /** + * Initialize API parameters. + */ + this.init = function(api_url, username, password) { + this.url = api_url; + this.username = username; + this.password = password; + } + + + ////////////////// + // Core methods // + ////////////////// + + + /** + * Request data from Zabbix API + * + * @param {string} method Zabbix API method name + * @param {object} params method params + * @return {object} data.result field or [] + */ + this.performZabbixAPIRequest = function(method, params) { + var options = { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + url: this.url, + data: { + jsonrpc: '2.0', + method: method, + params: params, + auth: this.auth, + id: 1 + } + }; + + var self = this; + return backendSrv.datasourceRequest(options).then(function (response) { + if (!response.data) { + return []; + } + // Handle Zabbix API errors + else if (response.data.error) { + + // Handle auth errors + if (response.data.error.data == "Session terminated, re-login, please." || + response.data.error.data == "Not authorised." || + response.data.error.data == "Not authorized") { + return self.performZabbixAPILogin().then(function (response) { + self.auth = response; + return self.performZabbixAPIRequest(method, params); + }); + } + } + return response.data.result; + }); + }; + + + /** + * Get authentication token. + * + * @return {string} auth token + */ + this.performZabbixAPILogin = function() { + var options = { + url : this.url, + method : 'POST', + data: { + jsonrpc: '2.0', + method: 'user.login', + params: { + user: this.username, + password: this.password + }, + auth: null, + id: 1 + }, + }; + + return backendSrv.datasourceRequest(options).then(function (result) { + if (!result.data) { + return null; + } + return result.data.result; + }); + }; + + + + ///////////////////////// + // API method wrappers // + ///////////////////////// + + + /** + * Perform history query from Zabbix API + * + * @param {Array} items Array of Zabbix item objects + * @param {Number} start Time in seconds + * @param {Number} end Time in seconds + * @return {Array} Array of Zabbix history objects + */ + this.getHistory = function(items, start, end) { + // Group items by value type + var grouped_items = _.groupBy(items, 'value_type'); + + // Perform request for each value type + return $q.all(_.map(grouped_items, function (items, value_type) { + var itemids = _.map(items, 'itemid'); + var params = { + output: 'extend', + history: value_type, + itemids: itemids, + sortfield: 'clock', + sortorder: 'ASC', + time_from: start + }; + + // Relative queries (e.g. last hour) don't include an end time + if (end) { + params.time_till = end; + } + + return this.performZabbixAPIRequest('history.get', params); + }, this)).then(function (results) { + return _.flatten(results); + }); + }; + + + /** + * Perform trends query from Zabbix API + * Use trends api extension from ZBXNEXT-1193 patch. + * + * @param {Array} items Array of Zabbix item objects + * @param {Number} start Time in seconds + * @param {Number} end Time in seconds + * @return {Array} Array of Zabbix trend objects + */ + this.getTrends = function(items, start, end) { + // Group items by value type + var grouped_items = _.groupBy(items, 'value_type'); + + // Perform request for each value type + return $q.all(_.map(grouped_items, function (items, value_type) { + var itemids = _.map(items, 'itemid'); + var params = { + output: 'extend', + trend: value_type, + itemids: itemids, + sortfield: 'clock', + sortorder: 'ASC', + time_from: start + }; + + // Relative queries (e.g. last hour) don't include an end time + if (end) { + params.time_till = end; + } + + return this.performZabbixAPIRequest('trend.get', params); + }, this)).then(function (results) { + return _.flatten(results); + }); + }; + + + /** + * Get the list of host groups + * + * @return {array} array of Zabbix hostgroup objects + */ + this.performHostGroupSuggestQuery = function() { + var params = { + output: ['name'], + sortfield: 'name', + // Return only host groups that contain hosts + real_hosts: true, + // Return only host groups that contain monitored hosts. + monitored_hosts: true + }; + + return this.performZabbixAPIRequest('hostgroup.get', params); + }; + + + /** + * Get the list of hosts + * + * @param {array} groupids + * @return {array} array of Zabbix host objects + */ + this.performHostSuggestQuery = function(groupids) { + var params = { + output: ['name', 'host'], + sortfield: 'name', + // Return only hosts that have items with numeric type of information. + with_simple_graph_items: true, + // Return only monitored hosts. + monitored_hosts: true + }; + // Return only hosts in given group + if (groupids) { + params.groupids = groupids; + } + return this.performZabbixAPIRequest('host.get', params); + }; + + + /** + * Get the list of applications + * + * @param {array} hostids + * @param {array} groupids + * @return {array} array of Zabbix application objects + */ + this.performAppSuggestQuery = function(hostids, /* optional */ groupids) { + var params = { + output: ['name'], + sortfield: 'name' + }; + if (hostids) { + params.hostids = hostids; + } + else if (groupids) { + params.groupids = groupids; + } + + return this.performZabbixAPIRequest('application.get', params); + }; + + + /** + * Items request + * + * @param {string or Array} hostids /////////////////////////// + * @param {string or Array} applicationids // Zabbix API parameters // + * @param {string or Array} groupids /////////////////////////// + * @return {string or Array} Array of Zabbix API item objects + */ + this.performItemSuggestQuery = function(hostids, applicationids, /* optional */ groupids) { + var params = { + output: ['name', 'key_', 'value_type', 'delay'], + sortfield: 'name', + //Include web items in the result + webitems: true, + // Return only numeric items + filter: { + value_type: [0,3] + }, + // Return only enabled items + monitored: true, + searchByAny: true + }; + + // Filter by hosts or by groups + if (hostids) { + params.hostids = hostids; + } else if (groupids) { + params.groupids = groupids; + } + + // If application selected return only relative items + if (applicationids) { + params.applicationids = applicationids; + } + + // Return host property for multiple hosts + if (!hostids || (_.isArray(hostids) && hostids.length > 1)) { + params.selectHosts = ['name']; + } + + return this.performZabbixAPIRequest('item.get', params); + }; + + + /** + * Get groups by names + * + * @param {string or array} group group names + * @return {array} array of Zabbix API hostgroup objects + */ + this.getGroupByName = function (group) { + var params = { + output: ['name'] + }; + if (group != '*') { + params.filter = { + name: group + }; + } + return this.performZabbixAPIRequest('hostgroup.get', params); + }; + + + /** + * Search group by name. + * + * @param {string} group group name + * @return {array} groups + */ + this.searchGroup = function (group) { + var params = { + output: ['name'], + search: { + name: group + }, + searchWildcardsEnabled: true + }; + return this.performZabbixAPIRequest('hostgroup.get', params); + }; + + + /** + * Get hosts by names + * + * @param {string or array} hostnames hosts names + * @return {array} array of Zabbix API host objects + */ + this.getHostByName = function (hostnames) { + var params = { + output: ['host', 'name'] + }; + if (hostnames != '*') { + params.filter = { + name: hostnames + }; + } + return this.performZabbixAPIRequest('host.get', params); + }; + + + /** + * Get applications by names + * + * @param {string or array} application applications names + * @return {array} array of Zabbix API application objects + */ + this.getAppByName = function (application) { + var params = { + output: ['name'] + } + if (application != '*') { + params.filter = { + name: application + }; + }; + return this.performZabbixAPIRequest('application.get', params); + }; + + + /** + * Get items belongs to passed groups, hosts and + * applications + * + * @param {string or array} groups + * @param {string or array} hosts + * @param {string or array} apps + * @return {array} array of Zabbix API item objects + */ + this.itemFindQuery = function(groups, hosts, apps) { + var promises = []; + + // Get hostids from names + if (hosts && hosts != '*') { + promises.push(this.getHostByName(hosts)); + } + // Get groupids from names + else if (groups) { + promises.push(this.getGroupByName(groups)); + } + // Get applicationids from names + if (apps) { + promises.push(this.getAppByName(apps)); + } + + var self = this; + return $q.all(promises).then(function (results) { + results = _.flatten(results); + if (groups) { + var groupids = _.map(_.filter(results, function (object) { + return object.groupid; + }), 'groupid'); + } + if (hosts && hosts != '*') { + var hostids = _.map(_.filter(results, function (object) { + return object.hostid; + }), 'hostid'); + } + if (apps) { + var applicationids = _.map(_.filter(results, function (object) { + return object.applicationid; + }), 'applicationid'); + } + + return self.performItemSuggestQuery(hostids, applicationids, groupids); + }); + }; + + + /** + * Find applications belongs to passed groups and hosts + * + * @param {string or array} hosts + * @param {string or array} groups + * @return {array} array of Zabbix API application objects + */ + this.appFindQuery = function(hosts, groups) { + var promises = []; + + // Get hostids from names + if (hosts && hosts != '*') { + promises.push(this.getHostByName(hosts)); + } + // Get groupids from names + else if (groups) { + promises.push(this.getGroupByName(groups)); + } + + var self = this; + return $q.all(promises).then(function (results) { + results = _.flatten(results); + if (groups) { + var groupids = _.map(_.filter(results, function (object) { + return object.groupid; + }), 'groupid'); + } + if (hosts && hosts != '*') { + var hostids = _.map(_.filter(results, function (object) { + return object.hostid; + }), 'hostid'); + } + + return self.performAppSuggestQuery(hostids, groupids); + }); + }; + + + /** + * Find hosts belongs to passed groups + * + * @param {string or array} groups + * @return {array} array of Zabbix API host objects + */ + this.hostFindQuery = function(groups) { + var self = this; + return this.getGroupByName(groups).then(function (results) { + results = _.flatten(results); + var groupids = _.map(_.filter(results, function (object) { + return object.groupid; + }), 'groupid'); + + return self.performHostSuggestQuery(groupids); + }); + }; + + + /** + * Expand item parameters, for example: + * CPU $2 time ($3) --> CPU system time (avg1) + * + * @param item: zabbix api item object + * @return: expanded item name (string) + */ + this.expandItemName = function(item) { + var name = item.name; + var key = item.key_; + + // extract params from key: + // "system.cpu.util[,system,avg1]" --> ["", "system", "avg1"] + var key_params = key.substring(key.indexOf('[') + 1, key.lastIndexOf(']')).split(','); + + // replace item parameters + for (var i = key_params.length; i >= 1; i--) { + name = name.replace('$' + i, key_params[i - 1]); + }; + return name; + } + + }); +});