diff --git a/pkg/api/api.go b/pkg/api/api.go index f79c0661d55..b61517c9d56 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -78,6 +78,7 @@ func Register(r *macaron.Macaron) { r.Get("/:id", GetDataSourceById) }, reqAccountAdmin) + r.Get("/frontend/settings/", GetFrontendSettings) r.Any("/datasources/proxy/:id/*", reqSignedIn, ProxyDataSourceRequest) // Dashboard diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index 071852a5e8e..bc909ca8ba1 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -9,7 +9,7 @@ import ( "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) if c.IsSignedIn { @@ -71,3 +71,13 @@ func getFrontendSettings(c *middleware.Context) (map[string]interface{}, error) 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) +} diff --git a/pkg/api/index.go b/pkg/api/index.go index 98860b26e6a..c63e65e5a39 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -7,7 +7,7 @@ import ( ) func setIndexViewData(c *middleware.Context) error { - settings, err := getFrontendSettings(c) + settings, err := getFrontendSettingsMap(c) if err != nil { return err } diff --git a/src/app/components/settings.js b/src/app/components/settings.js index 078b5519420..158d255a635 100644 --- a/src/app/components/settings.js +++ b/src/app/components/settings.js @@ -1,8 +1,7 @@ define([ 'lodash', - 'crypto', ], -function (_, crypto) { +function (_) { "use strict"; return function Settings (options) { @@ -32,49 +31,31 @@ function (_, crypto) { var settings = _.extend({}, defaults, options); - var parseBasicAuth = function(datasource) { - var passwordEnd = datasource.url.indexOf('@'); - if (passwordEnd > 0) { - var userStart = datasource.url.indexOf('//') + 2; - var userAndPassword = datasource.url.substring(userStart, passwordEnd); - var bytes = crypto.charenc.Binary.stringToBytes(userAndPassword); - datasource.basicAuth = crypto.util.bytesToBase64(bytes); - - var urlHead = datasource.url.substring(0, userStart); - datasource.url = urlHead + datasource.url.substring(passwordEnd + 1); - } - - return datasource; - }; - - var parseMultipleHosts = function(datasource) { - datasource.urls = _.map(datasource.url.split(","), function (url) { return url.trim(); }); - return datasource; - }; - - // backward compatible with old config - if (options.graphiteUrl) { - settings.datasources.graphite = { - type: 'graphite', - 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); } - }); + // var parseBasicAuth = function(datasource) { + // var passwordEnd = datasource.url.indexOf('@'); + // if (passwordEnd > 0) { + // var userStart = datasource.url.indexOf('//') + 2; + // var userAndPassword = datasource.url.substring(userStart, passwordEnd); + // var bytes = crypto.charenc.Binary.stringToBytes(userAndPassword); + // datasource.basicAuth = crypto.util.bytesToBase64(bytes); + // + // var urlHead = datasource.url.substring(0, userStart); + // datasource.url = urlHead + datasource.url.substring(passwordEnd + 1); + // } + // + // return datasource; + // }; + // + // var parseMultipleHosts = function(datasource) { + // datasource.urls = _.map(datasource.url.split(","), function (url) { return url.trim(); }); + // return datasource; + // }; + // + // _.each(settings.datasources, function(datasource, key) { + // datasource.name = key; + // if (datasource.url) { parseBasicAuth(datasource); } + // if (datasource.type === 'influxdb') { parseMultipleHosts(datasource); } + // }); if (settings.plugins.panels) { _.extend(settings.panels, settings.plugins.panels); diff --git a/src/app/features/account/datasourceEditCtrl.js b/src/app/features/account/datasourceEditCtrl.js index 389bf8bc7a8..5366cd05aa5 100644 --- a/src/app/features/account/datasourceEditCtrl.js +++ b/src/app/features/account/datasourceEditCtrl.js @@ -7,7 +7,7 @@ function (angular) { 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 = { 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() { if (!$scope.editForm.$valid) { return; } backendSrv.post('/api/datasources', $scope.current).then(function() { + $scope.updateFrontendSettings(); $location.path("account/datasources"); }); }; @@ -56,10 +63,10 @@ function (angular) { return; } - backendSrv.put('/api/datasources', $scope.current) - .then(function() { - $scope.getDatasources(); - }); + backendSrv.put('/api/datasources', $scope.current).then(function() { + $scope.updateFrontendSettings(); + $location.path("account/datasources"); + }); }; $scope.init(); diff --git a/src/app/features/account/datasourcesCtrl.js b/src/app/features/account/datasourcesCtrl.js index 00a906ba64e..da77df252e1 100644 --- a/src/app/features/account/datasourcesCtrl.js +++ b/src/app/features/account/datasourcesCtrl.js @@ -7,7 +7,7 @@ function (angular) { 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.datasources = []; @@ -23,6 +23,10 @@ function (angular) { $scope.remove = function(ds) { backendSrv.delete('/api/datasources/' + ds.id).then(function() { $scope.getDatasources(); + + backendSrv.get('/api/frontend/settings').then(function(settings) { + datasourceSrv.init(settings.datasources); + }); }); }; diff --git a/src/app/features/admin/adminEditUserCtrl.js b/src/app/features/admin/adminEditUserCtrl.js index d01d5d8559d..86b59c4599b 100644 --- a/src/app/features/admin/adminEditUserCtrl.js +++ b/src/app/features/admin/adminEditUserCtrl.js @@ -6,7 +6,7 @@ function (angular) { var module = angular.module('grafana.controllers'); - module.controller('AdminEditUserCtrl', function($scope, $routeParams, backendSrv) { + module.controller('AdminEditUserCtrl', function($scope, $routeParams, backendSrv, $location) { $scope.user = {}; $scope.init = function() { @@ -28,9 +28,13 @@ function (angular) { $scope.update = function() { if (!$scope.userForm.$valid) { return; } if ($scope.createMode) { - backendSrv.post('/api/admin/users', $scope.user); + backendSrv.post('/api/admin/users', $scope.user).then(function() { + $location.path('/admin/users'); + }); } 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'); + }); } }; diff --git a/src/app/services/datasourceSrv.js b/src/app/services/datasourceSrv.js index 1a2c4db5f35..9855bec7804 100644 --- a/src/app/services/datasourceSrv.js +++ b/src/app/services/datasourceSrv.js @@ -7,97 +7,85 @@ function (angular, _, config) { 'use strict'; 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) { - var datasources = {}; - var metricSources = []; - var annotationSources = []; - var grafanaDB = {}; - this.init = function() { - _.each(config.datasources, function(value, key) { + this.init = function(dsSettingList) { + config.datasources = dsSettingList; + + this.datasources = {}; + this.metricSources = []; + this.annotationSources = []; + + _.each(dsSettingList, function(value, key) { var ds = this.datasourceFactory(value); + ds.name = key; if (value.default) { this.default = ds; ds.default = true; } - datasources[key] = ds; + this.datasources[key] = ds; }, this); if (!this.default) { - this.default = datasources[_.keys(datasources)[0]]; + this.default = this.datasources[_.keys(this.datasources)[0]]; this.default.default = true; } // create list of different source types - _.each(datasources, function(value, key) { + _.each(this.datasources, function(value, key) { if (value.supportMetrics) { - metricSources.push({ + this.metricSources.push({ name: value.name, value: value.default ? null : key, default: value.default, }); } if (value.supportAnnotations) { - annotationSources.push({ - name: key, - editorSrc: value.annotationEditorSrc, - }); + this.annotationSources.push({ name: key, editorSrc: value.annotationEditorSrc }); } if (value.grafanaDB) { - grafanaDB = value; + this.grafanaDB = value; } - }); - + }, this); }; this.datasourceFactory = function(ds) { - var Datasource = null; - switch(ds.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); - } + var type = typeMap[ds.type] || ds.type; + var Datasource = $injector.get(type); return new Datasource(ds); }; this.get = function(name) { if (!name) { return this.default; } - if (datasources[name]) { return datasources[name]; } + if (this.datasources[name]) { return this.datasources[name]; } return this.default; }; this.getAll = function() { - return datasources; + return this.datasources; }; this.getAnnotationSources = function() { - return annotationSources; + return this.annotationSources; }; this.getMetricSources = function() { - return metricSources; + return this.metricSources; }; this.getGrafanaDB = function() { - return grafanaDB; + return this.grafanaDB; }; - this.init(); + this.init(config.datasources); }); });