grafana/public/app/features/dashboard/export/exporter.ts

156 lines
4.3 KiB
TypeScript

import config from 'app/core/config';
import _ from 'lodash';
import { DashboardModel } from '../dashboard_model';
export class DashboardExporter {
constructor(private datasourceSrv) {}
makeExportable(dashboard: DashboardModel) {
// clean up repeated rows and panels,
// this is done on the live real dashboard instance, not on a clone
// so we need to undo this
// this is pretty hacky and needs to be changed
dashboard.cleanUpRepeats();
var saveModel = dashboard.getSaveModelClone();
saveModel.id = null;
// undo repeat cleanup
dashboard.processRepeats();
var inputs = [];
var requires = {};
var datasources = {};
var promises = [];
var variableLookup: any = {};
for (let variable of saveModel.templating.list) {
variableLookup[variable.name] = variable;
}
var templateizeDatasourceUsage = obj => {
// ignore data source properties that contain a variable
if (obj.datasource && obj.datasource.indexOf('$') === 0) {
if (variableLookup[obj.datasource.substring(1)]) {
return;
}
}
promises.push(
this.datasourceSrv.get(obj.datasource).then(ds => {
if (ds.meta.builtIn) {
return;
}
var refName = 'DS_' + ds.name.replace(' ', '_').toUpperCase();
datasources[refName] = {
name: refName,
label: ds.name,
description: '',
type: 'datasource',
pluginId: ds.meta.id,
pluginName: ds.meta.name,
};
obj.datasource = '${' + refName + '}';
requires['datasource' + ds.meta.id] = {
type: 'datasource',
id: ds.meta.id,
name: ds.meta.name,
version: ds.meta.info.version || '1.0.0',
};
})
);
};
// check up panel data sources
for (let panel of saveModel.panels) {
if (panel.datasource !== undefined) {
templateizeDatasourceUsage(panel);
}
if (panel.targets) {
for (let target of panel.targets) {
if (target.datasource !== undefined) {
templateizeDatasourceUsage(target);
}
}
}
var panelDef = config.panels[panel.type];
if (panelDef) {
requires['panel' + panelDef.id] = {
type: 'panel',
id: panelDef.id,
name: panelDef.name,
version: panelDef.info.version,
};
}
}
// templatize template vars
for (let variable of saveModel.templating.list) {
if (variable.type === 'query') {
templateizeDatasourceUsage(variable);
variable.options = [];
variable.current = {};
variable.refresh = variable.refresh > 0 ? variable.refresh : 1;
}
}
// templatize annotations vars
for (let annotationDef of saveModel.annotations.list) {
templateizeDatasourceUsage(annotationDef);
}
// add grafana version
requires['grafana'] = {
type: 'grafana',
id: 'grafana',
name: 'Grafana',
version: config.buildInfo.version,
};
return Promise.all(promises)
.then(() => {
_.each(datasources, (value, key) => {
inputs.push(value);
});
// templatize constants
for (let variable of saveModel.templating.list) {
if (variable.type === 'constant') {
var refName = 'VAR_' + variable.name.replace(' ', '_').toUpperCase();
inputs.push({
name: refName,
type: 'constant',
label: variable.label || variable.name,
value: variable.current.value,
description: '',
});
// update current and option
variable.query = '${' + refName + '}';
variable.options[0] = variable.current = {
value: variable.query,
text: variable.query,
};
}
}
// make inputs and requires a top thing
var newObj = {};
newObj['__inputs'] = inputs;
newObj['__requires'] = _.sortBy(requires, ['id']);
_.defaults(newObj, saveModel);
return newObj;
})
.catch(err => {
console.log('Export failed:', err);
return {
error: err,
};
});
}
}