Skip to content

Commit bd096f9

Browse files
committed
Simplify cache.objectTypeForListObject
This changeset streamlines and simplifies the logic inside objectTypeForListObject. This method is used to retrieve from a List object, its respective actual resource GVK and a new instance of the object. In the previous iteration, the use of reflection was complicated to follow and looking at the fields in the struct passed in, instead of using the information we already have in the Scheme to create a new instance of the expected object and return. In addition to all of the above, we're also now handling PartialObjectMetadataList(s). Signed-off-by: Vince Prignano <[email protected]>
1 parent 5028a59 commit bd096f9

File tree

2 files changed

+35
-29
lines changed

2 files changed

+35
-29
lines changed

pkg/cache/informer_cache.go

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ package cache
1919
import (
2020
"context"
2121
"fmt"
22-
"reflect"
2322
"strings"
2423

2524
apimeta "k8s.io/apimachinery/pkg/api/meta"
25+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2626
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2727
"k8s.io/apimachinery/pkg/runtime"
2828
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -97,36 +97,28 @@ func (ip *informerCache) objectTypeForListObject(list client.ObjectList) (*schem
9797
return nil, nil, err
9898
}
9999

100-
// we need the non-list GVK, so chop off the "List" from the end of the kind
101-
if strings.HasSuffix(gvk.Kind, "List") && apimeta.IsListType(list) {
102-
gvk.Kind = gvk.Kind[:len(gvk.Kind)-4]
103-
}
100+
// We need the non-list GVK, so chop off the "List" from the end of the kind.
101+
gvk.Kind = strings.TrimSuffix(gvk.Kind, "List")
104102

105-
_, isUnstructured := list.(*unstructured.UnstructuredList)
106-
var cacheTypeObj runtime.Object
107-
if isUnstructured {
103+
// Handle unstructured.UnstructuredList.
104+
if _, isUnstructured := list.(*unstructured.UnstructuredList); isUnstructured {
108105
u := &unstructured.Unstructured{}
109106
u.SetGroupVersionKind(gvk)
110-
cacheTypeObj = u
111-
} else {
112-
itemsPtr, err := apimeta.GetItemsPtr(list)
113-
if err != nil {
114-
return nil, nil, err
115-
}
116-
// http://knowyourmeme.com/memes/this-is-fine
117-
elemType := reflect.Indirect(reflect.ValueOf(itemsPtr)).Type().Elem()
118-
if elemType.Kind() != reflect.Ptr {
119-
elemType = reflect.PtrTo(elemType)
120-
}
121-
122-
cacheTypeValue := reflect.Zero(elemType)
123-
var ok bool
124-
cacheTypeObj, ok = cacheTypeValue.Interface().(runtime.Object)
125-
if !ok {
126-
return nil, nil, fmt.Errorf("cannot get cache for %T, its element %T is not a runtime.Object", list, cacheTypeValue.Interface())
127-
}
107+
return &gvk, u, nil
108+
}
109+
// Handle metav1.PartialObjectMetadataList.
110+
if _, isPartialObjectMetadata := list.(*metav1.PartialObjectMetadataList); isPartialObjectMetadata {
111+
pom := &metav1.PartialObjectMetadata{}
112+
pom.SetGroupVersionKind(gvk)
113+
return &gvk, pom, nil
128114
}
129115

116+
// Any other list type should have a corresponding non-list type registered
117+
// in the scheme. Use that to create a new instance of the non-list type.
118+
cacheTypeObj, err := ip.scheme.New(gvk)
119+
if err != nil {
120+
return nil, nil, err
121+
}
130122
return &gvk, cacheTypeObj, nil
131123
}
132124

pkg/cache/informer_cache_unit_test.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
. "github.com/onsi/gomega"
2222

2323
corev1 "k8s.io/api/core/v1"
24+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2425
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2526
"k8s.io/apimachinery/pkg/runtime"
2627
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -55,7 +56,21 @@ var _ = Describe("ip.objectTypeForListObject", func() {
5556
referenceUnstructured := &unstructured.Unstructured{}
5657
referenceUnstructured.SetGroupVersionKind(*gvk)
5758
Expect(obj).To(Equal(referenceUnstructured))
59+
})
60+
61+
It("should find the object type for partial object metadata lists", func() {
62+
partialList := &metav1.PartialObjectMetadataList{}
63+
partialList.APIVersion = ("v1")
64+
partialList.Kind = "PodList"
5865

66+
gvk, obj, err := ip.objectTypeForListObject(partialList)
67+
Expect(err).ToNot(HaveOccurred())
68+
Expect(gvk.Group).To(Equal(""))
69+
Expect(gvk.Version).To(Equal("v1"))
70+
Expect(gvk.Kind).To(Equal("Pod"))
71+
referencePartial := &metav1.PartialObjectMetadata{}
72+
referencePartial.SetGroupVersionKind(*gvk)
73+
Expect(obj).To(Equal(referencePartial))
5974
})
6075

6176
It("should find the object type of a list with a slice of literals items field", func() {
@@ -64,9 +79,8 @@ var _ = Describe("ip.objectTypeForListObject", func() {
6479
Expect(gvk.Group).To(Equal(""))
6580
Expect(gvk.Version).To(Equal("v1"))
6681
Expect(gvk.Kind).To(Equal("Pod"))
67-
var referencePod *corev1.Pod
82+
referencePod := &corev1.Pod{}
6883
Expect(obj).To(Equal(referencePod))
69-
7084
})
7185

7286
It("should find the object type of a list with a slice of pointers items field", func() {
@@ -88,7 +102,7 @@ var _ = Describe("ip.objectTypeForListObject", func() {
88102
Expect(gvk.Group).To(Equal(itemPointerSliceTypeGroupName))
89103
Expect(gvk.Version).To(Equal(itemPointerSliceTypeVersion))
90104
Expect(gvk.Kind).To(Equal("UnconventionalListType"))
91-
var referenceObject *controllertest.UnconventionalListType
105+
referenceObject := &controllertest.UnconventionalListType{}
92106
Expect(obj).To(Equal(referenceObject))
93107
})
94108
})

0 commit comments

Comments
 (0)