mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Allow space in label and annotation names (#36549)
Signed-off-by: Ganesh Vernekar <ganeshvern@gmail.com>
This commit is contained in:
parent
9ace8686a1
commit
94d2520a84
@ -504,7 +504,7 @@ func (am *Alertmanager) PutAlerts(postableAlerts apimodels.PostableAlerts) error
|
||||
am.Metrics.Resolved().Inc()
|
||||
}
|
||||
|
||||
if err := alert.Validate(); err != nil {
|
||||
if err := validateAlert(alert); err != nil {
|
||||
if validationErr == nil {
|
||||
validationErr = &AlertValidationError{}
|
||||
}
|
||||
@ -528,6 +528,59 @@ func (am *Alertmanager) PutAlerts(postableAlerts apimodels.PostableAlerts) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateAlert is a.Validate() while additionally allowing
|
||||
// space for label and annotation names.
|
||||
func validateAlert(a *types.Alert) error {
|
||||
if a.StartsAt.IsZero() {
|
||||
return fmt.Errorf("start time missing")
|
||||
}
|
||||
if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) {
|
||||
return fmt.Errorf("start time must be before end time")
|
||||
}
|
||||
if err := validateLabelSet(a.Labels); err != nil {
|
||||
return fmt.Errorf("invalid label set: %s", err)
|
||||
}
|
||||
if len(a.Labels) == 0 {
|
||||
return fmt.Errorf("at least one label pair required")
|
||||
}
|
||||
if err := validateLabelSet(a.Annotations); err != nil {
|
||||
return fmt.Errorf("invalid annotations: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateLabelSet is ls.Validate() while additionally allowing
|
||||
// space for label names.
|
||||
func validateLabelSet(ls model.LabelSet) error {
|
||||
for ln, lv := range ls {
|
||||
if !isValidLabelName(ln) {
|
||||
return fmt.Errorf("invalid name %q", ln)
|
||||
}
|
||||
if !lv.IsValid() {
|
||||
return fmt.Errorf("invalid value %q", lv)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// isValidLabelName is ln.IsValid() while additionally allowing spaces.
|
||||
// The regex for Prometheus data model is ^[a-zA-Z_][a-zA-Z0-9_]*$
|
||||
// while we will follow ^[a-zA-Z_][a-zA-Z0-9_ ]*$
|
||||
func isValidLabelName(ln model.LabelName) bool {
|
||||
if len(ln) == 0 {
|
||||
return false
|
||||
}
|
||||
for i, b := range ln {
|
||||
if !((b >= 'a' && b <= 'z') ||
|
||||
(b >= 'A' && b <= 'Z') ||
|
||||
b == '_' ||
|
||||
(i > 0 && (b == ' ' || (b >= '0' && b <= '9')))) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// AlertValidationError is the error capturing the validation errors
|
||||
// faced on the alerts.
|
||||
type AlertValidationError struct {
|
||||
@ -538,7 +591,7 @@ type AlertValidationError struct {
|
||||
func (e AlertValidationError) Error() string {
|
||||
errMsg := ""
|
||||
if len(e.Errors) != 0 {
|
||||
errMsg := e.Errors[0].Error()
|
||||
errMsg = e.Errors[0].Error()
|
||||
for _, e := range e.Errors[1:] {
|
||||
errMsg += ";" + e.Error()
|
||||
}
|
||||
|
@ -182,6 +182,36 @@ func TestPutAlert(t *testing.T) {
|
||||
},
|
||||
}
|
||||
},
|
||||
}, {
|
||||
title: "Allow spaces in label and annotation name",
|
||||
postableAlerts: apimodels.PostableAlerts{
|
||||
PostableAlerts: []models.PostableAlert{
|
||||
{
|
||||
Annotations: models.LabelSet{"Dashboard URL": "http://localhost:3000"},
|
||||
Alert: models.Alert{
|
||||
Labels: models.LabelSet{"alertname": "Alert4", "Spaced Label": "works"},
|
||||
GeneratorURL: "http://localhost/url1",
|
||||
},
|
||||
StartsAt: strfmt.DateTime{},
|
||||
EndsAt: strfmt.DateTime{},
|
||||
},
|
||||
},
|
||||
},
|
||||
expAlerts: func(now time.Time) []*types.Alert {
|
||||
return []*types.Alert{
|
||||
{
|
||||
Alert: model.Alert{
|
||||
Annotations: model.LabelSet{"Dashboard URL": "http://localhost:3000"},
|
||||
Labels: model.LabelSet{"alertname": "Alert4", "Spaced Label": "works"},
|
||||
StartsAt: now,
|
||||
EndsAt: now.Add(defaultResolveTimeout),
|
||||
GeneratorURL: "http://localhost/url1",
|
||||
},
|
||||
UpdatedAt: now,
|
||||
Timeout: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
}, {
|
||||
title: "Invalid labels",
|
||||
postableAlerts: apimodels.PostableAlerts{
|
||||
|
Loading…
Reference in New Issue
Block a user