Alerting: Rule Modify Export APIs (#75322)

* extend RuleStore interface to get namespace by UID
* add new export API endpoints
* implement request handlers
* update authorization and wire handlers to paths
* add folder error matchers to errorToResponse
* add tests for export methods
This commit is contained in:
Yuri Tseretyan
2023-10-02 11:47:59 -04:00
committed by GitHub
parent e877174501
commit 027bd9356f
23 changed files with 1504 additions and 122 deletions
+46
View File
@@ -143,6 +143,43 @@ type AlertRuleGroupWithFolderTitle struct {
FolderTitle string
}
func NewAlertRuleGroupWithFolderTitle(groupKey AlertRuleGroupKey, rules []AlertRule, folderTitle string) AlertRuleGroupWithFolderTitle {
SortAlertRulesByGroupIndex(rules)
var interval int64
if len(rules) > 0 {
interval = rules[0].IntervalSeconds
}
var result = AlertRuleGroupWithFolderTitle{
AlertRuleGroup: &AlertRuleGroup{
Title: groupKey.RuleGroup,
FolderUID: groupKey.NamespaceUID,
Interval: interval,
Rules: rules,
},
FolderTitle: folderTitle,
OrgID: groupKey.OrgID,
}
return result
}
func NewAlertRuleGroupWithFolderTitleFromRulesGroup(groupKey AlertRuleGroupKey, rules RulesGroup, folderTitle string) AlertRuleGroupWithFolderTitle {
derefRules := make([]AlertRule, 0, len(rules))
for _, rule := range rules {
derefRules = append(derefRules, *rule)
}
return NewAlertRuleGroupWithFolderTitle(groupKey, derefRules, folderTitle)
}
// SortAlertRuleGroupWithFolderTitle sorts AlertRuleGroupWithFolderTitle by folder UID and group name
func SortAlertRuleGroupWithFolderTitle(g []AlertRuleGroupWithFolderTitle) {
sort.SliceStable(g, func(i, j int) bool {
if g[i].AlertRuleGroup.FolderUID == g[j].AlertRuleGroup.FolderUID {
return g[i].AlertRuleGroup.Title < g[j].AlertRuleGroup.Title
}
return g[i].AlertRuleGroup.FolderUID < g[j].AlertRuleGroup.FolderUID
})
}
// AlertRule is the model for alert rules in unified alerting.
type AlertRule struct {
ID int64 `xorm:"pk autoincr 'id'"`
@@ -556,6 +593,15 @@ func (g RulesGroup) SortByGroupIndex() {
})
}
func SortAlertRulesByGroupIndex(rules []AlertRule) {
sort.Slice(rules, func(i, j int) bool {
if rules[i].RuleGroupIndex == rules[j].RuleGroupIndex {
return rules[i].ID < rules[j].ID
}
return rules[i].RuleGroupIndex < rules[j].RuleGroupIndex
})
}
const (
QuotaTargetSrv quota.TargetSrv = "ngalert"
QuotaTarget quota.Target = "alert_rule"
+26
View File
@@ -4,8 +4,10 @@ import (
"encoding/json"
"fmt"
"math/rand"
"sync"
"time"
"github.com/google/uuid"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/expr"
@@ -92,6 +94,7 @@ func WithNotEmptyLabels(count int, prefix string) AlertRuleMutator {
rule.Labels = GenerateAlertLabels(count, prefix)
}
}
func WithUniqueID() AlertRuleMutator {
usedID := make(map[int64]struct{})
return func(rule *AlertRule) {
@@ -227,6 +230,29 @@ func WithLabel(key, value string) AlertRuleMutator {
}
}
func WithUniqueUID(knownUids *sync.Map) AlertRuleMutator {
return func(rule *AlertRule) {
uid := rule.UID
for {
_, ok := knownUids.LoadOrStore(uid, struct{}{})
if !ok {
rule.UID = uid
return
}
uid = uuid.NewString()
}
}
}
func WithQuery(query ...AlertQuery) AlertRuleMutator {
return func(rule *AlertRule) {
rule.Data = query
if len(query) > 1 {
rule.Condition = query[0].RefID
}
}
}
func GenerateAlertLabels(count int, prefix string) data.Labels {
labels := make(data.Labels, count)
for i := 0; i < count; i++ {