@@ -20,98 +20,115 @@ import (
20
20
21
21
var log = logf .KBLog .WithName ("object-cache" )
22
22
23
- // ObjectCache is a ReadInterface
24
- var _ ReadInterface = & ObjectCache {}
23
+ // objectCache is a ReadInterface
24
+ var _ ReadInterface = & objectCache {}
25
25
26
- type ObjectCache struct {
27
- cachesByType map [reflect.Type ]* SingleObjectCache
26
+ // objectCache is a Kubernetes Object cache populated from Informers
27
+ type objectCache struct {
28
+ cachesByType map [reflect.Type ]* singleObjectCache
28
29
scheme * runtime.Scheme
29
30
}
30
31
31
- func ObjectCacheFromInformers (informers map [schema.GroupVersionKind ]cache.SharedIndexInformer , scheme * runtime.Scheme ) * ObjectCache {
32
- res := NewObjectCache (scheme )
32
+ var _ Cache = & objectCache {}
33
+
34
+ // Cache implements ReadInterface by reading objects from a cache populated by Informers
35
+ type Cache interface {
36
+ ReadInterface
37
+ informer.Callback
38
+ }
39
+
40
+ // NewObjectCache returns a new objectCache populated from informers
41
+ func NewObjectCache (
42
+ informers map [schema.GroupVersionKind ]cache.SharedIndexInformer ,
43
+ scheme * runtime.Scheme ) Cache {
44
+ res := & objectCache {
45
+ cachesByType : make (map [reflect.Type ]* singleObjectCache ),
46
+ scheme : scheme ,
47
+ }
33
48
res .AddInformers (informers )
34
49
return res
35
50
}
36
51
37
- func (o * ObjectCache ) AddInformers (informers map [schema.GroupVersionKind ]cache.SharedIndexInformer ) {
52
+ // AddInformers adds new informers to the objectCache
53
+ func (o * objectCache ) AddInformers (informers map [schema.GroupVersionKind ]cache.SharedIndexInformer ) {
54
+ if informers == nil {
55
+ return
56
+ }
38
57
for gvk , informer := range informers {
39
58
o .AddInformer (gvk , informer )
40
59
}
41
60
}
42
61
43
- func (o * ObjectCache ) Call (gvk schema.GroupVersionKind , c cache.SharedIndexInformer ) {
62
+ // Call implements the informer callback
63
+ func (o * objectCache ) Call (gvk schema.GroupVersionKind , c cache.SharedIndexInformer ) {
44
64
o .AddInformer (gvk , c )
45
65
}
46
66
47
- func (o * ObjectCache ) AddInformer (gvk schema.GroupVersionKind , c cache.SharedIndexInformer ) {
67
+ // AddInformer adds an informer to the objectCache
68
+ func (o * objectCache ) AddInformer (gvk schema.GroupVersionKind , c cache.SharedIndexInformer ) {
48
69
obj , err := o .scheme .New (gvk )
49
70
if err != nil {
50
- log .Error (err , "could not register informer in ObjectCache for GVK" , "GroupVersionKind" , gvk )
71
+ log .Error (err , "could not register informer in objectCache for GVK" , "GroupVersionKind" , gvk )
51
72
return
52
73
}
53
- if _ , found := o .CacheFor (obj ); found {
74
+ if _ , found := o .cacheFor (obj ); found {
54
75
return
55
76
}
56
- o .RegisterCache (obj , gvk , c .GetIndexer ())
57
- }
58
-
59
- func NewObjectCache (scheme * runtime.Scheme ) * ObjectCache {
60
- return & ObjectCache {
61
- cachesByType : make (map [reflect.Type ]* SingleObjectCache ),
62
- scheme : scheme ,
63
- }
77
+ o .registerCache (obj , gvk , c .GetIndexer ())
64
78
}
65
79
66
- func (c * ObjectCache ) RegisterCache (obj runtime.Object , gvk schema.GroupVersionKind , store cache.Indexer ) {
80
+ func (o * objectCache ) registerCache (obj runtime.Object , gvk schema.GroupVersionKind , store cache.Indexer ) {
67
81
objType := reflect .TypeOf (obj )
68
- c .cachesByType [objType ] = & SingleObjectCache {
82
+ o .cachesByType [objType ] = & singleObjectCache {
69
83
Indexer : store ,
70
84
GroupVersionKind : gvk ,
71
85
}
72
86
}
73
87
74
- func (c * ObjectCache ) CacheFor (obj runtime.Object ) (* SingleObjectCache , bool ) {
88
+ func (o * objectCache ) cacheFor (obj runtime.Object ) (* singleObjectCache , bool ) {
75
89
objType := reflect .TypeOf (obj )
76
- cache , isKnown := c .cachesByType [objType ]
90
+ cache , isKnown := o .cachesByType [objType ]
77
91
return cache , isKnown
78
92
}
79
93
80
- func (c * ObjectCache ) Get (ctx context.Context , key ObjectKey , out runtime.Object ) error {
81
- cache , isKnown := c .CacheFor (out )
94
+ // Get implements client.Interface
95
+ func (o * objectCache ) Get (ctx context.Context , key ObjectKey , out runtime.Object ) error {
96
+ cache , isKnown := o .cacheFor (out )
82
97
if ! isKnown {
83
98
return fmt .Errorf ("no cache for objects of type %T, must have asked for an watch/informer first" , out )
84
99
}
85
100
return cache .Get (ctx , key , out )
86
101
}
87
102
88
- func (c * ObjectCache ) List (ctx context.Context , opts * ListOptions , out runtime.Object ) error {
103
+ // List implements client.Interface
104
+ func (o * objectCache ) List (ctx context.Context , opts * ListOptions , out runtime.Object ) error {
89
105
itemsPtr , err := apimeta .GetItemsPtr (out )
90
106
if err != nil {
91
107
return nil
92
108
}
93
109
// http://knowyourmeme.com/memes/this-is-fine
94
110
outType := reflect .Indirect (reflect .ValueOf (itemsPtr )).Type ().Elem ()
95
- cache , isKnown := c .cachesByType [outType ]
111
+ cache , isKnown := o .cachesByType [outType ]
96
112
if ! isKnown {
97
113
return fmt .Errorf ("no cache for objects of type %T" , out )
98
114
}
99
115
return cache .List (ctx , opts , out )
100
116
}
101
117
102
- // SingleObjectCache is a ReadInterface
103
- var _ ReadInterface = & SingleObjectCache {}
118
+ // singleObjectCache is a ReadInterface
119
+ var _ ReadInterface = & singleObjectCache {}
104
120
105
- // SingleObjectCache is a ReadInterface that retrieves objects
121
+ // singleObjectCache is a ReadInterface that retrieves objects
106
122
// from a single local cache populated by a watch.
107
- type SingleObjectCache struct {
123
+ type singleObjectCache struct {
108
124
// Indexer is the underlying indexer wrapped by this cache.
109
125
Indexer cache.Indexer
110
126
// GroupVersionKind is the group-version-kind of the resource.
111
127
GroupVersionKind schema.GroupVersionKind
112
128
}
113
129
114
- func (c * SingleObjectCache ) Get (_ context.Context , key ObjectKey , out runtime.Object ) error {
130
+ // Get implements client.Interface
131
+ func (c * singleObjectCache ) Get (_ context.Context , key ObjectKey , out runtime.Object ) error {
115
132
storeKey := objectKeyToStoreKey (key )
116
133
obj , exists , err := c .Indexer .GetByKey (storeKey )
117
134
if err != nil {
@@ -143,7 +160,8 @@ func (c *SingleObjectCache) Get(_ context.Context, key ObjectKey, out runtime.Ob
143
160
return nil
144
161
}
145
162
146
- func (c * SingleObjectCache ) List (ctx context.Context , opts * ListOptions , out runtime.Object ) error {
163
+ // List implements client.Interface
164
+ func (c * singleObjectCache ) List (ctx context.Context , opts * ListOptions , out runtime.Object ) error {
147
165
var objs []interface {}
148
166
var err error
149
167
@@ -196,29 +214,30 @@ func (c *SingleObjectCache) List(ctx context.Context, opts *ListOptions, out run
196
214
}
197
215
198
216
// TODO: Make an interface with this function that has an Informers as an object on the struct
199
- // that automatically calls InformerFor and passes in the Indexer into IndexByField
217
+ // that automatically calls InformerFor and passes in the Indexer into indexByField
200
218
201
219
// noNamespaceNamespace is used as the "namespace" when we want to list across all namespaces
202
220
const allNamespacesNamespace = "__all_namespaces"
203
221
222
+ // InformerFieldIndexer provides an in-memory index of Object fields
204
223
type InformerFieldIndexer struct {
205
224
Informers informer.Informers
206
225
}
207
226
227
+ // IndexField adds an indexer to the underlying cache, using extraction function to get
228
+ // value(s) from the given field. This index can then be used by passing a field selector
229
+ // to List. For one-to-one compatibility with "normal" field selectors, only return one value.
230
+ // The values may be anything. They will automatically be prefixed with the namespace of the
231
+ // given object, if present. The objects passed are guaranteed to be objects of the correct type.
208
232
func (i * InformerFieldIndexer ) IndexField (obj runtime.Object , field string , extractValue IndexerFunc ) error {
209
233
informer , err := i .Informers .InformerFor (obj )
210
234
if err != nil {
211
235
return err
212
236
}
213
- return IndexByField (informer .GetIndexer (), field , extractValue )
237
+ return indexByField (informer .GetIndexer (), field , extractValue )
214
238
}
215
239
216
- // IndexByField adds an indexer to the underlying cache, using extraction function to get
217
- // value(s) from the given field. This index can then be used by passing a field selector
218
- // to List. For one-to-one compatibility with "normal" field selectors, only return one value.
219
- // The values may be anything. They will automatically be prefixed with the namespace of the
220
- // given object, if present. The objects passed are guaranteed to be objects of the correct type.
221
- func IndexByField (indexer cache.Indexer , field string , extractor IndexerFunc ) error {
240
+ func indexByField (indexer cache.Indexer , field string , extractor IndexerFunc ) error {
222
241
indexFunc := func (objRaw interface {}) ([]string , error ) {
223
242
// TODO(directxman12): check if this is the correct type?
224
243
obj , isObj := objRaw .(runtime.Object )
0 commit comments