mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
added regular expression queries and esVersion service+directive+filter to allow a given element to require a specified elasticsearch version
This commit is contained in:
parent
cfceadc87d
commit
c6b1503950
@ -10,13 +10,15 @@ function (angular, config, _) {
|
||||
var module = angular.module('kibana.controllers');
|
||||
|
||||
module.controller('DashCtrl', function(
|
||||
$scope, $route, ejsResource, fields, dashboard, alertSrv, panelMove) {
|
||||
$scope, $route, ejsResource, fields, dashboard, alertSrv, panelMove, esVersion) {
|
||||
|
||||
$scope.requiredElasticSearchVersion = ">=0.20.5";
|
||||
|
||||
$scope.editor = {
|
||||
index: 0
|
||||
};
|
||||
|
||||
// For moving stuff around the dashboard. Needs better names
|
||||
$scope.panelMove = panelMove;
|
||||
// For moving stuff around the dashboard.
|
||||
$scope.panelMoveDrop = panelMove.onDrop;
|
||||
$scope.panelMoveStart = panelMove.onStart;
|
||||
$scope.panelMoveStop = panelMove.onStop;
|
||||
@ -24,16 +26,18 @@ function (angular, config, _) {
|
||||
$scope.panelMoveOut = panelMove.onOut;
|
||||
|
||||
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.config = config;
|
||||
// Make underscore.js available to views
|
||||
// Make stuff, including underscore.js available to views
|
||||
$scope._ = _;
|
||||
$scope.dashboard = dashboard;
|
||||
$scope.dashAlerts = alertSrv;
|
||||
$scope.esVersion = esVersion;
|
||||
|
||||
// Clear existing alerts
|
||||
alertSrv.clearAll();
|
||||
|
||||
// Provide a global list of all see fields
|
||||
// Provide a global list of all seen fields
|
||||
$scope.fields = fields;
|
||||
$scope.reset_row();
|
||||
|
||||
|
@ -7,5 +7,6 @@ define([
|
||||
'./ngBlur',
|
||||
'./ngModelOnBlur',
|
||||
'./tip',
|
||||
'./confirmClick'
|
||||
'./confirmClick',
|
||||
'./esVersion'
|
||||
], function () {});
|
25
src/app/directives/esVersion.js
Normal file
25
src/app/directives/esVersion.js
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
Only show an element if it meets an Elasticsearch version requirement
|
||||
*/
|
||||
|
||||
define([
|
||||
'angular',
|
||||
'app',
|
||||
],
|
||||
function (angular) {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('kibana.directives')
|
||||
.directive('esVersion', function(esVersion) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, elem, attr) {
|
||||
if(!esVersion.is(attr.esVersion)) {
|
||||
console.log('hiding');
|
||||
elem.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
@ -24,6 +24,18 @@ define(['angular', 'jquery', 'underscore', 'moment'], function (angular, $, _, m
|
||||
};
|
||||
});
|
||||
|
||||
/*
|
||||
Filter an array of objects by elasticsearch version requirements
|
||||
*/
|
||||
module.filter('esVersion', function(esVersion) {
|
||||
return function(items, require) {
|
||||
var ret = _.filter(items,function(qt) {
|
||||
return esVersion.is(qt[require]) ? true : false;
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
});
|
||||
|
||||
module.filter('slice', function() {
|
||||
return function(arr, start, end) {
|
||||
if(!_.isUndefined(arr)) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="panel-query-meta row-fluid" style="width:170px">
|
||||
<div class="panel-query-meta row-fluid" style="width:220px">
|
||||
|
||||
<style>
|
||||
.input-query-alias {
|
||||
@ -10,12 +10,19 @@
|
||||
|
||||
</style>
|
||||
<a class="close" ng-click="render();dismiss();" href="">×</a>
|
||||
<i ng-click="toggle_pin(id);dismiss();" class="small pointer icon-pushpin"></i>
|
||||
<label class="strong small ">Query Alias</label>
|
||||
<label class="strong small ">Query Alias <button class="btn btn-mini" ng-class="{active:querySrv.list[id].pin}" ng-click="toggle_pin(id);dismiss();" class="pointer"><i class="icon-pushpin"></i></button></label>
|
||||
|
||||
<form>
|
||||
<input class="input-medium input-query-alias" type="text" ng-model="querySrv.list[id].alias" placeholder='Alias...' />
|
||||
<input class="input-large input-query-alias" type="text" ng-model="querySrv.list[id].alias" placeholder='Alias...' />
|
||||
<div>
|
||||
<i ng-repeat="color in querySrv.colors" class="pointer" ng-class="{'icon-circle-blank':querySrv.list[id].color == color,'icon-circle':querySrv.list[id].color != color}" ng-style="{color:color}" ng-click="querySrv.list[id].color = color;render();"> </i>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<span>
|
||||
<label class="small">Query type</label>
|
||||
<select ng-change="dismiss();" class="input-small" ng-model="querySrv.list[id].type">
|
||||
<option ng-repeat="type in querySrv.queryTypes|esVersion:'require'">{{type.name}}</option>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
@ -2,10 +2,12 @@
|
||||
<div ng-repeat="id in (unPinnedQueries = (querySrv.ids|pinnedQuery:false))" ng-class="{'short-query': unPinnedQueries.length>1}">
|
||||
<form class="form-search" style="position:relative;margin-bottom:5px;" ng-submit="refresh()">
|
||||
<span class="begin-query">
|
||||
<i class="icon-circle pointer" data-unique="1" bs-popover="'app/panels/query/meta.html'" data-placement="rightTop" ng-style="{color: querySrv.list[id].color}"></i>
|
||||
<i class="icon-circle pointer" data-unique="1" bs-popover="'app/panels/query/meta.html'" data-placement="bottomLeft" ng-style="{color: querySrv.list[id].color}"></i>
|
||||
<i class="icon-remove-sign pointer remove-query" ng-show="querySrv.ids.length > 1" ng-click="querySrv.remove(id);refresh()"></i>
|
||||
</span>
|
||||
<input class="search-query panel-query" ng-class="{ 'input-block-level': unPinnedQueries.length==1, 'last-query': $last, 'has-remove': querySrv.ids.length > 1 }" bs-typeahead="panel.history" data-min-length=0 data-items=100 type="text" ng-model="querySrv.list[id].query" />
|
||||
<span>
|
||||
<input class="search-query panel-query" ng-class="{ 'input-block-level': unPinnedQueries.length==1, 'last-query': $last, 'has-remove': querySrv.ids.length > 1 }" bs-typeahead="panel.history" data-min-length=0 data-items=100 type="text" ng-model="querySrv.list[id].query" />
|
||||
</span>
|
||||
<span class="end-query">
|
||||
<i class="icon-search pointer" ng-click="refresh()" ng-show="$last"></i>
|
||||
<i class="icon-plus pointer" ng-click="querySrv.set({})" ng-show="$last"></i>
|
||||
@ -13,9 +15,9 @@
|
||||
</form>
|
||||
</div>
|
||||
<div style="display:inline-block" ng-repeat="id in querySrv.ids|pinnedQuery:true">
|
||||
<span class="pointer" ng-show="$first" ng-click="panel.pinned = !panel.pinned"><small class="pins">Pinned</small> <i ng-class="{'icon-caret-right':panel.pinned,'icon-caret-left':!panel.pinned}"></i></span>
|
||||
<span ng-show="panel.pinned" class="pinned badge">
|
||||
<i class="icon-circle pointer" ng-style="{color: querySrv.list[id].color}" data-unique="1" bs-popover="'app/panels/query/meta.html'"></i><span bs-tooltip="querySrv.list[id].query"> {{querySrv.list[id].alias || querySrv.list[id].query}}</span>
|
||||
<span class="pointer" ng-show="$first" ng-click="panel.pinned = !panel.pinned"><span class="pins">Pinned</span> <i ng-class="{'icon-caret-right':panel.pinned,'icon-caret-left':!panel.pinned}"></i></span>
|
||||
<span ng-show="panel.pinned" class="badge pinned">
|
||||
<i class="icon-circle pointer" ng-style="{color: querySrv.list[id].color}" data-unique="1" bs-popover="'app/panels/query/meta.html'" data-placement="bottomLeft"></i><span bs-tooltip="querySrv.list[id].query"> {{querySrv.list[id].alias || querySrv.list[id].query}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<span style="display:inline-block" ng-show="unPinnedQueries.length == 0">
|
||||
|
@ -6,6 +6,7 @@ define([
|
||||
'./kbnIndex',
|
||||
'./querySrv',
|
||||
'./timer',
|
||||
'./panelMove'
|
||||
'./panelMove',
|
||||
'./esVersion'
|
||||
],
|
||||
function () {});
|
150
src/app/services/esVersion.js
Normal file
150
src/app/services/esVersion.js
Normal file
@ -0,0 +1,150 @@
|
||||
define([
|
||||
'angular',
|
||||
'underscore',
|
||||
'config'
|
||||
],
|
||||
function (angular, _, config) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('kibana.services');
|
||||
|
||||
module.service('esVersion', function($http, alertSrv) {
|
||||
|
||||
this.versions = [];
|
||||
|
||||
// save a reference to this
|
||||
var self = this;
|
||||
|
||||
this.init = function() {
|
||||
getVersions();
|
||||
};
|
||||
|
||||
var getVersions = function() {
|
||||
var nodeInfo = $http({
|
||||
url: config.elasticsearch + '/_nodes',
|
||||
method: "GET"
|
||||
}).error(function(data, status) {
|
||||
if(status === 0) {
|
||||
alertSrv.set('Error',"Could not contact Elasticsearch at "+config.elasticsearch+
|
||||
". Please ensure that Elasticsearch is reachable from your system." ,'error');
|
||||
} else {
|
||||
alertSrv.set('Error',"Could not reach "+config.elasticsearch+"/_nodes. If you"+
|
||||
" are using a proxy, ensure it is configured correctly",'error');
|
||||
}
|
||||
});
|
||||
|
||||
return nodeInfo.then(function(p) {
|
||||
_.each(p.data.nodes, function(v) {
|
||||
self.versions.push(v.version.split('-')[0]);
|
||||
});
|
||||
self.versions = sortVersions(_.uniq(self.versions));
|
||||
});
|
||||
};
|
||||
|
||||
// Get the max version in this cluster
|
||||
this.max = function() {
|
||||
return _.last(self.versions);
|
||||
};
|
||||
|
||||
// Return the lowest version in the cluster
|
||||
this.min = function() {
|
||||
return _.first(self.versions);
|
||||
};
|
||||
|
||||
// Sort versions from lowest to highest
|
||||
var sortVersions = function(versions) {
|
||||
var _versions = _.clone(versions),
|
||||
_r = [];
|
||||
|
||||
while(_r.length < versions.length) {
|
||||
var _h = "0";
|
||||
/*jshint -W083 */
|
||||
_.each(_versions,function(v){
|
||||
if(self.compare(_h,v)) {
|
||||
_h = v;
|
||||
}
|
||||
});
|
||||
_versions = _.without(_versions,_h);
|
||||
_r.push(_h);
|
||||
}
|
||||
return _r.reverse();
|
||||
};
|
||||
|
||||
/*
|
||||
Takes a version string with one of the following optional comparison prefixes: >,>=,<.<=
|
||||
and evaluates if the cluster meets the requirement. If the prefix is omitted exact match
|
||||
is assumed
|
||||
*/
|
||||
this.is = function(equation) {
|
||||
var _v = equation,
|
||||
_cf;
|
||||
|
||||
if(_v.charAt(0) === '>') {
|
||||
_cf = _v.charAt(1) === '=' ? self.gte(_v.slice(2)) : self.gt(_v.slice(1));
|
||||
} else if (_v.charAt(0) === '<') {
|
||||
_cf = _v.charAt(1) === '=' ? self.lte(_v.slice(2)) : self.lt(_v.slice(1));
|
||||
} else {
|
||||
_cf = self.eq(_v);
|
||||
}
|
||||
|
||||
return _cf;
|
||||
};
|
||||
|
||||
// check if lowest version in cluster = `version`
|
||||
this.eq = function(version) {
|
||||
return version === self.min() ? true : false;
|
||||
};
|
||||
|
||||
// version > lowest version in cluster?
|
||||
this.gt = function(version) {
|
||||
return version === self.min() ? false : self.gte(version);
|
||||
};
|
||||
|
||||
// version < highest version in cluster?
|
||||
this.lt = function(version) {
|
||||
return version === self.max() ? false : self.lte(version);
|
||||
};
|
||||
|
||||
// Check if the lowest version in the cluster is >= to `version`
|
||||
this.gte = function(version) {
|
||||
return self.compare(version,self.min());
|
||||
};
|
||||
|
||||
// Check if the highest version in the cluster is <= to `version`
|
||||
this.lte = function(version) {
|
||||
return self.compare(self.max(),version);
|
||||
};
|
||||
|
||||
// Determine if a specific version is greater than or equal to another
|
||||
this.compare = function (required,installed) {
|
||||
var a = installed.split('.');
|
||||
var b = required.split('.');
|
||||
var i;
|
||||
|
||||
for (i = 0; i < a.length; ++i) {
|
||||
a[i] = Number(a[i]);
|
||||
}
|
||||
for (i = 0; i < b.length; ++i) {
|
||||
b[i] = Number(b[i]);
|
||||
}
|
||||
if (a.length === 2) {
|
||||
a[2] = 0;
|
||||
}
|
||||
|
||||
if (a[0] > b[0]){return true;}
|
||||
if (a[0] < b[0]){return false;}
|
||||
|
||||
if (a[1] > b[1]){return true;}
|
||||
if (a[1] < b[1]){return false;}
|
||||
|
||||
if (a[2] > b[2]){return true;}
|
||||
if (a[2] < b[2]){return false;}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
this.init();
|
||||
|
||||
});
|
||||
|
||||
});
|
@ -39,6 +39,12 @@ function (angular, _, config) {
|
||||
"#E0F9D7","#FCEACA","#CFFAFF","#F9E2D2","#FCE2DE","#BADFF4","#F9D9F9","#DEDAF7" //7
|
||||
];
|
||||
|
||||
// Define the query types and the version of elasticsearch they were first available in
|
||||
this.queryTypes = [
|
||||
{name:'lucene',require:">=0.17.0"},
|
||||
{name:'regex',require:">=0.90.3"}
|
||||
];
|
||||
|
||||
|
||||
// Save a reference to this
|
||||
var self = this;
|
||||
@ -104,6 +110,8 @@ function (angular, _, config) {
|
||||
{
|
||||
case 'lucene':
|
||||
return ejs.QueryStringQuery(q.query || '*');
|
||||
case 'regex':
|
||||
return ejs.RegexpQuery('_all',q.query);
|
||||
default:
|
||||
return _.isUndefined(q.query) ? false : ejs.QueryStringQuery(q.query || '*');
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
<body ng-cloak>
|
||||
|
||||
|
||||
<link rel="stylesheet" ng-href="css/bootstrap.{{dashboard.current.style||'dark'}}.min.css">
|
||||
<link rel="stylesheet" href="css/bootstrap-responsive.min.css">
|
||||
<link rel="stylesheet" href="css/font-awesome.min.css">
|
||||
|
Loading…
Reference in New Issue
Block a user