diff --git a/.betterer.results b/.betterer.results
index 730dabb6942..0f6c8fba7a6 100644
--- a/.betterer.results
+++ b/.betterer.results
@@ -2824,6 +2824,11 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with ", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "2"]
],
+ "public/app/features/plugins/datasource_srv.test.ts:5381": [
+ [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
+ [0, 0, 0, "Unexpected any. Specify a different type.", "1"],
+ [0, 0, 0, "Unexpected any. Specify a different type.", "2"]
+ ],
"public/app/features/plugins/datasource_srv.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
@@ -2847,11 +2852,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"]
],
- "public/app/features/plugins/tests/datasource_srv.test.ts:5381": [
- [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
- [0, 0, 0, "Unexpected any. Specify a different type.", "1"],
- [0, 0, 0, "Unexpected any. Specify a different type.", "2"]
- ],
"public/app/features/plugins/utils.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
diff --git a/public/app/features/plugins/tests/datasource_srv.test.ts b/public/app/features/plugins/datasource_srv.test.ts
similarity index 95%
rename from public/app/features/plugins/tests/datasource_srv.test.ts
rename to public/app/features/plugins/datasource_srv.test.ts
index c23f4d9cd6b..4d2592ea4b6 100644
--- a/public/app/features/plugins/tests/datasource_srv.test.ts
+++ b/public/app/features/plugins/datasource_srv.test.ts
@@ -61,7 +61,7 @@ class TestRuntimeDataSource extends RuntimeDataSource {
}
}
-jest.mock('../plugin_loader', () => ({
+jest.mock('./plugin_loader', () => ({
importDataSourcePlugin: (meta: DataSourcePluginMeta) => {
return Promise.resolve(new DataSourcePlugin(TestDataSource as any));
},
@@ -90,17 +90,17 @@ describe('datasource_srv', () => {
meta: { metrics: true, annotations: true },
},
'-- Grafana --': {
- type: 'grafana',
+ type: 'datasource',
name: '-- Grafana --',
meta: { builtIn: true, metrics: true, id: 'grafana' },
},
'-- Dashboard --': {
- type: 'dashboard',
+ type: 'datasource',
name: '-- Dashboard --',
meta: { builtIn: true, metrics: true, id: 'dashboard' },
},
'-- Mixed --': {
- type: 'test-db',
+ type: 'datasource',
name: '-- Mixed --',
meta: { builtIn: true, metrics: true, id: 'mixed' },
},
@@ -144,6 +144,7 @@ describe('datasource_srv', () => {
TestData: {
type: 'grafana-testdata-datasource',
name: 'TestData',
+ uid: 'testdata',
meta: { metrics: true, id: 'grafana-testdata-datasource', aliasIDs: ['testdata'] },
},
};
@@ -312,6 +313,20 @@ describe('datasource_srv', () => {
});
});
+ describe('when getting datasource by type', () => {
+ it('should return the first value of each type', async () => {
+ const jaeger = await dataSourceSrv.get({ type: `jaeger-db` });
+ const testdata = await dataSourceSrv.get({ type: `grafana-testdata-datasource` });
+ expect(jaeger.uid).toBe('uid-code-Jaeger');
+ expect(testdata.uid).toBe('testdata');
+ });
+
+ it('should prefer the default value', async () => {
+ const api = await dataSourceSrv.get({ type: `test-db` });
+ expect(api.uid).toBe('uid-code-BBB');
+ });
+ });
+
it('Should by default filter out data sources that cannot be queried', () => {
const list = dataSourceSrv.getList({});
expect(list.find((x) => x.name === 'no-query')).toBeUndefined();
@@ -407,7 +422,7 @@ describe('datasource_srv', () => {
},
"name": "TestData",
"type": "grafana-testdata-datasource",
- "uid": "TestData",
+ "uid": "testdata",
},
{
"meta": {
@@ -424,7 +439,7 @@ describe('datasource_srv', () => {
"metrics": true,
},
"name": "-- Mixed --",
- "type": "test-db",
+ "type": "datasource",
"uid": "-- Mixed --",
},
{
@@ -434,7 +449,7 @@ describe('datasource_srv', () => {
"metrics": true,
},
"name": "-- Dashboard --",
- "type": "dashboard",
+ "type": "datasource",
"uid": "-- Dashboard --",
},
{
@@ -444,7 +459,7 @@ describe('datasource_srv', () => {
"metrics": true,
},
"name": "-- Grafana --",
- "type": "grafana",
+ "type": "datasource",
"uid": "-- Grafana --",
},
]
diff --git a/public/app/features/plugins/datasource_srv.ts b/public/app/features/plugins/datasource_srv.ts
index e145a2e8db0..15b0fe15bd0 100644
--- a/public/app/features/plugins/datasource_srv.ts
+++ b/public/app/features/plugins/datasource_srv.ts
@@ -5,6 +5,7 @@ import {
DataSourceRef,
DataSourceSelectItem,
ScopedVars,
+ isObject,
matchPluginId,
} from '@grafana/data';
import {
@@ -142,6 +143,15 @@ 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) {
+ 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);
}
@@ -385,6 +395,13 @@ export function variableInterpolation(value: T | T[]) {
return value;
}
+const isDatasourceRef = (ref: string | DataSourceRef | null | undefined): ref is DataSourceRef => {
+ if (ref && isObject(ref) && 'type' in ref) {
+ return true;
+ }
+ return false;
+};
+
export const getDatasourceSrv = (): DatasourceSrv => {
return getDataSourceService() as DatasourceSrv;
};