Export: Templateize datasource uid when it's a library panel (#70648)

This commit is contained in:
Juan Cabanas 2023-06-29 12:48:25 -03:00 committed by GitHub
parent ebd6aa5034
commit 28d251e5f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 7 deletions

View File

@ -1,6 +1,7 @@
import { find } from 'lodash';
import { DataSourceInstanceSettings, DataSourceRef, PanelPluginMeta } from '@grafana/data';
import { Dashboard, ThresholdsMode } from '@grafana/schema';
import config from 'app/core/config';
import { LibraryElementKind } from '../../../library-panels/types';
@ -93,6 +94,80 @@ it('handles a default datasource in a template variable', async () => {
expect(exported.templating.list[0].datasource.uid).toBe('${DS_GFDB}');
});
it('replaces datasource ref in library panel', async () => {
const dashboard: Dashboard = {
style: 'dark',
editable: true,
graphTooltip: 1,
schemaVersion: 38,
panels: [
{
id: 1,
title: 'Panel title',
type: 'timeseries',
options: {
cellHeight: 'sm',
footer: {
countRows: false,
fields: '',
reducer: ['sum'],
show: false,
},
showHeader: true,
},
transformations: [],
transparent: false,
fieldConfig: {
defaults: {
custom: {
align: 'auto',
cellOptions: {
type: 'auto',
},
inspect: false,
},
mappings: [],
thresholds: {
mode: ThresholdsMode.Absolute,
steps: [
{
color: 'green',
value: 10,
},
{
color: 'red',
value: 80,
},
],
},
},
overrides: [],
},
gridPos: {
h: 8,
w: 12,
x: 0,
y: 0,
},
libraryPanel: {
name: 'Testing lib panel',
uid: 'c46a6b49-de40-43b3-982c-1b5e1ec084a4',
},
},
],
};
const dashboardModel = new DashboardModel(dashboard, {});
const exporter = new DashboardExporter();
const exported = await exporter.makeExportable(dashboardModel);
if ('error' in exported) {
throw new Error('error should not be returned when making exportable json');
}
expect(exported.__elements['c46a6b49-de40-43b3-982c-1b5e1ec084a4'].model.datasource.uid).toBe('${DS_GFDB}');
expect(exported.__inputs[0].name).toBe('DS_GFDB');
});
it('If a panel queries has no datasource prop ignore it', async () => {
const dashboard: any = {
panels: [
@ -376,8 +451,7 @@ describe('given dashboard with repeated panels', () => {
expect(element.name).toBe('Library Panel 2');
expect(element.kind).toBe(LibraryElementKind.Panel);
expect(element.model).toEqual({
datasource: { type: 'other2', uid: '$ds' },
targets: [{ refId: 'A', datasource: { type: 'other2', uid: '$ds' } }],
datasource: { type: 'testdb', uid: '${DS_GFDB}' },
type: 'graph',
});
});

View File

@ -177,6 +177,8 @@ export class DashboardExporter {
model = libPanel.model;
}
await templateizeDatasourceUsage(model);
const { gridPos, id, ...rest } = model as any;
if (!libraryPanels.has(uid)) {
libraryPanels.set(uid, { name, uid, kind: LibraryElementKind.Panel, model: rest });
@ -221,13 +223,9 @@ export class DashboardExporter {
version: config.buildInfo.version,
};
each(datasources, (value: any) => {
inputs.push(value);
});
// we need to process all panels again after all the promises are resolved
// so all data sources, variables and targets have been templateized when we process library panels
for (const panel of dashboard.panels) {
for (const panel of saveModel.panels) {
await processLibraryPanels(panel);
if (panel.collapsed !== undefined && panel.collapsed === true && panel.panels) {
for (const rowPanel of panel.panels) {
@ -236,6 +234,10 @@ export class DashboardExporter {
}
}
each(datasources, (value: any) => {
inputs.push(value);
});
// templatize constants
for (const variable of saveModel.getVariables()) {
if (isConstant(variable)) {