Merge branch 'triggers-panel'

This commit is contained in:
Alexander Zobnin
2017-02-01 18:53:58 +03:00
4 changed files with 249 additions and 334 deletions

View File

@@ -180,11 +180,8 @@ export class ZabbixQueryController extends QueryCtrl {
* Check query for template variables * Check query for template variables
*/ */
isContainsVariables() { isContainsVariables() {
var self = this; return _.some(['group', 'host', 'application'], field => {
return _.some(self.templateSrv.variables, variable => { return utils.isTemplateVariable(this.panel.triggers[field].filter, this.templateSrv.variables);
return _.some(['group', 'host', 'application', 'item'], field => {
return self.templateSrv.containsVariable(self.target[field].filter, variable.name);
});
}); });
} }

View File

@@ -1,337 +1,256 @@
<div class="editor-row"> <div class="editor-row">
<div class="section tight-form-container" style="margin-bottom: 20px"> <div class="section gf-form-group">
<h5>Select triggers</h5> <h5 class="section-heading">Select triggers</h5>
<div class="tight-form"> <div class="gf-form-inline">
<ul class="tight-form-list"> <div class="gf-form max-width-20">
<li class="tight-form-item" style="width: 80px"> <label class="gf-form-label query-keyword width-7">Group</label>
Group
</li>
<li>
<input type="text" <input type="text"
ng-model="editor.panel.triggers.group.filter" ng-model="editor.panel.triggers.group.filter"
bs-typeahead="editor.getGroupNames" bs-typeahead="editor.getGroupNames"
ng-blur="editor.parseTarget()" ng-blur="editor.parseTarget()"
data-min-length=0 data-min-length=0
data-items=100 data-items=100
class="input-large tight-form-input" class="gf-form-input"
ng-class="{ ng-class="{
'zbx-variable': editor.isVariable(editor.panel.triggers.group.filter), 'zbx-variable': editor.isVariable(editor.panel.triggers.group.filter),
'zbx-regex': editor.isRegex(editor.panel.triggers.group.filter) 'zbx-regex': editor.isRegex(editor.panel.triggers.group.filter)
}"> }">
</li> </div>
<li class="tight-form-item" style="width: 50px"> <div class="gf-form">
Host <label class="gf-form-label query-keyword width-7">Host</label>
</li>
<li>
<input type="text" <input type="text"
ng-model="editor.panel.triggers.host.filter" ng-model="editor.panel.triggers.host.filter"
bs-typeahead="editor.getHostNames" bs-typeahead="editor.getHostNames"
ng-blur="editor.parseTarget()" ng-blur="editor.parseTarget()"
data-min-length=0 data-min-length=0
data-items=100 data-items=100
class="input-large tight-form-input last" class="gf-form-input"
ng-class="{ ng-class="{
'zbx-variable': editor.isVariable(editor.panel.triggers.host.filter), 'zbx-variable': editor.isVariable(editor.panel.triggers.host.filter),
'zbx-regex': editor.isRegex(editor.panel.triggers.host.filter) 'zbx-regex': editor.isRegex(editor.panel.triggers.host.filter)
}"> }">
</li>
</ul>
<div class="clearfix"></div>
</div> </div>
<div class="tight-form"> </div>
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 80px"> <div class="gf-form-inline">
Application <div class="gf-form max-width-20">
</li> <label class="gf-form-label query-keyword width-7">Application</label>
<li>
<input type="text" <input type="text"
ng-model="editor.panel.triggers.application.filter" ng-model="editor.panel.triggers.application.filter"
bs-typeahead="editor.getApplicationNames" bs-typeahead="editor.getApplicationNames"
ng-blur="editor.parseTarget()" ng-blur="editor.parseTarget()"
data-min-length=0 data-min-length=0
data-items=100 data-items=100
class="input-large tight-form-input" class="gf-form-input"
ng-class="{ ng-class="{
'zbx-variable': editor.isVariable(editor.panel.triggers.application.filter), 'zbx-variable': editor.isVariable(editor.panel.triggers.application.filter),
'zbx-regex': editor.isRegex(editor.panel.triggers.application.filter) 'zbx-regex': editor.isRegex(editor.panel.triggers.application.filter)
}"> }">
</li> </div>
<li class="tight-form-item" style="width: 50px"> <div class="gf-form">
Trigger <label class="gf-form-label query-keyword width-7">Trigger</label>
</li>
<li>
<input type="text" <input type="text"
ng-model="editor.panel.triggers.trigger.filter" ng-model="editor.panel.triggers.trigger.filter"
ng-blur="editor.parseTarget()" ng-blur="editor.parseTarget()"
placeholder="trigger name" placeholder="trigger name"
class="input-large tight-form-input last" class="gf-form-input"
ng-style="editor.panel.triggers.trigger.style" ng-style="editor.panel.triggers.trigger.style"
empty-to-null> empty-to-null>
</li>
</ul>
<div class="clearfix"></div>
</div> </div>
</div> </div>
<div class="section"> </div>
<h5>Data source</h5>
<div class="section tight-form-container" style="margin-bottom: 20px"> <div class="section gf-form-group">
<div class="tight-form"> <h5 class="section-heading">Data source</h5>
<ul class="tight-form-list"> <div class="gf-form-inline">
<li> <div class="gf-form">
<select class="tight-form-input input-large last" <div class="gf-form-select-wrapper">
<select class="gf-form-input"
ng-model="editor.panel.datasource" ng-model="editor.panel.datasource"
ng-options="ds for ds in editor.datasources" ng-options="ds for ds in editor.datasources"
ng-change="editor.datasourceChanged()"> ng-change="editor.datasourceChanged()">
</select> </select>
</li> </div>
</ul> </div>
<div class="clearfix"></div>
</div> </div>
</div> </div>
</div> </div>
<div class="editor-row"> <div class="editor-row">
<div class="section"> <div class="section gf-form-group">
<h5>Options</h5> <h5 class="section-heading">Options</h5>
<div class="tight-form-container" style="margin-bottom: 20px"> <div class="gf-form-inline">
<div class="tight-form"> <div class="gf-form">
<ul class="tight-form-list"> <label class="gf-form-label width-8">Acknowledged</label>
<li class="tight-form-item" style="width: 100px"> <div class="gf-form-select-wrapper">
<strong>Acknowledged</strong> <select class="gf-form-input"
</li>
<li>
<select class="input-medium tight-form-input"
ng-model="editor.panel.showTriggers" ng-model="editor.panel.showTriggers"
ng-options="f for f in editor.ackFilters" ng-options="f for f in editor.ackFilters"
ng-change="editor.panelCtrl.refresh()"> ng-change="editor.panelCtrl.refresh()">
</select> </select>
</li> </div>
<li class="tight-form-item" style="width: 13em"> </div>
<strong>Limit triggers number to</strong> <div class="gf-form">
</li> <label class="gf-form-label width-12">Limit triggers number to</label>
<li> <input class="gf-form-input width-5"
<input class="input-small tight-form-input"
type="number" type="number"
ng-model="editor.panel.limit" ng-model="editor.panel.limit"
ng-model-onblur ng-model-onblur
ng-change="editor.panelCtrl.refresh()"> ng-change="editor.panelCtrl.refresh()">
</li>
</ul>
<div class="clearfix"></div>
</div> </div>
<div class="tight-form"> </div>
<ul class="tight-form-list"> <div class="gf-form-inline">
<li class="tight-form-item" style="width: 100px"> <div class="gf-form">
<strong>Sort by</strong> <label class="gf-form-label width-8">Sort by</label>
</li> <div class="gf-form-select-wrapper">
<li> <select class="gf-form-input"
<select class="input-medium tight-form-input"
ng-model="editor.panel.sortTriggersBy" ng-model="editor.panel.sortTriggersBy"
ng-options="f.text for f in editor.sortByFields track by f.value" ng-options="f.text for f in editor.sortByFields track by f.value"
ng-change="editor.panelCtrl.refresh()"> ng-change="editor.panelCtrl.refresh()">
</select> </select>
</li> </div>
<li class="tight-form-item" style="width: 13em"> </div>
<strong>Show events</strong> <div class="gf-form">
</li> <label class="gf-form-label width-8">Show events</label>
<li> <div class="gf-form-select-wrapper">
<select class="tight-form-input input-medium" <select class="gf-form-input"
ng-model="editor.panel.showEvents" ng-model="editor.panel.showEvents"
ng-options="f.text for f in editor.showEventsFields track by f.value" ng-options="f.text for f in editor.showEventsFields track by f.value"
ng-change="editor.panelCtrl.refresh()"> ng-change="editor.panelCtrl.refresh()">
</select> </select>
</li>
</ul>
<div class="clearfix"></div>
</div> </div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px">
<strong>Show fields</strong>
</li>
<li class="tight-form-item">
<label class="checkbox-label" for="hostField">Host Name</label>
<input class="cr1"
id="hostField"
type="checkbox"
ng-model="editor.panel.hostField"
ng-checked="editor.panel.hostField">
<label for="hostField" class="cr1"></label>
</li>
<li class="tight-form-item">
<label class="checkbox-label" for="hostField">Host Technical Name</label>
<input class="cr1"
id="hostTechNameField"
type="checkbox"
ng-model="editor.panel.hostTechNameField"
ng-checked="editor.panel.hostTechNameField">
<label for="hostTechNameField" class="cr1"></label>
</li>
<li class="tight-form-item">
<label class="checkbox-label" for="statusField">Status</label>
<input class="cr1"
id="statusField"
type="checkbox"
ng-model="editor.panel.statusField"
ng-checked="editor.panel.statusField">
<label for="statusField" class="cr1"></label>
</li>
<li class="tight-form-item">
<label class="checkbox-label" for="severityField">Severity</label>
<input class="cr1"
id="severityField"
type="checkbox"
ng-model="editor.panel.severityField"
ng-checked="editor.panel.severityField">
<label for="severityField" class="cr1"></label>
</li>
</ul>
<div class="clearfix"></div>
</div> </div>
<div class="tight-form"> </div>
<ul class="tight-form-list"> </div>
<li class="tight-form-item" style="width: 100px">
<strong>&nbsp;</strong> <div class="section gf-form-group">
</li> <h5 class="section-heading">Show fields</h5>
<li class="tight-form-item"> <div class="gf-form-inline">
<label class="checkbox-label" for="lastChangeField">Last change</label> <gf-form-switch class="gf-form"
<input class="cr1" label-class="width-8"
id="lastChangeField" label="Host name"
type="checkbox" checked="editor.panel.hostField"
ng-model="editor.panel.lastChangeField" on-change="ctrl.render()">
ng-checked="editor.panel.lastChangeField"> </gf-form-switch>
<label for="lastChangeField" class="cr1"></label> <gf-form-switch class="gf-form"
</li> label-class="width-12"
<li class="tight-form-item"> label="Host technical name"
<label class="checkbox-label" for="ageField">Age</label> checked="editor.panel.hostTechNameField"
<input class="cr1" on-change="ctrl.render()">
id="ageField" </gf-form-switch>
type="checkbox" <gf-form-switch class="gf-form"
ng-model="editor.panel.ageField" label-class="width-5"
ng-checked="editor.panel.ageField"> label="Status"
<label for="ageField" class="cr1"></label> checked="editor.panel.statusField"
</li> on-change="ctrl.render()">
<li class="tight-form-item"> </gf-form-switch>
<label class="checkbox-label" for="infoField">Info</label> </div>
<input class="cr1" <div class="gf-form-inline">
id="infoField" <gf-form-switch class="gf-form"
type="checkbox" label-class="width-5"
ng-model="editor.panel.infoField" label="Severity"
ng-checked="editor.panel.infoField"> checked="editor.panel.severityField"
<label for="infoField" class="cr1"></label> on-change="ctrl.render()">
</li> </gf-form-switch>
</ul> <gf-form-switch class="gf-form"
<div class="clearfix"></div> label-class="width-7"
label="Last change"
checked="editor.panel.lastChangeField"
on-change="ctrl.render()">
</gf-form-switch>
<gf-form-switch class="gf-form"
label-class="width-4"
label="Age"
checked="editor.panel.ageField"
on-change="ctrl.render()">
</gf-form-switch>
<gf-form-switch class="gf-form"
label-class="width-4"
label="Info"
checked="editor.panel.infoField"
on-change="ctrl.render()">
</gf-form-switch>
</div>
<div class="gf-form-inline">
<gf-form-switch class="gf-form"
label-class="width-14"
label="Custom Last change format"
checked="editor.panel.customLastChangeFormat"
on-change="ctrl.render()">
</gf-form-switch>
<div class="gf-form" ng-if="editor.panel.customLastChangeFormat">
<label class="gf-form-label width-3">
<a href="http://momentjs.com/docs/#/displaying/format/" target="_blank">
<tip>See moment.js dosc for time format.</tip>
</a>
</label>
<input class="gf-form-input width-18"
type="text"
placeholder="dddd, MMMM Do YYYY, h:mm:ss a"
empty-to-null
ng-model-onblur
ng-model="editor.panel.lastChangeFormat"
ng-change="editor.panelCtrl.refresh()">
</div>
</div>
</div>
</div> </div>
<div class="tight-form"> <div class="editor-row">
<ul class="tight-form-list"> <div class="section gf-form-group">
<li class="tight-form-item"> <h5 class="section-heading">Customize triggers severity and colors</h5>
<strong>Custom Last change format</strong> <div class="gf-form-inline" ng-repeat="trigger in editor.panel.triggerSeverity">
<label class="checkbox-label" for="customLastChangeFormat">&nbsp;</label> <div class="gf-form">
<input class="cr1" <label class="gf-form-label width-3">{{ trigger.priority }}</label>
id="customLastChangeFormat"
type="checkbox"
ng-change="editor.panelCtrl.refresh()"
ng-model="editor.panel.customLastChangeFormat"
ng-checked="editor.panel.customLastChangeFormat">
<label for="customLastChangeFormat" class="cr1"></label>
</li>
<li ng-if="editor.panel.customLastChangeFormat">
<input type="text" <input type="text"
ng-model="editor.panel.lastChangeFormat" class="gf-form-input width-12"
ng-blur="editor.panelCtrl.refresh()"
placeholder="dddd, MMMM Do YYYY, h:mm:ss a"
class="tight-form-input"
style="width: 300px"
empty-to-null>
</li>
<li class="tight-form-item last" ng-if="editor.panel.customLastChangeFormat">
<a href="http://momentjs.com/docs/#/displaying/format/" target="_blank">
<i class="fa fa-question-circle"
bs-tooltip="'See moment.js dosc for time format.'">
</i>
</a>
</li>
</ul>
<div class="clearfix"></div>
</div>
</div>
</div>
<div class="section">
<h5>Customize triggers severity and colors</h5>
<div class="tight-form" ng-repeat="trigger in editor.panel.triggerSeverity">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 10px">
{{ trigger.priority }}
</li>
<li>
<input class="tight-form-input input-medium"
type="text"
empty-to-null empty-to-null
ng-model="trigger.severity" ng-model="trigger.severity"
style="color: white" style="color: white"
ng-style="{background: trigger.color}" ng-style="{background: trigger.color}"
ng-model-onblur ng-model-onblur
ng-change="editor.panelCtrl.refresh()"> ng-change="editor.panelCtrl.refresh()">
</li> <span class="gf-form-label">
<li class="tight-form-item">
<spectrum-picker ng-model="trigger.color" ng-change="editor.panelCtrl.refresh()"></spectrum-picker> <spectrum-picker ng-model="trigger.color" ng-change="editor.panelCtrl.refresh()"></spectrum-picker>
</li> </span>
<li class="tight-form-item last" style="width: 28px">
<label class="checkbox-label" for="{{ 'trigger-show-' + $index }}"></label>
<input class="cr1"
ng-attr-id="{{ 'trigger-show-' + $index }}"
type="checkbox"
ng-model="trigger.show"
ng-checked="trigger.show"
ng-change="editor.panelCtrl.refresh()">
<label for="{{ 'trigger-show-' + $index }}" class="cr1"></label>
</li>
</ul>
<div class="clearfix"></div>
</div> </div>
<div class="tight-form"> <gf-form-switch class="gf-form"
<ul class="tight-form-list"> label-class="width-0"
<li class="tight-form-item" label="Show"
ng-style="{background:editor.panel.okEventColor}" checked="trigger.show"
style="width: 160px; color: white"> on-change="editor.panelCtrl.refresh()">
<span style="padding-left: 25px"> OK event color </span> </gf-form-switch>
</li>
<li class="tight-form-item">
<spectrum-picker
ng-model="editor.panel.okEventColor"
ng-change="editor.panelCtrl.refresh()">
</spectrum-picker>
</li>
</ul>
<div class="clearfix"></div>
</div> </div>
<div class="tight-form last">
<ul class="tight-form-list"> <div class="gf-form-inline">
<li class="tight-form-item" <div class="gf-form">
ng-style="{background:editor.panel.ackEventColor}" <label class="gf-form-label width-3">&nbsp;</label>
style="width: 160px; color: white"> <label class="gf-form-label width-12"
<span style="padding-left: 25px"> Acknowledged color </span> ng-style="{background:editor.panel.okEventColor}">
</li> OK event color
<li class="tight-form-item"> </label>
<spectrum-picker <span class="gf-form-label">
ng-model="editor.panel.ackEventColor" <spectrum-picker ng-model="editor.panel.okEventColor" ng-change="editor.panelCtrl.refresh()"></spectrum-picker>
ng-change="editor.panelCtrl.refresh()"> </span>
</spectrum-picker> </div>
</li> </div>
<li class="tight-form-item last" style="width: 28px"> <div class="gf-form-inline">
<label class="checkbox-label" for="ack-event-color"></label> <div class="gf-form">
<input class="cr1" <label class="gf-form-label width-3">&nbsp;</label>
id="ack-event-color" <label class="gf-form-label width-12"
type="checkbox" ng-style="{background:editor.panel.ackEventColor}">
ng-model="editor.panel.markAckEvents" Acknowledged color
ng-checked="editor.panel.markAckEvents" </label>
ng-change="editor.panelCtrl.refresh()"> <span class="gf-form-label">
<label for="ack-event-color" class="cr1"></label> <spectrum-picker ng-model="editor.panel.ackEventColor" ng-change="editor.panelCtrl.refresh()"></spectrum-picker>
</li> </span>
</ul> </div>
<div class="clearfix"></div> <gf-form-switch class="gf-form"
label-class="width-0"
label="Show"
checked="editor.panel.markAckEvents"
on-change="editor.panelCtrl.refresh()">
</gf-form-switch>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -75,6 +75,7 @@ class TriggerPanelEditorCtrl {
this.datasourceSrv.get(this.panel.datasource) this.datasourceSrv.get(this.panel.datasource)
.then(datasource => { .then(datasource => {
this.datasource = datasource; this.datasource = datasource;
this.zabbix = datasource.zabbix;
this.queryBuilder = datasource.queryBuilder; this.queryBuilder = datasource.queryBuilder;
this.initFilters(); this.initFilters();
this.panelCtrl.refresh(); this.panelCtrl.refresh();
@@ -90,7 +91,7 @@ class TriggerPanelEditorCtrl {
} }
suggestGroups() { suggestGroups() {
return this.queryBuilder.getAllGroups() return this.zabbix.getAllGroups()
.then(groups => { .then(groups => {
this.metric.groupList = groups; this.metric.groupList = groups;
return groups; return groups;
@@ -99,7 +100,7 @@ class TriggerPanelEditorCtrl {
suggestHosts() { suggestHosts() {
let groupFilter = this.datasource.replaceTemplateVars(this.panel.triggers.group.filter); let groupFilter = this.datasource.replaceTemplateVars(this.panel.triggers.group.filter);
return this.queryBuilder.getAllHosts(groupFilter) return this.zabbix.getAllHosts(groupFilter)
.then(hosts => { .then(hosts => {
this.metric.hostList = hosts; this.metric.hostList = hosts;
return hosts; return hosts;
@@ -109,7 +110,7 @@ class TriggerPanelEditorCtrl {
suggestApps() { suggestApps() {
let groupFilter = this.datasource.replaceTemplateVars(this.panel.triggers.group.filter); let groupFilter = this.datasource.replaceTemplateVars(this.panel.triggers.group.filter);
let hostFilter = this.datasource.replaceTemplateVars(this.panel.triggers.host.filter); let hostFilter = this.datasource.replaceTemplateVars(this.panel.triggers.host.filter);
return this.queryBuilder.getAllApps(groupFilter, hostFilter) return this.zabbix.getAllApps(groupFilter, hostFilter)
.then(apps => { .then(apps => {
this.metric.appList = apps; this.metric.appList = apps;
return apps; return apps;
@@ -126,11 +127,8 @@ class TriggerPanelEditorCtrl {
* Check query for template variables * Check query for template variables
*/ */
isContainsVariables() { isContainsVariables() {
var self = this;
return _.some(self.templateSrv.variables, variable => {
return _.some(['group', 'host', 'application'], field => { return _.some(['group', 'host', 'application'], field => {
return self.templateSrv.containsVariable(self.panel.triggers[field].filter, variable.name); return utils.isTemplateVariable(this.panel.triggers[field].filter, this.templateSrv.variables);
});
}); });
} }

View File

@@ -232,14 +232,15 @@ class TriggerPanelCtrl extends MetricsPanelCtrl {
} }
acknowledgeTrigger(trigger, message) { acknowledgeTrigger(trigger, message) {
let self = this;
let eventid = trigger.lastEvent.eventid; let eventid = trigger.lastEvent.eventid;
let grafana_user = this.contextSrv.user.name; let grafana_user = this.contextSrv.user.name;
let ack_message = grafana_user + ' (Grafana): ' + message; let ack_message = grafana_user + ' (Grafana): ' + message;
return this.datasourceSrv.get(this.panel.datasource).then(datasource => { return this.datasourceSrv.get(this.panel.datasource)
let zabbix = datasource.zabbixAPI; .then(datasource => {
return zabbix.acknowledgeEvent(eventid, ack_message).then(() => { let zabbixAPI = datasource.zabbix.zabbixAPI;
self.refresh(); return zabbixAPI.acknowledgeEvent(eventid, ack_message)
.then(() => {
this.refresh();
}); });
}); });
} }