Dashboards: SchemaV2 - Fix default datasource logic (#98573)

Get defaultDatasource config option from config.bootData.settings.defaultDatasource
This commit is contained in:
Alexa V 2025-01-09 10:51:53 +01:00 committed by GitHub
parent fb5783691d
commit f04d72a49c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 89 additions and 14 deletions

View File

@ -443,7 +443,7 @@ export function getAnnotationQueryKind(annotationQuery: AnnotationQuery): string
}
}
function getDefaultDataSourceRef(): DataSourceRef | undefined {
export function getDefaultDataSourceRef(): DataSourceRef | undefined {
// we need to return the default datasource configured in the BootConfig
const defaultDatasource = config.bootData.settings.defaultDatasource;

View File

@ -9,12 +9,72 @@ import {
AnnoKeyUpdatedBy,
AnnoKeyUpdatedTimestamp,
} from 'app/features/apiserver/types';
import { getDefaultDataSourceRef } from 'app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2';
import { DashboardDataDTO, DashboardDTO } from 'app/types';
import { getPanelQueries, ResponseTransformers } from './ResponseTransformers';
import { getDefaultDatasource, getPanelQueries, ResponseTransformers } from './ResponseTransformers';
import { DashboardWithAccessInfo } from './types';
jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
config: {
...jest.requireActual('@grafana/runtime').config,
bootData: {
...jest.requireActual('@grafana/runtime').config.bootData,
settings: {
...jest.requireActual('@grafana/runtime').config.bootData.settings,
datasources: {
PromTest: {
uid: 'xyz-abc',
name: 'PromTest',
id: 'prometheus',
meta: {
id: 'prometheus',
name: 'PromTest',
type: 'datasource',
},
isDefault: true,
apiVersion: 'v2',
},
'-- Grafana --': {
uid: 'grafana',
name: '-- Grafana --',
id: 'grafana',
meta: {
id: 'grafana',
name: '-- Grafana --',
type: 'datasource',
},
isDefault: false,
},
},
defaultDatasource: 'PromTest',
},
},
},
}));
describe('ResponseTransformers', () => {
describe('getDefaultDataSource', () => {
it('should return prometheus as default', () => {
expect(getDefaultDatasource()).toEqual({
apiVersion: 'v2',
uid: 'PromTest',
type: 'prometheus',
});
});
});
describe('getDefaultDataSourceRef', () => {
it('should return prometheus as default', () => {
expect(getDefaultDataSourceRef()).toEqual({
uid: 'PromTest',
type: 'prometheus',
});
});
});
describe('v1 -> v2 transformation', () => {
it('should transform DashboardDTO to DashboardWithAccessInfo<DashboardV2Spec>', () => {
const dashboardV1: DashboardDataDTO = {

View File

@ -22,6 +22,7 @@ import {
AnnoKeyUpdatedBy,
AnnoKeyUpdatedTimestamp,
} from 'app/features/apiserver/types';
import { getDefaultDataSourceRef } from 'app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2';
import { transformCursorSyncV2ToV1 } from 'app/features/dashboard-scene/serialization/transformToV1TypesUtils';
import {
transformCursorSynctoEnum,
@ -226,6 +227,11 @@ function getElementsFromPanels(panels: Panel[]): [DashboardV2Spec['elements'], D
// iterate over panels
for (const p of panels) {
// FIXME: for now we should skip row panels
if (p.type === 'row') {
continue;
}
const queries = getPanelQueries(
(p.targets as unknown as DataQuery[]) || [],
p.datasource || getDefaultDatasource()
@ -291,20 +297,23 @@ function getElementsFromPanels(panels: Panel[]): [DashboardV2Spec['elements'], D
}
function getDefaultDatasourceType() {
const datasources = config.datasources;
// find default datasource in datasources
return Object.values(datasources).find((ds) => ds.isDefault)!.type;
// if there is no default datasource, return 'grafana' as default
return getDefaultDataSourceRef()?.type ?? 'grafana';
}
function getDefaultDatasource(): DataSourceRef {
const datasources = config.datasources;
export function getDefaultDatasource(): DataSourceRef {
const configDefaultDS = getDefaultDataSourceRef() ?? { type: 'grafana', uid: '-- Grafana --' };
if (configDefaultDS.uid && !configDefaultDS.apiVersion) {
// get api version from config
const dsInstance = config.bootData.settings.datasources[configDefaultDS.uid];
configDefaultDS.apiVersion = dsInstance.apiVersion ?? undefined;
}
// find default datasource in datasources
const defaultDs = Object.values(datasources).find((ds) => ds.isDefault)!;
return {
apiVersion: defaultDs.apiVersion,
type: defaultDs.type,
uid: defaultDs.uid,
apiVersion: configDefaultDS.apiVersion,
type: configDefaultDS.type,
uid: configDefaultDS.uid,
};
}
@ -407,7 +416,8 @@ function getVariables(vars: VariableModel[]): DashboardV2Spec['variables'] {
variables.push(dv);
break;
default:
throw new Error(`Variable transformation not implemented: ${v.type}`);
// do not throw error, just log it
console.error(`Variable transformation not implemented: ${v.type}`);
}
}
return variables;

View File

@ -88,12 +88,14 @@ const saveDashboardResponse = {
},
};
jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
getBackendSrv: () => ({
get: () => mockDashboardDto,
put: jest.fn().mockResolvedValue(saveDashboardResponse),
post: jest.fn().mockResolvedValue(saveDashboardResponse),
}),
config: {
...jest.requireActual('@grafana/runtime').config,
buildInfo: {
version: '11.5.0-test-version-string',
},

View File

@ -27,10 +27,13 @@ const mockDashboardDto: DashboardWithAccessInfo<DashboardV2Spec> = {
};
jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
getBackendSrv: () => ({
get: () => mockDashboardDto,
}),
config: {},
config: {
...jest.requireActual('@grafana/runtime').config,
},
}));
jest.mock('app/features/live/dashboard/dashboardWatcher', () => ({