mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
prometheus: query field: better handle label-values with unusual characters (#41457)
This commit is contained in:
parent
16578b0af0
commit
5c40865547
@ -2,6 +2,7 @@ import type { Situation, Label } from './situation';
|
||||
import { NeverCaseError } from './util';
|
||||
// FIXME: we should not load this from the "outside", but we cannot do that while we have the "old" query-field too
|
||||
import { FUNCTIONS } from '../../../promql';
|
||||
import { escapeLabelValueInExactSelector } from '../../../language_utils';
|
||||
|
||||
export type CompletionType = 'HISTORY' | 'FUNCTION' | 'METRIC_NAME' | 'DURATION' | 'LABEL_NAME' | 'LABEL_VALUE';
|
||||
|
||||
@ -90,7 +91,9 @@ function makeSelector(metricName: string | undefined, labels: Label[]): string {
|
||||
allLabels.push({ name: '__name__', value: metricName, op: '=' });
|
||||
}
|
||||
|
||||
const allLabelTexts = allLabels.map((label) => `${label.name}${label.op}"${label.value}"`);
|
||||
const allLabelTexts = allLabels.map(
|
||||
(label) => `${label.name}${label.op}"${escapeLabelValueInExactSelector(label.value)}"`
|
||||
);
|
||||
|
||||
return `{${allLabelTexts.join(',')}}`;
|
||||
}
|
||||
|
@ -89,6 +89,24 @@ describe('situation', () => {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels: [{ name: 'one', value: 'val1', op: '=' }],
|
||||
});
|
||||
|
||||
// single-quoted label-values with escape
|
||||
assertSituation("{one='val\\'1',^}", {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels: [{ name: 'one', value: "val'1", op: '=' }],
|
||||
});
|
||||
|
||||
// double-quoted label-values with escape
|
||||
assertSituation('{one="val\\"1",^}', {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels: [{ name: 'one', value: 'val"1', op: '=' }],
|
||||
});
|
||||
|
||||
// backticked label-values with escape (the escape should not be interpreted)
|
||||
assertSituation('{one=`val\\"1`,^}', {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels: [{ name: 'one', value: 'val\\"1', op: '=' }],
|
||||
});
|
||||
});
|
||||
|
||||
it('handles label values', () => {
|
||||
|
@ -63,17 +63,34 @@ function getNodeText(node: SyntaxNode, text: string): string {
|
||||
}
|
||||
|
||||
function parsePromQLStringLiteral(text: string): string {
|
||||
// if it is a string-literal, it is inside quotes of some kind
|
||||
const inside = text.slice(1, text.length - 1);
|
||||
|
||||
// FIXME: support https://prometheus.io/docs/prometheus/latest/querying/basics/#string-literals
|
||||
// FIXME: maybe check other promql code, if all is supported or not
|
||||
|
||||
// for now we do only some very simple un-escaping
|
||||
|
||||
// we start with double-quotes
|
||||
if (text.startsWith('"') && text.endsWith('"')) {
|
||||
if (text.indexOf('\\') !== -1) {
|
||||
throw new Error('FIXME: escape-sequences not supported in label-values');
|
||||
}
|
||||
return text.slice(1, text.length - 1);
|
||||
} else {
|
||||
throw new Error('FIXME: invalid string literal');
|
||||
// NOTE: this is not 100% perfect, we only unescape the double-quote,
|
||||
// there might be other characters too
|
||||
return inside.replace(/\\"/, '"');
|
||||
}
|
||||
|
||||
// then single-quote
|
||||
if (text.startsWith("'") && text.endsWith("'")) {
|
||||
// NOTE: this is not 100% perfect, we only unescape the single-quote,
|
||||
// there might be other characters too
|
||||
return inside.replace(/\\'/, "'");
|
||||
}
|
||||
|
||||
// then backticks
|
||||
if (text.startsWith('`') && text.endsWith('`')) {
|
||||
return inside;
|
||||
}
|
||||
|
||||
throw new Error('FIXME: invalid string literal');
|
||||
}
|
||||
|
||||
type LabelOperator = '=' | '!=' | '=~' | '!~';
|
||||
|
Loading…
Reference in New Issue
Block a user