diff --git a/pkg/crd/parser_integration_test.go b/pkg/crd/parser_integration_test.go index b9fcab09f..16962bdeb 100644 --- a/pkg/crd/parser_integration_test.go +++ b/pkg/crd/parser_integration_test.go @@ -52,7 +52,7 @@ func packageErrors(pkg *loader.Package, filterKinds ...packages.ErrorKind) error } var _ = Describe("CRD Generation From Parsing to CustomResourceDefinition", func() { - It("should properly generate and flatten the rewritten CronJob schema", func() { + FIt("should properly generate and flatten the rewritten CronJob schema", func() { // TODO(directxman12): test generation across multiple versions (right // now, we're trusting k/k's conversion code, though, which is probably // fine for the time being) @@ -63,10 +63,10 @@ var _ = Describe("CRD Generation From Parsing to CustomResourceDefinition", func defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }() By("loading the roots") - pkgs, err := loader.LoadRoots("./", "./unserved", "./deprecated") + pkgs, err := loader.LoadRoots("./", "./unserved", "./deprecated", "./job/...") Expect(err).NotTo(HaveOccurred()) - Expect(pkgs).To(HaveLen(3)) - cronJobPkg := pkgs[0] + Expect(pkgs).To(HaveLen(4)) + cronJobPkg, jobPkg := pkgs[0], pkgs[3] By("setting up the parser") reg := &markers.Registry{} @@ -84,31 +84,61 @@ var _ = Describe("CRD Generation From Parsing to CustomResourceDefinition", func parser.NeedPackage(pkg) } - By("requesting that the CRD be generated") - groupKind := schema.GroupKind{Kind: "CronJob", Group: "testdata.kubebuilder.io"} - parser.NeedCRDFor(groupKind, nil) + { + By("requesting that the CrongJob CRD be generated") + groupKind := schema.GroupKind{Kind: "CronJob", Group: "testdata.kubebuilder.io"} + parser.NeedCRDFor(groupKind, nil) - By("fixing top level ObjectMeta on the CRD") - crd.FixTopLevelMetadata(parser.CustomResourceDefinitions[groupKind]) + By("fixing top level ObjectMeta on the CronJob CRD") + crd.FixTopLevelMetadata(parser.CustomResourceDefinitions[groupKind]) - By("checking that no errors occurred along the way (expect for type errors)") - Expect(packageErrors(cronJobPkg, packages.TypeError)).NotTo(HaveOccurred()) + By("checking that no errors occurred along the way (expect for type errors)") + Expect(packageErrors(cronJobPkg, packages.TypeError)).NotTo(HaveOccurred()) - By("checking that the CRD is present") - Expect(parser.CustomResourceDefinitions).To(HaveKey(groupKind)) + By("checking that the CronJob CRD is present") + Expect(parser.CustomResourceDefinitions).To(HaveKey(groupKind)) - By("loading the desired YAML") - expectedFile, err := ioutil.ReadFile("testdata.kubebuilder.io_cronjobs.yaml") - Expect(err).NotTo(HaveOccurred()) + By("loading the desired CronJob YAML") + expectedFile, err := ioutil.ReadFile("testdata.kubebuilder.io_cronjobs.yaml") + Expect(err).NotTo(HaveOccurred()) - By("parsing the desired YAML") - var crd apiext.CustomResourceDefinition - Expect(yaml.Unmarshal(expectedFile, &crd)).To(Succeed()) - // clear the annotations -- we don't care about the attribution annotation - crd.Annotations = nil + By("parsing the desired CronJob YAML") + var crd apiext.CustomResourceDefinition + Expect(yaml.Unmarshal(expectedFile, &crd)).To(Succeed()) + // clear the annotations -- we don't care about the attribution annotation + crd.Annotations = nil - By("comparing the two") - Expect(parser.CustomResourceDefinitions[groupKind]).To(Equal(crd), "type not as expected, check pkg/crd/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(parser.CustomResourceDefinitions[groupKind], crd)) + By("comparing the two CronJob CRDs") + Expect(parser.CustomResourceDefinitions[groupKind]).To(Equal(crd), "type not as expected, check pkg/crd/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(parser.CustomResourceDefinitions[groupKind], crd)) + } + + { + By("requesting that the Job CRD be generated") + groupKind := schema.GroupKind{Kind: "Job", Group: "testdata.kubebuilder.io"} + parser.NeedCRDFor(groupKind, nil) + + By("fixing top level ObjectMeta on the Job CRD") + crd.FixTopLevelMetadata(parser.CustomResourceDefinitions[groupKind]) + + By("checking that no errors occurred along the way (expect for type errors)") + Expect(packageErrors(jobPkg, packages.TypeError)).NotTo(HaveOccurred()) + + By("checking that the Job CRD is present") + Expect(parser.CustomResourceDefinitions).To(HaveKey(groupKind)) + + By("loading the desired Job YAML") + expectedFile, err := ioutil.ReadFile("testdata.kubebuilder.io_jobs.yaml") + Expect(err).NotTo(HaveOccurred()) + + By("parsing the desired Job YAML") + var crd apiext.CustomResourceDefinition + Expect(yaml.Unmarshal(expectedFile, &crd)).To(Succeed()) + // clear the annotations -- we don't care about the attribution annotation + crd.Annotations = nil + + By("comparing the two Job CRDs") + Expect(parser.CustomResourceDefinitions[groupKind]).To(Equal(crd), "type not as expected, check pkg/crd/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(parser.CustomResourceDefinitions[groupKind], crd)) + } }) It("should generate plural words for Kind correctly", func() { diff --git a/pkg/crd/testdata/cronjob_types.go b/pkg/crd/testdata/cronjob_types.go index 66222f6ea..46a61ef13 100644 --- a/pkg/crd/testdata/cronjob_types.go +++ b/pkg/crd/testdata/cronjob_types.go @@ -16,7 +16,7 @@ limitations under the License. // TODO(directxman12): test this across both versions (right now we're just // trusting k/k conversion, which is probably fine though) -//go:generate ../../../.run-controller-gen.sh crd:ignoreUnexportedFields=true,allowDangerousTypes=true paths=./;./deprecated;./unserved output:dir=. +//go:generate ../../../.run-controller-gen.sh crd:ignoreUnexportedFields=true,allowDangerousTypes=true paths=./;./deprecated;./unserved;./job/... output:dir=. // +groupName=testdata.kubebuilder.io // +versionName=v1 diff --git a/pkg/crd/testdata/job/types.go b/pkg/crd/testdata/job/types.go new file mode 100644 index 000000000..955266bed --- /dev/null +++ b/pkg/crd/testdata/job/types.go @@ -0,0 +1,64 @@ +/* + +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. +*/ + +// +groupName=testdata.kubebuilder.io +// +versionName=v1beta1 +package job + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "testdata.kubebuilder.io/cronjob/unserved" +) + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:singular=job + +// JobSpec is the spec for the jobs API. +type JobSpec struct { + // FriendlyName is the friendly name for the job. + // + // +kubebuilder:validation:MinLength=5 + FriendlyName string `json:"friendlyName"` + + // Count is the number of times a job may be executed. + // + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=10 + Count int32 `json:"count"` + + // CronJob is the spec for the related CrongJob. + CronnJob unserved.CronJobSpec `json:"crongJob"` +} + +// Job is the Schema for the jobs API +type Job struct { + /* + */ + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec JobSpec `json:"spec"` +} + +// +kubebuilder:object:root=true + +// JobList contains a list of Job +type JobList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Job `json:"items"` +} diff --git a/pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml b/pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml index a4b031f47..8d6c15e70 100644 --- a/pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml +++ b/pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml @@ -7504,6 +7504,24 @@ spec: type: string metadata: type: object + spec: + description: CronJobSpec defines the desired state of CronJob + properties: + int32WithValidations: + format: int32 + maximum: 2 + minimum: -2 + multipleOf: 2 + type: integer + twoOfAKindPart0: + description: This tests that markers that are allowed on both fields + and types are applied to fields + minLength: 4 + type: string + required: + - int32WithValidations + - twoOfAKindPart0 + type: object type: object served: false storage: false diff --git a/pkg/crd/testdata/testdata.kubebuilder.io_jobs.yaml b/pkg/crd/testdata/testdata.kubebuilder.io_jobs.yaml new file mode 100644 index 000000000..e4eed5463 --- /dev/null +++ b/pkg/crd/testdata/testdata.kubebuilder.io_jobs.yaml @@ -0,0 +1,75 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: jobs.testdata.kubebuilder.io +spec: + group: testdata.kubebuilder.io + names: + kind: Job + listKind: JobList + plural: jobs + singular: job + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Job is the Schema for the jobs 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: JobSpec is the spec for the jobs API. + properties: + count: + description: Count is the number of times a job may be executed. + format: int32 + maximum: 10 + minimum: 0 + type: integer + crongJob: + description: CronJob is the spec for the related CrongJob. + properties: + int32WithValidations: + format: int32 + maximum: 2 + minimum: -2 + multipleOf: 2 + type: integer + twoOfAKindPart0: + description: This tests that markers that are allowed on both + fields and types are applied to fields + minLength: 4 + type: string + required: + - int32WithValidations + - twoOfAKindPart0 + type: object + friendlyName: + description: FriendlyName is the friendly name for the job. + minLength: 5 + type: string + required: + - count + - crongJob + - friendlyName + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/pkg/crd/testdata/unserved/types.go b/pkg/crd/testdata/unserved/types.go index c4a7b3124..1c549f3bd 100644 --- a/pkg/crd/testdata/unserved/types.go +++ b/pkg/crd/testdata/unserved/types.go @@ -21,6 +21,18 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// CronJobSpec defines the desired state of CronJob +type CronJobSpec struct { + // This tests that markers that are allowed on both fields and types are applied to fields + // +kubebuilder:validation:MinLength=4 + TwoOfAKindPart0 string `json:"twoOfAKindPart0"` + + // +kubebuilder:validation:Minimum=-2 + // +kubebuilder:validation:Maximum=2 + // +kubebuilder:validation:MultipleOf=2 + Int32WithValidations int32 `json:"int32WithValidations"` +} + // +kubebuilder:object:root=true // +kubebuilder:subresource:status // +kubebuilder:resource:singular=mycronjob @@ -32,6 +44,8 @@ type CronJob struct { */ metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CronJobSpec `json:"spec,omitempty"` } // +kubebuilder:object:root=true