diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js
index 7fa57e0..97d4d03 100644
--- a/build/webpack.base.conf.js
+++ b/build/webpack.base.conf.js
@@ -11,7 +11,8 @@ module.exports = {
context: resolve('src'),
entry: {
'./module': './module.ts',
- './panel/graph_panel/module': './panel/graph_panel/graph_ctrl.ts'
+ './panel/graph_panel/module': './panel/graph_panel/graph_ctrl.ts',
+ './datasource/module': './datasource/module.ts'
},
output: {
filename: '[name].js',
@@ -35,7 +36,8 @@ module.exports = {
{ from: 'plugin.json' },
{ from: 'img/*' },
{ from: 'panel/graph_panel/plugin.json', to: 'panel/graph_panel/plugin.json' },
- { from: 'panel/graph_panel/partials/*' }
+ { from: 'panel/graph_panel/partials/*' },
+ { from: 'datasource/plugin.json', to: 'datasource/plugin.json' },
])
],
resolve: {
diff --git a/src/config/config_ctrl.ts b/src/config/config_ctrl.ts
index 6e125a4..49ee100 100644
--- a/src/config/config_ctrl.ts
+++ b/src/config/config_ctrl.ts
@@ -1,36 +1,13 @@
import template from './template.html';
-import { normalizeUrl } from '../utlis';
class ConfigCtrl {
static template = template;
appModel: any;
- appEditCtrl: any;
constructor() {
if(this.appModel.jsonData === undefined) {
this.appModel.jsonData = {};
}
-
- this.appEditCtrl.setPreUpdateHook(this.preUpdate.bind(this));
- this.appEditCtrl.setPostUpdateHook(this.postUpdate.bind(this));
- }
-
- preUpdate() {
- this.normalizeUrl();
- return Promise.resolve();
- }
-
- postUpdate() {
- // TODO: check whether hasticServerUrl is accessible
- if(!this.appModel.enabled) {
- return Promise.resolve();
- }
-
- return { message: 'Hastic app installed!' };
- }
-
- normalizeUrl() {
- this.appModel.jsonData.hasticServerUrl = normalizeUrl(this.appModel.jsonData.hasticServerUrl);
}
}
diff --git a/src/config/template.html b/src/config/template.html
index 309c183..d3f5a12 100644
--- a/src/config/template.html
+++ b/src/config/template.html
@@ -1,12 +1 @@
-
Enter your Hastic config
-
+
diff --git a/src/datasource/config_ctrl.ts b/src/datasource/config_ctrl.ts
new file mode 100644
index 0000000..cb02297
--- /dev/null
+++ b/src/datasource/config_ctrl.ts
@@ -0,0 +1,33 @@
+import { normalizeUrl } from '../utlis';
+import configTemplate from './partials/config.html';
+
+
+export class HasticConfigCtrl {
+ public static template = configTemplate;
+ public ACCESS_OPTIONS = [
+ { key: 'proxy', value: 'Server (Default)' },
+ { key: 'direct', value: 'Browser' }
+ ];
+
+ public showAccessHelp = false;
+
+ constructor(private $scope: any) {
+ if(this.$scope.current === undefined) {
+ this.$scope.current = {
+ url: '',
+ access: 'proxy'
+ };
+ }
+ }
+
+ normalizeUrl() {
+ if(this.$scope.current.url === '') {
+ return;
+ }
+ this.$scope.current.url = normalizeUrl(this.$scope.current.url);
+ }
+
+ toggleAccessHelp() {
+ this.showAccessHelp = !this.showAccessHelp;
+ }
+}
diff --git a/src/datasource/datasource.ts b/src/datasource/datasource.ts
new file mode 100644
index 0000000..9d5d6a0
--- /dev/null
+++ b/src/datasource/datasource.ts
@@ -0,0 +1,37 @@
+import HasticAPI from './hastic_api';
+
+import { BackendSrv } from 'grafana/app/core/services/backend_srv';
+
+export class HasticDatasource {
+ private hastic: HasticAPI;
+
+ /** @ngInject */
+ constructor(instanceSettings: any, backendSrv: BackendSrv) {
+ this.hastic = new HasticAPI(instanceSettings, backendSrv);
+ }
+
+ async query(options: any) {
+ console.log(options);
+ }
+
+ async testDatasource() {
+ try {
+ await this.hastic.get('/');
+ // TODO: check if it is hastic
+ return {
+ status: 'success', title: 'Success',
+ message: 'Datasource is working'
+ };
+ } catch(err) {
+ console.error(err);
+ return {
+ status: 'error', title: 'Error',
+ message: 'Hastic connection error'
+ };
+ }
+ }
+
+ metricFindQuery(options: any) {
+ return [];
+ }
+}
diff --git a/src/datasource/hastic_api.ts b/src/datasource/hastic_api.ts
new file mode 100644
index 0000000..4c9b836
--- /dev/null
+++ b/src/datasource/hastic_api.ts
@@ -0,0 +1,29 @@
+import { BackendSrv } from 'grafana/app/core/services/backend_srv';
+
+export default class HasticAPI {
+ private url: string;
+
+ constructor(instanceSettings: any, private backendSrv: BackendSrv) {
+ this.url = instanceSettings.url;
+ }
+
+ get(url: string, params?: any) {
+ return this._query('GET', url, params);
+ }
+
+ private async _query(method: string, url: string, data?: any) {
+ method = method.toUpperCase();
+ let options: any = {
+ method,
+ url: this.url + url
+ };
+ if(method === 'GET' || method === 'DELETE') {
+ options.params = data;
+ } else {
+ options.data = data;
+ }
+
+ const response = await this.backendSrv.datasourceRequest(options);
+ return response.data;
+ }
+}
diff --git a/src/datasource/module.ts b/src/datasource/module.ts
new file mode 100644
index 0000000..e3767cd
--- /dev/null
+++ b/src/datasource/module.ts
@@ -0,0 +1,10 @@
+import { HasticDatasource } from './datasource';
+import { HasticQueryCtrl } from './query_ctrl';
+import { HasticConfigCtrl } from './config_ctrl';
+
+
+export {
+ HasticDatasource as Datasource,
+ HasticConfigCtrl as ConfigCtrl,
+ HasticQueryCtrl as QueryCtrl
+};
diff --git a/src/datasource/partials/config.html b/src/datasource/partials/config.html
new file mode 100644
index 0000000..27b755a
--- /dev/null
+++ b/src/datasource/partials/config.html
@@ -0,0 +1,87 @@
+
+
+
diff --git a/src/datasource/partials/query_ctrl.html b/src/datasource/partials/query_ctrl.html
new file mode 100644
index 0000000..e69de29
diff --git a/src/datasource/plugin.json b/src/datasource/plugin.json
new file mode 100644
index 0000000..732e58c
--- /dev/null
+++ b/src/datasource/plugin.json
@@ -0,0 +1,12 @@
+{
+ "type": "datasource",
+ "name": "Hastic Datasource",
+ "id": "corpglory-hastic-datasource",
+ "metrics": true,
+ "info": {
+ "logos": {
+ "small": "../corpglory-hastic-app/img/icn-graph-panel.png",
+ "large": "../corpglory-hastic-app/img/icn-graph-panel.png"
+ }
+ }
+}
diff --git a/src/datasource/query_ctrl.ts b/src/datasource/query_ctrl.ts
new file mode 100644
index 0000000..d556f3d
--- /dev/null
+++ b/src/datasource/query_ctrl.ts
@@ -0,0 +1,12 @@
+import template from './partials/query_ctrl.html';
+
+import { QueryCtrl } from 'grafana/app/plugins/sdk';
+
+export class HasticQueryCtrl extends QueryCtrl {
+ static template = template;
+
+ /** @ngInject */
+ constructor($scope, $injector) {
+ super($scope, $injector);
+ }
+}
diff --git a/src/panel/graph_panel/controllers/analytic_controller.ts b/src/panel/graph_panel/controllers/analytic_controller.ts
index 285f1f8..a32525f 100644
--- a/src/panel/graph_panel/controllers/analytic_controller.ts
+++ b/src/panel/graph_panel/controllers/analytic_controller.ts
@@ -430,6 +430,9 @@ export class AnalyticController {
);
for await (const data of statusGenerator) {
+ if(data === undefined) {
+ break;
+ }
let status = data.status;
let error = data.errorMessage;
if(analyticUnit.status !== status) {
diff --git a/src/panel/graph_panel/graph_ctrl.ts b/src/panel/graph_panel/graph_ctrl.ts
index 719487f..cfbe5c0 100644
--- a/src/panel/graph_panel/graph_ctrl.ts
+++ b/src/panel/graph_panel/graph_ctrl.ts
@@ -29,7 +29,6 @@ class GraphCtrl extends MetricsPanelCtrl {
seriesList: any = [];
dataList: any = [];
- _backendUrl: string = undefined;
// annotations: any = [];
private _datasourceRequest: DatasourceRequest;
@@ -51,10 +50,15 @@ class GraphCtrl extends MetricsPanelCtrl {
_panelInfo: PanelInfo;
private _analyticUnitTypes: any;
+ private _hasticDatasources: any[];
+
+ private $graphElem: any;
+ private $legendElem: any;
panelDefaults = {
// datasource name, null = default datasource
datasource: null,
+ hasticDatasource: null,
// sets client side (flot) or native graphite png renderer (png)
renderer: 'flot',
yaxes: [
@@ -180,20 +184,16 @@ class GraphCtrl extends MetricsPanelCtrl {
this.rebindKeys();
}
- async getBackendURL(): Promise {
- if(this._backendUrl !== undefined) {
- return this._backendUrl;
- }
- var data = await this.backendSrv.get('api/plugins/corpglory-hastic-app/settings');
- if(data.jsonData === undefined || data.jsonData === null) {
- return undefined;
- }
- let val = data.jsonData.hasticServerUrl;
- if(val === undefined || val === null) {
- return undefined;
+ getBackendURL(): string {
+ const datasourceId = this.panel.hasticDatasource;
+ if(datasourceId !== undefined && datasourceId !== null) {
+ const datasource = _.find(this._hasticDatasources, { id: datasourceId });
+ if(datasource.access === 'proxy') {
+ return `/api/datasources/proxy/${datasource.id}`;
+ }
+ return datasource.url;
}
- val = val.replace(/\/+$/, "");
- return val;
+ return undefined;
}
async updateAnalyticUnitTypes() {
@@ -210,53 +210,34 @@ class GraphCtrl extends MetricsPanelCtrl {
return _.keys(this._analyticUnitTypes);
}
- private _checkBackendUrlOk(backendURL: string): boolean {
- if(backendURL === null || backendURL === undefined || backendURL === '') {
- appEvents.emit(
- 'alert-warning',
- [
- `hasticServerUrl is missing`,
- `Please set it in config. More info: https://github.com/hastic/hastic-grafana-app/wiki/Getting-started`
- ]
- );
- return false;
- }
- return true;
- }
-
async runBackendConnectivityCheck() {
- let backendURL = await this.getBackendURL();
- if(!this._checkBackendUrlOk(backendURL)) {
- return;
+ const backendURL = this.getBackendURL();
+
+ try {
+ const connected = await this.analyticService.isBackendOk();
+ if(connected) {
+ this.updateAnalyticUnitTypes();
+ appEvents.emit(
+ 'alert-success',
+ [
+ 'Connected to Hastic server',
+ `Hastic server: "${backendURL}"`
+ ]
+ );
+ }
}
- let connected = await this.analyticService.isBackendOk();
- if(connected) {
- this.updateAnalyticUnitTypes();
- appEvents.emit(
- 'alert-success',
- [
- 'Connected to Hastic server',
- `Hastic server: "${backendURL}"`
- ]
- );
+ catch(err) {
+ console.error(err);
}
}
async link(scope, elem, attrs, ctrl) {
+ this._datasources = {};
- this.processor = new DataProcessor(this.panel);
-
- let backendURL = await this.getBackendURL();
- if(!this._checkBackendUrlOk(backendURL)) {
- return;
- }
-
- this.analyticService = new AnalyticService(backendURL, this.$http);
-
- this.runBackendConnectivityCheck();
-
- this.analyticsController = new AnalyticController(this.panel, this.analyticService, this.events);
+ this.$graphElem = $(elem[0]).find('#graphPanel');
+ this.$legendElem = $(elem[0]).find('#graphLegend');
+ this.onHasticDatasourceChange();
this.events.on('render', this.onRender.bind(this));
this.events.on('data-received', this.onDataReceived.bind(this));
@@ -281,8 +262,6 @@ class GraphCtrl extends MetricsPanelCtrl {
this.$scope.$digest();
});
- this._datasources = {};
-
appEvents.on('ds-request-response', data => {
let requestConfig = data.config;
@@ -294,19 +273,6 @@ class GraphCtrl extends MetricsPanelCtrl {
type: undefined
};
});
-
- this.analyticsController.fetchAnalyticUnitsStatuses();
-
-
- var $graphElem = $(elem[0]).find('#graphPanel');
- var $legendElem = $(elem[0]).find('#graphLegend');
- this._graphRenderer = new GraphRenderer(
- $graphElem, this.timeSrv, this.contextSrv, this.$scope
- );
- this._graphLegend = new GraphLegend($legendElem, this.popoverSrv, this.$scope);
-
- this._updatePanelInfo();
- this.analyticsController.updateServerInfo();
}
onInitEditMode() {
@@ -329,6 +295,27 @@ class GraphCtrl extends MetricsPanelCtrl {
actions.push({ text: 'Toggle legend', click: 'ctrl.toggleLegend()' });
}
+ async onHasticDatasourceChange() {
+ this.processor = new DataProcessor(this.panel);
+
+ await this._fetchHasticDatasources();
+ const backendURL = this.getBackendURL();
+
+ this.analyticService = new AnalyticService(backendURL, this.$http);
+ this.runBackendConnectivityCheck();
+ this.analyticsController = new AnalyticController(this.panel, this.analyticService, this.events);
+
+ this.analyticsController.fetchAnalyticUnitsStatuses();
+
+ this._graphRenderer = new GraphRenderer(
+ this.$graphElem, this.timeSrv, this.contextSrv, this.$scope
+ );
+ this._graphLegend = new GraphLegend(this.$legendElem, this.popoverSrv, this.$scope);
+
+ this._updatePanelInfo();
+ this.analyticsController.updateServerInfo();
+ }
+
issueQueries(datasource) {
// this.annotationsPromise = this.annotationsSrv.getAnnotations({
// dashboard: this.dashboard,
@@ -385,15 +372,17 @@ class GraphCtrl extends MetricsPanelCtrl {
}
}
- var loadTasks = [
- // this.annotationsPromise,
- this.analyticsController.fetchAnalyticUnitsSegments(+this.range.from, +this.range.to)
- ];
+ if(this.analyticsController !== undefined) {
+ var loadTasks = [
+ // this.annotationsPromise,
+ this.analyticsController.fetchAnalyticUnitsSegments(+this.range.from, +this.range.to)
+ ];
- var results = await Promise.all(loadTasks);
- this.loading = false;
- // this.annotations = results[0].annotations;
- this.render(this.seriesList);
+ await Promise.all(loadTasks);
+ this.loading = false;
+ // this.annotations = results[0].annotations;
+ this.render(this.seriesList);
+ }
}
@@ -657,7 +646,7 @@ class GraphCtrl extends MetricsPanelCtrl {
private async _updatePanelInfo() {
const datasource = await this._getDatasourceByName(this.panel.datasource);
- const backendUrl = await this.getBackendURL();
+ const backendUrl = this.getBackendURL();
let grafanaVersion = 'unknown';
if(_.has(window, 'grafanaBootData.settings.buildInfo.version')) {
@@ -691,6 +680,16 @@ class GraphCtrl extends MetricsPanelCtrl {
}
}
+ private async _fetchHasticDatasources() {
+ this._hasticDatasources = await this.backendSrv.get('/api/datasources');
+ this._hasticDatasources = this._hasticDatasources.filter(ds => ds.type === 'corpglory-hastic-datasource');
+ this.$scope.$digest();
+ }
+
+ get hasticDatasources() {
+ return this._hasticDatasources;
+ }
+
get panelInfo() {
return this._panelInfo;
}
diff --git a/src/panel/graph_panel/models/info.ts b/src/panel/graph_panel/models/info.ts
index 5aa9e05..474b94b 100644
--- a/src/panel/graph_panel/models/info.ts
+++ b/src/panel/graph_panel/models/info.ts
@@ -2,9 +2,9 @@ export type ServerInfo = {
nodeVersion: string,
packageVersion: string,
npmUserAgent: string,
- docker: boolean,
+ docker: string | boolean,
zmqConectionString: string,
- serverPort: number,
+ serverPort: string | number,
gitBranch: string,
gitCommitHash: string
}
diff --git a/src/panel/graph_panel/partials/tab_analytics.html b/src/panel/graph_panel/partials/tab_analytics.html
index 81637a7..a2df5a9 100644
--- a/src/panel/graph_panel/partials/tab_analytics.html
+++ b/src/panel/graph_panel/partials/tab_analytics.html
@@ -1,210 +1,224 @@
-