@@ -20,13 +20,80 @@ import (
2020 "context"
2121 "testing"
2222
23+ . "github.com/onsi/ginkgo/v2"
24+ . "github.com/onsi/gomega"
2325 corev1 "k8s.io/api/core/v1"
2426 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
28+ "k8s.io/apimachinery/pkg/runtime/schema"
2529 "sigs.k8s.io/controller-runtime/pkg/client"
2630 "sigs.k8s.io/controller-runtime/pkg/client/fake"
2731 "sigs.k8s.io/controller-runtime/pkg/client/interceptor"
2832)
2933
34+ var _ = Describe ("ClientWithFieldValidation" , func () {
35+ It ("should return errors for invalid fields when using strict validation" , func () {
36+ cl , err := client .New (cfg , client.Options {})
37+ Expect (err ).NotTo (HaveOccurred ())
38+ Expect (cl ).NotTo (BeNil ())
39+
40+ wrappedClient := client .WithFieldValidation (cl , metav1 .FieldValidationStrict )
41+ ctx := context .Background ()
42+
43+ baseNode := & unstructured.Unstructured {}
44+ baseNode .SetGroupVersionKind (schema.GroupVersionKind {
45+ Group : "" ,
46+ Kind : "Node" ,
47+ Version : "v1" ,
48+ })
49+ baseNode .SetName ("client-with-field-validation-test-node" )
50+
51+ validNode := baseNode .DeepCopy ()
52+ patch := client .MergeFrom (validNode .DeepCopy ())
53+
54+ invalidNode := baseNode .DeepCopy ()
55+ Expect (unstructured .SetNestedField (invalidNode .Object , "value" , "spec" , "invalidField" )).To (Succeed ())
56+
57+ invalidStatusNode := baseNode .DeepCopy ()
58+ Expect (unstructured .SetNestedField (invalidStatusNode .Object , "value" , "status" , "invalidStatusField" )).To (Succeed ())
59+
60+ err = wrappedClient .Create (ctx , invalidNode )
61+ Expect (err ).To (HaveOccurred ())
62+ Expect (err .Error ()).To (ContainSubstring ("strict decoding error: unknown field \" spec.invalidField\" " ))
63+
64+ err = wrappedClient .Create (ctx , validNode )
65+ Expect (err ).ToNot (HaveOccurred ())
66+
67+ err = wrappedClient .Update (ctx , invalidNode )
68+ Expect (err ).To (HaveOccurred ())
69+ Expect (err .Error ()).To (ContainSubstring ("strict decoding error: unknown field \" spec.invalidField\" " ))
70+
71+ err = wrappedClient .Patch (ctx , invalidNode , patch )
72+ Expect (err ).To (HaveOccurred ())
73+ Expect (err .Error ()).To (ContainSubstring ("strict decoding error: unknown field \" spec.invalidField\" " ))
74+
75+ // Status.Create is not supported on Nodes
76+
77+ err = wrappedClient .Status ().Update (ctx , invalidStatusNode )
78+ Expect (err ).To (HaveOccurred ())
79+ Expect (err .Error ()).To (ContainSubstring ("strict decoding error: unknown field \" status.invalidStatusField\" " ))
80+
81+ err = wrappedClient .Status ().Patch (ctx , invalidStatusNode , patch )
82+ Expect (err ).To (HaveOccurred ())
83+ Expect (err .Error ()).To (ContainSubstring ("strict decoding error: unknown field \" status.invalidStatusField\" " ))
84+
85+ // Status.Create is not supported on Nodes
86+
87+ err = wrappedClient .SubResource ("status" ).Update (ctx , invalidStatusNode )
88+ Expect (err ).To (HaveOccurred ())
89+ Expect (err .Error ()).To (ContainSubstring ("strict decoding error: unknown field \" status.invalidStatusField\" " ))
90+
91+ err = wrappedClient .SubResource ("status" ).Patch (ctx , invalidStatusNode , patch )
92+ Expect (err ).To (HaveOccurred ())
93+ Expect (err .Error ()).To (ContainSubstring ("strict decoding error: unknown field \" status.invalidStatusField\" " ))
94+ })
95+ })
96+
3097func TestWithStrictFieldValidation (t * testing.T ) {
3198 calls := 0
3299 fakeClient := testFieldValidationClient (t , metav1 .FieldValidationStrict , func () { calls ++ })
@@ -88,6 +155,16 @@ func testFieldValidationClient(t *testing.T, expectedFieldValidation string, cal
88155 if got := out .FieldValidation ; expectedFieldValidation != got {
89156 t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
90157 }
158+
159+ if got := out .AsCreateOptions ().FieldValidation ; expectedFieldValidation != got {
160+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
161+ }
162+
163+ co := & client.CreateOptions {}
164+ out .ApplyToCreate (co )
165+ if got := co .FieldValidation ; expectedFieldValidation != got {
166+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
167+ }
91168 return nil
92169 },
93170 Update : func (ctx context.Context , c client.WithWatch , obj client.Object , opts ... client.UpdateOption ) error {
@@ -99,6 +176,16 @@ func testFieldValidationClient(t *testing.T, expectedFieldValidation string, cal
99176 if got := out .FieldValidation ; expectedFieldValidation != got {
100177 t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
101178 }
179+
180+ if got := out .AsUpdateOptions ().FieldValidation ; expectedFieldValidation != got {
181+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
182+ }
183+
184+ co := & client.UpdateOptions {}
185+ out .ApplyToUpdate (co )
186+ if got := co .FieldValidation ; expectedFieldValidation != got {
187+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
188+ }
102189 return nil
103190 },
104191 Patch : func (ctx context.Context , c client.WithWatch , obj client.Object , patch client.Patch , opts ... client.PatchOption ) error {
@@ -110,6 +197,16 @@ func testFieldValidationClient(t *testing.T, expectedFieldValidation string, cal
110197 if got := out .FieldValidation ; expectedFieldValidation != got {
111198 t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
112199 }
200+
201+ if got := out .AsPatchOptions ().FieldValidation ; expectedFieldValidation != got {
202+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
203+ }
204+
205+ co := & client.PatchOptions {}
206+ out .ApplyToPatch (co )
207+ if got := co .FieldValidation ; expectedFieldValidation != got {
208+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
209+ }
113210 return nil
114211 },
115212 SubResourceCreate : func (ctx context.Context , c client.Client , subResourceName string , obj client.Object , subResource client.Object , opts ... client.SubResourceCreateOption ) error {
@@ -121,6 +218,16 @@ func testFieldValidationClient(t *testing.T, expectedFieldValidation string, cal
121218 if got := out .FieldValidation ; expectedFieldValidation != got {
122219 t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
123220 }
221+
222+ if got := out .AsCreateOptions ().FieldValidation ; expectedFieldValidation != got {
223+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
224+ }
225+
226+ co := & client.CreateOptions {}
227+ out .ApplyToCreate (co )
228+ if got := co .FieldValidation ; expectedFieldValidation != got {
229+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
230+ }
124231 return nil
125232 },
126233 SubResourceUpdate : func (ctx context.Context , c client.Client , subResourceName string , obj client.Object , opts ... client.SubResourceUpdateOption ) error {
@@ -132,6 +239,16 @@ func testFieldValidationClient(t *testing.T, expectedFieldValidation string, cal
132239 if got := out .FieldValidation ; expectedFieldValidation != got {
133240 t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
134241 }
242+
243+ if got := out .AsUpdateOptions ().FieldValidation ; expectedFieldValidation != got {
244+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
245+ }
246+
247+ co := & client.UpdateOptions {}
248+ out .ApplyToUpdate (co )
249+ if got := co .FieldValidation ; expectedFieldValidation != got {
250+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
251+ }
135252 return nil
136253 },
137254 SubResourcePatch : func (ctx context.Context , c client.Client , subResourceName string , obj client.Object , patch client.Patch , opts ... client.SubResourcePatchOption ) error {
@@ -143,6 +260,16 @@ func testFieldValidationClient(t *testing.T, expectedFieldValidation string, cal
143260 if got := out .FieldValidation ; expectedFieldValidation != got {
144261 t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
145262 }
263+
264+ if got := out .AsPatchOptions ().FieldValidation ; expectedFieldValidation != got {
265+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
266+ }
267+
268+ co := & client.PatchOptions {}
269+ out .ApplyToPatch (co )
270+ if got := co .FieldValidation ; expectedFieldValidation != got {
271+ t .Fatalf ("wrong field validation: expected=%q; got=%q" , expectedFieldValidation , got )
272+ }
146273 return nil
147274 },
148275 }).Build ()
0 commit comments