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