Skip to content

Commit

Permalink
Merge pull request #2202 from k8s-infra-cherrypick-robot/cherry-pick-…
Browse files Browse the repository at this point in the history
…2192-to-release-0.14

[release-0.14] 🌱 GVKForObject should handle multiple GVKs in Scheme gracefully
  • Loading branch information
k8s-ci-robot authored Feb 17, 2023
2 parents 7a19e15 + 1e00eec commit b6fc422
Showing 1 changed file with 32 additions and 8 deletions.
40 changes: 32 additions & 8 deletions pkg/client/apiutil/apimachinery.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,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 @@ -103,16 +104,39 @@ 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 Go type %T, was the type registered with the Scheme?", obj)
case len(gvks) > 1:
err := fmt.Errorf("multiple GroupVersionKinds associated with Go type %T within the Scheme, this can happen when a type is registered for multiple GVKs at the same time", obj)

// 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
}
}

return schema.GroupVersionKind{}, fmt.Errorf(
"%w: the object's supplied GroupVersionKind %q was not found in the Scheme's list; refusing to guess at one: %q", err, currentGVK, gvks)
}

// 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)
"%w: 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", err, 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 b6fc422

Please sign in to comment.