Skip to content

Commit

Permalink
Add additional alerts validations
Browse files Browse the repository at this point in the history
Signed-off-by: assafad <aadmi@redhat.com>
  • Loading branch information
assafad committed Feb 28, 2024
1 parent d4e1fe8 commit d8f32a3
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 1 deletion.
72 changes: 72 additions & 0 deletions pkg/testutil/alert_custom_validations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package testutil

import promv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"

func ValidateAlertNameLength(alert *promv1.Rule) []Problem {
var result []Problem

if len(alert.Alert) > 50 {
result = append(result, Problem{
ResourceName: alert.Alert,
Description: "alert name exceeds 50 characters",
})
}

return result
}

func ValidateAlertRunbookURLAnnotation(alert *promv1.Rule) []Problem {
var result []Problem

runbookURL := alert.Annotations["runbook_url"]
if runbookURL == "" {
result = append(result, Problem{
ResourceName: alert.Alert,
Description: "alert must have a runbook_url annotation",
})
}

return result
}

func ValidateHealthImpactLabel(alert *promv1.Rule) []Problem {
var result []Problem

healthImpact := alert.Labels["operator_health_impact"]
if healthImpact == "" {
result = append(result, Problem{
ResourceName: alert.Alert,
Description: "alert must have a operator_health_impact label",
})
}

return result
}

func ValidateAlertPartOfLabel(alert *promv1.Rule) []Problem {
var result []Problem

partOf := alert.Labels["kubernetes_operator_part_of"]
if partOf == "" {
result = append(result, Problem{
ResourceName: alert.Alert,
Description: "alert must have a kubernetes_operator_part_of label",
})
}

return result
}

func ValidateAlertComponentLabel(alert *promv1.Rule) []Problem {
var result []Problem

partOf := alert.Labels["kubernetes_operator_component"]
if partOf == "" {
result = append(result, Problem{
ResourceName: alert.Alert,
Description: "alert must have a kubernetes_operator_component label",
})
}

return result
}
134 changes: 133 additions & 1 deletion pkg/testutil/alert_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var _ = Describe("Validators", func() {
linter = New()
})

Context("Alert Validation", func() {
Context("Default alert Validations", func() {
It("should validate alert with valid input", func() {
alert := &promv1.Rule{
Alert: "ExampleAlert",
Expand Down Expand Up @@ -116,4 +116,136 @@ var _ = Describe("Validators", func() {
Expect(problems[0].Description).To(ContainSubstring("alert must have a description annotation"))
})
})

Context("Custom alert Validations", func() {
It("should not return error if all custom validations were added and all exist", func() {
alert := &promv1.Rule{
Alert: "ExampleAlert",
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
Labels: map[string]string{
"severity": "critical",
"operator_health_impact": "example_health_impact",
"kubernetes_operator_part_of": "example_part_of",
"kubernetes_operator_component": "example_component",
},
Annotations: map[string]string{
"summary": "Example summary",
"description": "Example description",
"runbook_url": "example_runbook_url",
},
}
linter.AddCustomAlertValidations(ValidateAlertNameLength, ValidateAlertRunbookURLAnnotation,
ValidateHealthImpactLabel, ValidateAlertPartOfLabel, ValidateAlertComponentLabel)
problems := linter.LintAlert(alert)
Expect(problems).To(BeEmpty())
})

It("should return error if alert name length custom validation was added and alert name is too long", func() {
alert := &promv1.Rule{
Alert: "ExampleAlertWithVeryLongNameExtendedToMeetFiftyOneLength",
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "Example summary",
"description": "Example description",
},
}
linter.AddCustomAlertValidations(ValidateAlertNameLength)
problems := linter.LintAlert(alert)
Expect(problems).To(HaveLen(1))
Expect(problems[0].Description).To(ContainSubstring("alert name exceeds 50 characters"))
})

It("should return error if runbook_url custom validation was added and is missing", func() {
alert := &promv1.Rule{
Alert: "ExampleAlert",
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "Example summary",
"description": "Example description",
},
}
linter.AddCustomAlertValidations(ValidateAlertRunbookURLAnnotation)
problems := linter.LintAlert(alert)
Expect(problems).To(HaveLen(1))
Expect(problems[0].Description).To(ContainSubstring("alert must have a runbook_url annotation"))
})

It("should return error if kubernetes_operator_part_of custom validation was added and is missing", func() {
alert := &promv1.Rule{
Alert: "ExampleAlert",
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "Example summary",
"description": "Example description",
},
}
linter.AddCustomAlertValidations(ValidateAlertPartOfLabel)
problems := linter.LintAlert(alert)
Expect(problems).To(HaveLen(1))
Expect(problems[0].Description).To(ContainSubstring("alert must have a kubernetes_operator_part_of label"))
})

It("should return error if operator_health_impact custom validation was added and is missing", func() {
alert := &promv1.Rule{
Alert: "ExampleAlert",
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "Example summary",
"description": "Example description",
},
}
linter.AddCustomAlertValidations(ValidateHealthImpactLabel)
problems := linter.LintAlert(alert)
Expect(problems).To(HaveLen(1))
Expect(problems[0].Description).To(ContainSubstring("alert must have a operator_health_impact label"))
})

It("should return error if kubernetes_operator_component custom validation was added and is missing", func() {
alert := &promv1.Rule{
Alert: "ExampleAlert",
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "Example summary",
"description": "Example description",
},
}
linter.AddCustomAlertValidations(ValidateAlertComponentLabel)
problems := linter.LintAlert(alert)
Expect(problems).To(HaveLen(1))
Expect(problems[0].Description).To(ContainSubstring("alert must have a kubernetes_operator_component label"))
})

It("should return error if kubernetes_operator_component custom validation was added and is missing", func() {
alert := &promv1.Rule{
Alert: "ExampleAlert",
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "Example summary",
"description": "Example description",
},
}
linter.AddCustomAlertValidations(ValidateAlertComponentLabel)
problems := linter.LintAlert(alert)
Expect(problems).To(HaveLen(1))
Expect(problems[0].Description).To(ContainSubstring("alert must have a kubernetes_operator_component label"))
})
})
})

0 comments on commit d8f32a3

Please sign in to comment.