mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(plugins): changed what datasources should return, they should now return the datasource constructor
This commit is contained in:
@@ -38,6 +38,7 @@ type DataSourcePlugin struct {
|
|||||||
Annotations bool `json:"annotations"`
|
Annotations bool `json:"annotations"`
|
||||||
Metrics bool `json:"metrics"`
|
Metrics bool `json:"metrics"`
|
||||||
BuiltIn bool `json:"builtIn"`
|
BuiltIn bool `json:"builtIn"`
|
||||||
|
Mixed bool `json:"mixed"`
|
||||||
App string `json:"app"`
|
App string `json:"app"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,3 @@
|
|||||||
// import grafanaCtrl from './grafana_ctrl';
|
|
||||||
//
|
|
||||||
// import * as asd from './sidemenu_ctrl';
|
|
||||||
//
|
|
||||||
// export {grafanaCtrl};
|
|
||||||
|
|
||||||
define([
|
define([
|
||||||
'./grafana_ctrl',
|
'./grafana_ctrl',
|
||||||
'./search_ctrl',
|
'./search_ctrl',
|
||||||
|
|||||||
@@ -58,12 +58,21 @@ function (angular, _, coreModule, config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
|
|
||||||
var pluginDef = dsConfig.meta;
|
var pluginDef = dsConfig.meta;
|
||||||
|
|
||||||
System.import(pluginDef.module).then(function() {
|
System.import(pluginDef.module).then(function(plugin) {
|
||||||
var AngularService = $injector.get(pluginDef.serviceName);
|
// check if its in cache now
|
||||||
var instance = new AngularService(dsConfig, pluginDef);
|
if (self.datasources[name]) {
|
||||||
|
deferred.resolve(self.datasources[name]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// plugin module needs to export a constructor function named Datasource
|
||||||
|
if (!plugin.Datasource) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var instance = $injector.instantiate(plugin.Datasource, {instanceSettings: dsConfig});
|
||||||
instance.meta = pluginDef;
|
instance.meta = pluginDef;
|
||||||
instance.name = name;
|
instance.name = name;
|
||||||
self.datasources[name] = instance;
|
self.datasources[name] = instance;
|
||||||
|
|||||||
3
public/app/plugins/datasource/elasticsearch/datasource.d.ts
vendored
Normal file
3
public/app/plugins/datasource/elasticsearch/datasource.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
declare var Datasource: any;
|
||||||
|
export {Datasource};
|
||||||
|
|
||||||
@@ -12,28 +12,22 @@ define([
|
|||||||
function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticResponse) {
|
function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticResponse) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var module = angular.module('grafana.services');
|
function ElasticDatasource(instanceSettings, $q, backendSrv, templateSrv, timeSrv) {
|
||||||
|
this.basicAuth = instanceSettings.basicAuth;
|
||||||
module.factory('ElasticDatasource', function($q, backendSrv, templateSrv, timeSrv) {
|
this.withCredentials = instanceSettings.withCredentials;
|
||||||
|
this.url = instanceSettings.url;
|
||||||
function ElasticDatasource(datasource) {
|
this.name = instanceSettings.name;
|
||||||
this.type = 'elasticsearch';
|
this.index = instanceSettings.index;
|
||||||
this.basicAuth = datasource.basicAuth;
|
this.timeField = instanceSettings.jsonData.timeField;
|
||||||
this.withCredentials = datasource.withCredentials;
|
this.esVersion = instanceSettings.jsonData.esVersion;
|
||||||
this.url = datasource.url;
|
this.indexPattern = new IndexPattern(instanceSettings.index, instanceSettings.jsonData.interval);
|
||||||
this.name = datasource.name;
|
this.interval = instanceSettings.jsonData.timeInterval;
|
||||||
this.index = datasource.index;
|
|
||||||
this.timeField = datasource.jsonData.timeField;
|
|
||||||
this.esVersion = datasource.jsonData.esVersion;
|
|
||||||
this.indexPattern = new IndexPattern(datasource.index, datasource.jsonData.interval);
|
|
||||||
this.interval = datasource.jsonData.timeInterval;
|
|
||||||
this.queryBuilder = new ElasticQueryBuilder({
|
this.queryBuilder = new ElasticQueryBuilder({
|
||||||
timeField: this.timeField,
|
timeField: this.timeField,
|
||||||
esVersion: this.esVersion,
|
esVersion: this.esVersion,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
ElasticDatasource.prototype._request = function(method, url, data) {
|
this._request = function(method, url, data) {
|
||||||
var options = {
|
var options = {
|
||||||
url: this.url + "/" + url,
|
url: this.url + "/" + url,
|
||||||
method: method,
|
method: method,
|
||||||
@@ -52,21 +46,21 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
|||||||
return backendSrv.datasourceRequest(options);
|
return backendSrv.datasourceRequest(options);
|
||||||
};
|
};
|
||||||
|
|
||||||
ElasticDatasource.prototype._get = function(url) {
|
this._get = function(url) {
|
||||||
return this._request('GET', this.indexPattern.getIndexForToday() + url)
|
return this._request('GET', this.indexPattern.getIndexForToday() + url)
|
||||||
.then(function(results) {
|
.then(function(results) {
|
||||||
return results.data;
|
return results.data;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ElasticDatasource.prototype._post = function(url, data) {
|
this._post = function(url, data) {
|
||||||
return this._request('POST', url, data)
|
return this._request('POST', url, data)
|
||||||
.then(function(results) {
|
.then(function(results) {
|
||||||
return results.data;
|
return results.data;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ElasticDatasource.prototype.annotationQuery = function(options) {
|
this.annotationQuery = function(options) {
|
||||||
var annotation = options.annotation;
|
var annotation = options.annotation;
|
||||||
var timeField = annotation.timeField || '@timestamp';
|
var timeField = annotation.timeField || '@timestamp';
|
||||||
var queryString = annotation.query || '*';
|
var queryString = annotation.query || '*';
|
||||||
@@ -147,7 +141,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ElasticDatasource.prototype.testDatasource = function() {
|
this.testDatasource = function() {
|
||||||
return this._get('/_stats').then(function() {
|
return this._get('/_stats').then(function() {
|
||||||
return { status: "success", message: "Data source is working", title: "Success" };
|
return { status: "success", message: "Data source is working", title: "Success" };
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
@@ -159,13 +153,13 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ElasticDatasource.prototype.getQueryHeader = function(searchType, timeFrom, timeTo) {
|
this.getQueryHeader = function(searchType, timeFrom, timeTo) {
|
||||||
var header = {search_type: searchType, "ignore_unavailable": true};
|
var header = {search_type: searchType, "ignore_unavailable": true};
|
||||||
header.index = this.indexPattern.getIndexList(timeFrom, timeTo);
|
header.index = this.indexPattern.getIndexList(timeFrom, timeTo);
|
||||||
return angular.toJson(header);
|
return angular.toJson(header);
|
||||||
};
|
};
|
||||||
|
|
||||||
ElasticDatasource.prototype.query = function(options) {
|
this.query = function(options) {
|
||||||
var payload = "";
|
var payload = "";
|
||||||
var target;
|
var target;
|
||||||
var sentTargets = [];
|
var sentTargets = [];
|
||||||
@@ -203,7 +197,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ElasticDatasource.prototype.getFields = function(query) {
|
this.getFields = function(query) {
|
||||||
return this._get('/_mapping').then(function(res) {
|
return this._get('/_mapping').then(function(res) {
|
||||||
var fields = {};
|
var fields = {};
|
||||||
var typeMap = {
|
var typeMap = {
|
||||||
@@ -240,7 +234,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ElasticDatasource.prototype.getTerms = function(queryDef) {
|
this.getTerms = function(queryDef) {
|
||||||
var range = timeSrv.timeRange();
|
var range = timeSrv.timeRange();
|
||||||
var header = this.getQueryHeader('count', range.from, range.to);
|
var header = this.getQueryHeader('count', range.from, range.to);
|
||||||
var esQuery = angular.toJson(this.queryBuilder.getTermsQuery(queryDef));
|
var esQuery = angular.toJson(this.queryBuilder.getTermsQuery(queryDef));
|
||||||
@@ -258,7 +252,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ElasticDatasource.prototype.metricFindQuery = function(query) {
|
this.metricFindQuery = function(query) {
|
||||||
query = templateSrv.replace(query);
|
query = templateSrv.replace(query);
|
||||||
query = angular.fromJson(query);
|
query = angular.fromJson(query);
|
||||||
if (!query) {
|
if (!query) {
|
||||||
@@ -273,14 +267,14 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ElasticDatasource.prototype.getDashboard = function(id) {
|
this.getDashboard = function(id) {
|
||||||
return this._get('/dashboard/' + id)
|
return this._get('/dashboard/' + id)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
return angular.fromJson(result._source.dashboard);
|
return angular.fromJson(result._source.dashboard);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ElasticDatasource.prototype.searchDashboards = function() {
|
this.searchDashboards = function() {
|
||||||
var query = {
|
var query = {
|
||||||
query: { query_string: { query: '*' } },
|
query: { query_string: { query: '*' } },
|
||||||
size: 10000,
|
size: 10000,
|
||||||
@@ -308,7 +302,9 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
|||||||
return displayHits;
|
return displayHits;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return ElasticDatasource;
|
return {
|
||||||
});
|
Datasource: ElasticDatasource,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,28 +1,32 @@
|
|||||||
|
|
||||||
import "../datasource";
|
|
||||||
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
|
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
import helpers from 'test/specs/helpers';
|
import helpers from 'test/specs/helpers';
|
||||||
|
import {Datasource} from "../datasource";
|
||||||
|
|
||||||
describe('ElasticDatasource', function() {
|
describe('ElasticDatasource', function() {
|
||||||
var ctx = new helpers.ServiceTestContext();
|
var ctx = new helpers.ServiceTestContext();
|
||||||
|
var instanceSettings: any = {jsonData: {}};
|
||||||
|
|
||||||
beforeEach(angularMocks.module('grafana.core'));
|
beforeEach(angularMocks.module('grafana.core'));
|
||||||
beforeEach(angularMocks.module('grafana.services'));
|
beforeEach(angularMocks.module('grafana.services'));
|
||||||
beforeEach(ctx.providePhase(['templateSrv', 'backendSrv']));
|
beforeEach(ctx.providePhase(['templateSrv', 'backendSrv']));
|
||||||
beforeEach(ctx.createService('ElasticDatasource'));
|
beforeEach(angularMocks.inject(function($q, $rootScope, $httpBackend, $injector) {
|
||||||
beforeEach(function() {
|
ctx.$q = $q;
|
||||||
ctx.ds = new ctx.service({jsonData: {}});
|
ctx.$httpBackend = $httpBackend;
|
||||||
});
|
ctx.$rootScope = $rootScope;
|
||||||
|
ctx.$injector = $injector;
|
||||||
|
}));
|
||||||
|
|
||||||
|
function createDatasource(instanceSettings) {
|
||||||
|
instanceSettings.jsonData = instanceSettings.jsonData || {};
|
||||||
|
ctx.ds = ctx.$injector.instantiate(Datasource, {instanceSettings: instanceSettings});
|
||||||
|
}
|
||||||
|
|
||||||
describe('When testing datasource with index pattern', function() {
|
describe('When testing datasource with index pattern', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
ctx.ds = new ctx.service({
|
createDatasource({url: 'http://es.com', index: '[asd-]YYYY.MM.DD', jsonData: {interval: 'Daily'}});
|
||||||
url: 'http://es.com',
|
|
||||||
index: '[asd-]YYYY.MM.DD',
|
|
||||||
jsonData: { interval: 'Daily' }
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should translate index pattern to current day', function() {
|
it('should translate index pattern to current day', function() {
|
||||||
@@ -44,11 +48,7 @@ describe('ElasticDatasource', function() {
|
|||||||
var requestOptions, parts, header;
|
var requestOptions, parts, header;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
ctx.ds = new ctx.service({
|
createDatasource({url: 'http://es.com', index: '[asd-]YYYY.MM.DD', jsonData: {interval: 'Daily'}});
|
||||||
url: 'http://es.com',
|
|
||||||
index: '[asd-]YYYY.MM.DD',
|
|
||||||
jsonData: { interval: 'Daily' }
|
|
||||||
});
|
|
||||||
|
|
||||||
ctx.backendSrv.datasourceRequest = function(options) {
|
ctx.backendSrv.datasourceRequest = function(options) {
|
||||||
requestOptions = options;
|
requestOptions = options;
|
||||||
@@ -83,7 +83,7 @@ describe('ElasticDatasource', function() {
|
|||||||
var requestOptions, parts, header;
|
var requestOptions, parts, header;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
ctx.ds = new ctx.service({url: 'http://es.com', index: 'test', jsonData: {}});
|
createDatasource({url: 'http://es.com', index: 'test'});
|
||||||
|
|
||||||
ctx.backendSrv.datasourceRequest = function(options) {
|
ctx.backendSrv.datasourceRequest = function(options) {
|
||||||
requestOptions = options;
|
requestOptions = options;
|
||||||
|
|||||||
@@ -301,4 +301,7 @@ function (angular, _, $, config, dateMath) {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
serviceName: "GraphiteDatasource"
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
define([
|
|
||||||
'angular',
|
|
||||||
'lodash',
|
|
||||||
],
|
|
||||||
function (angular, _) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var module = angular.module('grafana.services');
|
|
||||||
|
|
||||||
module.factory('MixedDatasource', function($q, backendSrv, datasourceSrv) {
|
|
||||||
|
|
||||||
function MixedDatasource() {
|
|
||||||
}
|
|
||||||
|
|
||||||
MixedDatasource.prototype.query = function(options) {
|
|
||||||
var sets = _.groupBy(options.targets, 'datasource');
|
|
||||||
var promises = _.map(sets, function(targets) {
|
|
||||||
return datasourceSrv.get(targets[0].datasource).then(function(ds) {
|
|
||||||
var opt = angular.copy(options);
|
|
||||||
opt.targets = targets;
|
|
||||||
return ds.query(opt);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return $q.all(promises).then(function(results) {
|
|
||||||
return { data: _.flatten(_.pluck(results, 'data')) };
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
return MixedDatasource;
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
37
public/app/plugins/datasource/mixed/datasource.ts
Normal file
37
public/app/plugins/datasource/mixed/datasource.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
///<reference path="../../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import angular from 'angular';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
class MixedDatasource {
|
||||||
|
|
||||||
|
constructor(private $q, private datasourceSrv) {
|
||||||
|
}
|
||||||
|
|
||||||
|
query(options) {
|
||||||
|
var sets = _.groupBy(options.targets, 'datasource');
|
||||||
|
var promises = _.map(sets, targets => {
|
||||||
|
var dsName = targets[0].datasource;
|
||||||
|
if (dsName === '-- Mixed --') {
|
||||||
|
return this.$q([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.datasourceSrv.get(dsName).then(function(ds) {
|
||||||
|
var opt = angular.copy(options);
|
||||||
|
opt.targets = targets;
|
||||||
|
return ds.query(opt);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.$q.all(promises).then(function(results) {
|
||||||
|
return { data: _.flatten(_.pluck(results, 'data')) };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {MixedDatasource, MixedDatasource as Datasource}
|
||||||
|
|
||||||
|
// var module = angular.module('grafana.services');
|
||||||
|
// module.factory('MixedDatasource', MixedDatasource);
|
||||||
|
//
|
||||||
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
var _global = <any>(window);
|
var _global = <any>(window);
|
||||||
var beforeEach = _global.beforeEach;
|
var beforeEach = _global.beforeEach;
|
||||||
|
var before = _global.before;
|
||||||
var describe = _global.describe;
|
var describe = _global.describe;
|
||||||
var it = _global.it;
|
var it = _global.it;
|
||||||
var sinon = _global.sinon;
|
var sinon = _global.sinon;
|
||||||
@@ -9,10 +10,12 @@ var expect = _global.expect;
|
|||||||
|
|
||||||
var angularMocks = {
|
var angularMocks = {
|
||||||
module: _global.module,
|
module: _global.module,
|
||||||
|
inject: _global.inject,
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
beforeEach,
|
beforeEach,
|
||||||
|
before,
|
||||||
describe,
|
describe,
|
||||||
it,
|
it,
|
||||||
sinon,
|
sinon,
|
||||||
|
|||||||
Reference in New Issue
Block a user