Skip to content

Commit

Permalink
GVKForObject should handle multiple GVKs in Scheme gracefully
Browse files Browse the repository at this point in the history
- If the user sets the GVK, make sure that's in the list of the GVK
  returned from the Scheme.
- Always print out the multiple GVKs when erroring out
- Add more comments on where to find more information about this issue

Signed-off-by: Vince Prignano <vincepri@redhat.com>
  • Loading branch information
vincepri committed Feb 13, 2023
1 parent c98b7fd commit 48ec279
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions pkg/client/apiutil/apimachinery.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersi
return gvk, nil
}

// Use the given scheme to retrieve all the GVKs for the object.
gvks, isUnversioned, err := scheme.ObjectKinds(obj)
if err != nil {
return schema.GroupVersionKind{}, err
Expand All @@ -140,16 +141,34 @@ func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersi
return schema.GroupVersionKind{}, fmt.Errorf("cannot create group-version-kind for unversioned type %T", obj)
}

if len(gvks) < 1 {
return schema.GroupVersionKind{}, fmt.Errorf("no group-version-kinds associated with type %T", obj)
}
if len(gvks) > 1 {
// this should only trigger for things like metav1.XYZ --
// normal versioned types should be fine
switch {
case len(gvks) < 1:
// If the object has no GVK, the object might not have been registered with the scheme.
// or it's not a valid object.
return schema.GroupVersionKind{}, fmt.Errorf("no GroupVersionKind associated with type %T, was the type registered with the Scheme?", obj)
case len(gvks) > 1:
// We've found multiple GVKs for the object.
currentGVK := obj.GetObjectKind().GroupVersionKind()
if !currentGVK.Empty() {
// If the base object has a GVK, check if it's in the list of GVKs before using it.
for _, gvk := range gvks {
if gvk == currentGVK {
return gvk, nil
}
}
}

// This should only trigger for things like metav1.XYZ --
// normal versioned types should be fine.
//
// See https://github.com/kubernetes-sigs/controller-runtime/issues/362
// for more information.
return schema.GroupVersionKind{}, fmt.Errorf(
"multiple group-version-kinds associated with type %T, refusing to guess at one", obj)
"multiple GroupVersionKinds associated with type %T within the Scheme: this can happen when a type is registered for multiple GVKs at the same time, callers can either fix their type registration to only register it once, or specify the GroupVersionKind to use for object passed in; refusing to guess at one: %q", obj, gvks)
default:
// In any other case, we've found a single GVK for the object.
return gvks[0], nil
}
return gvks[0], nil
}

// RESTClientForGVK constructs a new rest.Interface capable of accessing the resource associated
Expand Down

0 comments on commit 48ec279

Please sign in to comment.