From baea7a7556db3d3eecfa5d2849c2b872b8215a8a Mon Sep 17 00:00:00 2001 From: Yuri Tseretyan Date: Mon, 4 Sep 2023 13:30:15 -0400 Subject: [PATCH] Alerting: Fix provisioning of contact points when contact point is renamed (#74238) * add test that demonstrates the bug * fix renaming provisioning contact points when it is the last in the group --- .../ngalert/provisioning/contactpoints.go | 9 +- .../provisioning/contactpoints_test.go | 102 ++++++++++++++++++ 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/pkg/services/ngalert/provisioning/contactpoints.go b/pkg/services/ngalert/provisioning/contactpoints.go index 5de1a847f23..eeb2537596a 100644 --- a/pkg/services/ngalert/provisioning/contactpoints.go +++ b/pkg/services/ngalert/provisioning/contactpoints.go @@ -454,7 +454,7 @@ func stitchReceiver(cfg *apimodels.PostableUserConfig, target *apimodels.Postabl // All receivers in a given receiver group have the same name. We must maintain this across renames. configModified := false groupLoop: - for _, receiverGroup := range cfg.AlertmanagerConfig.Receivers { + for groupIdx, receiverGroup := range cfg.AlertmanagerConfig.Receivers { // Does the current group contain the grafana receiver we're interested in? for i, grafanaReceiver := range receiverGroup.GrafanaManagedReceivers { if grafanaReceiver.UID == target.UID { @@ -477,8 +477,6 @@ groupLoop: replaceReferences(receiverGroup.Name, target.Name, cfg.AlertmanagerConfig.Route) receiverGroup.Name = target.Name receiverGroup.GrafanaManagedReceivers[i] = target - configModified = true - break groupLoop } // Otherwise, we only want to rename the receiver we are touching... NOT all of them. @@ -491,6 +489,11 @@ groupLoop: // Add the modified receiver to the new group... candidateExistingGroup.GrafanaManagedReceivers = append(candidateExistingGroup.GrafanaManagedReceivers, target) configModified = true + + // if the old receiver group turns out to be empty. Remove it. + if len(receiverGroup.GrafanaManagedReceivers) == 0 { + cfg.AlertmanagerConfig.Receivers = append(cfg.AlertmanagerConfig.Receivers[:groupIdx], cfg.AlertmanagerConfig.Receivers[groupIdx+1:]...) + } break groupLoop } } diff --git a/pkg/services/ngalert/provisioning/contactpoints_test.go b/pkg/services/ngalert/provisioning/contactpoints_test.go index d92dfa8bd00..745a83855f1 100644 --- a/pkg/services/ngalert/provisioning/contactpoints_test.go +++ b/pkg/services/ngalert/provisioning/contactpoints_test.go @@ -992,6 +992,108 @@ func TestStitchReceivers(t *testing.T) { }, }, }, + { + name: "single item group rename to existing group", + initial: &definitions.PostableUserConfig{ + AlertmanagerConfig: definitions.PostableApiAlertingConfig{ + Config: definitions.Config{ + Route: &definitions.Route{ + Receiver: "receiver-1", + Routes: []*definitions.Route{ + { + Receiver: "receiver-1", + }, + { + Receiver: "receiver-2", + }, + }, + }, + }, + Receivers: []*definitions.PostableApiReceiver{ + { + Receiver: config.Receiver{ + Name: "receiver-1", + }, + PostableGrafanaReceivers: definitions.PostableGrafanaReceivers{ + GrafanaManagedReceivers: []*definitions.PostableGrafanaReceiver{ + { + UID: "1", + Name: "receiver-1", + Type: "slack", + }, + { + UID: "2", + Name: "receiver-1", + Type: "slack", + }, + }, + }, + }, + { + Receiver: config.Receiver{ + Name: "receiver-2", + }, + PostableGrafanaReceivers: definitions.PostableGrafanaReceivers{ + GrafanaManagedReceivers: []*definitions.PostableGrafanaReceiver{ + { + UID: "3", + Name: "receiver-2", + Type: "slack", + }, + }, + }, + }, + }, + }, + }, + new: &definitions.PostableGrafanaReceiver{ + UID: "3", + Name: "receiver-1", + Type: "slack", + }, + expModified: true, + expCfg: definitions.PostableApiAlertingConfig{ + Config: definitions.Config{ + Route: &definitions.Route{ + Receiver: "receiver-1", + Routes: []*definitions.Route{ + { + Receiver: "receiver-1", + }, + { + Receiver: "receiver-1", + }, + }, + }, + }, + Receivers: []*definitions.PostableApiReceiver{ + { + Receiver: config.Receiver{ + Name: "receiver-1", + }, + PostableGrafanaReceivers: definitions.PostableGrafanaReceivers{ + GrafanaManagedReceivers: []*definitions.PostableGrafanaReceiver{ + { + UID: "1", + Name: "receiver-1", + Type: "slack", + }, + { + UID: "2", + Name: "receiver-1", + Type: "slack", + }, + { + UID: "3", + Name: "receiver-1", + Type: "slack", + }, + }, + }, + }, + }, + }, + }, } for _, c := range cases {