Alerting: Add support for alpha rules apis in legacy storage
Rules created in the new api makes the rule have no group in the database, but the rule is returned in the old group api with a sentinel group name formatted with the rule uid for compatiblity with the old api. This makes the UI continue to work with the rules without a group, and the ruler will continue to work with the rules without a group. Rules are not allowed to be created in the provisioning api with a NoGroup sentinel mask, but NoGroup rules can be manipulated through both the new and old apis. Co-authored-by: William Wernert <william.wernert@grafana.com>
This commit is contained in:
committed by
Moustafa Baiou
co-authored by
William Wernert
parent
0a85a30642
commit
ca8324e62a
@@ -281,6 +281,55 @@ func NewUserUID(requester interface{ GetIdentifier() string }) *UserUID {
|
||||
return &userUID
|
||||
}
|
||||
|
||||
const (
|
||||
NoGroupPrefix = "no_group_for_rule_"
|
||||
NoGroupNameLength = 200
|
||||
)
|
||||
|
||||
// NoGroupRuleGroup is a special rule group that is used to represent rules that do not belong to any group.
|
||||
type NoGroupRuleGroup struct {
|
||||
ruleUID string
|
||||
}
|
||||
|
||||
func NewNoGroupRuleGroup(ruleUID string) (*NoGroupRuleGroup, error) {
|
||||
// Generate a "no group" string that exceeds 190 char limit to fail validation
|
||||
// This is to ensure that the rule group is not created in the database.
|
||||
if len(ruleUID) > NoGroupNameLength-len(NoGroupPrefix) {
|
||||
return nil, fmt.Errorf("rule UID is too long: %s", ruleUID)
|
||||
}
|
||||
return &NoGroupRuleGroup{ruleUID: ruleUID}, nil
|
||||
}
|
||||
|
||||
func (ruleGroup *NoGroupRuleGroup) String() string {
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString(NoGroupPrefix)
|
||||
sb.WriteString(ruleGroup.ruleUID)
|
||||
for sb.Len() < NoGroupNameLength {
|
||||
sb.WriteRune('*')
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func (ruleGroup *NoGroupRuleGroup) GetRuleUID() string {
|
||||
return ruleGroup.ruleUID
|
||||
}
|
||||
|
||||
func IsNoGroupRuleGroup(ruleGroup string) bool {
|
||||
return strings.HasPrefix(ruleGroup, NoGroupPrefix) && len(ruleGroup) == NoGroupNameLength &&
|
||||
strings.Count(ruleGroup, "*") >= (NoGroupNameLength-len(NoGroupPrefix)-util.MaxUIDLength)
|
||||
}
|
||||
|
||||
func ParseNoRuleGroup(ruleGroup string) (*NoGroupRuleGroup, error) {
|
||||
if !IsNoGroupRuleGroup(ruleGroup) {
|
||||
return nil, fmt.Errorf("rule group %s is not a no group rule group", ruleGroup)
|
||||
}
|
||||
ruleUID := strings.TrimRight(strings.TrimPrefix(ruleGroup, NoGroupPrefix), "*")
|
||||
if err := util.ValidateUID(ruleUID); err != nil {
|
||||
return nil, fmt.Errorf("rule group %s is not a no group rule group, rule uid could not be parsed: %w", ruleGroup, err)
|
||||
}
|
||||
return &NoGroupRuleGroup{ruleUID: ruleUID}, nil
|
||||
}
|
||||
|
||||
// AlertRule is the model for alert rules in unified alerting.
|
||||
type AlertRule struct {
|
||||
ID int64
|
||||
|
||||
@@ -314,7 +314,7 @@ func (a *AlertRuleMutators) WithIntervalSeconds(seconds int64) AlertRuleMutator
|
||||
}
|
||||
}
|
||||
|
||||
// WithIntervalMatching mutator that generates random interval and `for` duration that are times of the provided base interval.
|
||||
// WithIntervalMatching mutator that generates random interval and `for` duration that are multiples of the provided base interval.
|
||||
func (a *AlertRuleMutators) WithIntervalMatching(baseInterval time.Duration) AlertRuleMutator {
|
||||
return func(rule *AlertRule) {
|
||||
rule.IntervalSeconds = int64(baseInterval.Seconds()) * (rand.Int63n(10) + 1)
|
||||
|
||||
Reference in New Issue
Block a user