Skip to content

Commit

Permalink
Add x-kubernetes-{embedded-resource,preserve-unknown-fields} support
Browse files Browse the repository at this point in the history
  • Loading branch information
sttts committed Oct 25, 2019
1 parent d556e7d commit b20b951
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 0 deletions.
1 change: 1 addition & 0 deletions Gopkg.lock

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

1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ require (
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f
k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783
k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655
k8s.io/utils v0.0.0-20190801114015-581e00157fb1
sigs.k8s.io/yaml v1.1.0
)
38 changes: 38 additions & 0 deletions pkg/crd/markers/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ var ValidationMarkers = mustMakeAllWithPrefix("kubebuilder:validation", markers.
Enum(nil),
Format(""),
Type(""),
XPreserveUnknownFields{},
XEmbeddedResource{},
)

// FieldOnlyMarkers list field-specific validation markers (i.e. those markers that don't make
Expand All @@ -75,6 +77,11 @@ 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()),
}

func init() {
Expand Down Expand Up @@ -175,6 +182,26 @@ type Default struct {
Value interface{}
}

// +controllertools:marker:generateHelp:category="CRD pruning"
// PreserveUnknownFields stops the apiserver from pruning fields which are not specified.
//
// By default the apiserver drops unknown fields from the request payload
// during the decoding step. This marker stops the API server from doing so.
// It affects fields recursively, but switches back to normal pruning behaviour
// if nested properties or additionalProperties are specified in the schema.
// This can either be true or undefined. False
// is forbidden.
type XPreserveUnknownFields struct{}

// +controllertools:marker:generateHelp:category="CRD validation"
// EmbeddedResource marks a fields as an embedded resource with apiVersion, kind and metadata fields.
//
// An embedded resource is a value that has apiVersion, kind and metadata fields.
// They are validated implicitly according to the semantics of the currently
// running apiserver. It is not necessary to add any additional schema for these
// field, yet it is possible. This can be combined with PreserveUnknownFields.
type XEmbeddedResource struct{}

func (m Maximum) ApplyToSchema(schema *v1beta1.JSONSchemaProps) error {
if schema.Type != "integer" {
return fmt.Errorf("must apply maximum to an integer")
Expand Down Expand Up @@ -310,3 +337,14 @@ func (m Default) ApplyToSchema(schema *v1beta1.JSONSchemaProps) error {
schema.Default = &v1beta1.JSON{Raw: marshalledDefault}
return nil
}

func (m XPreserveUnknownFields) ApplyToSchema(schema *v1beta1.JSONSchemaProps) error {
defTrue := true
schema.XPreserveUnknownFields = &defTrue
return nil
}

func (m XEmbeddedResource) ApplyToSchema(schema *v1beta1.JSONSchemaProps) error {
schema.XEmbeddedResource = true
return nil
}
22 changes: 22 additions & 0 deletions pkg/crd/markers/zz_generated.markerhelp.go

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

15 changes: 15 additions & 0 deletions pkg/crd/testdata/cronjob_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
batchv1beta1 "k8s.io/api/batch/v1beta1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
Expand Down Expand Up @@ -109,6 +110,19 @@ type CronJobSpec struct {
// This tests that pattern validator is properly applied.
// +kubebuilder:validation:Pattern=`^$|^((https):\/\/?)[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/?))$`
PatternObject string `json:"patternObject"`

// +kubebuilder:validation:EmbeddedResource
// +kubebuilder:validation:nullable
EmbeddedResource runtime.RawExtension `json:"embeddedResource"`

// +kubebuilder:validation:nullable
// +kubebuilder:pruning:PreserveUnknownFields
UnprunedJSON NestedObject `json:"unprunedJSON"`

// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:EmbeddedResource
// +kubebuilder:validation:nullable
UnprunedEmbeddedResource runtime.RawExtension `json:"unprunedEmbeddedResource"`
}

type NestedObject struct {
Expand Down Expand Up @@ -147,6 +161,7 @@ func (t *TotallyABool) UnmarshalJSON(in []byte) error {
default:
return fmt.Errorf("bad TotallyABool value %q", string(in))
}
return nil
}

// ConcurrencyPolicy describes how the job will be handled.
Expand Down
21 changes: 21 additions & 0 deletions pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ spec:
default: forty-two
description: This tests that primitive defaulting can be performed.
type: string
embeddedResource:
type: object
x-kubernetes-embedded-resource: true
failedJobsHistoryLimit:
description: The number of failed finished jobs to retain. This is a
pointer to distinguish between explicit zero and not specified.
Expand Down Expand Up @@ -4827,17 +4830,35 @@ spec:
and types are applied to types
minLength: 4
type: string
unprunedEmbeddedResource:
type: object
x-kubernetes-embedded-resource: true
x-kubernetes-preserve-unknown-fields: true
unprunedJSON:
properties:
bar:
type: boolean
foo:
type: string
required:
- bar
- foo
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- binaryName
- canBeNull
- defaultedObject
- defaultedSlice
- defaultedString
- embeddedResource
- jobTemplate
- patternObject
- schedule
- twoOfAKindPart0
- twoOfAKindPart1
- unprunedEmbeddedResource
- unprunedJSON
type: object
status:
description: CronJobStatus defines the observed state of CronJob
Expand Down

0 comments on commit b20b951

Please sign in to comment.