Skip to content

Commit c5cde12

Browse files
committed
Adds a client that enables strict field validation for all requests
1 parent 2c61cfe commit c5cde12

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

pkg/client/fieldvalidation.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package client
18+
19+
import (
20+
"context"
21+
22+
"k8s.io/apimachinery/pkg/api/meta"
23+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
"k8s.io/apimachinery/pkg/runtime"
25+
"k8s.io/apimachinery/pkg/runtime/schema"
26+
)
27+
28+
// WithStrictFieldValidation wraps a Client and configures strict field
29+
// validation to all write requests from this client.
30+
func WithStrictFieldValidation(c Client) Client {
31+
return &clientWithFieldValidation{
32+
validation: metav1.FieldValidationStrict,
33+
c: c,
34+
Reader: c,
35+
}
36+
}
37+
38+
type clientWithFieldValidation struct {
39+
validation string
40+
c Client
41+
Reader
42+
}
43+
44+
func (f *clientWithFieldValidation) Create(ctx context.Context, obj Object, opts ...CreateOption) error {
45+
return f.c.Create(ctx, obj, append([]CreateOption{FieldValidation(f.validation)}, opts...)...)
46+
}
47+
48+
func (f *clientWithFieldValidation) Update(ctx context.Context, obj Object, opts ...UpdateOption) error {
49+
return f.c.Update(ctx, obj, append([]UpdateOption{FieldValidation(f.validation)}, opts...)...)
50+
}
51+
52+
func (f *clientWithFieldValidation) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error {
53+
return f.c.Patch(ctx, obj, patch, append([]PatchOption{FieldValidation(f.validation)}, opts...)...)
54+
}
55+
56+
func (f *clientWithFieldValidation) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error {
57+
return f.c.Delete(ctx, obj, opts...)
58+
}
59+
60+
func (f *clientWithFieldValidation) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error {
61+
return f.c.DeleteAllOf(ctx, obj, opts...)
62+
}
63+
64+
func (f *clientWithFieldValidation) Scheme() *runtime.Scheme { return f.c.Scheme() }
65+
func (f *clientWithFieldValidation) RESTMapper() meta.RESTMapper { return f.c.RESTMapper() }
66+
func (f *clientWithFieldValidation) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) {
67+
return f.c.GroupVersionKindFor(obj)
68+
}
69+
70+
func (f *clientWithFieldValidation) IsObjectNamespaced(obj runtime.Object) (bool, error) {
71+
return f.c.IsObjectNamespaced(obj)
72+
}
73+
74+
func (f *clientWithFieldValidation) Status() StatusWriter {
75+
return &subresourceClientWithFieldValidation{
76+
validation: f.validation,
77+
subresourceWriter: f.c.Status(),
78+
}
79+
}
80+
81+
func (f *clientWithFieldValidation) SubResource(subresource string) SubResourceClient {
82+
c := f.c.SubResource(subresource)
83+
return &subresourceClientWithFieldValidation{
84+
validation: f.validation,
85+
subresourceWriter: c,
86+
SubResourceReader: c,
87+
}
88+
}
89+
90+
type subresourceClientWithFieldValidation struct {
91+
validation string
92+
subresourceWriter SubResourceWriter
93+
SubResourceReader
94+
}
95+
96+
func (f *subresourceClientWithFieldValidation) Create(ctx context.Context, obj Object, subresource Object, opts ...SubResourceCreateOption) error {
97+
return f.subresourceWriter.Create(ctx, obj, subresource, append([]SubResourceCreateOption{FieldValidation(f.validation)}, opts...)...)
98+
}
99+
100+
func (f *subresourceClientWithFieldValidation) Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error {
101+
return f.subresourceWriter.Update(ctx, obj, append([]SubResourceUpdateOption{FieldValidation(f.validation)}, opts...)...)
102+
}
103+
104+
func (f *subresourceClientWithFieldValidation) Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error {
105+
return f.subresourceWriter.Patch(ctx, obj, patch, append([]SubResourcePatchOption{FieldValidation(f.validation)}, opts...)...)
106+
}

pkg/client/options.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,39 @@ func (f FieldOwner) ApplyToSubResourceUpdate(opts *SubResourceUpdateOptions) {
169169
opts.FieldManager = string(f)
170170
}
171171

172+
// FieldValidation configures field validation for the given requests.
173+
type FieldValidation string
174+
175+
// ApplyToPatch applies this configuration to the given patch options.
176+
func (f FieldValidation) ApplyToPatch(opts *PatchOptions) {
177+
opts.FieldValidation = string(f)
178+
}
179+
180+
// ApplyToCreate applies this configuration to the given create options.
181+
func (f FieldValidation) ApplyToCreate(opts *CreateOptions) {
182+
opts.FieldValidation = string(f)
183+
}
184+
185+
// ApplyToUpdate applies this configuration to the given update options.
186+
func (f FieldValidation) ApplyToUpdate(opts *UpdateOptions) {
187+
opts.FieldValidation = string(f)
188+
}
189+
190+
// ApplyToSubResourcePatch applies this configuration to the given patch options.
191+
func (f FieldValidation) ApplyToSubResourcePatch(opts *SubResourcePatchOptions) {
192+
opts.FieldValidation = string(f)
193+
}
194+
195+
// ApplyToSubResourceCreate applies this configuration to the given create options.
196+
func (f FieldValidation) ApplyToSubResourceCreate(opts *SubResourceCreateOptions) {
197+
opts.FieldValidation = string(f)
198+
}
199+
200+
// ApplyToSubResourceUpdate applies this configuration to the given update options.
201+
func (f FieldValidation) ApplyToSubResourceUpdate(opts *SubResourceUpdateOptions) {
202+
opts.FieldValidation = string(f)
203+
}
204+
172205
// }}}
173206

174207
// {{{ Create Options

0 commit comments

Comments
 (0)