Skip to content

Commit

Permalink
crd: allow specifying spec.preserveUnknownFields
Browse files Browse the repository at this point in the history
Reinstate crd:preserveUnknownFields option removed by kubernetes-sigs#607
to allow specifying the value of deprecated spec.preserveUnknownFields
CRD field.

This is useful for updating CRDs that were automatically converted from
v1beta1 version which had true as a default value and resulted in:
```
$ kubectl get crd foo.bar -o yaml | grep preserveUnknownFields
  preserveUnknownFields: true
    message: 'spec.preserveUnknownFields: Invalid value: true: must be false'
```

For kubernetes-sigs#476
  • Loading branch information
AlexanderYastrebov committed Apr 11, 2024
1 parent 4c82505 commit 818eebe
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
27 changes: 26 additions & 1 deletion pkg/crd/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ type Generator struct {

// Year specifies the year to substitute for " YEAR" in the header file.
Year string `marker:",optional"`

// PreserveUnknownFields indicates whether or not we should turn off pruning.
//
// Specifies spec.preserveUnknownFields value that is false and omitted by default.
//
// It's required to be false for v1 CRDs.
PreserveUnknownFields *bool `marker:",optional"`
}

func (Generator) CheckFilter() loader.NodeFilter {
Expand All @@ -100,6 +107,16 @@ func transformRemoveCRDStatus(obj map[string]interface{}) error {
return nil
}

// transformPreserveUnknownFields adds spec.preserveUnknownFields=value.
func transformPreserveUnknownFields(value bool) func(map[string]interface{}) error {
return func(obj map[string]interface{}) error {
if spec, ok := obj["spec"].(map[interface{}]interface{}); ok {
spec["preserveUnknownFields"] = value
}
return nil
}
}

func (g Generator) Generate(ctx *genall.GenerationContext) error {
parser := &Parser{
Collector: ctx.Collector,
Expand Down Expand Up @@ -146,6 +163,14 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
}
headerText = strings.ReplaceAll(headerText, " YEAR", " "+g.Year)

yamlOpts := []*genall.WriteYAMLOptions{
genall.WithTransform(transformRemoveCRDStatus),
genall.WithTransform(genall.TransformRemoveCreationTimestamp),
}
if g.PreserveUnknownFields != nil {
yamlOpts = append(yamlOpts, genall.WithTransform(transformPreserveUnknownFields(*g.PreserveUnknownFields)))
}

for _, groupKind := range kubeKinds {
parser.NeedCRDFor(groupKind, g.MaxDescLen)
crdRaw := parser.CustomResourceDefinitions[groupKind]
Expand All @@ -171,7 +196,7 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
} else {
fileName = fmt.Sprintf("%s_%s.%s.yaml", crdRaw.Spec.Group, crdRaw.Spec.Names.Plural, crdVersions[i])
}
if err := ctx.WriteYAML(fileName, headerText, []interface{}{crd}, genall.WithTransform(transformRemoveCRDStatus), genall.WithTransform(genall.TransformRemoveCreationTimestamp)); err != nil {
if err := ctx.WriteYAML(fileName, headerText, []interface{}{crd}, yamlOpts...); err != nil {
return err
}
}
Expand Down
37 changes: 37 additions & 0 deletions pkg/crd/gen_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,43 @@ var _ = Describe("CRD Generation proper defaulting", func() {
expectedOut := string(expectedFileFoos) + string(expectedFileZoos)
Expect(out.buf.String()).To(Equal(expectedOut), cmp.Diff(out.buf.String(), expectedOut))
})

It("should add preserveUnknownFields=false when specified", func() {
By("calling Generate")
no := false
gen := &crd.Generator{
CRDVersions: []string{"v1"},
PreserveUnknownFields: &no,
}
Expect(gen.Generate(ctx)).NotTo(HaveOccurred())

By("searching preserveUnknownFields")
Expect(out.buf.String()).To(ContainSubstring("preserveUnknownFields: false"))
})

It("should add preserveUnknownFields=true when specified", func() {
By("calling Generate")
yes := true
gen := &crd.Generator{
CRDVersions: []string{"v1"},
PreserveUnknownFields: &yes,
}
Expect(gen.Generate(ctx)).NotTo(HaveOccurred())

By("searching preserveUnknownFields")
Expect(out.buf.String()).To(ContainSubstring("preserveUnknownFields: true"))
})

It("should not add preserveUnknownFields when not specified", func() {
By("calling Generate")
gen := &crd.Generator{
CRDVersions: []string{"v1"},
}
Expect(gen.Generate(ctx)).NotTo(HaveOccurred())

By("searching preserveUnknownFields")
Expect(out.buf.String()).NotTo(ContainSubstring("preserveUnknownFields"))
})
})

// fixAnnotations fixes the attribution annotation for tests.
Expand Down

0 comments on commit 818eebe

Please sign in to comment.