diff --git a/src/app/controllers/dashLoader.js b/src/app/controllers/dashLoader.js
index dc29006bcdc..9349c5cf00b 100644
--- a/src/app/controllers/dashLoader.js
+++ b/src/app/controllers/dashLoader.js
@@ -2,16 +2,18 @@ define([
'angular',
'underscore',
'moment',
+ 'config',
'filesaver'
],
-function (angular, _, moment) {
+function (angular, _, moment, config) {
'use strict';
var module = angular.module('grafana.controllers');
- module.controller('dashLoader', function($scope, $rootScope, $http, alertSrv, $location, playlistSrv, elastic) {
+ module.controller('dashLoader', function($scope, $rootScope, $http, alertSrv, $location, playlistSrv, datasourceSrv) {
$scope.init = function() {
+ $scope.db = datasourceSrv.getGrafanaDB();
$scope.onAppEvent('save-dashboard', function() {
$scope.saveDashboard();
});
@@ -19,7 +21,6 @@ function (angular, _, moment) {
$scope.onAppEvent('zoom-out', function() {
$scope.zoom(2);
});
-
};
$scope.exitFullscreen = function() {
@@ -38,6 +39,9 @@ function (angular, _, moment) {
if(type === 'save') {
return (_l.save_elasticsearch);
}
+ if(type === 'share') {
+ return (_l.save_temp);
+ }
return false;
};
@@ -52,7 +56,7 @@ function (angular, _, moment) {
};
$scope.saveForSharing = function() {
- elastic.saveForSharing($scope.dashboard)
+ $scope.db.saveDashboardTemp($scope.dashboard)
.then(function(result) {
$scope.share = { url: result.url, title: result.title };
@@ -62,10 +66,32 @@ function (angular, _, moment) {
});
};
+ $scope.passwordCache = function(pwd) {
+ if (!window.sessionStorage) { return null; }
+ if (!pwd) { return window.sessionStorage["grafanaAdminPassword"]; }
+ window.sessionStorage["grafanaAdminPassword"] = pwd;
+ };
+
+ $scope.isAdmin = function() {
+ if (!config.admin || !config.admin.password) { return true; }
+ if (this.passwordCache() === config.admin.password) { return true; }
+
+ var password = window.prompt("Admin password", "");
+ this.passwordCache(password);
+
+ if (password === config.admin.password) { return true; }
+
+ alertSrv.set('Save failed', 'Password incorrect', 'error');
+
+ return false;
+ };
+
$scope.saveDashboard = function() {
- elastic.saveDashboard($scope.dashboard, $scope.dashboard.title)
+ if (!this.isAdmin()) { return false; }
+
+ $scope.db.saveDashboard($scope.dashboard, $scope.dashboard.title)
.then(function(result) {
- alertSrv.set('Dashboard Saved', 'Dashboard has been saved to Elasticsearch as "' + result.title + '"','success', 5000);
+ alertSrv.set('Dashboard Saved', 'Dashboard has been saved as "' + result.title + '"','success', 5000);
$location.path(result.url);
@@ -81,7 +107,9 @@ function (angular, _, moment) {
return;
}
- elastic.deleteDashboard(id).then(function(id) {
+ if (!this.isAdmin()) { return false; }
+
+ $scope.db.deleteDashboard(id).then(function(id) {
alertSrv.set('Dashboard Deleted', id + ' has been deleted', 'success', 5000);
}, function() {
alertSrv.set('Dashboard Not Deleted', 'An error occurred deleting the dashboard', 'error', 5000);
diff --git a/src/app/controllers/graphiteImport.js b/src/app/controllers/graphiteImport.js
index de30ef64711..bb38eaffb45 100644
--- a/src/app/controllers/graphiteImport.js
+++ b/src/app/controllers/graphiteImport.js
@@ -11,8 +11,7 @@ function (angular, app, _) {
module.controller('GraphiteImportCtrl', function($scope, $rootScope, $timeout, datasourceSrv) {
$scope.init = function() {
- console.log('hej!');
- $scope.datasources = datasourceSrv.listOptions();
+ $scope.datasources = datasourceSrv.getMetricSources();
$scope.setDatasource(null);
};
@@ -96,7 +95,8 @@ function (angular, app, _) {
currentRow.panels.push(panel);
});
- $scope.dashboard.dash_load(newDashboard);
+ $scope.emitAppEvent('setup-dashboard', newDashboard);
+ $scope.dismiss();
}
});
diff --git a/src/app/controllers/search.js b/src/app/controllers/search.js
index f88e9e0c079..1ecd544b289 100644
--- a/src/app/controllers/search.js
+++ b/src/app/controllers/search.js
@@ -9,13 +9,14 @@ function (angular, _, config, $) {
var module = angular.module('grafana.controllers');
- module.controller('SearchCtrl', function($scope, $rootScope, $element, $location, elastic) {
+ module.controller('SearchCtrl', function($scope, $rootScope, $element, $location, datasourceSrv) {
$scope.init = function() {
$scope.giveSearchFocus = 0;
$scope.selectedIndex = -1;
$scope.results = {dashboards: [], tags: [], metrics: []};
$scope.query = { query: 'title:' };
+ $scope.db = datasourceSrv.getGrafanaDB();
$scope.onAppEvent('open-search', $scope.openSearch);
};
@@ -57,40 +58,12 @@ function (angular, _, config, $) {
};
};
- $scope.searchDasboards = function(queryString) {
- var tagsOnly = queryString.indexOf('tags!:') === 0;
- if (tagsOnly) {
- var tagsQuery = queryString.substring(6, queryString.length);
- queryString = 'tags:' + tagsQuery + '*';
- }
- else {
- if (queryString.length === 0) {
- queryString = 'title:';
- }
-
- if (queryString[queryString.length - 1] !== '*') {
- queryString += '*';
- }
- }
-
- var query = {
- query: { query_string: { query: queryString } },
- facets: { tags: { terms: { field: "tags", order: "term", size: 50 } } },
- size: 20,
- sort: ["_uid"]
- };
-
- return elastic.post('/dashboard/_search', query)
+ $scope.searchDashboards = function(queryString) {
+ return $scope.db.searchDashboards(queryString)
.then(function(results) {
- if(_.isUndefined(results.hits)) {
- $scope.results.dashboards = [];
- $scope.results.tags = [];
- return;
- }
-
- $scope.tagsOnly = tagsOnly;
- $scope.results.dashboards = results.hits.hits;
- $scope.results.tags = results.facets.tags.terms;
+ $scope.tagsOnly = results.dashboards.length === 0 && results.tags.length > 0;
+ $scope.results.dashboards = results.dashboards;
+ $scope.results.tags = results.tags;
});
};
@@ -118,12 +91,9 @@ function (angular, _, config, $) {
$scope.selectedIndex = -1;
var queryStr = $scope.query.query.toLowerCase();
+ queryStr = queryStr.replace(' and ', ' AND ');
- if (queryStr.indexOf('m:') !== 0) {
- queryStr = queryStr.replace(' and ', ' AND ');
- $scope.searchDasboards(queryStr);
- return;
- }
+ $scope.searchDashboards(queryStr);
};
$scope.openSearch = function (evt) {
@@ -177,4 +147,4 @@ function (angular, _, config, $) {
};
});
-});
\ No newline at end of file
+});
diff --git a/src/app/partials/dashLoader.html b/src/app/partials/dashLoader.html
index 6544924f90e..c13227b07fe 100644
--- a/src/app/partials/dashLoader.html
+++ b/src/app/partials/dashLoader.html
@@ -47,8 +47,11 @@
Export dashboard
- Share temp copy
-
+
+
+ Share temp copy
+
+
diff --git a/src/app/partials/dasheditor.html b/src/app/partials/dasheditor.html
index db6343470d0..50284aac4b4 100644
--- a/src/app/partials/dasheditor.html
+++ b/src/app/partials/dasheditor.html
@@ -2,7 +2,7 @@
Dashboard settings
-
-
-
-
-
+
diff --git a/src/app/routes/dashboard-from-es.js b/src/app/routes/dashboard-from-es.js
index 280776efa3b..f2d8ce85fb5 100644
--- a/src/app/routes/dashboard-from-es.js
+++ b/src/app/routes/dashboard-from-es.js
@@ -1,9 +1,7 @@
define([
'angular',
- 'jquery',
- 'config'
],
-function (angular, $, config) {
+function (angular) {
"use strict";
var module = angular.module('grafana.routes');
@@ -20,37 +18,15 @@ function (angular, $, config) {
});
});
- module.controller('DashFromElasticProvider', function($scope, $rootScope, elastic, $routeParams, alertSrv) {
+ module.controller('DashFromElasticProvider', function($scope, $rootScope, datasourceSrv, $routeParams, alertSrv) {
- var elasticsearch_load = function(id) {
- var url = '/dashboard/' + id;
-
- // hack to check if it is a temp dashboard
- if (window.location.href.indexOf('dashboard/temp') > 0) {
- url = '/temp/' + id;
- }
-
- return elastic.get(url)
- .then(function(result) {
- if (result._source && result._source.dashboard) {
- return angular.fromJson(result._source.dashboard);
- } else {
- return false;
- }
- }, function(data, status) {
- if(status === 0) {
- alertSrv.set('Error',"Could not contact Elasticsearch at " +
- config.elasticsearch + ". Please ensure that Elasticsearch is reachable from your browser.",'error');
- } else {
- alertSrv.set('Error',"Could not find dashboard " + id, 'error');
- }
- return false;
- });
- };
-
- elasticsearch_load($routeParams.id).then(function(dashboard) {
- $scope.emitAppEvent('setup-dashboard', dashboard);
- });
+ var db = datasourceSrv.getGrafanaDB();
+ db.getDashboard($routeParams.id)
+ .then(function(dashboard) {
+ $scope.emitAppEvent('setup-dashboard', dashboard);
+ }).then(null, function(error) {
+ alertSrv.set('Error', error, 'error');
+ });
});
diff --git a/src/app/services/all.js b/src/app/services/all.js
index b426088bd11..7f00219dbca 100644
--- a/src/app/services/all.js
+++ b/src/app/services/all.js
@@ -8,8 +8,7 @@ define([
'./annotationsSrv',
'./playlistSrv',
'./unsavedChangesSrv',
- './elasticsearch/es-client',
'./dashboard/dashboardKeyBindings',
'./dashboard/dashboardModel',
],
-function () {});
\ No newline at end of file
+function () {});
diff --git a/src/app/services/datasourceSrv.js b/src/app/services/datasourceSrv.js
index 705230515f8..97cf10cb6f9 100644
--- a/src/app/services/datasourceSrv.js
+++ b/src/app/services/datasourceSrv.js
@@ -16,6 +16,7 @@ function (angular, _, config) {
var datasources = {};
var metricSources = [];
var annotationSources = [];
+ var grafanaDB = {};
this.init = function() {
_.each(config.datasources, function(value, key) {
@@ -44,6 +45,9 @@ function (angular, _, config) {
editorSrc: value.annotationEditorSrc,
});
}
+ if (value.grafanaDB) {
+ grafanaDB = value;
+ }
});
};
@@ -82,6 +86,10 @@ function (angular, _, config) {
return metricSources;
};
+ this.getGrafanaDB = function() {
+ return grafanaDB;
+ };
+
this.init();
});
});
diff --git a/src/app/services/elasticsearch/es-client.js b/src/app/services/elasticsearch/es-client.js
deleted file mode 100644
index 5898bf8743f..00000000000
--- a/src/app/services/elasticsearch/es-client.js
+++ /dev/null
@@ -1,116 +0,0 @@
-define([
- 'angular',
- 'config'
-],
-function(angular, config) {
- "use strict";
-
- var module = angular.module('grafana.services');
-
- module.service('elastic', function($http, $q) {
-
- this._request = function(method, url, data) {
- var options = {
- url: config.elasticsearch + "/" + config.grafana_index + url,
- method: method,
- data: data
- };
-
- if (config.elasticsearchBasicAuth) {
- options.headers = {
- "Authorization": "Basic " + config.elasticsearchBasicAuth
- };
- }
-
- return $http(options);
- };
-
- this.get = function(url) {
- return this._request('GET', url)
- .then(function(results) {
- return results.data;
- });
- };
-
- this.post = function(url, data) {
- return this._request('POST', url, data)
- .then(function(results) {
- return results.data;
- });
- };
-
- this.deleteDashboard = function(id) {
- if (!this.isAdmin()) { return $q.reject("Invalid admin password"); }
-
- return this._request('DELETE', '/dashboard/' + id)
- .then(function(result) {
- return result.data._id;
- }, function(err) {
- throw err.data;
- });
- };
-
- this.saveForSharing = function(dashboard) {
- var data = {
- user: 'guest',
- group: 'guest',
- title: dashboard.title,
- tags: dashboard.tags,
- dashboard: angular.toJson(dashboard)
- };
-
- var ttl = dashboard.loader.save_temp_ttl;
-
- return this._request('POST', '/temp/?ttl=' + ttl, data)
- .then(function(result) {
-
- var baseUrl = window.location.href.replace(window.location.hash,'');
- var url = baseUrl + "#dashboard/temp/" + result.data._id;
-
- return { title: dashboard.title, url: url };
-
- }, function(err) {
- throw "Failed to save to temp dashboard to elasticsearch " + err.data;
- });
- };
-
- this.passwordCache = function(pwd) {
- if (!window.sessionStorage) { return null; }
- if (!pwd) { return window.sessionStorage["grafanaAdminPassword"]; }
- window.sessionStorage["grafanaAdminPassword"] = pwd;
- };
-
- this.isAdmin = function() {
- if (!config.admin || !config.admin.password) { return true; }
- if (this.passwordCache() === config.admin.password) { return true; }
-
- var password = window.prompt("Admin password", "");
- this.passwordCache(password);
-
- return password === config.admin.password;
- };
-
- this.saveDashboard = function(dashboard, title) {
- if (!this.isAdmin()) { return $q.reject("Invalid admin password"); }
-
- var dashboardClone = angular.copy(dashboard);
- title = dashboardClone.title = title ? title : dashboard.title;
-
- var data = {
- user: 'guest',
- group: 'guest',
- title: title,
- tags: dashboardClone.tags,
- dashboard: angular.toJson(dashboardClone)
- };
-
- return this._request('PUT', '/dashboard/' + encodeURIComponent(title), data)
- .then(function() {
- return { title: title, url: '/dashboard/elasticsearch/' + title };
- }, function(err) {
- throw 'Failed to save to elasticsearch ' + err.data;
- });
- };
-
- });
-});
diff --git a/src/app/services/elasticsearch/es-datasource.js b/src/app/services/elasticsearch/es-datasource.js
index 29291e029f3..1303bdd042e 100644
--- a/src/app/services/elasticsearch/es-datasource.js
+++ b/src/app/services/elasticsearch/es-datasource.js
@@ -21,16 +21,17 @@ function (angular, _, $, config, kbn, moment) {
this.supportAnnotations = true;
this.supportMetrics = false;
this.index = datasource.index;
+ this.grafanaDB = datasource.grafanaDB;
this.annotationEditorSrc = 'app/partials/elasticsearch/annotation_editor.html';
}
- ElasticDatasource.prototype._request = function(method, url, data) {
+ ElasticDatasource.prototype._request = function(method, url, index, data) {
var options = {
- url: this.url + "/" + this.index + url,
+ url: this.url + "/" + index + url,
method: method,
data: data
};
-
+ // TODO: fix basic auth
if (config.elasticsearchBasicAuth) {
options.headers = {
"Authorization": "Basic " + config.elasticsearchBasicAuth
@@ -41,14 +42,14 @@ function (angular, _, $, config, kbn, moment) {
};
ElasticDatasource.prototype._get = function(url) {
- return this._request('GET', url)
+ return this._request('GET', url, this.index)
.then(function(results) {
return results.data;
});
};
ElasticDatasource.prototype._post = function(url, data) {
- return this._request('POST', url, data)
+ return this._request('POST', url, this.index, data)
.then(function(results) {
return results.data;
});
@@ -71,9 +72,7 @@ function (angular, _, $, config, kbn, moment) {
var query = { "bool": { "should": [{ "query_string": { "query": queryString } }] } };
var data = { "query" : { "filtered": { "query" : query, "filter": filter } }, "size": 100 };
- this.index = annotation.index;
-
- return this._request('POST', '/_search', data).then(function(results) {
+ return this._request('POST', '/_search', annotation.index, data).then(function(results) {
var list = [];
var hits = results.data.hits.hits;
@@ -103,6 +102,116 @@ function (angular, _, $, config, kbn, moment) {
});
};
+ ElasticDatasource.prototype.getDashboard = function(id) {
+ var url = '/dashboard/' + id;
+
+ // hack to check if it is a temp dashboard
+ if (window.location.href.indexOf('dashboard/temp') > 0) {
+ url = '/temp/' + id;
+ }
+
+ return this._get(url)
+ .then(function(result) {
+ if (result._source && result._source.dashboard) {
+ return angular.fromJson(result._source.dashboard);
+ } else {
+ return false;
+ }
+ }, function(data, status) {
+ if(status === 0) {
+ throw "Could not contact Elasticsearch. Please ensure that Elasticsearch is reachable from your browser.";
+ } else {
+ throw "Could not find dashboard " + id;
+ }
+ });
+ };
+
+ ElasticDatasource.prototype.saveDashboard = function(dashboard, title) {
+ var dashboardClone = angular.copy(dashboard);
+ title = dashboardClone.title = title ? title : dashboard.title;
+
+ var data = {
+ user: 'guest',
+ group: 'guest',
+ title: title,
+ tags: dashboardClone.tags,
+ dashboard: angular.toJson(dashboardClone)
+ };
+
+ return this._request('PUT', '/dashboard/' + encodeURIComponent(title), this.index, data)
+ .then(function() {
+ return { title: title, url: '/dashboard/elasticsearch/' + title };
+ }, function(err) {
+ throw 'Failed to save to elasticsearch ' + err.data;
+ });
+ };
+
+ ElasticDatasource.prototype.saveDashboardTemp = function(dashboard) {
+ var data = {
+ user: 'guest',
+ group: 'guest',
+ title: dashboard.title,
+ tags: dashboard.tags,
+ dashboard: angular.toJson(dashboard)
+ };
+
+ var ttl = dashboard.loader.save_temp_ttl;
+
+ return this._request('POST', '/temp/?ttl=' + ttl, this.index, data)
+ .then(function(result) {
+
+ var baseUrl = window.location.href.replace(window.location.hash,'');
+ var url = baseUrl + "#dashboard/temp/" + result.data._id;
+
+ return { title: dashboard.title, url: url };
+
+ }, function(err) {
+ throw "Failed to save to temp dashboard to elasticsearch " + err.data;
+ });
+ };
+
+ ElasticDatasource.prototype.deleteDashboard = function(id) {
+ return this._request('DELETE', '/dashboard/' + id, this.index)
+ .then(function(result) {
+ return result.data._id;
+ }, function(err) {
+ throw err.data;
+ });
+ };
+
+ ElasticDatasource.prototype.searchDashboards = function(queryString) {
+ var tagsOnly = queryString.indexOf('tags!:') === 0;
+ if (tagsOnly) {
+ var tagsQuery = queryString.substring(6, queryString.length);
+ queryString = 'tags:' + tagsQuery + '*';
+ }
+ else {
+ if (queryString.length === 0) {
+ queryString = 'title:';
+ }
+
+ if (queryString[queryString.length - 1] !== '*') {
+ queryString += '*';
+ }
+ }
+
+ var query = {
+ query: { query_string: { query: queryString } },
+ facets: { tags: { terms: { field: "tags", order: "term", size: 50 } } },
+ size: 20,
+ sort: ["_uid"]
+ };
+
+ return this._post('/dashboard/_search', query)
+ .then(function(results) {
+ if(_.isUndefined(results.hits)) {
+ return { dashboards: [], tags: [] };
+ }
+
+ return { dashboards: results.hits.hits, tags: results.facets.terms };
+ });
+ };
+
return ElasticDatasource;
});