mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
@@ -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() {
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -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 },
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user