Fixing issue 16090 where Grafana uses illegal characters in requests … (#21447)
* Fixing issue 16090 where Grafana uses illegal characters in requests to Prometheus * Rebase with Grafana and Merge branch 'master' of https://github.com/BhartiAgrawalNvidia/grafana into fix-16090 # Conflicts: # public/app/plugins/datasource/prometheus/language_provider.ts * Rebase with Grafana and Merge branch 'master' of https://github.com/BhartiAgrawalNvidia/grafana into fix-16090 # Conflicts: # public/app/plugins/datasource/prometheus/language_provider.ts * Use querystring to escape the url Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com> Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
co-authored by
Andrej Ocenas
Arve Knudsen
parent
98420c63d1
commit
ce8df91cc9
@@ -403,14 +403,20 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
|||||||
*/
|
*/
|
||||||
fetchSeriesLabels = async (name: string, withName?: boolean): Promise<Record<string, string[]>> => {
|
fetchSeriesLabels = async (name: string, withName?: boolean): Promise<Record<string, string[]>> => {
|
||||||
const tRange = this.datasource.getTimeRange();
|
const tRange = this.datasource.getTimeRange();
|
||||||
const url = `/api/v1/series?match[]=${name}&start=${tRange['start']}&end=${tRange['end']}`;
|
const params = new URLSearchParams({
|
||||||
|
'match[]': name,
|
||||||
|
start: tRange['start'].toString(),
|
||||||
|
end: tRange['end'].toString(),
|
||||||
|
});
|
||||||
|
const url = `/api/v1/series?${params.toString()}`;
|
||||||
// Cache key is a bit different here. We add the `withName` param and also round up to a minute the intervals.
|
// Cache key is a bit different here. We add the `withName` param and also round up to a minute the intervals.
|
||||||
// The rounding may seem strange but makes relative intervals like now-1h less prone to need separate request every
|
// The rounding may seem strange but makes relative intervals like now-1h less prone to need separate request every
|
||||||
// millisecond while still actually getting all the keys for the correct interval. This still can create problems
|
// millisecond while still actually getting all the keys for the correct interval. This still can create problems
|
||||||
// when user does not the newest values for a minute if already cached.
|
// when user does not the newest values for a minute if already cached.
|
||||||
const cacheKey = `/api/v1/series?match[]=${name}&start=${this.roundToMinutes(
|
params.set('start', this.roundToMinutes(tRange['start']).toString());
|
||||||
tRange['start']
|
params.set('end', this.roundToMinutes(tRange['end']).toString());
|
||||||
)}&end=${this.roundToMinutes(tRange['end'])}&withName=${!!withName}`;
|
params.append('withName', withName ? 'true' : 'false');
|
||||||
|
const cacheKey = `/api/v1/series?${params.toString()}`;
|
||||||
let value = this.labelsCache.get(cacheKey);
|
let value = this.labelsCache.get(cacheKey);
|
||||||
if (!value) {
|
if (!value) {
|
||||||
const data = await this.request(url, []);
|
const data = await this.request(url, []);
|
||||||
|
|||||||
@@ -114,7 +114,9 @@ describe('PrometheusMetricFindQuery', () => {
|
|||||||
expect(datasourceRequestMock).toHaveBeenCalledTimes(1);
|
expect(datasourceRequestMock).toHaveBeenCalledTimes(1);
|
||||||
expect(datasourceRequestMock).toHaveBeenCalledWith({
|
expect(datasourceRequestMock).toHaveBeenCalledWith({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: `proxied/api/v1/series?match[]=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
url: `proxied/api/v1/series?match${encodeURIComponent(
|
||||||
|
'[]'
|
||||||
|
)}=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||||
silent: true,
|
silent: true,
|
||||||
headers: {},
|
headers: {},
|
||||||
});
|
});
|
||||||
@@ -137,9 +139,8 @@ describe('PrometheusMetricFindQuery', () => {
|
|||||||
expect(datasourceRequestMock).toHaveBeenCalledTimes(1);
|
expect(datasourceRequestMock).toHaveBeenCalledTimes(1);
|
||||||
expect(datasourceRequestMock).toHaveBeenCalledWith({
|
expect(datasourceRequestMock).toHaveBeenCalledWith({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: `proxied/api/v1/series?match[]=${encodeURIComponent(
|
url:
|
||||||
'metric{label1="foo", label2="bar", label3="baz"}'
|
'proxied/api/v1/series?match%5B%5D=metric%7Blabel1%3D%22foo%22%2C+label2%3D%22bar%22%2C+label3%3D%22baz%22%7D&start=1524650400&end=1524654000',
|
||||||
)}&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
|
||||||
silent: true,
|
silent: true,
|
||||||
headers: {},
|
headers: {},
|
||||||
});
|
});
|
||||||
@@ -164,7 +165,9 @@ describe('PrometheusMetricFindQuery', () => {
|
|||||||
expect(datasourceRequestMock).toHaveBeenCalledTimes(1);
|
expect(datasourceRequestMock).toHaveBeenCalledTimes(1);
|
||||||
expect(datasourceRequestMock).toHaveBeenCalledWith({
|
expect(datasourceRequestMock).toHaveBeenCalledWith({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: `proxied/api/v1/series?match[]=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
url: `proxied/api/v1/series?match${encodeURIComponent(
|
||||||
|
'[]'
|
||||||
|
)}=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||||
silent: true,
|
silent: true,
|
||||||
headers: {},
|
headers: {},
|
||||||
});
|
});
|
||||||
@@ -237,7 +240,7 @@ describe('PrometheusMetricFindQuery', () => {
|
|||||||
expect(datasourceRequestMock).toHaveBeenCalledTimes(1);
|
expect(datasourceRequestMock).toHaveBeenCalledTimes(1);
|
||||||
expect(datasourceRequestMock).toHaveBeenCalledWith({
|
expect(datasourceRequestMock).toHaveBeenCalledWith({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: `proxied/api/v1/series?match[]=${encodeURIComponent(
|
url: `proxied/api/v1/series?match${encodeURIComponent('[]')}=${encodeURIComponent(
|
||||||
'up{job="job1"}'
|
'up{job="job1"}'
|
||||||
)}&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
)}&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
||||||
silent: true,
|
silent: true,
|
||||||
|
|||||||
@@ -70,7 +70,12 @@ export default class PrometheusMetricFindQuery {
|
|||||||
} else {
|
} else {
|
||||||
const start = this.datasource.getPrometheusTime(this.range.from, false);
|
const start = this.datasource.getPrometheusTime(this.range.from, false);
|
||||||
const end = this.datasource.getPrometheusTime(this.range.to, true);
|
const end = this.datasource.getPrometheusTime(this.range.to, true);
|
||||||
url = '/api/v1/series?match[]=' + encodeURIComponent(metric) + '&start=' + start + '&end=' + end;
|
const params = new URLSearchParams({
|
||||||
|
'match[]': metric,
|
||||||
|
start: start.toString(),
|
||||||
|
end: end.toString(),
|
||||||
|
});
|
||||||
|
url = `/api/v1/series?${params.toString()}`;
|
||||||
|
|
||||||
return this.datasource.metadataRequest(url).then((result: any) => {
|
return this.datasource.metadataRequest(url).then((result: any) => {
|
||||||
const _labels = _.map(result.data.data, metric => {
|
const _labels = _.map(result.data.data, metric => {
|
||||||
@@ -134,7 +139,12 @@ export default class PrometheusMetricFindQuery {
|
|||||||
metricNameAndLabelsQuery(query: string) {
|
metricNameAndLabelsQuery(query: string) {
|
||||||
const start = this.datasource.getPrometheusTime(this.range.from, false);
|
const start = this.datasource.getPrometheusTime(this.range.from, false);
|
||||||
const end = this.datasource.getPrometheusTime(this.range.to, true);
|
const end = this.datasource.getPrometheusTime(this.range.to, true);
|
||||||
const url = '/api/v1/series?match[]=' + encodeURIComponent(query) + '&start=' + start + '&end=' + end;
|
const params = new URLSearchParams({
|
||||||
|
'match[]': query,
|
||||||
|
start: start.toString(),
|
||||||
|
end: end.toString(),
|
||||||
|
});
|
||||||
|
const url = `/api/v1/series?${params.toString()}`;
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
return this.datasource.metadataRequest(url).then((result: PromDataQueryResponse) => {
|
return this.datasource.metadataRequest(url).then((result: PromDataQueryResponse) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user