Dashboard: replace datasource name with a reference object (#33817)

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
Co-authored-by: Elfo404 <me@giordanoricci.com>
This commit is contained in:
Ryan McKinley
2021-10-29 10:57:24 -07:00
committed by GitHub
parent 61fbdb60ff
commit 7319efe077
78 changed files with 759 additions and 320 deletions

View File

@@ -121,7 +121,7 @@ export class QueryEditorRow<TQuery extends DataQuery> extends PureComponent<Prop
getQueryDataSourceIdentifier(): string | null | undefined {
const { query, dataSource: dsSettings } = this.props;
return query.datasource ?? dsSettings.name;
return query.datasource?.uid ?? dsSettings.uid;
}
async loadDatasource() {

View File

@@ -3,12 +3,20 @@ import { fireEvent, render, screen } from '@testing-library/react';
import { Props, QueryEditorRowHeader } from './QueryEditorRowHeader';
import { DataSourceInstanceSettings } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { mockDataSource } from 'app/features/alerting/unified/mocks';
import { DataSourceType } from 'app/features/alerting/unified/utils/datasource';
const mockDS = mockDataSource({
name: 'CloudManager',
type: DataSourceType.Alertmanager,
});
jest.mock('@grafana/runtime/src/services/dataSourceSrv', () => {
return {
getDataSourceSrv: () => ({
getInstanceSettings: jest.fn(),
getList: jest.fn().mockReturnValue([]),
get: () => Promise.resolve(mockDS),
getList: () => [mockDS],
getInstanceSettings: () => mockDS,
}),
};
});

View File

@@ -67,7 +67,7 @@ export class QueryEditorRows extends PureComponent<Props> {
if (previous?.type === dataSource.type) {
return {
...item,
datasource: dataSource.name,
datasource: { uid: dataSource.uid },
};
}
}
@@ -75,7 +75,7 @@ export class QueryEditorRows extends PureComponent<Props> {
return {
refId: item.refId,
hide: item.hide,
datasource: dataSource.name,
datasource: { uid: dataSource.uid },
};
})
);

View File

@@ -22,6 +22,7 @@ import {
DataQuery,
DataSourceApi,
DataSourceInstanceSettings,
DataSourceRef,
getDefaultTimeRange,
LoadingState,
PanelData,
@@ -91,7 +92,8 @@ export class QueryGroup extends PureComponent<Props, State> {
const ds = await this.dataSourceSrv.get(options.dataSource.name);
const dsSettings = this.dataSourceSrv.getInstanceSettings(options.dataSource.name);
const defaultDataSource = await this.dataSourceSrv.get();
const queries = options.queries.map((q) => (q.datasource ? q : { ...q, datasource: dsSettings?.name }));
const datasource: DataSourceRef = { type: ds.type, uid: ds.uid };
const queries = options.queries.map((q) => (q.datasource ? q : { ...q, datasource }));
this.setState({ queries, dataSource: ds, dsSettings, defaultDataSource });
} catch (error) {
console.log('failed to load data source', error);
@@ -119,6 +121,7 @@ export class QueryGroup extends PureComponent<Props, State> {
dataSource: {
name: newSettings.name,
uid: newSettings.uid,
type: newSettings.meta.id,
default: newSettings.isDefault,
},
});
@@ -139,12 +142,10 @@ export class QueryGroup extends PureComponent<Props, State> {
newQuery(): Partial<DataQuery> {
const { dsSettings, defaultDataSource } = this.state;
if (!dsSettings?.meta.mixed) {
return { datasource: dsSettings?.name };
}
const ds = !dsSettings?.meta.mixed ? dsSettings : defaultDataSource;
return {
datasource: defaultDataSource?.name,
datasource: { uid: ds?.uid, type: ds?.type },
};
}
@@ -182,7 +183,7 @@ export class QueryGroup extends PureComponent<Props, State> {
<div className={styles.dataSourceRowItem}>
<DataSourcePicker
onChange={this.onChangeDataSource}
current={options.dataSource.name}
current={options.dataSource}
metrics={true}
mixed={true}
dashboard={true}
@@ -258,7 +259,7 @@ export class QueryGroup extends PureComponent<Props, State> {
onAddQuery = (query: Partial<DataQuery>) => {
const { dsSettings, queries } = this.state;
this.onQueriesChange(addQuery(queries, query, dsSettings?.name));
this.onQueriesChange(addQuery(queries, query, { type: dsSettings?.type, uid: dsSettings?.uid }));
this.onScrollBottom();
};

View File

@@ -108,6 +108,7 @@ function describeQueryRunnerScenario(
const datasource: any = {
name: 'TestDB',
uid: 'TestDB-uid',
interval: ctx.dsInterval,
query: (options: grafanaData.DataQueryRequest) => {
ctx.queryCalledWith = options;
@@ -156,8 +157,8 @@ describe('PanelQueryRunner', () => {
expect(ctx.queryCalledWith?.requestId).toBe('Q100');
});
it('should set datasource name on request', async () => {
expect(ctx.queryCalledWith?.targets[0].datasource).toBe('TestDB');
it('should set datasource uid on request', async () => {
expect(ctx.queryCalledWith?.targets[0].datasource?.uid).toBe('TestDB-uid');
});
it('should pass scopedVars to datasource with interval props', async () => {

View File

@@ -21,6 +21,7 @@ import {
DataQueryRequest,
DataSourceApi,
DataSourceJsonData,
DataSourceRef,
DataTransformerConfig,
LoadingState,
PanelData,
@@ -38,7 +39,7 @@ export interface QueryRunnerOptions<
TQuery extends DataQuery = DataQuery,
TOptions extends DataSourceJsonData = DataSourceJsonData
> {
datasource: string | DataSourceApi<TQuery, TOptions> | null;
datasource: DataSourceRef | DataSourceApi<TQuery, TOptions> | null;
queries: TQuery[];
panelId?: number;
dashboardId?: number;
@@ -223,7 +224,7 @@ export class PanelQueryRunner {
// Attach the data source name to each query
request.targets = request.targets.map((query) => {
if (!query.datasource) {
query.datasource = ds.name;
query.datasource = { uid: ds.uid };
}
return query;
});
@@ -326,7 +327,7 @@ export class PanelQueryRunner {
}
async function getDataSource(
datasource: string | DataSourceApi | null,
datasource: DataSourceRef | string | DataSourceApi | null,
scopedVars: ScopedVars
): Promise<DataSourceApi> {
if (datasource && (datasource as any).query) {

View File

@@ -8,6 +8,7 @@ import {
QueryRunnerOptions,
QueryRunner as QueryRunnerSrv,
LoadingState,
DataSourceRef,
} from '@grafana/data';
import { getTemplateSrv } from '@grafana/runtime';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
@@ -78,7 +79,7 @@ export class QueryRunner implements QueryRunnerSrv {
// Attach the datasource name to each query
request.targets = request.targets.map((query) => {
if (!query.datasource) {
query.datasource = ds.name;
query.datasource = ds.getRef();
}
return query;
});
@@ -140,11 +141,11 @@ export class QueryRunner implements QueryRunnerSrv {
}
async function getDataSource(
datasource: string | DataSourceApi | null,
datasource: DataSourceRef | DataSourceApi | null,
scopedVars: ScopedVars
): Promise<DataSourceApi> {
if (datasource && (datasource as any).query) {
return datasource as DataSourceApi;
}
return await getDatasourceSrv().get(datasource as string, scopedVars);
return await getDatasourceSrv().get(datasource, scopedVars);
}