From 9920f4b4374ad8d234fba191ada6e20edb889b15 Mon Sep 17 00:00:00 2001 From: Dominik Prokop Date: Fri, 5 Sep 2025 11:30:13 +0200 Subject: [PATCH] DatasourceSrv: Fix getInstanceSettings for type-only datasource references (#110612) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Add handling for type-only refs like {type: 'prometheus'} in getInstanceSettings() • Ensure consistency with get() method behavior • Add test case verifying both methods return same results for type-only refs --- .../features/plugins/datasource_srv.test.ts | 13 +++++++++ public/app/features/plugins/datasource_srv.ts | 29 +++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/public/app/features/plugins/datasource_srv.test.ts b/public/app/features/plugins/datasource_srv.test.ts index 9734aaa9b02..eaa8c15c5f3 100644 --- a/public/app/features/plugins/datasource_srv.test.ts +++ b/public/app/features/plugins/datasource_srv.test.ts @@ -299,6 +299,19 @@ describe('datasource_srv', () => { const settings = dataSourceSrv.getInstanceSettings(runtimeDataSource.name); expect(settings).toBe(undefined); }); + + it('should handle type-only datasource references consistently', async () => { + const typeOnlyRef = { type: 'jaeger-db' }; + + const datasource = await dataSourceSrv.get(typeOnlyRef); + const settings = dataSourceSrv.getInstanceSettings(typeOnlyRef); + + expect(datasource.uid).toBe('uid-code-Jaeger'); + expect(datasource.type).toBe('jaeger-db'); + expect(settings?.uid).toBe(datasource.uid); + expect(settings?.type).toBe(datasource.type); + expect(settings?.name).toBe('Jaeger'); + }); }); describe('when loading datasource', () => { diff --git a/public/app/features/plugins/datasource_srv.ts b/public/app/features/plugins/datasource_srv.ts index a7d081244c6..99dda9e89a1 100644 --- a/public/app/features/plugins/datasource_srv.ts +++ b/public/app/features/plugins/datasource_srv.ts @@ -107,6 +107,14 @@ export class DatasourceSrv implements DataSourceService { } if (nameOrUid === 'default' || nameOrUid == null) { + // Handle type-only datasource references (e.g., {type: 'prometheus'}) + if (isDatasourceRef(ref) && ref.type) { + const ds = this.findDatasourceByType(ref.type); + if (ds) { + return ds; + } + } + // Fall back to default datasource if no type match found return this.settingsMapByUid[this.defaultName] ?? this.settingsMapByName[this.defaultName]; } @@ -143,13 +151,12 @@ export class DatasourceSrv implements DataSourceService { get(ref?: string | DataSourceRef | null, scopedVars?: ScopedVars): Promise { let nameOrUid = getNameOrUid(ref); if (!nameOrUid) { - // type exists, but not the other properties - if (isDatasourceRef(ref)) { - const settings = this.getList({ type: ref.type }); - if (!settings?.length) { + // Handle type-only datasource references + if (isDatasourceRef(ref) && ref.type) { + const ds = this.findDatasourceByType(ref.type); + if (!ds) { return Promise.reject('no datasource of type'); } - const ds = settings.find((v) => v.isDefault) ?? settings[0]; return this.get(ds.uid); } return this.get(this.defaultName); @@ -184,6 +191,18 @@ export class DatasourceSrv implements DataSourceService { return this.loadDatasource(nameOrUid); } + /** + * Finds the best datasource instance settings for a given type. + * Prefers the default datasource of that type, otherwise returns the first one found. + */ + private findDatasourceByType(type: string): DataSourceInstanceSettings | undefined { + const settings = this.getList({ type }); + if (!settings?.length) { + return undefined; + } + return settings.find((v) => v.isDefault) ?? settings[0]; + } + async loadDatasource(key: string): Promise { if (this.datasources[key]) { return Promise.resolve(this.datasources[key]);