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:
Yuri Tseretyan
2025-02-03 13:26:18 -05:00
committed by GitHub
parent 8a259ecafa
commit ac41c19350
20 changed files with 772 additions and 16 deletions
+25
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"slices"
"sort"
"strings"
"time"
@@ -330,6 +331,30 @@ func (srv RulerSrv) RouteGetRuleByUID(c *contextmodel.ReqContext, ruleUID string
return response.JSON(http.StatusOK, result)
}
func (srv RulerSrv) RouteGetRuleVersionsByUID(c *contextmodel.ReqContext, ruleUID string) response.Response {
ctx := c.Req.Context()
// make sure the user has access to the current version of the rule. Also, check if it exists
_, err := srv.getAuthorizedRuleByUid(ctx, c, ruleUID)
if err != nil {
if errors.Is(err, ngmodels.ErrAlertRuleNotFound) {
return response.Empty(http.StatusNotFound)
}
return response.ErrOrFallback(http.StatusInternalServerError, "failed to get rule by UID", err)
}
rules, err := srv.store.GetAlertRuleVersions(ctx, ngmodels.AlertRuleKey{OrgID: c.OrgID, UID: ruleUID})
if err != nil {
return response.ErrOrFallback(http.StatusInternalServerError, "failed to get rule history", err)
}
sort.Slice(rules, func(i, j int) bool { return rules[i].ID > rules[j].ID })
result := make(apimodels.GettableRuleVersions, 0, len(rules))
for _, rule := range rules {
// do not provide provenance status because we do not have historical changes for it
result = append(result, toGettableExtendedRuleNode(*rule, map[string]ngmodels.Provenance{}, srv.resolveUserIdToNameFn(ctx)))
}
return response.JSON(http.StatusOK, result)
}
func (srv RulerSrv) RoutePostNameRulesConfig(c *contextmodel.ReqContext, ruleGroupConfig apimodels.PostableRuleGroupConfig, namespaceUID string) response.Response {
namespace, err := srv.store.GetNamespaceByUID(c.Req.Context(), namespaceUID, c.SignedInUser.GetOrgID(), c.SignedInUser)
if err != nil {