@@ -20,6 +20,7 @@ import (
2020 "fmt"
2121 "go/types"
2222
23+ apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
2324 "k8s.io/apimachinery/pkg/runtime/schema"
2425
2526 crdmarkers "sigs.k8s.io/controller-tools/pkg/crd/markers"
@@ -29,12 +30,17 @@ import (
2930)
3031
3132// Generator is a genall.Generator that generates CRDs.
32- type Generator struct {}
33+ type Generator struct {
34+ // TrivialVersions indicates that we should produce a legacy
35+ // "trival-version" CRD compatible with older (pre 1.13) Kubernetes API
36+ // servers. The storage version's schema will be used as the CRD's schema.
37+ TrivialVersions bool `marker:",optional"`
38+ }
3339
3440func (Generator ) RegisterMarkers (into * markers.Registry ) error {
3541 return crdmarkers .Register (into )
3642}
37- func (Generator ) Generate (ctx * genall.GenerationContext ) error {
43+ func (g Generator ) Generate (ctx * genall.GenerationContext ) error {
3844 parser := & Parser {
3945 Collector : ctx .Collector ,
4046 Checker : ctx .Checker ,
@@ -61,6 +67,9 @@ func (Generator) Generate(ctx *genall.GenerationContext) error {
6167 for _ , groupKind := range kubeKinds {
6268 parser .NeedCRDFor (groupKind )
6369 crd := parser .CustomResourceDefinitions [groupKind ]
70+ if g .TrivialVersions {
71+ toTrivialVersions (& crd )
72+ }
6473 fileName := fmt .Sprintf ("%s_%s.yaml" , crd .Spec .Group , crd .Spec .Names .Plural )
6574 if err := ctx .WriteYAML (crd , fileName ); err != nil {
6675 return err
@@ -70,6 +79,32 @@ func (Generator) Generate(ctx *genall.GenerationContext) error {
7079 return nil
7180}
7281
82+ // toTrivialVersions strips out all schemata except for the storage schema,
83+ // and moves that up into the root object. This makes the CRD compatible
84+ // with pre 1.13 clusters.
85+ func toTrivialVersions (crd * apiext.CustomResourceDefinition ) {
86+ var canonicalSchema * apiext.CustomResourceValidation
87+ var canonicalSubresources * apiext.CustomResourceSubresources
88+ var canonicalColumns []apiext.CustomResourceColumnDefinition
89+ for i , ver := range crd .Spec .Versions {
90+ if ver .Storage == true {
91+ canonicalSchema = ver .Schema
92+ canonicalSubresources = ver .Subresources
93+ canonicalColumns = ver .AdditionalPrinterColumns
94+ }
95+ crd .Spec .Versions [i ].Schema = nil
96+ crd .Spec .Versions [i ].Subresources = nil
97+ crd .Spec .Versions [i ].AdditionalPrinterColumns = nil
98+ }
99+ if canonicalSchema == nil {
100+ return
101+ }
102+
103+ crd .Spec .Validation = canonicalSchema
104+ crd .Spec .Subresources = canonicalSubresources
105+ crd .Spec .AdditionalPrinterColumns = canonicalColumns
106+ }
107+
73108// findMetav1 locates the actual package representing metav1 amongst
74109// the imports of the roots.
75110func findMetav1 (roots []* loader.Package ) * loader.Package {
0 commit comments