diff --git a/pkg/services/ngalert/api/api_ruler_validation.go b/pkg/services/ngalert/api/api_ruler_validation.go index 1c69a8d16a2..ea1eb185acb 100644 --- a/pkg/services/ngalert/api/api_ruler_validation.go +++ b/pkg/services/ngalert/api/api_ruler_validation.go @@ -3,7 +3,6 @@ package api import ( "errors" "fmt" - "strconv" "time" "github.com/grafana/grafana/pkg/models" @@ -120,20 +119,9 @@ func validateRuleNode( newAlertRule.Annotations = ruleNode.ApiRuleNode.Annotations newAlertRule.Labels = ruleNode.ApiRuleNode.Labels - dashUID := ruleNode.ApiRuleNode.Annotations[ngmodels.DashboardUIDAnnotation] - panelID := ruleNode.ApiRuleNode.Annotations[ngmodels.PanelIDAnnotation] - - if dashUID != "" && panelID == "" || dashUID == "" && panelID != "" { - return nil, fmt.Errorf("both annotations %s and %s must be specified", ngmodels.DashboardUIDAnnotation, ngmodels.PanelIDAnnotation) - } - - if dashUID != "" { - panelIDValue, err := strconv.ParseInt(panelID, 10, 64) - if err != nil { - return nil, fmt.Errorf("annotation %s must be a valid integer Panel ID", ngmodels.PanelIDAnnotation) - } - newAlertRule.DashboardUID = &dashUID - newAlertRule.PanelID = &panelIDValue + err = newAlertRule.SetDashboardAndPanel() + if err != nil { + return nil, err } } return &newAlertRule, nil diff --git a/pkg/services/ngalert/models/alert_rule.go b/pkg/services/ngalert/models/alert_rule.go index 1b08e18bc46..275695e5071 100644 --- a/pkg/services/ngalert/models/alert_rule.go +++ b/pkg/services/ngalert/models/alert_rule.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "sort" + "strconv" "time" "github.com/google/go-cmp/cmp" @@ -186,6 +187,31 @@ func (alertRule *AlertRule) Diff(rule *AlertRule, ignore ...string) cmputil.Diff return reporter.Diffs } +// SetDashboardAndPanel will set the DashboardUID and PanlID +// field be doing a lookup in the annotations. Errors when +// the found annotations are not valid. +func (alertRule *AlertRule) SetDashboardAndPanel() error { + if alertRule.Annotations == nil { + return nil + } + dashUID := alertRule.Annotations[DashboardUIDAnnotation] + panelID := alertRule.Annotations[PanelIDAnnotation] + if dashUID != "" && panelID == "" || dashUID == "" && panelID != "" { + return fmt.Errorf("both annotations %s and %s must be specified", + DashboardUIDAnnotation, PanelIDAnnotation) + } + if dashUID != "" { + panelIDValue, err := strconv.ParseInt(panelID, 10, 64) + if err != nil { + return fmt.Errorf("annotation %s must be a valid integer Panel ID", + PanelIDAnnotation) + } + alertRule.DashboardUID = &dashUID + alertRule.PanelID = &panelIDValue + } + return nil +} + // AlertRuleKey is the alert definition identifier type AlertRuleKey struct { OrgID int64 `xorm:"org_id"` diff --git a/pkg/services/ngalert/provisioning/alert_rules.go b/pkg/services/ngalert/provisioning/alert_rules.go index 26175f65338..82e07f37617 100644 --- a/pkg/services/ngalert/provisioning/alert_rules.go +++ b/pkg/services/ngalert/provisioning/alert_rules.go @@ -73,6 +73,10 @@ func (service *AlertRuleService) CreateAlertRule(ctx context.Context, rule model return models.AlertRule{}, err } rule.IntervalSeconds = interval + err = rule.SetDashboardAndPanel() + if err != nil { + return models.AlertRule{}, err + } rule.Updated = time.Now() err = service.xact.InTransaction(ctx, func(ctx context.Context) error { ids, err := service.ruleStore.InsertAlertRules(ctx, []models.AlertRule{ @@ -180,6 +184,10 @@ func (service *AlertRuleService) UpdateAlertRule(ctx context.Context, rule model if err != nil { return models.AlertRule{}, err } + err = rule.SetDashboardAndPanel() + if err != nil { + return models.AlertRule{}, err + } err = service.xact.InTransaction(ctx, func(ctx context.Context) error { err := service.ruleStore.UpdateAlertRules(ctx, []store.UpdateRule{ {