[v11.2.x] Alerting: Fix preview of silences when label name contains spaces (#93051)

Co-authored-by: Tom Ratcliffe <tom.ratcliffe@grafana.com>
Fix preview of silences when label name contains spaces (#92802)
This commit is contained in:
grafana-delivery-bot[bot]
2024-09-09 16:23:40 +03:00
committed by GitHub
parent 1dd04a4014
commit 44da28e3f1
4 changed files with 42 additions and 3 deletions
@@ -304,6 +304,14 @@ describe('Silence create/edit', () => {
TEST_TIMEOUT
);
it('works when previewing alerts with spaces in label name', async () => {
renderSilences(`${baseUrlPath}?alertmanager=${GRAFANA_RULES_SOURCE_NAME}`);
await enterSilenceLabel(0, 'label with spaces', MatcherOperator.equal, 'value with spaces');
expect((await screen.findAllByTestId('row'))[0]).toBeInTheDocument();
});
it('shows an error when existing silence cannot be found', async () => {
renderSilences('/alerting/silence/foo-bar/edit');
@@ -58,7 +58,9 @@ export const alertmanagerApi = alertingApi.injectEndpoints({
// TODO Add support for active, silenced, inhibited, unprocessed filters
const filterMatchers = filter?.matchers
?.filter((matcher) => matcher.name && matcher.value)
.map((matcher) => `${matcher.name}${matcherToOperator(matcher)}${wrapWithQuotes(matcher.value)}`);
.map(
(matcher) => `${wrapWithQuotes(matcher.name)}${matcherToOperator(matcher)}${wrapWithQuotes(matcher.value)}`
);
const { silenced, inhibited, unprocessed, active } = filter || {};
@@ -66,7 +66,7 @@ export const SilencedInstancesPreview = ({ amSourceName, matchers: inputMatchers
if (isError) {
return (
<Alert title="Preview not available" severity="error">
Error occured when generating preview of affected alerts. Are your matchers valid?
Error occurred when generating preview of affected alerts. Are your matchers valid?
</Alert>
);
}
@@ -11,8 +11,37 @@ export const grafanaAlertingConfigurationStatusHandler = (
response = defaultGrafanaAlertingConfigurationStatusResponse
) => http.get('/api/v1/ngalert', () => HttpResponse.json(response));
const getInvalidMatcher = (matchers: string[]) => {
return matchers.find((matcher) => {
const split = matcher.split('=');
try {
// Try and parse as JSON, as this will fail if
// we've failed to wrap the label value in quotes
// (e.g. `foo space` can't be parsed, but `"foo space"` can)
JSON.parse(split[0]);
return false;
} catch (e) {
return true;
}
});
};
export const alertmanagerAlertsListHandler = () =>
http.get<{ datasourceUid: string }>('/api/alertmanager/:datasourceUid/api/v2/alerts', ({ params }) => {
http.get<{ datasourceUid: string }>('/api/alertmanager/:datasourceUid/api/v2/alerts', ({ params, request }) => {
const matchers = new URL(request.url).searchParams.getAll('filter');
const invalidMatcher = getInvalidMatcher(matchers);
if (invalidMatcher) {
return HttpResponse.json(
{
message: `bad matcher format: ${invalidMatcher}: unable to retrieve alerts`,
traceID: '',
},
{ status: 400 }
);
}
if (params.datasourceUid === MOCK_DATASOURCE_UID_BROKEN_ALERTMANAGER) {
return HttpResponse.json({ traceId: '' }, { status: 502 });
}