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 17, 2019
1 parent 83f6193 commit a3cca5d
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 1 deletion.
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 @@ -22,6 +22,7 @@ import (
"encoding/json"

"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/utils/pointer"

"sigs.k8s.io/controller-tools/pkg/markers"
)
Expand Down Expand Up @@ -58,6 +59,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 +78,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 +183,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.stops the API server. This marker stop 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 +338,13 @@ func (m Default) ApplyToSchema(schema *v1beta1.JSONSchemaProps) error {
schema.Default = &v1beta1.JSON{Raw: marshalledDefault}
return nil
}

func (m XPreserveUnknownFields) ApplyToSchema(schema *v1beta1.JSONSchemaProps) error {
schema.XPreserveUnknownFields = pointer.BoolPtr(true)
return nil
}

func (m XEmbeddedResource) ApplyToSchema(schema *v1beta1.JSONSchemaProps) error {
schema.XEmbeddedResource = true
return nil
}
24 changes: 23 additions & 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.

14 changes: 14 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 @@ -105,6 +106,19 @@ type CronJobSpec struct {
// This tests that object defaulting can be performed.
// +kubebuilder:default={{nested: {foo: "baz", bar: true}},{nested: {bar: false}}}
DefaultedObject []RootObject `json:"defaultedObject"`

// +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
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 @@ -4823,16 +4826,34 @@ 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
- schedule
- twoOfAKindPart0
- twoOfAKindPart1
- unprunedEmbeddedResource
- unprunedJSON
type: object
status:
description: CronJobStatus defines the observed state of CronJob
Expand Down

0 comments on commit a3cca5d

Please sign in to comment.