Skip to content

Commit 5292e2e

Browse files
committed
⚠️ Fakeclient: Clear typemeta for structured
The fakeclient currently differs from the liveclient in that if a structured object is created that has typemeta set, it will retain that. In contrast to that, the liveclient always strips it. This change makes the fakeclient strip it just like the live client.
1 parent 06ac559 commit 5292e2e

File tree

2 files changed

+143
-115
lines changed

2 files changed

+143
-115
lines changed

pkg/client/fake/client.go

Lines changed: 72 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,9 @@ func (t versionedTracker) Create(gvr schema.GroupVersionResource, obj runtime.Ob
332332
return fmt.Errorf("failed to get accessor for object: %w", err)
333333
}
334334
if accessor.GetName() == "" {
335+
gvk, _ := apiutil.GVKForObject(obj, t.scheme)
335336
return apierrors.NewInvalid(
336-
obj.GetObjectKind().GroupVersionKind().GroupKind(),
337+
gvk.GroupKind(),
337338
accessor.GetName(),
338339
field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
339340
}
@@ -433,8 +434,9 @@ func (t versionedTracker) updateObject(gvr schema.GroupVersionResource, obj runt
433434
}
434435

435436
if accessor.GetName() == "" {
437+
gvk, _ := apiutil.GVKForObject(obj, t.scheme)
436438
return nil, apierrors.NewInvalid(
437-
obj.GetObjectKind().GroupVersionKind().GroupKind(),
439+
gvk.GroupKind(),
438440
accessor.GetName(),
439441
field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
440442
}
@@ -527,33 +529,35 @@ func (c *fakeClient) Get(ctx context.Context, key client.ObjectKey, obj client.O
527529
if err != nil {
528530
return err
529531
}
532+
gvk, err := apiutil.GVKForObject(obj, c.scheme)
533+
if err != nil {
534+
return err
535+
}
530536
o, err := c.tracker.Get(gvr, key.Namespace, key.Name)
531537
if err != nil {
532538
return err
533539
}
534540

535-
_, isUnstructured := obj.(runtime.Unstructured)
536-
_, isPartialObject := obj.(*metav1.PartialObjectMetadata)
537-
538-
if isUnstructured || isPartialObject {
539-
gvk, err := apiutil.GVKForObject(obj, c.scheme)
540-
if err != nil {
541-
return err
542-
}
543-
ta, err := meta.TypeAccessor(o)
544-
if err != nil {
545-
return err
546-
}
547-
ta.SetKind(gvk.Kind)
548-
ta.SetAPIVersion(gvk.GroupVersion().String())
541+
ta, err := meta.TypeAccessor(o)
542+
if err != nil {
543+
return err
549544
}
550545

546+
// If the final object is unstructuctured, the json
547+
// representation must contain GVK or the apimachinery
548+
// json serializer will error out.
549+
ta.SetAPIVersion(gvk.GroupVersion().String())
550+
ta.SetKind(gvk.Kind)
551+
551552
j, err := json.Marshal(o)
552553
if err != nil {
553554
return err
554555
}
555556
zero(obj)
556-
return json.Unmarshal(j, obj)
557+
if err := json.Unmarshal(j, obj); err != nil {
558+
return err
559+
}
560+
return ensureTypeMeta(obj, gvk)
557561
}
558562

559563
func (c *fakeClient) Watch(ctx context.Context, list client.ObjectList, opts ...client.ListOption) (watch.Interface, error) {
@@ -579,8 +583,7 @@ func (c *fakeClient) List(ctx context.Context, obj client.ObjectList, opts ...cl
579583
return err
580584
}
581585

582-
originalKind := gvk.Kind
583-
586+
originalGVK := gvk
584587
gvk.Kind = strings.TrimSuffix(gvk.Kind, "List")
585588

586589
if _, isUnstructuredList := obj.(runtime.Unstructured); isUnstructuredList && !c.scheme.Recognizes(gvk) {
@@ -602,39 +605,28 @@ func (c *fakeClient) List(ctx context.Context, obj client.ObjectList, opts ...cl
602605
return err
603606
}
604607

605-
if _, isUnstructured := obj.(runtime.Unstructured); isUnstructured {
606-
ta, err := meta.TypeAccessor(o)
607-
if err != nil {
608-
return err
609-
}
610-
ta.SetKind(originalKind)
611-
ta.SetAPIVersion(gvk.GroupVersion().String())
612-
}
613-
614608
j, err := json.Marshal(o)
615609
if err != nil {
616610
return err
617611
}
618612
zero(obj)
613+
if err := ensureTypeMeta(obj, originalGVK); err != nil {
614+
return err
615+
}
619616
objCopy := obj.DeepCopyObject().(client.ObjectList)
620617
if err := json.Unmarshal(j, objCopy); err != nil {
621618
return err
622619
}
623620

624-
if _, isUnstructured := obj.(runtime.Unstructured); isUnstructured {
625-
ta, err := meta.TypeAccessor(obj)
626-
if err != nil {
627-
return err
628-
}
629-
ta.SetKind(originalKind)
630-
ta.SetAPIVersion(gvk.GroupVersion().String())
631-
}
632-
633621
objs, err := meta.ExtractList(objCopy)
634622
if err != nil {
635623
return err
636624
}
637625

626+
for _, o := range objs {
627+
ensureTypeMeta(o, gvk)
628+
}
629+
638630
if listOpts.LabelSelector == nil && listOpts.FieldSelector == nil {
639631
return meta.SetList(obj, objs)
640632
}
@@ -775,7 +767,15 @@ func (c *fakeClient) Create(ctx context.Context, obj client.Object, opts ...clie
775767

776768
c.trackerWriteLock.Lock()
777769
defer c.trackerWriteLock.Unlock()
778-
return c.tracker.Create(gvr, obj, accessor.GetNamespace())
770+
if err := c.tracker.Create(gvr, obj, accessor.GetNamespace()); err != nil {
771+
return err
772+
}
773+
774+
gvk, err := apiutil.GVKForObject(obj, c.scheme)
775+
if err != nil {
776+
return err
777+
}
778+
return ensureTypeMeta(obj, gvk)
779779
}
780780

781781
func (c *fakeClient) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error {
@@ -892,14 +892,22 @@ func (c *fakeClient) update(obj client.Object, isStatus bool, opts ...client.Upd
892892
if err != nil {
893893
return err
894894
}
895+
gvk, err := apiutil.GVKForObject(obj, c.scheme)
896+
if err != nil {
897+
return err
898+
}
895899
accessor, err := meta.Accessor(obj)
896900
if err != nil {
897901
return err
898902
}
899903

900904
c.trackerWriteLock.Lock()
901905
defer c.trackerWriteLock.Unlock()
902-
return c.tracker.update(gvr, obj, accessor.GetNamespace(), isStatus, false, *updateOptions.AsUpdateOptions())
906+
if err := c.tracker.update(gvr, obj, accessor.GetNamespace(), isStatus, false, *updateOptions.AsUpdateOptions()); err != nil {
907+
return err
908+
}
909+
910+
return ensureTypeMeta(obj, gvk)
903911
}
904912

905913
func (c *fakeClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error {
@@ -922,16 +930,15 @@ func (c *fakeClient) patch(obj client.Object, patch client.Patch, opts ...client
922930
if err != nil {
923931
return err
924932
}
925-
accessor, err := meta.Accessor(obj)
933+
gvk, err := apiutil.GVKForObject(obj, c.scheme)
926934
if err != nil {
927935
return err
928936
}
929-
data, err := patch.Data(obj)
937+
accessor, err := meta.Accessor(obj)
930938
if err != nil {
931939
return err
932940
}
933-
934-
gvk, err := apiutil.GVKForObject(obj, c.scheme)
941+
data, err := patch.Data(obj)
935942
if err != nil {
936943
return err
937944
}
@@ -978,13 +985,8 @@ func (c *fakeClient) patch(obj client.Object, patch client.Patch, opts ...client
978985
panic("tracker could not handle patch method")
979986
}
980987

981-
if _, isUnstructured := obj.(runtime.Unstructured); isUnstructured {
982-
ta, err := meta.TypeAccessor(o)
983-
if err != nil {
984-
return err
985-
}
986-
ta.SetKind(gvk.Kind)
987-
ta.SetAPIVersion(gvk.GroupVersion().String())
988+
if err := ensureTypeMeta(obj, gvk); err != nil {
989+
return err
988990
}
989991

990992
j, err := json.Marshal(o)
@@ -1600,3 +1602,23 @@ func AddIndex(c client.Client, obj runtime.Object, field string, extractValue cl
16001602

16011603
return nil
16021604
}
1605+
1606+
func ensureTypeMeta(obj runtime.Object, gvk schema.GroupVersionKind) error {
1607+
ta, err := meta.TypeAccessor(obj)
1608+
if err != nil {
1609+
return err
1610+
}
1611+
_, isUnstructured := obj.(runtime.Unstructured)
1612+
_, isPartialObject := obj.(*metav1.PartialObjectMetadata)
1613+
_, isPartialObjectList := obj.(*metav1.PartialObjectMetadataList)
1614+
if !isUnstructured && !isPartialObject && !isPartialObjectList {
1615+
ta.SetKind("")
1616+
ta.SetAPIVersion("")
1617+
return nil
1618+
}
1619+
1620+
ta.SetKind(gvk.Kind)
1621+
ta.SetAPIVersion(gvk.GroupVersion().String())
1622+
1623+
return nil
1624+
}

0 commit comments

Comments
 (0)