mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus: Use configured HTTP method for /series and /labels endpoints (#31401)
* Run post-friendly request with set method first * Improve messaging, retry only when post and specific status code * Add comments * Fix backend * Update public/app/plugins/datasource/prometheus/datasource.ts
This commit is contained in:
parent
6d1076fca7
commit
dce67db6ba
@ -245,8 +245,8 @@ func (proxy *DataSourceProxy) validateRequest() error {
|
|||||||
if proxy.ctx.Req.Request.Method == "PUT" {
|
if proxy.ctx.Req.Request.Method == "PUT" {
|
||||||
return errors.New("puts not allowed on proxied Prometheus datasource")
|
return errors.New("puts not allowed on proxied Prometheus datasource")
|
||||||
}
|
}
|
||||||
if proxy.ctx.Req.Request.Method == "POST" && !(proxy.proxyPath == "api/v1/query" || proxy.proxyPath == "api/v1/query_range") {
|
if proxy.ctx.Req.Request.Method == "POST" && !(proxy.proxyPath == "api/v1/query" || proxy.proxyPath == "api/v1/query_range" || proxy.proxyPath == "api/v1/series" || proxy.proxyPath == "api/v1/labels") {
|
||||||
return errors.New("posts not allowed on proxied Prometheus datasource except on /query and /query_range")
|
return errors.New("posts not allowed on proxied Prometheus datasource except on /query, /query_range, /series and /labels")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,8 +105,7 @@ describe('PrometheusDatasource', () => {
|
|||||||
expect(fetchMock.mock.calls.length).toBe(1);
|
expect(fetchMock.mock.calls.length).toBe(1);
|
||||||
expect(fetchMock.mock.calls[0][0].method).toBe('GET');
|
expect(fetchMock.mock.calls[0][0].method).toBe('GET');
|
||||||
});
|
});
|
||||||
|
it('should still perform a GET request with the DS HTTP method set to POST and not POST-friendly endpoint', () => {
|
||||||
it('should still perform a GET request with the DS HTTP method set to POST', () => {
|
|
||||||
const postSettings = _.cloneDeep(instanceSettings);
|
const postSettings = _.cloneDeep(instanceSettings);
|
||||||
postSettings.jsonData.httpMethod = 'POST';
|
postSettings.jsonData.httpMethod = 'POST';
|
||||||
const promDs = new PrometheusDatasource(postSettings, templateSrvStub as any, timeSrvStub as any);
|
const promDs = new PrometheusDatasource(postSettings, templateSrvStub as any, timeSrvStub as any);
|
||||||
@ -114,6 +113,14 @@ describe('PrometheusDatasource', () => {
|
|||||||
expect(fetchMock.mock.calls.length).toBe(1);
|
expect(fetchMock.mock.calls.length).toBe(1);
|
||||||
expect(fetchMock.mock.calls[0][0].method).toBe('GET');
|
expect(fetchMock.mock.calls[0][0].method).toBe('GET');
|
||||||
});
|
});
|
||||||
|
it('should try to perform a POST request with the DS HTTP method set to POST and POST-friendly endpoint', () => {
|
||||||
|
const postSettings = _.cloneDeep(instanceSettings);
|
||||||
|
postSettings.jsonData.httpMethod = 'POST';
|
||||||
|
const promDs = new PrometheusDatasource(postSettings, templateSrvStub as any, timeSrvStub as any);
|
||||||
|
promDs.metadataRequest('api/v1/series');
|
||||||
|
expect(fetchMock.mock.calls.length).toBe(1);
|
||||||
|
expect(fetchMock.mock.calls[0][0].method).toBe('POST');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('When using customQueryParams', () => {
|
describe('When using customQueryParams', () => {
|
||||||
|
@ -44,6 +44,7 @@ import { PrometheusVariableSupport } from './variables';
|
|||||||
import PrometheusMetricFindQuery from './metric_find_query';
|
import PrometheusMetricFindQuery from './metric_find_query';
|
||||||
|
|
||||||
export const ANNOTATION_QUERY_STEP_DEFAULT = '60s';
|
export const ANNOTATION_QUERY_STEP_DEFAULT = '60s';
|
||||||
|
const GET_AND_POST_MEDATADATA_ENDPOINTS = ['api/v1/query', 'api/v1/query_range', 'api/v1/series', 'api/v1/labels'];
|
||||||
|
|
||||||
export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions> {
|
export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions> {
|
||||||
type: string;
|
type: string;
|
||||||
@ -136,7 +137,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use this for tab completion features, wont publish response to other components
|
// Use this for tab completion features, wont publish response to other components
|
||||||
metadataRequest<T = any>(url: string) {
|
async metadataRequest<T = any>(url: string) {
|
||||||
const data: any = {};
|
const data: any = {};
|
||||||
for (const [key, value] of this.customQueryParameters) {
|
for (const [key, value] of this.customQueryParameters) {
|
||||||
if (data[key] == null) {
|
if (data[key] == null) {
|
||||||
@ -144,7 +145,21 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._request<T>(url, data, { method: 'GET', hideFromInspector: true }).toPromise(); // toPromise until we change getTagValues, getTagKeys to Observable
|
// 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_MEDATADATA_ENDPOINTS.some((endpoint) => url.includes(endpoint))) {
|
||||||
|
try {
|
||||||
|
return await this._request<T>(url, data, { method: this.httpMethod, hideFromInspector: true }).toPromise();
|
||||||
|
} catch (err) {
|
||||||
|
// If status code of error is Method Not Allowed (405) and HTTP method is POST, retry with GET
|
||||||
|
if (this.httpMethod === 'POST' && err.status === 405) {
|
||||||
|
console.warn(`Couldn't use configured POST HTTP method for this request. Trying to use GET method instead.`);
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await this._request<T>(url, data, { method: 'GET', hideFromInspector: true }).toPromise(); // toPromise until we change getTagValues, getTagKeys to Observable
|
||||||
}
|
}
|
||||||
|
|
||||||
interpolateQueryExpr(value: string | string[] = [], variable: any) {
|
interpolateQueryExpr(value: string | string[] = [], variable: any) {
|
||||||
|
Loading…
Reference in New Issue
Block a user