Alerting: Update rule provisioning service to accept user (#84480)
This commit is contained in:
@@ -58,17 +58,17 @@ type MuteTimingService interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AlertRuleService interface {
|
type AlertRuleService interface {
|
||||||
GetAlertRules(ctx context.Context, orgID int64) ([]*alerting_models.AlertRule, map[string]alerting_models.Provenance, error)
|
GetAlertRules(ctx context.Context, user identity.Requester) ([]*alerting_models.AlertRule, map[string]alerting_models.Provenance, error)
|
||||||
GetAlertRule(ctx context.Context, orgID int64, ruleUID string) (alerting_models.AlertRule, alerting_models.Provenance, error)
|
GetAlertRule(ctx context.Context, user identity.Requester, ruleUID string) (alerting_models.AlertRule, alerting_models.Provenance, error)
|
||||||
CreateAlertRule(ctx context.Context, user identity.Requester, rule alerting_models.AlertRule, provenance alerting_models.Provenance) (alerting_models.AlertRule, error)
|
CreateAlertRule(ctx context.Context, user identity.Requester, rule alerting_models.AlertRule, provenance alerting_models.Provenance) (alerting_models.AlertRule, error)
|
||||||
UpdateAlertRule(ctx context.Context, rule alerting_models.AlertRule, provenance alerting_models.Provenance) (alerting_models.AlertRule, error)
|
UpdateAlertRule(ctx context.Context, user identity.Requester, rule alerting_models.AlertRule, provenance alerting_models.Provenance) (alerting_models.AlertRule, error)
|
||||||
DeleteAlertRule(ctx context.Context, orgID int64, ruleUID string, provenance alerting_models.Provenance) error
|
DeleteAlertRule(ctx context.Context, user identity.Requester, ruleUID string, provenance alerting_models.Provenance) error
|
||||||
GetRuleGroup(ctx context.Context, orgID int64, folder, group string) (alerting_models.AlertRuleGroup, error)
|
GetRuleGroup(ctx context.Context, user identity.Requester, folder, group string) (alerting_models.AlertRuleGroup, error)
|
||||||
ReplaceRuleGroup(ctx context.Context, orgID int64, group alerting_models.AlertRuleGroup, userID int64, provenance alerting_models.Provenance) error
|
ReplaceRuleGroup(ctx context.Context, user identity.Requester, group alerting_models.AlertRuleGroup, provenance alerting_models.Provenance) error
|
||||||
DeleteRuleGroup(ctx context.Context, orgID int64, folder, group string, provenance alerting_models.Provenance) error
|
DeleteRuleGroup(ctx context.Context, user identity.Requester, folder, group string, provenance alerting_models.Provenance) error
|
||||||
GetAlertRuleWithFolderTitle(ctx context.Context, orgID int64, ruleUID string) (provisioning.AlertRuleWithFolderTitle, error)
|
GetAlertRuleWithFolderTitle(ctx context.Context, user identity.Requester, ruleUID string) (provisioning.AlertRuleWithFolderTitle, error)
|
||||||
GetAlertRuleGroupWithFolderTitle(ctx context.Context, orgID int64, folder, group string) (alerting_models.AlertRuleGroupWithFolderTitle, error)
|
GetAlertRuleGroupWithFolderTitle(ctx context.Context, user identity.Requester, folder, group string) (alerting_models.AlertRuleGroupWithFolderTitle, error)
|
||||||
GetAlertGroupsWithFolderTitle(ctx context.Context, orgID int64, folderUIDs []string) ([]alerting_models.AlertRuleGroupWithFolderTitle, error)
|
GetAlertGroupsWithFolderTitle(ctx context.Context, user identity.Requester, folderUIDs []string) ([]alerting_models.AlertRuleGroupWithFolderTitle, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *ProvisioningSrv) RouteGetPolicyTree(c *contextmodel.ReqContext) response.Response {
|
func (srv *ProvisioningSrv) RouteGetPolicyTree(c *contextmodel.ReqContext) response.Response {
|
||||||
@@ -309,7 +309,7 @@ func (srv *ProvisioningSrv) RouteDeleteMuteTiming(c *contextmodel.ReqContext, na
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (srv *ProvisioningSrv) RouteGetAlertRules(c *contextmodel.ReqContext) response.Response {
|
func (srv *ProvisioningSrv) RouteGetAlertRules(c *contextmodel.ReqContext) response.Response {
|
||||||
rules, provenances, err := srv.alertRules.GetAlertRules(c.Req.Context(), c.SignedInUser.GetOrgID())
|
rules, provenances, err := srv.alertRules.GetAlertRules(c.Req.Context(), c.SignedInUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrResp(http.StatusInternalServerError, err, "")
|
return ErrResp(http.StatusInternalServerError, err, "")
|
||||||
}
|
}
|
||||||
@@ -317,7 +317,7 @@ func (srv *ProvisioningSrv) RouteGetAlertRules(c *contextmodel.ReqContext) respo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (srv *ProvisioningSrv) RouteRouteGetAlertRule(c *contextmodel.ReqContext, UID string) response.Response {
|
func (srv *ProvisioningSrv) RouteRouteGetAlertRule(c *contextmodel.ReqContext, UID string) response.Response {
|
||||||
rule, provenace, err := srv.alertRules.GetAlertRule(c.Req.Context(), c.SignedInUser.GetOrgID(), UID)
|
rule, provenace, err := srv.alertRules.GetAlertRule(c.Req.Context(), c.SignedInUser, UID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, alerting_models.ErrAlertRuleNotFound) {
|
if errors.Is(err, alerting_models.ErrAlertRuleNotFound) {
|
||||||
return response.Empty(http.StatusNotFound)
|
return response.Empty(http.StatusNotFound)
|
||||||
@@ -363,7 +363,7 @@ func (srv *ProvisioningSrv) RoutePutAlertRule(c *contextmodel.ReqContext, ar def
|
|||||||
updated.OrgID = c.SignedInUser.GetOrgID()
|
updated.OrgID = c.SignedInUser.GetOrgID()
|
||||||
updated.UID = UID
|
updated.UID = UID
|
||||||
provenance := determineProvenance(c)
|
provenance := determineProvenance(c)
|
||||||
updatedAlertRule, err := srv.alertRules.UpdateAlertRule(c.Req.Context(), updated, alerting_models.Provenance(provenance))
|
updatedAlertRule, err := srv.alertRules.UpdateAlertRule(c.Req.Context(), c.SignedInUser, updated, alerting_models.Provenance(provenance))
|
||||||
if errors.Is(err, alerting_models.ErrAlertRuleUniqueConstraintViolation) {
|
if errors.Is(err, alerting_models.ErrAlertRuleUniqueConstraintViolation) {
|
||||||
return ErrResp(http.StatusBadRequest, err, "")
|
return ErrResp(http.StatusBadRequest, err, "")
|
||||||
}
|
}
|
||||||
@@ -386,7 +386,7 @@ func (srv *ProvisioningSrv) RoutePutAlertRule(c *contextmodel.ReqContext, ar def
|
|||||||
|
|
||||||
func (srv *ProvisioningSrv) RouteDeleteAlertRule(c *contextmodel.ReqContext, UID string) response.Response {
|
func (srv *ProvisioningSrv) RouteDeleteAlertRule(c *contextmodel.ReqContext, UID string) response.Response {
|
||||||
provenance := determineProvenance(c)
|
provenance := determineProvenance(c)
|
||||||
err := srv.alertRules.DeleteAlertRule(c.Req.Context(), c.SignedInUser.GetOrgID(), UID, alerting_models.Provenance(provenance))
|
err := srv.alertRules.DeleteAlertRule(c.Req.Context(), c.SignedInUser, UID, alerting_models.Provenance(provenance))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrResp(http.StatusInternalServerError, err, "")
|
return ErrResp(http.StatusInternalServerError, err, "")
|
||||||
}
|
}
|
||||||
@@ -394,7 +394,7 @@ func (srv *ProvisioningSrv) RouteDeleteAlertRule(c *contextmodel.ReqContext, UID
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (srv *ProvisioningSrv) RouteGetAlertRuleGroup(c *contextmodel.ReqContext, folder string, group string) response.Response {
|
func (srv *ProvisioningSrv) RouteGetAlertRuleGroup(c *contextmodel.ReqContext, folder string, group string) response.Response {
|
||||||
g, err := srv.alertRules.GetRuleGroup(c.Req.Context(), c.SignedInUser.GetOrgID(), folder, group)
|
g, err := srv.alertRules.GetRuleGroup(c.Req.Context(), c.SignedInUser, folder, group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.ErrOrFallback(http.StatusInternalServerError, "", err)
|
return response.ErrOrFallback(http.StatusInternalServerError, "", err)
|
||||||
}
|
}
|
||||||
@@ -422,7 +422,7 @@ func (srv *ProvisioningSrv) RouteGetAlertRulesExport(c *contextmodel.ReqContext)
|
|||||||
return srv.RouteGetAlertRuleGroupExport(c, folderUIDs[0], group)
|
return srv.RouteGetAlertRuleGroupExport(c, folderUIDs[0], group)
|
||||||
}
|
}
|
||||||
|
|
||||||
groupsWithTitle, err := srv.alertRules.GetAlertGroupsWithFolderTitle(c.Req.Context(), c.SignedInUser.GetOrgID(), folderUIDs)
|
groupsWithTitle, err := srv.alertRules.GetAlertGroupsWithFolderTitle(c.Req.Context(), c.SignedInUser, folderUIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrResp(http.StatusInternalServerError, err, "failed to get alert rules")
|
return ErrResp(http.StatusInternalServerError, err, "failed to get alert rules")
|
||||||
}
|
}
|
||||||
@@ -440,7 +440,7 @@ func (srv *ProvisioningSrv) RouteGetAlertRulesExport(c *contextmodel.ReqContext)
|
|||||||
|
|
||||||
// RouteGetAlertRuleGroupExport retrieves the given alert rule group in a format compatible with file provisioning.
|
// RouteGetAlertRuleGroupExport retrieves the given alert rule group in a format compatible with file provisioning.
|
||||||
func (srv *ProvisioningSrv) RouteGetAlertRuleGroupExport(c *contextmodel.ReqContext, folder string, group string) response.Response {
|
func (srv *ProvisioningSrv) RouteGetAlertRuleGroupExport(c *contextmodel.ReqContext, folder string, group string) response.Response {
|
||||||
g, err := srv.alertRules.GetAlertRuleGroupWithFolderTitle(c.Req.Context(), c.SignedInUser.GetOrgID(), folder, group)
|
g, err := srv.alertRules.GetAlertRuleGroupWithFolderTitle(c.Req.Context(), c.SignedInUser, folder, group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.ErrOrFallback(http.StatusInternalServerError, "failed to get alert rule group", err)
|
return response.ErrOrFallback(http.StatusInternalServerError, "failed to get alert rule group", err)
|
||||||
}
|
}
|
||||||
@@ -455,7 +455,7 @@ func (srv *ProvisioningSrv) RouteGetAlertRuleGroupExport(c *contextmodel.ReqCont
|
|||||||
|
|
||||||
// RouteGetAlertRuleExport retrieves the given alert rule in a format compatible with file provisioning.
|
// RouteGetAlertRuleExport retrieves the given alert rule in a format compatible with file provisioning.
|
||||||
func (srv *ProvisioningSrv) RouteGetAlertRuleExport(c *contextmodel.ReqContext, UID string) response.Response {
|
func (srv *ProvisioningSrv) RouteGetAlertRuleExport(c *contextmodel.ReqContext, UID string) response.Response {
|
||||||
rule, err := srv.alertRules.GetAlertRuleWithFolderTitle(c.Req.Context(), c.SignedInUser.GetOrgID(), UID)
|
rule, err := srv.alertRules.GetAlertRuleWithFolderTitle(c.Req.Context(), c.SignedInUser, UID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, alerting_models.ErrAlertRuleNotFound) {
|
if errors.Is(err, alerting_models.ErrAlertRuleNotFound) {
|
||||||
return ErrResp(http.StatusNotFound, err, "")
|
return ErrResp(http.StatusNotFound, err, "")
|
||||||
@@ -481,9 +481,7 @@ func (srv *ProvisioningSrv) RoutePutAlertRuleGroup(c *contextmodel.ReqContext, a
|
|||||||
ErrResp(http.StatusBadRequest, err, "")
|
ErrResp(http.StatusBadRequest, err, "")
|
||||||
}
|
}
|
||||||
provenance := determineProvenance(c)
|
provenance := determineProvenance(c)
|
||||||
|
err = srv.alertRules.ReplaceRuleGroup(c.Req.Context(), c.SignedInUser, groupModel, alerting_models.Provenance(provenance))
|
||||||
userID, _ := identity.UserIdentifier(c.SignedInUser.GetNamespacedID())
|
|
||||||
err = srv.alertRules.ReplaceRuleGroup(c.Req.Context(), c.SignedInUser.GetOrgID(), groupModel, userID, alerting_models.Provenance(provenance))
|
|
||||||
if errors.Is(err, alerting_models.ErrAlertRuleUniqueConstraintViolation) {
|
if errors.Is(err, alerting_models.ErrAlertRuleUniqueConstraintViolation) {
|
||||||
return ErrResp(http.StatusBadRequest, err, "")
|
return ErrResp(http.StatusBadRequest, err, "")
|
||||||
}
|
}
|
||||||
@@ -501,7 +499,7 @@ func (srv *ProvisioningSrv) RoutePutAlertRuleGroup(c *contextmodel.ReqContext, a
|
|||||||
|
|
||||||
func (srv *ProvisioningSrv) RouteDeleteAlertRuleGroup(c *contextmodel.ReqContext, folderUID string, group string) response.Response {
|
func (srv *ProvisioningSrv) RouteDeleteAlertRuleGroup(c *contextmodel.ReqContext, folderUID string, group string) response.Response {
|
||||||
provenance := determineProvenance(c)
|
provenance := determineProvenance(c)
|
||||||
err := srv.alertRules.DeleteRuleGroup(c.Req.Context(), c.SignedInUser.GetOrgID(), folderUID, group, alerting_models.Provenance(provenance))
|
err := srv.alertRules.DeleteRuleGroup(c.Req.Context(), c.SignedInUser, folderUID, group, alerting_models.Provenance(provenance))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.ErrOrFallback(http.StatusInternalServerError, "", err)
|
return response.ErrOrFallback(http.StatusInternalServerError, "", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ func NewAlertRuleService(ruleStore RuleStore,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *AlertRuleService) GetAlertRules(ctx context.Context, orgID int64) ([]*models.AlertRule, map[string]models.Provenance, error) {
|
func (service *AlertRuleService) GetAlertRules(ctx context.Context, user identity.Requester) ([]*models.AlertRule, map[string]models.Provenance, error) {
|
||||||
q := models.ListAlertRulesQuery{
|
q := models.ListAlertRulesQuery{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
}
|
}
|
||||||
rules, err := service.ruleStore.ListAlertRules(ctx, &q)
|
rules, err := service.ruleStore.ListAlertRules(ctx, &q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -73,7 +73,7 @@ func (service *AlertRuleService) GetAlertRules(ctx context.Context, orgID int64)
|
|||||||
provenances := make(map[string]models.Provenance)
|
provenances := make(map[string]models.Provenance)
|
||||||
if len(rules) > 0 {
|
if len(rules) > 0 {
|
||||||
resourceType := rules[0].ResourceType()
|
resourceType := rules[0].ResourceType()
|
||||||
provenances, err = service.provenanceStore.GetProvenances(ctx, orgID, resourceType)
|
provenances, err = service.provenanceStore.GetProvenances(ctx, user.GetOrgID(), resourceType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -81,16 +81,16 @@ func (service *AlertRuleService) GetAlertRules(ctx context.Context, orgID int64)
|
|||||||
return rules, provenances, nil
|
return rules, provenances, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *AlertRuleService) GetAlertRule(ctx context.Context, orgID int64, ruleUID string) (models.AlertRule, models.Provenance, error) {
|
func (service *AlertRuleService) GetAlertRule(ctx context.Context, user identity.Requester, ruleUID string) (models.AlertRule, models.Provenance, error) {
|
||||||
query := &models.GetAlertRuleByUIDQuery{
|
query := &models.GetAlertRuleByUIDQuery{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
UID: ruleUID,
|
UID: ruleUID,
|
||||||
}
|
}
|
||||||
rule, err := service.ruleStore.GetAlertRuleByUID(ctx, query)
|
rule, err := service.ruleStore.GetAlertRuleByUID(ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return models.AlertRule{}, models.ProvenanceNone, err
|
return models.AlertRule{}, models.ProvenanceNone, err
|
||||||
}
|
}
|
||||||
provenance, err := service.provenanceStore.GetProvenance(ctx, rule, orgID)
|
provenance, err := service.provenanceStore.GetProvenance(ctx, rule, user.GetOrgID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return models.AlertRule{}, models.ProvenanceNone, err
|
return models.AlertRule{}, models.ProvenanceNone, err
|
||||||
}
|
}
|
||||||
@@ -103,9 +103,9 @@ type AlertRuleWithFolderTitle struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAlertRuleWithFolderTitle returns a single alert rule with its folder title.
|
// GetAlertRuleWithFolderTitle returns a single alert rule with its folder title.
|
||||||
func (service *AlertRuleService) GetAlertRuleWithFolderTitle(ctx context.Context, orgID int64, ruleUID string) (AlertRuleWithFolderTitle, error) {
|
func (service *AlertRuleService) GetAlertRuleWithFolderTitle(ctx context.Context, user identity.Requester, ruleUID string) (AlertRuleWithFolderTitle, error) {
|
||||||
query := &models.GetAlertRuleByUIDQuery{
|
query := &models.GetAlertRuleByUIDQuery{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
UID: ruleUID,
|
UID: ruleUID,
|
||||||
}
|
}
|
||||||
rule, err := service.ruleStore.GetAlertRuleByUID(ctx, query)
|
rule, err := service.ruleStore.GetAlertRuleByUID(ctx, query)
|
||||||
@@ -114,7 +114,7 @@ func (service *AlertRuleService) GetAlertRuleWithFolderTitle(ctx context.Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
dq := dashboards.GetDashboardQuery{
|
dq := dashboards.GetDashboardQuery{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
UID: rule.NamespaceUID,
|
UID: rule.NamespaceUID,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,12 +184,7 @@ func (service *AlertRuleService) CreateAlertRule(ctx context.Context, user ident
|
|||||||
return errors.New("couldn't find newly created id")
|
return errors.New("couldn't find newly created id")
|
||||||
}
|
}
|
||||||
|
|
||||||
// default to 0 if there is no user
|
if err = service.checkLimitsTransactionCtx(ctx, user); err != nil {
|
||||||
userID := int64(0)
|
|
||||||
if user != nil {
|
|
||||||
userID, _ = identity.UserIdentifier(user.GetNamespacedID())
|
|
||||||
}
|
|
||||||
if err = service.checkLimitsTransactionCtx(ctx, rule.OrgID, userID); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,9 +196,9 @@ func (service *AlertRuleService) CreateAlertRule(ctx context.Context, user ident
|
|||||||
return rule, nil
|
return rule, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *AlertRuleService) GetRuleGroup(ctx context.Context, orgID int64, namespaceUID, group string) (models.AlertRuleGroup, error) {
|
func (service *AlertRuleService) GetRuleGroup(ctx context.Context, user identity.Requester, namespaceUID, group string) (models.AlertRuleGroup, error) {
|
||||||
q := models.ListAlertRulesQuery{
|
q := models.ListAlertRulesQuery{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
NamespaceUIDs: []string{namespaceUID},
|
NamespaceUIDs: []string{namespaceUID},
|
||||||
RuleGroup: group,
|
RuleGroup: group,
|
||||||
}
|
}
|
||||||
@@ -229,13 +224,13 @@ func (service *AlertRuleService) GetRuleGroup(ctx context.Context, orgID int64,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateRuleGroup will update the interval for all rules in the group.
|
// UpdateRuleGroup will update the interval for all rules in the group.
|
||||||
func (service *AlertRuleService) UpdateRuleGroup(ctx context.Context, orgID int64, namespaceUID string, ruleGroup string, intervalSeconds int64) error {
|
func (service *AlertRuleService) UpdateRuleGroup(ctx context.Context, user identity.Requester, namespaceUID string, ruleGroup string, intervalSeconds int64) error {
|
||||||
if err := models.ValidateRuleGroupInterval(intervalSeconds, service.baseIntervalSeconds); err != nil {
|
if err := models.ValidateRuleGroupInterval(intervalSeconds, service.baseIntervalSeconds); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return service.xact.InTransaction(ctx, func(ctx context.Context) error {
|
return service.xact.InTransaction(ctx, func(ctx context.Context) error {
|
||||||
query := &models.ListAlertRulesQuery{
|
query := &models.ListAlertRulesQuery{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
NamespaceUIDs: []string{namespaceUID},
|
NamespaceUIDs: []string{namespaceUID},
|
||||||
RuleGroup: ruleGroup,
|
RuleGroup: ruleGroup,
|
||||||
}
|
}
|
||||||
@@ -259,12 +254,12 @@ func (service *AlertRuleService) UpdateRuleGroup(ctx context.Context, orgID int6
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *AlertRuleService) ReplaceRuleGroup(ctx context.Context, orgID int64, group models.AlertRuleGroup, userID int64, provenance models.Provenance) error {
|
func (service *AlertRuleService) ReplaceRuleGroup(ctx context.Context, user identity.Requester, group models.AlertRuleGroup, provenance models.Provenance) error {
|
||||||
if err := models.ValidateRuleGroupInterval(group.Interval, service.baseIntervalSeconds); err != nil {
|
if err := models.ValidateRuleGroupInterval(group.Interval, service.baseIntervalSeconds); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
delta, err := service.calcDelta(ctx, orgID, group)
|
delta, err := service.calcDelta(ctx, user, group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -286,13 +281,13 @@ func (service *AlertRuleService) ReplaceRuleGroup(ctx context.Context, orgID int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return service.persistDelta(ctx, orgID, delta, userID, provenance)
|
return service.persistDelta(ctx, user, delta, provenance)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *AlertRuleService) DeleteRuleGroup(ctx context.Context, orgID int64, namespaceUID, group string, provenance models.Provenance) error {
|
func (service *AlertRuleService) DeleteRuleGroup(ctx context.Context, user identity.Requester, namespaceUID, group string, provenance models.Provenance) error {
|
||||||
// List all rules in the group.
|
// List all rules in the group.
|
||||||
q := models.ListAlertRulesQuery{
|
q := models.ListAlertRulesQuery{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
NamespaceUIDs: []string{namespaceUID},
|
NamespaceUIDs: []string{namespaceUID},
|
||||||
RuleGroup: group,
|
RuleGroup: group,
|
||||||
}
|
}
|
||||||
@@ -317,16 +312,16 @@ func (service *AlertRuleService) DeleteRuleGroup(ctx context.Context, orgID int6
|
|||||||
|
|
||||||
// Delete all rules.
|
// Delete all rules.
|
||||||
return service.xact.InTransaction(ctx, func(ctx context.Context) error {
|
return service.xact.InTransaction(ctx, func(ctx context.Context) error {
|
||||||
return service.deleteRules(ctx, orgID, ruleList...)
|
return service.deleteRules(ctx, user.GetOrgID(), ruleList...)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *AlertRuleService) calcDelta(ctx context.Context, orgID int64, group models.AlertRuleGroup) (*store.GroupDelta, error) {
|
func (service *AlertRuleService) calcDelta(ctx context.Context, user identity.Requester, group models.AlertRuleGroup) (*store.GroupDelta, error) {
|
||||||
// If the provided request did not provide the rules list at all, treat it as though it does not wish to change rules.
|
// If the provided request did not provide the rules list at all, treat it as though it does not wish to change rules.
|
||||||
// This is done for backwards compatibility. Requests which specify only the interval must update only the interval.
|
// This is done for backwards compatibility. Requests which specify only the interval must update only the interval.
|
||||||
if group.Rules == nil {
|
if group.Rules == nil {
|
||||||
listRulesQuery := models.ListAlertRulesQuery{
|
listRulesQuery := models.ListAlertRulesQuery{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
NamespaceUIDs: []string{group.FolderUID},
|
NamespaceUIDs: []string{group.FolderUID},
|
||||||
RuleGroup: group.Title,
|
RuleGroup: group.Title,
|
||||||
}
|
}
|
||||||
@@ -347,12 +342,12 @@ func (service *AlertRuleService) calcDelta(ctx context.Context, orgID int64, gro
|
|||||||
}
|
}
|
||||||
|
|
||||||
key := models.AlertRuleGroupKey{
|
key := models.AlertRuleGroupKey{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
NamespaceUID: group.FolderUID,
|
NamespaceUID: group.FolderUID,
|
||||||
RuleGroup: group.Title,
|
RuleGroup: group.Title,
|
||||||
}
|
}
|
||||||
rules := make([]*models.AlertRuleWithOptionals, len(group.Rules))
|
rules := make([]*models.AlertRuleWithOptionals, len(group.Rules))
|
||||||
group = *syncGroupRuleFields(&group, orgID)
|
group = *syncGroupRuleFields(&group, user.GetOrgID())
|
||||||
for i := range group.Rules {
|
for i := range group.Rules {
|
||||||
if err := group.Rules[i].SetDashboardAndPanelFromAnnotations(); err != nil {
|
if err := group.Rules[i].SetDashboardAndPanelFromAnnotations(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -368,13 +363,13 @@ func (service *AlertRuleService) calcDelta(ctx context.Context, orgID int64, gro
|
|||||||
return store.UpdateCalculatedRuleFields(delta), nil
|
return store.UpdateCalculatedRuleFields(delta), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *AlertRuleService) persistDelta(ctx context.Context, orgID int64, delta *store.GroupDelta, userID int64, provenance models.Provenance) error {
|
func (service *AlertRuleService) persistDelta(ctx context.Context, user identity.Requester, delta *store.GroupDelta, provenance models.Provenance) error {
|
||||||
return service.xact.InTransaction(ctx, func(ctx context.Context) error {
|
return service.xact.InTransaction(ctx, func(ctx context.Context) error {
|
||||||
// Delete first as this could prevent future unique constraint violations.
|
// Delete first as this could prevent future unique constraint violations.
|
||||||
if len(delta.Delete) > 0 {
|
if len(delta.Delete) > 0 {
|
||||||
for _, del := range delta.Delete {
|
for _, del := range delta.Delete {
|
||||||
// check that provenance is not changed in an invalid way
|
// check that provenance is not changed in an invalid way
|
||||||
storedProvenance, err := service.provenanceStore.GetProvenance(ctx, del, orgID)
|
storedProvenance, err := service.provenanceStore.GetProvenance(ctx, del, user.GetOrgID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -382,7 +377,7 @@ func (service *AlertRuleService) persistDelta(ctx context.Context, orgID int64,
|
|||||||
return fmt.Errorf("cannot update with provided provenance '%s', needs '%s'", provenance, storedProvenance)
|
return fmt.Errorf("cannot update with provided provenance '%s', needs '%s'", provenance, storedProvenance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := service.deleteRules(ctx, orgID, delta.Delete...); err != nil {
|
if err := service.deleteRules(ctx, user.GetOrgID(), delta.Delete...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,7 +386,7 @@ func (service *AlertRuleService) persistDelta(ctx context.Context, orgID int64,
|
|||||||
updates := make([]models.UpdateRule, 0, len(delta.Update))
|
updates := make([]models.UpdateRule, 0, len(delta.Update))
|
||||||
for _, update := range delta.Update {
|
for _, update := range delta.Update {
|
||||||
// check that provenance is not changed in an invalid way
|
// check that provenance is not changed in an invalid way
|
||||||
storedProvenance, err := service.provenanceStore.GetProvenance(ctx, update.New, orgID)
|
storedProvenance, err := service.provenanceStore.GetProvenance(ctx, update.New, user.GetOrgID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -407,7 +402,7 @@ func (service *AlertRuleService) persistDelta(ctx context.Context, orgID int64,
|
|||||||
return fmt.Errorf("failed to update alert rules: %w", err)
|
return fmt.Errorf("failed to update alert rules: %w", err)
|
||||||
}
|
}
|
||||||
for _, update := range delta.Update {
|
for _, update := range delta.Update {
|
||||||
if err := service.provenanceStore.SetProvenance(ctx, update.New, orgID, provenance); err != nil {
|
if err := service.provenanceStore.SetProvenance(ctx, update.New, user.GetOrgID(), provenance); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -419,13 +414,13 @@ func (service *AlertRuleService) persistDelta(ctx context.Context, orgID int64,
|
|||||||
return fmt.Errorf("failed to insert alert rules: %w", err)
|
return fmt.Errorf("failed to insert alert rules: %w", err)
|
||||||
}
|
}
|
||||||
for _, key := range uids {
|
for _, key := range uids {
|
||||||
if err := service.provenanceStore.SetProvenance(ctx, &models.AlertRule{UID: key.UID}, orgID, provenance); err != nil {
|
if err := service.provenanceStore.SetProvenance(ctx, &models.AlertRule{UID: key.UID}, user.GetOrgID(), provenance); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := service.checkLimitsTransactionCtx(ctx, orgID, userID); err != nil {
|
if err := service.checkLimitsTransactionCtx(ctx, user); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,8 +429,8 @@ func (service *AlertRuleService) persistDelta(ctx context.Context, orgID int64,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateAlertRule updates an alert rule.
|
// UpdateAlertRule updates an alert rule.
|
||||||
func (service *AlertRuleService) UpdateAlertRule(ctx context.Context, rule models.AlertRule, provenance models.Provenance) (models.AlertRule, error) {
|
func (service *AlertRuleService) UpdateAlertRule(ctx context.Context, user identity.Requester, rule models.AlertRule, provenance models.Provenance) (models.AlertRule, error) {
|
||||||
storedRule, storedProvenance, err := service.GetAlertRule(ctx, rule.OrgID, rule.UID)
|
storedRule, storedProvenance, err := service.GetAlertRule(ctx, user, rule.UID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return models.AlertRule{}, err
|
return models.AlertRule{}, err
|
||||||
}
|
}
|
||||||
@@ -478,9 +473,9 @@ func (service *AlertRuleService) UpdateAlertRule(ctx context.Context, rule model
|
|||||||
return rule, err
|
return rule, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *AlertRuleService) DeleteAlertRule(ctx context.Context, orgID int64, ruleUID string, provenance models.Provenance) error {
|
func (service *AlertRuleService) DeleteAlertRule(ctx context.Context, user identity.Requester, ruleUID string, provenance models.Provenance) error {
|
||||||
rule := &models.AlertRule{
|
rule := &models.AlertRule{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
UID: ruleUID,
|
UID: ruleUID,
|
||||||
}
|
}
|
||||||
// check that provenance is not changed in an invalid way
|
// check that provenance is not changed in an invalid way
|
||||||
@@ -492,14 +487,22 @@ func (service *AlertRuleService) DeleteAlertRule(ctx context.Context, orgID int6
|
|||||||
return fmt.Errorf("cannot delete with provided provenance '%s', needs '%s'", provenance, storedProvenance)
|
return fmt.Errorf("cannot delete with provided provenance '%s', needs '%s'", provenance, storedProvenance)
|
||||||
}
|
}
|
||||||
return service.xact.InTransaction(ctx, func(ctx context.Context) error {
|
return service.xact.InTransaction(ctx, func(ctx context.Context) error {
|
||||||
return service.deleteRules(ctx, orgID, rule)
|
return service.deleteRules(ctx, user.GetOrgID(), rule)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkLimitsTransactionCtx checks whether the current transaction (as identified by the ctx) breaches configured alert rule limits.
|
// checkLimitsTransactionCtx checks whether the current transaction (as identified by the ctx) breaches configured alert rule limits.
|
||||||
func (service *AlertRuleService) checkLimitsTransactionCtx(ctx context.Context, orgID, userID int64) error {
|
func (service *AlertRuleService) checkLimitsTransactionCtx(ctx context.Context, user identity.Requester) error {
|
||||||
|
// default to 0 if there is no user
|
||||||
|
userID := int64(0)
|
||||||
|
u, err := identity.UserIdentifier(user.GetNamespacedID())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to check alert rule quota: %w", err)
|
||||||
|
}
|
||||||
|
userID = u
|
||||||
|
|
||||||
limitReached, err := service.quotas.CheckQuotaReached(ctx, models.QuotaTargetSrv, "a.ScopeParameters{
|
limitReached, err := service.quotas.CheckQuotaReached(ctx, models.QuotaTargetSrv, "a.ScopeParameters{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -532,9 +535,9 @@ func (service *AlertRuleService) deleteRules(ctx context.Context, orgID int64, t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAlertRuleGroupWithFolderTitle returns the alert rule group with folder title.
|
// GetAlertRuleGroupWithFolderTitle returns the alert rule group with folder title.
|
||||||
func (service *AlertRuleService) GetAlertRuleGroupWithFolderTitle(ctx context.Context, orgID int64, namespaceUID, group string) (models.AlertRuleGroupWithFolderTitle, error) {
|
func (service *AlertRuleService) GetAlertRuleGroupWithFolderTitle(ctx context.Context, user identity.Requester, namespaceUID, group string) (models.AlertRuleGroupWithFolderTitle, error) {
|
||||||
q := models.ListAlertRulesQuery{
|
q := models.ListAlertRulesQuery{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
NamespaceUIDs: []string{namespaceUID},
|
NamespaceUIDs: []string{namespaceUID},
|
||||||
RuleGroup: group,
|
RuleGroup: group,
|
||||||
}
|
}
|
||||||
@@ -547,7 +550,7 @@ func (service *AlertRuleService) GetAlertRuleGroupWithFolderTitle(ctx context.Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
dq := dashboards.GetDashboardQuery{
|
dq := dashboards.GetDashboardQuery{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
UID: namespaceUID,
|
UID: namespaceUID,
|
||||||
}
|
}
|
||||||
dash, err := service.dashboardService.GetDashboard(ctx, &dq)
|
dash, err := service.dashboardService.GetDashboard(ctx, &dq)
|
||||||
@@ -560,9 +563,9 @@ func (service *AlertRuleService) GetAlertRuleGroupWithFolderTitle(ctx context.Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAlertGroupsWithFolderTitle returns all groups with folder title in the folders identified by folderUID that have at least one alert. If argument folderUIDs is nil or empty - returns groups in all folders.
|
// GetAlertGroupsWithFolderTitle returns all groups with folder title in the folders identified by folderUID that have at least one alert. If argument folderUIDs is nil or empty - returns groups in all folders.
|
||||||
func (service *AlertRuleService) GetAlertGroupsWithFolderTitle(ctx context.Context, orgID int64, folderUIDs []string) ([]models.AlertRuleGroupWithFolderTitle, error) {
|
func (service *AlertRuleService) GetAlertGroupsWithFolderTitle(ctx context.Context, user identity.Requester, folderUIDs []string) ([]models.AlertRuleGroupWithFolderTitle, error) {
|
||||||
q := models.ListAlertRulesQuery{
|
q := models.ListAlertRulesQuery{
|
||||||
OrgID: orgID,
|
OrgID: user.GetOrgID(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(folderUIDs) > 0 {
|
if len(folderUIDs) > 0 {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/expr"
|
"github.com/grafana/grafana/pkg/expr"
|
||||||
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/db"
|
"github.com/grafana/grafana/pkg/infra/db"
|
||||||
@@ -25,17 +26,21 @@ import (
|
|||||||
func TestAlertRuleService(t *testing.T) {
|
func TestAlertRuleService(t *testing.T) {
|
||||||
ruleService := createAlertRuleService(t)
|
ruleService := createAlertRuleService(t)
|
||||||
var orgID int64 = 1
|
var orgID int64 = 1
|
||||||
|
u := &user.SignedInUser{
|
||||||
|
UserID: 1,
|
||||||
|
OrgID: orgID,
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("group creation should set the right provenance", func(t *testing.T) {
|
t.Run("group creation should set the right provenance", func(t *testing.T) {
|
||||||
group := createDummyGroup("group-test-1", orgID)
|
group := createDummyGroup("group-test-1", orgID)
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), orgID, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
readGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "group-test-1")
|
readGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "group-test-1")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, readGroup.Rules)
|
require.NotEmpty(t, readGroup.Rules)
|
||||||
for _, rule := range readGroup.Rules {
|
for _, rule := range readGroup.Rules {
|
||||||
_, provenance, err := ruleService.GetAlertRule(context.Background(), orgID, rule.UID)
|
_, provenance, err := ruleService.GetAlertRule(context.Background(), u, rule.UID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, models.ProvenanceAPI, provenance)
|
require.Equal(t, models.ProvenanceAPI, provenance)
|
||||||
}
|
}
|
||||||
@@ -44,15 +49,15 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
t.Run("alert rule group should be updated correctly", func(t *testing.T) {
|
t.Run("alert rule group should be updated correctly", func(t *testing.T) {
|
||||||
rule := dummyRule("test#3", orgID)
|
rule := dummyRule("test#3", orgID)
|
||||||
rule.RuleGroup = "a"
|
rule.RuleGroup = "a"
|
||||||
rule, err := ruleService.CreateAlertRule(context.Background(), nil, rule, models.ProvenanceNone)
|
rule, err := ruleService.CreateAlertRule(context.Background(), u, rule, models.ProvenanceNone)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int64(60), rule.IntervalSeconds)
|
require.Equal(t, int64(60), rule.IntervalSeconds)
|
||||||
|
|
||||||
var interval int64 = 120
|
var interval int64 = 120
|
||||||
err = ruleService.UpdateRuleGroup(context.Background(), orgID, rule.NamespaceUID, rule.RuleGroup, 120)
|
err = ruleService.UpdateRuleGroup(context.Background(), u, rule.NamespaceUID, rule.RuleGroup, 120)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
rule, _, err = ruleService.GetAlertRule(context.Background(), orgID, rule.UID)
|
rule, _, err = ruleService.GetAlertRule(context.Background(), u, rule.UID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, interval, rule.IntervalSeconds)
|
require.Equal(t, interval, rule.IntervalSeconds)
|
||||||
})
|
})
|
||||||
@@ -61,24 +66,24 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
var orgID int64 = 2
|
var orgID int64 = 2
|
||||||
rule := dummyRule("test#1", orgID)
|
rule := dummyRule("test#1", orgID)
|
||||||
rule.NamespaceUID = "123abc"
|
rule.NamespaceUID = "123abc"
|
||||||
rule, err := ruleService.CreateAlertRule(context.Background(), nil, rule, models.ProvenanceNone)
|
u := &user.SignedInUser{OrgID: orgID}
|
||||||
|
rule, err := ruleService.CreateAlertRule(context.Background(), u, rule, models.ProvenanceNone)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
rule.NamespaceUID = "abc123"
|
rule.NamespaceUID = "abc123"
|
||||||
_, err = ruleService.UpdateAlertRule(context.Background(),
|
_, err = ruleService.UpdateAlertRule(context.Background(), u, rule, models.ProvenanceNone)
|
||||||
rule, models.ProvenanceNone)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("group update should propagate folderUID from group to rules", func(t *testing.T) {
|
t.Run("group update should propagate folderUID from group to rules", func(t *testing.T) {
|
||||||
ruleService := createAlertRuleService(t)
|
ruleService := createAlertRuleService(t)
|
||||||
group := createDummyGroup("namespace-test", 1)
|
group := createDummyGroup("namespace-test", orgID)
|
||||||
group.Rules[0].NamespaceUID = ""
|
group.Rules[0].NamespaceUID = ""
|
||||||
|
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), 1, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
readGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "namespace-test")
|
readGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "namespace-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, readGroup.Rules)
|
require.NotEmpty(t, readGroup.Rules)
|
||||||
require.Equal(t, "my-namespace", readGroup.Rules[0].NamespaceUID)
|
require.Equal(t, "my-namespace", readGroup.Rules[0].NamespaceUID)
|
||||||
@@ -88,10 +93,10 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
group := createDummyGroup("group-test-3", orgID)
|
group := createDummyGroup("group-test-3", orgID)
|
||||||
group.Rules[0].RuleGroup = "something different"
|
group.Rules[0].RuleGroup = "something different"
|
||||||
|
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), orgID, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
readGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "group-test-3")
|
readGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "group-test-3")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, readGroup.Rules)
|
require.NotEmpty(t, readGroup.Rules)
|
||||||
for _, rule := range readGroup.Rules {
|
for _, rule := range readGroup.Rules {
|
||||||
@@ -102,16 +107,16 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
t.Run("alert rule should get interval from existing rule group", func(t *testing.T) {
|
t.Run("alert rule should get interval from existing rule group", func(t *testing.T) {
|
||||||
rule := dummyRule("test#4", orgID)
|
rule := dummyRule("test#4", orgID)
|
||||||
rule.RuleGroup = "b"
|
rule.RuleGroup = "b"
|
||||||
rule, err := ruleService.CreateAlertRule(context.Background(), nil, rule, models.ProvenanceNone)
|
rule, err := ruleService.CreateAlertRule(context.Background(), u, rule, models.ProvenanceNone)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var interval int64 = 120
|
var interval int64 = 120
|
||||||
err = ruleService.UpdateRuleGroup(context.Background(), orgID, rule.NamespaceUID, rule.RuleGroup, 120)
|
err = ruleService.UpdateRuleGroup(context.Background(), u, rule.NamespaceUID, rule.RuleGroup, 120)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
rule = dummyRule("test#4-1", orgID)
|
rule = dummyRule("test#4-1", orgID)
|
||||||
rule.RuleGroup = "b"
|
rule.RuleGroup = "b"
|
||||||
rule, err = ruleService.CreateAlertRule(context.Background(), nil, rule, models.ProvenanceNone)
|
rule, err = ruleService.CreateAlertRule(context.Background(), u, rule, models.ProvenanceNone)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, interval, rule.IntervalSeconds)
|
require.Equal(t, interval, rule.IntervalSeconds)
|
||||||
})
|
})
|
||||||
@@ -124,22 +129,23 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
ruleGroup = "abc"
|
ruleGroup = "abc"
|
||||||
newInterval int64 = 120
|
newInterval int64 = 120
|
||||||
)
|
)
|
||||||
|
u := &user.SignedInUser{OrgID: orgID}
|
||||||
rule := dummyRule("my_rule", orgID)
|
rule := dummyRule("my_rule", orgID)
|
||||||
rule.UID = ruleUID
|
rule.UID = ruleUID
|
||||||
rule.RuleGroup = ruleGroup
|
rule.RuleGroup = ruleGroup
|
||||||
rule.NamespaceUID = namespaceUID
|
rule.NamespaceUID = namespaceUID
|
||||||
_, err := ruleService.CreateAlertRule(context.Background(), nil, rule, models.ProvenanceNone)
|
_, err := ruleService.CreateAlertRule(context.Background(), u, rule, models.ProvenanceNone)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
rule, _, err = ruleService.GetAlertRule(context.Background(), orgID, ruleUID)
|
rule, _, err = ruleService.GetAlertRule(context.Background(), u, ruleUID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int64(1), rule.Version)
|
require.Equal(t, int64(1), rule.Version)
|
||||||
require.Equal(t, int64(60), rule.IntervalSeconds)
|
require.Equal(t, int64(60), rule.IntervalSeconds)
|
||||||
|
|
||||||
err = ruleService.UpdateRuleGroup(context.Background(), orgID, namespaceUID, ruleGroup, newInterval)
|
err = ruleService.UpdateRuleGroup(context.Background(), u, namespaceUID, ruleGroup, newInterval)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
rule, _, err = ruleService.GetAlertRule(context.Background(), orgID, ruleUID)
|
rule, _, err = ruleService.GetAlertRule(context.Background(), u, ruleUID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int64(2), rule.Version)
|
require.Equal(t, int64(2), rule.Version)
|
||||||
require.Equal(t, newInterval, rule.IntervalSeconds)
|
require.Equal(t, newInterval, rule.IntervalSeconds)
|
||||||
@@ -147,16 +153,16 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("updating a group by updating a rule should bump that rule's data and version number", func(t *testing.T) {
|
t.Run("updating a group by updating a rule should bump that rule's data and version number", func(t *testing.T) {
|
||||||
group := createDummyGroup("group-test-5", orgID)
|
group := createDummyGroup("group-test-5", orgID)
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), orgID, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "group-test-5")
|
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "group-test-5")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
updatedGroup.Rules[0].Title = "some-other-title-asdf"
|
updatedGroup.Rules[0].Title = "some-other-title-asdf"
|
||||||
err = ruleService.ReplaceRuleGroup(context.Background(), orgID, updatedGroup, 0, models.ProvenanceAPI)
|
err = ruleService.ReplaceRuleGroup(context.Background(), u, updatedGroup, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
readGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "group-test-5")
|
readGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "group-test-5")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, readGroup.Rules)
|
require.NotEmpty(t, readGroup.Rules)
|
||||||
require.Len(t, readGroup.Rules, 1)
|
require.Len(t, readGroup.Rules, 1)
|
||||||
@@ -175,17 +181,17 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
dummyRule("overlap-test-rule-2", orgID),
|
dummyRule("overlap-test-rule-2", orgID),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), orgID, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "overlap-test")
|
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "overlap-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
updatedGroup.Rules[0].Title = "overlap-test-rule-2"
|
updatedGroup.Rules[0].Title = "overlap-test-rule-2"
|
||||||
updatedGroup.Rules[1].Title = "overlap-test-rule-3"
|
updatedGroup.Rules[1].Title = "overlap-test-rule-3"
|
||||||
err = ruleService.ReplaceRuleGroup(context.Background(), orgID, updatedGroup, 0, models.ProvenanceAPI)
|
err = ruleService.ReplaceRuleGroup(context.Background(), u, updatedGroup, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
readGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "overlap-test")
|
readGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "overlap-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, readGroup.Rules)
|
require.NotEmpty(t, readGroup.Rules)
|
||||||
require.Len(t, readGroup.Rules, 2)
|
require.Len(t, readGroup.Rules, 2)
|
||||||
@@ -206,17 +212,17 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
dummyRule("swap-test-rule-2", orgID),
|
dummyRule("swap-test-rule-2", orgID),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), orgID, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "swap-test")
|
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "swap-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
updatedGroup.Rules[0].Title = "swap-test-rule-2"
|
updatedGroup.Rules[0].Title = "swap-test-rule-2"
|
||||||
updatedGroup.Rules[1].Title = "swap-test-rule-1"
|
updatedGroup.Rules[1].Title = "swap-test-rule-1"
|
||||||
err = ruleService.ReplaceRuleGroup(context.Background(), orgID, updatedGroup, 0, models.ProvenanceAPI)
|
err = ruleService.ReplaceRuleGroup(context.Background(), u, updatedGroup, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
readGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "swap-test")
|
readGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "swap-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, readGroup.Rules)
|
require.NotEmpty(t, readGroup.Rules)
|
||||||
require.Len(t, readGroup.Rules, 2)
|
require.Len(t, readGroup.Rules, 2)
|
||||||
@@ -238,18 +244,18 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
dummyRule("cycle-test-rule-3", orgID),
|
dummyRule("cycle-test-rule-3", orgID),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), orgID, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "cycle-test")
|
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "cycle-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
updatedGroup.Rules[0].Title = "cycle-test-rule-2"
|
updatedGroup.Rules[0].Title = "cycle-test-rule-2"
|
||||||
updatedGroup.Rules[1].Title = "cycle-test-rule-3"
|
updatedGroup.Rules[1].Title = "cycle-test-rule-3"
|
||||||
updatedGroup.Rules[2].Title = "cycle-test-rule-1"
|
updatedGroup.Rules[2].Title = "cycle-test-rule-1"
|
||||||
err = ruleService.ReplaceRuleGroup(context.Background(), orgID, updatedGroup, 0, models.ProvenanceAPI)
|
err = ruleService.ReplaceRuleGroup(context.Background(), u, updatedGroup, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
readGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "cycle-test")
|
readGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "cycle-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, readGroup.Rules)
|
require.NotEmpty(t, readGroup.Rules)
|
||||||
require.Len(t, readGroup.Rules, 3)
|
require.Len(t, readGroup.Rules, 3)
|
||||||
@@ -276,9 +282,9 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
dummyRule("multi-cycle-test-rule-5", orgID),
|
dummyRule("multi-cycle-test-rule-5", orgID),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), orgID, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "multi-cycle-test")
|
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "multi-cycle-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
updatedGroup.Rules[0].Title = "multi-cycle-test-rule-2"
|
updatedGroup.Rules[0].Title = "multi-cycle-test-rule-2"
|
||||||
@@ -288,10 +294,10 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
updatedGroup.Rules[3].Title = "multi-cycle-test-rule-5"
|
updatedGroup.Rules[3].Title = "multi-cycle-test-rule-5"
|
||||||
updatedGroup.Rules[4].Title = "multi-cycle-test-rule-3"
|
updatedGroup.Rules[4].Title = "multi-cycle-test-rule-3"
|
||||||
|
|
||||||
err = ruleService.ReplaceRuleGroup(context.Background(), orgID, updatedGroup, 0, models.ProvenanceAPI)
|
err = ruleService.ReplaceRuleGroup(context.Background(), u, updatedGroup, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
readGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "multi-cycle-test")
|
readGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "multi-cycle-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, readGroup.Rules)
|
require.NotEmpty(t, readGroup.Rules)
|
||||||
require.Len(t, readGroup.Rules, 5)
|
require.Len(t, readGroup.Rules, 5)
|
||||||
@@ -317,7 +323,7 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
dummyRule("recreate-test-rule-1", orgID),
|
dummyRule("recreate-test-rule-1", orgID),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), orgID, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
updatedGroup := models.AlertRuleGroup{
|
updatedGroup := models.AlertRuleGroup{
|
||||||
Title: "recreate-test",
|
Title: "recreate-test",
|
||||||
@@ -327,10 +333,10 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
dummyRule("recreate-test-rule-1", orgID),
|
dummyRule("recreate-test-rule-1", orgID),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err = ruleService.ReplaceRuleGroup(context.Background(), orgID, updatedGroup, 0, models.ProvenanceAPI)
|
err = ruleService.ReplaceRuleGroup(context.Background(), u, updatedGroup, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
readGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "recreate-test")
|
readGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "recreate-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, readGroup.Rules)
|
require.NotEmpty(t, readGroup.Rules)
|
||||||
require.Len(t, readGroup.Rules, 1)
|
require.Len(t, readGroup.Rules, 1)
|
||||||
@@ -348,17 +354,17 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
dummyRule("create-overlap-test-rule-1", orgID),
|
dummyRule("create-overlap-test-rule-1", orgID),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), orgID, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "create-overlap-test")
|
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "create-overlap-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
updatedGroup.Rules[0].Title = "create-overlap-test-rule-2"
|
updatedGroup.Rules[0].Title = "create-overlap-test-rule-2"
|
||||||
updatedGroup.Rules = append(updatedGroup.Rules, dummyRule("create-overlap-test-rule-1", orgID))
|
updatedGroup.Rules = append(updatedGroup.Rules, dummyRule("create-overlap-test-rule-1", orgID))
|
||||||
|
|
||||||
err = ruleService.ReplaceRuleGroup(context.Background(), orgID, updatedGroup, 0, models.ProvenanceAPI)
|
err = ruleService.ReplaceRuleGroup(context.Background(), u, updatedGroup, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
readGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "create-overlap-test")
|
readGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "create-overlap-test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, readGroup.Rules)
|
require.NotEmpty(t, readGroup.Rules)
|
||||||
require.Len(t, readGroup.Rules, 2)
|
require.Len(t, readGroup.Rules, 2)
|
||||||
@@ -377,9 +383,9 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
models.PanelIDAnnotation: strconv.FormatInt(panelId, 10),
|
models.PanelIDAnnotation: strconv.FormatInt(panelId, 10),
|
||||||
}
|
}
|
||||||
|
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), orgID, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), orgID, "my-namespace", "group-test-5")
|
updatedGroup, err := ruleService.GetRuleGroup(context.Background(), u, "my-namespace", "group-test-5")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.NotNil(t, updatedGroup.Rules[0].DashboardUID)
|
require.NotNil(t, updatedGroup.Rules[0].DashboardUID)
|
||||||
@@ -434,12 +440,11 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
var orgID int64 = 1
|
|
||||||
rule := dummyRule(t.Name(), orgID)
|
rule := dummyRule(t.Name(), orgID)
|
||||||
rule, err := ruleService.CreateAlertRule(context.Background(), nil, rule, test.from)
|
rule, err := ruleService.CreateAlertRule(context.Background(), u, rule, test.from)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, err = ruleService.UpdateAlertRule(context.Background(), rule, test.to)
|
_, err = ruleService.UpdateAlertRule(context.Background(), u, rule, test.to)
|
||||||
if test.errNil {
|
if test.errNil {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
} else {
|
} else {
|
||||||
@@ -497,11 +502,11 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
var orgID int64 = 1
|
var orgID int64 = 1
|
||||||
group := createDummyGroup(t.Name(), orgID)
|
group := createDummyGroup(t.Name(), orgID)
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), 1, group, 0, test.from)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, test.from)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
group.Rules[0].Title = t.Name()
|
group.Rules[0].Title = t.Name()
|
||||||
err = ruleService.ReplaceRuleGroup(context.Background(), 1, group, 0, test.to)
|
err = ruleService.ReplaceRuleGroup(context.Background(), u, group, test.to)
|
||||||
if test.errNil {
|
if test.errNil {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
} else {
|
} else {
|
||||||
@@ -517,7 +522,7 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
checker.EXPECT().LimitExceeded()
|
checker.EXPECT().LimitExceeded()
|
||||||
ruleService.quotas = checker
|
ruleService.quotas = checker
|
||||||
|
|
||||||
_, err := ruleService.CreateAlertRule(context.Background(), nil, dummyRule("test#1", orgID), models.ProvenanceNone)
|
_, err := ruleService.CreateAlertRule(context.Background(), u, dummyRule("test#1", orgID), models.ProvenanceNone)
|
||||||
|
|
||||||
require.ErrorIs(t, err, models.ErrQuotaReached)
|
require.ErrorIs(t, err, models.ErrQuotaReached)
|
||||||
})
|
})
|
||||||
@@ -528,8 +533,8 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
checker.EXPECT().LimitExceeded()
|
checker.EXPECT().LimitExceeded()
|
||||||
ruleService.quotas = checker
|
ruleService.quotas = checker
|
||||||
|
|
||||||
group := createDummyGroup("quota-reached", 1)
|
group := createDummyGroup("quota-reached", orgID)
|
||||||
err := ruleService.ReplaceRuleGroup(context.Background(), 1, group, 0, models.ProvenanceAPI)
|
err := ruleService.ReplaceRuleGroup(context.Background(), u, group, models.ProvenanceAPI)
|
||||||
|
|
||||||
require.ErrorIs(t, err, models.ErrQuotaReached)
|
require.ErrorIs(t, err, models.ErrQuotaReached)
|
||||||
})
|
})
|
||||||
@@ -538,18 +543,19 @@ func TestAlertRuleService(t *testing.T) {
|
|||||||
func TestCreateAlertRule(t *testing.T) {
|
func TestCreateAlertRule(t *testing.T) {
|
||||||
ruleService := createAlertRuleService(t)
|
ruleService := createAlertRuleService(t)
|
||||||
var orgID int64 = 1
|
var orgID int64 = 1
|
||||||
|
u := &user.SignedInUser{OrgID: orgID}
|
||||||
|
|
||||||
t.Run("should return the created id", func(t *testing.T) {
|
t.Run("should return the created id", func(t *testing.T) {
|
||||||
rule, err := ruleService.CreateAlertRule(context.Background(), nil, dummyRule("test#1", orgID), models.ProvenanceNone)
|
rule, err := ruleService.CreateAlertRule(context.Background(), u, dummyRule("test#1", orgID), models.ProvenanceNone)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEqual(t, 0, rule.ID, "expected to get the created id and not the zero value")
|
require.NotEqual(t, 0, rule.ID, "expected to get the created id and not the zero value")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("should set the right provenance", func(t *testing.T) {
|
t.Run("should set the right provenance", func(t *testing.T) {
|
||||||
rule, err := ruleService.CreateAlertRule(context.Background(), nil, dummyRule("test#2", orgID), models.ProvenanceAPI)
|
rule, err := ruleService.CreateAlertRule(context.Background(), u, dummyRule("test#2", orgID), models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, provenance, err := ruleService.GetAlertRule(context.Background(), orgID, rule.UID)
|
_, provenance, err := ruleService.GetAlertRule(context.Background(), u, rule.UID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, models.ProvenanceAPI, provenance)
|
require.Equal(t, models.ProvenanceAPI, provenance)
|
||||||
})
|
})
|
||||||
@@ -558,17 +564,17 @@ func TestCreateAlertRule(t *testing.T) {
|
|||||||
t.Run("return error if it is not valid UID", func(t *testing.T) {
|
t.Run("return error if it is not valid UID", func(t *testing.T) {
|
||||||
rule := dummyRule("test#3", orgID)
|
rule := dummyRule("test#3", orgID)
|
||||||
rule.UID = strings.Repeat("1", util.MaxUIDLength+1)
|
rule.UID = strings.Repeat("1", util.MaxUIDLength+1)
|
||||||
rule, err := ruleService.CreateAlertRule(context.Background(), nil, rule, models.ProvenanceNone)
|
rule, err := ruleService.CreateAlertRule(context.Background(), u, rule, models.ProvenanceNone)
|
||||||
require.ErrorIs(t, err, models.ErrAlertRuleFailedValidation)
|
require.ErrorIs(t, err, models.ErrAlertRuleFailedValidation)
|
||||||
})
|
})
|
||||||
t.Run("should create a new rule with this UID", func(t *testing.T) {
|
t.Run("should create a new rule with this UID", func(t *testing.T) {
|
||||||
rule := dummyRule("test#3", orgID)
|
rule := dummyRule("test#3", orgID)
|
||||||
uid := util.GenerateShortUID()
|
uid := util.GenerateShortUID()
|
||||||
rule.UID = uid
|
rule.UID = uid
|
||||||
created, err := ruleService.CreateAlertRule(context.Background(), nil, rule, models.ProvenanceNone)
|
created, err := ruleService.CreateAlertRule(context.Background(), u, rule, models.ProvenanceNone)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uid, created.UID)
|
require.Equal(t, uid, created.UID)
|
||||||
_, _, err = ruleService.GetAlertRule(context.Background(), orgID, uid)
|
_, _, err = ruleService.GetAlertRule(context.Background(), u, uid)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
|
"github.com/grafana/grafana/pkg/services/auth/identity"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/folder"
|
"github.com/grafana/grafana/pkg/services/folder"
|
||||||
alert_models "github.com/grafana/grafana/pkg/services/ngalert/models"
|
alert_models "github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
|
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
|
||||||
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -42,6 +44,7 @@ func (prov *defaultAlertRuleProvisioner) Provision(ctx context.Context,
|
|||||||
files []*AlertingFile) error {
|
files []*AlertingFile) error {
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
for _, group := range file.Groups {
|
for _, group := range file.Groups {
|
||||||
|
u := provisionerUser(group.OrgID)
|
||||||
folderUID, err := prov.getOrCreateFolderUID(ctx, group.FolderTitle, group.OrgID)
|
folderUID, err := prov.getOrCreateFolderUID(ctx, group.FolderTitle, group.OrgID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -54,19 +57,18 @@ func (prov *defaultAlertRuleProvisioner) Provision(ctx context.Context,
|
|||||||
for _, rule := range group.Rules {
|
for _, rule := range group.Rules {
|
||||||
rule.NamespaceUID = folderUID
|
rule.NamespaceUID = folderUID
|
||||||
rule.RuleGroup = group.Title
|
rule.RuleGroup = group.Title
|
||||||
err = prov.provisionRule(ctx, group.OrgID, rule)
|
err = prov.provisionRule(ctx, u, rule)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = prov.ruleService.UpdateRuleGroup(ctx, group.OrgID, folderUID, group.Title, group.Interval)
|
err = prov.ruleService.UpdateRuleGroup(ctx, u, folderUID, group.Title, group.Interval)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, deleteRule := range file.DeleteRules {
|
for _, deleteRule := range file.DeleteRules {
|
||||||
err := prov.ruleService.DeleteAlertRule(ctx, deleteRule.OrgID,
|
err := prov.ruleService.DeleteAlertRule(ctx, provisionerUser(deleteRule.OrgID), deleteRule.UID, alert_models.ProvenanceFile)
|
||||||
deleteRule.UID, alert_models.ProvenanceFile)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -77,20 +79,20 @@ func (prov *defaultAlertRuleProvisioner) Provision(ctx context.Context,
|
|||||||
|
|
||||||
func (prov *defaultAlertRuleProvisioner) provisionRule(
|
func (prov *defaultAlertRuleProvisioner) provisionRule(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
orgID int64,
|
user identity.Requester,
|
||||||
rule alert_models.AlertRule) error {
|
rule alert_models.AlertRule) error {
|
||||||
prov.logger.Debug("provisioning alert rule", "uid", rule.UID, "org", rule.OrgID)
|
prov.logger.Debug("provisioning alert rule", "uid", rule.UID, "org", rule.OrgID)
|
||||||
_, _, err := prov.ruleService.GetAlertRule(ctx, orgID, rule.UID)
|
_, _, err := prov.ruleService.GetAlertRule(ctx, user, rule.UID)
|
||||||
if err != nil && !errors.Is(err, alert_models.ErrAlertRuleNotFound) {
|
if err != nil && !errors.Is(err, alert_models.ErrAlertRuleNotFound) {
|
||||||
return err
|
return err
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
prov.logger.Debug("creating rule", "uid", rule.UID, "org", rule.OrgID)
|
prov.logger.Debug("creating rule", "uid", rule.UID, "org", rule.OrgID)
|
||||||
// a nil user is passed in as then the quota logic will only check for
|
// a nil user is passed in as then the quota logic will only check for
|
||||||
// the organization quota since we don't have any user scope here.
|
// the organization quota since we don't have any user scope here.
|
||||||
_, err = prov.ruleService.CreateAlertRule(ctx, nil, rule, alert_models.ProvenanceFile)
|
_, err = prov.ruleService.CreateAlertRule(ctx, user, rule, alert_models.ProvenanceFile)
|
||||||
} else {
|
} else {
|
||||||
prov.logger.Debug("updating rule", "uid", rule.UID, "org", rule.OrgID)
|
prov.logger.Debug("updating rule", "uid", rule.UID, "org", rule.OrgID)
|
||||||
_, err = prov.ruleService.UpdateAlertRule(ctx, rule, alert_models.ProvenanceFile)
|
_, err = prov.ruleService.UpdateAlertRule(ctx, user, rule, alert_models.ProvenanceFile)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -129,3 +131,8 @@ func (prov *defaultAlertRuleProvisioner) getOrCreateFolderUID(
|
|||||||
|
|
||||||
return cmdResult.UID, nil
|
return cmdResult.UID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UserID is 0 to use org quota
|
||||||
|
var provisionerUser = func(orgID int64) identity.Requester {
|
||||||
|
return &user.SignedInUser{UserID: 0, Login: "alert_provisioner", OrgID: orgID}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user