[v11.3.x] Alerting: Fix escaping of silence matchers in utf8 mode (#95347)
Co-authored-by: Gilles De Mey <gilles.de.mey@gmail.com> Co-authored-by: Tom Ratcliffe <tom.ratcliffe@grafana.com> Fix escaping of silence matchers in utf8 mode (#95067)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
|
import { encodeMatcher } from 'app/features/alerting/unified/utils/matchers';
|
||||||
import { dispatch } from 'app/store/store';
|
import { dispatch } from 'app/store/store';
|
||||||
import { ReceiversStateDTO } from 'app/types/alerting';
|
import { ReceiversStateDTO } from 'app/types/alerting';
|
||||||
|
|
||||||
@@ -17,13 +18,13 @@ import {
|
|||||||
} from '../../../../plugins/datasource/alertmanager/types';
|
} from '../../../../plugins/datasource/alertmanager/types';
|
||||||
import { NotifierDTO } from '../../../../types';
|
import { NotifierDTO } from '../../../../types';
|
||||||
import { withPerformanceLogging } from '../Analytics';
|
import { withPerformanceLogging } from '../Analytics';
|
||||||
import { matcherToOperator } from '../utils/alertmanager';
|
import { matcherToMatcherField } from '../utils/alertmanager';
|
||||||
import {
|
import {
|
||||||
GRAFANA_RULES_SOURCE_NAME,
|
GRAFANA_RULES_SOURCE_NAME,
|
||||||
getDatasourceAPIUid,
|
getDatasourceAPIUid,
|
||||||
isVanillaPrometheusAlertManagerDataSource,
|
isVanillaPrometheusAlertManagerDataSource,
|
||||||
} from '../utils/datasource';
|
} from '../utils/datasource';
|
||||||
import { retryWhile, wrapWithQuotes } from '../utils/misc';
|
import { retryWhile } from '../utils/misc';
|
||||||
import { messageFromError, withSerializedError } from '../utils/redux';
|
import { messageFromError, withSerializedError } from '../utils/redux';
|
||||||
|
|
||||||
import { alertingApi } from './alertingApi';
|
import { alertingApi } from './alertingApi';
|
||||||
@@ -72,9 +73,9 @@ export const alertmanagerApi = alertingApi.injectEndpoints({
|
|||||||
// TODO Add support for active, silenced, inhibited, unprocessed filters
|
// TODO Add support for active, silenced, inhibited, unprocessed filters
|
||||||
const filterMatchers = filter?.matchers
|
const filterMatchers = filter?.matchers
|
||||||
?.filter((matcher) => matcher.name && matcher.value)
|
?.filter((matcher) => matcher.name && matcher.value)
|
||||||
.map(
|
.map((matcher) => {
|
||||||
(matcher) => `${wrapWithQuotes(matcher.name)}${matcherToOperator(matcher)}${wrapWithQuotes(matcher.value)}`
|
return encodeMatcher(matcherToMatcherField(matcher));
|
||||||
);
|
});
|
||||||
|
|
||||||
const { silenced, inhibited, unprocessed, active } = filter || {};
|
const { silenced, inhibited, unprocessed, active } = filter || {};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
sortAlerts,
|
sortAlerts,
|
||||||
wrapWithQuotes,
|
|
||||||
escapeQuotes,
|
|
||||||
createExploreLink,
|
createExploreLink,
|
||||||
makeLabelBasedSilenceLink,
|
makeLabelBasedSilenceLink,
|
||||||
makeDataSourceLink,
|
makeDataSourceLink,
|
||||||
@@ -46,24 +44,6 @@ function permute(inputArray: any[]): any[] {
|
|||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('wrapWithQuotes', () => {
|
|
||||||
it('should work as expected', () => {
|
|
||||||
expect(wrapWithQuotes('"hello, world!"')).toBe('\\"hello, world!\\"');
|
|
||||||
expect(wrapWithQuotes('hello, world!')).toBe('"hello, world!"');
|
|
||||||
expect(wrapWithQuotes('hello, "world"!')).toBe('"hello, \\"world\\"!"');
|
|
||||||
expect(wrapWithQuotes('"hello""')).toBe('\\"hello\\"\\"');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('escapeQuotes', () => {
|
|
||||||
it('should escape all quotes', () => {
|
|
||||||
expect(escapeQuotes('"hello, world!"')).toBe('\\"hello, world!\\"');
|
|
||||||
expect(escapeQuotes('hello, world!')).toBe('hello, world!');
|
|
||||||
expect(escapeQuotes('hello, "world"!')).toBe('hello, \\"world\\"!');
|
|
||||||
expect(escapeQuotes('hello"')).toBe('hello\\"');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Unified Altering misc', () => {
|
describe('Unified Altering misc', () => {
|
||||||
describe('sortAlerts', () => {
|
describe('sortAlerts', () => {
|
||||||
describe('when using any sortOrder with a list of alert instances', () => {
|
describe('when using any sortOrder with a list of alert instances', () => {
|
||||||
|
|||||||
@@ -111,13 +111,6 @@ export function makeAMLink(path: string, alertManagerName?: string, options?: UR
|
|||||||
return `${path}?${search.toString()}`;
|
return `${path}?${search.toString()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const escapeQuotes = (input: string) => input.replace(/\"/g, '\\"');
|
|
||||||
|
|
||||||
export function wrapWithQuotes(input: string) {
|
|
||||||
const alreadyWrapped = input.startsWith('"') && input.endsWith('"');
|
|
||||||
return alreadyWrapped ? escapeQuotes(input) : `"${escapeQuotes(input)}"`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function makeLabelBasedSilenceLink(alertManagerSourceName: string, labels: Labels) {
|
export function makeLabelBasedSilenceLink(alertManagerSourceName: string, labels: Labels) {
|
||||||
const silenceUrlParams = new URLSearchParams();
|
const silenceUrlParams = new URLSearchParams();
|
||||||
silenceUrlParams.append('alertmanager', alertManagerSourceName);
|
silenceUrlParams.append('alertmanager', alertManagerSourceName);
|
||||||
|
|||||||
Reference in New Issue
Block a user