From 7cba9ad79d17428bd467d23c19b5cbfed02f1e1e Mon Sep 17 00:00:00 2001 From: anandf Date: Wed, 25 Sep 2024 01:40:28 +0530 Subject: [PATCH] Added err checks for glob validations Signed-off-by: anandf --- cmd/util/project.go | 6 ++++-- controller/sync.go | 10 ++++++++-- .../application/v1alpha1/app_project_types.go | 16 +++++++++++++++- util/glob/glob.go | 8 ++++++++ 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/cmd/util/project.go b/cmd/util/project.go index b0a82883dc0bb..3626f414aafd9 100644 --- a/cmd/util/project.go +++ b/cmd/util/project.go @@ -48,6 +48,8 @@ func AddProjFlags(command *cobra.Command, opts *ProjectOpts) { command.Flags().StringArrayVar(&opts.allowedNamespacedResources, "allow-namespaced-resource", []string{}, "List of allowed namespaced resources") command.Flags().StringArrayVar(&opts.deniedNamespacedResources, "deny-namespaced-resource", []string{}, "List of denied namespaced resources") command.Flags().StringSliceVar(&opts.SourceNamespaces, "source-namespaces", []string{}, "List of source namespaces for applications") + command.Flags().StringArrayVarP(&opts.destinationServiceAccounts, "dest-service-accounts", "", []string{}, + "Destination server, namespace and target service account (e.g. https://192.168.99.100:8443,default,default-sa)") } func getGroupKindList(values []string) []v1.GroupKind { @@ -98,8 +100,8 @@ func (opts *ProjectOpts) GetDestinationServiceAccounts() []v1alpha1.ApplicationD destinationServiceAccounts := make([]v1alpha1.ApplicationDestinationServiceAccount, 0) for _, destStr := range opts.destinationServiceAccounts { parts := strings.Split(destStr, ",") - if len(parts) != 2 { - log.Fatalf("Expected destination of the form: server,namespace. Received: %s", destStr) + if len(parts) != 3 { + log.Fatalf("Expected destination service account of the form: server,namespace, defaultServiceAccount. Received: %s", destStr) } else { destinationServiceAccounts = append(destinationServiceAccounts, v1alpha1.ApplicationDestinationServiceAccount{ Server: parts[0], diff --git a/controller/sync.go b/controller/sync.go index f3336a9ef99b7..3d39a42b01b01 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -574,8 +574,14 @@ func deriveServiceAccountToImpersonate(project *v1alpha1.AppProject, application // Loop through the destinationServiceAccounts and see if there is any destination that is a candidate. // if so, return the service account specified for that destination. for _, item := range project.Spec.DestinationServiceAccounts { - dstServerMatched := glob.Match(item.Server, application.Spec.Destination.Server) - dstNamespaceMatched := glob.Match(item.Namespace, application.Spec.Destination.Namespace) + dstServerMatched, err := glob.MatchWithError(item.Server, application.Spec.Destination.Server) + if err != nil { + return "", err + } + dstNamespaceMatched, err := glob.MatchWithError(item.Namespace, application.Spec.Destination.Namespace) + if err != nil { + return "", err + } if dstServerMatched && dstNamespaceMatched { if item.DefaultServiceAccount == "" { return "", fmt.Errorf("default service account cannot be an empty string") diff --git a/pkg/apis/application/v1alpha1/app_project_types.go b/pkg/apis/application/v1alpha1/app_project_types.go index b888cd37391b3..b2488ce6a6a52 100644 --- a/pkg/apis/application/v1alpha1/app_project_types.go +++ b/pkg/apis/application/v1alpha1/app_project_types.go @@ -8,7 +8,7 @@ import ( "github.com/argoproj/argo-cd/v2/util/git" "github.com/argoproj/argo-cd/v2/util/glob" - + globutil "github.com/gobwas/glob" "github.com/google/go-cmp/cmp" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -275,6 +275,20 @@ func (p *AppProject) ValidateProject() error { return status.Errorf(codes.InvalidArgument, "namespace has an invalid format, '!*'") } + if strings.Contains(destServiceAcct.DefaultServiceAccount, "*") { + return status.Errorf(codes.InvalidArgument, "defaultServiceAccount does not support glob patterns") + } + + _, err := globutil.Compile(destServiceAcct.Server) + if err != nil { + return err + } + + _, err = globutil.Compile(destServiceAcct.Namespace) + if err != nil { + return err + } + key := fmt.Sprintf("%s/%s", destServiceAcct.Server, destServiceAcct.Namespace) if _, ok := destServiceAccts[key]; ok { return status.Errorf(codes.InvalidArgument, "destinationServiceAccount '%s' already added", key) diff --git a/util/glob/glob.go b/util/glob/glob.go index 0ef7cda28635a..b104d9a184318 100644 --- a/util/glob/glob.go +++ b/util/glob/glob.go @@ -13,3 +13,11 @@ func Match(pattern, text string, separators ...rune) bool { } return compiledGlob.Match(text) } + +func MatchWithError(pattern, text string, separators ...rune) (bool, error) { + compiledGlob, err := glob.Compile(pattern, separators...) + if err != nil { + return false, err + } + return compiledGlob.Match(text), nil +}