Refresh frontend datasourceSrv after datasource update, no longer need to reload the page to use a newly added or updated datasource, #1493

This commit is contained in:
Torkel Ödegaard 2015-02-18 14:06:44 +01:00
parent 4ed54f6aa9
commit 60ae4afe87
8 changed files with 94 additions and 99 deletions

View File

@ -78,6 +78,7 @@ func Register(r *macaron.Macaron) {
r.Get("/:id", GetDataSourceById) r.Get("/:id", GetDataSourceById)
}, reqAccountAdmin) }, reqAccountAdmin)
r.Get("/frontend/settings/", GetFrontendSettings)
r.Any("/datasources/proxy/:id/*", reqSignedIn, ProxyDataSourceRequest) r.Any("/datasources/proxy/:id/*", reqSignedIn, ProxyDataSourceRequest)
// Dashboard // Dashboard

View File

@ -9,7 +9,7 @@ import (
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
) )
func getFrontendSettings(c *middleware.Context) (map[string]interface{}, error) { func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, error) {
accountDataSources := make([]*m.DataSource, 0) accountDataSources := make([]*m.DataSource, 0)
if c.IsSignedIn { if c.IsSignedIn {
@ -71,3 +71,13 @@ func getFrontendSettings(c *middleware.Context) (map[string]interface{}, error)
return jsonObj, nil return jsonObj, nil
} }
func GetFrontendSettings(c *middleware.Context) {
settings, err := getFrontendSettingsMap(c)
if err != nil {
c.JsonApiErr(400, "Failed to get frontend settings", err)
return
}
c.JSON(200, settings)
}

View File

@ -7,7 +7,7 @@ import (
) )
func setIndexViewData(c *middleware.Context) error { func setIndexViewData(c *middleware.Context) error {
settings, err := getFrontendSettings(c) settings, err := getFrontendSettingsMap(c)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,8 +1,7 @@
define([ define([
'lodash', 'lodash',
'crypto',
], ],
function (_, crypto) { function (_) {
"use strict"; "use strict";
return function Settings (options) { return function Settings (options) {
@ -32,49 +31,31 @@ function (_, crypto) {
var settings = _.extend({}, defaults, options); var settings = _.extend({}, defaults, options);
var parseBasicAuth = function(datasource) { // var parseBasicAuth = function(datasource) {
var passwordEnd = datasource.url.indexOf('@'); // var passwordEnd = datasource.url.indexOf('@');
if (passwordEnd > 0) { // if (passwordEnd > 0) {
var userStart = datasource.url.indexOf('//') + 2; // var userStart = datasource.url.indexOf('//') + 2;
var userAndPassword = datasource.url.substring(userStart, passwordEnd); // var userAndPassword = datasource.url.substring(userStart, passwordEnd);
var bytes = crypto.charenc.Binary.stringToBytes(userAndPassword); // var bytes = crypto.charenc.Binary.stringToBytes(userAndPassword);
datasource.basicAuth = crypto.util.bytesToBase64(bytes); // datasource.basicAuth = crypto.util.bytesToBase64(bytes);
//
var urlHead = datasource.url.substring(0, userStart); // var urlHead = datasource.url.substring(0, userStart);
datasource.url = urlHead + datasource.url.substring(passwordEnd + 1); // datasource.url = urlHead + datasource.url.substring(passwordEnd + 1);
} // }
//
return datasource; // return datasource;
}; // };
//
var parseMultipleHosts = function(datasource) { // var parseMultipleHosts = function(datasource) {
datasource.urls = _.map(datasource.url.split(","), function (url) { return url.trim(); }); // datasource.urls = _.map(datasource.url.split(","), function (url) { return url.trim(); });
return datasource; // return datasource;
}; // };
//
// backward compatible with old config // _.each(settings.datasources, function(datasource, key) {
if (options.graphiteUrl) { // datasource.name = key;
settings.datasources.graphite = { // if (datasource.url) { parseBasicAuth(datasource); }
type: 'graphite', // if (datasource.type === 'influxdb') { parseMultipleHosts(datasource); }
url: options.graphiteUrl, // });
default: true
};
}
if (options.elasticsearch) {
settings.datasources.elasticsearch = {
type: 'elasticsearch',
url: options.elasticsearch,
index: options.grafana_index,
grafanaDB: true
};
}
_.each(settings.datasources, function(datasource, key) {
datasource.name = key;
if (datasource.url) { parseBasicAuth(datasource); }
if (datasource.type === 'influxdb') { parseMultipleHosts(datasource); }
});
if (settings.plugins.panels) { if (settings.plugins.panels) {
_.extend(settings.panels, settings.plugins.panels); _.extend(settings.panels, settings.plugins.panels);

View File

@ -7,7 +7,7 @@ function (angular) {
var module = angular.module('grafana.controllers'); var module = angular.module('grafana.controllers');
module.controller('DataSourceEditCtrl', function($scope, $http, backendSrv, $routeParams, $location) { module.controller('DataSourceEditCtrl', function($scope, $http, backendSrv, $routeParams, $location, datasourceSrv) {
var defaults = { var defaults = {
name: '', name: '',
@ -41,12 +41,19 @@ function (angular) {
}); });
}; };
$scope.updateFrontendSettings = function() {
backendSrv.get('/api/frontend/settings').then(function(settings) {
datasourceSrv.init(settings.datasources);
});
};
$scope.update = function() { $scope.update = function() {
if (!$scope.editForm.$valid) { if (!$scope.editForm.$valid) {
return; return;
} }
backendSrv.post('/api/datasources', $scope.current).then(function() { backendSrv.post('/api/datasources', $scope.current).then(function() {
$scope.updateFrontendSettings();
$location.path("account/datasources"); $location.path("account/datasources");
}); });
}; };
@ -56,10 +63,10 @@ function (angular) {
return; return;
} }
backendSrv.put('/api/datasources', $scope.current) backendSrv.put('/api/datasources', $scope.current).then(function() {
.then(function() { $scope.updateFrontendSettings();
$scope.getDatasources(); $location.path("account/datasources");
}); });
}; };
$scope.init(); $scope.init();

View File

@ -7,7 +7,7 @@ function (angular) {
var module = angular.module('grafana.controllers'); var module = angular.module('grafana.controllers');
module.controller('DataSourcesCtrl', function($scope, $http, backendSrv) { module.controller('DataSourcesCtrl', function($scope, $http, backendSrv, datasourceSrv) {
$scope.init = function() { $scope.init = function() {
$scope.datasources = []; $scope.datasources = [];
@ -23,6 +23,10 @@ function (angular) {
$scope.remove = function(ds) { $scope.remove = function(ds) {
backendSrv.delete('/api/datasources/' + ds.id).then(function() { backendSrv.delete('/api/datasources/' + ds.id).then(function() {
$scope.getDatasources(); $scope.getDatasources();
backendSrv.get('/api/frontend/settings').then(function(settings) {
datasourceSrv.init(settings.datasources);
});
}); });
}; };

View File

@ -6,7 +6,7 @@ function (angular) {
var module = angular.module('grafana.controllers'); var module = angular.module('grafana.controllers');
module.controller('AdminEditUserCtrl', function($scope, $routeParams, backendSrv) { module.controller('AdminEditUserCtrl', function($scope, $routeParams, backendSrv, $location) {
$scope.user = {}; $scope.user = {};
$scope.init = function() { $scope.init = function() {
@ -28,9 +28,13 @@ function (angular) {
$scope.update = function() { $scope.update = function() {
if (!$scope.userForm.$valid) { return; } if (!$scope.userForm.$valid) { return; }
if ($scope.createMode) { if ($scope.createMode) {
backendSrv.post('/api/admin/users', $scope.user); backendSrv.post('/api/admin/users', $scope.user).then(function() {
$location.path('/admin/users');
});
} else { } else {
backendSrv.put('/api/admin/users/' + $scope.user_id, $scope.user); backendSrv.put('/api/admin/users/' + $scope.user_id, $scope.user).then(function() {
$location.path('/admin/users');
});
} }
}; };

View File

@ -7,97 +7,85 @@ function (angular, _, config) {
'use strict'; 'use strict';
var module = angular.module('grafana.services'); var module = angular.module('grafana.services');
var typeMap = {
'graphite': 'GraphiteDatasource',
'influxdb': 'InfluxDatasource',
'elasticsearch': 'ElasticDatasource',
'opentsdb': 'OpenTSDBDatasource',
'grafana': 'GrafanaDatasource',
};
module.service('datasourceSrv', function($q, $http, $injector) { module.service('datasourceSrv', function($q, $http, $injector) {
var datasources = {};
var metricSources = [];
var annotationSources = [];
var grafanaDB = {};
this.init = function() { this.init = function(dsSettingList) {
_.each(config.datasources, function(value, key) { config.datasources = dsSettingList;
this.datasources = {};
this.metricSources = [];
this.annotationSources = [];
_.each(dsSettingList, function(value, key) {
var ds = this.datasourceFactory(value); var ds = this.datasourceFactory(value);
ds.name = key;
if (value.default) { if (value.default) {
this.default = ds; this.default = ds;
ds.default = true; ds.default = true;
} }
datasources[key] = ds; this.datasources[key] = ds;
}, this); }, this);
if (!this.default) { if (!this.default) {
this.default = datasources[_.keys(datasources)[0]]; this.default = this.datasources[_.keys(this.datasources)[0]];
this.default.default = true; this.default.default = true;
} }
// create list of different source types // create list of different source types
_.each(datasources, function(value, key) { _.each(this.datasources, function(value, key) {
if (value.supportMetrics) { if (value.supportMetrics) {
metricSources.push({ this.metricSources.push({
name: value.name, name: value.name,
value: value.default ? null : key, value: value.default ? null : key,
default: value.default, default: value.default,
}); });
} }
if (value.supportAnnotations) { if (value.supportAnnotations) {
annotationSources.push({ this.annotationSources.push({ name: key, editorSrc: value.annotationEditorSrc });
name: key,
editorSrc: value.annotationEditorSrc,
});
} }
if (value.grafanaDB) { if (value.grafanaDB) {
grafanaDB = value; this.grafanaDB = value;
} }
}); }, this);
}; };
this.datasourceFactory = function(ds) { this.datasourceFactory = function(ds) {
var Datasource = null; var type = typeMap[ds.type] || ds.type;
switch(ds.type) { var Datasource = $injector.get(type);
case 'graphite':
Datasource = $injector.get('GraphiteDatasource');
break;
case 'influxdb':
Datasource = $injector.get('InfluxDatasource');
break;
case 'opentsdb':
Datasource = $injector.get('OpenTSDBDatasource');
break;
case 'elasticsearch':
Datasource = $injector.get('ElasticDatasource');
break;
case 'grafana':
Datasource = $injector.get('GrafanaDatasource');
break;
default:
Datasource = $injector.get(ds.type);
}
return new Datasource(ds); return new Datasource(ds);
}; };
this.get = function(name) { this.get = function(name) {
if (!name) { return this.default; } if (!name) { return this.default; }
if (datasources[name]) { return datasources[name]; } if (this.datasources[name]) { return this.datasources[name]; }
return this.default; return this.default;
}; };
this.getAll = function() { this.getAll = function() {
return datasources; return this.datasources;
}; };
this.getAnnotationSources = function() { this.getAnnotationSources = function() {
return annotationSources; return this.annotationSources;
}; };
this.getMetricSources = function() { this.getMetricSources = function() {
return metricSources; return this.metricSources;
}; };
this.getGrafanaDB = function() { this.getGrafanaDB = function() {
return grafanaDB; return this.grafanaDB;
}; };
this.init(); this.init(config.datasources);
}); });
}); });