mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
A lot of work on backend plugin model for frontend components, right now for data sources, will enable dropin plugins for data sources and panels, #1472
This commit is contained in:
parent
5bd5713a52
commit
c198242292
@ -40,7 +40,7 @@ type DataSource struct {
|
||||
Id int64 `json:"id"`
|
||||
OrgId int64 `json:"orgId"`
|
||||
Name string `json:"name"`
|
||||
Type m.DsType `json:"type"`
|
||||
Type string `json:"type"`
|
||||
Access m.DsAccess `json:"access"`
|
||||
Url string `json:"url"`
|
||||
Password string `json:"password"`
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
@ -38,6 +39,13 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
|
||||
"url": url,
|
||||
}
|
||||
|
||||
meta, exists := plugins.DataSources[ds.Type]
|
||||
if !exists {
|
||||
//return nil, errors.New(fmt.Sprintf("Could not find plugin definition for data source: %v", ds.Type))
|
||||
}
|
||||
|
||||
dsMap["meta"] = meta
|
||||
|
||||
if ds.IsDefault {
|
||||
defaultDatasource = ds.Name
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ func createDataSource(c *cli.Context) {
|
||||
OrgId: orgId,
|
||||
Name: ds,
|
||||
Url: url,
|
||||
Type: m.DsType(dsType),
|
||||
Type: dsType,
|
||||
Access: m.DsAccess(dsAccess),
|
||||
IsDefault: dsDefault,
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/eventpublisher"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/social"
|
||||
@ -74,6 +75,7 @@ func runWeb(c *cli.Context) {
|
||||
|
||||
social.NewOAuthService()
|
||||
eventpublisher.Init()
|
||||
plugins.Init()
|
||||
|
||||
var err error
|
||||
m := newMacaron()
|
||||
|
@ -20,7 +20,6 @@ var (
|
||||
ErrDataSourceNotFound = errors.New("Data source not found")
|
||||
)
|
||||
|
||||
type DsType string
|
||||
type DsAccess string
|
||||
|
||||
type DataSource struct {
|
||||
@ -29,7 +28,7 @@ type DataSource struct {
|
||||
Version int
|
||||
|
||||
Name string
|
||||
Type DsType
|
||||
Type string
|
||||
Access DsAccess
|
||||
Url string
|
||||
Password string
|
||||
@ -51,7 +50,7 @@ type DataSource struct {
|
||||
type AddDataSourceCommand struct {
|
||||
OrgId int64 `json:"-"`
|
||||
Name string
|
||||
Type DsType
|
||||
Type string
|
||||
Access DsAccess
|
||||
Url string
|
||||
Password string
|
||||
@ -67,7 +66,7 @@ type UpdateDataSourceCommand struct {
|
||||
Id int64
|
||||
OrgId int64
|
||||
Name string
|
||||
Type DsType
|
||||
Type string
|
||||
Access DsAccess
|
||||
Url string
|
||||
Password string
|
||||
|
@ -4,9 +4,11 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
type PluginMeta struct {
|
||||
@ -15,7 +17,7 @@ type PluginMeta struct {
|
||||
}
|
||||
|
||||
var (
|
||||
List []*PluginMeta
|
||||
DataSources map[string]interface{}
|
||||
)
|
||||
|
||||
type PluginScanner struct {
|
||||
@ -23,8 +25,12 @@ type PluginScanner struct {
|
||||
errors []error
|
||||
}
|
||||
|
||||
func Scan(pluginDir string) error {
|
||||
List = make([]*PluginMeta, 0)
|
||||
func Init() {
|
||||
scan(path.Join(setting.StaticRootPath, "app/plugins"))
|
||||
}
|
||||
|
||||
func scan(pluginDir string) error {
|
||||
DataSources = make(map[string]interface{})
|
||||
|
||||
scanner := &PluginScanner{
|
||||
pluginPath: pluginDir,
|
||||
@ -51,31 +57,43 @@ func (scanner *PluginScanner) walker(path string, f os.FileInfo, err error) erro
|
||||
}
|
||||
|
||||
if f.Name() == "plugin.json" {
|
||||
pluginMeta, err := loadPluginMeta(path)
|
||||
err := scanner.loadPluginJson(path)
|
||||
if err != nil {
|
||||
log.Error(3, "Failed to load plugin json file: %v, err: %v", path, err)
|
||||
scanner.errors = append(scanner.errors, err)
|
||||
} else {
|
||||
List = append(List, pluginMeta)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadPluginMeta(path string) (*PluginMeta, error) {
|
||||
func (scanner *PluginScanner) loadPluginJson(path string) error {
|
||||
reader, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
defer reader.Close()
|
||||
|
||||
jsonParser := json.NewDecoder(reader)
|
||||
|
||||
pluginMeta := &PluginMeta{}
|
||||
if err := jsonParser.Decode(pluginMeta); err != nil {
|
||||
return nil, err
|
||||
pluginJson := make(map[string]interface{})
|
||||
if err := jsonParser.Decode(&pluginJson); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return pluginMeta, nil
|
||||
pluginType, exists := pluginJson["pluginType"]
|
||||
if !exists {
|
||||
return errors.New("Did not find pluginType property in plugin.json")
|
||||
}
|
||||
|
||||
if pluginType == "datasource" {
|
||||
datasourceType, exists := pluginJson["type"]
|
||||
if !exists {
|
||||
return errors.New("Did not find type property in plugin.json")
|
||||
}
|
||||
|
||||
DataSources[datasourceType.(string)] = pluginJson
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -11,9 +11,9 @@ func TestPluginScans(t *testing.T) {
|
||||
|
||||
Convey("When scaning for plugins", t, func() {
|
||||
path, _ := filepath.Abs("../../src/app/plugins")
|
||||
err := Scan(path)
|
||||
err := scan(path)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(len(List), ShouldEqual, 1)
|
||||
So(len(DataSources), ShouldEqual, 1)
|
||||
})
|
||||
}
|
||||
|
@ -97,10 +97,6 @@ function (angular, $, _, appLevelRequire, config) {
|
||||
'routes/backend/all',
|
||||
];
|
||||
|
||||
_.each(config.plugins.dependencies, function(dep) {
|
||||
preBootRequires.push('../plugins/' + dep);
|
||||
});
|
||||
|
||||
app.boot = function() {
|
||||
require(preBootRequires, function () {
|
||||
|
||||
|
@ -52,14 +52,6 @@ function (_) {
|
||||
// if (datasource.type === 'influxdb') { parseMultipleHosts(datasource); }
|
||||
// });
|
||||
|
||||
if (settings.plugins.panels) {
|
||||
_.extend(settings.panels, settings.plugins.panels);
|
||||
}
|
||||
|
||||
if (!settings.plugins.dependencies) {
|
||||
settings.plugins.dependencies = [];
|
||||
}
|
||||
|
||||
return settings;
|
||||
};
|
||||
});
|
||||
|
@ -57,12 +57,10 @@ function (angular, _, config) {
|
||||
|
||||
$scope.setDatasource = function(datasource) {
|
||||
$scope.panel.datasource = datasource;
|
||||
$scope.datasource = datasourceSrv.get(datasource);
|
||||
|
||||
if (!$scope.datasource) {
|
||||
$scope.panelMeta.error = "Cannot find datasource " + datasource;
|
||||
return;
|
||||
}
|
||||
debugger;
|
||||
datasourceSrv.get(datasource).then(function(ds) {
|
||||
$scope.datasource = ds;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.changeDatasource = function(datasource) {
|
||||
@ -90,28 +88,37 @@ function (angular, _, config) {
|
||||
return $scope.dashboardViewState.fullscreen && !$scope.fullscreen;
|
||||
};
|
||||
|
||||
$scope.get_data = function() {
|
||||
if ($scope.otherPanelInFullscreenMode()) { return; }
|
||||
|
||||
delete $scope.panelMeta.error;
|
||||
$scope.panelMeta.loading = true;
|
||||
|
||||
if ($scope.datasource) {
|
||||
return $scope.refreshData($scope.datasource);
|
||||
}
|
||||
|
||||
datasourceSrv.get($scope.panel.datasource).then(function(datasource) {
|
||||
$scope.datasource = datasource;
|
||||
return $scope.refreshData($scope.datasource);
|
||||
});
|
||||
};
|
||||
|
||||
if ($scope.refreshData) {
|
||||
$scope.$on("refresh", $scope.get_data);
|
||||
}
|
||||
|
||||
// Post init phase
|
||||
$scope.fullscreen = false;
|
||||
$scope.editor = { index: 1 };
|
||||
|
||||
// $scope.datasources = datasourceSrv.getMetricSources();
|
||||
// $scope.setDatasource($scope.panel.datasource);
|
||||
$scope.dashboardViewState.registerPanel($scope);
|
||||
$scope.datasources = datasourceSrv.getMetricSources();
|
||||
|
||||
if ($scope.get_data) {
|
||||
var panel_get_data = $scope.get_data;
|
||||
$scope.get_data = function() {
|
||||
if ($scope.otherPanelInFullscreenMode()) { return; }
|
||||
|
||||
delete $scope.panelMeta.error;
|
||||
$scope.panelMeta.loading = true;
|
||||
|
||||
panel_get_data();
|
||||
};
|
||||
|
||||
if (!$scope.skipDataOnInit) {
|
||||
if (!$scope.skipDataOnInit) {
|
||||
$timeout(function() {
|
||||
$scope.get_data();
|
||||
}
|
||||
}, 30);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -47,11 +47,9 @@ function (angular, app, _, config, PanelMeta) {
|
||||
if ($scope.isNewPanel()) {
|
||||
$scope.panel.title = "Starred Dashboards";
|
||||
}
|
||||
|
||||
$scope.$on('refresh', $scope.get_data);
|
||||
};
|
||||
|
||||
$scope.get_data = function() {
|
||||
$scope.refreshData = function() {
|
||||
var params = {
|
||||
limit: $scope.panel.limit
|
||||
};
|
||||
|
@ -51,10 +51,6 @@ function (angular, $, kbn, moment, _, GraphTooltip) {
|
||||
}
|
||||
});
|
||||
|
||||
scope.$on('refresh', function() {
|
||||
scope.get_data();
|
||||
});
|
||||
|
||||
// Receive render events
|
||||
scope.$on('render',function(event, renderData) {
|
||||
data = renderData || data;
|
||||
|
@ -23,7 +23,7 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
|
||||
};
|
||||
});
|
||||
|
||||
module.controller('GraphCtrl', function($scope, $rootScope, panelSrv, annotationsSrv, timeSrv, datasourceSrv) {
|
||||
module.controller('GraphCtrl', function($scope, $rootScope, panelSrv, annotationsSrv, timeSrv) {
|
||||
|
||||
$scope.panelMeta = new PanelMeta({
|
||||
panelName: 'Graph',
|
||||
@ -169,7 +169,7 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
|
||||
$scope.interval = kbn.calculateInterval($scope.range, $scope.resolution, $scope.panel.interval);
|
||||
};
|
||||
|
||||
$scope.get_data = function() {
|
||||
$scope.refreshData = function(datasource) {
|
||||
$scope.updateTimeRange();
|
||||
|
||||
var metricsQuery = {
|
||||
@ -183,17 +183,15 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
|
||||
|
||||
$scope.annotationsPromise = annotationsSrv.getAnnotations($scope.rangeUnparsed, $scope.dashboard);
|
||||
|
||||
return datasourceSrv.get($scope.panel.datasource).then(function(ds) {
|
||||
return ds.query(metricsQuery)
|
||||
.then($scope.dataHandler)
|
||||
.then(null, function(err) {
|
||||
$scope.panelMeta.loading = false;
|
||||
$scope.panelMeta.error = err.message || "Timeseries data request error";
|
||||
$scope.inspector.error = err;
|
||||
$scope.seriesList = [];
|
||||
$scope.render([]);
|
||||
});
|
||||
});
|
||||
return datasource.query(metricsQuery)
|
||||
.then($scope.dataHandler)
|
||||
.then(null, function(err) {
|
||||
$scope.panelMeta.loading = false;
|
||||
$scope.panelMeta.error = err.message || "Timeseries data request error";
|
||||
$scope.inspector.error = err;
|
||||
$scope.seriesList = [];
|
||||
$scope.render([]);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.dataHandler = function(results) {
|
||||
@ -230,8 +228,8 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
|
||||
|
||||
var series = new TimeSeries({
|
||||
datapoints: datapoints,
|
||||
alias: alias,
|
||||
color: color,
|
||||
alias: alias,
|
||||
color: color,
|
||||
});
|
||||
|
||||
if (datapoints && datapoints.length > 0) {
|
||||
|
@ -74,7 +74,6 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
|
||||
|
||||
$scope.init = function() {
|
||||
panelSrv.init($scope);
|
||||
$scope.$on('refresh', $scope.get_data);
|
||||
};
|
||||
|
||||
$scope.updateTimeRange = function () {
|
||||
@ -84,7 +83,7 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
|
||||
$scope.interval = kbn.calculateInterval($scope.range, $scope.resolution, $scope.panel.interval);
|
||||
};
|
||||
|
||||
$scope.get_data = function() {
|
||||
$scope.refreshData = function(datasource) {
|
||||
$scope.updateTimeRange();
|
||||
|
||||
var metricsQuery = {
|
||||
@ -95,7 +94,7 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
|
||||
cacheTimeout: $scope.panel.cacheTimeout
|
||||
};
|
||||
|
||||
return $scope.datasource.query(metricsQuery)
|
||||
return datasource.query(metricsQuery)
|
||||
.then($scope.dataHandler)
|
||||
.then(null, function(err) {
|
||||
console.log("err");
|
||||
|
@ -43,7 +43,11 @@ function (angular, app, _, require, PanelMeta) {
|
||||
$scope.init = function() {
|
||||
panelSrv.init($scope);
|
||||
$scope.ready = false;
|
||||
$scope.$on('refresh', $scope.render);
|
||||
$scope.render();
|
||||
};
|
||||
|
||||
$scope.refreshData = function() {
|
||||
$scope.panelMeta.loading = false;
|
||||
$scope.render();
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div ng-include src="datasource.editorSrc"></div>
|
||||
<div ng-include src="datasource.meta.partials.query"></div>
|
||||
|
||||
|
||||
<div class="editor-row" style="margin-top: 30px">
|
||||
|
@ -1,10 +0,0 @@
|
||||
<div>
|
||||
<div class="row-fluid">
|
||||
<div class="span4">
|
||||
<label class="small">Mode</label> <select class="input-medium" ng-model="panel.mode" ng-options="f for f in ['html','markdown','text']"></select>
|
||||
</div>
|
||||
<div class="span2" ng-show="panel.mode == 'text'">
|
||||
<label class="small">Font Size</label> <select class="input-mini" ng-model="panel.style['font-size']" ng-options="f for f in ['6pt','7pt','8pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,3 +0,0 @@
|
||||
<div ng-controller='CustomPanelCtrl'>
|
||||
<h2>Custom panel</h2>
|
||||
</div>
|
@ -1,27 +0,0 @@
|
||||
define([
|
||||
'angular',
|
||||
'app',
|
||||
'lodash',
|
||||
'components/panelmeta',
|
||||
],
|
||||
function (angular, app, _, PanelMeta) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.panels.custom', []);
|
||||
app.useModule(module);
|
||||
|
||||
module.controller('CustomPanelCtrl', function($scope, panelSrv) {
|
||||
|
||||
$scope.panelMeta = new PanelMeta({
|
||||
description : "A static text panel that can use plain text, markdown, or (sanitized) HTML"
|
||||
});
|
||||
|
||||
// set and populate defaults
|
||||
var _d = {
|
||||
};
|
||||
|
||||
_.defaults($scope.panel, _d);
|
||||
|
||||
panelSrv.init($scope);
|
||||
});
|
||||
});
|
@ -1,55 +0,0 @@
|
||||
define([
|
||||
'angular',
|
||||
'lodash',
|
||||
'kbn',
|
||||
'moment'
|
||||
],
|
||||
function (angular, _, kbn) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.services');
|
||||
|
||||
module.factory('CustomDatasource', function($q) {
|
||||
|
||||
// the datasource object passed to constructor
|
||||
// is the same defined in config.js
|
||||
function CustomDatasource(datasource) {
|
||||
this.name = datasource.name;
|
||||
this.supportMetrics = true;
|
||||
this.url = datasource.url;
|
||||
}
|
||||
|
||||
CustomDatasource.prototype.query = function(options) {
|
||||
// get from & to in seconds
|
||||
var from = kbn.parseDate(options.range.from).getTime();
|
||||
var to = kbn.parseDate(options.range.to).getTime();
|
||||
|
||||
var series = [];
|
||||
var stepInSeconds = (to - from) / options.maxDataPoints;
|
||||
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var walker = Math.random() * 100;
|
||||
var time = from;
|
||||
var timeSeries = {
|
||||
target: "Series " + i,
|
||||
datapoints: []
|
||||
};
|
||||
|
||||
for (var j = 0; j < options.maxDataPoints; j++) {
|
||||
timeSeries.datapoints[j] = [walker, time];
|
||||
walker += Math.random() - 0.5;
|
||||
time += stepInSeconds;
|
||||
}
|
||||
|
||||
series.push(timeSeries);
|
||||
}
|
||||
|
||||
return $q.when({data: series });
|
||||
|
||||
};
|
||||
|
||||
return CustomDatasource;
|
||||
|
||||
});
|
||||
|
||||
});
|
@ -17,18 +17,12 @@ function (angular, _, $, config, kbn, moment) {
|
||||
module.factory('GraphiteDatasource', function($q, $http, templateSrv) {
|
||||
|
||||
function GraphiteDatasource(datasource) {
|
||||
this.type = 'graphite';
|
||||
this.basicAuth = datasource.basicAuth;
|
||||
this.url = datasource.url;
|
||||
this.name = datasource.name;
|
||||
this.cacheTimeout = datasource.cacheTimeout;
|
||||
this.withCredentials = datasource.withCredentials;
|
||||
this.render_method = datasource.render_method || 'POST';
|
||||
|
||||
this.supportAnnotations = true;
|
||||
this.supportMetrics = true;
|
||||
this.editorSrc = 'app/features/graphite/partials/query.editor.html';
|
||||
this.annotationEditorSrc = 'app/features/graphite/partials/annotations.editor.html';
|
||||
}
|
||||
|
||||
GraphiteDatasource.prototype.query = function(options) {
|
@ -1,20 +0,0 @@
|
||||
define([
|
||||
'angular',
|
||||
],
|
||||
function (angular) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.services');
|
||||
|
||||
module.factory('MyDataSource', function() {
|
||||
|
||||
function MyDataSource(datasource) {
|
||||
this.type = 'my_ds';
|
||||
this.datasource = datasource;
|
||||
}
|
||||
|
||||
return MyDataSource;
|
||||
|
||||
});
|
||||
|
||||
});
|
@ -1,7 +1,18 @@
|
||||
{
|
||||
"type": "datasource",
|
||||
"name": "My Data source",
|
||||
"keyName": "graphite"
|
||||
"serviceName": "MyDataSource",
|
||||
"editPartial": "./partials/edit.html",
|
||||
"pluginType": "datasource",
|
||||
"description": "Graphite",
|
||||
|
||||
"type": "graphite",
|
||||
"serviceName": "GraphiteDatasource",
|
||||
|
||||
"module": "plugins/datasources/graphite/datasource",
|
||||
|
||||
"partials": {
|
||||
"config": "app/plugins/datasources/graphite/partials/config.html",
|
||||
"query": "app/plugins/datasources/graphite/partials/query.editor.html",
|
||||
"annotations": "app/plugins/datasources/graphite/partials/query.editor.html"
|
||||
},
|
||||
|
||||
"metrics": true,
|
||||
"annotations": true
|
||||
}
|
||||
|
@ -15,23 +15,14 @@ function (angular, _, kbn, InfluxSeries, InfluxQueryBuilder) {
|
||||
module.factory('InfluxDatasource_08', function($q, $http, templateSrv) {
|
||||
|
||||
function InfluxDatasource(datasource) {
|
||||
this.type = 'influxdb_08';
|
||||
this.urls = _.map(datasource.url.split(','), function(url) {
|
||||
return url.trim();
|
||||
});
|
||||
|
||||
this.username = datasource.username;
|
||||
this.password = datasource.password;
|
||||
this.name = datasource.name;
|
||||
this.basicAuth = datasource.basicAuth;
|
||||
this.grafanaDB = datasource.grafanaDB;
|
||||
|
||||
this.saveTemp = _.isUndefined(datasource.save_temp) ? true : datasource.save_temp;
|
||||
this.saveTempTTL = _.isUndefined(datasource.save_temp_ttl) ? '30d' : datasource.save_temp_ttl;
|
||||
|
||||
this.supportAnnotations = true;
|
||||
this.supportMetrics = true;
|
||||
this.editorSrc = 'app/features/influxdb_08/partials/query.editor.html';
|
||||
this.annotationEditorSrc = 'app/features/influxdb_08/partials/annotations.editor.html';
|
||||
}
|
||||
|
||||
InfluxDatasource.prototype.query = function(options) {
|
18
src/app/plugins/datasources/influxdb_08/plugin.json
Normal file
18
src/app/plugins/datasources/influxdb_08/plugin.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"pluginType": "datasource",
|
||||
"description": "InfluxDB 0.8.x",
|
||||
|
||||
"type": "influxdb_08",
|
||||
"serviceName": "InfluxDatasource08",
|
||||
|
||||
"module": "plugins/datasources/influxdb_08/datasource",
|
||||
|
||||
"partials": {
|
||||
"config": "app/plugins/datasources/influxdb_08/partials/config.html",
|
||||
"query": "app/plugins/datasources/influxdb_08/partials/query.editor.html",
|
||||
"annotations": "app/plugins/datasources/influxdb_08/partials/query.editor.html"
|
||||
},
|
||||
|
||||
"metrics": true,
|
||||
"annotations": true
|
||||
}
|
@ -7,37 +7,27 @@ function (angular, _, config) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.services');
|
||||
var typeMap = {
|
||||
'graphite': 'GraphiteDatasource',
|
||||
'influxdb': 'InfluxDatasource',
|
||||
'influxdb_08': 'InfluxDatasource_08',
|
||||
'elasticsearch': 'ElasticDatasource',
|
||||
'opentsdb': 'OpenTSDBDatasource',
|
||||
'grafana': 'GrafanaDatasource',
|
||||
};
|
||||
|
||||
var plugins = {
|
||||
datasources: {
|
||||
'graphite': {
|
||||
'serviceName': 'GraphiteDatasource',
|
||||
'module': 'features/graphite/datasource'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.service('datasourceSrv', function($q, $injector, $rootScope) {
|
||||
var self = this;
|
||||
|
||||
this.datasources = {};
|
||||
this.metricSources = [];
|
||||
this.annotationSources = [];
|
||||
this.grafanaDB = new ($injector.get("GrafanaDatasource"));
|
||||
|
||||
this.init = function(dsSettingList) {
|
||||
config.datasources = dsSettingList;
|
||||
};
|
||||
|
||||
this.datasourceFactory = function(ds) {
|
||||
var type = typeMap[ds.type] || ds.type;
|
||||
var Datasource = $injector.get(type);
|
||||
return new Datasource(ds);
|
||||
_.each(config.datasources, function(value, key) {
|
||||
if (value.meta && value.meta.metrics) {
|
||||
self.metricSources.push({ value: key, name: key });
|
||||
}
|
||||
});
|
||||
|
||||
if (!config.defaultDatasource) {
|
||||
$rootScope.appEvent('alert-error', ["No default data source found", ""]);
|
||||
}
|
||||
};
|
||||
|
||||
this.get = function(name) {
|
||||
@ -53,18 +43,16 @@ function (angular, _, config) {
|
||||
};
|
||||
|
||||
this.loadDatasource = function(name) {
|
||||
var datasourceConfig = config.datasources[name];
|
||||
var pluginDef = plugins.datasources[datasourceConfig.type];
|
||||
|
||||
if (!pluginDef) {
|
||||
throw { message: "No plugin definition for data source: " + name };
|
||||
}
|
||||
|
||||
var dsConfig = config.datasources[name];
|
||||
var deferred = $q.defer();
|
||||
|
||||
var pluginDef = dsConfig.meta;
|
||||
|
||||
$rootScope.require([pluginDef.module], function() {
|
||||
var AngularService = $injector.get(pluginDef.serviceName);
|
||||
var instance = new AngularService(datasourceConfig);
|
||||
var instance = new AngularService(dsConfig, pluginDef);
|
||||
instance.meta = pluginDef;
|
||||
instance.name = name;
|
||||
self.datasources[name] = instance;
|
||||
deferred.resolve(instance);
|
||||
});
|
||||
|
@ -24,7 +24,7 @@ define([
|
||||
]
|
||||
}));
|
||||
ctx.scope.render = sinon.spy();
|
||||
ctx.scope.get_data();
|
||||
ctx.scope.refreshData(ctx.datasource);
|
||||
ctx.scope.$digest();
|
||||
});
|
||||
|
||||
@ -36,7 +36,7 @@ define([
|
||||
describe('get_data failure following success', function() {
|
||||
beforeEach(function() {
|
||||
ctx.datasource.query = sinon.stub().returns(ctx.$q.reject('Datasource Error'));
|
||||
ctx.scope.get_data();
|
||||
ctx.scope.refreshData(ctx.datasource);
|
||||
ctx.scope.$digest();
|
||||
});
|
||||
|
||||
|
@ -14,7 +14,13 @@ define([
|
||||
this.templateSrv = new TemplateSrvStub();
|
||||
this.datasourceSrv = {
|
||||
getMetricSources: function() {},
|
||||
get: function() { return self.datasource; }
|
||||
get: function() {
|
||||
return {
|
||||
then: function(callback) {
|
||||
callback(self.datasource);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
this.providePhase = function(mocks) {
|
||||
|
Loading…
Reference in New Issue
Block a user