diff --git a/pkg/services/ngalert/models/alert_rule.go b/pkg/services/ngalert/models/alert_rule.go index e5f1b41ed1c..4faf0d52e65 100644 --- a/pkg/services/ngalert/models/alert_rule.go +++ b/pkg/services/ngalert/models/alert_rule.go @@ -768,7 +768,7 @@ func PatchPartialAlertRule(existingRule *AlertRule, ruleToPatch *AlertRuleWithOp if ruleToPatch.Title == "" { ruleToPatch.Title = existingRule.Title } - if ruleToPatch.Condition == "" || len(ruleToPatch.Data) == 0 { + if !hasAnyCondition(ruleToPatch) || len(ruleToPatch.Data) == 0 { ruleToPatch.Condition = existingRule.Condition ruleToPatch.Data = existingRule.Data } @@ -873,3 +873,7 @@ func (r *Record) Fingerprint() data.Fingerprint { writeString(r.From) return data.Fingerprint(h.Sum64()) } + +func hasAnyCondition(rule *AlertRuleWithOptionals) bool { + return rule.Condition != "" || (rule.Record != nil && rule.Record.From != "") +} diff --git a/pkg/services/ngalert/store/deltas_test.go b/pkg/services/ngalert/store/deltas_test.go index 2ae30ae5ef0..2b5c9760575 100644 --- a/pkg/services/ngalert/store/deltas_test.go +++ b/pkg/services/ngalert/store/deltas_test.go @@ -555,6 +555,47 @@ func TestCalculateRuleUpdate(t *testing.T) { require.Contains(t, delta.AffectedGroups, targetGroupKey) assert.Equal(t, models.RulesGroup(targetGroup), delta.AffectedGroups[targetGroupKey]) }) + + t.Run("when an alert rule query is updated", func(t *testing.T) { + cp := models.CopyRule(rule) + cp.Record = nil + cp.Data = []models.AlertQuery{{RefID: "something else"}} + + delta, err := CalculateRuleUpdate(context.Background(), fakeStore, &models.AlertRuleWithOptionals{ + AlertRule: *cp, + HasPause: false, + }) + require.NoError(t, err) + + assert.Equal(t, rule.GetGroupKey(), delta.GroupKey) + assert.Empty(t, delta.New) + assert.Empty(t, delta.Delete) + assert.Len(t, delta.Update, 1) + assert.Equal(t, cp, delta.Update[0].New) + assert.Equal(t, rule, delta.Update[0].Existing) + require.Contains(t, delta.AffectedGroups, delta.GroupKey) + }) + + t.Run("when a recording rule query is updated", func(t *testing.T) { + base := gen.With(models.RuleGen.WithAllRecordingRules()).GenerateRef() + fakeStore.Rules[base.OrgID] = []*models.AlertRule{base} + cp := models.CopyRule(base) + cp.Data = []models.AlertQuery{{RefID: "something else"}} + + delta, err := CalculateRuleUpdate(context.Background(), fakeStore, &models.AlertRuleWithOptionals{ + AlertRule: *cp, + HasPause: false, + }) + require.NoError(t, err) + + assert.Equal(t, base.GetGroupKey(), delta.GroupKey) + assert.Empty(t, delta.New) + assert.Empty(t, delta.Delete) + assert.Len(t, delta.Update, 1) + assert.Equal(t, cp, delta.Update[0].New) + assert.Equal(t, base, delta.Update[0].Existing) + require.Contains(t, delta.AffectedGroups, delta.GroupKey) + }) } func TestCalculateRuleCreate(t *testing.T) {