1
- package client
1
+ /*
2
+ Copyright 2018 The Kubernetes Authors.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ package cache
2
18
3
19
import (
4
20
"context"
@@ -14,58 +30,25 @@ import (
14
30
"k8s.io/apimachinery/pkg/selection"
15
31
"k8s.io/client-go/tools/cache"
16
32
17
- "github.com/kubernetes-sigs/controller-runtime/pkg/internal/informer "
33
+ "github.com/kubernetes-sigs/controller-runtime/pkg/client "
18
34
logf "github.com/kubernetes-sigs/controller-runtime/pkg/runtime/log"
19
35
)
20
36
21
37
var log = logf .KBLog .WithName ("object-cache" )
22
38
23
39
// objectCache is a ReadInterface
24
- var _ ReadInterface = & objectCache {}
40
+ var _ client. ReadInterface = & objectCache {}
25
41
26
42
// objectCache is a Kubernetes Object cache populated from Informers
27
43
type objectCache struct {
28
44
cachesByType map [reflect.Type ]* singleObjectCache
29
45
scheme * runtime.Scheme
30
46
}
31
47
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
- }
48
- res .AddInformers (informers )
49
- return res
50
- }
51
-
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
- }
57
- for gvk , informer := range informers {
58
- o .AddInformer (gvk , informer )
59
- }
60
- }
61
-
62
- // Call implements the informer.Callback so that the cache can be populate with new Informers as they are added
63
- func (o * objectCache ) Call (gvk schema.GroupVersionKind , c cache.SharedIndexInformer ) {
64
- o .AddInformer (gvk , c )
65
- }
48
+ var _ client.ReadInterface = & objectCache {}
66
49
67
- // AddInformer adds an informer to the objectCache
68
- func (o * objectCache ) AddInformer (gvk schema.GroupVersionKind , c cache.SharedIndexInformer ) {
50
+ // addInformer adds an informer to the objectCache
51
+ func (o * objectCache ) addInformer (gvk schema.GroupVersionKind , c cache.SharedIndexInformer ) {
69
52
obj , err := o .scheme .New (gvk )
70
53
if err != nil {
71
54
log .Error (err , "could not register informer in objectCache for GVK" , "GroupVersionKind" , gvk )
@@ -91,17 +74,17 @@ func (o *objectCache) cacheFor(obj runtime.Object) (*singleObjectCache, bool) {
91
74
return cache , isKnown
92
75
}
93
76
94
- // Get implements client .ReadInterface
95
- func (o * objectCache ) Get (ctx context.Context , key ObjectKey , out runtime.Object ) error {
77
+ // Get implements populatingClient .ReadInterface
78
+ func (o * objectCache ) Get (ctx context.Context , key client. ObjectKey , out runtime.Object ) error {
96
79
cache , isKnown := o .cacheFor (out )
97
80
if ! isKnown {
98
81
return fmt .Errorf ("no cache for objects of type %T, must have asked for an watch/informer first" , out )
99
82
}
100
83
return cache .Get (ctx , key , out )
101
84
}
102
85
103
- // List implements client .ReadInterface
104
- func (o * objectCache ) List (ctx context.Context , opts * ListOptions , out runtime.Object ) error {
86
+ // List implements populatingClient .ReadInterface
87
+ func (o * objectCache ) List (ctx context.Context , opts * client. ListOptions , out runtime.Object ) error {
105
88
itemsPtr , err := apimeta .GetItemsPtr (out )
106
89
if err != nil {
107
90
return nil
@@ -116,7 +99,7 @@ func (o *objectCache) List(ctx context.Context, opts *ListOptions, out runtime.O
116
99
}
117
100
118
101
// singleObjectCache is a ReadInterface
119
- var _ ReadInterface = & singleObjectCache {}
102
+ var _ client. ReadInterface = & singleObjectCache {}
120
103
121
104
// singleObjectCache is a ReadInterface that retrieves objects
122
105
// from a single local cache populated by a watch.
@@ -127,8 +110,8 @@ type singleObjectCache struct {
127
110
GroupVersionKind schema.GroupVersionKind
128
111
}
129
112
130
- // Get implements client.Interface
131
- func (c * singleObjectCache ) Get (_ context.Context , key ObjectKey , out runtime.Object ) error {
113
+ // Get implements populatingClient.Client
114
+ func (c * singleObjectCache ) Get (_ context.Context , key client. ObjectKey , out runtime.Object ) error {
132
115
storeKey := objectKeyToStoreKey (key )
133
116
obj , exists , err := c .Indexer .GetByKey (storeKey )
134
117
if err != nil {
@@ -160,8 +143,8 @@ func (c *singleObjectCache) Get(_ context.Context, key ObjectKey, out runtime.Ob
160
143
return nil
161
144
}
162
145
163
- // List implements client.Interface
164
- func (c * singleObjectCache ) List (ctx context.Context , opts * ListOptions , out runtime.Object ) error {
146
+ // List implements populatingClient.Client
147
+ func (c * singleObjectCache ) List (ctx context.Context , opts * client. ListOptions , out runtime.Object ) error {
165
148
var objs []interface {}
166
149
var err error
167
150
@@ -219,30 +202,25 @@ func (c *singleObjectCache) getListItems(objs []interface{}, labelSel labels.Sel
219
202
}
220
203
221
204
// TODO: Make an interface with this function that has an Informers as an object on the struct
222
- // that automatically calls InformerFor and passes in the Indexer into indexByField
205
+ // that automatically calls GetInformer and passes in the Indexer into indexByField
223
206
224
207
// noNamespaceNamespace is used as the "namespace" when we want to list across all namespaces
225
208
const allNamespacesNamespace = "__all_namespaces"
226
209
227
- // InformerFieldIndexer provides an in-memory index of Object fields
228
- type InformerFieldIndexer struct {
229
- Informers informer.Informers
230
- }
231
-
232
210
// IndexField adds an indexer to the underlying cache, using extraction function to get
233
211
// value(s) from the given field. This index can then be used by passing a field selector
234
212
// to List. For one-to-one compatibility with "normal" field selectors, only return one value.
235
213
// The values may be anything. They will automatically be prefixed with the namespace of the
236
214
// given object, if present. The objects passed are guaranteed to be objects of the correct type.
237
- func (i * InformerFieldIndexer ) IndexField (obj runtime.Object , field string , extractValue IndexerFunc ) error {
238
- informer , err := i .Informers . InformerFor (obj )
215
+ func (i * informers ) IndexField (obj runtime.Object , field string , extractValue client. IndexerFunc ) error {
216
+ informer , err := i .GetInformer (obj )
239
217
if err != nil {
240
218
return err
241
219
}
242
220
return indexByField (informer .GetIndexer (), field , extractValue )
243
221
}
244
222
245
- func indexByField (indexer cache.Indexer , field string , extractor IndexerFunc ) error {
223
+ func indexByField (indexer cache.Indexer , field string , extractor client. IndexerFunc ) error {
246
224
indexFunc := func (objRaw interface {}) ([]string , error ) {
247
225
// TODO(directxman12): check if this is the correct type?
248
226
obj , isObj := objRaw .(runtime.Object )
@@ -300,7 +278,7 @@ func keyToNamespacedKey(ns string, baseKey string) string {
300
278
// It's akin to MetaNamespaceKeyFunc. It's separate from
301
279
// String to allow keeping the key format easily in sync with
302
280
// MetaNamespaceKeyFunc.
303
- func objectKeyToStoreKey (k ObjectKey ) string {
281
+ func objectKeyToStoreKey (k client. ObjectKey ) string {
304
282
if k .Namespace == "" {
305
283
return k .Name
306
284
}
@@ -319,11 +297,3 @@ func requiresExactMatch(sel fields.Selector) (field, val string, required bool)
319
297
}
320
298
return req .Field , req .Value , true
321
299
}
322
-
323
- // SplitReaderWriter forms an interface Interface by composing separate
324
- // read and write interfaces. This way, you can have an Interface that
325
- // reads from a cache and writes to the API server.
326
- type SplitReaderWriter struct {
327
- ReadInterface
328
- WriteInterface
329
- }
0 commit comments