diff --git a/pkg/model/resource/gvk.go b/pkg/model/resource/gvk.go index 811edf1972..a17e7fd287 100644 --- a/pkg/model/resource/gvk.go +++ b/pkg/model/resource/gvk.go @@ -18,17 +18,24 @@ package resource import ( "fmt" + "regexp" "strings" "sigs.k8s.io/kubebuilder/v3/pkg/internal/validation" ) const ( + versionPattern = "^v\\d+(?:alpha\\d+|beta\\d+)?$" + groupRequired = "group cannot be empty if the domain is empty" versionRequired = "version cannot be empty" kindRequired = "kind cannot be empty" ) +var ( + versionRegex = regexp.MustCompile(versionPattern) +) + // GVK stores the Group - Version - Kind triplet that uniquely identifies a resource. // In kubebuilder, the k8s fully qualified group is stored as Group and Domain to improve UX. type GVK struct { @@ -53,9 +60,8 @@ func (gvk GVK) Validate() error { if gvk.Version == "" { return fmt.Errorf(versionRequired) } - if err := validation.IsDNS1035Label(gvk.Version); err != nil { - // NOTE: IsDNS1035Label returns a slice of strings instead of an error, so no wrapping - return fmt.Errorf("invalid Version: %#v", err) + if !versionRegex.MatchString(gvk.Version) { + return fmt.Errorf("Version must match %s (was %s)", versionPattern, gvk.Version) } // Check if kind has a valid DNS1035 label value diff --git a/pkg/model/resource/gvk_test.go b/pkg/model/resource/gvk_test.go index e04ff1c18a..8b93bef4dd 100644 --- a/pkg/model/resource/gvk_test.go +++ b/pkg/model/resource/gvk_test.go @@ -47,9 +47,13 @@ var _ = Describe("GVK", func() { Entry("Domain (non-alpha characters)", GVK{Group: group, Domain: "_*?", Version: version, Kind: kind}), Entry("Group and Domain (empty)", GVK{Group: "", Domain: "", Version: version, Kind: kind}), Entry("Version (empty)", GVK{Group: group, Domain: domain, Version: "", Kind: kind}), - Entry("Version (starts with number)", GVK{Group: group, Domain: domain, Version: "1", Kind: kind}), - Entry("Version (uppercase)", GVK{Group: group, Domain: domain, Version: "V1", Kind: kind}), - Entry("Version (non-alpha characters)", GVK{Group: group, Domain: domain, Version: "_*?", Kind: kind}), + Entry("Version (no v prefix)", GVK{Group: group, Domain: domain, Version: "1", Kind: kind}), + Entry("Version (wrong prefix)", GVK{Group: group, Domain: domain, Version: "a1", Kind: kind}), + Entry("Version (unstable no v prefix)", GVK{Group: group, Domain: domain, Version: "1beta1", Kind: kind}), + Entry("Version (unstable no alpha/beta number)", + GVK{Group: group, Domain: domain, Version: "v1beta", Kind: kind}), + Entry("Version (multiple unstable)", + GVK{Group: group, Domain: domain, Version: "v1beta1alpha1", Kind: kind}), Entry("Kind (empty)", GVK{Group: group, Domain: domain, Version: version, Kind: ""}), Entry("Kind (whitespaces)", GVK{Group: group, Domain: domain, Version: version, Kind: "Ki nd"}), Entry("Kind (lowercase)", GVK{Group: group, Domain: domain, Version: version, Kind: "kind"}),