Skip to content

Commit 25d6edd

Browse files
authored
Merge pull request #2192 from vincepri/gvk-for-object-multiple-hits
🌱 GVKForObject should handle multiple GVKs in Scheme gracefully
2 parents c98506d + ea10051 commit 25d6edd

File tree

1 file changed

+32
-8
lines changed

1 file changed

+32
-8
lines changed

pkg/client/apiutil/apimachinery.go

+32-8
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersi
132132
return gvk, nil
133133
}
134134

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

143-
if len(gvks) < 1 {
144-
return schema.GroupVersionKind{}, fmt.Errorf("no group-version-kinds associated with type %T", obj)
145-
}
146-
if len(gvks) > 1 {
147-
// this should only trigger for things like metav1.XYZ --
148-
// normal versioned types should be fine
144+
switch {
145+
case len(gvks) < 1:
146+
// If the object has no GVK, the object might not have been registered with the scheme.
147+
// or it's not a valid object.
148+
return schema.GroupVersionKind{}, fmt.Errorf("no GroupVersionKind associated with Go type %T, was the type registered with the Scheme?", obj)
149+
case len(gvks) > 1:
150+
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)
151+
152+
// We've found multiple GVKs for the object.
153+
currentGVK := obj.GetObjectKind().GroupVersionKind()
154+
if !currentGVK.Empty() {
155+
// If the base object has a GVK, check if it's in the list of GVKs before using it.
156+
for _, gvk := range gvks {
157+
if gvk == currentGVK {
158+
return gvk, nil
159+
}
160+
}
161+
162+
return schema.GroupVersionKind{}, fmt.Errorf(
163+
"%w: the object's supplied GroupVersionKind %q was not found in the Scheme's list; refusing to guess at one: %q", err, currentGVK, gvks)
164+
}
165+
166+
// This should only trigger for things like metav1.XYZ --
167+
// normal versioned types should be fine.
168+
//
169+
// See https://github.com/kubernetes-sigs/controller-runtime/issues/362
170+
// for more information.
149171
return schema.GroupVersionKind{}, fmt.Errorf(
150-
"multiple group-version-kinds associated with type %T, refusing to guess at one", obj)
172+
"%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)
173+
default:
174+
// In any other case, we've found a single GVK for the object.
175+
return gvks[0], nil
151176
}
152-
return gvks[0], nil
153177
}
154178

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

0 commit comments

Comments
 (0)