浏览代码

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

Torkel Ödegaard 11 年之前
父节点
当前提交
60ae4afe87

+ 1 - 0
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

+ 11 - 1
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)
+}

+ 1 - 1
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
 	}

+ 26 - 45
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);

+ 12 - 5
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();

+ 5 - 1
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);
+        });
       });
     };
 

+ 7 - 3
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');
+        });
       }
     };
 

+ 31 - 43
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);
   });
 });