Alerting: refactor rule API to create rule group in a single place (#48915)

* extract method toGettableRuleGroupConfig
pull/44865/head^2
Yuriy Tseretyan 4 years ago committed by GitHub
parent 6c9cf4843f
commit 186ba26b59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 78
      pkg/services/ngalert/api/api_ruler.go

@ -226,9 +226,6 @@ func (srv RulerSrv) RouteGetRulesGroupConfig(c *models.ReqContext) response.Resp
return ErrResp(http.StatusInternalServerError, err, "failed to get group alert rules") return ErrResp(http.StatusInternalServerError, err, "failed to get group alert rules")
} }
var ruleGroupInterval model.Duration
ruleNodes := make([]apimodels.GettableExtendedRuleNode, 0, len(q.Result))
hasAccess := func(evaluator accesscontrol.Evaluator) bool { hasAccess := func(evaluator accesscontrol.Evaluator) bool {
return accesscontrol.HasAccess(srv.ac, c)(accesscontrol.ReqSignedIn, evaluator) return accesscontrol.HasAccess(srv.ac, c)(accesscontrol.ReqSignedIn, evaluator)
} }
@ -238,20 +235,16 @@ func (srv RulerSrv) RouteGetRulesGroupConfig(c *models.ReqContext) response.Resp
return ErrResp(http.StatusInternalServerError, err, "failed to get group alert rules") return ErrResp(http.StatusInternalServerError, err, "failed to get group alert rules")
} }
groupRules := make([]*ngmodels.AlertRule, 0, len(q.Result))
for _, r := range q.Result { for _, r := range q.Result {
if !authorizeDatasourceAccessForRule(r, hasAccess) { if !authorizeDatasourceAccessForRule(r, hasAccess) {
continue continue
} }
ruleGroupInterval = model.Duration(time.Duration(r.IntervalSeconds) * time.Second) groupRules = append(groupRules, r)
ruleNodes = append(ruleNodes, toGettableExtendedRuleNode(*r, namespace.Id, provenanceRecords))
} }
result := apimodels.RuleGroupConfigResponse{ result := apimodels.RuleGroupConfigResponse{
GettableRuleGroupConfig: apimodels.GettableRuleGroupConfig{ GettableRuleGroupConfig: toGettableRuleGroupConfig(ruleGroup, groupRules, namespace.Id, provenanceRecords),
Name: ruleGroup,
Interval: ruleGroupInterval,
Rules: ruleNodes,
},
} }
return response.JSON(http.StatusAccepted, result) return response.JSON(http.StatusAccepted, result)
} }
@ -293,7 +286,7 @@ func (srv RulerSrv) RouteGetRulesConfig(c *models.ReqContext) response.Response
return ErrResp(http.StatusInternalServerError, err, "failed to get alert rules") return ErrResp(http.StatusInternalServerError, err, "failed to get alert rules")
} }
configs := make(map[string]map[string]apimodels.GettableRuleGroupConfig) configs := make(map[string]map[string][]*ngmodels.AlertRule)
hasAccess := func(evaluator accesscontrol.Evaluator) bool { hasAccess := func(evaluator accesscontrol.Evaluator) bool {
return accesscontrol.HasAccess(srv.ac, c)(accesscontrol.ReqSignedIn, evaluator) return accesscontrol.HasAccess(srv.ac, c)(accesscontrol.ReqSignedIn, evaluator)
@ -308,44 +301,25 @@ func (srv RulerSrv) RouteGetRulesConfig(c *models.ReqContext) response.Response
if !authorizeDatasourceAccessForRule(r, hasAccess) { if !authorizeDatasourceAccessForRule(r, hasAccess) {
continue continue
} }
folder, ok := namespaceMap[r.NamespaceUID] namespaceCfgs, ok := configs[r.NamespaceUID]
if !ok { if !ok {
srv.log.Error("namespace not visible to the user", "user", c.SignedInUser.UserId, "namespace", r.NamespaceUID, "rule", r.UID) namespaceCfgs = make(map[string][]*ngmodels.AlertRule)
continue configs[r.NamespaceUID] = namespaceCfgs
} }
namespace := folder.Title group := namespaceCfgs[r.RuleGroup]
_, ok = configs[namespace] group = append(group, r)
if !ok { namespaceCfgs[r.RuleGroup] = group
ruleGroupInterval := model.Duration(time.Duration(r.IntervalSeconds) * time.Second)
configs[namespace] = make(map[string]apimodels.GettableRuleGroupConfig)
configs[namespace][r.RuleGroup] = apimodels.GettableRuleGroupConfig{
Name: r.RuleGroup,
Interval: ruleGroupInterval,
Rules: []apimodels.GettableExtendedRuleNode{
toGettableExtendedRuleNode(*r, folder.Id, provenanceRecords),
},
} }
} else {
ruleGroupConfig, ok := configs[namespace][r.RuleGroup] for namespaceUID, m := range configs {
folder, ok := namespaceMap[namespaceUID]
if !ok { if !ok {
ruleGroupInterval := model.Duration(time.Duration(r.IntervalSeconds) * time.Second) srv.log.Error("namespace not visible to the user", "user", c.SignedInUser.UserId, "namespace", namespaceUID)
configs[namespace][r.RuleGroup] = apimodels.GettableRuleGroupConfig{ continue
Name: r.RuleGroup,
Interval: ruleGroupInterval,
Rules: []apimodels.GettableExtendedRuleNode{
toGettableExtendedRuleNode(*r, folder.Id, provenanceRecords),
},
}
} else {
ruleGroupConfig.Rules = append(ruleGroupConfig.Rules, toGettableExtendedRuleNode(*r, folder.Id, provenanceRecords))
configs[namespace][r.RuleGroup] = ruleGroupConfig
}
}
} }
namespace := folder.Title
for namespace, m := range configs { for groupName, groupRules := range m {
for _, ruleGroupConfig := range m { result[namespace] = append(result[namespace], toGettableRuleGroupConfig(groupName, groupRules, folder.Id, provenanceRecords))
result[namespace] = append(result[namespace], ruleGroupConfig)
} }
} }
return response.JSON(http.StatusOK, result) return response.JSON(http.StatusOK, result)
@ -526,6 +500,22 @@ func (srv RulerSrv) updateAlertRulesInGroup(c *models.ReqContext, namespace *mod
return response.JSON(http.StatusAccepted, util.DynMap{"message": "rule group updated successfully"}) return response.JSON(http.StatusAccepted, util.DynMap{"message": "rule group updated successfully"})
} }
func toGettableRuleGroupConfig(groupName string, rules []*ngmodels.AlertRule, namespaceID int64, provenanceRecords map[string]ngmodels.Provenance) apimodels.GettableRuleGroupConfig {
ruleNodes := make([]apimodels.GettableExtendedRuleNode, 0, len(rules))
var interval time.Duration
if len(rules) > 0 {
interval = time.Duration(rules[0].IntervalSeconds) * time.Second
}
for _, r := range rules {
ruleNodes = append(ruleNodes, toGettableExtendedRuleNode(*r, namespaceID, provenanceRecords))
}
return apimodels.GettableRuleGroupConfig{
Name: groupName,
Interval: model.Duration(interval),
Rules: ruleNodes,
}
}
func toGettableExtendedRuleNode(r ngmodels.AlertRule, namespaceID int64, provenanceRecords map[string]ngmodels.Provenance) apimodels.GettableExtendedRuleNode { func toGettableExtendedRuleNode(r ngmodels.AlertRule, namespaceID int64, provenanceRecords map[string]ngmodels.Provenance) apimodels.GettableExtendedRuleNode {
provenance := ngmodels.ProvenanceNone provenance := ngmodels.ProvenanceNone
if prov, exists := provenanceRecords[r.ResourceID()]; exists { if prov, exists := provenanceRecords[r.ResourceID()]; exists {

Loading…
Cancel
Save