Dashboards: Do not expose datasource name and uid on dashboard external export (#88382)

Co-authored-by: Juan Cabanas <juan.cabanas@grafana.com>
This commit is contained in:
Ezequiel Victorero 2024-05-29 14:36:48 -03:00 committed by GitHub
parent 55ea077c3e
commit e81f48ef95
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 5 deletions

View File

@ -1,10 +1,11 @@
import { find } from 'lodash';
import { DataSourceInstanceSettings, DataSourceRef, PanelPluginMeta } from '@grafana/data';
import { Dashboard, ThresholdsMode } from '@grafana/schema';
import { DataSourceInstanceSettings, DataSourceRef, PanelPluginMeta, TypedVariableModel } from '@grafana/data';
import { Dashboard, DashboardCursorSync, ThresholdsMode } from '@grafana/schema';
import config from 'app/core/config';
import { LibraryElementKind } from '../../../library-panels/types';
import { DashboardJson } from '../../../manage-dashboards/types';
import { variableAdapters } from '../../../variables/adapters';
import { createConstantVariableAdapter } from '../../../variables/constant/adapter';
import { createDataSourceVariableAdapter } from '../../../variables/datasource/adapter';
@ -94,6 +95,54 @@ it('handles a default datasource in a template variable', async () => {
expect(exported.templating.list[0].datasource.uid).toBe('${DS_GFDB}');
});
it('do not expose datasource name and id in a in a template variable of type datasource', async () => {
const dashboard: Dashboard = {
title: 'My dashboard',
revision: 1,
editable: false,
graphTooltip: DashboardCursorSync.Off,
schemaVersion: 1,
timepicker: { hidden: true },
timezone: '',
panels: [
{
id: 1,
type: 'timeseries',
title: 'My panel title',
gridPos: { x: 0, y: 0, w: 1, h: 1 },
},
],
templating: {
list: [
{
current: {
selected: false,
text: 'my-prometheus-datasource',
value: 'my-prometheus-datasource-uid',
},
hide: 0,
includeAll: false,
multi: false,
name: 'query1',
options: [],
query: 'prometheus',
refresh: 1,
regex: '',
skipUrlSync: false,
type: 'datasource',
},
],
},
};
const dashboardModel = new DashboardModel(dashboard, undefined, {
getVariablesFromState: () => dashboard.templating!.list! as TypedVariableModel[],
});
const exporter = new DashboardExporter();
const exported = (await exporter.makeExportable(dashboardModel)) as DashboardJson;
const value = exported?.templating?.list ? exported?.templating?.list[0].current : '';
expect(value).toEqual({});
});
it('replaces datasource ref in library panel', async () => {
const dashboard: Dashboard = {
editable: true,

View File

@ -9,7 +9,8 @@ import { variableRegex } from 'app/features/variables/utils';
import { isPanelModelLibraryPanel } from '../../../library-panels/guard';
import { LibraryElementKind } from '../../../library-panels/types';
import { isConstant, isQuery } from '../../../variables/guard';
import { DashboardJson } from '../../../manage-dashboards/types';
import { isConstant } from '../../../variables/guard';
import { DashboardModel } from '../../state/DashboardModel';
import { GridPos } from '../../state/PanelModel';
@ -224,12 +225,14 @@ export class DashboardExporter {
// templatize template vars
for (const variable of saveModel.getVariables()) {
if (isQuery(variable)) {
if (variable.type === 'query') {
await templateizeDatasourceUsage(variable);
variable.options = [];
variable.current = {} as unknown as VariableOption;
variable.refresh =
variable.refresh !== VariableRefresh.never ? variable.refresh : VariableRefresh.onDashboardLoad;
} else if (variable.type === 'datasource') {
variable.current = {};
}
}
@ -292,7 +295,7 @@ export class DashboardExporter {
);
// make inputs and requires a top thing
const newObj: ExternalDashboard = defaults(
const newObj: DashboardJson = defaults(
{
__inputs: inputs,
__elements,