Alerting: Rule version history API (#99041)
* implement store method to read rule versions * implement request handler * declare a new endpoint * fix fake to return correct response * add tests * add integration tests * rename history to versions * apply diff from swagger CI step Signed-off-by: Yuri Tseretyan <yuriy.tseretyan@grafana.com> --------- Signed-off-by: Yuri Tseretyan <yuriy.tseretyan@grafana.com>
This commit is contained in:
@@ -118,6 +118,36 @@ func (st DBstore) GetAlertRuleByUID(ctx context.Context, query *ngmodels.GetAler
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (st DBstore) GetAlertRuleVersions(ctx context.Context, key ngmodels.AlertRuleKey) ([]*ngmodels.AlertRule, error) {
|
||||
alertRules := make([]*ngmodels.AlertRule, 0)
|
||||
err := st.SQLStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
rows, err := sess.Table(new(alertRuleVersion)).Where("rule_org_id = ? AND rule_uid = ?", key.OrgID, key.UID).Desc("id").Rows(new(alertRuleVersion))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Deserialize each rule separately in case any of them contain invalid JSON.
|
||||
for rows.Next() {
|
||||
rule := new(alertRuleVersion)
|
||||
err = rows.Scan(rule)
|
||||
if err != nil {
|
||||
st.Logger.Error("Invalid rule version found in DB store, ignoring it", "func", "GetAlertRuleVersions", "error", err)
|
||||
continue
|
||||
}
|
||||
converted, err := alertRuleToModelsAlertRule(alertRuleVersionToAlertRule(*rule), st.Logger)
|
||||
if err != nil {
|
||||
st.Logger.Error("Invalid rule found in DB store, cannot convert, ignoring it", "func", "GetAlertRuleVersions", "error", err, "version_id", rule.ID)
|
||||
continue
|
||||
}
|
||||
alertRules = append(alertRules, &converted)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return alertRules, nil
|
||||
}
|
||||
|
||||
// GetRuleByID retrieves models.AlertRule by ID.
|
||||
// It returns models.ErrAlertRuleNotFound if no alert rule is found for the provided ID.
|
||||
func (st DBstore) GetRuleByID(ctx context.Context, query ngmodels.GetAlertRuleByIDQuery) (result *ngmodels.AlertRule, err error) {
|
||||
|
||||
@@ -204,3 +204,34 @@ func alertRuleToAlertRuleVersion(rule alertRule) alertRuleVersion {
|
||||
Metadata: rule.Metadata,
|
||||
}
|
||||
}
|
||||
|
||||
func alertRuleVersionToAlertRule(version alertRuleVersion) alertRule {
|
||||
return alertRule{
|
||||
ID: version.ID,
|
||||
OrgID: version.RuleOrgID,
|
||||
Title: version.Title,
|
||||
Condition: version.Condition,
|
||||
Data: version.Data,
|
||||
Updated: version.Created,
|
||||
UpdatedBy: version.CreatedBy,
|
||||
IntervalSeconds: version.IntervalSeconds,
|
||||
Version: version.Version,
|
||||
UID: version.RuleUID,
|
||||
NamespaceUID: version.RuleNamespaceUID,
|
||||
// Versions do not store Dashboard\Panel as separate column.
|
||||
// However, these fields are part of annotations and information in these fields is redundant
|
||||
DashboardUID: nil,
|
||||
PanelID: nil,
|
||||
RuleGroup: version.RuleGroup,
|
||||
RuleGroupIndex: version.RuleGroupIndex,
|
||||
Record: version.Record,
|
||||
NoDataState: version.NoDataState,
|
||||
ExecErrState: version.ExecErrState,
|
||||
For: version.For,
|
||||
Annotations: version.Annotations,
|
||||
Labels: version.Labels,
|
||||
IsPaused: version.IsPaused,
|
||||
NotificationSettings: version.NotificationSettings,
|
||||
Metadata: version.Metadata,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,3 +43,20 @@ func TestAlertRuleToModelsAlertRule(t *testing.T) {
|
||||
require.Equal(t, ngmodels.ErrorErrState, converted.ExecErrState)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAlertRuleVersionToAlertRule(t *testing.T) {
|
||||
g := ngmodels.RuleGen
|
||||
|
||||
t.Run("make sure no data is lost between conversions", func(t *testing.T) {
|
||||
for _, rule := range g.GenerateMany(100) {
|
||||
// ignore fields
|
||||
rule.DashboardUID = nil
|
||||
rule.PanelID = nil
|
||||
|
||||
r, err := alertRuleFromModelsAlertRule(rule)
|
||||
require.NoError(t, err)
|
||||
r2 := alertRuleVersionToAlertRule(alertRuleToAlertRuleVersion(r))
|
||||
require.Equal(t, r, r2)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user