Merge remote-tracking branch 'origin/master' into develop

Conflicts:
	src/datasource-zabbix/partials/query.editor.html
	src/datasource-zabbix/query.controller.js
This commit is contained in:
Alexander Zobnin
2016-04-28 19:15:22 +03:00
8 changed files with 142 additions and 198 deletions

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6c46b44d6db23e898c29e72a3c3df3f36d62d712206b3453c18c173fcbcc5529
size 139772
oid sha256:dc8ff42dbfa78458edcf931377156775973b87037b358daf82ecd5a3e49787b7
size 138620

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:98e41015ed5e6738645065a057af30ce46482ec6797e4cbe85d9990e1fdce5be
size 140142
oid sha256:4932343924aa2416b72e46344e61335f2c0c4472575b919ee0629933d2c74b3e
size 139070

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fcaa6263d827d3344eb88fec28b1b3b084856af80174551e8c0725c3fd99e982
size 132477
oid sha256:ef6860cefddd6ead2fe97d1ff3ebaa14320e8b0366fc094c13a47a6502e62f42
size 131496

View File

@@ -17,14 +17,20 @@ select _Zabbix_ from dropdown list.
![Configure Zabbix data source](../img/installation-datasource_config.png)
### Http settings
### HTTP settings
- **Url**: set Zabbix API url (full path with `api_jsonrpc.php`).
- **Access**: can be either _proxy_ or _direct_.
- **Access**:
- **Proxy**: access via Grafana backend
- **Direct**: access from browser.
- **Http Auth**: configure if you use proxy authentication.
- **Basic Auth**:
- **With Credentials**:
Proxy access means that the Grafana backend will proxy all requests from the browser, and send them on to the Data Source. This is useful because it can eliminate CORS (Cross Origin Site Resource) issues, as well as eliminate the need to disseminate authentication details to the Data Source to the browser.
Direct access is still supported because in some cases it may be useful to access a Data Source directly depending on the use case and topology of Grafana, the user, and the Data Source.
### Zabbix API details
- **User** and **Password**: setup login for access to Zabbix API. Also check user's permissions

View File

@@ -3,11 +3,43 @@ page_description: Installation instructions for Grafana-Zabbix.
# Installation
## From release package
Download [latest release](https://github.com/alexanderzobnin/grafana-zabbix/releases/latest)
for relative Grafana version. Unpack archive and copy *grafana-zabbix* into your grafana
plugins directory (default `/var/lib/grafana/plugins` if your installing grafana with package).
Restart grafana-server and the plugin should be automatically detected and used.
## Using grafana-cli tool
Get list of available plugins
```sh
grafana-cli plugins list-remote
```
Install zabbix plugin
```sh
grafana-cli plugins install alexanderzobnin-zabbix-app
```
Restart grafana after installing plugins
```sh
service grafana-server restart
```
Read more about installing plugins in [Grafana docs](http://docs.grafana.org/plugins/installation/)
## From special repo
You can use [grafana-zabbix-app](https://github.com/alexanderzobnin/grafana-zabbix-app) repo,
which contains latest builded version of plugin.
```sh
cd /var/lib/grafana/plugins
git clone https://github.com/alexanderzobnin/grafana-zabbix-app
```
Then restart grafana server.
Using this way you can easy upgrade plugin just running
```sh
cd /var/lib/grafana/plugins/grafana-zabbix-app
git pull
service grafana-server restart
```
## Building from sources
You need NodeJS, npm and Grunt for building plugin from sources. Read more about required versions
@@ -39,22 +71,6 @@ grunt
Restart Grafana server
```sh
sudo service grafana-server restart
service grafana-server restart
systemctl restart grafana-server
```
## Using grafana-cli tool
Get list of available plugins
```sh
grafana-cli plugins list-remote
```
Install zabbix plugin
```sh
grafana-cli plugins install zabbix-app
```
Read more in [Grafana docs](http://docs.grafana.org/plugins/installation/)

View File

@@ -8,10 +8,10 @@ angular
.module('grafana.directives')
.directive('addMetricFunction', function($compile) {
var inputTemplate = '<input type="text"'+
' class="tight-form-input input-medium tight-form-input"' +
' class="gf-form-input"' +
' spellcheck="false" style="display:none"></input>';
var buttonTemplate = '<a class="tight-form-item tight-form-func dropdown-toggle"' +
var buttonTemplate = '<a class="gf-form-label tight-form-func dropdown-toggle query-part"' +
' tabindex="1" gf-dropdown="functionMenu" data-toggle="dropdown">' +
'<i class="fa fa-plus"></i></a>';

View File

@@ -1,226 +1,149 @@
<div class="tight-form">
<ul class="tight-form-list pull-right">
<li class="tight-form-item small" ng-show="ctrl.target.datasource">
<em>{{ctrl.target.datasource}}</em>
</li>
<li class="tight-form-item">
<div class="dropdown">
<a class="pointer dropdown-toggle"
data-toggle="dropdown"
tabindex="1">
<i class="fa fa-bars"></i>
</a>
<ul class="dropdown-menu pull-right" role="menu">
<query-editor-row query-ctrl="ctrl" can-collapse="false">
<!-- Switch editor mode -->
<li role="menuitem" ng-show="ctrl.target.mode">
<a class="pointer" tabindex="1"
ng-click="ctrl.switchEditorMode(0)">Numeric metrics</a>
</li>
<li role="menuitem" ng-show="ctrl.target.mode != 1">
<a class="pointer" tabindex="1"
ng-click="ctrl.switchEditorMode(1)">IT services</a>
</li>
<li role="menuitem" ng-show="ctrl.target.mode != 2">
<a class="pointer" tabindex="1"
ng-click="ctrl.switchEditorMode(2)">Text metrics</a>
</li>
<li class="divider" role="menuitem"></li>
<!-- From app/features/panel/partials/query_editor_row.html -->
<li role="menuitem">
<a tabindex="1" ng-click="ctrl.duplicateQuery()">Duplicate</a>
</li>
<li role="menuitem">
<a tabindex="1" ng-click="ctrl.moveQuery(-1)">Move up</a>
</li>
<li role="menuitem">
<a tabindex="1" ng-click="ctrl.moveQuery(1)">Move down</a>
</li>
</ul>
<div class="gf-form-inline">
<div class="gf-form max-width-20">
<label class="gf-form-label width-7">Query Mode</label>
<div class="gf-form-select-wrapper max-width-20">
<select class="gf-form-input"
ng-change="ctrl.switchEditorMode(ctrl.target.mode)"
ng-model="ctrl.target.mode"
ng-options="v.mode as v.text for (k, v) in ctrl.editorModes">
</select>
</div>
</div>
<div class="gf-form gf-form--grow">
<div class="gf-form-label gf-form-label--grow"></div>
</div>
</div>
</li>
<li class="tight-form-item last">
<a class="pointer" tabindex="1" ng-click="ctrl.removeQuery(target)">
<i class="fa fa-trash"></i>
</a>
</li>
</ul>
<ul class="tight-form-list">
<li class="tight-form-item" style="min-width: 15px; text-align: center">
{{ctrl.target.refId}}
</li>
<li>
<a class="tight-form-item" ng-click="ctrl.toggleHideQuery()" role="menuitem">
<i class="fa fa-eye"></i>
</a>
</li>
</ul>
<!-- IT Service editor -->
<ul class="tight-form-list" role="menu" ng-show="ctrl.target.mode == 1">
<li class="tight-form-item query-keyword input-small">IT Service</li>
<li>
<select class="tight-form-input input-large"
<div class="gf-form-inline" ng-show="ctrl.target.mode == 1">
<div class="gf-form max-width-20">
<label class="gf-form-label width-7">IT Service</label>
<div class="gf-form-select-wrapper max-width-20">
<select class="gf-form-input"
ng-change="ctrl.selectITService()"
ng-model="ctrl.target.itservice"
bs-tooltip="ctrl.target.itservice.name.length > 25 ? ctrl.target.itservice.name : ''"
ng-options="itservice.name for itservice in ctrl.itserviceList track by itservice.name">
<option value="">-- Select IT service --</option>
</select>
</li>
<li class="tight-form-item query-keyword input-medium">IT service property</li>
<li>
<select class="tight-form-input input-medium"
</div>
</div>
<div class="gf-form">
<label class="gf-form-label">IT service property</label>
<div class="gf-form-select-wrapper">
<select class="gf-form-input"
ng-change="ctrl.selectITService()"
ng-model="ctrl.target.slaProperty"
ng-options="slaProperty.name for slaProperty in ctrl.slaPropertyList track by slaProperty.name">
<option value="">-- Property --</option>
</select>
</li>
</ul>
</div>
</div>
<div class="gf-form gf-form--grow">
<div class="gf-form-label gf-form-label--grow"></div>
</div>
</div>
<ul class="tight-form-list" role="menu" ng-hide="ctrl.target.mode == 1">
<!-- Select Host Group -->
<li class="tight-form-item query-keyword input-small" style="width: 6em">Group</li>
<li>
<div class="gf-form-inline" ng-hide="ctrl.target.mode == 1">
<!-- Select Group -->
<div class="gf-form max-width-20">
<label class="gf-form-label width-7">Group</label>
<input type="text"
ng-model="ctrl.target.group.filter"
bs-typeahead="ctrl.getGroupNames"
ng-blur="ctrl.onTargetBlur()"
data-min-length=0
data-items=100
class="input-medium tight-form-input"
class="gf-form-input"
ng-class="{
'zbx-variable': ctrl.isVariable(ctrl.target.group.filter),
'zbx-regex': ctrl.isRegex(ctrl.target.group.filter)
}">
</li>
}"></input>
</div>
<!-- Select Host -->
<li class="tight-form-item query-keyword input-small" style="width: 3em">Host</li>
<li>
<div class="gf-form">
<label class="gf-form-label width-7">Host</label>
<input type="text"
ng-model="ctrl.target.host.filter"
bs-typeahead="ctrl.getHostNames"
ng-blur="ctrl.onTargetBlur()"
data-min-length=0
data-items=100
class="input-large tight-form-input"
class="gf-form-input"
ng-class="{
'zbx-variable': ctrl.isVariable(ctrl.target.host.filter),
'zbx-regex': ctrl.isRegex(ctrl.target.host.filter)
}">
</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form" ng-hide="ctrl.target.mode == 1">
<ul class="tight-form-list" role="menu">
<gf-form-switch class="gf-form" ng-hide="ctrl.target.mode == 2"
label="Show disabled items" checked="ctrl.target.showDisabledItems" on-change="ctrl.onTargetBlur()">
</gf-form-switch>
<div class="gf-form gf-form--grow">
<div class="gf-form-label gf-form-label--grow"></div>
</div>
</div>
<div class="gf-form-inline" ng-hide="ctrl.target.mode == 1">
<!-- Select Application -->
<li class="tight-form-item query-keyword tight-form-align" style="width: 6em">Application</li>
<li>
<div class="gf-form max-width-20">
<label class="gf-form-label width-7">Application</label>
<input type="text"
ng-model="ctrl.target.application.filter"
bs-typeahead="ctrl.getApplicationNames"
ng-blur="ctrl.onTargetBlur()"
data-min-length=0
data-items=100
class="input-medium tight-form-input"
class="gf-form-input"
ng-class="{
'zbx-variable': ctrl.isVariable(ctrl.target.application.filter),
'zbx-regex': ctrl.isRegex(ctrl.target.application.filter)
}">
</li>
</div>
<!-- Select Item -->
<li class="tight-form-item query-keyword input-small" style="width: 3em">Item</li>
<li>
<div class="gf-form">
<label class="gf-form-label width-7">Item</label>
<input type="text"
ng-model="ctrl.target.item.filter"
bs-typeahead="ctrl.getItemNames"
ng-blur="ctrl.onTargetBlur()"
data-min-length=0
data-items=100
class="input-large tight-form-input"
class="gf-form-input"
ng-class="{
'zbx-variable': ctrl.isVariable(ctrl.target.item.filter),
'zbx-regex': ctrl.isRegex(ctrl.target.item.filter)
}">
</li>
<li class="tight-form-item last">
<a ng-click="ctrl.toggleQueryOptions()">
<i class="fa fa-caret-down" ng-show="ctrl.showQueryOptions"></i>
<i class="fa fa-caret-right" ng-hide="ctrl.showQueryOptions"></i>
{{ctrl.queryOptionsText}}
</a>
</li>
</ul>
<div class="clearfix"></div>
</div>
<!-- Functions -->
<div class="tight-form" ng-show="!ctrl.target.mode">
<ul class="tight-form-list" role="menu">
<li class="tight-form-item query-keyword tight-form-align" style="width: 6em">Functions</li>
<li ng-repeat="func in ctrl.target.functions">
<span metric-function-editor class="tight-form-item tight-form-func"></span>
</li>
<li class="dropdown" add-metric-function></li>
</ul>
<div class="clearfix"></div>
<div class="gf-form">
<label class="gf-form-label">Options</label>
<div ng-repeat="func in ctrl.target.functions" class="gf-form-label query-part" metric-function-editor></div>
</div>
<!-- Query options -->
<div class="tight-form" ng-if="ctrl.showQueryOptions">
<div class="tight-form-inner-box">
<div class="tight-form last">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 170px">
Show disabled items
</li>
<li class="tight-form-item last">
<editor-checkbox text=""
model="ctrl.target.options.showDisabledItems"
change="ctrl.onQueryOptionChange()">
</editor-checkbox>
</li>
</ul>
<div class="clearfix"></div>
<div class="gf-form dropdown" add-metric-function>
</div>
<div class="gf-form gf-form--grow">
<div class="gf-form-label gf-form-label--grow"></div>
</div>
</div>
<div class="tight-form" ng-show="ctrl.target.mode == 2">
<ul class="tight-form-list" role="menu">
<div class="gf-form-inline" ng-show="ctrl.target.mode == 2">
<!-- Text metric regex -->
<li class="tight-form-item query-keyword tight-form-align" style="width: 6em" ng-show="ctrl.target.mode == 2">
Text filter
</li>
<li ng-show="ctrl.target.mode == 2">
<div class="gf-form max-width-20">
<label class="gf-form-label width-7">Text filter</label>
<input type="text"
class="tight-form-input" style="width: 417px"
class="gf-form-input"
ng-model="ctrl.target.textFilter"
spellcheck='false'
placeholder="Text filter (regex)"
ng-blur="ctrl.targetBlur()">
</li>
<li class="tight-form-item" ng-show="ctrl.target.mode == 2">
Use capture groups&nbsp;
<input class="cr1" id="ctrl.target.useCaptureGroups" type="checkbox"
ng-model="ctrl.target.useCaptureGroups"
ng-checked="ctrl.target.useCaptureGroups"
ng-change="ctrl.targetBlur()">
<label for="ctrl.target.useCaptureGroups" class="cr1"></label>
</li>
</ul>
<div class="clearfix"></div>
ng-blur="ctrl.onTargetBlur()">
</div>
<gf-form-switch class="gf-form" label="Use capture groups" checked="ctrl.target.useCaptureGroups" on-change="ctrl.onTargetBlur()">
</gf-form-switch>
</div>
</query-editor-row>

View File

@@ -26,9 +26,9 @@ export class ZabbixQueryController extends QueryCtrl {
this.templateSrv = templateSrv;
this.editorModes = {
0: 'num',
1: 'itservice',
2: 'text'
0: {value: 'num', text: 'Numeric metrics', mode: 0},
1: {value: 'itservice', text: 'IT Services', mode: 1},
2: {value: 'text', text: 'Text metrics', mode: 2}
};
// Map functions for bs-typeahead
@@ -63,8 +63,7 @@ export class ZabbixQueryController extends QueryCtrl {
functions: [],
options: {
showDisabledItems: false
},
refId: "A"
}
};
_.defaults(target, targetDefaults);
@@ -102,7 +101,7 @@ export class ZabbixQueryController extends QueryCtrl {
initFilters() {
var self = this;
var itemtype = self.editorModes[self.target.mode];
var itemtype = self.editorModes[self.target.mode].value;
return this.$q.when(this.suggestGroups())
.then(() => {return self.suggestHosts();})
.then(() => {return self.suggestApps();})