Before requesting the metadata check the access mode (#55403)
* Before requesting the metadata check the access mode * Update tests * Update tests again
This commit is contained in:
@@ -131,6 +131,7 @@ describe('PrometheusDatasource', () => {
|
||||
|
||||
describe('customQueryParams', () => {
|
||||
const target = { expr: 'test{job="testjob"}', format: 'time_series', refId: '' };
|
||||
|
||||
function makeQuery(target: PromQuery) {
|
||||
return {
|
||||
range: { from: time({ seconds: 63 }), to: time({ seconds: 183 }) },
|
||||
@@ -140,19 +141,27 @@ describe('PrometheusDatasource', () => {
|
||||
}
|
||||
|
||||
describe('with GET http method', () => {
|
||||
const promDs = new PrometheusDatasource(
|
||||
{ ...instanceSettings, jsonData: { customQueryParameters: 'customQuery=123', httpMethod: 'GET' } as any },
|
||||
templateSrvStub as any,
|
||||
timeSrvStub as any
|
||||
);
|
||||
const getPromDs = (access: 'direct' | 'proxy') => {
|
||||
return new PrometheusDatasource(
|
||||
{
|
||||
...instanceSettings,
|
||||
access,
|
||||
jsonData: { customQueryParameters: 'customQuery=123', httpMethod: 'GET' } as any,
|
||||
},
|
||||
templateSrvStub as any,
|
||||
timeSrvStub as any
|
||||
);
|
||||
};
|
||||
|
||||
it('added to metadata request', () => {
|
||||
const promDs = getPromDs('proxy');
|
||||
promDs.metadataRequest('/foo');
|
||||
expect(fetchMock.mock.calls.length).toBe(1);
|
||||
expect(fetchMock.mock.calls[0][0].url).toBe('/api/datasources/1/resources/foo?customQuery=123');
|
||||
});
|
||||
|
||||
it('adds params to timeseries query', () => {
|
||||
const promDs = getPromDs('direct');
|
||||
promDs.query(makeQuery(target));
|
||||
expect(fetchMock.mock.calls.length).toBe(1);
|
||||
expect(fetchMock.mock.calls[0][0].url).toBe(
|
||||
@@ -160,6 +169,7 @@ describe('PrometheusDatasource', () => {
|
||||
);
|
||||
});
|
||||
it('adds params to exemplars query', () => {
|
||||
const promDs = getPromDs('direct');
|
||||
promDs.query(makeQuery({ ...target, exemplar: true }));
|
||||
// We do also range query for single exemplars target
|
||||
expect(fetchMock.mock.calls.length).toBe(2);
|
||||
@@ -168,6 +178,7 @@ describe('PrometheusDatasource', () => {
|
||||
});
|
||||
|
||||
it('adds params to instant query', () => {
|
||||
const promDs = getPromDs('direct');
|
||||
promDs.query(makeQuery({ ...target, instant: true }));
|
||||
expect(fetchMock.mock.calls.length).toBe(1);
|
||||
expect(fetchMock.mock.calls[0][0].url).toContain('&customQuery=123');
|
||||
@@ -175,19 +186,31 @@ describe('PrometheusDatasource', () => {
|
||||
});
|
||||
|
||||
describe('with POST http method', () => {
|
||||
const promDs = new PrometheusDatasource(
|
||||
{ ...instanceSettings, jsonData: { customQueryParameters: 'customQuery=123', httpMethod: 'POST' } as any },
|
||||
templateSrvStub as any,
|
||||
timeSrvStub as any
|
||||
);
|
||||
const getPromDs = (access: 'direct' | 'proxy') => {
|
||||
return new PrometheusDatasource(
|
||||
{
|
||||
...instanceSettings,
|
||||
access,
|
||||
jsonData: { customQueryParameters: 'customQuery=123', httpMethod: 'POST' } as any,
|
||||
},
|
||||
templateSrvStub as any,
|
||||
timeSrvStub as any
|
||||
);
|
||||
};
|
||||
|
||||
it('added to metadata request with non-POST endpoint', () => {
|
||||
promDs.metadataRequest('/foo');
|
||||
it('added to metadata request with non-POST endpoint ', () => {
|
||||
const proxyPromDs = getPromDs('proxy');
|
||||
proxyPromDs.metadataRequest('/foo');
|
||||
expect(fetchMock.mock.calls.length).toBe(1);
|
||||
expect(fetchMock.mock.calls[0][0].url).toBe('/api/datasources/1/resources/foo?customQuery=123');
|
||||
const directPromDs = getPromDs('direct');
|
||||
directPromDs.metadataRequest('/foo');
|
||||
expect(fetchMock.mock.calls.length).toBe(2);
|
||||
expect(fetchMock.mock.calls[1][0].url).toBe('proxied/foo?customQuery=123');
|
||||
});
|
||||
|
||||
it('added to metadata request with POST endpoint', () => {
|
||||
const promDs = getPromDs('proxy');
|
||||
promDs.metadataRequest('/api/v1/labels');
|
||||
expect(fetchMock.mock.calls.length).toBe(1);
|
||||
expect(fetchMock.mock.calls[0][0].url).toBe('/api/datasources/1/resources/api/v1/labels');
|
||||
@@ -195,6 +218,7 @@ describe('PrometheusDatasource', () => {
|
||||
});
|
||||
|
||||
it('adds params to timeseries query', () => {
|
||||
const promDs = getPromDs('direct');
|
||||
promDs.query(makeQuery(target));
|
||||
expect(fetchMock.mock.calls.length).toBe(1);
|
||||
expect(fetchMock.mock.calls[0][0].url).toBe('proxied/api/v1/query_range');
|
||||
@@ -206,7 +230,9 @@ describe('PrometheusDatasource', () => {
|
||||
start: 60,
|
||||
});
|
||||
});
|
||||
|
||||
it('adds params to exemplars query', () => {
|
||||
const promDs = getPromDs('direct');
|
||||
promDs.query(makeQuery({ ...target, exemplar: true }));
|
||||
// We do also range query for single exemplars target
|
||||
expect(fetchMock.mock.calls.length).toBe(2);
|
||||
@@ -215,6 +241,7 @@ describe('PrometheusDatasource', () => {
|
||||
});
|
||||
|
||||
it('adds params to instant query', () => {
|
||||
const promDs = getPromDs('direct');
|
||||
promDs.query(makeQuery({ ...target, instant: true }));
|
||||
expect(fetchMock.mock.calls.length).toBe(1);
|
||||
expect(fetchMock.mock.calls[0][0].data.customQuery).toBe('123');
|
||||
|
||||
@@ -5,8 +5,10 @@ import { forkJoin, lastValueFrom, merge, Observable, of, OperatorFunction, pipe,
|
||||
import { catchError, filter, map, tap } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
AbstractQuery,
|
||||
AnnotationEvent,
|
||||
CoreApp,
|
||||
DataFrame,
|
||||
DataQueryError,
|
||||
DataQueryRequest,
|
||||
DataQueryResponse,
|
||||
@@ -15,31 +17,29 @@ import {
|
||||
DataSourceWithQueryImportSupport,
|
||||
dateMath,
|
||||
DateTime,
|
||||
AbstractQuery,
|
||||
dateTime,
|
||||
LoadingState,
|
||||
QueryFixAction,
|
||||
rangeUtil,
|
||||
ScopedVars,
|
||||
TimeRange,
|
||||
DataFrame,
|
||||
dateTime,
|
||||
QueryFixAction,
|
||||
} from '@grafana/data';
|
||||
import {
|
||||
BackendDataSourceResponse,
|
||||
BackendSrvRequest,
|
||||
DataSourceWithBackend,
|
||||
FetchError,
|
||||
FetchResponse,
|
||||
getBackendSrv,
|
||||
DataSourceWithBackend,
|
||||
BackendDataSourceResponse,
|
||||
toDataQueryResponse,
|
||||
isFetchError,
|
||||
toDataQueryResponse,
|
||||
} from '@grafana/runtime';
|
||||
import { Badge, BadgeColor, Tooltip } from '@grafana/ui';
|
||||
import { safeStringifyValue } from 'app/core/utils/explore';
|
||||
import { discoverDataSourceFeatures } from 'app/features/alerting/unified/api/buildInfo';
|
||||
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { PromApplication, PromApiFeatures } from 'app/types/unified-alerting-dto';
|
||||
import { PromApiFeatures, PromApplication } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { addLabelToQuery } from './add_label_to_query';
|
||||
import { AnnotationQueryEditor } from './components/AnnotationQueryEditor';
|
||||
@@ -214,11 +214,16 @@ export class PrometheusDatasource
|
||||
|
||||
// Use this for tab completion features, wont publish response to other components
|
||||
async metadataRequest<T = any>(url: string, params = {}, options?: Partial<BackendSrvRequest>) {
|
||||
// Build the request URL based on the access mode
|
||||
let queryUrl = url;
|
||||
if (this.access === 'proxy') {
|
||||
queryUrl = `/api/datasources/${this.id}/resources` + queryUrl;
|
||||
}
|
||||
// If URL includes endpoint that supports POST and GET method, try to use configured method. This might fail as POST is supported only in v2.10+.
|
||||
if (GET_AND_POST_METADATA_ENDPOINTS.some((endpoint) => url.includes(endpoint))) {
|
||||
try {
|
||||
return await lastValueFrom(
|
||||
this._request<T>(`/api/datasources/${this.id}/resources${url}`, params, {
|
||||
this._request<T>(queryUrl, params, {
|
||||
method: this.httpMethod,
|
||||
hideFromInspector: true,
|
||||
showErrorAlert: false,
|
||||
@@ -236,7 +241,7 @@ export class PrometheusDatasource
|
||||
}
|
||||
|
||||
return await lastValueFrom(
|
||||
this._request<T>(`/api/datasources/${this.id}/resources${url}`, params, {
|
||||
this._request<T>(queryUrl, params, {
|
||||
method: 'GET',
|
||||
hideFromInspector: true,
|
||||
...options,
|
||||
|
||||
@@ -76,7 +76,7 @@ describe('PrometheusMetricFindQuery', () => {
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith({
|
||||
method: 'GET',
|
||||
url: `/api/datasources/1/resources/api/v1/labels?start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||
url: `proxied/api/v1/labels?start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||
hideFromInspector: true,
|
||||
showErrorAlert: false,
|
||||
headers: {},
|
||||
@@ -96,7 +96,7 @@ describe('PrometheusMetricFindQuery', () => {
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith({
|
||||
method: 'GET',
|
||||
url: `/api/datasources/1/resources/api/v1/label/resource/values?start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||
url: `proxied/api/v1/label/resource/values?start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||
hideFromInspector: true,
|
||||
headers: {},
|
||||
});
|
||||
@@ -119,7 +119,7 @@ describe('PrometheusMetricFindQuery', () => {
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith({
|
||||
method: 'GET',
|
||||
url: `/api/datasources/1/resources/api/v1/series?match${encodeURIComponent(
|
||||
url: `proxied/api/v1/series?match${encodeURIComponent(
|
||||
'[]'
|
||||
)}=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||
hideFromInspector: true,
|
||||
@@ -145,7 +145,7 @@ describe('PrometheusMetricFindQuery', () => {
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith({
|
||||
method: 'GET',
|
||||
url: '/api/datasources/1/resources/api/v1/series?match%5B%5D=metric%7Blabel1%3D%22foo%22%2C%20label2%3D%22bar%22%2C%20label3%3D%22baz%22%7D&start=1524650400&end=1524654000',
|
||||
url: 'proxied/api/v1/series?match%5B%5D=metric%7Blabel1%3D%22foo%22%2C%20label2%3D%22bar%22%2C%20label3%3D%22baz%22%7D&start=1524650400&end=1524654000',
|
||||
hideFromInspector: true,
|
||||
showErrorAlert: false,
|
||||
headers: {},
|
||||
@@ -171,7 +171,7 @@ describe('PrometheusMetricFindQuery', () => {
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith({
|
||||
method: 'GET',
|
||||
url: `/api/datasources/1/resources/api/v1/series?match${encodeURIComponent(
|
||||
url: `proxied/api/v1/series?match${encodeURIComponent(
|
||||
'[]'
|
||||
)}=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||
hideFromInspector: true,
|
||||
@@ -193,7 +193,7 @@ describe('PrometheusMetricFindQuery', () => {
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith({
|
||||
method: 'GET',
|
||||
url: `/api/datasources/1/resources/api/v1/label/__name__/values?start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||
url: `proxied/api/v1/label/__name__/values?start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||
hideFromInspector: true,
|
||||
headers: {},
|
||||
});
|
||||
@@ -269,7 +269,7 @@ describe('PrometheusMetricFindQuery', () => {
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith({
|
||||
method: 'GET',
|
||||
url: `/api/datasources/1/resources/api/v1/series?match${encodeURIComponent('[]')}=${encodeURIComponent(
|
||||
url: `proxied/api/v1/series?match${encodeURIComponent('[]')}=${encodeURIComponent(
|
||||
'up{job="job1"}'
|
||||
)}&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||
hideFromInspector: true,
|
||||
|
||||
Reference in New Issue
Block a user