From 60d4cd80bf424c9b6512b5b9bb541bf5daffcfc7 Mon Sep 17 00:00:00 2001 From: Yuriy Tseretyan Date: Wed, 23 Mar 2022 16:09:53 -0400 Subject: [PATCH] Alerting: update DeleteAlertRuleByUID to accept many UID (#46890) --- pkg/services/ngalert/api/api_ruler.go | 11 ++++++++--- pkg/services/ngalert/schedule/schedule_test.go | 3 ++- pkg/services/ngalert/store/alert_rule.go | 17 ++++++++++------- pkg/services/ngalert/store/testing.go | 4 +++- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/pkg/services/ngalert/api/api_ruler.go b/pkg/services/ngalert/api/api_ruler.go index e21d2f25636..0b386ccc99e 100644 --- a/pkg/services/ngalert/api/api_ruler.go +++ b/pkg/services/ngalert/api/api_ruler.go @@ -308,9 +308,14 @@ func (srv RulerSrv) updateAlertRulesInGroup(c *models.ReqContext, namespace *mod } } - for _, rule := range groupChanges.Delete { - if err = srv.store.DeleteAlertRuleByUID(tranCtx, c.SignedInUser.OrgId, rule.UID); err != nil { - return fmt.Errorf("failed to delete rule %d with UID %s: %w", rule.ID, rule.UID, err) + if len(groupChanges.Delete) > 0 { + UIDs := make([]string, 0, len(groupChanges.Delete)) + for _, rule := range groupChanges.Delete { + UIDs = append(UIDs, rule.UID) + } + + if err = srv.store.DeleteAlertRulesByUID(tranCtx, c.SignedInUser.OrgId, UIDs...); err != nil { + return fmt.Errorf("failed to delete rules: %w", err) } } diff --git a/pkg/services/ngalert/schedule/schedule_test.go b/pkg/services/ngalert/schedule/schedule_test.go index 4e309ca9bb1..e8b754e56b0 100644 --- a/pkg/services/ngalert/schedule/schedule_test.go +++ b/pkg/services/ngalert/schedule/schedule_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/grafana/grafana-plugin-sdk-go/data" + "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/ngalert/eval" "github.com/grafana/grafana/pkg/services/ngalert/metrics" @@ -200,7 +201,7 @@ func TestAlertingTicker(t *testing.T) { }) key := alerts[0].GetKey() - err := dbstore.DeleteAlertRuleByUID(ctx, alerts[0].OrgID, alerts[0].UID) + err := dbstore.DeleteAlertRulesByUID(ctx, alerts[0].OrgID, alerts[0].UID) require.NoError(t, err) t.Logf("alert rule: %v deleted", key) diff --git a/pkg/services/ngalert/store/alert_rule.go b/pkg/services/ngalert/store/alert_rule.go index 97b2fa7ec4c..59308e64bc1 100644 --- a/pkg/services/ngalert/store/alert_rule.go +++ b/pkg/services/ngalert/store/alert_rule.go @@ -35,7 +35,7 @@ type UpsertRule struct { // Store is the interface for persisting alert rules and instances type RuleStore interface { - DeleteAlertRuleByUID(ctx context.Context, orgID int64, ruleUID string) error + DeleteAlertRulesByUID(ctx context.Context, orgID int64, ruleUID ...string) error DeleteNamespaceAlertRules(ctx context.Context, orgID int64, namespaceUID string) ([]string, error) DeleteRuleGroupAlertRules(ctx context.Context, orgID int64, namespaceUID string, ruleGroup string) ([]string, error) DeleteAlertInstancesByRuleUID(ctx context.Context, orgID int64, ruleUID string) error @@ -63,24 +63,27 @@ func getAlertRuleByUID(sess *sqlstore.DBSession, alertRuleUID string, orgID int6 return &alertRule, nil } -// DeleteAlertRuleByUID is a handler for deleting an alert rule. -func (st DBstore) DeleteAlertRuleByUID(ctx context.Context, orgID int64, ruleUID string) error { +// DeleteAlertRulesByUID is a handler for deleting an alert rule. +func (st DBstore) DeleteAlertRulesByUID(ctx context.Context, orgID int64, ruleUID ...string) error { + logger := st.Logger.New("org_id", orgID, "rule_uids", ruleUID) return st.SQLStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error { - _, err := sess.Exec("DELETE FROM alert_rule WHERE org_id = ? AND uid = ?", orgID, ruleUID) + rows, err := sess.Table("alert_rule").Where("org_id = ?", orgID).In("uid", ruleUID).Delete(ngmodels.AlertRule{}) if err != nil { return err } + logger.Debug("deleted alert rules", "count", rows) - _, err = sess.Exec("DELETE FROM alert_rule_version WHERE rule_org_id = ? and rule_uid = ?", orgID, ruleUID) - + rows, err = sess.Table("alert_rule_version").Where("rule_org_id = ?", orgID).In("rule_uid", ruleUID).Delete(ngmodels.AlertRule{}) if err != nil { return err } + logger.Debug("deleted alert rule versions", "count", rows) - _, err = sess.Exec("DELETE FROM alert_instance WHERE rule_org_id = ? AND rule_uid = ?", orgID, ruleUID) + rows, err = sess.Table("alert_instance").Where("rule_org_id = ?", orgID).In("rule_uid", ruleUID).Delete(ngmodels.AlertRule{}) if err != nil { return err } + logger.Debug("deleted alert instances", "count", rows) return nil }) } diff --git a/pkg/services/ngalert/store/testing.go b/pkg/services/ngalert/store/testing.go index 62f37d1dfd5..362e000c239 100644 --- a/pkg/services/ngalert/store/testing.go +++ b/pkg/services/ngalert/store/testing.go @@ -76,7 +76,9 @@ func (f *FakeRuleStore) GetRecordedCommands(predicate func(cmd interface{}) (int return result } -func (f *FakeRuleStore) DeleteAlertRuleByUID(_ context.Context, _ int64, _ string) error { return nil } +func (f *FakeRuleStore) DeleteAlertRulesByUID(_ context.Context, _ int64, _ ...string) error { + return nil +} func (f *FakeRuleStore) DeleteNamespaceAlertRules(_ context.Context, _ int64, _ string) ([]string, error) { return []string{}, nil }