Add optional APIVersion to DatasourceRef (#90076)

This commit is contained in:
Andres Martinez Gotor 2024-07-08 13:12:56 +02:00 committed by GitHub
parent 96cdce7f72
commit 2b7338f8b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 88 additions and 68 deletions

View File

@ -1,6 +1,8 @@
import { ComponentType } from 'react';
import { Observable } from 'rxjs';
import { DataSourceRef } from '@grafana/schema';
import { makeClassES5Compatible } from '../utils/makeClassES5Compatible';
import { ScopedVars } from './ScopedVars';
@ -11,7 +13,7 @@ import { KeyValue, LoadingState, TableData, TimeSeries } from './data';
import { DataFrame, DataFrameDTO } from './dataFrame';
import { PanelData } from './panel';
import { GrafanaPlugin, PluginMeta } from './plugin';
import { DataQuery, DataSourceRef } from './query';
import { DataQuery } from './query';
import { Scope } from './scopes';
import { AdHocVariableFilter } from './templateVars';
import { RawTimeRange, TimeRange } from './time';
@ -217,6 +219,11 @@ abstract class DataSourceApi<
*/
readonly uid: string;
/**
* Set in constructor
*/
readonly apiVersion?: string;
/**
* min interval range
*/
@ -229,6 +236,7 @@ abstract class DataSourceApi<
this.meta = instanceSettings.meta;
this.cachingConfig = instanceSettings.cachingConfig;
this.uid = instanceSettings.uid;
this.apiVersion = instanceSettings.apiVersion;
}
/**
@ -322,7 +330,11 @@ abstract class DataSourceApi<
/** Get an identifier object for this datasource instance */
getRef(): DataSourceRef {
return { type: this.type, uid: this.uid };
const ref: DataSourceRef = { type: this.type, uid: this.uid };
if (this.apiVersion) {
ref.apiVersion = this.apiVersion;
}
return ref;
}
/**
@ -660,6 +672,7 @@ export interface DataSourceInstanceSettings<T extends DataSourceJsonData = DataS
uid: string;
type: string;
name: string;
apiVersion?: string;
meta: DataSourcePluginMeta;
cachingConfig?: PluginQueryCachingConfig;
readOnly: boolean;

View File

@ -1,5 +1,7 @@
import { isString } from 'lodash';
import { DataSourceRef } from '@grafana/schema';
import { KeyValue } from '../types/data';
import {
DataSourceInstanceSettings,
@ -7,7 +9,6 @@ import {
DataSourcePluginOptionsEditorProps,
DataSourceSettings,
} from '../types/datasource';
import { DataSourceRef } from '../types/query';
import { SelectableValue } from '../types/select';
/**
@ -16,7 +17,11 @@ import { SelectableValue } from '../types/select';
* @public
*/
export function getDataSourceRef(ds: DataSourceInstanceSettings): DataSourceRef {
return { uid: ds.uid, type: ds.type };
const ref: DataSourceRef = { uid: ds.uid, type: ds.type };
if (ds.apiVersion) {
ref.apiVersion = ds.apiVersion;
}
return ref;
}
/**

View File

@ -861,6 +861,10 @@ export enum VariableFormatID {
}
export interface DataSourceRef {
/**
* Datasource API version
*/
apiVersion?: string;
/**
* The plugin type-id
*/

View File

@ -42,4 +42,6 @@ DataSourceRef: {
type?: string
// Specific datasource instance
uid?: string
// Datasource API version
apiVersion?: string
} @cuetsy(kind="interface")

View File

@ -5,6 +5,7 @@ import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd';
import {
DataQuery,
DataSourceInstanceSettings,
getDataSourceRef,
LoadingState,
PanelData,
rangeUtil,
@ -226,10 +227,7 @@ function copyModel(item: AlertQuery, settings: DataSourceInstanceSettings): Omit
...item,
model: {
...omit(item.model, 'datasource'),
datasource: {
type: settings.type,
uid: settings.uid,
},
datasource: getDataSourceRef(settings),
},
datasourceUid: settings.uid,
};
@ -244,10 +242,7 @@ function newModel(item: AlertQuery, settings: DataSourceInstanceSettings): Omit<
model: {
refId: item.refId,
hide: false,
datasource: {
type: settings.type,
uid: settings.uid,
},
datasource: getDataSourceRef(settings),
},
};
}

View File

@ -1,6 +1,13 @@
import { createAction, createReducer } from '@reduxjs/toolkit';
import { DataQuery, getDefaultRelativeTimeRange, getNextRefId, rangeUtil, RelativeTimeRange } from '@grafana/data';
import {
DataQuery,
getDataSourceRef,
getDefaultRelativeTimeRange,
getNextRefId,
rangeUtil,
RelativeTimeRange,
} from '@grafana/data';
import { findDataSourceFromExpressionRecursive } from 'app/features/alerting/unified/utils/dataSourceFromExpression';
import { dataSource as expressionDatasource } from 'app/features/expressions/ExpressionDatasource';
import { isExpressionQuery } from 'app/features/expressions/guards';
@ -64,10 +71,7 @@ export const queriesAndExpressionsReducer = createReducer(initialState, (builder
datasourceUid: datasource.uid,
model: {
refId: '',
datasource: {
type: datasource.type,
uid: datasource.uid,
},
datasource: getDataSourceRef(datasource),
},
});
})

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import { CoreApp, DataSourceApi, DataSourceInstanceSettings, IconName } from '@grafana/data';
import { CoreApp, DataSourceApi, DataSourceInstanceSettings, IconName, getDataSourceRef } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { config, getDataSourceSrv } from '@grafana/runtime';
import { SceneObjectBase, SceneComponentProps, sceneGraph, SceneQueryRunner } from '@grafana/scenes';
@ -81,8 +81,9 @@ export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabStat
: undefined,
dataSource: {
default: panelManager.state.dsSettings?.isDefault,
type: panelManager.state.dsSettings?.type,
uid: panelManager.state.dsSettings?.uid,
...(panelManager.state.dsSettings
? getDataSourceRef(panelManager.state.dsSettings)
: { type: undefined, uid: undefined }),
},
queries,
maxDataPoints: queryRunner.state.maxDataPoints,
@ -145,7 +146,9 @@ export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabStat
onAddQuery = (query: Partial<DataQuery>) => {
const queries = this.getQueries();
const dsSettings = this._panelManager.state.dsSettings;
this.onQueriesChange(addQuery(queries, query, { type: dsSettings?.type, uid: dsSettings?.uid }));
this.onQueriesChange(
addQuery(queries, query, dsSettings ? getDataSourceRef(dsSettings) : { type: undefined, uid: undefined })
);
};
isExpressionsSupported(dsSettings: DataSourceInstanceSettings): boolean {

View File

@ -9,6 +9,7 @@ import {
GrafanaTheme2,
PanelModel,
filterFieldConfigOverrides,
getDataSourceRef,
isStandardFieldProp,
restoreCustomOverrideRules,
} from '@grafana/data';
@ -159,8 +160,8 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
this.queryRunner.setState({
datasource: {
...getDataSourceRef(dsSettings),
uid: lastUsedDatasource?.datasourceUid,
type: dsSettings.type,
},
});
}
@ -173,12 +174,7 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
if (datasource && dsSettings) {
this.setState({ datasource, dsSettings });
storeLastUsedDataSourceInLocalStorage(
{
type: dsSettings.type,
uid: dsSettings.uid,
} || { default: true }
);
storeLastUsedDataSourceInLocalStorage(getDataSourceRef(dsSettings) || { default: true });
}
} catch (err) {
//set default datasource if we fail to load the datasource
@ -192,10 +188,7 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
});
this.queryRunner.setState({
datasource: {
uid: dsSettings.uid,
type: dsSettings.type,
},
datasource: getDataSourceRef(dsSettings),
});
}
@ -296,10 +289,7 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
const queries = defaultQueries || (await updateQueries(nextDS, newSettings.uid, currentQueries, currentDS));
queryRunner.setState({
datasource: {
type: newSettings.type,
uid: newSettings.uid,
},
datasource: getDataSourceRef(newSettings),
queries,
});
if (defaultQueries) {

View File

@ -1,9 +1,8 @@
import { useAsync } from 'react-use';
import { DataSourceInstanceSettings, MetricFindValue } from '@grafana/data';
import { DataSourceInstanceSettings, MetricFindValue, getDataSourceRef } from '@grafana/data';
import { getDataSourceSrv } from '@grafana/runtime';
import { AdHocFiltersVariable } from '@grafana/scenes';
import { DataSourceRef } from '@grafana/schema';
import { AdHocVariableForm } from '../components/AdHocVariableForm';
@ -25,10 +24,7 @@ export function AdHocFiltersVariableEditor(props: AdHocFiltersVariableEditorProp
: 'This data source does not support ad hoc filters yet.';
const onDataSourceChange = (ds: DataSourceInstanceSettings) => {
const dsRef: DataSourceRef = {
uid: ds.uid,
type: ds.type,
};
const dsRef = getDataSourceRef(ds);
variable.setState({
datasource: dsRef,

View File

@ -1,6 +1,6 @@
import { useAsync } from 'react-use';
import { DataSourceInstanceSettings, DataSourceRef, MetricFindValue } from '@grafana/data';
import { DataSourceInstanceSettings, MetricFindValue, getDataSourceRef } from '@grafana/data';
import { getDataSourceSrv } from '@grafana/runtime';
import { GroupByVariable } from '@grafana/scenes';
@ -24,10 +24,7 @@ export function GroupByVariableEditor(props: GroupByVariableEditorProps) {
: 'This data source does not support group by variable yet.';
const onDataSourceChange = async (ds: DataSourceInstanceSettings) => {
const dsRef: DataSourceRef = {
uid: ds.uid,
type: ds.type,
};
const dsRef = getDataSourceRef(ds);
variable.setState({ datasource: dsRef });
onRunQuery();

View File

@ -1,9 +1,9 @@
import { FormEvent } from 'react';
import * as React from 'react';
import { SelectableValue, DataSourceInstanceSettings } from '@grafana/data';
import { SelectableValue, DataSourceInstanceSettings, getDataSourceRef } from '@grafana/data';
import { QueryVariable, sceneGraph } from '@grafana/scenes';
import { DataSourceRef, VariableRefresh, VariableSort } from '@grafana/schema';
import { VariableRefresh, VariableSort } from '@grafana/schema';
import { QueryVariableEditorForm } from '../components/QueryVariableForm';
@ -36,7 +36,7 @@ export function QueryVariableEditor({ variable, onRunQuery }: QueryVariableEdito
variable.setState({ allValue: event.currentTarget.value });
};
const onDataSourceChange = (dsInstanceSettings: DataSourceInstanceSettings) => {
const datasource: DataSourceRef = { uid: dsInstanceSettings.uid, type: dsInstanceSettings.type };
const datasource = getDataSourceRef(dsInstanceSettings);
if (variable.state.datasource && variable.state.datasource.type !== datasource.type) {
variable.setState({ datasource, query: '', definition: '' });

View File

@ -40,8 +40,7 @@ export class PanelEditorQueries extends PureComponent<Props> {
cacheTimeout: datasourceSettings?.meta.queryOptions?.cacheTimeout ? panel.cacheTimeout : undefined,
dataSource: {
default: datasourceSettings?.isDefault,
type: datasourceSettings?.type,
uid: datasourceSettings?.uid,
...(datasourceSettings ? getDataSourceRef(datasourceSettings) : { type: undefined, uid: undefined }),
},
queryCachingTTL: datasourceSettings?.cachingConfig?.enabled ? panel.queryCachingTTL : undefined,
queries: panel.targets,

View File

@ -544,10 +544,7 @@ export class PanelModel implements DataConfigSource, IPanelModel {
updateQueries(options: QueryGroupOptions) {
const { dataSource } = options;
this.datasource = {
uid: dataSource.uid,
type: dataSource.type,
};
this.datasource = dataSource;
this.cacheTimeout = options.cacheTimeout;
this.queryCachingTTL = options.queryCachingTTL;

View File

@ -20,6 +20,7 @@ import {
PanelEvents,
QueryResultMetaNotice,
TimeRange,
getDataSourceRef,
toLegacyResponseData,
} from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
@ -364,7 +365,7 @@ export class QueryEditorRow<TQuery extends DataQuery> extends PureComponent<Prop
onClickExample = (query: TQuery) => {
if (query.datasource === undefined) {
query.datasource = { type: this.props.dataSource.type, uid: this.props.dataSource.uid };
query.datasource = getDataSourceRef(this.props.dataSource);
}
this.props.onChange({

View File

@ -5,10 +5,10 @@ import {
CoreApp,
DataQuery,
DataSourceInstanceSettings,
DataSourceRef,
EventBusExtended,
HistoryItem,
PanelData,
getDataSourceRef,
} from '@grafana/data';
import { getDataSourceSrv, reportInteraction } from '@grafana/runtime';
@ -65,10 +65,7 @@ export class QueryEditorRows extends PureComponent<Props> {
return item;
}
const dataSourceRef: DataSourceRef = {
type: dataSource.type,
uid: dataSource.uid,
};
const dataSourceRef = getDataSourceRef(dataSource);
if (item.datasource) {
const previous = getDataSourceSrv().getInstanceSettings(item.datasource);

View File

@ -7,6 +7,7 @@ import {
CoreApp,
DataSourceApi,
DataSourceInstanceSettings,
getDataSourceRef,
getDefaultTimeRange,
LoadingState,
PanelData,
@ -149,8 +150,7 @@ export class QueryGroup extends PureComponent<Props, State> {
dataSource: {
name: newSettings.name,
uid: newSettings.uid,
type: newSettings.meta.id,
default: newSettings.isDefault,
...getDataSourceRef(newSettings),
},
});
@ -174,11 +174,16 @@ export class QueryGroup extends PureComponent<Props, State> {
newQuery(): Partial<DataQuery> {
const { dsSettings, defaultDataSource } = this.state;
const ds = !dsSettings?.meta.mixed ? dsSettings : defaultDataSource;
const ds =
dsSettings && !dsSettings.meta.mixed
? getDataSourceRef(dsSettings)
: defaultDataSource
? defaultDataSource.getRef()
: { type: undefined, uid: undefined };
return {
...this.state.dataSource?.getDefaultQuery?.(CoreApp.PanelEditor),
datasource: { uid: ds?.uid, type: ds?.type },
datasource: ds,
};
}
@ -241,7 +246,9 @@ export class QueryGroup extends PureComponent<Props, State> {
onAddQuery = (query: Partial<DataQuery>) => {
const { dsSettings, queries } = this.state;
this.onQueriesChange(addQuery(queries, query, { type: dsSettings?.type, uid: dsSettings?.uid }));
this.onQueriesChange(
addQuery(queries, query, dsSettings ? getDataSourceRef(dsSettings) : { type: undefined, uid: undefined })
);
this.onScrollBottom();
};

View File

@ -12,6 +12,7 @@ const oldUidDS = {
meta: {
id: 'old-type',
},
getRef: () => ({ uid: 'old-uid', type: 'old-type' }),
} as DataSourceApi;
const mixedDS = {
@ -20,6 +21,7 @@ const mixedDS = {
id: 'mixed',
mixed: true,
},
getRef: () => ({ uid: 'mixed' }),
} as DataSourceApi;
const newUidDS = {
@ -28,6 +30,7 @@ const newUidDS = {
meta: {
id: 'new-type',
},
getRef: () => ({ uid: 'new-uid', type: 'new-type' }),
} as DataSourceApi;
const newUidSameTypeDS = {
@ -36,6 +39,7 @@ const newUidSameTypeDS = {
meta: {
id: 'old-type',
},
getRef: () => ({ uid: 'new-uid-same-type', type: 'old-type' }),
} as DataSourceApi;
const templateSrv = new TemplateSrv();
@ -376,6 +380,7 @@ describe('updateQueries with import', () => {
const importedQueries = queries.map((q) => ({ ...q, imported: true }));
return Promise.resolve(importedQueries);
},
getRef: () => ({ uid: 'new-uid', type: 'new-type' }),
} as DataSourceWithQueryImportSupport<DataQuery>;
const oldUidDSWithAbstract = {
@ -389,6 +394,7 @@ describe('updateQueries with import', () => {
const exportedQueries = queries.map((q) => ({ ...q, exported: true }));
return Promise.resolve(exportedQueries);
},
getRef: () => ({ uid: 'old-uid', type: 'old-type' }),
} as DataSourceWithQueryExportSupport<any>;
const queries = [
@ -452,6 +458,7 @@ describe('updateQueries with import', () => {
importFromAbstractQueries: () => {
return Promise.resolve([]);
},
getRef: () => ({ uid: 'new-uid', type: 'new-type' }),
} as DataSourceWithQueryImportSupport<DataQuery>;
const oldUidDSWithAbstract = {
@ -464,6 +471,7 @@ describe('updateQueries with import', () => {
const exportedQueries = queries.map((q) => ({ ...q, exported: true }));
return Promise.resolve(exportedQueries);
},
getRef: () => ({ uid: 'old-uid', type: 'old-type' }),
} as DataSourceWithQueryExportSupport<any>;
const queries = [
@ -510,6 +518,7 @@ describe('updateQueries with import', () => {
const importedQueries = queries.map((q) => ({ ...q, imported: true }));
return Promise.resolve(importedQueries);
},
getRef: () => ({ uid: 'new-uid', type: 'new-type' }),
} as DataSourceApi<any>;
const oldUidDS = {
@ -573,6 +582,7 @@ describe('updateQueries with import', () => {
importQueries: (queries, origin) => {
return Promise.resolve([] as DataQuery[]);
},
getRef: () => ({ uid: 'new-uid', type: 'new-type' }),
} as DataSourceApi;
const oldUidDS = {

View File

@ -10,7 +10,7 @@ export async function updateQueries(
currentDS?: DataSourceApi
): Promise<DataQuery[]> {
let nextQueries = queries;
const datasource = { type: nextDS.type, uid: nextDSUidOrVariableExpression };
const datasource = { ...nextDS.getRef(), uid: nextDSUidOrVariableExpression };
const DEFAULT_QUERY = { ...nextDS?.getDefaultQuery?.(CoreApp.PanelEditor), datasource, refId: 'A' };
// we are changing data source type