Skip to content

Commit fdc8bd7

Browse files
authored
Merge pull request #2913 from sbueringer/pr-test-cov-field-validation
🐛 Fix WithFieldValidation client
2 parents e882354 + 7dfd3bb commit fdc8bd7

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

pkg/client/fieldvalidation_test.go

+127
Original file line numberDiff line numberDiff line change
@@ -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+
3097
func 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()

pkg/client/options.go

+12
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ func (o *CreateOptions) AsCreateOptions() *metav1.CreateOptions {
254254

255255
o.Raw.DryRun = o.DryRun
256256
o.Raw.FieldManager = o.FieldManager
257+
o.Raw.FieldValidation = o.FieldValidation
257258
return o.Raw
258259
}
259260

@@ -274,6 +275,9 @@ func (o *CreateOptions) ApplyToCreate(co *CreateOptions) {
274275
if o.FieldManager != "" {
275276
co.FieldManager = o.FieldManager
276277
}
278+
if o.FieldValidation != "" {
279+
co.FieldValidation = o.FieldValidation
280+
}
277281
if o.Raw != nil {
278282
co.Raw = o.Raw
279283
}
@@ -764,6 +768,7 @@ func (o *UpdateOptions) AsUpdateOptions() *metav1.UpdateOptions {
764768

765769
o.Raw.DryRun = o.DryRun
766770
o.Raw.FieldManager = o.FieldManager
771+
o.Raw.FieldValidation = o.FieldValidation
767772
return o.Raw
768773
}
769774

@@ -786,6 +791,9 @@ func (o *UpdateOptions) ApplyToUpdate(uo *UpdateOptions) {
786791
if o.FieldManager != "" {
787792
uo.FieldManager = o.FieldManager
788793
}
794+
if o.FieldValidation != "" {
795+
uo.FieldValidation = o.FieldValidation
796+
}
789797
if o.Raw != nil {
790798
uo.Raw = o.Raw
791799
}
@@ -858,6 +866,7 @@ func (o *PatchOptions) AsPatchOptions() *metav1.PatchOptions {
858866
o.Raw.DryRun = o.DryRun
859867
o.Raw.Force = o.Force
860868
o.Raw.FieldManager = o.FieldManager
869+
o.Raw.FieldValidation = o.FieldValidation
861870
return o.Raw
862871
}
863872

@@ -874,6 +883,9 @@ func (o *PatchOptions) ApplyToPatch(po *PatchOptions) {
874883
if o.FieldManager != "" {
875884
po.FieldManager = o.FieldManager
876885
}
886+
if o.FieldValidation != "" {
887+
po.FieldValidation = o.FieldValidation
888+
}
877889
if o.Raw != nil {
878890
po.Raw = o.Raw
879891
}

0 commit comments

Comments
 (0)