Skip to content

Commit 48ec279

Browse files
committed
GVKForObject should handle multiple GVKs in Scheme gracefully
- 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 <[email protected]>
1 parent c98b7fd commit 48ec279

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

pkg/client/apiutil/apimachinery.go

Lines changed: 27 additions & 8 deletions
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,34 @@ 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 type %T, was the type registered with the Scheme?", obj)
149+
case len(gvks) > 1:
150+
// We've found multiple GVKs for the object.
151+
currentGVK := obj.GetObjectKind().GroupVersionKind()
152+
if !currentGVK.Empty() {
153+
// If the base object has a GVK, check if it's in the list of GVKs before using it.
154+
for _, gvk := range gvks {
155+
if gvk == currentGVK {
156+
return gvk, nil
157+
}
158+
}
159+
}
160+
161+
// This should only trigger for things like metav1.XYZ --
162+
// normal versioned types should be fine.
163+
//
164+
// See https://github.com/kubernetes-sigs/controller-runtime/issues/362
165+
// for more information.
149166
return schema.GroupVersionKind{}, fmt.Errorf(
150-
"multiple group-version-kinds associated with type %T, refusing to guess at one", obj)
167+
"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)
168+
default:
169+
// In any other case, we've found a single GVK for the object.
170+
return gvks[0], nil
151171
}
152-
return gvks[0], nil
153172
}
154173

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

0 commit comments

Comments
 (0)