diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 0d92e94b7a878a..fca7e75e22158a 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -56,6 +56,7 @@ import ( argodiff "github.com/argoproj/argo-cd/v2/util/argo/diff" "github.com/argoproj/argo-cd/v2/util/argo/normalizers" "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/regex" "github.com/argoproj/argo-cd/v2/util/stats" kubeerrors "k8s.io/apimachinery/pkg/api/errors" @@ -2087,7 +2088,7 @@ func (ctrl *ApplicationController) shouldSelfHeal(app *appv1.Application) (bool, // isAppNamespaceAllowed returns whether the application is allowed in the // namespace it's residing in. func (ctrl *ApplicationController) isAppNamespaceAllowed(app *appv1.Application) bool { - return app.Namespace == ctrl.namespace || glob.MatchStringInList(ctrl.applicationNamespaces, app.Namespace, false) + return app.Namespace == ctrl.namespace || regex.MatchStringInList(ctrl.applicationNamespaces, app.Namespace, false) } func (ctrl *ApplicationController) canProcessApp(obj interface{}) bool { diff --git a/go.mod b/go.mod index d88bc3c8eb2e3f..763ea6cd04f3f4 100644 --- a/go.mod +++ b/go.mod @@ -185,6 +185,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/dlclark/regexp2 v1.11.1 github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/evanphx/json-patch/v5 v5.8.0 // indirect diff --git a/go.sum b/go.sum index e7778ef8ae56f9..62baa335a5b6d8 100644 --- a/go.sum +++ b/go.sum @@ -844,6 +844,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/dlclark/regexp2 v1.11.1 h1:CJs78ewKXO9PuNf6Xwlw6eibMadBkXTRpOeUdv+IcWM= +github.com/dlclark/regexp2 v1.11.1/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= diff --git a/notification_controller/controller/controller.go b/notification_controller/controller/controller.go index 1bc3e73a6fbd71..7514e136b68c75 100644 --- a/notification_controller/controller/controller.go +++ b/notification_controller/controller/controller.go @@ -6,8 +6,6 @@ import ( "fmt" "time" - "github.com/argoproj/argo-cd/v2/util/glob" - "github.com/argoproj/argo-cd/v2/util/notification/k8s" service "github.com/argoproj/argo-cd/v2/util/notification/argocd" @@ -18,6 +16,7 @@ import ( "github.com/argoproj/argo-cd/v2/util/notification/settings" + "github.com/argoproj/argo-cd/v2/util/regex" "github.com/argoproj/notifications-engine/pkg/api" "github.com/argoproj/notifications-engine/pkg/controller" "github.com/argoproj/notifications-engine/pkg/services" @@ -122,7 +121,7 @@ func NewController( // Check if app is not in the namespace where the controller is in, and also app is not in one of the applicationNamespaces func checkAppNotInAdditionalNamespaces(app *unstructured.Unstructured, namespace string, applicationNamespaces []string) bool { - return namespace != app.GetNamespace() && !glob.MatchStringInList(applicationNamespaces, app.GetNamespace(), false) + return namespace != app.GetNamespace() && !regex.MatchStringInList(applicationNamespaces, app.GetNamespace(), false) } func (c *notificationController) alterDestinations(obj v1.Object, destinations services.Destinations, cfg api.Config) services.Destinations { @@ -151,7 +150,7 @@ func newInformer(resClient dynamic.ResourceInterface, controllerNamespace string } newItems := []unstructured.Unstructured{} for _, res := range appList.Items { - if controllerNamespace == res.GetNamespace() || glob.MatchStringInList(applicationNamespaces, res.GetNamespace(), false) { + if controllerNamespace == res.GetNamespace() || regex.MatchStringInList(applicationNamespaces, res.GetNamespace(), false) { newItems = append(newItems, res) } } diff --git a/util/glob/list.go b/util/glob/list.go index 1a6a8732ad3f83..e80c133c68cb7a 100644 --- a/util/glob/list.go +++ b/util/glob/list.go @@ -4,7 +4,9 @@ package glob // exactMatch is set to false, list may contain globs to be matched. func MatchStringInList(list []string, item string, exactMatch bool) bool { for _, ll := range list { - if item == ll || (!exactMatch && Match(ll, item)) { + if item == ll { + return true + } else if !exactMatch && Match(ll, item) { return true } } diff --git a/util/regex/list.go b/util/regex/list.go new file mode 100644 index 00000000000000..75dd991381fb05 --- /dev/null +++ b/util/regex/list.go @@ -0,0 +1,14 @@ +package regex + +// MatchStringInList will return true if item is contained in list. If +// exactMatch is set to false, list may contain globs to be matched. +func MatchStringInList(list []string, item string, exactMatch bool) bool { + for _, ll := range list { + if item == ll || (!exactMatch && Match(ll, item)) { + return true + } else { + + } + } + return false +} diff --git a/util/regex/regex.go b/util/regex/regex.go new file mode 100644 index 00000000000000..9ff73b8497e0a7 --- /dev/null +++ b/util/regex/regex.go @@ -0,0 +1,20 @@ +package regex + +import ( + "github.com/dlclark/regexp2" + log "github.com/sirupsen/logrus" +) + +func Match(pattern, text string) bool { + compiledRegex, err := regexp2.Compile(pattern, 0) + if err != nil { + log.Warnf("failed to compile pattern %s due to error %v", pattern, err) + return false + } + regexMatch, err := compiledRegex.MatchString(text) + if err != nil { + log.Warnf("failed to match pattern %s due to error %v", pattern, err) + return false + } + return regexMatch +} diff --git a/util/security/application_namespaces.go b/util/security/application_namespaces.go index 2ef5edea33a7fc..fdadd7021553e6 100644 --- a/util/security/application_namespaces.go +++ b/util/security/application_namespaces.go @@ -3,11 +3,11 @@ package security import ( "fmt" - "github.com/argoproj/argo-cd/v2/util/glob" + "github.com/argoproj/argo-cd/v2/util/regex" ) func IsNamespaceEnabled(namespace string, serverNamespace string, enabledNamespaces []string) bool { - return namespace == serverNamespace || glob.MatchStringInList(enabledNamespaces, namespace, false) + return namespace == serverNamespace || regex.MatchStringInList(enabledNamespaces, namespace, false) } func NamespaceNotPermittedError(namespace string) error {