Skip to content

Commit f8773da

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 f8773da

File tree

2 files changed

+166
-116
lines changed

2 files changed

+166
-116
lines changed

pkg/client/fake/client.go

Lines changed: 79 additions & 51 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,30 @@ 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+
if err := ensureTypeMeta(o, gvk); err != nil {
628+
return err
629+
}
630+
}
631+
638632
if listOpts.LabelSelector == nil && listOpts.FieldSelector == nil {
639633
return meta.SetList(obj, objs)
640634
}
@@ -775,7 +769,15 @@ func (c *fakeClient) Create(ctx context.Context, obj client.Object, opts ...clie
775769

776770
c.trackerWriteLock.Lock()
777771
defer c.trackerWriteLock.Unlock()
778-
return c.tracker.Create(gvr, obj, accessor.GetNamespace())
772+
if err := c.tracker.Create(gvr, obj, accessor.GetNamespace()); err != nil {
773+
return err
774+
}
775+
776+
gvk, err := apiutil.GVKForObject(obj, c.scheme)
777+
if err != nil {
778+
return err
779+
}
780+
return ensureTypeMeta(obj, gvk)
779781
}
780782

781783
func (c *fakeClient) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error {
@@ -892,14 +894,22 @@ func (c *fakeClient) update(obj client.Object, isStatus bool, opts ...client.Upd
892894
if err != nil {
893895
return err
894896
}
897+
gvk, err := apiutil.GVKForObject(obj, c.scheme)
898+
if err != nil {
899+
return err
900+
}
895901
accessor, err := meta.Accessor(obj)
896902
if err != nil {
897903
return err
898904
}
899905

900906
c.trackerWriteLock.Lock()
901907
defer c.trackerWriteLock.Unlock()
902-
return c.tracker.update(gvr, obj, accessor.GetNamespace(), isStatus, false, *updateOptions.AsUpdateOptions())
908+
if err := c.tracker.update(gvr, obj, accessor.GetNamespace(), isStatus, false, *updateOptions.AsUpdateOptions()); err != nil {
909+
return err
910+
}
911+
912+
return ensureTypeMeta(obj, gvk)
903913
}
904914

905915
func (c *fakeClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error {
@@ -922,16 +932,15 @@ func (c *fakeClient) patch(obj client.Object, patch client.Patch, opts ...client
922932
if err != nil {
923933
return err
924934
}
925-
accessor, err := meta.Accessor(obj)
935+
gvk, err := apiutil.GVKForObject(obj, c.scheme)
926936
if err != nil {
927937
return err
928938
}
929-
data, err := patch.Data(obj)
939+
accessor, err := meta.Accessor(obj)
930940
if err != nil {
931941
return err
932942
}
933-
934-
gvk, err := apiutil.GVKForObject(obj, c.scheme)
943+
data, err := patch.Data(obj)
935944
if err != nil {
936945
return err
937946
}
@@ -978,21 +987,20 @@ func (c *fakeClient) patch(obj client.Object, patch client.Patch, opts ...client
978987
panic("tracker could not handle patch method")
979988
}
980989

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())
990+
if err := ensureTypeMeta(obj, gvk); err != nil {
991+
return err
988992
}
989993

990994
j, err := json.Marshal(o)
991995
if err != nil {
992996
return err
993997
}
994998
zero(obj)
995-
return json.Unmarshal(j, obj)
999+
if err := json.Unmarshal(j, obj); err != nil {
1000+
return err
1001+
}
1002+
1003+
return ensureTypeMeta(obj, gvk)
9961004
}
9971005

9981006
// Applying a patch results in a deletionTimestamp that is truncated to the nearest second.
@@ -1600,3 +1608,23 @@ func AddIndex(c client.Client, obj runtime.Object, field string, extractValue cl
16001608

16011609
return nil
16021610
}
1611+
1612+
func ensureTypeMeta(obj runtime.Object, gvk schema.GroupVersionKind) error {
1613+
ta, err := meta.TypeAccessor(obj)
1614+
if err != nil {
1615+
return err
1616+
}
1617+
_, isUnstructured := obj.(runtime.Unstructured)
1618+
_, isPartialObject := obj.(*metav1.PartialObjectMetadata)
1619+
_, isPartialObjectList := obj.(*metav1.PartialObjectMetadataList)
1620+
if !isUnstructured && !isPartialObject && !isPartialObjectList {
1621+
ta.SetKind("")
1622+
ta.SetAPIVersion("")
1623+
return nil
1624+
}
1625+
1626+
ta.SetKind(gvk.Kind)
1627+
ta.SetAPIVersion(gvk.GroupVersion().String())
1628+
1629+
return nil
1630+
}

0 commit comments

Comments
 (0)