Skip to content

Commit

Permalink
Merge pull request #422 from jiachengxu/preserveunknownfields-dupmarkers
Browse files Browse the repository at this point in the history
✨Deprecate the duplicated kubebuilder:validation:XPreserveUnknownFields marker.
  • Loading branch information
k8s-ci-robot committed Oct 14, 2020
2 parents d9cb41e + 72b140e commit 6fa696d
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 3 deletions.
17 changes: 15 additions & 2 deletions pkg/crd/markers/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,20 @@ var FieldOnlyMarkers = []*definitionWithHelp{
must(markers.MakeAnyTypeDefinition("kubebuilder:default", markers.DescribesField, Default{})).
WithHelp(Default{}.Help()),

must(markers.MakeDefinition("kubebuilder:pruning:PreserveUnknownFields", markers.DescribesField, XPreserveUnknownFields{})).
WithHelp(XPreserveUnknownFields{}.Help()),
must(markers.MakeDefinition("kubebuilder:validation:EmbeddedResource", markers.DescribesField, XEmbeddedResource{})).
WithHelp(XEmbeddedResource{}.Help()),
}

// ValidationIshMarkers are field-and-type markers that don't fall under the
// :validation: prefix, and/or don't have a name that directly matches their
// type.
var ValidationIshMarkers = []*definitionWithHelp{
must(markers.MakeDefinition("kubebuilder:pruning:PreserveUnknownFields", markers.DescribesField, XPreserveUnknownFields{})).
WithHelp(XPreserveUnknownFields{}.Help()),
must(markers.MakeDefinition("kubebuilder:pruning:PreserveUnknownFields", markers.DescribesType, XPreserveUnknownFields{})).
WithHelp(XPreserveUnknownFields{}.Help()),
}

func init() {
AllDefinitions = append(AllDefinitions, ValidationMarkers...)

Expand All @@ -101,6 +109,7 @@ func init() {
}

AllDefinitions = append(AllDefinitions, FieldOnlyMarkers...)
AllDefinitions = append(AllDefinitions, ValidationIshMarkers...)
}

// +controllertools:marker:generateHelp:category="CRD validation"
Expand Down Expand Up @@ -201,6 +210,10 @@ type Default struct {
// if nested properties or additionalProperties are specified in the schema.
// This can either be true or undefined. False
// is forbidden.
//
// NB: The kubebuilder:validation:XPreserveUnknownFields variant is deprecated
// in favor of the kubebuilder:pruning:PreserveUnknownFields variant. They function
// identically.
type XPreserveUnknownFields struct{}

// +controllertools:marker:generateHelp:category="CRD validation"
Expand Down
2 changes: 1 addition & 1 deletion pkg/crd/markers/zz_generated.markerhelp.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions pkg/crd/testdata/cronjob_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ limitations under the License.
package cronjob

import (
"encoding/json"
"fmt"

batchv1beta1 "k8s.io/api/batch/v1beta1"
Expand Down Expand Up @@ -130,6 +131,9 @@ type CronJobSpec struct {
// +kubebuilder:validation:nullable
UnprunedEmbeddedResource runtime.RawExtension `json:"unprunedEmbeddedResource"`

// This tests that a type-level pruning maker works.
UnprunedFromType Preserved `json:"unprunedFomType"`

// This tests that associative lists work.
// +listType=map
// +listMapKey=name
Expand All @@ -152,6 +156,37 @@ type CronJobSpec struct {
MinMaxProperties MinMaxObject `json:"minMaxProperties,omitempty"`
}

// +kubebuilder:validation:Type=object
// +kubebuilder:pruning:PreserveUnknownFields
type Preserved struct {
ConcreteField string `json:"concreteField"`
Rest map[string]interface{} `json:"-"`
}
func (p *Preserved) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &p.Rest); err != nil {
return err
}
conc, found := p.Rest["concreteField"]
if !found {
return nil
}
concStr, isStr := conc.(string)
if !isStr {
return fmt.Errorf("concreteField was not string")
}
delete(p.Rest, "concreteField")
p.ConcreteField = concStr
return nil
}
func (p *Preserved) MarshalJSON() ([]byte, error) {
full := make(map[string]interface{}, len(p.Rest)+1)
for k, v := range p.Rest {
full[k] = v
}
full["concreteField"] = p.ConcreteField
return json.Marshal(full)
}

type NestedObject struct {
Foo string `json:"foo"`
Bar bool `json:"bar"`
Expand Down
10 changes: 10 additions & 0 deletions pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5120,6 +5120,15 @@ spec:
type: object
x-kubernetes-embedded-resource: true
x-kubernetes-preserve-unknown-fields: true
unprunedFomType:
description: This tests that a type-level pruning maker works.
properties:
concreteField:
type: string
required:
- concreteField
type: object
x-kubernetes-preserve-unknown-fields: true
unprunedJSON:
properties:
bar:
Expand Down Expand Up @@ -5147,6 +5156,7 @@ spec:
- twoOfAKindPart0
- twoOfAKindPart1
- unprunedEmbeddedResource
- unprunedFomType
- unprunedJSON
type: object
status:
Expand Down

0 comments on commit 6fa696d

Please sign in to comment.