Skip to content

Commit ae6b39a

Browse files
authored
Merge pull request #345 from sttts/sttts-vendor-extensions
Add x-kubernetes-{embedded-resource,preserve-unknown-fields} support
2 parents 73ac12a + f370b86 commit ae6b39a

File tree

6 files changed

+98
-1
lines changed

6 files changed

+98
-1
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ require (
1717
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f
1818
k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783
1919
k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655
20+
k8s.io/utils v0.0.0-20190801114015-581e00157fb1
2021
sigs.k8s.io/yaml v1.1.0
2122
)

pkg/crd/markers/validation.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ var ValidationMarkers = mustMakeAllWithPrefix("kubebuilder:validation", markers.
5858
Enum(nil),
5959
Format(""),
6060
Type(""),
61+
XPreserveUnknownFields{},
62+
XEmbeddedResource{},
6163
)
6264

6365
// FieldOnlyMarkers list field-specific validation markers (i.e. those markers that don't make
@@ -75,6 +77,11 @@ var FieldOnlyMarkers = []*definitionWithHelp{
7577

7678
must(markers.MakeAnyTypeDefinition("kubebuilder:default", markers.DescribesField, Default{})).
7779
WithHelp(Default{}.Help()),
80+
81+
must(markers.MakeDefinition("kubebuilder:pruning:PreserveUnknownFields", markers.DescribesField, XPreserveUnknownFields{})).
82+
WithHelp(XPreserveUnknownFields{}.Help()),
83+
must(markers.MakeDefinition("kubebuilder:validation:EmbeddedResource", markers.DescribesField, XEmbeddedResource{})).
84+
WithHelp(XEmbeddedResource{}.Help()),
7885
}
7986

8087
func init() {
@@ -175,6 +182,26 @@ type Default struct {
175182
Value interface{}
176183
}
177184

185+
// +controllertools:marker:generateHelp:category="CRD processing"
186+
// PreserveUnknownFields stops the apiserver from pruning fields which are not specified.
187+
//
188+
// By default the apiserver drops unknown fields from the request payload
189+
// during the decoding step. This marker stops the API server from doing so.
190+
// It affects fields recursively, but switches back to normal pruning behaviour
191+
// if nested properties or additionalProperties are specified in the schema.
192+
// This can either be true or undefined. False
193+
// is forbidden.
194+
type XPreserveUnknownFields struct{}
195+
196+
// +controllertools:marker:generateHelp:category="CRD validation"
197+
// EmbeddedResource marks a fields as an embedded resource with apiVersion, kind and metadata fields.
198+
//
199+
// An embedded resource is a value that has apiVersion, kind and metadata fields.
200+
// They are validated implicitly according to the semantics of the currently
201+
// running apiserver. It is not necessary to add any additional schema for these
202+
// field, yet it is possible. This can be combined with PreserveUnknownFields.
203+
type XEmbeddedResource struct{}
204+
178205
func (m Maximum) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
179206
if schema.Type != "integer" {
180207
return fmt.Errorf("must apply maximum to an integer")
@@ -310,3 +337,14 @@ func (m Default) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
310337
schema.Default = &apiext.JSON{Raw: marshalledDefault}
311338
return nil
312339
}
340+
341+
func (m XPreserveUnknownFields) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
342+
defTrue := true
343+
schema.XPreserveUnknownFields = &defTrue
344+
return nil
345+
}
346+
347+
func (m XEmbeddedResource) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
348+
schema.XEmbeddedResource = true
349+
return nil
350+
}

pkg/crd/markers/zz_generated.markerhelp.go

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/crd/testdata/cronjob_types.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
batchv1beta1 "k8s.io/api/batch/v1beta1"
2929
corev1 "k8s.io/api/core/v1"
3030
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31+
"k8s.io/apimachinery/pkg/runtime"
3132
)
3233

3334
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
@@ -112,6 +113,19 @@ type CronJobSpec struct {
112113
// This tests that pattern validator is properly applied.
113114
// +kubebuilder:validation:Pattern=`^$|^((https):\/\/?)[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/?))$`
114115
PatternObject string `json:"patternObject"`
116+
117+
// +kubebuilder:validation:EmbeddedResource
118+
// +kubebuilder:validation:nullable
119+
EmbeddedResource runtime.RawExtension `json:"embeddedResource"`
120+
121+
// +kubebuilder:validation:nullable
122+
// +kubebuilder:pruning:PreserveUnknownFields
123+
UnprunedJSON NestedObject `json:"unprunedJSON"`
124+
125+
// +kubebuilder:pruning:PreserveUnknownFields
126+
// +kubebuilder:validation:EmbeddedResource
127+
// +kubebuilder:validation:nullable
128+
UnprunedEmbeddedResource runtime.RawExtension `json:"unprunedEmbeddedResource"`
115129
}
116130

117131
type NestedObject struct {
@@ -150,6 +164,7 @@ func (t *TotallyABool) UnmarshalJSON(in []byte) error {
150164
default:
151165
return fmt.Errorf("bad TotallyABool value %q", string(in))
152166
}
167+
return nil
153168
}
154169

155170
// ConcurrencyPolicy describes how the job will be handled.

pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ spec:
9797
default: forty-two
9898
description: This tests that primitive defaulting can be performed.
9999
type: string
100+
embeddedResource:
101+
type: object
102+
x-kubernetes-embedded-resource: true
100103
failedJobsHistoryLimit:
101104
description: The number of failed finished jobs to retain. This is
102105
a pointer to distinguish between explicit zero and not specified.
@@ -4983,17 +4986,35 @@ spec:
49834986
and types are applied to types
49844987
minLength: 4
49854988
type: string
4989+
unprunedEmbeddedResource:
4990+
type: object
4991+
x-kubernetes-embedded-resource: true
4992+
x-kubernetes-preserve-unknown-fields: true
4993+
unprunedJSON:
4994+
properties:
4995+
bar:
4996+
type: boolean
4997+
foo:
4998+
type: string
4999+
required:
5000+
- bar
5001+
- foo
5002+
type: object
5003+
x-kubernetes-preserve-unknown-fields: true
49865004
required:
49875005
- binaryName
49885006
- canBeNull
49895007
- defaultedObject
49905008
- defaultedSlice
49915009
- defaultedString
5010+
- embeddedResource
49925011
- jobTemplate
49935012
- patternObject
49945013
- schedule
49955014
- twoOfAKindPart0
49965015
- twoOfAKindPart1
5016+
- unprunedEmbeddedResource
5017+
- unprunedJSON
49975018
type: object
49985019
status:
49995020
description: CronJobStatus defines the observed state of CronJob

pkg/crd/zz_generated.markerhelp.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)