From 21353c80dbab65ff14b7e2e37a413fa8ec9831e6 Mon Sep 17 00:00:00 2001 From: chunter0 Date: Mon, 7 Aug 2023 15:48:57 -0500 Subject: [PATCH] Revert "Support for conditionally enabling of alpha-level CRDs (#462)" This reverts commit ac641d98df25318de2730ae69db40175155bba95. --- api/multicluster/v1alpha1/group.go | 18 +- .../v0.33.0/conditional_crd_rendering.yaml | 5 - codegen/cmd.go | 64 ++- codegen/cmd_test.go | 30 +- codegen/kuberesource/crd.go | 142 ++----- codegen/kuberesource/crd_test.go | 135 +------ codegen/model/resource.go | 22 -- codegen/render/kube_crud_test.go | 5 +- codegen/render/kube_multicluster_test.go | 3 +- codegen/render/manifests_renderer.go | 178 ++------- codegen/render/manifests_renderer_test.go | 370 +----------------- codegen/templates/manifests/crd.yamltmpl | 30 -- ..._crds.yaml => things.test.io_v1_crds.yaml} | 66 ++-- .../templates/things.test.io_crds.yaml | 169 -------- ..._crds.yaml => things.test.io_v1_crds.yaml} | 66 ++-- .../chart/templates/things.test.io_crds.yaml | 173 -------- ..._crds.yaml => things.test.io_v1_crds.yaml} | 34 +- .../templates/things.test.io_crds.yaml | 59 --- ...> multicluster.solo.io_v1alpha1_crds.yaml} | 0 go.mod | 2 +- templates/multicluster.solo.io_crds.yaml | 161 -------- 21 files changed, 223 insertions(+), 1509 deletions(-) delete mode 100644 changelog/v0.33.0/conditional_crd_rendering.yaml delete mode 100644 codegen/templates/manifests/crd.yamltmpl rename codegen/test/chart-no-desc/crds/{things.test.io_crds.yaml => things.test.io_v1_crds.yaml} (100%) delete mode 100644 codegen/test/chart-no-desc/templates/things.test.io_crds.yaml rename codegen/test/chart/crds/{things.test.io_crds.yaml => things.test.io_v1_crds.yaml} (100%) delete mode 100644 codegen/test/chart/templates/things.test.io_crds.yaml rename codegen/test/name_override_chart/crds/{things.test.io_crds.yaml => things.test.io_v1_crds.yaml} (100%) delete mode 100644 codegen/test/name_override_chart/templates/things.test.io_crds.yaml rename crds/{multicluster.solo.io_crds.yaml => multicluster.solo.io_v1alpha1_crds.yaml} (100%) delete mode 100644 templates/multicluster.solo.io_crds.yaml diff --git a/api/multicluster/v1alpha1/group.go b/api/multicluster/v1alpha1/group.go index a63cf9fa7..9291ebf47 100644 --- a/api/multicluster/v1alpha1/group.go +++ b/api/multicluster/v1alpha1/group.go @@ -26,16 +26,14 @@ var Group = model.Group{ Name: "KubernetesClusterStatus", }, }, - Stored: true, }, }, - RenderManifests: true, - RenderValidationSchemas: true, - RenderController: true, - RenderClients: true, - RenderTypes: true, - MockgenDirective: true, - ApiRoot: "pkg/api", - CustomTemplates: contrib.AllGroupCustomTemplates, - SkipConditionalCRDLoading: true, + RenderManifests: true, + RenderValidationSchemas: true, + RenderController: true, + RenderClients: true, + RenderTypes: true, + MockgenDirective: true, + ApiRoot: "pkg/api", + CustomTemplates: contrib.AllGroupCustomTemplates, } diff --git a/changelog/v0.33.0/conditional_crd_rendering.yaml b/changelog/v0.33.0/conditional_crd_rendering.yaml deleted file mode 100644 index 0ad14deed..000000000 --- a/changelog/v0.33.0/conditional_crd_rendering.yaml +++ /dev/null @@ -1,5 +0,0 @@ -changelog: - - type: BREAKING_CHANGE - issueLink: https://github.com/solo-io/gloo-mesh-enterprise/issues/9019 - description: > - Add support for conditional rendering of CRDs. diff --git a/codegen/cmd.go b/codegen/cmd.go index 41c90cd65..e9251af4a 100644 --- a/codegen/cmd.go +++ b/codegen/cmd.go @@ -106,10 +106,6 @@ type Command struct { // context of the command ctx context.Context - - // the name of the flag to pass the list of enabled alpha-level crds - // used in codegen/templates/manifests/crd.yamltmpl - EnabledAlphaApiFlagName string } // function to execute skv2 code gen from another repository @@ -148,16 +144,17 @@ func (c Command) Execute() error { var groups []*model.Group for _, group := range c.Groups { group := group // pike - c.initGroup(&group, descriptors) groups = append(groups, &group) } + for i, group := range groups { + group := group // pike + c.initGroup(group, descriptors) - if err := c.generateGroups(groups, protoOpts, c.GroupOptions); err != nil { - return err - } + if err := c.generateGroup(*group, protoOpts, c.GroupOptions); err != nil { + return err + } - // replace group in Groups array with the group including generated fields - for i, group := range groups { + // replace group in Groups array with the group including generated fields c.Groups[i] = *group } @@ -242,8 +239,8 @@ func (c Command) renderProtos() ([]*collector.DescriptorWithPath, error) { return descriptors, nil } -func (c Command) generateGroups( - grps []*model.Group, +func (c Command) generateGroup( + grp model.Group, protoOpts proto.Options, groupOptions model.GroupOptions, ) error { @@ -253,27 +250,25 @@ func (c Command) generateGroups( Header: c.GeneratedHeader, } - for _, grp := range grps { - protoTypes, err := render.RenderProtoTypes(*grp) - if err != nil { - return err - } + protoTypes, err := render.RenderProtoTypes(grp) + if err != nil { + return err + } - if err := fileWriter.WriteFiles(protoTypes); err != nil { - return err - } + if err := fileWriter.WriteFiles(protoTypes); err != nil { + return err + } - apiTypes, err := render.RenderApiTypes(*grp) - if err != nil { - return err - } + apiTypes, err := render.RenderApiTypes(grp) + if err != nil { + return err + } - if err := fileWriter.WriteFiles(apiTypes); err != nil { - return err - } + if err := fileWriter.WriteFiles(apiTypes); err != nil { + return err } - manifests, err := render.RenderManifests(c.AppName, c.ManifestRoot, c.ProtoDir, c.EnabledAlphaApiFlagName, protoOpts, groupOptions, grps) + manifests, err := render.RenderManifests(c.AppName, c.ManifestRoot, c.ProtoDir, protoOpts, groupOptions, grp) if err != nil { return err } @@ -282,10 +277,8 @@ func (c Command) generateGroups( return err } - for _, grp := range grps { - if err := render.KubeCodegen(*grp); err != nil { - return err - } + if err := render.KubeCodegen(grp); err != nil { + return err } return nil @@ -342,13 +335,6 @@ func (c Command) initGroup( // default to the resource API Group name matchingProtoPackage = resource.Group.Group } - // TODO (dmitri-d): This assumes we only ever have a single message with a given name, and breaks when we - // have multiple versions of the same proto message. - // `go_package`` is not a reliable way to determine the package version, as it is not always set. - // protobuf path is not reliable either, as it is not always contains the version (see test/test_api.proto). - // A common approach is to include the version in the proto package name, perhaps we could adopt that? - // For example, workspace.proto package now is "admin.gloo.solo.io", it would change to - // "admin.gloo.solo.io.v2" with such an approach. if fileDescriptor.GetPackage() == matchingProtoPackage { if message := fileDescriptor.GetMessage(fieldType.Name); message != nil { fieldType.Message = message diff --git a/codegen/cmd_test.go b/codegen/cmd_test.go index 018180384..7ef5a78b4 100644 --- a/codegen/cmd_test.go +++ b/codegen/cmd_test.go @@ -9,7 +9,6 @@ import ( "os/exec" "path/filepath" "reflect" - "strings" goyaml "gopkg.in/yaml.v3" rbacv1 "k8s.io/api/rbac/v1" @@ -166,13 +165,11 @@ var _ = Describe("Cmd", func() { Kind: "Paint", Spec: Field{Type: Type{Name: "PaintSpec"}}, Status: &Field{Type: Type{Name: "PaintStatus"}}, - Stored: true, }, { Kind: "ClusterResource", Spec: Field{Type: Type{Name: "ClusterResourceSpec"}}, ClusterScoped: true, - Stored: true, }, }, RenderManifests: true, @@ -247,7 +244,6 @@ var _ = Describe("Cmd", func() { Name: "KubernetesCluster", GoPackage: "github.com/solo-io/skv2/pkg/api/multicluster.solo.io/v1alpha1", }}, - Stored: true, }, }, RenderManifests: true, @@ -286,13 +282,11 @@ var _ = Describe("Cmd", func() { Kind: "Paint", Spec: Field{Type: Type{Name: "PaintSpec"}}, Status: &Field{Type: Type{Name: "PaintStatus"}}, - Stored: true, }, { Kind: "ClusterResource", Spec: Field{Type: Type{Name: "ClusterResourceSpec"}}, ClusterScoped: true, - Stored: true, }, }, RenderManifests: true, @@ -373,13 +367,11 @@ var _ = Describe("Cmd", func() { Kind: "Paint", Spec: Field{Type: Type{Name: "PaintSpec"}}, Status: &Field{Type: Type{Name: "PaintStatus"}}, - Stored: true, }, { Kind: "ClusterResource", Spec: Field{Type: Type{Name: "ClusterResourceSpec"}}, ClusterScoped: true, - Stored: true, }, }, RenderManifests: true, @@ -494,13 +486,11 @@ var _ = Describe("Cmd", func() { Kind: "Paint", Spec: Field{Type: Type{Name: "PaintSpec"}}, Status: &Field{Type: Type{Name: "PaintStatus"}}, - Stored: true, }, { Kind: "ClusterResource", Spec: Field{Type: Type{Name: "ClusterResourceSpec"}}, ClusterScoped: true, - Stored: true, }, }, RenderManifests: true, @@ -1507,13 +1497,11 @@ roleRef: Kind: "Paint", Spec: Field{Type: Type{Name: "PaintSpec"}}, Status: &Field{Type: Type{Name: "PaintStatus"}}, - Stored: true, }, { Kind: "ClusterResource", Spec: Field{Type: Type{Name: "ClusterResourceSpec"}}, ClusterScoped: true, - Stored: true, }, }, RenderManifests: true, @@ -1629,7 +1617,7 @@ roleRef: }) It("can include field descriptions", func() { - crdFilePath := filepath.Join(util.GetModuleRoot(), cmd.ManifestRoot, "/crds/things.test.io_crds.yaml") + crdFilePath := filepath.Join(util.GetModuleRoot(), cmd.ManifestRoot, "/crds/things.test.io_v1_crds.yaml") err := cmd.Execute() Expect(err).NotTo(HaveOccurred()) @@ -1639,25 +1627,16 @@ roleRef: Expect(string(bytes)).To(ContainSubstring("description: OpenAPI gen test for recursive fields")) }) - // TODO (dmitri-d): kube_crud_test and kube_multicluster_test depend on crds in this suite. It("generates google.protobuf.Value with no type", func() { - crdFilePath := filepath.Join(util.GetModuleRoot(), cmd.ManifestRoot, "/crds/things.test.io_crds.yaml") + crdFilePath := filepath.Join(util.GetModuleRoot(), cmd.ManifestRoot, "/crds/things.test.io_v1_crds.yaml") err := cmd.Execute() Expect(err).NotTo(HaveOccurred()) bytes, err := ioutil.ReadFile(crdFilePath) Expect(err).NotTo(HaveOccurred()) - paintCrdYaml := "" - for _, crd := range strings.Split(string(bytes), "---") { - if strings.Contains(crd, "kind: Paint") { - paintCrdYaml = crd - } - } - Expect(paintCrdYaml).ToNot(BeEmpty()) - generatedCrd := &v12.CustomResourceDefinition{} - Expect(yaml.Unmarshal([]byte(paintCrdYaml), &generatedCrd)).NotTo(HaveOccurred()) + Expect(yaml.Unmarshal(bytes, generatedCrd)).NotTo(HaveOccurred()) protobufValueField := generatedCrd.Spec.Versions[0].Schema.OpenAPIV3Schema.Properties["spec"].Properties["recursiveType"].Properties["protobufValue"] // access the field to make sure it's not nil Expect(protobufValueField.XPreserveUnknownFields).ToNot(BeNil()) @@ -1669,7 +1648,7 @@ roleRef: // write this manifest to a different dir to avoid modifying the crd file from the // above test, which other tests seem to depend on cmd.ManifestRoot = "codegen/test/chart-no-desc" - crdFilePath := filepath.Join(util.GetModuleRoot(), cmd.ManifestRoot, "/crds/things.test.io_crds.yaml") + crdFilePath := filepath.Join(util.GetModuleRoot(), cmd.ManifestRoot, "/crds/things.test.io_v1_crds.yaml") cmd.Groups[0].SkipSchemaDescriptions = true @@ -1837,7 +1816,6 @@ func helmTemplate(path string, values interface{}) []byte { path, "--values", helmValuesFile.Name(), ).CombinedOutput() - ExpectWithOffset(1, err).NotTo(HaveOccurred(), string(out)) return out } diff --git a/codegen/kuberesource/crd.go b/codegen/kuberesource/crd.go index ef655204e..02148c62d 100644 --- a/codegen/kuberesource/crd.go +++ b/codegen/kuberesource/crd.go @@ -2,14 +2,11 @@ package kuberesource import ( "fmt" - "sort" "strings" - "github.com/google/go-cmp/cmp" "github.com/mitchellh/hashstructure" "github.com/solo-io/skv2/codegen/util/stringutils" "github.com/solo-io/skv2/pkg/crdutils" - "golang.org/x/exp/maps" "github.com/rotisserie/eris" "github.com/solo-io/skv2/codegen/model" @@ -21,54 +18,23 @@ import ( // Create CRDs for a group func CustomResourceDefinitions( - groups []*model.Group, -) (objects []apiextv1.CustomResourceDefinition, err error) { - resourcesByKind := make(map[string][]model.Resource) - skipHashByKind := make(map[string]bool) - for _, group := range groups { - for i, resource := range group.Resources { - resourcesByKind[resource.Kind] = append(resourcesByKind[resource.Kind], group.Resources[i]) - skipHashByKind[resource.Kind] = skipHashByKind[resource.Kind] || resource.Group.SkipSpecHash - } - } - - // Make ordering of crds in a group deterministic - kinds := maps.Keys(resourcesByKind) - sort.Strings(kinds) - for _, kind := range kinds { - resources := resourcesByKind[kind] - // make version ordering deterministic - sort.Slice(resources, func(i, j int) bool { return resources[i].Version < resources[j].Version }) - validationSchemas, err := constructValidationSchemas(resources) - if err != nil { - return nil, err - } - - crd, err := CustomResourceDefinition(resources, validationSchemas, skipHashByKind[kind]) - if err != nil { - return nil, err - } - objects = append(objects, *crd) - } - return objects, nil -} + group model.Group, +) (objects []metav1.Object, err error) { + for _, resource := range group.Resources { -func constructValidationSchemas(resources []model.Resource) (map[string]*apiextv1.CustomResourceValidation, error) { - validationSchemas := make(map[string]*apiextv1.CustomResourceValidation) - for _, resource := range resources { var validationSchema *apiextv1.CustomResourceValidation - validationSchema, err := constructValidationSchema( - resource.Group.RenderValidationSchemas, + validationSchema, err = constructValidationSchema( + group.RenderValidationSchemas, resource, - resource.Group.OpenApiSchemas, + group.OpenApiSchemas, ) if err != nil { return nil, err } - validationSchemas[resource.Group.String()] = validationSchema + objects = append(objects, CustomResourceDefinition(resource, validationSchema, group.SkipSpecHash)) } - return validationSchemas, nil + return objects, nil } func constructValidationSchema( @@ -150,71 +116,28 @@ func validateStructural(s *apiextv1.JSONSchemaProps) error { return nil } -func validateCRDResources(resources []model.Resource) error { - if len(resources) < 2 { - return nil - } - - scope := resources[0].ClusterScoped - shortNames := resources[0].ShortNames - categories := resources[0].Categories - - for i := 1; i < len(resources); i++ { - if resources[i].ClusterScoped != scope { - return fmt.Errorf("mismatched 'currentScope' in versions of CRD for resource kind %s", resources[i].Kind) - } - if !cmp.Equal(resources[i].ShortNames, shortNames) { - return fmt.Errorf("mismatched 'ShortNames' in versions of CRD for resource kind %s", resources[i].Kind) - } - if !cmp.Equal(resources[i].Categories, categories) { - return fmt.Errorf("mismatched 'Categories' in versions of CRD for resource kind %s", resources[i].Kind) - } - } - - return nil -} - func CustomResourceDefinition( - resources []model.Resource, - validationSchemas map[string]*apiextv1.CustomResourceValidation, + resource model.Resource, + validationSchema *apiextv1.CustomResourceValidation, withoutSpecHash bool, -) (*apiextv1.CustomResourceDefinition, error) { - - err := validateCRDResources(resources) - if err != nil { - return nil, err - } +) *apiextv1.CustomResourceDefinition { - group := resources[0].Group.Group - kind := resources[0].Kind + group := resource.Group.Group + version := resource.Group.Version + kind := resource.Kind kindLowerPlural := strings.ToLower(stringutils.Pluralize(kind)) kindLower := strings.ToLower(kind) + var status *apiextv1.CustomResourceSubresourceStatus + if resource.Status != nil { + status = &apiextv1.CustomResourceSubresourceStatus{} + } + scope := apiextv1.NamespaceScoped - if resources[0].ClusterScoped { + if resource.ClusterScoped { scope = apiextv1.ClusterScoped } - versions := make([]apiextv1.CustomResourceDefinitionVersion, 0, len(resources)) - for _, resource := range resources { - var status *apiextv1.CustomResourceSubresourceStatus - if resource.Status != nil { - status = &apiextv1.CustomResourceSubresourceStatus{} - } - - v := apiextv1.CustomResourceDefinitionVersion{ - Name: resource.Group.Version, - Served: true, - Storage: resource.Stored, - Deprecated: resource.Deprecated, - AdditionalPrinterColumns: resource.AdditionalPrinterColumns, - Subresources: &apiextv1.CustomResourceSubresources{ - Status: status, - }, - Schema: validationSchemas[resource.Group.String()], - } - versions = append(versions, v) - } crd := &apiextv1.CustomResourceDefinition{ TypeMeta: metav1.TypeMeta{ APIVersion: apiextv1.SchemeGroupVersion.String(), @@ -224,16 +147,27 @@ func CustomResourceDefinition( Name: fmt.Sprintf("%s.%s", kindLowerPlural, group), }, Spec: apiextv1.CustomResourceDefinitionSpec{ - Group: group, - Scope: scope, - Versions: versions, + Group: group, + Scope: scope, + Versions: []apiextv1.CustomResourceDefinitionVersion{ + { + Name: version, + Served: true, + Storage: true, + AdditionalPrinterColumns: resource.AdditionalPrinterColumns, + Subresources: &apiextv1.CustomResourceSubresources{ + Status: status, + }, + Schema: validationSchema, + }, + }, Names: apiextv1.CustomResourceDefinitionNames{ Plural: kindLowerPlural, Singular: kindLower, Kind: kind, - ShortNames: resources[0].ShortNames, + ShortNames: resource.ShortNames, ListKind: kind + "List", - Categories: resources[0].Categories, + Categories: resource.Categories, }, }, } @@ -248,9 +182,9 @@ func CustomResourceDefinition( } } - if len(validationSchemas) > 0 { + if validationSchema != nil { // Setting PreserveUnknownFields to false ensures that objects with unknown fields are rejected. crd.Spec.PreserveUnknownFields = false } - return crd, nil + return crd } diff --git a/codegen/kuberesource/crd_test.go b/codegen/kuberesource/crd_test.go index 316d1ed52..efe9e4989 100644 --- a/codegen/kuberesource/crd_test.go +++ b/codegen/kuberesource/crd_test.go @@ -1,11 +1,8 @@ package kuberesource_test import ( - "fmt" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" v1 "github.com/solo-io/skv2/codegen/test/api/things.test.io/v1" @@ -18,11 +15,11 @@ var _ = Describe("Crd", func() { Describe("CRD gen", func() { var ( - grps []*model.Group + grp model.Group ) BeforeEach(func() { - grps = []*model.Group{{ + grp = model.Group{ Resources: []model.Resource{ { Kind: "kind", @@ -32,141 +29,31 @@ var _ = Describe("Crd", func() { Message: &v1.AcrylicType{}, }, }, - Stored: true, - Deprecated: false, }, - { - Kind: "kind-1", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.PaintColor{}, - }, - }, - Stored: false, - Deprecated: true, - }, - }}, - } - for i := range grps { - grps[i].Init() + }, } + grp.Init() }) It("should generate spec hash", func() { - grps[0].SkipSpecHash = false - o, err := CustomResourceDefinitions(grps) + grp.SkipSpecHash = false + o, err := CustomResourceDefinitions(grp) Expect(err).NotTo(HaveOccurred()) - Expect(o).To(HaveLen(2)) + Expect(o).To(HaveLen(1)) // note: we intentionally provide the "b6ec737002f7d02e" hash in the test, as it shouldn't change // between runs. Expect(o[0].GetAnnotations()).To(HaveKeyWithValue(crdutils.CRDSpecHashKey, "b6ec737002f7d02e")) + }) It("should not generate spec hash", func() { - grps[0].SkipSpecHash = true - o, err := CustomResourceDefinitions(grps) + grp.SkipSpecHash = true + o, err := CustomResourceDefinitions(grp) Expect(err).NotTo(HaveOccurred()) - Expect(o).To(HaveLen(2)) + Expect(o).To(HaveLen(1)) // note: we intentionally provide the "d18828e563010e32" hash in the test, as it shouldn't change // between runs. Expect(o[0].GetAnnotations()).NotTo(HaveKey(crdutils.CRDSpecHashKey)) }) - It("should set 'Stored' and 'Deprecated' fields", func() { - grps[0].SkipSpecHash = false - o, err := CustomResourceDefinitions(grps) - Expect(err).NotTo(HaveOccurred()) - Expect(o).To(HaveLen(2)) - Expect(o[0].Spec.Versions).To(HaveLen(1)) - Expect(o[0].Spec.Versions[0].Storage).To(BeTrue()) - Expect(o[0].Spec.Versions[0].Deprecated).To(BeFalse()) - Expect(o[1].Spec.Versions).To(HaveLen(1)) - Expect(o[1].Spec.Versions[0].Storage).To(BeFalse()) - Expect(o[1].Spec.Versions[0].Deprecated).To(BeTrue()) - }) - }) - Describe("CRD gen with errors", func() { - It("should return an error when scopes are mismatched", func() { - resources := []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - ClusterScoped: true, - }, - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.PaintColor{}, - }, - }, - ClusterScoped: false, - }, - } - - _, err := CustomResourceDefinition(resources, map[string]*apiextv1.CustomResourceValidation{}, false) - Expect(err).To(Equal(fmt.Errorf("mismatched 'currentScope' in versions of CRD for resource kind kind"))) - }) - It("should return an error when ShortNames are mismatched", func() { - resources := []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - ShortNames: []string{"name1", "name2"}, - }, - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.PaintColor{}, - }, - }, - ShortNames: []string{"name2", "name3"}, - }, - } - - _, err := CustomResourceDefinition(resources, map[string]*apiextv1.CustomResourceValidation{}, false) - Expect(err).To(Equal(fmt.Errorf("mismatched 'ShortNames' in versions of CRD for resource kind kind"))) - }) - It("should return an error when Categories are mismatched", func() { - resources := []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - Categories: []string{"cat1", "cat2"}, - }, - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.PaintColor{}, - }, - }, - Categories: []string{"cat2", "cat3"}, - }, - } - - _, err := CustomResourceDefinition(resources, map[string]*apiextv1.CustomResourceValidation{}, false) - Expect(err).To(Equal(fmt.Errorf("mismatched 'Categories' in versions of CRD for resource kind kind"))) - }) - }) }) diff --git a/codegen/model/resource.go b/codegen/model/resource.go index e508a6008..f0c03e604 100644 --- a/codegen/model/resource.go +++ b/codegen/model/resource.go @@ -114,17 +114,6 @@ type Group struct { // Some resources use pointer slices for the Items field. PointerSlices bool `default:"false"` - - // Set to true to skip rendering of conditional loading logic - // for CRDs containing alpha-versioned resources. - // Used by codegen/templates/manifests/crd.yamltmpl - SkipConditionalCRDLoading bool - - // Skip generation of crd manifests that live in crd/ directory of a chart - SkipCRDManifest bool - - // Skip generation of templated crd manifests that live in templates/ dir of a chart - SkipTemplatedCRDManifest bool } type GroupOptions struct { @@ -183,17 +172,6 @@ type Resource struct { // If enabled, the unmarshal will NOT allow unknown fields. StrictUnmarshal bool - - // Corresponds to CRD's versions.storage field - // Only one version of a resource can be marked as "stored" - // Set to false by default - // See https://kubernetes.io/docs/reference/kubernetes-api/extend-resources/custom-resource-definition-v1/#CustomResourceDefinitionSpec - Stored bool - - // Corresponds to CRD's versions.deprecated field - // Set to false by default - // See https://kubernetes.io/docs/reference/kubernetes-api/extend-resources/custom-resource-definition-v1/#CustomResourceDefinitionSpec - Deprecated bool } type Field struct { diff --git a/codegen/render/kube_crud_test.go b/codegen/render/kube_crud_test.go index 5c9116cef..d30e18cc7 100644 --- a/codegen/render/kube_crud_test.go +++ b/codegen/render/kube_crud_test.go @@ -31,14 +31,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" ) -// TODO (dmitri-d): Remove dependency of these tests on crds generated in cmd_test func applyFile(file string, extraArgs ...string) error { path := filepath.Join(util.GetModuleRoot(), "codegen/test/chart/crds", file) b, err := ioutil.ReadFile(path) if err != nil { return err } - return util.KubectlApply(b, extraArgs...) } @@ -119,8 +117,7 @@ var _ = Describe("Generated Code", func() { log.SetLogger(zaputil.New( zaputil.Level(&logLevel), )) - err := applyFile("things.test.io_crds.yaml") - + err := applyFile("things.test.io_v1_crds.yaml") Expect(err).NotTo(HaveOccurred()) ns = randutils.RandString(4) kube = kubehelp.MustKubeClient() diff --git a/codegen/render/kube_multicluster_test.go b/codegen/render/kube_multicluster_test.go index d8046b913..67fbb4a6b 100644 --- a/codegen/render/kube_multicluster_test.go +++ b/codegen/render/kube_multicluster_test.go @@ -40,7 +40,6 @@ func WithRemoteClusterContextDescribe(text string, body func()) bool { return Describe(text, body) } -// TODO (dmitri-d): Remove dependency of these tests on crds generated in cmd_test var _ = WithRemoteClusterContextDescribe("Multicluster", func() { var ( ctx context.Context @@ -67,7 +66,7 @@ var _ = WithRemoteClusterContextDescribe("Multicluster", func() { Expect(err).NotTo(HaveOccurred()) for _, kubeContext := range []string{"", remoteContext} { - err = applyFile("things.test.io_crds.yaml", "--context", kubeContext) + err = applyFile("things.test.io_v1_crds.yaml", "--context", kubeContext) Expect(err).NotTo(HaveOccurred()) cfg := test.MustConfig(kubeContext) diff --git a/codegen/render/manifests_renderer.go b/codegen/render/manifests_renderer.go index 3f05fff9a..6b1e6a47c 100644 --- a/codegen/render/manifests_renderer.go +++ b/codegen/render/manifests_renderer.go @@ -2,7 +2,6 @@ package render import ( "encoding/json" - "fmt" "regexp" "strings" @@ -27,92 +26,60 @@ import ( // creates a k8s resource for a group // this gets turned into a k8s manifest file -type MakeResourceFunc func(groups []*Group) ([]metav1.Object, error) +type MakeResourceFunc func(group Group) ([]metav1.Object, error) // renders kubernetes from templates type ManifestsRenderer struct { - templateRenderer AppName string // used for labeling ResourceFuncs map[OutFile]MakeResourceFunc ManifestDir string ProtoDir string - // the name of the flag to pass the list of enabled alpha-level crds - // used in codegen/templates/manifests/crd.yamltmpl - EnabledAlphaApiFlagName string -} - -type templateArgs struct { - Crds []apiextv1.CustomResourceDefinition - ShouldSkip map[string]bool - EnabledAlphaApiFlagName string } func RenderManifests( - appName, manifestDir, protoDir, enabledAlphaApiFlagName string, + appName, manifestDir, protoDir string, protoOpts protoutil.Options, groupOptions model.GroupOptions, - grps []*Group, + grp Group, ) ([]OutFile, error) { defaultManifestsRenderer := ManifestsRenderer{ - AppName: appName, - ManifestDir: manifestDir, - ProtoDir: protoDir, - EnabledAlphaApiFlagName: enabledAlphaApiFlagName, - } - return defaultManifestsRenderer.RenderManifests(grps, protoOpts, groupOptions) + AppName: appName, + ManifestDir: manifestDir, + ProtoDir: protoDir, + ResourceFuncs: map[OutFile]MakeResourceFunc{ + { + Path: manifestDir + "/crds/" + grp.Group + "_" + grp.Version + "_" + "crds.yaml", + }: func(group Group) ([]metav1.Object, error) { + return kuberesource.CustomResourceDefinitions(group) + }, + }, + } + return defaultManifestsRenderer.RenderManifests(grp, protoOpts, groupOptions) } -func (r ManifestsRenderer) RenderManifests(grps []*Group, protoOpts protoutil.Options, groupOptions model.GroupOptions) ([]OutFile, error) { - grpsByGroupName := make(map[string][]*Group) - shouldRenderGroups := make(map[string]bool) - shouldSkipCRDManifest := make(map[string]bool) - shouldSkipTemplatedCRDManifest := make(map[string]bool) - grandfatheredGroups := make(map[string]bool) - for _, grp := range grps { - grpsByGroupName[grp.Group] = append(grpsByGroupName[grp.Group], grp) - shouldRenderGroups[grp.Group] = shouldRenderGroups[grp.Group] || grp.RenderManifests - grandfatheredGroups[grp.GroupVersion.String()] = grandfatheredGroups[grp.GroupVersion.String()] || grp.SkipConditionalCRDLoading - shouldSkipCRDManifest[grp.Group] = - shouldSkipCRDManifest[grp.Group] || grp.SkipCRDManifest - shouldSkipTemplatedCRDManifest[grp.Group] = - shouldSkipTemplatedCRDManifest[grp.Group] || grp.SkipTemplatedCRDManifest - } - - for _, grp := range grps { - if grp.RenderValidationSchemas && shouldRenderGroups[grp.Group] { - var err error - oapiSchemas, err := generateOpenApi(*grp, r.ProtoDir, protoOpts, groupOptions) - if err != nil { - return nil, err - } - grp.OpenApiSchemas = oapiSchemas - } +func (r ManifestsRenderer) RenderManifests(grp Group, protoOpts protoutil.Options, groupOptions model.GroupOptions) ([]OutFile, error) { + if !grp.RenderManifests { + return nil, nil } - var renderedFiles []OutFile - - for groupName, selectedGrps := range grpsByGroupName { - if !shouldRenderGroups[groupName] { - continue - } - - crds, err := r.createCrds(r.AppName, selectedGrps) - if err != nil { - return nil, err - } - out, err := r.renderCRDManifest(r.AppName, groupName, crds) + if grp.RenderValidationSchemas { + var err error + oapiSchemas, err := generateOpenApi(grp, r.ProtoDir, protoOpts, groupOptions) if err != nil { return nil, err } - renderedFiles = append(renderedFiles, out) + grp.OpenApiSchemas = oapiSchemas + } - out, err = r.renderTemplatedCRDManifest(r.AppName, groupName, crds, grandfatheredGroups) + var renderedFiles []OutFile + for out, mkFunc := range r.ResourceFuncs { + content, err := r.renderManifest(r.AppName, mkFunc, grp) if err != nil { return nil, err } + out.Content = content renderedFiles = append(renderedFiles, out) } - return renderedFiles, nil } @@ -251,100 +218,41 @@ func SetVersionForObject(obj metav1.Object, version string) { } a[crdutils.CRDVersionKey] = strippedVersion.String() - obj.SetAnnotations(a) } } -// TODO (dmitri-d): this can be removed once we migrate to use platform charts exclusively -func (r ManifestsRenderer) renderCRDManifest(appName, groupName string, objs []apiextv1.CustomResourceDefinition) (OutFile, error) { - outFile := OutFile{ - Path: r.ManifestDir + "/crds/" + groupName + "_" + "crds.yaml", +func (r ManifestsRenderer) renderManifest(appName string, mk MakeResourceFunc, group Group) (string, error) { + objs, err := mk(group) + if err != nil { + return "", err } var objManifests []string for _, obj := range objs { - manifest, err := marshalObjToYaml(appName, &obj) + // find the annotation of the manifest, and add to them + SetVersionForObject(obj, group.AddChartVersion) + manifest, err := marshalObjToYaml(appName, obj) if err != nil { - return OutFile{}, err + return "", err } objManifests = append(objManifests, manifest) } - outFile.Content = strings.Join(objManifests, "\n---\n") - return outFile, nil -} - -func (r ManifestsRenderer) renderTemplatedCRDManifest(appName, groupName string, - objs []apiextv1.CustomResourceDefinition, - grandfatheredGroups map[string]bool) (OutFile, error) { - - renderer := DefaultTemplateRenderer - - // when rendering helm charts, we need - // to use a custom delimiter - renderer.left = "[[" - renderer.right = "]]" - - defaultManifestRenderer := ChartRenderer{ - templateRenderer: renderer, - } - - outFile := OutFile{Path: r.ManifestDir + "/templates/" + groupName + "_" + "crds.yaml"} - templatesToRender := inputTemplates{ - "manifests/crd.yamltmpl": outFile, - } - - if err := r.canRenderCRDTemplate(objs, grandfatheredGroups); err != nil { - return OutFile{}, err - } - - files, err := defaultManifestRenderer.renderCoreTemplates( - templatesToRender, - templateArgs{Crds: objs, ShouldSkip: grandfatheredGroups, EnabledAlphaApiFlagName: r.EnabledAlphaApiFlagName}) - if err != nil { - return OutFile{}, err - } - // if we got here there's one item in []files, - // as we only rendered one template and there were no errors - return files[0], nil -} - -func (r ManifestsRenderer) canRenderCRDTemplate(objs []apiextv1.CustomResourceDefinition, grandfatheredGroups map[string]bool) error { - for _, obj := range objs { - for _, v := range obj.Spec.Versions { - if strings.Contains(v.Name, "alpha") && !grandfatheredGroups[obj.Spec.Group+"/"+v.Name] && r.EnabledAlphaApiFlagName == "" { - return fmt.Errorf("error rendering CRD template for kind %s: 'EnabledAlphaApiFlagName' is not defined", obj.Spec.Names.Kind) - } - } - } - return nil + return strings.Join(objManifests, "\n---\n"), nil } -func (r ManifestsRenderer) createCrds(appName string, groups []*Group) ([]apiextv1.CustomResourceDefinition, error) { - objs, err := kuberesource.CustomResourceDefinitions(groups) - if err != nil { - return nil, err +func marshalObjToYaml(appName string, obj metav1.Object) (string, error) { + labels := obj.GetLabels() + if labels == nil { + labels = map[string]string{} } - for i, obj := range objs { - // find the annotation of the manifest, and add to them - SetVersionForObject(objs[i].GetObjectMeta(), groups[0].AddChartVersion) + labels["app"] = appName + labels["app.kubernetes.io/name"] = appName - labels := obj.GetLabels() - if labels == nil { - labels = map[string]string{} - } - - labels["app"] = appName - labels["app.kubernetes.io/name"] = appName - - objs[i].SetLabels(labels) - } - return objs, nil -} + obj.SetLabels(labels) -func marshalObjToYaml(appName string, obj metav1.Object) (string, error) { yam, err := yaml.Marshal(obj) if err != nil { return "", err diff --git a/codegen/render/manifests_renderer_test.go b/codegen/render/manifests_renderer_test.go index ae9ef1d3b..5d9ed79c3 100644 --- a/codegen/render/manifests_renderer_test.go +++ b/codegen/render/manifests_renderer_test.go @@ -1,14 +1,10 @@ package render_test import ( - "fmt" - "strings" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" v1 "github.com/solo-io/skv2/codegen/test/api/things.test.io/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" "github.com/solo-io/skv2/codegen/model" "github.com/solo-io/skv2/codegen/render" @@ -55,13 +51,13 @@ var _ = Describe("ManifestsRenderer", func() { Expect(obj).To(Equal(expectedObj)) }) - Describe("Generate non-alpha versioned CRD", func() { + Describe("CRD gen", func() { var ( - grps []*model.Group + grp model.Group ) BeforeEach(func() { - grps = []*model.Group{{ + grp = model.Group{ RenderManifests: true, AddChartVersion: "1.0.0", Resources: []model.Resource{ @@ -73,375 +69,25 @@ var _ = Describe("ManifestsRenderer", func() { Message: &v1.AcrylicType{}, }, }, - Stored: true, }, - }}, - } - for i := range grps { - grps[i].Init() + }, } + grp.Init() }) It("Renderse manifests with chart and spec hash", func() { // get api-level code gen options from descriptors outFiles, err := render.RenderManifests( - "appName", "manifestDir", "protoDir", "enabledExperimentalApi", + "appName", "manifestDir", "protoDir", nil, model.GroupOptions{}, - grps, + grp, ) Expect(err).NotTo(HaveOccurred()) - Expect(outFiles).To(HaveLen(2)) // legacy and templated manifests + Expect(outFiles).To(HaveLen(1)) Expect(outFiles[0].Content).To(ContainSubstring(crdutils.CRDVersionKey + ": 1.0.0")) Expect(outFiles[0].Content).To(ContainSubstring(crdutils.CRDSpecHashKey + ": b6ec737002f7d02e")) - // only alpha versioned CRDs contain logic to conditionally render templates - Expect(outFiles[0].Content).To(Equal(outFiles[0].Content)) - }) - }) - - Describe("Generate alpha versioned CRD", func() { - var ( - grps []*model.Group - ) - - BeforeEach(func() { - grps = []*model.Group{{ - GroupVersion: schema.GroupVersion{ - Group: "things.test.io", - Version: "v1alpha1", - }, - RenderManifests: true, - AddChartVersion: "1.0.0", - Resources: []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - Stored: true, - }, - }}, - } - for i := range grps { - grps[i].Init() - } - }) - It("Renders manifests with template and spec hash", func() { - - // get api-level code gen options from descriptors - outFiles, err := render.RenderManifests( - "appName", "manifestDir", "protoDir", "enabledExperimentalApi", - nil, - model.GroupOptions{}, - grps, - ) - Expect(err).NotTo(HaveOccurred()) - Expect(outFiles).To(HaveLen(2)) // legacy and templated manifests - // only alpha versioned CRDs contain logic to conditionally render templates - Expect(outFiles[1].Content).To(HavePrefix("\n{{- if has \"kinds.things.test.io/v1alpha1\" $.Values.enabledExperimentalApi }}")) - Expect(outFiles[1].Content).To(HaveSuffix("{{- end }}\n---\n")) - Expect(outFiles[1].Content).To(ContainSubstring(crdutils.CRDVersionKey + ": 1.0.0")) - Expect(outFiles[1].Content).To(ContainSubstring(crdutils.CRDSpecHashKey + ": 80c06d3e2484e4c8")) - }) - }) - - Describe("Skip template for grandfathered alpha versioned CRD", func() { - var ( - grps []*model.Group - ) - BeforeEach(func() { - grps = []*model.Group{{ - GroupVersion: schema.GroupVersion{ - Group: "things.test.io", - Version: "v1alpha1", - }, - RenderManifests: true, - AddChartVersion: "1.0.0", - SkipConditionalCRDLoading: true, - Resources: []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - Stored: true, - }, - }}, - } - for i := range grps { - grps[i].Init() - } - }) - It("Renders manifests without template", func() { - // get api-level code gen options from descriptors - outFiles, err := render.RenderManifests( - "appName", "manifestDir", "protoDir", "enabledExperimentalApi", - nil, - model.GroupOptions{}, - grps, - ) - Expect(err).NotTo(HaveOccurred()) - Expect(outFiles).To(HaveLen(2)) // legacy and templated manifests - // only alpha versioned CRDs contain logic to conditionally render templates - Expect(outFiles[1].Content).ToNot(ContainSubstring("{{- if has \"kinds.things.test.io/v1alpha1\" $.Values.enabledExperimentalApi }}")) - Expect(outFiles[1].Content).ToNot(ContainSubstring("{{- end }}")) - }) - }) - - Describe("Generate combined alpha, grandfathered alpha, and non-alpha versioned CRD", func() { - var ( - grps []*model.Group - ) - - BeforeEach(func() { - grps = []*model.Group{{ - GroupVersion: schema.GroupVersion{ - Group: "things.test.io", - Version: "v3alpha1", - }, - RenderManifests: true, - AddChartVersion: "1.0.0", - Resources: []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - Stored: false, - }, - }}, - { - GroupVersion: schema.GroupVersion{ - Group: "things.test.io", - Version: "v2", - }, - RenderManifests: true, - AddChartVersion: "1.0.0", - Resources: []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - Stored: true, - }, - }}, - { - GroupVersion: schema.GroupVersion{ - Group: "things.test.io", - Version: "v1alpha1", - }, - RenderManifests: true, - AddChartVersion: "1.0.0", - SkipConditionalCRDLoading: true, - Resources: []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - Stored: true, - }, - }}, - } - for i := range grps { - grps[i].Init() - } - }) - It("Renderse manifests with chart and spec hash", func() { - - // get api-level code gen options from descriptors - outFiles, err := render.RenderManifests( - "appName", "manifestDir", "protoDir", "enabledExperimentalApi", - nil, - model.GroupOptions{}, - grps, - ) - Expect(err).NotTo(HaveOccurred()) - Expect(outFiles).To(HaveLen(2)) // legacy and templated manifests - // only v3alpha1 version of the CRDs is conditionally rendered, v2 and v1alpha1 have no conditions surrounding them - Expect(outFiles[1].Content).To(ContainSubstring("subresources: {}\n {{- if has \"kinds.things.test.io/v3alpha1\" $.Values.enabledExperimentalApi }}")) - Expect(outFiles[1].Content).ToNot(ContainSubstring("{{- if has \"kinds.things.test.io/v1alpha1\" $.Values.enabledExperimentalApi }}\n - name: v2alpha1")) - Expect(outFiles[1].Content).To(ContainSubstring("{{- end }}\n---\n")) - Expect(strings.Count(outFiles[1].Content, "{{- end }}")).To(Equal(1)) - }) - }) - - Describe("Generate combined alpha, grandfathered alpha, and non-alpha versioned CRD", func() { - var ( - grps []*model.Group - ) - - BeforeEach(func() { - grps = []*model.Group{{ - GroupVersion: schema.GroupVersion{ - Group: "things.test.io", - Version: "v3alpha1", - }, - RenderManifests: true, - AddChartVersion: "1.0.0", - Resources: []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - Stored: false, - }, - }}, - { - GroupVersion: schema.GroupVersion{ - Group: "things.test.io", - Version: "v2", - }, - RenderManifests: true, - AddChartVersion: "1.0.0", - Resources: []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - Stored: true, - }, - }}, - { - GroupVersion: schema.GroupVersion{ - Group: "things.test.io", - Version: "v1alpha1", - }, - RenderManifests: true, - AddChartVersion: "1.0.0", - SkipConditionalCRDLoading: true, - Resources: []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - Stored: true, - }, - }}, - } - for i := range grps { - grps[i].Init() - } - }) - It("Renderse manifests with chart and spec hash", func() { - - // get api-level code gen options from descriptors - outFiles, err := render.RenderManifests( - "appName", "manifestDir", "protoDir", "enabledExperimentalApi", - nil, - model.GroupOptions{}, - grps, - ) - Expect(err).NotTo(HaveOccurred()) - Expect(outFiles).To(HaveLen(2)) // legacy and templated manifests - // only v3alpha1 version of the CRDs is conditionally rendered, v2 and v1alpha1 have no conditions surrounding them - expectedTemplateString := "subresources: {}\n {{- if has \"kinds.things.test.io/v3alpha1\" $.Values.enabledExperimentalApi }}" - Expect(outFiles[1].Content).To(ContainSubstring(expectedTemplateString)) - Expect(strings.Count(outFiles[1].Content, expectedTemplateString)).To(Equal(1)) - Expect(outFiles[1].Content).ToNot(ContainSubstring("{{- if has \"kinds.things.test.io/v1alpha1\" $.Values.enabledExperimentalApi }}\n - name: v2alpha1")) - Expect(outFiles[1].Content).To(ContainSubstring("{{- end }}\n---\n")) - Expect(strings.Count(outFiles[1].Content, "{{- end }}\n---\n")).To(Equal(1)) - Expect(strings.Count(outFiles[1].Content, "{{- end }}")).To(Equal(1)) - }) - }) - - Describe("Render CRD template when 'EnabledAlphaApiFlagName' isn't set", func() { - It("and resource contains an alpha version that should not be skipped", func() { - grps := []*model.Group{{ - GroupVersion: schema.GroupVersion{ - Group: "things.test.io", - Version: "v3alpha1", - }, - RenderManifests: true, - AddChartVersion: "1.0.0", - Resources: []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - Stored: false, - }, - }}, - } - for i := range grps { - grps[i].Init() - } - - _, err := render.RenderManifests( - "appName", "manifestDir", "protoDir", "", - nil, - model.GroupOptions{}, - grps, - ) - Expect(err).ToNot(BeNil()) - Expect(err).To(Equal(fmt.Errorf("error rendering CRD template for kind kind: 'EnabledAlphaApiFlagName' is not defined"))) - }) - It("and resource contains an alpha version that should be skipped", func() { - grps := []*model.Group{{ - GroupVersion: schema.GroupVersion{ - Group: "things.test.io", - Version: "v3alpha1", - }, - RenderManifests: true, - AddChartVersion: "1.0.0", - SkipConditionalCRDLoading: true, - Resources: []model.Resource{ - { - Kind: "kind", - Spec: model.Field{ - Type: model.Type{ - Name: "test", - Message: &v1.AcrylicType{}, - }, - }, - Stored: false, - }, - }}, - } - for i := range grps { - grps[i].Init() - } - - _, err := render.RenderManifests( - "appName", "manifestDir", "protoDir", "", - nil, - model.GroupOptions{}, - grps, - ) - Expect(err).To(BeNil()) }) }) }) diff --git a/codegen/templates/manifests/crd.yamltmpl b/codegen/templates/manifests/crd.yamltmpl deleted file mode 100644 index db66b723f..000000000 --- a/codegen/templates/manifests/crd.yamltmpl +++ /dev/null @@ -1,30 +0,0 @@ -[[- range $crd := .Crds -]] -[[- if render_outer_conditional_crd_template $crd (index $crd.Spec.Versions 0).Name $.ShouldSkip ]] -{{- if has "[[ $crd.GetName ]]/[[ (index $crd.Spec.Versions 0).Name ]]" $.Values.[[ $.EnabledAlphaApiFlagName ]] }} -[[- end ]] -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: [[- $crd.GetAnnotations | toYaml | nindent 4 ]] - labels: [[- $crd.GetLabels | toYaml | nindent 4 ]] - name: [[ $crd.GetName ]] -spec: - group: [[ $crd.Spec.Group ]] - names: [[- $crd.Spec.Names | toYaml | nindent 4 ]] - scope: [[ $crd.Spec.Scope ]] - versions: - [[- range $version := $crd.Spec.Versions ]] - [[- if render_inner_conditional_crd_template $crd $version.Name $.ShouldSkip ]] - {{- if has "[[ $crd.GetName ]]/[[ $version.Name ]]" $.Values.[[ $.EnabledAlphaApiFlagName ]] }} - [[- end ]] - - - [[- $version | toYaml | indent 4 | trimPrefix " " ]] - [[- if render_inner_conditional_crd_template $crd $version.Name $.ShouldSkip ]] - {{- end }} - [[- end ]] - [[- end ]] -[[- if render_outer_conditional_crd_template $crd (index $crd.Spec.Versions 0).Name $.ShouldSkip ]] -{{- end }} -[[- end ]] ---- -[[ end ]] \ No newline at end of file diff --git a/codegen/test/chart-no-desc/crds/things.test.io_crds.yaml b/codegen/test/chart-no-desc/crds/things.test.io_v1_crds.yaml similarity index 100% rename from codegen/test/chart-no-desc/crds/things.test.io_crds.yaml rename to codegen/test/chart-no-desc/crds/things.test.io_v1_crds.yaml index b83d9e1b8..b44f06926 100644 --- a/codegen/test/chart-no-desc/crds/things.test.io_crds.yaml +++ b/codegen/test/chart-no-desc/crds/things.test.io_v1_crds.yaml @@ -1,38 +1,5 @@ # Code generated by skv2. DO NOT EDIT. -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - crd.solo.io/specHash: a7f6c51daca2a86e - labels: - app: "" - app.kubernetes.io/name: "" - name: clusterresources.things.test.io -spec: - group: things.test.io - names: - kind: ClusterResource - listKind: ClusterResourceList - plural: clusterresources - singular: clusterresource - scope: Cluster - versions: - - name: v1 - schema: - openAPIV3Schema: - properties: - spec: - properties: - imported: - type: string - type: object - type: object - served: true - storage: true - subresources: {} - ---- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -165,3 +132,36 @@ spec: storage: true subresources: status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + crd.solo.io/specHash: a7f6c51daca2a86e + labels: + app: "" + app.kubernetes.io/name: "" + name: clusterresources.things.test.io +spec: + group: things.test.io + names: + kind: ClusterResource + listKind: ClusterResourceList + plural: clusterresources + singular: clusterresource + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + imported: + type: string + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/codegen/test/chart-no-desc/templates/things.test.io_crds.yaml b/codegen/test/chart-no-desc/templates/things.test.io_crds.yaml deleted file mode 100644 index f5cc1031a..000000000 --- a/codegen/test/chart-no-desc/templates/things.test.io_crds.yaml +++ /dev/null @@ -1,169 +0,0 @@ -# Code generated by skv2. DO NOT EDIT. - - -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - crd.solo.io/specHash: a7f6c51daca2a86e - labels: - app: "" - app.kubernetes.io/name: "" - name: clusterresources.things.test.io -spec: - group: things.test.io - names: - kind: ClusterResource - listKind: ClusterResourceList - plural: clusterresources - singular: clusterresource - scope: Cluster - versions: - - name: v1 - schema: - openAPIV3Schema: - properties: - spec: - properties: - imported: - type: string - type: object - type: object - served: true - storage: true - subresources: {} ---- - -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - crd.solo.io/specHash: 52f9159d46759d37 - labels: - app: "" - app.kubernetes.io/name: "" - name: paints.things.test.io -spec: - group: things.test.io - names: - kind: Paint - listKind: PaintList - plural: paints - singular: paint - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - properties: - spec: - oneOf: - - not: - anyOf: - - required: - - acrylic - - properties: - oil: - oneOf: - - not: - anyOf: - - required: - - powder - - required: - - fluid - - required: - - powder - - required: - - fluid - required: - - oil - - required: - - acrylic - - properties: - oil: - oneOf: - - not: - anyOf: - - required: - - powder - - required: - - fluid - - required: - - powder - - required: - - fluid - required: - - oil - properties: - acrylic: - properties: - body: - enum: - - Light - - Medium - - Heavy - type: string - type: object - color: - properties: - hue: - type: string - value: - format: float - type: number - type: object - myFavorite: - type: object - x-kubernetes-preserve-unknown-fields: true - oil: - properties: - fluid: - type: string - powder: - type: string - waterMixable: - type: boolean - type: object - recursiveType: - properties: - protobufValue: - x-kubernetes-preserve-unknown-fields: true - recursiveField: - type: object - x-kubernetes-preserve-unknown-fields: true - recursiveFieldOutermostScope: - type: object - x-kubernetes-preserve-unknown-fields: true - repeatedRecursiveField: - items: - type: object - x-kubernetes-preserve-unknown-fields: true - type: array - type: object - type: object - status: - properties: - nearbyPaints: - additionalProperties: - properties: - x: - type: object - x-kubernetes-preserve-unknown-fields: true - "y": - type: object - x-kubernetes-preserve-unknown-fields: true - type: object - type: object - observedGeneration: - format: int64 - type: integer - percentRemaining: - format: int64 - type: integer - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- diff --git a/codegen/test/chart/crds/things.test.io_crds.yaml b/codegen/test/chart/crds/things.test.io_v1_crds.yaml similarity index 100% rename from codegen/test/chart/crds/things.test.io_crds.yaml rename to codegen/test/chart/crds/things.test.io_v1_crds.yaml index 3aa575da9..0a333a174 100644 --- a/codegen/test/chart/crds/things.test.io_crds.yaml +++ b/codegen/test/chart/crds/things.test.io_v1_crds.yaml @@ -1,38 +1,5 @@ # Code generated by skv2. DO NOT EDIT. -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - crd.solo.io/specHash: a7f6c51daca2a86e - labels: - app: "" - app.kubernetes.io/name: "" - name: clusterresources.things.test.io -spec: - group: things.test.io - names: - kind: ClusterResource - listKind: ClusterResourceList - plural: clusterresources - singular: clusterresource - scope: Cluster - versions: - - name: v1 - schema: - openAPIV3Schema: - properties: - spec: - properties: - imported: - type: string - type: object - type: object - served: true - storage: true - subresources: {} - ---- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -169,3 +136,36 @@ spec: storage: true subresources: status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + crd.solo.io/specHash: a7f6c51daca2a86e + labels: + app: "" + app.kubernetes.io/name: "" + name: clusterresources.things.test.io +spec: + group: things.test.io + names: + kind: ClusterResource + listKind: ClusterResourceList + plural: clusterresources + singular: clusterresource + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + imported: + type: string + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/codegen/test/chart/templates/things.test.io_crds.yaml b/codegen/test/chart/templates/things.test.io_crds.yaml deleted file mode 100644 index 50170ee18..000000000 --- a/codegen/test/chart/templates/things.test.io_crds.yaml +++ /dev/null @@ -1,173 +0,0 @@ -# Code generated by skv2. DO NOT EDIT. - - -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - crd.solo.io/specHash: a7f6c51daca2a86e - labels: - app: "" - app.kubernetes.io/name: "" - name: clusterresources.things.test.io -spec: - group: things.test.io - names: - kind: ClusterResource - listKind: ClusterResourceList - plural: clusterresources - singular: clusterresource - scope: Cluster - versions: - - name: v1 - schema: - openAPIV3Schema: - properties: - spec: - properties: - imported: - type: string - type: object - type: object - served: true - storage: true - subresources: {} ---- - -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - crd.solo.io/specHash: 888c42601b3e10b6 - labels: - app: "" - app.kubernetes.io/name: "" - name: paints.things.test.io -spec: - group: things.test.io - names: - kind: Paint - listKind: PaintList - plural: paints - singular: paint - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - properties: - spec: - oneOf: - - not: - anyOf: - - required: - - acrylic - - properties: - oil: - oneOf: - - not: - anyOf: - - required: - - powder - - required: - - fluid - - required: - - powder - - required: - - fluid - required: - - oil - - required: - - acrylic - - properties: - oil: - oneOf: - - not: - anyOf: - - required: - - powder - - required: - - fluid - - required: - - powder - - required: - - fluid - required: - - oil - properties: - acrylic: - properties: - body: - enum: - - Light - - Medium - - Heavy - type: string - type: object - color: - properties: - hue: - type: string - value: - format: float - type: number - type: object - myFavorite: - type: object - x-kubernetes-preserve-unknown-fields: true - oil: - properties: - fluid: - type: string - powder: - type: string - waterMixable: - type: boolean - type: object - recursiveType: - description: OpenAPI gen test for recursive fields - properties: - protobufValue: - x-kubernetes-preserve-unknown-fields: true - recursiveField: - type: object - x-kubernetes-preserve-unknown-fields: true - recursiveFieldOutermostScope: - description: |- - Ensure that FieldOptions can be defined using package name resolution that starts from the - outermost scope: https://developers.google.com/protocol-buffers/docs/proto3#packages_and_name_resolution - type: object - x-kubernetes-preserve-unknown-fields: true - repeatedRecursiveField: - items: - type: object - x-kubernetes-preserve-unknown-fields: true - type: array - type: object - type: object - status: - properties: - nearbyPaints: - additionalProperties: - properties: - x: - type: object - x-kubernetes-preserve-unknown-fields: true - "y": - type: object - x-kubernetes-preserve-unknown-fields: true - type: object - type: object - observedGeneration: - format: int64 - type: integer - percentRemaining: - format: int64 - type: integer - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- diff --git a/codegen/test/name_override_chart/crds/things.test.io_crds.yaml b/codegen/test/name_override_chart/crds/things.test.io_v1_crds.yaml similarity index 100% rename from codegen/test/name_override_chart/crds/things.test.io_crds.yaml rename to codegen/test/name_override_chart/crds/things.test.io_v1_crds.yaml index 649673502..69f3cbb1c 100644 --- a/codegen/test/name_override_chart/crds/things.test.io_crds.yaml +++ b/codegen/test/name_override_chart/crds/things.test.io_v1_crds.yaml @@ -4,19 +4,19 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - crd.solo.io/specHash: 2c0000aa4677e683 + crd.solo.io/specHash: 80e7931efac2214e labels: app: "" app.kubernetes.io/name: "" - name: clusterresources.things.test.io + name: paints.things.test.io spec: group: things.test.io names: - kind: ClusterResource - listKind: ClusterResourceList - plural: clusterresources - singular: clusterresource - scope: Cluster + kind: Paint + listKind: PaintList + plural: paints + singular: paint + scope: Namespaced versions: - name: v1 schema: @@ -25,26 +25,27 @@ spec: x-kubernetes-preserve-unknown-fields: true served: true storage: true - subresources: {} + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - crd.solo.io/specHash: 80e7931efac2214e + crd.solo.io/specHash: 2c0000aa4677e683 labels: app: "" app.kubernetes.io/name: "" - name: paints.things.test.io + name: clusterresources.things.test.io spec: group: things.test.io names: - kind: Paint - listKind: PaintList - plural: paints - singular: paint - scope: Namespaced + kind: ClusterResource + listKind: ClusterResourceList + plural: clusterresources + singular: clusterresource + scope: Cluster versions: - name: v1 schema: @@ -53,5 +54,4 @@ spec: x-kubernetes-preserve-unknown-fields: true served: true storage: true - subresources: - status: {} + subresources: {} diff --git a/codegen/test/name_override_chart/templates/things.test.io_crds.yaml b/codegen/test/name_override_chart/templates/things.test.io_crds.yaml deleted file mode 100644 index d23e63f00..000000000 --- a/codegen/test/name_override_chart/templates/things.test.io_crds.yaml +++ /dev/null @@ -1,59 +0,0 @@ -# Code generated by skv2. DO NOT EDIT. - - -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - crd.solo.io/specHash: 2c0000aa4677e683 - labels: - app: "" - app.kubernetes.io/name: "" - name: clusterresources.things.test.io -spec: - group: things.test.io - names: - kind: ClusterResource - listKind: ClusterResourceList - plural: clusterresources - singular: clusterresource - scope: Cluster - versions: - - name: v1 - schema: - openAPIV3Schema: - type: object - x-kubernetes-preserve-unknown-fields: true - served: true - storage: true - subresources: {} ---- - -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - crd.solo.io/specHash: 80e7931efac2214e - labels: - app: "" - app.kubernetes.io/name: "" - name: paints.things.test.io -spec: - group: things.test.io - names: - kind: Paint - listKind: PaintList - plural: paints - singular: paint - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - type: object - x-kubernetes-preserve-unknown-fields: true - served: true - storage: true - subresources: - status: {} ---- diff --git a/crds/multicluster.solo.io_crds.yaml b/crds/multicluster.solo.io_v1alpha1_crds.yaml similarity index 100% rename from crds/multicluster.solo.io_crds.yaml rename to crds/multicluster.solo.io_v1alpha1_crds.yaml diff --git a/go.mod b/go.mod index 80d53e146..3d59df981 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,6 @@ require ( github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 github.com/google/gnostic v0.5.7-v3refs - github.com/google/go-cmp v0.5.9 github.com/hashicorp/go-multierror v1.1.0 github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 github.com/iancoleman/strcase v0.1.3 @@ -81,6 +80,7 @@ require ( github.com/gobuffalo/packd v0.3.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect github.com/google/uuid v1.3.0 // indirect diff --git a/templates/multicluster.solo.io_crds.yaml b/templates/multicluster.solo.io_crds.yaml deleted file mode 100644 index f430e3c30..000000000 --- a/templates/multicluster.solo.io_crds.yaml +++ /dev/null @@ -1,161 +0,0 @@ -# Code generated by skv2. DO NOT EDIT. - - -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - crd.solo.io/specHash: 396fd84315636ecb - labels: - app: skv2 - app.kubernetes.io/name: skv2 - name: kubernetesclusters.multicluster.solo.io -spec: - group: multicluster.solo.io - names: - kind: KubernetesCluster - listKind: KubernetesClusterList - plural: kubernetesclusters - singular: kubernetescluster - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - properties: - spec: - description: Representation of a Kubernetes cluster that has been registered. - properties: - clusterDomain: - description: |- - name local DNS suffix used by the cluster. - used for building FQDNs for in-cluster services - defaults to 'cluster.local' - type: string - providerInfo: - description: Metadata for clusters provisioned from cloud providers. - oneOf: - - not: - anyOf: - - required: - - eks - - required: - - eks - properties: - eks: - description: Provider info for an AWS EKS provisioned cluster. - properties: - accountId: - description: AWS 12 digit account ID. - type: string - arn: - description: AWS ARN. - type: string - name: - description: EKS resource name. - type: string - region: - description: AWS region. - type: string - type: object - type: object - secretName: - description: name of the secret which contains the kubeconfig with information - to connect to the remote cluster. - type: string - type: object - status: - properties: - namespace: - description: The namespace in which cluster registration resources were - created. - type: string - policyRules: - description: The set of PolicyRules attached to ClusterRoles when this - cluster was registered. - items: - properties: - apiGroups: - description: |- - APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of - the enumerated resources in any API group will be allowed. - +optional - items: - type: string - type: array - nonResourceUrls: - description: |- - NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path - Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. - Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both. - +optional - items: - type: string - type: array - resourceNames: - description: |- - ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. - +optional - items: - type: string - type: array - resources: - description: |- - Resources is a list of resources this rule applies to. ResourceAll represents all resources. - +optional - items: - type: string - type: array - verbs: - description: Verbs is a list of Verbs that apply to ALL the ResourceKinds - and AttributeRestrictions contained in this rule. VerbAll represents - all kinds. - items: - type: string - type: array - type: object - type: array - status: - description: |- - List of statuses about the kubernetes cluster. - This list allows for multiple applications/pods to record their connection status. - items: - properties: - message: - description: A human readable message about the current state of - the object - type: string - observedGeneration: - description: |- - The most recently observed generation of the resource. This value corresponds to the `metadata.generation` of - a kubernetes resource - format: int64 - type: integer - owner: - description: |- - (optional) The owner of the status, this value can be used to identify the entity which wrote this status. - This is useful in situations where a given resource may have multiple owners. - nullable: true - type: string - processingTime: - description: The time at which this status was recorded - format: date-time - type: string - state: - description: The current state of the resource - enum: - - PENDING - - PROCESSING - - INVALID - - FAILED - - ACCEPTED - type: string - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} ----