Skip to content

Commit bc9f14f

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 bc9f14f

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, 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)