The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/features/dashboard/export/exporter.ts

156 lines
4.1 KiB

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
};
});
}
}