Alerting: introduce AlertRuleGroupKey and use it in API handlers (#48945)
* create AlertGroupKey structure * update PrometheusSrv. - extract creation of RuleGroup to a separate method. Use group key for grouping * update RuleSrv - update calculateChanges to use groupKey - authorize to use groupkey
This commit is contained in:
@@ -33,11 +33,10 @@ func TestCalculateChanges(t *testing.T) {
|
||||
t.Run("detects alerts that need to be added", func(t *testing.T) {
|
||||
fakeStore := store.NewFakeRuleStore(t)
|
||||
|
||||
namespace := randFolder()
|
||||
groupName := util.GenerateShortUID()
|
||||
groupKey := models.GenerateGroupKey(orgId)
|
||||
submitted := models.GenerateAlertRules(rand.Intn(5)+1, models.AlertRuleGen(withOrgID(orgId), simulateSubmitted, withoutUID))
|
||||
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, orgId, namespace, groupName, submitted)
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, groupKey, submitted)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, changes.New, len(submitted))
|
||||
@@ -56,14 +55,13 @@ func TestCalculateChanges(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("detects alerts that need to be deleted", func(t *testing.T) {
|
||||
namespace := randFolder()
|
||||
groupName := util.GenerateShortUID()
|
||||
inDatabaseMap, inDatabase := models.GenerateUniqueAlertRules(rand.Intn(5)+1, models.AlertRuleGen(withOrgID(orgId), withGroup(groupName), withNamespace(namespace)))
|
||||
groupKey := models.GenerateGroupKey(orgId)
|
||||
inDatabaseMap, inDatabase := models.GenerateUniqueAlertRules(rand.Intn(5)+1, models.AlertRuleGen(withGroupKey(groupKey)))
|
||||
|
||||
fakeStore := store.NewFakeRuleStore(t)
|
||||
fakeStore.PutRule(context.Background(), inDatabase...)
|
||||
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, orgId, namespace, groupName, make([]*models.AlertRule, 0))
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, groupKey, make([]*models.AlertRule, 0))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Empty(t, changes.New)
|
||||
@@ -77,15 +75,14 @@ func TestCalculateChanges(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("should detect alerts that needs to be updated", func(t *testing.T) {
|
||||
namespace := randFolder()
|
||||
groupName := util.GenerateShortUID()
|
||||
inDatabaseMap, inDatabase := models.GenerateUniqueAlertRules(rand.Intn(5)+1, models.AlertRuleGen(withOrgID(orgId), withGroup(groupName), withNamespace(namespace)))
|
||||
submittedMap, submitted := models.GenerateUniqueAlertRules(len(inDatabase), models.AlertRuleGen(simulateSubmitted, withOrgID(orgId), withGroup(groupName), withNamespace(namespace), withUIDs(inDatabaseMap)))
|
||||
groupKey := models.GenerateGroupKey(orgId)
|
||||
inDatabaseMap, inDatabase := models.GenerateUniqueAlertRules(rand.Intn(5)+1, models.AlertRuleGen(withGroupKey(groupKey)))
|
||||
submittedMap, submitted := models.GenerateUniqueAlertRules(len(inDatabase), models.AlertRuleGen(simulateSubmitted, withGroupKey(groupKey), withUIDs(inDatabaseMap)))
|
||||
|
||||
fakeStore := store.NewFakeRuleStore(t)
|
||||
fakeStore.PutRule(context.Background(), inDatabase...)
|
||||
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, orgId, namespace, groupName, submitted)
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, groupKey, submitted)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, changes.Update, len(inDatabase))
|
||||
@@ -101,9 +98,8 @@ func TestCalculateChanges(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("should include only if there are changes ignoring specific fields", func(t *testing.T) {
|
||||
namespace := randFolder()
|
||||
groupName := util.GenerateShortUID()
|
||||
_, inDatabase := models.GenerateUniqueAlertRules(rand.Intn(5)+1, models.AlertRuleGen(withOrgID(orgId), withGroup(groupName), withNamespace(namespace)))
|
||||
groupKey := models.GenerateGroupKey(orgId)
|
||||
_, inDatabase := models.GenerateUniqueAlertRules(rand.Intn(5)+1, models.AlertRuleGen(withGroupKey(groupKey)))
|
||||
|
||||
submitted := make([]*models.AlertRule, 0, len(inDatabase))
|
||||
for _, rule := range inDatabase {
|
||||
@@ -120,7 +116,7 @@ func TestCalculateChanges(t *testing.T) {
|
||||
fakeStore := store.NewFakeRuleStore(t)
|
||||
fakeStore.PutRule(context.Background(), inDatabase...)
|
||||
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, orgId, namespace, groupName, submitted)
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, groupKey, submitted)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Empty(t, changes.Update)
|
||||
@@ -171,15 +167,14 @@ func TestCalculateChanges(t *testing.T) {
|
||||
fakeStore := store.NewFakeRuleStore(t)
|
||||
fakeStore.PutRule(context.Background(), dbRule)
|
||||
|
||||
namespace := randFolder()
|
||||
groupName := util.GenerateShortUID()
|
||||
groupKey := models.GenerateGroupKey(orgId)
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
expected := models.AlertRuleGen(simulateSubmitted, testCase.mutator)()
|
||||
expected.UID = dbRule.UID
|
||||
submitted := *expected
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, orgId, namespace, groupName, []*models.AlertRule{&submitted})
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, groupKey, []*models.AlertRule{&submitted})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, changes.Update, 1)
|
||||
ch := changes.Update[0]
|
||||
@@ -199,9 +194,16 @@ func TestCalculateChanges(t *testing.T) {
|
||||
|
||||
namespace := randFolder()
|
||||
groupName := util.GenerateShortUID()
|
||||
submittedMap, submitted := models.GenerateUniqueAlertRules(rand.Intn(len(inDatabase)-5)+5, models.AlertRuleGen(simulateSubmitted, withOrgID(orgId), withGroup(groupName), withNamespace(namespace), withUIDs(inDatabaseMap)))
|
||||
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, orgId, namespace, groupName, submitted)
|
||||
groupKey := models.AlertRuleGroupKey{
|
||||
OrgID: orgId,
|
||||
NamespaceUID: namespace.Uid,
|
||||
RuleGroup: groupName,
|
||||
}
|
||||
|
||||
submittedMap, submitted := models.GenerateUniqueAlertRules(rand.Intn(len(inDatabase)-5)+5, models.AlertRuleGen(simulateSubmitted, withGroupKey(groupKey), withUIDs(inDatabaseMap)))
|
||||
|
||||
changes, err := calculateChanges(context.Background(), fakeStore, groupKey, submitted)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Empty(t, changes.Delete)
|
||||
@@ -218,13 +220,11 @@ func TestCalculateChanges(t *testing.T) {
|
||||
|
||||
t.Run("should fail when submitted rule has UID that does not exist in db", func(t *testing.T) {
|
||||
fakeStore := store.NewFakeRuleStore(t)
|
||||
|
||||
namespace := randFolder()
|
||||
groupName := util.GenerateShortUID()
|
||||
groupKey := models.GenerateGroupKey(orgId)
|
||||
submitted := models.AlertRuleGen(withOrgID(orgId), simulateSubmitted)()
|
||||
require.NotEqual(t, "", submitted.UID)
|
||||
|
||||
_, err := calculateChanges(context.Background(), fakeStore, orgId, namespace, groupName, []*models.AlertRule{submitted})
|
||||
_, err := calculateChanges(context.Background(), fakeStore, groupKey, []*models.AlertRule{submitted})
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
@@ -239,11 +239,10 @@ func TestCalculateChanges(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
namespace := randFolder()
|
||||
groupName := util.GenerateShortUID()
|
||||
groupKey := models.GenerateGroupKey(orgId)
|
||||
submitted := models.AlertRuleGen(withOrgID(orgId), simulateSubmitted, withoutUID)()
|
||||
|
||||
_, err := calculateChanges(context.Background(), fakeStore, orgId, namespace, groupName, []*models.AlertRule{submitted})
|
||||
_, err := calculateChanges(context.Background(), fakeStore, groupKey, []*models.AlertRule{submitted})
|
||||
require.ErrorIs(t, err, expectedErr)
|
||||
})
|
||||
|
||||
@@ -258,11 +257,10 @@ func TestCalculateChanges(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
namespace := randFolder()
|
||||
groupName := util.GenerateShortUID()
|
||||
groupKey := models.GenerateGroupKey(orgId)
|
||||
submitted := models.AlertRuleGen(withOrgID(orgId), simulateSubmitted)()
|
||||
|
||||
_, err := calculateChanges(context.Background(), fakeStore, orgId, namespace, groupName, []*models.AlertRule{submitted})
|
||||
_, err := calculateChanges(context.Background(), fakeStore, groupKey, []*models.AlertRule{submitted})
|
||||
require.Error(t, err, expectedErr)
|
||||
})
|
||||
}
|
||||
@@ -705,6 +703,14 @@ func withNamespace(namespace *models2.Folder) func(rule *models.AlertRule) {
|
||||
}
|
||||
}
|
||||
|
||||
func withGroupKey(groupKey models.AlertRuleGroupKey) func(rule *models.AlertRule) {
|
||||
return func(rule *models.AlertRule) {
|
||||
rule.RuleGroup = groupKey.RuleGroup
|
||||
rule.OrgID = groupKey.OrgID
|
||||
rule.NamespaceUID = groupKey.NamespaceUID
|
||||
}
|
||||
}
|
||||
|
||||
// simulateSubmitted resets some fields of the structure that are not populated by API model to model conversion
|
||||
func simulateSubmitted(rule *models.AlertRule) {
|
||||
rule.ID = 0
|
||||
|
||||
Reference in New Issue
Block a user