Skip to content

Commit

Permalink
Merge pull request #14 from machadovilaca/operatorrules-remove-usage-…
Browse files Browse the repository at this point in the history
…of-global-variables

Remove usage of global variable in operatorrules
  • Loading branch information
machadovilaca authored Jul 30, 2024
2 parents 413f6b5 + b8e6d1c commit 8d1631c
Show file tree
Hide file tree
Showing 9 changed files with 332 additions and 99 deletions.
3 changes: 2 additions & 1 deletion _examples/rules/operator_alerts.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

promv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/ptr"
)

var operatorAlerts = []promv1.Rule{
Expand All @@ -22,7 +23,7 @@ var operatorAlerts = []promv1.Rule{
{
Alert: "GuestbookOperatorNotReady",
Expr: intstr.FromString(fmt.Sprintf("%snumber_of_ready_pods < %snumber_of_pods", recordingRulesPrefix, recordingRulesPrefix)),
For: "5m",
For: ptr.To(promv1.Duration("5m")),
Annotations: map[string]string{
"summary": "Guestbook operator is not ready",
"description": "Guestbook operator is not ready for more than 5 minutes.",
Expand Down
12 changes: 7 additions & 5 deletions _examples/rules/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const (
)

var (
operatorRegistry = operatorrules.NewRegistry()

// Add your custom recording rules here
recordingRules = [][]operatorrules.RecordingRule{
operatorRecordingRules,
Expand All @@ -24,19 +26,19 @@ var (
)

func SetupRules() {
err := operatorrules.RegisterRecordingRules(recordingRules...)
err := operatorRegistry.RegisterRecordingRules(recordingRules...)
if err != nil {
panic(err)
}

err = operatorrules.RegisterAlerts(alerts...)
err = operatorRegistry.RegisterAlerts(alerts...)
if err != nil {
panic(err)
}
}

func BuildPrometheusRule() (*promv1.PrometheusRule, error) {
rules, err := operatorrules.BuildPrometheusRule(
rules, err := operatorRegistry.BuildPrometheusRule(
"guestbook-operator-prometheus-rules",
"default",
map[string]string{"app": "guestbook-operator"},
Expand All @@ -49,9 +51,9 @@ func BuildPrometheusRule() (*promv1.PrometheusRule, error) {
}

func ListRecordingRules() []operatorrules.RecordingRule {
return operatorrules.ListRecordingRules()
return operatorRegistry.ListRecordingRules()
}

func ListAlerts() []promv1.Rule {
return operatorrules.ListAlerts()
return operatorRegistry.ListAlerts()
}
37 changes: 37 additions & 0 deletions pkg/operatorrules/compatibility.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package operatorrules

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

// Deprecated: operatorRegistry is deprecated.
var operatorRegistry = NewRegistry()

// Deprecated: RegisterRecordingRules is deprecated.
func RegisterRecordingRules(recordingRules ...[]RecordingRule) error {
return operatorRegistry.RegisterRecordingRules(recordingRules...)
}

// Deprecated: RegisterAlerts is deprecated.
func RegisterAlerts(alerts ...[]promv1.Rule) error {
return operatorRegistry.RegisterAlerts(alerts...)
}

// Deprecated: ListRecordingRules is deprecated.
func ListRecordingRules() []RecordingRule {
return operatorRegistry.ListRecordingRules()
}

// Deprecated: ListAlerts is deprecated.
func ListAlerts() []promv1.Rule {
return operatorRegistry.ListAlerts()
}

// Deprecated: CleanRegistry is deprecated.
func CleanRegistry() error {
operatorRegistry = NewRegistry()
return nil
}

// Deprecated: BuildPrometheusRule is deprecated.
func BuildPrometheusRule(name, namespace string, labels map[string]string) (*promv1.PrometheusRule, error) {
return operatorRegistry.BuildPrometheusRule(name, namespace, labels)
}
231 changes: 231 additions & 0 deletions pkg/operatorrules/compatibility_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
package operatorrules

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"k8s.io/apimachinery/pkg/util/intstr"

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

"github.com/machadovilaca/operator-observability/pkg/operatormetrics"
)

var _ = Describe("OperatorRules", func() {
BeforeEach(func() {
operatorRegistry = NewRegistry()
})

Context("RecordingRule Registration", func() {
It("should register recording rules without error", func() {
recordingRules := []RecordingRule{
{
MetricsOpts: operatormetrics.MetricOpts{Name: "ExampleRecordingRule1"},
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
},
{
MetricsOpts: operatormetrics.MetricOpts{Name: "ExampleRecordingRule2"},
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
},
}

err := RegisterRecordingRules(recordingRules)
Expect(err).To(BeNil())

registeredRules := ListRecordingRules()
Expect(registeredRules).To(ConsistOf(recordingRules))
})

It("should replace recording rule with the same name and expression", func() {
recordingRules := []RecordingRule{
{
MetricsOpts: operatormetrics.MetricOpts{Name: "ExampleRecordingRule1"},
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
},
{
MetricsOpts: operatormetrics.MetricOpts{Name: "ExampleRecordingRule1"},
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
},
}

err := RegisterRecordingRules(recordingRules)
Expect(err).To(BeNil())

registeredRules := ListRecordingRules()
Expect(registeredRules).To(HaveLen(1))
Expect(registeredRules[0].Expr.String()).To(Equal("sum(rate(http_requests_total[5m]))"))
})

It("should create 2 recording rules when registered with the same name but different expressions", func() {
recordingRules := []RecordingRule{
{
MetricsOpts: operatormetrics.MetricOpts{Name: "ExampleRecordingRule1"},
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
},
}

err := RegisterRecordingRules(recordingRules)
Expect(err).To(BeNil())

recordingRules = []RecordingRule{
{
MetricsOpts: operatormetrics.MetricOpts{Name: "ExampleRecordingRule1"},
Expr: intstr.FromString("sum(rate(http_requests_total[10m]))"),
},
}

err = RegisterRecordingRules(recordingRules)
Expect(err).To(BeNil())

registeredRules := ListRecordingRules()
Expect(registeredRules).To(HaveLen(2))
Expect(registeredRules[0].Expr.String()).To(Equal("sum(rate(http_requests_total[10m]))"))
Expect(registeredRules[1].Expr.String()).To(Equal("sum(rate(http_requests_total[5m]))"))
})
})

Context("Alert Registration", func() {
It("should register alerts without error", func() {
alerts := []promv1.Rule{
{
Alert: "ExampleAlert1",
Expr: intstr.FromString("sum(rate(http_requests_total[1m])) > 100"),
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "High request rate",
"description": "The request rate is too high.",
},
},
{
Alert: "ExampleAlert2",
Expr: intstr.FromString("sum(rate(http_requests_total[5m])) > 100"),
Labels: map[string]string{
"severity": "warning",
},
Annotations: map[string]string{
"summary": "Moderate request rate",
"description": "The request rate is moderately high.",
},
},
}

err := RegisterAlerts(alerts)
Expect(err).To(BeNil())

registeredAlerts := ListAlerts()
Expect(registeredAlerts).To(ConsistOf(alerts))
})

It("should replace alerts with the same name in the same RegisterAlerts call", func() {
alerts := []promv1.Rule{
{
Alert: "ExampleAlert1",
Expr: intstr.FromString("sum(rate(http_requests_total[1m])) > 100"),
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "High request rate",
"description": "The request rate is too high.",
},
},
{
Alert: "ExampleAlert1",
Expr: intstr.FromString("sum(rate(http_requests_total[1m])) > 200"),
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "High request rate",
"description": "The request rate is too high.",
},
},
}

err := RegisterAlerts(alerts)
Expect(err).To(BeNil())

registeredAlerts := ListAlerts()
Expect(registeredAlerts).To(HaveLen(1))
Expect(registeredAlerts[0].Expr.String()).To(Equal("sum(rate(http_requests_total[1m])) > 200"))
})

It("should replace alerts with the same name in different RegisterAlerts calls", func() {
alerts := []promv1.Rule{
{
Alert: "ExampleAlert1",
Expr: intstr.FromString("sum(rate(http_requests_total[1m])) > 100"),
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "High request rate",
"description": "The request rate is too high.",
},
},
}

err := RegisterAlerts(alerts)
Expect(err).To(BeNil())

alerts = []promv1.Rule{
{
Alert: "ExampleAlert1",
Expr: intstr.FromString("sum(rate(http_requests_total[1m])) > 200"),
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "High request rate",
"description": "The request rate is too high.",
},
},
}

err = RegisterAlerts(alerts)
Expect(err).To(BeNil())

registeredAlerts := ListAlerts()
Expect(registeredAlerts).To(HaveLen(1))
Expect(registeredAlerts[0].Expr.String()).To(Equal("sum(rate(http_requests_total[1m])) > 200"))
})
})

Context("Clean Registry", func() {
It("should clean registry without error", func() {
recordingRules := []RecordingRule{
{
MetricsOpts: operatormetrics.MetricOpts{Name: "ExampleRecordingRule1"},
Expr: intstr.FromString("sum(rate(http_requests_total[5m]))"),
},
}

alerts := []promv1.Rule{
{
Alert: "ExampleAlert1",
Expr: intstr.FromString("sum(rate(http_requests_total[1m])) > 100"),
},
}

err := RegisterRecordingRules(recordingRules)
Expect(err).To(BeNil())
registeredRules := ListRecordingRules()
Expect(registeredRules).To(ConsistOf(recordingRules))

err = RegisterAlerts(alerts)
Expect(err).To(BeNil())
registeredAlerts := ListAlerts()
Expect(registeredAlerts).To(ConsistOf(alerts))

err = CleanRegistry()
Expect(err).To(BeNil())

registeredRules = ListRecordingRules()
Expect(registeredRules).To(BeEmpty())
registeredAlerts = ListAlerts()
Expect(registeredAlerts).To(BeEmpty())
})
})
})
2 changes: 1 addition & 1 deletion pkg/operatorrules/operatorrules_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package operatorrules
package operatorrules_test

import (
"testing"
Expand Down
18 changes: 9 additions & 9 deletions pkg/operatorrules/prometheusrules.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
)

// BuildPrometheusRule builds a PrometheusRule object from the registered recording rules and alerts.
func BuildPrometheusRule(name, namespace string, labels map[string]string) (*promv1.PrometheusRule, error) {
spec, err := buildPrometheusRuleSpec()
func (r *Registry) BuildPrometheusRule(name, namespace string, labels map[string]string) (*promv1.PrometheusRule, error) {
spec, err := r.buildPrometheusRuleSpec()
if err != nil {
return nil, err
}
Expand All @@ -31,20 +31,20 @@ func BuildPrometheusRule(name, namespace string, labels map[string]string) (*pro
}, nil
}

func buildPrometheusRuleSpec() (*promv1.PrometheusRuleSpec, error) {
func (r *Registry) buildPrometheusRuleSpec() (*promv1.PrometheusRuleSpec, error) {
var groups []promv1.RuleGroup

if len(operatorRegistry.registeredRecordingRules) != 0 {
if len(r.registeredRecordingRules) != 0 {
groups = append(groups, promv1.RuleGroup{
Name: "recordingRules.rules",
Rules: buildRecordingRulesRules(),
Rules: r.buildRecordingRulesRules(),
})
}

if len(operatorRegistry.registeredAlerts) != 0 {
if len(r.registeredAlerts) != 0 {
groups = append(groups, promv1.RuleGroup{
Name: "alerts.rules",
Rules: ListAlerts(),
Rules: r.ListAlerts(),
})
}

Expand All @@ -55,10 +55,10 @@ func buildPrometheusRuleSpec() (*promv1.PrometheusRuleSpec, error) {
return &promv1.PrometheusRuleSpec{Groups: groups}, nil
}

func buildRecordingRulesRules() []promv1.Rule {
func (r *Registry) buildRecordingRulesRules() []promv1.Rule {
var rules []promv1.Rule

for _, recordingRule := range operatorRegistry.registeredRecordingRules {
for _, recordingRule := range r.registeredRecordingRules {
rules = append(rules, promv1.Rule{
Record: recordingRule.MetricsOpts.Name,
Expr: recordingRule.Expr,
Expand Down
Loading

0 comments on commit 8d1631c

Please sign in to comment.