From f404191ccbe84cf2a00bac71fb0aafc1ecc89884 Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Sat, 4 Jun 2022 02:06:17 -0400 Subject: [PATCH] Alerting: only delete mute time if not used by route (#50193) (#50205) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Alerting: only delete mute time if not used by route * add a testcase * import package only once * replace apimodels with definitions (cherry picked from commit 8de4ffe61f28efb93e62856169d31acf372a0791) Co-authored-by: Jean-Philippe Quéméner --- .../ngalert/provisioning/mute_timings.go | 20 ++++++++ .../ngalert/provisioning/mute_timings_test.go | 50 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/pkg/services/ngalert/provisioning/mute_timings.go b/pkg/services/ngalert/provisioning/mute_timings.go index 0df16beada4..3df436a7c8b 100644 --- a/pkg/services/ngalert/provisioning/mute_timings.go +++ b/pkg/services/ngalert/provisioning/mute_timings.go @@ -159,6 +159,9 @@ func (svc *MuteTimingService) DeleteMuteTiming(ctx context.Context, name string, if revision.cfg.AlertmanagerConfig.MuteTimeIntervals == nil { return nil } + if isMuteTimeInUse(name, []*definitions.Route{revision.cfg.AlertmanagerConfig.Route}) { + return fmt.Errorf("mute time '%s' is currently used by a notification policy", name) + } for i, existing := range revision.cfg.AlertmanagerConfig.MuteTimeIntervals { if name == existing.Name { intervals := revision.cfg.AlertmanagerConfig.MuteTimeIntervals @@ -190,3 +193,20 @@ func (svc *MuteTimingService) DeleteMuteTiming(ctx context.Context, name string, return nil }) } + +func isMuteTimeInUse(name string, routes []*definitions.Route) bool { + if len(routes) == 0 { + return false + } + for _, route := range routes { + for _, mtName := range route.MuteTimeIntervals { + if mtName == name { + return true + } + } + if isMuteTimeInUse(name, route.Routes) { + return true + } + } + return false +} diff --git a/pkg/services/ngalert/provisioning/mute_timings_test.go b/pkg/services/ngalert/provisioning/mute_timings_test.go index 9a6b6e90853..4085f713d7a 100644 --- a/pkg/services/ngalert/provisioning/mute_timings_test.go +++ b/pkg/services/ngalert/provisioning/mute_timings_test.go @@ -356,6 +356,18 @@ func TestMuteTimingService(t *testing.T) { require.ErrorContains(t, err, "failed to save config") }) + + t.Run("when mute timing is used in route", func(t *testing.T) { + sut := createMuteTimingSvcSut() + sut.config.(*MockAMConfigStore).EXPECT(). + getsConfig(models.AlertConfiguration{ + AlertmanagerConfiguration: configWithMuteTimingsInRoute, + }) + + err := sut.DeleteMuteTiming(context.Background(), "asdf", 1) + + require.Error(t, err) + }) }) }) } @@ -408,3 +420,41 @@ var configWithMuteTimings = ` } } ` + +var configWithMuteTimingsInRoute = ` +{ + "template_files": { + "a": "template" + }, + "alertmanager_config": { + "route": { + "receiver": "grafana-default-email", + "routes": [ + { + "receiver": "grafana-default-email", + "mute_time_intervals": ["asdf"] + } + ] + }, + "mute_time_intervals": [{ + "name": "asdf", + "time_intervals": [{ + "times": [], + "weekdays": ["monday"] + }] + }], + "receivers": [{ + "name": "grafana-default-email", + "grafana_managed_receiver_configs": [{ + "uid": "", + "name": "email receiver", + "type": "email", + "isDefault": true, + "settings": { + "addresses": "" + } + }] + }] + } +} +`