@@ -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,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
781781func (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
905913func (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