mirror of
https://github.com/grafana/grafana.git
synced 2024-12-29 10:21:41 -06:00
UpdateDatasource: Add apiVersion if enabled (#90038)
This commit is contained in:
parent
06de37e6cd
commit
61b95783d5
@ -647,6 +647,7 @@ export interface DataSourceSettings<T extends DataSourceJsonData = DataSourceJso
|
|||||||
readOnly: boolean;
|
readOnly: boolean;
|
||||||
withCredentials: boolean;
|
withCredentials: boolean;
|
||||||
version?: number;
|
version?: number;
|
||||||
|
apiVersion?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
35
public/app/features/apiserver/client.test.ts
Normal file
35
public/app/features/apiserver/client.test.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { getBackendSrv } from '@grafana/runtime';
|
||||||
|
|
||||||
|
import { DatasourceAPIVersions } from './client';
|
||||||
|
|
||||||
|
jest.mock('@grafana/runtime', () => ({
|
||||||
|
getBackendSrv: jest.fn().mockReturnValue({
|
||||||
|
get: jest.fn(),
|
||||||
|
}),
|
||||||
|
config: {},
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('DatasourceAPIVersions', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get', async () => {
|
||||||
|
const getMock = jest.fn().mockResolvedValue({
|
||||||
|
groups: [
|
||||||
|
{ name: 'testdata.datasource.grafana.app', preferredVersion: { version: 'v1' } },
|
||||||
|
{ name: 'prometheus.datasource.grafana.app', preferredVersion: { version: 'v2' } },
|
||||||
|
{ name: 'myorg-myplugin.datasource.grafana.app', preferredVersion: { version: 'v3' } },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
getBackendSrv().get = getMock;
|
||||||
|
const apiVersions = new DatasourceAPIVersions();
|
||||||
|
expect(await apiVersions.get('testdata')).toBe('v1');
|
||||||
|
expect(await apiVersions.get('grafana-testdata-datasource')).toBe('v1');
|
||||||
|
expect(await apiVersions.get('prometheus')).toBe('v2');
|
||||||
|
expect(await apiVersions.get('graphite')).toBeUndefined();
|
||||||
|
expect(await apiVersions.get('myorg-myplugin-datasource')).toBe('v3');
|
||||||
|
expect(getMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(getMock).toHaveBeenCalledWith('/apis');
|
||||||
|
});
|
||||||
|
});
|
@ -14,6 +14,7 @@ import {
|
|||||||
AnnoKeyOriginPath,
|
AnnoKeyOriginPath,
|
||||||
AnnoKeyOriginHash,
|
AnnoKeyOriginHash,
|
||||||
AnnoKeyOriginName,
|
AnnoKeyOriginName,
|
||||||
|
K8sAPIGroupList,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
export interface GroupVersionResource {
|
export interface GroupVersionResource {
|
||||||
@ -110,3 +111,34 @@ function setOriginAsUI(meta: Partial<ObjectMeta>) {
|
|||||||
meta.annotations[AnnoKeyOriginPath] = window.location.pathname;
|
meta.annotations[AnnoKeyOriginPath] = window.location.pathname;
|
||||||
meta.annotations[AnnoKeyOriginHash] = config.buildInfo.versionString;
|
meta.annotations[AnnoKeyOriginHash] = config.buildInfo.versionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class DatasourceAPIVersions {
|
||||||
|
private apiVersions?: { [pluginID: string]: string };
|
||||||
|
|
||||||
|
async get(pluginID: string): Promise<string | undefined> {
|
||||||
|
if (this.apiVersions) {
|
||||||
|
return this.apiVersions[pluginID];
|
||||||
|
}
|
||||||
|
const apis = await getBackendSrv().get<K8sAPIGroupList>('/apis');
|
||||||
|
const apiVersions: { [pluginID: string]: string } = {};
|
||||||
|
apis.groups.forEach((group) => {
|
||||||
|
if (group.name.includes('datasource.grafana.app')) {
|
||||||
|
const id = group.name.split('.')[0];
|
||||||
|
apiVersions[id] = group.preferredVersion.version;
|
||||||
|
// workaround for plugins that don't append '-datasource' for the group name
|
||||||
|
// e.g. org-plugin-datasource uses org-plugin.datasource.grafana.app
|
||||||
|
if (!id.endsWith('-datasource')) {
|
||||||
|
if (!id.includes('-')) {
|
||||||
|
// workaroud for Grafana plugins that don't include the org either
|
||||||
|
// e.g. testdata uses testdata.datasource.grafana.app
|
||||||
|
apiVersions[`grafana-${id}-datasource`] = group.preferredVersion.version;
|
||||||
|
} else {
|
||||||
|
apiVersions[`${id}-datasource`] = group.preferredVersion.version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.apiVersions = apiVersions;
|
||||||
|
return apiVersions[pluginID];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -150,3 +150,13 @@ export interface ResourceClient<T = object, K = string> {
|
|||||||
update(obj: ResourceForCreate<T, K>): Promise<Resource<T, K>>;
|
update(obj: ResourceForCreate<T, K>): Promise<Resource<T, K>>;
|
||||||
delete(name: string): Promise<MetaStatus>;
|
delete(name: string): Promise<MetaStatus>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface K8sAPIGroup {
|
||||||
|
name: string;
|
||||||
|
versions: Array<{ groupVersion: string; version: string }>;
|
||||||
|
preferredVersion: { groupVersion: string; version: string };
|
||||||
|
}
|
||||||
|
export interface K8sAPIGroupList {
|
||||||
|
kind: 'APIGroupList';
|
||||||
|
groups: K8sAPIGroup[];
|
||||||
|
}
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
import { updateNavIndex } from 'app/core/actions';
|
import { updateNavIndex } from 'app/core/actions';
|
||||||
import { appEvents, contextSrv } from 'app/core/core';
|
import { appEvents, contextSrv } from 'app/core/core';
|
||||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||||
|
import { DatasourceAPIVersions } from 'app/features/apiserver/client';
|
||||||
import { ROUTES as CONNECTIONS_ROUTES } from 'app/features/connections/constants';
|
import { ROUTES as CONNECTIONS_ROUTES } from 'app/features/connections/constants';
|
||||||
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||||
import { getPluginSettings } from 'app/features/plugins/pluginSettings';
|
import { getPluginSettings } from 'app/features/plugins/pluginSettings';
|
||||||
@ -264,6 +265,8 @@ export function loadDataSourcePlugins(): ThunkResult<void> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dsApiVersions = new DatasourceAPIVersions();
|
||||||
|
|
||||||
export function updateDataSource(dataSource: DataSourceSettings) {
|
export function updateDataSource(dataSource: DataSourceSettings) {
|
||||||
return async (
|
return async (
|
||||||
dispatch: (
|
dispatch: (
|
||||||
@ -271,6 +274,9 @@ export function updateDataSource(dataSource: DataSourceSettings) {
|
|||||||
) => DataSourceSettings
|
) => DataSourceSettings
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
|
if (config.featureToggles.grafanaAPIServerWithExperimentalAPIs) {
|
||||||
|
dataSource.apiVersion = await dsApiVersions.get(dataSource.type);
|
||||||
|
}
|
||||||
await api.updateDataSource(dataSource);
|
await api.updateDataSource(dataSource);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const formattedError = parseHealthCheckError(err);
|
const formattedError = parseHealthCheckError(err);
|
||||||
|
Loading…
Reference in New Issue
Block a user