mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Fix removal of notification policy without labels matchers (#50678)
This commit is contained in:
parent
3430928294
commit
9d0e7564ed
@ -95,6 +95,9 @@ const ui = {
|
|||||||
groupWaitContainer: byTestId('am-group-wait'),
|
groupWaitContainer: byTestId('am-group-wait'),
|
||||||
groupIntervalContainer: byTestId('am-group-interval'),
|
groupIntervalContainer: byTestId('am-group-interval'),
|
||||||
groupRepeatContainer: byTestId('am-repeat-interval'),
|
groupRepeatContainer: byTestId('am-repeat-interval'),
|
||||||
|
|
||||||
|
confirmDeleteModal: byRole('dialog'),
|
||||||
|
confirmDeleteButton: byLabelText('Confirm Modal Danger Button'),
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('AmRoutes', () => {
|
describe('AmRoutes', () => {
|
||||||
@ -154,6 +157,8 @@ describe('AmRoutes', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const emptyRoute: Route = {};
|
||||||
|
|
||||||
const simpleRoute: Route = {
|
const simpleRoute: Route = {
|
||||||
receiver: 'simple-receiver',
|
receiver: 'simple-receiver',
|
||||||
matchers: ['hello=world', 'foo!=bar'],
|
matchers: ['hello=world', 'foo!=bar'],
|
||||||
@ -465,6 +470,61 @@ describe('AmRoutes', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should be able to delete an empty route', async () => {
|
||||||
|
const routeConfig = {
|
||||||
|
continue: false,
|
||||||
|
receiver: 'default',
|
||||||
|
group_by: ['alertname'],
|
||||||
|
routes: [emptyRoute],
|
||||||
|
group_interval: '4m',
|
||||||
|
group_wait: '1m',
|
||||||
|
repeat_interval: '5h',
|
||||||
|
mute_time_intervals: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultConfig: AlertManagerCortexConfig = {
|
||||||
|
alertmanager_config: {
|
||||||
|
receivers: [{ name: 'default' }, { name: 'critical' }],
|
||||||
|
route: routeConfig,
|
||||||
|
templates: [],
|
||||||
|
},
|
||||||
|
template_files: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
mocks.api.fetchAlertManagerConfig.mockImplementation(() => {
|
||||||
|
return Promise.resolve(defaultConfig);
|
||||||
|
});
|
||||||
|
|
||||||
|
mocks.api.updateAlertManagerConfig.mockResolvedValue(Promise.resolve());
|
||||||
|
|
||||||
|
await renderAmRoutes(GRAFANA_RULES_SOURCE_NAME);
|
||||||
|
expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalled();
|
||||||
|
|
||||||
|
const deleteButtons = await ui.deleteRouteButton.findAll();
|
||||||
|
expect(deleteButtons).toHaveLength(1);
|
||||||
|
|
||||||
|
await userEvent.click(deleteButtons[0]);
|
||||||
|
|
||||||
|
const confirmDeleteButton = ui.confirmDeleteButton.get(ui.confirmDeleteModal.get());
|
||||||
|
expect(confirmDeleteButton).toBeInTheDocument();
|
||||||
|
|
||||||
|
await userEvent.click(confirmDeleteButton);
|
||||||
|
|
||||||
|
expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalledWith<[string, AlertManagerCortexConfig]>(
|
||||||
|
GRAFANA_RULES_SOURCE_NAME,
|
||||||
|
{
|
||||||
|
...defaultConfig,
|
||||||
|
alertmanager_config: {
|
||||||
|
...defaultConfig.alertmanager_config,
|
||||||
|
route: {
|
||||||
|
...routeConfig,
|
||||||
|
routes: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('Keeps matchers for non-grafana alertmanager sources', async () => {
|
it('Keeps matchers for non-grafana alertmanager sources', async () => {
|
||||||
const defaultConfig: AlertManagerCortexConfig = {
|
const defaultConfig: AlertManagerCortexConfig = {
|
||||||
alertmanager_config: {
|
alertmanager_config: {
|
||||||
|
@ -77,20 +77,22 @@ export const emptyRoute: FormAmRoute = {
|
|||||||
muteTimeIntervals: [],
|
muteTimeIntervals: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
//returns route, and a record mapping id to existing route route
|
//returns route, and a record mapping id to existing route
|
||||||
export const amRouteToFormAmRoute = (route: Route | undefined): [FormAmRoute, Record<string, Route>] => {
|
export const amRouteToFormAmRoute = (route: Route | undefined): [FormAmRoute, Record<string, Route>] => {
|
||||||
if (!route || Object.keys(route).length === 0) {
|
if (!route) {
|
||||||
return [emptyRoute, {}];
|
return [emptyRoute, {}];
|
||||||
}
|
}
|
||||||
|
|
||||||
const [groupWaitValue, groupWaitValueType] = intervalToValueAndType(route.group_wait, ['', 's']);
|
|
||||||
const [groupIntervalValue, groupIntervalValueType] = intervalToValueAndType(route.group_interval, ['', 'm']);
|
|
||||||
const [repeatIntervalValue, repeatIntervalValueType] = intervalToValueAndType(route.repeat_interval, ['', 'h']);
|
|
||||||
|
|
||||||
const id = String(Math.random());
|
const id = String(Math.random());
|
||||||
const id2route = {
|
const id2route = {
|
||||||
[id]: route,
|
[id]: route,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (Object.keys(route).length === 0) {
|
||||||
|
const formAmRoute = { ...emptyRoute, id };
|
||||||
|
return [formAmRoute, id2route];
|
||||||
|
}
|
||||||
|
|
||||||
const formRoutes: FormAmRoute[] = [];
|
const formRoutes: FormAmRoute[] = [];
|
||||||
route.routes?.forEach((subRoute) => {
|
route.routes?.forEach((subRoute) => {
|
||||||
const [subFormRoute, subId2Route] = amRouteToFormAmRoute(subRoute);
|
const [subFormRoute, subId2Route] = amRouteToFormAmRoute(subRoute);
|
||||||
@ -105,6 +107,10 @@ export const amRouteToFormAmRoute = (route: Route | undefined): [FormAmRoute, Re
|
|||||||
(matcher) => ({ name: matcher[0], operator: matcher[1], value: matcher[2] } as MatcherFieldValue)
|
(matcher) => ({ name: matcher[0], operator: matcher[1], value: matcher[2] } as MatcherFieldValue)
|
||||||
) ?? [];
|
) ?? [];
|
||||||
|
|
||||||
|
const [groupWaitValue, groupWaitValueType] = intervalToValueAndType(route.group_wait, ['', 's']);
|
||||||
|
const [groupIntervalValue, groupIntervalValueType] = intervalToValueAndType(route.group_interval, ['', 'm']);
|
||||||
|
const [repeatIntervalValue, repeatIntervalValueType] = intervalToValueAndType(route.repeat_interval, ['', 'h']);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
|
Loading…
Reference in New Issue
Block a user