mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
open queries that have utf8 labels in explore properly
This commit is contained in:
@@ -71,7 +71,7 @@ import {
|
||||
RawRecordingRules,
|
||||
RuleQueryMapping,
|
||||
} from './types';
|
||||
import { utf8Support, wrapUtf8Filters } from './utf8_support';
|
||||
import { utf8Support } from './utf8_support';
|
||||
import { PrometheusVariableSupport } from './variables';
|
||||
|
||||
const ANNOTATION_QUERY_STEP_DEFAULT = '60s';
|
||||
@@ -931,9 +931,6 @@ export class PrometheusDatasource
|
||||
variables,
|
||||
(value: string | string[] = [], variable: QueryVariableModel | CustomVariableModel) => {
|
||||
if (typeof value === 'string' && target.fromExploreMetrics) {
|
||||
if (variable.name === 'filters') {
|
||||
return wrapUtf8Filters(value);
|
||||
}
|
||||
if (variable.name === 'groupby') {
|
||||
return utf8Support(value);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { escapeForUtf8Support, utf8Support, wrapUtf8Filters } from './utf8_support';
|
||||
import { escapeForUtf8Support, utf8Support } from './utf8_support';
|
||||
|
||||
describe('utf8 support', () => {
|
||||
it('should return utf8 labels wrapped in quotes', () => {
|
||||
@@ -33,95 +33,3 @@ describe('applyValueEncodingEscaping', () => {
|
||||
expect(excapedLabels).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('wrapUtf8Filters', () => {
|
||||
it('should correctly wrap UTF-8 labels and values for multiple key-value pairs', () => {
|
||||
const result = wrapUtf8Filters('label.with.spaß="this_is_fun",instance="localhost:9112"');
|
||||
const expected = '"label.with.spaß"="this_is_fun",instance="localhost:9112"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly wrap UTF-8 labels and values for a single key-value pair', () => {
|
||||
const result = wrapUtf8Filters('label.with.spaß="this_is_fun"');
|
||||
const expected = '"label.with.spaß"="this_is_fun"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly handle commas within values', () => {
|
||||
const result = wrapUtf8Filters('label.with.spaß="this,is,fun",instance="localhost:9112"');
|
||||
const expected = '"label.with.spaß"="this,is,fun",instance="localhost:9112"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly handle escaped quotes within values', () => {
|
||||
const result = wrapUtf8Filters(`label.with.spaß="this_is_\\"fun\\"",instance="localhost:9112"`);
|
||||
const expected = `"label.with.spaß"="this_is_\\"fun\\"",instance="localhost:9112"`;
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly handle spaces within keys', () => {
|
||||
const result = wrapUtf8Filters('label with space="value with space",instance="localhost:9112"');
|
||||
const expected = '"label with space"="value with space",instance="localhost:9112"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly process mixed inputs with various formats', () => {
|
||||
const result = wrapUtf8Filters('key1="value1",key2="value,with,comma",key3="val3"');
|
||||
const expected = 'key1="value1",key2="value,with,comma",key3="val3"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly handle empty values', () => {
|
||||
const result = wrapUtf8Filters('key1="",key2="value2"');
|
||||
const expected = 'key1="",key2="value2"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle an empty input string', () => {
|
||||
const result = wrapUtf8Filters('');
|
||||
const expected = '';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle a single key with an empty value', () => {
|
||||
const result = wrapUtf8Filters('key1=""');
|
||||
const expected = 'key1=""';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle multiple consecutive commas in a value', () => {
|
||||
const result = wrapUtf8Filters('key1="value1,,value2",key2="value3"');
|
||||
const expected = 'key1="value1,,value2",key2="value3"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle a key-value pair with special characters in the key', () => {
|
||||
const result = wrapUtf8Filters('special@key#="value1",key2="value2"');
|
||||
const expected = '"special@key#"="value1",key2="value2"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle a key-value pair with special characters in the value', () => {
|
||||
const result = wrapUtf8Filters('key1="value@#&*",key2="value2"');
|
||||
const expected = 'key1="value@#&*",key2="value2"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly process keys without special characters', () => {
|
||||
const result = wrapUtf8Filters('key1="value1",key2="value2"');
|
||||
const expected = 'key1="value1",key2="value2"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle nested escaped quotes correctly', () => {
|
||||
const result = wrapUtf8Filters('key1="nested \\"escaped\\" quotes",key2="value2"');
|
||||
const expected = 'key1="nested \\"escaped\\" quotes",key2="value2"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle escaped quotes correctly', () => {
|
||||
const result = wrapUtf8Filters('key1="nested \\"escaped\\" quotes",key2="value with \\"escaped\\" quotes"');
|
||||
const expected = 'key1="nested \\"escaped\\" quotes",key2="value with \\"escaped\\" quotes"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -79,35 +79,3 @@ const isValidCodePoint = (codePoint: number): boolean => {
|
||||
// Validate the code point for UTF-8 compliance if needed.
|
||||
return codePoint >= 0 && codePoint <= 0x10ffff;
|
||||
};
|
||||
|
||||
export const wrapUtf8Filters = (filterStr: string): string => {
|
||||
const resultArray: string[] = [];
|
||||
let currentKey = '';
|
||||
let currentValue = '';
|
||||
let inQuotes = false;
|
||||
let temp = '';
|
||||
|
||||
for (const char of filterStr) {
|
||||
if (char === '"' && temp[temp.length - 1] !== '\\') {
|
||||
// Toggle inQuotes when an unescaped quote is found
|
||||
inQuotes = !inQuotes;
|
||||
temp += char;
|
||||
} else if (char === ',' && !inQuotes) {
|
||||
// When outside quotes and encountering ',', finalize the current pair
|
||||
[currentKey, currentValue] = temp.split('=');
|
||||
resultArray.push(`${utf8Support(currentKey.trim())}="${currentValue.slice(1, -1)}"`);
|
||||
temp = ''; // Reset for the next pair
|
||||
} else {
|
||||
// Collect characters
|
||||
temp += char;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the last key-value pair
|
||||
if (temp) {
|
||||
[currentKey, currentValue] = temp.split('=');
|
||||
resultArray.push(`${utf8Support(currentKey.trim())}="${currentValue.slice(1, -1)}"`);
|
||||
}
|
||||
|
||||
return resultArray.join(',');
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
} from '@grafana/data';
|
||||
import { PrometheusDatasource, PromMetricsMetadata, PromMetricsMetadataItem, PromQuery } from '@grafana/prometheus';
|
||||
import PromQlLanguageProvider from '@grafana/prometheus/src/language_provider';
|
||||
import { utf8Support } from '@grafana/prometheus/src/utf8_support';
|
||||
import { getDataSourceSrv } from '@grafana/runtime';
|
||||
|
||||
import { DataTrail } from '../DataTrail';
|
||||
@@ -134,7 +135,13 @@ export class MetricDatasourceHelper {
|
||||
|
||||
if (ds instanceof PrometheusDatasource) {
|
||||
const keys = await ds.getTagKeys(options);
|
||||
return keys;
|
||||
return keys.map((key) => {
|
||||
if (typeof key.value === 'string') {
|
||||
key.value = utf8Support(key.value);
|
||||
key.text = utf8Support(key.text);
|
||||
}
|
||||
return key;
|
||||
});
|
||||
}
|
||||
|
||||
return [];
|
||||
|
||||
Reference in New Issue
Block a user