grafana/public/app/features/plugins/ds_edit_ctrl.ts
mrsiano cc1e3a0e3c Pass configured/auth headers to a Datasource.
In some setups (ex openshift), the Datasource will require Grafana
to pass oauth token as header when sending queries.
Also, this PR allow to send any header which is something
Grafana currently does not support.
2018-06-21 14:58:05 +03:00

227 lines
5.6 KiB
TypeScript

import _ from 'lodash';
import { toJS } from 'mobx';
import config from 'app/core/config';
import { coreModule, appEvents } from 'app/core/core';
import { store } from 'app/stores/store';
var datasourceTypes = [];
var defaults = {
name: '',
type: 'graphite',
url: '',
access: 'proxy',
jsonData: {},
secureJsonFields: {},
secureJsonData: {},
};
var datasourceCreated = false;
export class DataSourceEditCtrl {
isNew: boolean;
datasources: any[];
current: any;
types: any;
testing: any;
datasourceMeta: any;
editForm: any;
gettingStarted: boolean;
navModel: any;
/** @ngInject */
constructor(private $q, private backendSrv, private $routeParams, private $location, private datasourceSrv) {
if (store.nav.main === null) {
store.nav.load('cfg', 'datasources');
}
this.navModel = toJS(store.nav);
this.datasources = [];
this.loadDatasourceTypes().then(() => {
if (this.$routeParams.id) {
this.getDatasourceById(this.$routeParams.id);
} else {
this.initNewDatasourceModel();
}
});
}
initNewDatasourceModel() {
this.isNew = true;
this.current = _.cloneDeep(defaults);
// We are coming from getting started
if (this.$location.search().gettingstarted) {
this.gettingStarted = true;
this.current.isDefault = true;
}
this.typeChanged();
}
loadDatasourceTypes() {
if (datasourceTypes.length > 0) {
this.types = datasourceTypes;
return this.$q.when(null);
}
return this.backendSrv.get('/api/plugins', { enabled: 1, type: 'datasource' }).then(plugins => {
datasourceTypes = plugins;
this.types = plugins;
});
}
getDatasourceById(id) {
this.backendSrv.get('/api/datasources/' + id).then(ds => {
this.isNew = false;
this.current = ds;
if (datasourceCreated) {
datasourceCreated = false;
this.testDatasource();
}
return this.typeChanged();
});
}
userChangedType() {
// reset model but keep name & default flag
this.current = _.defaults(
{
id: this.current.id,
name: this.current.name,
isDefault: this.current.isDefault,
type: this.current.type,
},
_.cloneDeep(defaults)
);
this.typeChanged();
}
updateNav() {
store.nav.initDatasourceEditNav(this.current, this.datasourceMeta, 'datasource-settings');
this.navModel = toJS(store.nav);
}
typeChanged() {
return this.backendSrv.get('/api/plugins/' + this.current.type + '/settings').then(pluginInfo => {
this.datasourceMeta = pluginInfo;
this.updateNav();
});
}
updateFrontendSettings() {
return this.backendSrv.get('/api/frontend/settings').then(settings => {
config.datasources = settings.datasources;
config.defaultDatasource = settings.defaultDatasource;
this.datasourceSrv.init();
});
}
testDatasource() {
this.datasourceSrv.get(this.current.name).then(datasource => {
if (!datasource.testDatasource) {
return;
}
this.testing = { done: false, status: 'error' };
// make test call in no backend cache context
this.backendSrv
.withNoBackendCache(() => {
return datasource
.testDatasource()
.then(result => {
this.testing.message = result.message;
this.testing.status = result.status;
})
.catch(err => {
if (err.statusText) {
this.testing.message = 'HTTP Error ' + err.statusText;
} else {
this.testing.message = err.message;
}
});
})
.finally(() => {
this.testing.done = true;
});
});
}
saveChanges() {
if (!this.editForm.$valid) {
return;
}
if (this.current.readOnly) {
return;
}
if (this.current.id) {
return this.backendSrv.put('/api/datasources/' + this.current.id, this.current).then(result => {
this.current = result.datasource;
this.updateNav();
this.updateFrontendSettings().then(() => {
this.testDatasource();
});
});
} else {
return this.backendSrv.post('/api/datasources', this.current).then(result => {
this.current = result.datasource;
this.updateFrontendSettings();
datasourceCreated = true;
this.$location.path('datasources/edit/' + result.id);
});
}
}
confirmDelete() {
this.backendSrv.delete('/api/datasources/' + this.current.id).then(() => {
this.$location.path('datasources');
});
}
delete(s) {
appEvents.emit('confirm-modal', {
title: 'Delete',
text: 'Are you sure you want to delete this datasource?',
yesText: 'Delete',
icon: 'fa-trash',
onConfirm: () => {
this.confirmDelete();
},
});
}
}
coreModule.controller('DataSourceEditCtrl', DataSourceEditCtrl);
coreModule.directive('datasourceHttpSettings', function() {
return {
scope: {
current: '=',
suggestUrl: '@',
noDirectAccess: '@',
},
templateUrl: 'public/app/features/plugins/partials/ds_http_settings.html',
link: {
pre: function($scope, elem, attrs) {
// do not show access option if direct access is disabled
$scope.showAccessOption = $scope.noDirectAccess !== 'true';
$scope.showAccessHelp = false;
$scope.toggleAccessHelp = function() {
$scope.showAccessHelp = !$scope.showAccessHelp;
};
$scope.getSuggestUrls = function() {
return [$scope.suggestUrl];
};
},
},
};
});