From 251597b378cd0c6af322def1d53e247565420b3d Mon Sep 17 00:00:00 2001 From: Thomas Leclaire Date: Mon, 29 Dec 2025 17:53:01 +0100 Subject: [PATCH] add some node filters Signed-off-by: Thomas Leclaire --- config/config.go | 3 +++ config/config_test.go | 57 ++++++++++++++++++++++++++++++++++++++++++ handler/processNode.go | 8 +++++- 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index 465fa4d1..a0d475f8 100644 --- a/config/config.go +++ b/config/config.go @@ -68,6 +68,9 @@ type Config struct { // Patterns are compiled from IgnoreLogPatterns after populating // IgnoreLogPatterns configuration IgnoreLogPatternsCompiled []*regexp.Regexp + + // IgnoreNodeReasons is an optional list of node reasons for which alerting should be skipped + IgnoreNodeReasons []string `yaml:"ignoreNodeReasons"` } // App confing struct diff --git a/config/config_test.go b/config/config_test.go index d1d1f6fd..600fa52d 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -122,3 +122,60 @@ func TestGetCompiledIgnorePatterns(t *testing.T) { assert.NotNil(err) } + +func TestIgnoreNodeReasonsLoading(t *testing.T) { + assert := assert.New(t) + + defer os.Unsetenv("CONFIG_FILE") + defer os.RemoveAll("config.yaml") + + os.Setenv("CONFIG_FILE", "config.yaml") + + n := Config{ + IgnoreNodeReasons: []string{"NotReady", "KubeletNotReady", "custom-reason"}, + } + yamlData, _ := yaml.Marshal(&n) + os.WriteFile("config.yaml", yamlData, 0644) + + cfg, _ := LoadConfig() + assert.NotNil(cfg) + assert.Equal([]string{"NotReady", "KubeletNotReady", "custom-reason"}, cfg.IgnoreNodeReasons) +} + +func TestIgnoreNodeReasonsEmpty(t *testing.T) { + assert := assert.New(t) + + defer os.Unsetenv("CONFIG_FILE") + defer os.RemoveAll("config.yaml") + + os.Setenv("CONFIG_FILE", "config.yaml") + + n := Config{ + IgnoreNodeReasons: []string{}, + } + yamlData, _ := yaml.Marshal(&n) + os.WriteFile("config.yaml", yamlData, 0644) + + cfg, _ := LoadConfig() + assert.NotNil(cfg) + assert.Equal([]string{}, cfg.IgnoreNodeReasons) +} + +func TestIgnoreNodeReasonsSpecialChars(t *testing.T) { + assert := assert.New(t) + + defer os.Unsetenv("CONFIG_FILE") + defer os.RemoveAll("config.yaml") + + os.Setenv("CONFIG_FILE", "config.yaml") + + n := Config{ + IgnoreNodeReasons: []string{"reason-1", "reason_2", "reason.with.dot", "reason/with/slash"}, + } + yamlData, _ := yaml.Marshal(&n) + os.WriteFile("config.yaml", yamlData, 0644) + + cfg, _ := LoadConfig() + assert.NotNil(cfg) + assert.Equal([]string{"reason-1", "reason_2", "reason.with.dot", "reason/with/slash"}, cfg.IgnoreNodeReasons) +} diff --git a/handler/processNode.go b/handler/processNode.go index fc014391..dbfaeb23 100644 --- a/handler/processNode.go +++ b/handler/processNode.go @@ -2,7 +2,6 @@ package handler import ( "fmt" - "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" @@ -28,6 +27,13 @@ func (h *handler) ProcessNode(eventType string, obj runtime.Object) { if c.Type == corev1.NodeReady { if c.Status == corev1.ConditionFalse && !h.memory.HasNode(node.Name) { logrus.Printf("node %s is not ready: %s", node.Name, c.Reason) + // Skip alert if Reason is in IgnoreNodeReasons + for _, ignoreReason := range h.config.IgnoreNodeReasons { + if c.Reason == ignoreReason { + logrus.Printf("Skipping Notify for node %s due to ignored reason: %s", node.Name, c.Reason) + return + } + } h.alertManager.Notify(fmt.Sprintf("Node %s is not ready: %s - %s", node.Name, c.Reason,