From 86d2572e56d2e4ef6166425022a15c21cb7e3b0b Mon Sep 17 00:00:00 2001 From: Jirka Kremser <535866+jkremser@users.noreply.github.com> Date: Fri, 2 Oct 2020 18:07:09 +0200 Subject: [PATCH] Add a support for ignoring the events from a namespace that matches regexp (#386) Fixes issue #295 ##### ISSUE TYPE - Feature Pull Request ##### SUMMARY This change allows to ignore whole sets of namespaces using the asterix expansion. It still does the exact match check for all the namespaces (separated by comma in config), but if it contains a `*`, it's actually replaced with `.*` and passed to `regexp.MatchString` to do the job. PR also contains couple of very simple test cases. deps: `namespace_checker.go` now imports also `regexp` Fixes #295 It's my very first golang code, so please let me know if it's not idiomatic go :cookie: --- deploy-all-in-one-tls.yaml | 4 ++-- deploy-all-in-one.yaml | 4 ++-- helm/botkube/sample-res-config.yaml | 4 ++-- helm/botkube/values.yaml | 4 ++-- pkg/config/config.go | 3 ++- pkg/filterengine/filters/namespace_checker.go | 18 +++++++++++++++--- .../filters/namespace_checker_test.go | 9 ++++++--- resource_config.yaml | 4 ++-- test/resource_config.yaml | 4 ++-- 9 files changed, 35 insertions(+), 19 deletions(-) diff --git a/deploy-all-in-one-tls.yaml b/deploy-all-in-one-tls.yaml index 3b658fccc..35960c414 100644 --- a/deploy-all-in-one-tls.yaml +++ b/deploy-all-in-one-tls.yaml @@ -21,8 +21,8 @@ data: namespaces: # List of namespaces, "all" will watch all the namespaces include: - all - ignore: # List of namespaces to be ignored (omitempty), used only with include: all - - # example : include [all], ignore [x,y,z] + ignore: # List of namespaces to be ignored (omitempty), used only with include: all, can contain a wildcard (*) + - # example : include [all], ignore [x,y,secret-ns-*] events: # List of lifecycle events you want to receive, e.g create, update, delete, error OR all - create - delete diff --git a/deploy-all-in-one.yaml b/deploy-all-in-one.yaml index b22afed02..1983b5c9f 100644 --- a/deploy-all-in-one.yaml +++ b/deploy-all-in-one.yaml @@ -21,8 +21,8 @@ data: namespaces: # List of namespaces, "all" will watch all the namespaces include: - all - ignore: # List of namespaces to be ignored (omitempty), used only with include: all - - # example : include [all], ignore [x,y,z] + ignore: # List of namespaces to be ignored (omitempty), used only with include: all, can contain a wildcard (*) + - # example : include [all], ignore [x,y,secret-ns-*] events: # List of lifecycle events you want to receive, e.g create, update, delete, error OR all - create - delete diff --git a/helm/botkube/sample-res-config.yaml b/helm/botkube/sample-res-config.yaml index 6e4cb7d42..e87d29fd0 100644 --- a/helm/botkube/sample-res-config.yaml +++ b/helm/botkube/sample-res-config.yaml @@ -6,8 +6,8 @@ config: namespaces: # List of namespaces, "all" will watch all the namespaces include: - all - ignore: # List of namespaces to be ignored (omitempty), used only with include: all - - kube-system # example : include [all], ignore [x,y,z] + ignore: # List of namespaces to be ignored (omitempty), used only with include: all, can contain a wildcard (*) + - kube-system # example : include [all], ignore [x,y,secret-ns-*] events: # List of lifecycle events you want to receive, e.g create, update, delete, error OR all - create - delete diff --git a/helm/botkube/values.yaml b/helm/botkube/values.yaml index de509f6f5..85cf056ff 100644 --- a/helm/botkube/values.yaml +++ b/helm/botkube/values.yaml @@ -38,8 +38,8 @@ config: namespaces: # List of namespaces, "all" will watch all the namespaces include: - all - ignore: # List of namespaces to be ignored (omitempty), used only with include: all - - # example : include [all], ignore [x,y,z] + ignore: # List of namespaces to be ignored (omitempty), used only with include: all, can contain a wildcard (*) + - # example : include [all], ignore [x,y,secret-ns-*] events: # List of lifecycle events you want to receive, e.g create, update, delete, error OR all - create - delete diff --git a/pkg/config/config.go b/pkg/config/config.go index 7130fb83a..8eba2db7b 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -121,7 +121,8 @@ type UpdateSetting struct { // - "all" to watch all the namespaces // Ignore contains a list of namespaces to be ignored when all namespaces are included // It is an optional (omitempty) field which is tandem with Include [all] -// example : include [all], ignore [x,y,z] +// It can also contain a * that would expand to zero or more arbitrary characters +// example : include [all], ignore [x,y,secret-ns-*] type Namespaces struct { Include []string Ignore []string `yaml:",omitempty"` diff --git a/pkg/filterengine/filters/namespace_checker.go b/pkg/filterengine/filters/namespace_checker.go index cd32e3895..fe3bc6fa7 100644 --- a/pkg/filterengine/filters/namespace_checker.go +++ b/pkg/filterengine/filters/namespace_checker.go @@ -21,6 +21,7 @@ package filters import ( "fmt" + "regexp" "strings" "github.com/infracloudio/botkube/pkg/config" @@ -75,9 +76,20 @@ func (f NamespaceChecker) Describe() string { func isNamespaceIgnored(resourceNamespaces config.Namespaces, eventNamespace string) bool { if len(resourceNamespaces.Include) == 1 && resourceNamespaces.Include[0] == "all" { if len(resourceNamespaces.Ignore) > 0 { - ignoredNamespaces := fmt.Sprintf("%#v", resourceNamespaces.Ignore) - if strings.Contains(ignoredNamespaces, eventNamespace) { - return true + for _, ignoredNamespace := range resourceNamespaces.Ignore { + // exact match + if ignoredNamespace == eventNamespace { + return true + } + + // regexp + if strings.Contains(ignoredNamespace, "*") { + ns := strings.Replace(ignoredNamespace, "*", ".*", -1) + matched, err := regexp.MatchString(ns, eventNamespace) + if err == nil && matched { + return true + } + } } } } diff --git a/pkg/filterengine/filters/namespace_checker_test.go b/pkg/filterengine/filters/namespace_checker_test.go index cbf2f169a..69a5151c8 100644 --- a/pkg/filterengine/filters/namespace_checker_test.go +++ b/pkg/filterengine/filters/namespace_checker_test.go @@ -31,9 +31,12 @@ func TestIsNamespaceIgnored(t *testing.T) { eventNamespace string expected bool }{ - `include all and ignore few --> watch all except ignored`: {config.Namespaces{Include: []string{"all"}, Ignore: []string{"demo", "abc"}}, "demo", true}, - `include all and ignore is "" --> watch all`: {config.Namespaces{Include: []string{"all"}, Ignore: []string{""}}, "demo", false}, - `include all and ignore is [] --> watch all`: {config.Namespaces{Include: []string{"all"}, Ignore: []string{}}, "demo", false}, + `include all and ignore few --> watch all except ignored`: {config.Namespaces{Include: []string{"all"}, Ignore: []string{"demo", "abc"}}, "demo", true}, + `include all and ignore is "" --> watch all`: {config.Namespaces{Include: []string{"all"}, Ignore: []string{""}}, "demo", false}, + `include all and ignore is [] --> watch all`: {config.Namespaces{Include: []string{"all"}, Ignore: []string{}}, "demo", false}, + `include all and ignore with reqexp --> watch all except matched`: {config.Namespaces{Include: []string{"all"}, Ignore: []string{"my-*"}}, "my-ns", true}, + `include all and ignore few combined with regexp --> watch all except ignored`: {config.Namespaces{Include: []string{"all"}, Ignore: []string{"demo", "ignored-*-ns"}}, "ignored-42-ns", true}, + `include all and ignore with regexp that doesn't match anything --> watch all`: {config.Namespaces{Include: []string{"all"}, Ignore: []string{"demo-*"}}, "demo", false}, // utils.AllowedEventKindsMap inherently handles remaining test case } for name, test := range tests { diff --git a/resource_config.yaml b/resource_config.yaml index e4ac2a070..162a6aec4 100644 --- a/resource_config.yaml +++ b/resource_config.yaml @@ -6,8 +6,8 @@ resources: namespaces: # List of namespaces, "all" will watch all the namespaces include: - all - ignore: # List of namespaces to be ignored (omitempty), used only with include: all - - # example : include [all], ignore [x,y,z] + ignore: # List of namespaces to be ignored (omitempty), used only with include: all, can contain a wildcard (*) + - # example : include [all], ignore [x,y,secret-ns-*] events: # List of lifecycle events you want to receive, e.g create, update, delete, error OR all - create - delete diff --git a/test/resource_config.yaml b/test/resource_config.yaml index 661c81ab0..f138f141b 100644 --- a/test/resource_config.yaml +++ b/test/resource_config.yaml @@ -24,8 +24,8 @@ resources: namespaces: # List of namespaces, "all" will watch all the namespaces include: - all - ignore: # List of namespaces to be ignored (omitempty), used only with include: all - - # example : include [all], ignore [x,y,z] + ignore: # List of namespaces to be ignored (omitempty), used only with include: all, can contain a wildcard (*) + - # example : include [all], ignore [x,y,secret-ns-*] events: # List of lifecycle events you want to receive, e.g create, update, delete, error OR all - create - delete