From 0836f71da617924c43453cfe305f457f3c522dfa Mon Sep 17 00:00:00 2001 From: Dominik Prokop Date: Fri, 3 Jan 2025 10:25:06 +0100 Subject: [PATCH] Schema v2 queries transformation: Respect panel defined data source (#98444) --- .../api/ResponseTransformers.test.ts | 73 ++++++++++++++++++- .../dashboard/api/ResponseTransformers.ts | 23 ++++-- 2 files changed, 89 insertions(+), 7 deletions(-) diff --git a/public/app/features/dashboard/api/ResponseTransformers.test.ts b/public/app/features/dashboard/api/ResponseTransformers.test.ts index 6dc7dea62e8..5dba3a6cf3f 100644 --- a/public/app/features/dashboard/api/ResponseTransformers.test.ts +++ b/public/app/features/dashboard/api/ResponseTransformers.test.ts @@ -1,3 +1,4 @@ +import { DataQuery } from '@grafana/schema'; import { DashboardV2Spec } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha0/dashboard.gen'; import { AnnoKeyCreatedBy, @@ -9,7 +10,7 @@ import { } from 'app/features/apiserver/types'; import { DashboardDataDTO, DashboardDTO } from 'app/types'; -import { ResponseTransformers } from './ResponseTransformers'; +import { getPanelQueries, ResponseTransformers } from './ResponseTransformers'; import { DashboardWithAccessInfo } from './types'; describe('ResponseTransformers', () => { @@ -258,4 +259,74 @@ describe('ResponseTransformers', () => { expect(dashboard.annotations).toEqual({ list: [] }); }); }); + + describe('getPanelQueries', () => { + it('respects targets data source', () => { + const panelDs = { + type: 'theoretical-ds', + uid: 'theoretical-uid', + }; + const targets: DataQuery[] = [ + { + refId: 'A', + datasource: { + type: 'theoretical-ds', + uid: 'theoretical-uid', + }, + }, + { + refId: 'B', + datasource: { + type: 'theoretical-ds', + uid: 'theoretical-uid', + }, + }, + ]; + + const result = getPanelQueries(targets, panelDs); + + expect(result).toHaveLength(targets.length); + expect(result[0].spec.refId).toBe('A'); + expect(result[1].spec.refId).toBe('B'); + + result.forEach((query) => { + expect(query.kind).toBe('PanelQuery'); + expect(query.spec.datasource).toEqual({ + type: 'theoretical-ds', + uid: 'theoretical-uid', + }); + expect(query.spec.query.kind).toBe('theoretical-ds'); + }); + }); + + it('respects panel data source', () => { + const panelDs = { + type: 'theoretical-ds', + uid: 'theoretical-uid', + }; + const targets: DataQuery[] = [ + { + refId: 'A', + }, + { + refId: 'B', + }, + ]; + + const result = getPanelQueries(targets, panelDs); + + expect(result).toHaveLength(targets.length); + expect(result[0].spec.refId).toBe('A'); + expect(result[1].spec.refId).toBe('B'); + + result.forEach((query) => { + expect(query.kind).toBe('PanelQuery'); + expect(query.spec.datasource).toEqual({ + type: 'theoretical-ds', + uid: 'theoretical-uid', + }); + expect(query.spec.query.kind).toBe('theoretical-ds'); + }); + }); + }); }); diff --git a/public/app/features/dashboard/api/ResponseTransformers.ts b/public/app/features/dashboard/api/ResponseTransformers.ts index 13b35d94e49..af4e61bd76f 100644 --- a/public/app/features/dashboard/api/ResponseTransformers.ts +++ b/public/app/features/dashboard/api/ResponseTransformers.ts @@ -1,5 +1,5 @@ import { config } from '@grafana/runtime'; -import { AnnotationQuery, DataQuery, Panel, VariableModel } from '@grafana/schema'; +import { AnnotationQuery, DataQuery, DataSourceRef, Panel, VariableModel } from '@grafana/schema'; import { AnnotationQueryKind, DashboardV2Spec, @@ -223,7 +223,7 @@ function getElementsFromPanels(panels: Panel[]): [DashboardV2Spec['elements'], D for (const p of panels) { const queries = getPanelQueries( (p.targets as unknown as DataQuery[]) || [], - p.datasource?.type || getDefaultDatasourceType() + p.datasource || getDefaultDatasource() ); const transformations = getPanelTransformations(p.transformations || []); @@ -291,7 +291,19 @@ function getDefaultDatasourceType() { return Object.values(datasources).find((ds) => ds.isDefault)!.type; } -function getPanelQueries(targets: DataQuery[], panelDatasourceType: string): PanelQueryKind[] { +function getDefaultDatasource(): DataSourceRef { + const datasources = config.datasources; + + // find default datasource in datasources + const defaultDs = Object.values(datasources).find((ds) => ds.isDefault)!; + return { + apiVersion: defaultDs.apiVersion, + type: defaultDs.type, + uid: defaultDs.uid, + }; +} + +export function getPanelQueries(targets: DataQuery[], panelDatasource: DataSourceRef): PanelQueryKind[] { return targets.map((t) => { const { refId, hide, datasource, ...query } = t; const q: PanelQueryKind = { @@ -299,10 +311,9 @@ function getPanelQueries(targets: DataQuery[], panelDatasourceType: string): Pan spec: { refId: t.refId, hidden: t.hide ?? false, - // TODO[schema v2]: ds coming from panel ?!?!!?! AAAAAAAAAAAAA! Send help! - datasource: t.datasource ? t.datasource : undefined, + datasource: t.datasource ? t.datasource : panelDatasource, query: { - kind: t.datasource?.type || panelDatasourceType, + kind: t.datasource?.type || panelDatasource.type!, spec: { ...query, },