diff --git a/pkg/util/collections/includes_excludes.go b/pkg/util/collections/includes_excludes.go index 898d1a260..1f2128c71 100644 --- a/pkg/util/collections/includes_excludes.go +++ b/pkg/util/collections/includes_excludes.go @@ -164,21 +164,13 @@ func ValidateNamespaceIncludesExcludes(includesList, excludesList []string) []er excludes := sets.NewString(excludesList...) for _, itm := range includes.List() { - // Although asterisks is not a valid Kubernetes namespace name, it is - // allowed here. - if itm != "*" { - if nsErrs := validateNamespaceName(itm); nsErrs != nil { - errs = append(errs, nsErrs...) - } + if nsErrs := validateNamespaceName(itm); nsErrs != nil { + errs = append(errs, nsErrs...) } } - for _, itm := range excludes.List() { - // Asterisks in excludes list have been checked previously. - if itm != "*" { - if nsErrs := validateNamespaceName(itm); nsErrs != nil { - errs = append(errs, nsErrs...) - } + if nsErrs := validateNamespaceName(itm); nsErrs != nil { + errs = append(errs, nsErrs...) } } @@ -188,7 +180,12 @@ func ValidateNamespaceIncludesExcludes(includesList, excludesList []string) []er func validateNamespaceName(ns string) []error { var errs []error - if errMsgs := validation.ValidateNamespaceName(ns, false); errMsgs != nil { + // Kubernetes does not allow asterisks in namespaces but Velero uses them as + // wildcards. Replace asterisks with an arbitrary letter to pass Kubernetes + // validation. + tmpNamespace := strings.ReplaceAll(ns, "*", "x") + + if errMsgs := validation.ValidateNamespaceName(tmpNamespace, false); errMsgs != nil { for _, msg := range errMsgs { errs = append(errs, errors.Errorf("invalid namespace %q: %s", ns, msg)) } diff --git a/pkg/util/collections/includes_excludes_test.go b/pkg/util/collections/includes_excludes_test.go index a9841c25a..0ba885bd2 100644 --- a/pkg/util/collections/includes_excludes_test.go +++ b/pkg/util/collections/includes_excludes_test.go @@ -232,7 +232,7 @@ func TestValidateNamespaceIncludesExcludes(t *testing.T) { { name: "special characters in name is invalid", includes: []string{"foo?", "foo.bar", "bar_321"}, - excludes: []string{"$foo", "foo*bar", "bar=321"}, + excludes: []string{"$foo", "foo>bar", "bar=321"}, wantErr: true, }, { @@ -245,6 +245,18 @@ func TestValidateNamespaceIncludesExcludes(t *testing.T) { includes: []string{"*"}, wantErr: false, }, + { + name: "excludes can contain wildcard", + includes: []string{"foo", "bar"}, + excludes: []string{"nginx-ingress-*", "*-bar", "*-ingress-*"}, + wantErr: false, + }, + { + name: "includes can contain wildcard", + includes: []string{"*-foo", "kube-*", "*kube*"}, + excludes: []string{"bar"}, + wantErr: false, + }, { name: "include everything not allowed with other includes", includes: []string{"*", "foo"},