From 0dacb11a12055e7bb8fa5e12b995971aa655c7d2 Mon Sep 17 00:00:00 2001 From: George Robinson Date: Tue, 31 Jan 2023 14:19:44 +0000 Subject: [PATCH] Alerting: Validate that tags are 100 characters or less (#62335) Co-authored-by: Gilles De Mey --- pkg/services/alerting/extractor.go | 25 +++++++++++++++++-------- pkg/services/alerting/models/alert.go | 13 +++++++++++-- public/app/core/services/backend_srv.ts | 3 ++- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/pkg/services/alerting/extractor.go b/pkg/services/alerting/extractor.go index 4dce85874e5..f754b3bf47b 100644 --- a/pkg/services/alerting/extractor.go +++ b/pkg/services/alerting/extractor.go @@ -106,7 +106,7 @@ func UAEnabled(ctx context.Context) bool { return enabled } -func (e *DashAlertExtractorService) getAlertFromPanels(ctx context.Context, jsonWithPanels *simplejson.Json, validateAlertFunc func(*models.Alert) bool, logTranslationFailures bool, dashAlertInfo DashAlertInfo) ([]*models.Alert, error) { +func (e *DashAlertExtractorService) getAlertFromPanels(ctx context.Context, jsonWithPanels *simplejson.Json, validateAlertFunc func(*models.Alert) error, logTranslationFailures bool, dashAlertInfo DashAlertInfo) ([]*models.Alert, error) { ret := make([]*models.Alert, 0) for _, panelObj := range jsonWithPanels.Get("panels").MustArray() { @@ -238,8 +238,8 @@ func (e *DashAlertExtractorService) getAlertFromPanels(ctx context.Context, json return nil, err } - if !validateAlertFunc(alert) { - return nil, ValidationError{Reason: fmt.Sprintf("Panel id is not correct, alertName=%v, panelId=%v", alert.Name, alert.PanelId)} + if err := validateAlertFunc(alert); err != nil { + return nil, err } ret = append(ret, alert) @@ -248,8 +248,14 @@ func (e *DashAlertExtractorService) getAlertFromPanels(ctx context.Context, json return ret, nil } -func validateAlertRule(alert *models.Alert) bool { - return alert.ValidToSave() +func validateAlertRule(alert *models.Alert) error { + if !alert.ValidDashboardPanel() { + return ValidationError{Reason: fmt.Sprintf("Panel id is not correct, alertName=%v, panelId=%v", alert.Name, alert.PanelId)} + } + if !alert.ValidTags() { + return ValidationError{Reason: "Invalid tags, must be less than 100 characters"} + } + return nil } // GetAlerts extracts alerts from the dashboard json and does full validation on the alert json data. @@ -257,7 +263,7 @@ func (e *DashAlertExtractorService) GetAlerts(ctx context.Context, dashAlertInfo return e.extractAlerts(ctx, validateAlertRule, true, dashAlertInfo) } -func (e *DashAlertExtractorService) extractAlerts(ctx context.Context, validateFunc func(alert *models.Alert) bool, logTranslationFailures bool, dashAlertInfo DashAlertInfo) ([]*models.Alert, error) { +func (e *DashAlertExtractorService) extractAlerts(ctx context.Context, validateFunc func(alert *models.Alert) error, logTranslationFailures bool, dashAlertInfo DashAlertInfo) ([]*models.Alert, error) { dashboardJSON, err := copyJSON(dashAlertInfo.Dash.Data) if err != nil { return nil, err @@ -294,8 +300,11 @@ func (e *DashAlertExtractorService) extractAlerts(ctx context.Context, validateF // ValidateAlerts validates alerts in the dashboard json but does not require a valid dashboard id // in the first validation pass. func (e *DashAlertExtractorService) ValidateAlerts(ctx context.Context, dashAlertInfo DashAlertInfo) error { - _, err := e.extractAlerts(ctx, func(alert *models.Alert) bool { - return alert.OrgId != 0 && alert.PanelId != 0 + _, err := e.extractAlerts(ctx, func(alert *models.Alert) error { + if alert.OrgId == 0 || alert.PanelId == 0 { + return errors.New("missing OrgId, PanelId or both") + } + return nil }, false, dashAlertInfo) return err } diff --git a/pkg/services/alerting/models/alert.go b/pkg/services/alerting/models/alert.go index 9d8a8e15f05..6ac2cda8bbe 100644 --- a/pkg/services/alerting/models/alert.go +++ b/pkg/services/alerting/models/alert.go @@ -92,8 +92,17 @@ type Alert struct { Settings *simplejson.Json } -func (a *Alert) ValidToSave() bool { - return a.DashboardId != 0 && a.OrgId != 0 && a.PanelId != 0 +func (a *Alert) ValidDashboardPanel() bool { + return a.OrgId != 0 && a.DashboardId != 0 && a.PanelId != 0 +} + +func (a *Alert) ValidTags() bool { + for _, tag := range a.GetTagsFromSettings() { + if len(tag.Key) > 100 || len(tag.Value) > 100 { + return false + } + } + return true } func (a *Alert) ContainsUpdates(other *Alert) bool { diff --git a/public/app/core/services/backend_srv.ts b/public/app/core/services/backend_srv.ts index 6a4e009372e..a16ffd71cfc 100644 --- a/public/app/core/services/backend_srv.ts +++ b/public/app/core/services/backend_srv.ts @@ -304,7 +304,7 @@ export class BackendSrv implements BackendService { } } - showErrorAlert(config: BackendSrvRequest, err: FetchError) { + showErrorAlert(config: BackendSrvRequest, err: FetchError) { if (config.showErrorAlert === false) { return; } @@ -324,6 +324,7 @@ export class BackendSrv implements BackendService { // Validation if (err.status === 422) { + description = err.data.message; message = 'Validation failed'; }