[Release 12.0.1]SchemaV2 - Fix Import showing grafana ds(#104461) (#104828)

Dashboard: SchemaV2 - Fix Import showing grafana datasources (#104461)

* Fix: do not map when identifying default grafana ds

* add also datasource type

* Refactor code, add unit test

* Fix types references and linting

* Update public/app/features/manage-dashboards/state/actions.test.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
(cherry picked from commit 26ce124208)
pull/104847/head
Alexa V 3 months ago committed by GitHub
parent 3b2165d787
commit 5ad33cb0a9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 65
      public/app/features/manage-dashboards/state/actions.test.ts
  2. 15
      public/app/features/manage-dashboards/state/actions.ts

@ -3,11 +3,11 @@ import { thunkTester } from 'test/core/thunk/thunkTester';
import { DataSourceInstanceSettings, ThresholdsMode } from '@grafana/data';
import { defaultDashboard, FieldColorModeId } from '@grafana/schema';
import {
DashboardV2Spec,
defaultDashboardV2Spec,
Spec as DashboardV2Spec,
defaultSpec as defaultDashboardV2Spec,
defaultPanelSpec,
defaultQueryVariableSpec,
} from '@grafana/schema/dist/esm/schema/dashboard/v2alpha0';
} from '@grafana/schema/dist/esm/schema/dashboard/v2alpha1/types.spec.gen';
import { browseDashboardsAPI } from 'app/features/browse-dashboards/api/browseDashboardsAPI';
import { getLibraryPanel } from 'app/features/library-panels/state/api';
@ -16,7 +16,13 @@ import { LibraryElementDTO } from '../../library-panels/types';
import { DashboardJson } from '../types';
import { validateDashboardJson } from '../utils/validation';
import { getLibraryPanelInputs, importDashboard, processDashboard, processV2Datasources } from './actions';
import {
getLibraryPanelInputs,
importDashboard,
processDashboard,
processV2DatasourceInput,
processV2Datasources,
} from './actions';
import { DataSourceInput, ImportDashboardDTO, initialImportDashboardState, InputType } from './reducers';
jest.mock('app/features/library-panels/state/api');
@ -29,7 +35,7 @@ jest.mock('@grafana/runtime', () => ({
getDataSourceSrv: () => ({
...jest.requireActual('@grafana/runtime').getDataSourceSrv(),
get: jest.fn().mockImplementation((dsType: { type: string }) => {
const dsList: {
const dsListTypeDSMock: {
[key: string]: {
uid: string;
name: string;
@ -55,8 +61,15 @@ jest.mock('@grafana/runtime', () => ({
type: 'grafana',
meta: { id: 'grafana' },
},
// "datasource" type is what we call "--Dashboard--" datasource
datasource: {
uid: '--Dashboard--',
name: '--Dashboard--',
type: 'datasource',
meta: { id: 'dashboard' },
},
};
return dsList[dsType.type];
return dsListTypeDSMock[dsType.type];
}),
}),
}));
@ -959,3 +972,43 @@ describe('processV2Datasources', () => {
);
});
});
describe('processV2DatasourceInput', () => {
// should not map grafana datasource input or dashboard datasource input
it('Should not map grafana datasource input', async () => {
const queryVariable = {
kind: 'QueryVariable',
spec: {
...defaultQueryVariableSpec(),
name: 'var2WithGrafanaDs',
query: {
kind: 'grafana',
spec: {
panelId: 2,
},
},
},
};
const result = await processV2DatasourceInput(queryVariable.spec, {});
expect(result).toEqual({});
});
it('Should not map dashboard datasource input', async () => {
// create a panel with dashboard datasource input
const panelQuery = {
kind: 'PanelQuery',
spec: {
refId: 'A',
hidden: false,
query: {
kind: 'datasource',
spec: {
panelId: 2,
},
},
},
};
const result = await processV2DatasourceInput(panelQuery.spec, {});
expect(result).toEqual({});
});
});

@ -162,26 +162,26 @@ export function processV2Datasources(dashboard: DashboardV2Spec): ThunkResult<vo
const { elements, variables, annotations } = dashboard;
// get elements from dashboard
// each element can only be a panel
const inputs: Record<string, DataSourceInput> = {};
let inputs: Record<string, DataSourceInput> = {};
for (const element of Object.values(elements)) {
if (element.kind !== 'Panel') {
throw new Error('Only panels are currenlty supported in v2 dashboards');
}
if (element.spec.data.spec.queries.length > 0) {
for (const query of element.spec.data.spec.queries) {
await processV2DatasourceInput(query.spec, inputs);
inputs = await processV2DatasourceInput(query.spec, inputs);
}
}
}
for (const variable of variables) {
if (variable.kind === 'QueryVariable') {
await processV2DatasourceInput(variable.spec, inputs);
inputs = await processV2DatasourceInput(variable.spec, inputs);
}
}
for (const annotation of annotations) {
await processV2DatasourceInput(annotation.spec, inputs);
inputs = await processV2DatasourceInput(annotation.spec, inputs);
}
dispatch(setInputs(Object.values(inputs)));
@ -337,6 +337,12 @@ export async function processV2DatasourceInput(
const datasourceRef = obj?.datasource;
if (!datasourceRef && obj?.query) {
const dsType = obj.query.kind;
// if dsType is grafana, it means we are using a built-in annotation or default grafana datasource, in those
// cases we don't need to map it
// "datasource" type is what we call "--Dashboard--" datasource <.-.>
if (dsType === 'grafana' || dsType === 'datasource') {
return inputs;
}
const datasource = await getDatasourceSrv().get({ type: dsType });
let dataSourceInput: DataSourceInput | undefined;
if (datasource) {
@ -363,4 +369,5 @@ export async function processV2DatasourceInput(
inputs[dsType] = dataSourceInput;
}
}
return inputs;
}

Loading…
Cancel
Save