CloudMigrations: Add config for alert rules state behavior and remove experimental feature toggle on alerts migration (#97254)

* CloudMigrations: add config for controlling alert rules state behavior

* CloudMigrations: remove experimental 'onPremToCloudMigrationsAlerts' feature toggle
This commit is contained in:
Matheus Macabu
2024-12-17 12:56:18 +01:00
committed by GitHub
parent ae7cb6866d
commit c824f5b9bf
12 changed files with 69 additions and 95 deletions
@@ -826,7 +826,9 @@ func ctxWithSignedInUser() context.Context {
return ctx
}
func setUpServiceTest(t *testing.T, withDashboardMock bool) cloudmigration.Service {
type configOverrides func(c *setting.Cfg)
func setUpServiceTest(t *testing.T, withDashboardMock bool, cfgOverrides ...configOverrides) cloudmigration.Service {
sqlStore := db.InitTestDB(t)
secretsService := secretsfakes.NewFakeSecretsService()
rr := routing.NewRouteRegister()
@@ -866,7 +868,6 @@ func setUpServiceTest(t *testing.T, withDashboardMock bool) cloudmigration.Servi
featureToggles := featuremgmt.WithFeatures(
featuremgmt.FlagOnPremToCloudMigrations,
featuremgmt.FlagOnPremToCloudMigrationsAlerts,
featuremgmt.FlagDashboardRestore, // needed for skipping creating soft-deleted dashboards in the snapshot.
)
@@ -930,6 +931,10 @@ func setUpServiceTest(t *testing.T, withDashboardMock bool) cloudmigration.Servi
require.NoError(t, err)
}
for _, cfgOverride := range cfgOverrides {
cfgOverride(cfg)
}
s, err := ProvideService(
cfg,
httpclient.NewProvider(),
@@ -9,11 +9,11 @@ import (
"github.com/prometheus/common/model"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/featuremgmt"
ngalertapi "github.com/grafana/grafana/pkg/services/ngalert/api"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
type muteTimeInterval struct {
@@ -25,10 +25,6 @@ type muteTimeInterval struct {
}
func (s *Service) getAlertMuteTimings(ctx context.Context, signedInUser *user.SignedInUser) ([]muteTimeInterval, error) {
if !s.features.IsEnabledGlobally(featuremgmt.FlagOnPremToCloudMigrationsAlerts) {
return nil, nil
}
muteTimings, err := s.ngAlert.Api.MuteTimings.GetMuteTimings(ctx, signedInUser.OrgID)
if err != nil {
return nil, fmt.Errorf("fetching ngalert mute timings: %w", err)
@@ -56,10 +52,6 @@ type notificationTemplate struct {
}
func (s *Service) getNotificationTemplates(ctx context.Context, signedInUser *user.SignedInUser) ([]notificationTemplate, error) {
if !s.features.IsEnabledGlobally(featuremgmt.FlagOnPremToCloudMigrationsAlerts) {
return nil, nil
}
templates, err := s.ngAlert.Api.Templates.GetTemplates(ctx, signedInUser.OrgID)
if err != nil {
return nil, fmt.Errorf("fetching ngalert notification templates: %w", err)
@@ -87,10 +79,6 @@ type contactPoint struct {
}
func (s *Service) getContactPoints(ctx context.Context, signedInUser *user.SignedInUser) ([]contactPoint, error) {
if !s.features.IsEnabledGlobally(featuremgmt.FlagOnPremToCloudMigrationsAlerts) {
return nil, nil
}
query := provisioning.ContactPointQuery{
OrgID: signedInUser.GetOrgID(),
Decrypt: true, // needed to recreate the settings in the target instance.
@@ -122,10 +110,6 @@ type notificationPolicy struct {
}
func (s *Service) getNotificationPolicies(ctx context.Context, signedInUser *user.SignedInUser) (notificationPolicy, error) {
if !s.features.IsEnabledGlobally(featuremgmt.FlagOnPremToCloudMigrationsAlerts) {
return notificationPolicy{}, nil
}
policyTree, _, err := s.ngAlert.Api.Policies.GetPolicyTree(ctx, signedInUser.GetOrgID())
if err != nil {
return notificationPolicy{}, fmt.Errorf("fetching ngalert notification policy tree: %w", err)
@@ -158,18 +142,21 @@ type alertRule struct {
}
func (s *Service) getAlertRules(ctx context.Context, signedInUser *user.SignedInUser) ([]alertRule, error) {
if !s.features.IsEnabledGlobally(featuremgmt.FlagOnPremToCloudMigrationsAlerts) {
return nil, nil
}
alertRules, _, err := s.ngAlert.Api.AlertRules.GetAlertRules(ctx, signedInUser)
if err != nil {
return nil, fmt.Errorf("fetching alert rules: %w", err)
}
settingAlertRulesPaused := s.cfg.CloudMigration.AlertRulesState == setting.GMSAlertRulesPaused
provisionedAlertRules := make([]alertRule, 0, len(alertRules))
for _, rule := range alertRules {
isPaused := rule.IsPaused
if settingAlertRulesPaused {
isPaused = true
}
provisionedAlertRules = append(provisionedAlertRules, alertRule{
ID: rule.ID,
UID: rule.UID,
@@ -185,7 +172,7 @@ func (s *Service) getAlertRules(ctx context.Context, signedInUser *user.SignedIn
ExecErrState: rule.ExecErrState.String(),
Annotations: rule.Annotations,
Labels: rule.Labels,
IsPaused: rule.IsPaused,
IsPaused: isPaused,
NotificationSettings: ngalertapi.AlertRuleNotificationSettingsFromNotificationSettings(rule.NotificationSettings),
Record: ngalertapi.ApiRecordFromModelRecord(rule.Record),
})
@@ -3,6 +3,7 @@ package cloudmigrationimpl
import (
"context"
"encoding/json"
"fmt"
"testing"
"time"
@@ -17,25 +18,17 @@ import (
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
func TestGetAlertMuteTimings(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is not enabled it returns nil", func(t *testing.T) {
t.Run("it returns the mute timings", func(t *testing.T) {
s := setUpServiceTest(t, false).(*Service)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations)
muteTimeIntervals, err := s.getAlertMuteTimings(ctx, nil)
require.NoError(t, err)
require.Nil(t, muteTimeIntervals)
})
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is enabled it returns the mute timings", func(t *testing.T) {
s := setUpServiceTest(t, false).(*Service)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations, featuremgmt.FlagOnPremToCloudMigrationsAlerts)
user := &user.SignedInUser{OrgID: 1}
createdMuteTiming := createMuteTiming(t, ctx, s, user)
@@ -52,18 +45,8 @@ func TestGetNotificationTemplates(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is not enabled it returns nil", func(t *testing.T) {
t.Run("it returns the notification templates", func(t *testing.T) {
s := setUpServiceTest(t, false).(*Service)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations)
notificationTemplates, err := s.getNotificationTemplates(ctx, nil)
require.NoError(t, err)
require.Nil(t, notificationTemplates)
})
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is enabled it returns the notification templates", func(t *testing.T) {
s := setUpServiceTest(t, false).(*Service)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations, featuremgmt.FlagOnPremToCloudMigrationsAlerts)
user := &user.SignedInUser{OrgID: 1}
@@ -81,18 +64,8 @@ func TestGetContactPoints(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is not enabled it returns nil", func(t *testing.T) {
t.Run("it returns the contact points", func(t *testing.T) {
s := setUpServiceTest(t, false).(*Service)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations)
contactPoints, err := s.getContactPoints(ctx, nil)
require.NoError(t, err)
require.Nil(t, contactPoints)
})
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is enabled it returns the contact points", func(t *testing.T) {
s := setUpServiceTest(t, false).(*Service)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations, featuremgmt.FlagOnPremToCloudMigrationsAlerts)
user := &user.SignedInUser{
OrgID: 1,
@@ -119,18 +92,8 @@ func TestGetNotificationPolicies(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is not enabled it returns nil", func(t *testing.T) {
t.Run("it returns the contact points", func(t *testing.T) {
s := setUpServiceTest(t, false).(*Service)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations)
notificationPolicies, err := s.getNotificationPolicies(ctx, nil)
require.NoError(t, err)
require.Empty(t, notificationPolicies)
})
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is enabled it returns the contact points", func(t *testing.T) {
s := setUpServiceTest(t, false).(*Service)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations, featuremgmt.FlagOnPremToCloudMigrationsAlerts)
user := &user.SignedInUser{OrgID: 1}
@@ -153,28 +116,40 @@ func TestGetAlertRules(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is not enabled it returns nil", func(t *testing.T) {
t.Run("it returns the alert rules", func(t *testing.T) {
s := setUpServiceTest(t, false).(*Service)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations)
alertRules, err := s.getAlertRules(ctx, nil)
require.NoError(t, err)
require.Nil(t, alertRules)
})
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is enabled it returns the alert rules", func(t *testing.T) {
s := setUpServiceTest(t, false).(*Service)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations, featuremgmt.FlagOnPremToCloudMigrationsAlerts)
user := &user.SignedInUser{OrgID: 1}
alertRule := createAlertRule(t, ctx, s, user)
alertRule := createAlertRule(t, ctx, s, user, false)
alertRules, err := s.getAlertRules(ctx, user)
require.NoError(t, err)
require.Len(t, alertRules, 1)
require.Equal(t, alertRule.UID, alertRules[0].UID)
})
t.Run("when the alert_rules_state config is `paused`, then the alert rules are all returned in `paused` state", func(t *testing.T) {
alertRulesState := func(c *setting.Cfg) {
c.CloudMigration.AlertRulesState = setting.GMSAlertRulesPaused
}
s := setUpServiceTest(t, false, alertRulesState).(*Service)
user := &user.SignedInUser{OrgID: 1}
alertRulePaused := createAlertRule(t, ctx, s, user, true)
require.True(t, alertRulePaused.IsPaused)
alertRuleUnpaused := createAlertRule(t, ctx, s, user, false)
require.False(t, alertRuleUnpaused.IsPaused)
alertRules, err := s.getAlertRules(ctx, user)
require.NoError(t, err)
require.Len(t, alertRules, 2)
require.True(t, alertRules[0].IsPaused)
require.True(t, alertRules[1].IsPaused)
})
}
func createMuteTiming(t *testing.T, ctx context.Context, service *Service, user *user.SignedInUser) definitions.MuteTimeInterval {
@@ -292,12 +267,12 @@ func updateNotificationPolicyTree(t *testing.T, ctx context.Context, service *Se
require.NoError(t, err)
}
func createAlertRule(t *testing.T, ctx context.Context, service *Service, user *user.SignedInUser) models.AlertRule {
func createAlertRule(t *testing.T, ctx context.Context, service *Service, user *user.SignedInUser, isPaused bool) models.AlertRule {
t.Helper()
rule := models.AlertRule{
OrgID: user.GetOrgID(),
Title: "Alert Rule SLO",
Title: fmt.Sprintf("Alert Rule SLO (Paused: %v)", isPaused),
NamespaceUID: "folderUID",
Condition: "A",
Data: []models.AlertQuery{
@@ -310,6 +285,7 @@ func createAlertRule(t *testing.T, ctx context.Context, service *Service, user *
},
},
},
IsPaused: isPaused,
RuleGroup: "ruleGroup",
For: time.Minute,
IntervalSeconds: 60,