diff --git a/packages/grafana-runtime/src/services/dataSourceSrv.ts b/packages/grafana-runtime/src/services/dataSourceSrv.ts index d56db7f27cb..31baf9a9f5e 100644 --- a/packages/grafana-runtime/src/services/dataSourceSrv.ts +++ b/packages/grafana-runtime/src/services/dataSourceSrv.ts @@ -24,7 +24,10 @@ export interface DataSourceSrv { /** * Get settings and plugin metadata by name or uid */ - getInstanceSettings(ref?: DataSourceRef | string | null): DataSourceInstanceSettings | undefined; + getInstanceSettings( + ref?: DataSourceRef | string | null, + scopedVars?: ScopedVars + ): DataSourceInstanceSettings | undefined; } /** @public */ diff --git a/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts b/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts index a9271e937a6..844e2a7ee0c 100644 --- a/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts +++ b/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts @@ -119,7 +119,7 @@ class DataSourceWithBackend< } if (q.datasource) { - const ds = getDataSourceSrv().getInstanceSettings(q.datasource); + const ds = getDataSourceSrv().getInstanceSettings(q.datasource, request.scopedVars); if (!ds) { throw new Error(`Unknown Datasource: ${JSON.stringify(q.datasource)}`); diff --git a/public/app/features/plugins/datasource_srv.ts b/public/app/features/plugins/datasource_srv.ts index 44a2500c82b..dd17b7faa0d 100644 --- a/public/app/features/plugins/datasource_srv.ts +++ b/public/app/features/plugins/datasource_srv.ts @@ -62,7 +62,10 @@ export class DatasourceSrv implements DataSourceService { return this.settingsMapByUid[uid]; } - getInstanceSettings(ref: string | null | undefined | DataSourceRef): DataSourceInstanceSettings | undefined { + getInstanceSettings( + ref: string | null | undefined | DataSourceRef, + scopedVars?: ScopedVars + ): DataSourceInstanceSettings | undefined { const isstring = typeof ref === 'string'; let nameOrUid = isstring ? (ref as string) : ((ref as any)?.uid as string | undefined); @@ -81,7 +84,7 @@ export class DatasourceSrv implements DataSourceService { // Complex logic to support template variable data source names // For this we just pick the current or first data source in the variable if (nameOrUid[0] === '$') { - const interpolatedName = this.templateSrv.replace(nameOrUid, {}, variableInterpolation); + const interpolatedName = this.templateSrv.replace(nameOrUid, scopedVars, variableInterpolation); let dsSettings; diff --git a/public/app/features/plugins/tests/datasource_srv.test.ts b/public/app/features/plugins/tests/datasource_srv.test.ts index a471af2b66e..9af0de14ff1 100644 --- a/public/app/features/plugins/tests/datasource_srv.test.ts +++ b/public/app/features/plugins/tests/datasource_srv.test.ts @@ -1,5 +1,11 @@ import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { DataSourceApi, DataSourceInstanceSettings, DataSourcePlugin, DataSourcePluginMeta } from '@grafana/data'; +import { + DataSourceApi, + DataSourceInstanceSettings, + DataSourcePlugin, + DataSourcePluginMeta, + ScopedVar, +} from '@grafana/data'; // Datasource variable $datasource with current value 'BBB' const templateSrv: any = { @@ -19,7 +25,11 @@ const templateSrv: any = { }, }, ], - replace: (v: string) => { + replace: (v: string, scopedVars: ScopedVar) => { + if (scopedVars && scopedVars.datasource) { + return v.replace('${datasource}', scopedVars.datasource.value); + } + let result = v.replace('${datasource}', 'BBB'); result = result.replace('${datasourceDefault}', 'default'); return result; @@ -124,6 +134,14 @@ describe('datasource_srv', () => { expect(instance.uid).toBe('uid-code-mmm'); expect(instance.getRef()).toEqual({ type: 'test-db', uid: 'uid-code-mmm' }); }); + + it('Can get by variable', async () => { + const ds = (await dataSourceSrv.get('${datasource}')) as any; + expect(ds.meta).toBe(dataSourceInit.BBB.meta); + + const ds2 = await dataSourceSrv.get('${datasource}', { datasource: { text: 'Prom', value: 'uid-code-aaa' } }); + expect(ds2.uid).toBe(dataSourceInit.aaa.uid); + }); }); describe('when getting instance settings', () => { @@ -145,6 +163,13 @@ describe('datasource_srv', () => { `); }); + it('should work with variable via scopedVars', () => { + const ds = dataSourceSrv.getInstanceSettings('${datasource}', { + datasource: { text: 'Prom', value: 'uid-code-aaa' }, + }); + expect(ds?.rawRef?.uid).toBe('uid-code-aaa'); + }); + it('should not set isDefault when being fetched via variable', () => { const ds = dataSourceSrv.getInstanceSettings('${datasource}'); expect(ds?.isDefault).toBe(false);