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:
@@ -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"
|
||||
|
||||
@@ -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++ {
|
||||
|
||||
Reference in New Issue
Block a user