Skip to content

Commit b6fc422

Browse files
authored
Merge pull request #2202 from k8s-infra-cherrypick-robot/cherry-pick-2192-to-release-0.14
[release-0.14] 🌱 GVKForObject should handle multiple GVKs in Scheme gracefully
2 parents 7a19e15 + 1e00eec commit b6fc422

File tree

1 file changed

+32
-8
lines changed

1 file changed

+32
-8
lines changed

pkg/client/apiutil/apimachinery.go

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersi
9595
return gvk, nil
9696
}
9797

98+
// Use the given scheme to retrieve all the GVKs for the object.
9899
gvks, isUnversioned, err := scheme.ObjectKinds(obj)
99100
if err != nil {
100101
return schema.GroupVersionKind{}, err
@@ -103,16 +104,39 @@ func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersi
103104
return schema.GroupVersionKind{}, fmt.Errorf("cannot create group-version-kind for unversioned type %T", obj)
104105
}
105106

106-
if len(gvks) < 1 {
107-
return schema.GroupVersionKind{}, fmt.Errorf("no group-version-kinds associated with type %T", obj)
108-
}
109-
if len(gvks) > 1 {
110-
// this should only trigger for things like metav1.XYZ --
111-
// normal versioned types should be fine
107+
switch {
108+
case len(gvks) < 1:
109+
// If the object has no GVK, the object might not have been registered with the scheme.
110+
// or it's not a valid object.
111+
return schema.GroupVersionKind{}, fmt.Errorf("no GroupVersionKind associated with Go type %T, was the type registered with the Scheme?", obj)
112+
case len(gvks) > 1:
113+
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)
114+
115+
// We've found multiple GVKs for the object.
116+
currentGVK := obj.GetObjectKind().GroupVersionKind()
117+
if !currentGVK.Empty() {
118+
// If the base object has a GVK, check if it's in the list of GVKs before using it.
119+
for _, gvk := range gvks {
120+
if gvk == currentGVK {
121+
return gvk, nil
122+
}
123+
}
124+
125+
return schema.GroupVersionKind{}, fmt.Errorf(
126+
"%w: the object's supplied GroupVersionKind %q was not found in the Scheme's list; refusing to guess at one: %q", err, currentGVK, gvks)
127+
}
128+
129+
// This should only trigger for things like metav1.XYZ --
130+
// normal versioned types should be fine.
131+
//
132+
// See https://github.com/kubernetes-sigs/controller-runtime/issues/362
133+
// for more information.
112134
return schema.GroupVersionKind{}, fmt.Errorf(
113-
"multiple group-version-kinds associated with type %T, refusing to guess at one", obj)
135+
"%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)
136+
default:
137+
// In any other case, we've found a single GVK for the object.
138+
return gvks[0], nil
114139
}
115-
return gvks[0], nil
116140
}
117141

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

0 commit comments

Comments
 (0)