@@ -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
559563func (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
781783func (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
905915func (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,13 +987,8 @@ 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 )
@@ -1600,3 +1604,23 @@ func AddIndex(c client.Client, obj runtime.Object, field string, extractValue cl
16001604
16011605 return nil
16021606}
1607+
1608+ func ensureTypeMeta (obj runtime.Object , gvk schema.GroupVersionKind ) error {
1609+ ta , err := meta .TypeAccessor (obj )
1610+ if err != nil {
1611+ return err
1612+ }
1613+ _ , isUnstructured := obj .(runtime.Unstructured )
1614+ _ , isPartialObject := obj .(* metav1.PartialObjectMetadata )
1615+ _ , isPartialObjectList := obj .(* metav1.PartialObjectMetadataList )
1616+ if ! isUnstructured && ! isPartialObject && ! isPartialObjectList {
1617+ ta .SetKind ("" )
1618+ ta .SetAPIVersion ("" )
1619+ return nil
1620+ }
1621+
1622+ ta .SetKind (gvk .Kind )
1623+ ta .SetAPIVersion (gvk .GroupVersion ().String ())
1624+
1625+ return nil
1626+ }
0 commit comments