diff --git a/docs/book/src/cronjob-tutorial/testdata/project/PROJECT b/docs/book/src/cronjob-tutorial/testdata/project/PROJECT index 573e2e5ff1f..95a8adf0e32 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/PROJECT +++ b/docs/book/src/cronjob-tutorial/testdata/project/PROJECT @@ -9,7 +9,6 @@ projectName: project repo: tutorial.kubebuilder.io/project resources: - api: - crdVersion: v1 namespaced: true controller: true domain: tutorial.kubebuilder.io @@ -20,5 +19,4 @@ resources: webhooks: defaulting: true validation: true - webhookVersion: v1 version: "3" diff --git a/docs/book/src/getting-started/testdata/project/PROJECT b/docs/book/src/getting-started/testdata/project/PROJECT index 628fed927e7..f1ed715f910 100644 --- a/docs/book/src/getting-started/testdata/project/PROJECT +++ b/docs/book/src/getting-started/testdata/project/PROJECT @@ -9,7 +9,6 @@ projectName: project repo: example.com/memcached resources: - api: - crdVersion: v1 namespaced: true controller: true domain: example.com diff --git a/docs/book/src/multiversion-tutorial/testdata/project/PROJECT b/docs/book/src/multiversion-tutorial/testdata/project/PROJECT index 867776e2af8..8ec8cf29c47 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/PROJECT +++ b/docs/book/src/multiversion-tutorial/testdata/project/PROJECT @@ -9,7 +9,6 @@ projectName: project repo: tutorial.kubebuilder.io/project resources: - api: - crdVersion: v1 namespaced: true controller: true domain: tutorial.kubebuilder.io @@ -20,9 +19,7 @@ resources: webhooks: defaulting: true validation: true - webhookVersion: v1 - api: - crdVersion: v1 namespaced: true domain: tutorial.kubebuilder.io group: batch @@ -33,5 +30,4 @@ resources: conversion: true defaulting: true validation: true - webhookVersion: v1 version: "3" diff --git a/pkg/cli/cli_test.go b/pkg/cli/cli_test.go index e2419518484..e82833e5bd2 100644 --- a/pkg/cli/cli_test.go +++ b/pkg/cli/cli_test.go @@ -99,8 +99,7 @@ layout: go.kubebuilder.io/v3 projectName: demo-zeus-operator repo: github.com/jmrodri/demo-zeus-operator resources: -- crdVersion: v1 - group: test +- group: test kind: Test version: v1 version: 3-alpha diff --git a/pkg/cli/resource_test.go b/pkg/cli/resource_test.go index f1d646ebded..0b935662b14 100644 --- a/pkg/cli/resource_test.go +++ b/pkg/cli/resource_test.go @@ -77,11 +77,9 @@ var _ = Describe("resourceOptions", func() { // Plural is checked in the next test Expect(resource.Path).To(Equal("")) Expect(resource.API).NotTo(BeNil()) - Expect(resource.API.CRDVersion).To(Equal("")) Expect(resource.API.Namespaced).To(BeFalse()) Expect(resource.Controller).To(BeFalse()) Expect(resource.Webhooks).NotTo(BeNil()) - Expect(resource.Webhooks.WebhookVersion).To(Equal("")) Expect(resource.Webhooks.Defaulting).To(BeFalse()) Expect(resource.Webhooks.Validation).To(BeFalse()) Expect(resource.Webhooks.Conversion).To(BeFalse()) diff --git a/pkg/config/interface.go b/pkg/config/interface.go index 9ce7da8ba24..144b1b8a8db 100644 --- a/pkg/config/interface.go +++ b/pkg/config/interface.go @@ -79,10 +79,6 @@ type Config interface { // HasGroup checks if the provided group is the same as any of the tracked resources. HasGroup(group string) bool - // ListCRDVersions returns a list of the CRD versions in use by the tracked resources. - ListCRDVersions() []string - // ListWebhookVersions returns a list of the webhook versions in use by the tracked resources. - ListWebhookVersions() []string /* Plugins */ diff --git a/pkg/config/v3/config.go b/pkg/config/v3/config.go index a3420bb3e64..4e0235772cc 100644 --- a/pkg/config/v3/config.go +++ b/pkg/config/v3/config.go @@ -253,42 +253,6 @@ func (c Cfg) HasGroup(group string) bool { return false } -// ListCRDVersions implements config.Config -func (c Cfg) ListCRDVersions() []string { - // Make a map to remove duplicates - versionSet := make(map[string]struct{}) - for _, r := range c.Resources { - if r.API != nil && r.API.CRDVersion != "" { - versionSet[r.API.CRDVersion] = struct{}{} - } - } - - // Convert the map into a slice - versions := make([]string, 0, len(versionSet)) - for version := range versionSet { - versions = append(versions, version) - } - return versions -} - -// ListWebhookVersions implements config.Config -func (c Cfg) ListWebhookVersions() []string { - // Make a map to remove duplicates - versionSet := make(map[string]struct{}) - for _, r := range c.Resources { - if r.Webhooks != nil && r.Webhooks.WebhookVersion != "" { - versionSet[r.Webhooks.WebhookVersion] = struct{}{} - } - } - - // Convert the map into a slice - versions := make([]string, 0, len(versionSet)) - for version := range versionSet { - versions = append(versions, version) - } - return versions -} - // DecodePluginConfig implements config.Config func (c Cfg) DecodePluginConfig(key string, configObj interface{}) error { if len(c.Plugins) == 0 { diff --git a/pkg/config/v3/config_test.go b/pkg/config/v3/config_test.go index 94a61c01055..4d774863dec 100644 --- a/pkg/config/v3/config_test.go +++ b/pkg/config/v3/config_test.go @@ -18,7 +18,6 @@ package v3 import ( "errors" - "sort" "testing" . "github.com/onsi/ginkgo/v2" @@ -145,15 +144,13 @@ var _ = Describe("Cfg", func() { Plural: "kinds", Path: "api/v1", API: &resource.API{ - CRDVersion: "v1", Namespaced: true, }, Controller: true, Webhooks: &resource.Webhooks{ - WebhookVersion: "v1", - Defaulting: true, - Validation: true, - Conversion: true, + Defaulting: true, + Validation: true, + Conversion: true, }, } resWithoutPlural = res.Copy() @@ -172,7 +169,6 @@ var _ = Describe("Cfg", func() { Expect(result.API).To(BeNil()) } else { Expect(result.API).NotTo(BeNil()) - Expect(result.API.CRDVersion).To(Equal(expected.API.CRDVersion)) Expect(result.API.Namespaced).To(Equal(expected.API.Namespaced)) } Expect(result.Controller).To(Equal(expected.Controller)) @@ -180,7 +176,6 @@ var _ = Describe("Cfg", func() { Expect(result.Webhooks).To(BeNil()) } else { Expect(result.Webhooks).NotTo(BeNil()) - Expect(result.Webhooks.WebhookVersion).To(Equal(expected.Webhooks.WebhookVersion)) Expect(result.Webhooks.Defaulting).To(Equal(expected.Webhooks.Defaulting)) Expect(result.Webhooks.Validation).To(Equal(expected.Webhooks.Validation)) Expect(result.Webhooks.Conversion).To(Equal(expected.Webhooks.Conversion)) @@ -283,62 +278,6 @@ var _ = Describe("Cfg", func() { c.Resources = append(c.Resources, res) Expect(c.HasGroup("other-group")).To(BeFalse()) }) - - It("ListCRDVersions should return an empty list with no tracked resources", func() { - Expect(c.ListCRDVersions()).To(BeEmpty()) - }) - - It("ListCRDVersions should return a list of tracked resources CRD versions", func() { - c.Resources = append(c.Resources, - resource.Resource{ - GVK: resource.GVK{ - Group: res.Group, - Version: res.Version, - Kind: res.Kind, - }, - API: &resource.API{CRDVersion: "v1beta1"}, - }, - resource.Resource{ - GVK: resource.GVK{ - Group: res.Group, - Version: res.Version, - Kind: "OtherKind", - }, - API: &resource.API{CRDVersion: "v1"}, - }, - ) - versions := c.ListCRDVersions() - sort.Strings(versions) // ListCRDVersions has no order guarantee so sorting for reproducibility - Expect(versions).To(Equal([]string{"v1", "v1beta1"})) - }) - - It("ListWebhookVersions should return an empty list with no tracked resources", func() { - Expect(c.ListWebhookVersions()).To(BeEmpty()) - }) - - It("ListWebhookVersions should return a list of tracked resources webhook versions", func() { - c.Resources = append(c.Resources, - resource.Resource{ - GVK: resource.GVK{ - Group: res.Group, - Version: res.Version, - Kind: res.Kind, - }, - Webhooks: &resource.Webhooks{WebhookVersion: "v1beta1"}, - }, - resource.Resource{ - GVK: resource.GVK{ - Group: res.Group, - Version: res.Version, - Kind: "OtherKind", - }, - Webhooks: &resource.Webhooks{WebhookVersion: "v1"}, - }, - ) - versions := c.ListWebhookVersions() - sort.Strings(versions) // ListWebhookVersions has no order guarantee so sorting for reproducibility - Expect(versions).To(Equal([]string{"v1", "v1beta1"})) - }) }) Context("Plugins", func() { @@ -461,9 +400,9 @@ var _ = Describe("Cfg", func() { Version: "v1", Kind: "Kind2", }, - API: &resource.API{CRDVersion: "v1"}, + API: &resource.API{}, Controller: true, - Webhooks: &resource.Webhooks{WebhookVersion: "v1"}, + Webhooks: &resource.Webhooks{}, }, { GVK: resource.GVK{ @@ -482,15 +421,13 @@ var _ = Describe("Cfg", func() { Kind: "Kind", }, API: &resource.API{ - CRDVersion: "v1", Namespaced: true, }, Controller: true, Webhooks: &resource.Webhooks{ - WebhookVersion: "v1", - Defaulting: true, - Validation: true, - Conversion: true, + Defaulting: true, + Validation: true, + Conversion: true, }, }, }, @@ -539,7 +476,6 @@ resources: kind: Kind version: v1 - api: - crdVersion: v1 controller: true group: group kind: Kind2 @@ -551,7 +487,6 @@ resources: plural: kindes version: v1-beta - api: - crdVersion: v1 namespaced: true controller: true group: group2 diff --git a/pkg/model/resource/api.go b/pkg/model/resource/api.go index 002205161ca..80fdbc504f9 100644 --- a/pkg/model/resource/api.go +++ b/pkg/model/resource/api.go @@ -16,26 +16,15 @@ limitations under the License. package resource -import ( - "fmt" -) - // API contains information about scaffolded APIs type API struct { - // CRDVersion holds the CustomResourceDefinition API version used for the resource. - CRDVersion string `json:"crdVersion,omitempty"` - // Namespaced is true if the API is namespaced. Namespaced bool `json:"namespaced,omitempty"` } // Validate checks that the API is valid. func (api API) Validate() error { - // Validate the CRD version - if err := validateAPIVersion(api.CRDVersion); err != nil { - return fmt.Errorf("invalid CRD version: %w", err) - } - + // TODO: Validate API return nil } @@ -53,15 +42,6 @@ func (api *API) Update(other *API) error { return nil } - // Update the version. - if other.CRDVersion != "" { - if api.CRDVersion == "" { - api.CRDVersion = other.CRDVersion - } else if api.CRDVersion != other.CRDVersion { - return fmt.Errorf("CRD versions do not match") - } - } - // Update the namespace. api.Namespaced = api.Namespaced || other.Namespaced @@ -70,5 +50,5 @@ func (api *API) Update(other *API) error { // IsEmpty returns if the API's fields all contain zero-values. func (api API) IsEmpty() bool { - return api.CRDVersion == "" && !api.Namespaced + return !api.Namespaced } diff --git a/pkg/model/resource/api_test.go b/pkg/model/resource/api_test.go index fbce493e50a..07b5a94e043 100644 --- a/pkg/model/resource/api_test.go +++ b/pkg/model/resource/api_test.go @@ -25,14 +25,13 @@ import ( var _ = Describe("API", func() { Context("Validate", func() { It("should succeed for a valid API", func() { - Expect(API{CRDVersion: v1}.Validate()).To(Succeed()) + Expect(API{Namespaced: false}.Validate()).To(Succeed()) }) DescribeTable("should fail for invalid APIs", func(api API) { Expect(api.Validate()).NotTo(Succeed()) }, // Ensure that the rest of the fields are valid to check each part Entry("empty CRD version", API{}), - Entry("invalid CRD version", API{CRDVersion: "1"}), ) }) @@ -42,47 +41,15 @@ var _ = Describe("API", func() { It("should do nothing if provided a nil pointer", func() { api = API{} Expect(api.Update(nil)).To(Succeed()) - Expect(api.CRDVersion).To(Equal("")) Expect(api.Namespaced).To(BeFalse()) api = API{ - CRDVersion: v1, Namespaced: true, } Expect(api.Update(nil)).To(Succeed()) - Expect(api.CRDVersion).To(Equal(v1)) Expect(api.Namespaced).To(BeTrue()) }) - Context("CRD version", func() { - It("should modify the CRD version if provided and not previously set", func() { - api = API{} - other = API{CRDVersion: v1} - Expect(api.Update(&other)).To(Succeed()) - Expect(api.CRDVersion).To(Equal(v1)) - }) - - It("should keep the CRD version if not provided", func() { - api = API{CRDVersion: v1} - other = API{} - Expect(api.Update(&other)).To(Succeed()) - Expect(api.CRDVersion).To(Equal(v1)) - }) - - It("should keep the CRD version if provided the same as previously set", func() { - api = API{CRDVersion: v1} - other = API{CRDVersion: v1} - Expect(api.Update(&other)).To(Succeed()) - Expect(api.CRDVersion).To(Equal(v1)) - }) - - It("should fail if previously set and provided CRD versions do not match", func() { - api = API{CRDVersion: v1} - other = API{CRDVersion: "v1beta1"} - Expect(api.Update(&other)).NotTo(Succeed()) - }) - }) - Context("Namespaced", func() { It("should set the namespace scope if provided and not previously set", func() { api = API{} @@ -116,12 +83,9 @@ var _ = Describe("API", func() { Context("IsEmpty", func() { var ( - none = API{} - cluster = API{ - CRDVersion: v1, - } + none = API{} + cluster = API{} namespaced = API{ - CRDVersion: v1, Namespaced: true, } ) diff --git a/pkg/model/resource/resource.go b/pkg/model/resource/resource.go index 7d4a9c40929..bd4855be575 100644 --- a/pkg/model/resource/resource.go +++ b/pkg/model/resource/resource.go @@ -57,8 +57,6 @@ func (r Resource) Validate() error { return fmt.Errorf("invalid Plural: %#v", errors) } - // TODO: validate the path - // Validate the API if r.API != nil && !r.API.IsEmpty() { if err := r.API.Validate(); err != nil { @@ -85,7 +83,7 @@ func (r Resource) PackageName() string { return safeImport(r.Group) } -// ImportAlias returns a identifier usable as an import alias for this resource. +// ImportAlias returns an identifier usable as an import alias for this resource. func (r Resource) ImportAlias() string { if r.Group == "" { return safeImport(r.Domain + r.Version) @@ -96,7 +94,7 @@ func (r Resource) ImportAlias() string { // HasAPI returns true if the resource has an associated API. func (r Resource) HasAPI() bool { - return r.API != nil && r.API.CRDVersion != "" + return r.API != nil } // HasController returns true if the resource has an associated controller. diff --git a/pkg/model/resource/resource_test.go b/pkg/model/resource/resource_test.go index 5935d02e2f9..56861e09f8c 100644 --- a/pkg/model/resource/resource_test.go +++ b/pkg/model/resource/resource_test.go @@ -55,8 +55,8 @@ var _ = Describe("Resource", func() { // Ensure that the rest of the fields are valid to check each part Entry("invalid GVK", Resource{GVK: GVK{}, Plural: "plural"}), Entry("invalid Plural", Resource{GVK: gvk, Plural: "Plural"}), - Entry("invalid API", Resource{GVK: gvk, Plural: "plural", API: &API{CRDVersion: "1"}}), - Entry("invalid Webhooks", Resource{GVK: gvk, Plural: "plural", Webhooks: &Webhooks{WebhookVersion: "1"}}), + Entry("invalid API", Resource{GVK: gvk, Plural: "plural", API: &API{}}), + Entry("invalid Webhooks", Resource{GVK: gvk, Plural: "plural", Webhooks: &Webhooks{}}), ) }) @@ -126,7 +126,7 @@ var _ = Describe("Resource", func() { Context("part check", func() { Context("HasAPI", func() { It("should return true if the API is scaffolded", func() { - Expect(Resource{API: &API{CRDVersion: "v1"}}.HasAPI()).To(BeTrue()) + Expect(Resource{API: &API{Namespaced: true}}.HasAPI()).To(BeTrue()) }) DescribeTable("should return false if the API is not scaffolded", @@ -195,9 +195,7 @@ var _ = Describe("Resource", func() { Context("Copy", func() { const ( - path = "api/v1" - crdVersion = "v1" - webhookVersion = "v1" + path = "api/v1" ) res := Resource{ @@ -205,15 +203,13 @@ var _ = Describe("Resource", func() { Plural: plural, Path: path, API: &API{ - CRDVersion: crdVersion, Namespaced: true, }, Controller: true, Webhooks: &Webhooks{ - WebhookVersion: webhookVersion, - Defaulting: true, - Validation: true, - Conversion: true, + Defaulting: true, + Validation: true, + Conversion: true, }, } @@ -226,11 +222,9 @@ var _ = Describe("Resource", func() { Expect(other.Plural).To(Equal(res.Plural)) Expect(other.Path).To(Equal(res.Path)) Expect(other.API).NotTo(BeNil()) - Expect(other.API.CRDVersion).To(Equal(res.API.CRDVersion)) Expect(other.API.Namespaced).To(Equal(res.API.Namespaced)) Expect(other.Controller).To(Equal(res.Controller)) Expect(other.Webhooks).NotTo(BeNil()) - Expect(other.Webhooks.WebhookVersion).To(Equal(res.Webhooks.WebhookVersion)) Expect(other.Webhooks.Defaulting).To(Equal(res.Webhooks.Defaulting)) Expect(other.Webhooks.Validation).To(Equal(res.Webhooks.Validation)) Expect(other.Webhooks.Conversion).To(Equal(res.Webhooks.Conversion)) @@ -244,11 +238,9 @@ var _ = Describe("Resource", func() { other.Kind = "kind2" other.Plural = "kind2s" other.Path = "api/v2" - other.API.CRDVersion = v1beta1 other.API.Namespaced = false other.API = nil // Change fields before changing pointer other.Controller = false - other.Webhooks.WebhookVersion = v1beta1 other.Webhooks.Defaulting = false other.Webhooks.Validation = false other.Webhooks.Conversion = false @@ -261,11 +253,9 @@ var _ = Describe("Resource", func() { Expect(res.Plural).To(Equal(plural)) Expect(res.Path).To(Equal(path)) Expect(res.API).NotTo(BeNil()) - Expect(res.API.CRDVersion).To(Equal(crdVersion)) Expect(res.API.Namespaced).To(BeTrue()) Expect(res.Controller).To(BeTrue()) Expect(res.Webhooks).NotTo(BeNil()) - Expect(res.Webhooks.WebhookVersion).To(Equal(webhookVersion)) Expect(res.Webhooks.Defaulting).To(BeTrue()) Expect(res.Webhooks.Validation).To(BeTrue()) Expect(res.Webhooks.Conversion).To(BeTrue()) @@ -333,21 +323,17 @@ var _ = Describe("Resource", func() { r = Resource{GVK: gvk} other = Resource{ GVK: gvk, - API: &API{CRDVersion: v1}, } Expect(r.Update(other)).To(Succeed()) Expect(r.API).NotTo(BeNil()) - Expect(r.API.CRDVersion).To(Equal(v1)) }) It("should fail if API.Update fails", func() { r = Resource{ GVK: gvk, - API: &API{CRDVersion: v1}, } other = Resource{ GVK: gvk, - API: &API{CRDVersion: v1beta1}, } Expect(r.Update(other)).NotTo(Succeed()) }) @@ -398,22 +384,18 @@ var _ = Describe("Resource", func() { It("should work with nil Webhooks", func() { r = Resource{GVK: gvk} other = Resource{ - GVK: gvk, - Webhooks: &Webhooks{WebhookVersion: v1}, + GVK: gvk, } Expect(r.Update(other)).To(Succeed()) Expect(r.Webhooks).NotTo(BeNil()) - Expect(r.Webhooks.WebhookVersion).To(Equal(v1)) }) It("should fail if Webhooks.Update fails", func() { r = Resource{ - GVK: gvk, - Webhooks: &Webhooks{WebhookVersion: v1}, + GVK: gvk, } other = Resource{ - GVK: gvk, - Webhooks: &Webhooks{WebhookVersion: v1beta1}, + GVK: gvk, } Expect(r.Update(other)).NotTo(Succeed()) }) diff --git a/pkg/model/resource/webhooks.go b/pkg/model/resource/webhooks.go index 6d8bc0378aa..f19432d02cf 100644 --- a/pkg/model/resource/webhooks.go +++ b/pkg/model/resource/webhooks.go @@ -16,15 +16,8 @@ limitations under the License. package resource -import ( - "fmt" -) - // Webhooks contains information about scaffolded webhooks type Webhooks struct { - // WebhookVersion holds the {Validating,Mutating}WebhookConfiguration API version used for the resource. - WebhookVersion string `json:"webhookVersion,omitempty"` - // Defaulting specifies if a defaulting webhook is associated to the resource. Defaulting bool `json:"defaulting,omitempty"` @@ -37,11 +30,7 @@ type Webhooks struct { // Validate checks that the Webhooks is valid. func (webhooks Webhooks) Validate() error { - // Validate the Webhook version - if err := validateAPIVersion(webhooks.WebhookVersion); err != nil { - return fmt.Errorf("invalid Webhook version: %w", err) - } - + // TODO: Validate Webhooks return nil } @@ -59,15 +48,6 @@ func (webhooks *Webhooks) Update(other *Webhooks) error { return nil } - // Update the version. - if other.WebhookVersion != "" { - if webhooks.WebhookVersion == "" { - webhooks.WebhookVersion = other.WebhookVersion - } else if webhooks.WebhookVersion != other.WebhookVersion { - return fmt.Errorf("webhook versions do not match") - } - } - // Update defaulting. webhooks.Defaulting = webhooks.Defaulting || other.Defaulting @@ -82,5 +62,5 @@ func (webhooks *Webhooks) Update(other *Webhooks) error { // IsEmpty returns if the Webhooks' fields all contain zero-values. func (webhooks Webhooks) IsEmpty() bool { - return webhooks.WebhookVersion == "" && !webhooks.Defaulting && !webhooks.Validation && !webhooks.Conversion + return !webhooks.Defaulting && !webhooks.Validation && !webhooks.Conversion } diff --git a/pkg/model/resource/webhooks_test.go b/pkg/model/resource/webhooks_test.go index 4b0d6bd9132..4c569393095 100644 --- a/pkg/model/resource/webhooks_test.go +++ b/pkg/model/resource/webhooks_test.go @@ -23,72 +23,27 @@ import ( //nolint:dupl var _ = Describe("Webhooks", func() { - Context("Validate", func() { - It("should succeed for a valid Webhooks", func() { - Expect(Webhooks{WebhookVersion: v1}.Validate()).To(Succeed()) - }) - - DescribeTable("should fail for invalid Webhooks", - func(webhooks Webhooks) { Expect(webhooks.Validate()).NotTo(Succeed()) }, - // Ensure that the rest of the fields are valid to check each part - Entry("empty webhook version", Webhooks{}), - Entry("invalid webhook version", Webhooks{WebhookVersion: "1"}), - ) - }) - Context("Update", func() { var webhook, other Webhooks It("should do nothing if provided a nil pointer", func() { webhook = Webhooks{} Expect(webhook.Update(nil)).To(Succeed()) - Expect(webhook.WebhookVersion).To(Equal("")) Expect(webhook.Defaulting).To(BeFalse()) Expect(webhook.Validation).To(BeFalse()) Expect(webhook.Conversion).To(BeFalse()) webhook = Webhooks{ - WebhookVersion: v1, - Defaulting: true, - Validation: true, - Conversion: true, + Defaulting: true, + Validation: true, + Conversion: true, } Expect(webhook.Update(nil)).To(Succeed()) - Expect(webhook.WebhookVersion).To(Equal(v1)) Expect(webhook.Defaulting).To(BeTrue()) Expect(webhook.Validation).To(BeTrue()) Expect(webhook.Conversion).To(BeTrue()) }) - Context("webhooks version", func() { - It("should modify the webhooks version if provided and not previously set", func() { - webhook = Webhooks{} - other = Webhooks{WebhookVersion: v1} - Expect(webhook.Update(&other)).To(Succeed()) - Expect(webhook.WebhookVersion).To(Equal(v1)) - }) - - It("should keep the webhooks version if not provided", func() { - webhook = Webhooks{WebhookVersion: v1} - other = Webhooks{} - Expect(webhook.Update(&other)).To(Succeed()) - Expect(webhook.WebhookVersion).To(Equal(v1)) - }) - - It("should keep the webhooks version if provided the same as previously set", func() { - webhook = Webhooks{WebhookVersion: v1} - other = Webhooks{WebhookVersion: v1} - Expect(webhook.Update(&other)).To(Succeed()) - Expect(webhook.WebhookVersion).To(Equal(v1)) - }) - - It("should fail if previously set and provided webhooks versions do not match", func() { - webhook = Webhooks{WebhookVersion: v1} - other = Webhooks{WebhookVersion: "v1beta1"} - Expect(webhook.Update(&other)).NotTo(Succeed()) - }) - }) - Context("Defaulting", func() { It("should set the defaulting webhook if provided and not previously set", func() { webhook = Webhooks{} @@ -184,46 +139,39 @@ var _ = Describe("Webhooks", func() { var ( none = Webhooks{} defaulting = Webhooks{ - WebhookVersion: "v1", - Defaulting: true, - Validation: false, - Conversion: false, + Defaulting: true, + Validation: false, + Conversion: false, } validation = Webhooks{ - WebhookVersion: "v1", - Defaulting: false, - Validation: true, - Conversion: false, + Defaulting: false, + Validation: true, + Conversion: false, } conversion = Webhooks{ - WebhookVersion: "v1", - Defaulting: false, - Validation: false, - Conversion: true, + Defaulting: false, + Validation: false, + Conversion: true, } defaultingAndValidation = Webhooks{ - WebhookVersion: "v1", - Defaulting: true, - Validation: true, - Conversion: false, + Defaulting: true, + Validation: true, + Conversion: false, } defaultingAndConversion = Webhooks{ - WebhookVersion: "v1", - Defaulting: true, - Validation: false, - Conversion: true, + Defaulting: true, + Validation: false, + Conversion: true, } validationAndConversion = Webhooks{ - WebhookVersion: "v1", - Defaulting: false, - Validation: true, - Conversion: true, + Defaulting: false, + Validation: true, + Conversion: true, } all = Webhooks{ - WebhookVersion: "v1", - Defaulting: true, - Validation: true, - Conversion: true, + Defaulting: true, + Validation: true, + Conversion: true, } ) diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go index b327b2de2ce..307a2f5ad73 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault/enablecainection_patch.go @@ -47,7 +47,7 @@ func (f *WebhookCAInjectionPatch) SetTemplateDefaults() error { const injectCAPatchTemplate = `# This patch add annotation to admission webhook config and # CERTIFICATE_NAMESPACE and CERTIFICATE_NAME will be substituted by kustomize -apiVersion: admissionregistration.k8s.io/{{ .Resource.Webhooks.WebhookVersion }} +apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: labels: @@ -57,7 +57,7 @@ metadata: annotations: cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME --- -apiVersion: admissionregistration.k8s.io/{{ .Resource.Webhooks.WebhookVersion }} +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: labels: diff --git a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/kustomization.go b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/kustomization.go index 29048544107..7bcd6993916 100644 --- a/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/kustomization.go +++ b/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/webhook/kustomization.go @@ -51,7 +51,7 @@ func (f *Kustomization) SetTemplateDefaults() error { } const kustomizeWebhookTemplate = `resources: -- manifests{{ if ne .Resource.Webhooks.WebhookVersion "v1" }}.{{ .Resource.Webhooks.WebhookVersion }}{{ end }}.yaml +- manifests.yaml - service.yaml configurations: diff --git a/pkg/plugins/golang/options.go b/pkg/plugins/golang/options.go index 865f6137949..7c43eeb339f 100644 --- a/pkg/plugins/golang/options.go +++ b/pkg/plugins/golang/options.go @@ -78,7 +78,6 @@ func (opts Options) UpdateResource(res *resource.Resource, c config.Config) { res.Path = resource.APIPackagePath(c.GetRepository(), res.Group, res.Version, c.IsMultiGroup()) res.API = &resource.API{ - CRDVersion: "v1", Namespaced: opts.Namespaced, } @@ -92,7 +91,6 @@ func (opts Options) UpdateResource(res *resource.Resource, c config.Config) { //nolint:staticcheck res.Path = resource.APIPackagePath(c.GetRepository(), res.Group, res.Version, c.IsMultiGroup()) - res.Webhooks.WebhookVersion = "v1" if opts.DoDefaulting { res.Webhooks.Defaulting = true } diff --git a/pkg/plugins/golang/v4/scaffolds/internal/templates/api/webhook.go b/pkg/plugins/golang/v4/scaffolds/internal/templates/api/webhook.go index 25b6ae1d830..5b2fe8f05a2 100644 --- a/pkg/plugins/golang/v4/scaffolds/internal/templates/api/webhook.go +++ b/pkg/plugins/golang/v4/scaffolds/internal/templates/api/webhook.go @@ -121,7 +121,7 @@ func (r *{{ .Resource.Kind }}) SetupWebhookWithManager(mgr ctrl.Manager) error { //nolint:lll defaultingWebhookTemplate = ` -// +kubebuilder:webhook:{{ if ne .Resource.Webhooks.WebhookVersion "v1" }}webhookVersions={{"{"}}{{ .Resource.Webhooks.WebhookVersion }}{{"}"}},{{ end }}path=/mutate-{{ .QualifiedGroupWithDash }}-{{ .Resource.Version }}-{{ lower .Resource.Kind }},mutating=true,failurePolicy=fail,sideEffects=None,groups={{ .Resource.QualifiedGroup }},resources={{ .Resource.Plural }},verbs=create;update,versions={{ .Resource.Version }},name=m{{ lower .Resource.Kind }}-{{ .Resource.Version }}.kb.io,admissionReviewVersions={{ .AdmissionReviewVersions }} +// +kubebuilder:webhook:path=/mutate-{{ .QualifiedGroupWithDash }}-{{ .Resource.Version }}-{{ lower .Resource.Kind }},mutating=true,failurePolicy=fail,sideEffects=None,groups={{ .Resource.QualifiedGroup }},resources={{ .Resource.Plural }},verbs=create;update,versions={{ .Resource.Version }},name=m{{ lower .Resource.Kind }}-{{ .Resource.Version }}.kb.io,admissionReviewVersions={{ .AdmissionReviewVersions }} // +kubebuilder:object:generate=false // {{ .Resource.Kind }}CustomDefaulter struct is responsible for setting default values on the custom resource of the @@ -154,7 +154,7 @@ func (d *{{ .Resource.Kind }}CustomDefaulter) Default(ctx context.Context, obj r // TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. // NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. // Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. -// +kubebuilder:webhook:{{ if ne .Resource.Webhooks.WebhookVersion "v1" }}webhookVersions={{"{"}}{{ .Resource.Webhooks.WebhookVersion }}{{"}"}},{{ end }}path=/validate-{{ .QualifiedGroupWithDash }}-{{ .Resource.Version }}-{{ lower .Resource.Kind }},mutating=false,failurePolicy=fail,sideEffects=None,groups={{ .Resource.QualifiedGroup }},resources={{ .Resource.Plural }},verbs=create;update,versions={{ .Resource.Version }},name=v{{ lower .Resource.Kind }}-{{ .Resource.Version }}.kb.io,admissionReviewVersions={{ .AdmissionReviewVersions }} +// +kubebuilder:webhook:path=/validate-{{ .QualifiedGroupWithDash }}-{{ .Resource.Version }}-{{ lower .Resource.Kind }},mutating=false,failurePolicy=fail,sideEffects=None,groups={{ .Resource.QualifiedGroup }},resources={{ .Resource.Plural }},verbs=create;update,versions={{ .Resource.Version }},name=v{{ lower .Resource.Kind }}-{{ .Resource.Version }}.kb.io,admissionReviewVersions={{ .AdmissionReviewVersions }} // +kubebuilder:object:generate=false // {{ .Resource.Kind }}CustomValidator struct is responsible for validating the {{ .Resource.Kind }} resource diff --git a/test/e2e/alphagenerate/generate_test.go b/test/e2e/alphagenerate/generate_test.go index fb93663f0f9..77305ab0410 100644 --- a/test/e2e/alphagenerate/generate_test.go +++ b/test/e2e/alphagenerate/generate_test.go @@ -223,7 +223,6 @@ func ReGenerateProject(kbc *utils.TestContext) { By("checking if the project file was generated without namespace: true") var nonNamespacedFields = fmt.Sprintf(`api: - crdVersion: v1 controller: true domain: %s group: crew diff --git a/testdata/project-v4-multigroup/PROJECT b/testdata/project-v4-multigroup/PROJECT index ea5536b0583..7abe384f77f 100644 --- a/testdata/project-v4-multigroup/PROJECT +++ b/testdata/project-v4-multigroup/PROJECT @@ -29,7 +29,6 @@ projectName: project-v4-multigroup repo: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup resources: - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org @@ -40,9 +39,7 @@ resources: webhooks: defaulting: true validation: true - webhookVersion: v1 - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org @@ -52,10 +49,7 @@ resources: version: v1beta1 webhooks: conversion: true - webhookVersion: v1 -- api: - crdVersion: v1 - controller: true +- controller: true domain: testproject.org group: ship kind: Destroyer @@ -63,10 +57,7 @@ resources: version: v1 webhooks: defaulting: true - webhookVersion: v1 -- api: - crdVersion: v1 - controller: true +- controller: true domain: testproject.org group: ship kind: Cruiser @@ -74,9 +65,7 @@ resources: version: v2alpha1 webhooks: validation: true - webhookVersion: v1 - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org @@ -85,7 +74,6 @@ resources: path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta1 version: v1beta1 - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org @@ -94,7 +82,6 @@ resources: path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/sea-creatures/v1beta2 version: v1beta2 - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org @@ -108,7 +95,6 @@ resources: path: k8s.io/api/apps/v1 version: v1 - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org @@ -117,7 +103,6 @@ resources: path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo/v1 version: v1 - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org @@ -126,7 +111,6 @@ resources: path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/fiz/v1 version: v1 - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org @@ -136,9 +120,7 @@ resources: version: v1alpha1 webhooks: validation: true - webhookVersion: v1 - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org diff --git a/testdata/project-v4-multigroup/api/apps/v1/deployment_types.go b/testdata/project-v4-multigroup/api/apps/v1/deployment_types.go new file mode 100644 index 00000000000..e059451ab27 --- /dev/null +++ b/testdata/project-v4-multigroup/api/apps/v1/deployment_types.go @@ -0,0 +1,65 @@ +/* +Copyright 2024 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// DeploymentSpec defines the desired state of Deployment. +type DeploymentSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Deployment. Edit deployment_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// DeploymentStatus defines the observed state of Deployment. +type DeploymentStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Cluster + +// Deployment is the Schema for the deployments API. +type Deployment struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec DeploymentSpec `json:"spec,omitempty"` + Status DeploymentStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// DeploymentList contains a list of Deployment. +type DeploymentList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Deployment `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Deployment{}, &DeploymentList{}) +} diff --git a/testdata/project-v4-multigroup/api/apps/v1/groupversion_info.go b/testdata/project-v4-multigroup/api/apps/v1/groupversion_info.go new file mode 100644 index 00000000000..4d2bc7470c7 --- /dev/null +++ b/testdata/project-v4-multigroup/api/apps/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2024 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1 contains API Schema definitions for the apps v1 API group. +// +kubebuilder:object:generate=true +// +groupName=apps +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "apps", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/testdata/project-v4-multigroup/api/apps/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/apps/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..33333829d1d --- /dev/null +++ b/testdata/project-v4-multigroup/api/apps/v1/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2024 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Deployment) DeepCopyInto(out *Deployment) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Deployment. +func (in *Deployment) DeepCopy() *Deployment { + if in == nil { + return nil + } + out := new(Deployment) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Deployment) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeploymentList) DeepCopyInto(out *DeploymentList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Deployment, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentList. +func (in *DeploymentList) DeepCopy() *DeploymentList { + if in == nil { + return nil + } + out := new(DeploymentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DeploymentList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentSpec. +func (in *DeploymentSpec) DeepCopy() *DeploymentSpec { + if in == nil { + return nil + } + out := new(DeploymentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStatus. +func (in *DeploymentStatus) DeepCopy() *DeploymentStatus { + if in == nil { + return nil + } + out := new(DeploymentStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-multigroup/cmd/main.go b/testdata/project-v4-multigroup/cmd/main.go index e7dc7e0a55e..09fa785b124 100644 --- a/testdata/project-v4-multigroup/cmd/main.go +++ b/testdata/project-v4-multigroup/cmd/main.go @@ -35,6 +35,8 @@ import ( metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" + appsv1 "k8s.io/api/apps/v1" + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/crew/v1" examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" fizv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/fiz/v1" @@ -71,6 +73,7 @@ func init() { utilruntime.Must(seacreaturesv1beta1.AddToScheme(scheme)) utilruntime.Must(seacreaturesv1beta2.AddToScheme(scheme)) utilruntime.Must(foopolicyv1.AddToScheme(scheme)) + utilruntime.Must(appsv1.AddToScheme(scheme)) utilruntime.Must(foov1.AddToScheme(scheme)) utilruntime.Must(fizv1.AddToScheme(scheme)) utilruntime.Must(examplecomv1alpha1.AddToScheme(scheme)) diff --git a/testdata/project-v4-multigroup/config/crd/bases/apps_deployments.yaml b/testdata/project-v4-multigroup/config/crd/bases/apps_deployments.yaml new file mode 100644 index 00000000000..0e26c9dcc1b --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/bases/apps_deployments.yaml @@ -0,0 +1,54 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: deployments.apps +spec: + group: apps + names: + kind: Deployment + listKind: DeploymentList + plural: deployments + singular: deployment + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Deployment is the Schema for the deployments API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: DeploymentSpec defines the desired state of Deployment. + properties: + foo: + description: Foo is an example field of Deployment. Edit deployment_types.go + to remove/update + type: string + type: object + status: + description: DeploymentStatus defines the observed state of Deployment. + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testdata/project-v4-multigroup/config/crd/kustomization.yaml b/testdata/project-v4-multigroup/config/crd/kustomization.yaml index 6b362727dd7..e46ad9755de 100644 --- a/testdata/project-v4-multigroup/config/crd/kustomization.yaml +++ b/testdata/project-v4-multigroup/config/crd/kustomization.yaml @@ -9,6 +9,7 @@ resources: - bases/sea-creatures.testproject.org_krakens.yaml - bases/sea-creatures.testproject.org_leviathans.yaml - bases/foo.policy.testproject.org_healthcheckpolicies.yaml +- bases/apps_deployments.yaml - bases/foo.testproject.org_bars.yaml - bases/fiz.testproject.org_bars.yaml - bases/example.com.testproject.org_memcacheds.yaml @@ -34,6 +35,7 @@ patches: #- path: patches/cainjection_in_sea-creatures_krakens.yaml #- path: patches/cainjection_in_sea-creatures_leviathans.yaml #- path: patches/cainjection_in_foo.policy_healthcheckpolicies.yaml +#- path: patches/cainjection_in_apps_deployments.yaml #- path: patches/cainjection_in_foo_bars.yaml #- path: patches/cainjection_in_fiz_bars.yaml #- path: patches/cainjection_in_example.com_memcacheds.yaml diff --git a/testdata/project-v4-multigroup/config/rbac/apps_deployment_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/apps_deployment_editor_role.yaml new file mode 100644 index 00000000000..6ea21b144c8 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/apps_deployment_editor_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to edit deployments. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: project-v4-multigroup + app.kubernetes.io/managed-by: kustomize + name: apps-deployment-editor-role +rules: +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get diff --git a/testdata/project-v4-multigroup/config/rbac/apps_deployment_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/apps_deployment_viewer_role.yaml new file mode 100644 index 00000000000..b7073a4575d --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/apps_deployment_viewer_role.yaml @@ -0,0 +1,23 @@ +# permissions for end users to view deployments. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: project-v4-multigroup + app.kubernetes.io/managed-by: kustomize + name: apps-deployment-viewer-role +rules: +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get diff --git a/testdata/project-v4-multigroup/config/rbac/kustomization.yaml b/testdata/project-v4-multigroup/config/rbac/kustomization.yaml index bbf5c747bb5..930330cb406 100644 --- a/testdata/project-v4-multigroup/config/rbac/kustomization.yaml +++ b/testdata/project-v4-multigroup/config/rbac/kustomization.yaml @@ -30,6 +30,8 @@ resources: - fiz_bar_viewer_role.yaml - foo_bar_editor_role.yaml - foo_bar_viewer_role.yaml +- apps_deployment_editor_role.yaml +- apps_deployment_viewer_role.yaml - foo.policy_healthcheckpolicy_editor_role.yaml - foo.policy_healthcheckpolicy_viewer_role.yaml - sea-creatures_leviathan_editor_role.yaml diff --git a/testdata/project-v4-multigroup/config/samples/apps_v1_deployment.yaml b/testdata/project-v4-multigroup/config/samples/apps_v1_deployment.yaml new file mode 100644 index 00000000000..3024ec5cc5a --- /dev/null +++ b/testdata/project-v4-multigroup/config/samples/apps_v1_deployment.yaml @@ -0,0 +1,9 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: project-v4-multigroup + app.kubernetes.io/managed-by: kustomize + name: deployment-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/kustomization.yaml b/testdata/project-v4-multigroup/config/samples/kustomization.yaml index cffe4bc820a..5c3f4eb79ae 100644 --- a/testdata/project-v4-multigroup/config/samples/kustomization.yaml +++ b/testdata/project-v4-multigroup/config/samples/kustomization.yaml @@ -7,6 +7,7 @@ resources: - sea-creatures_v1beta1_kraken.yaml - sea-creatures_v1beta2_leviathan.yaml - foo.policy_v1_healthcheckpolicy.yaml +- apps_v1_deployment.yaml - foo_v1_bar.yaml - fiz_v1_bar.yaml - example.com_v1alpha1_memcached.yaml diff --git a/testdata/project-v4-multigroup/dist/install.yaml b/testdata/project-v4-multigroup/dist/install.yaml index 05a31522eeb..cd0daefdd2b 100644 --- a/testdata/project-v4-multigroup/dist/install.yaml +++ b/testdata/project-v4-multigroup/dist/install.yaml @@ -361,6 +361,60 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: deployments.apps +spec: + group: apps + names: + kind: Deployment + listKind: DeploymentList + plural: deployments + singular: deployment + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Deployment is the Schema for the deployments API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: DeploymentSpec defines the desired state of Deployment. + properties: + foo: + description: Foo is an example field of Deployment. Edit deployment_types.go + to remove/update + type: string + type: object + status: + description: DeploymentStatus defines the observed state of Deployment. + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.16.1 @@ -832,6 +886,56 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: project-v4-multigroup + name: project-v4-multigroup-apps-deployment-editor-role +rules: +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: project-v4-multigroup + name: project-v4-multigroup-apps-deployment-viewer-role +rules: +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: labels: app.kubernetes.io/managed-by: kustomize diff --git a/testdata/project-v4-multigroup/internal/controller/apps/deployment_controller_test.go b/testdata/project-v4-multigroup/internal/controller/apps/deployment_controller_test.go index 339a1532026..2939d6ed208 100644 --- a/testdata/project-v4-multigroup/internal/controller/apps/deployment_controller_test.go +++ b/testdata/project-v4-multigroup/internal/controller/apps/deployment_controller_test.go @@ -17,14 +17,65 @@ limitations under the License. package apps import ( + "context" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var _ = Describe("Deployment Controller", func() { Context("When reconciling a resource", func() { + const resourceName = "test-resource" + + ctx := context.Background() + + typeNamespacedName := types.NamespacedName{ + Name: resourceName, + Namespace: "default", // TODO(user):Modify as needed + } + deployment := &appsv1.Deployment{} + BeforeEach(func() { + By("creating the custom resource for the Kind Deployment") + err := k8sClient.Get(ctx, typeNamespacedName, deployment) + if err != nil && errors.IsNotFound(err) { + resource := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: resourceName, + Namespace: "default", + }, + // TODO(user): Specify other spec details if needed. + } + Expect(k8sClient.Create(ctx, resource)).To(Succeed()) + } + }) + + AfterEach(func() { + // TODO(user): Cleanup logic after each test, like removing the resource instance. + resource := &appsv1.Deployment{} + err := k8sClient.Get(ctx, typeNamespacedName, resource) + Expect(err).NotTo(HaveOccurred()) + + By("Cleanup the specific resource instance Deployment") + Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) + }) It("should successfully reconcile the resource", func() { + By("Reconciling the created resource") + controllerReconciler := &DeploymentReconciler{ + Client: k8sClient, + Scheme: k8sClient.Scheme(), + } + _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ + NamespacedName: typeNamespacedName, + }) + Expect(err).NotTo(HaveOccurred()) // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. // Example: If you expect a certain status condition after reconciliation, verify it here. }) diff --git a/testdata/project-v4-multigroup/internal/controller/apps/suite_test.go b/testdata/project-v4-multigroup/internal/controller/apps/suite_test.go index 8d7a448f9e8..452f333db90 100644 --- a/testdata/project-v4-multigroup/internal/controller/apps/suite_test.go +++ b/testdata/project-v4-multigroup/internal/controller/apps/suite_test.go @@ -59,7 +59,7 @@ var _ = BeforeSuite(func() { By("bootstrapping test environment") testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, + ErrorIfCRDPathMissing: true, // The BinaryAssetsDirectory is only required if you want to run the tests directly // without call the makefile target test. If not informed it will look for the diff --git a/testdata/project-v4-with-plugins/PROJECT b/testdata/project-v4-with-plugins/PROJECT index f006d1cad32..a4ac09e2469 100644 --- a/testdata/project-v4-with-plugins/PROJECT +++ b/testdata/project-v4-with-plugins/PROJECT @@ -28,7 +28,6 @@ projectName: project-v4-with-plugins repo: sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins resources: - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org @@ -38,9 +37,7 @@ resources: version: v1alpha1 webhooks: validation: true - webhookVersion: v1 - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org diff --git a/testdata/project-v4/PROJECT b/testdata/project-v4/PROJECT index 91fdfce8a83..c864be79062 100644 --- a/testdata/project-v4/PROJECT +++ b/testdata/project-v4/PROJECT @@ -9,7 +9,6 @@ projectName: project-v4 repo: sigs.k8s.io/kubebuilder/testdata/project-v4 resources: - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org @@ -20,9 +19,7 @@ resources: webhooks: defaulting: true validation: true - webhookVersion: v1 - api: - crdVersion: v1 namespaced: true controller: true domain: testproject.org @@ -32,10 +29,7 @@ resources: version: v1 webhooks: conversion: true - webhookVersion: v1 -- api: - crdVersion: v1 - controller: true +- controller: true domain: testproject.org group: crew kind: Admiral @@ -44,5 +38,4 @@ resources: version: v1 webhooks: defaulting: true - webhookVersion: v1 version: "3"