@@ -41,7 +41,7 @@ const globalCache = "_cluster-scope"
41
41
// MultiNamespacedCacheBuilder - Builder function to create a new multi-namespaced cache.
42
42
// This will scope the cache to a list of namespaces. Listing for all namespaces
43
43
// will list for all the namespaces that this knows about. By default this will create
44
- // a global cache for cluster scoped resource (having empty namespace) . Note that this is not intended
44
+ // a global cache for cluster scoped resource. Note that this is not intended
45
45
// to be used for excluding namespaces, this is better done via a Predicate. Also note that
46
46
// you may face performance issues when using this with a high number of namespaces.
47
47
func MultiNamespacedCacheBuilder (namespaces []string ) NewCacheFunc {
@@ -59,9 +59,6 @@ func MultiNamespacedCacheBuilder(namespaces []string) NewCacheFunc {
59
59
return nil , fmt .Errorf ("error creating global cache %v" , err )
60
60
}
61
61
62
- // add global cache to the cacheMap
63
- caches [globalCache ] = gCache
64
-
65
62
for _ , ns := range namespaces {
66
63
opts .Namespace = ns
67
64
c , err := New (config , opts )
@@ -70,7 +67,7 @@ func MultiNamespacedCacheBuilder(namespaces []string) NewCacheFunc {
70
67
}
71
68
caches [ns ] = c
72
69
}
73
- return & multiNamespaceCache {namespaceToCache : caches , Scheme : opts .Scheme , RESTMapper : opts .Mapper }, nil
70
+ return & multiNamespaceCache {namespaceToCache : caches , Scheme : opts .Scheme , RESTMapper : opts .Mapper , ClusterCache : gCache }, nil
74
71
}
75
72
}
76
73
@@ -82,6 +79,7 @@ type multiNamespaceCache struct {
82
79
namespaceToCache map [string ]Cache
83
80
Scheme * runtime.Scheme
84
81
RESTMapper meta.RESTMapper
82
+ ClusterCache Cache
85
83
}
86
84
87
85
var _ Cache = & multiNamespaceCache {}
@@ -96,6 +94,12 @@ func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object
96
94
}
97
95
informers [ns ] = informer
98
96
}
97
+ clusterCacheInf , err := c .ClusterCache .GetInformer (ctx , obj )
98
+ if err != nil {
99
+ return nil , err
100
+ }
101
+ informers [globalCache ] = clusterCacheInf
102
+
99
103
return & multiNamespaceInformer {namespaceToInformer : informers }, nil
100
104
}
101
105
@@ -108,10 +112,24 @@ func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema
108
112
}
109
113
informers [ns ] = informer
110
114
}
115
+ clusterCacheInf , err := c .ClusterCache .GetInformerForKind (ctx , gvk )
116
+ if err != nil {
117
+ return nil , err
118
+ }
119
+ informers [globalCache ] = clusterCacheInf
111
120
return & multiNamespaceInformer {namespaceToInformer : informers }, nil
112
121
}
113
122
114
123
func (c * multiNamespaceCache ) Start (ctx context.Context ) error {
124
+ // start global cache
125
+ go func () {
126
+ err := c .ClusterCache .Start (ctx )
127
+ if err != nil {
128
+ log .Error (err , "cluster scoped cache failed to start" )
129
+ }
130
+ }()
131
+
132
+ // start namespaced caches
115
133
for ns , cache := range c .namespaceToCache {
116
134
go func (ns string , cache Cache ) {
117
135
err := cache .Start (ctx )
@@ -120,6 +138,7 @@ func (c *multiNamespaceCache) Start(ctx context.Context) error {
120
138
}
121
139
}(ns , cache )
122
140
}
141
+
123
142
<- ctx .Done ()
124
143
return nil
125
144
}
@@ -131,6 +150,11 @@ func (c *multiNamespaceCache) WaitForCacheSync(ctx context.Context) bool {
131
150
synced = s
132
151
}
133
152
}
153
+
154
+ // check if cluster scoped cache has synced
155
+ if ! c .ClusterCache .WaitForCacheSync (ctx ) {
156
+ synced = false
157
+ }
134
158
return synced
135
159
}
136
160
@@ -140,6 +164,10 @@ func (c *multiNamespaceCache) IndexField(ctx context.Context, obj client.Object,
140
164
return err
141
165
}
142
166
}
167
+
168
+ if err := c .ClusterCache .IndexField (ctx , obj , field , extractValue ); err != nil {
169
+ return fmt .Errorf ("error adding index on object with cluster scoped cache %v" , err )
170
+ }
143
171
return nil
144
172
}
145
173
@@ -151,8 +179,7 @@ func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj
151
179
152
180
if ! isNamespaced {
153
181
// Look into the global cache to fetch the object
154
- cache := c .namespaceToCache [globalCache ]
155
- return cache .Get (ctx , key , obj )
182
+ return c .ClusterCache .Get (ctx , key , obj )
156
183
}
157
184
158
185
cache , ok := c .namespaceToCache [key .Namespace ]
@@ -174,8 +201,7 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList,
174
201
175
202
if ! isNamespaced {
176
203
// Look at the global cache to get the objects with the specified GVK
177
- cache := c .namespaceToCache [globalCache ]
178
- return cache .List (ctx , list , opts ... )
204
+ return c .ClusterCache .List (ctx , list , opts ... )
179
205
}
180
206
181
207
if listOpts .Namespace != corev1 .NamespaceAll {
@@ -199,10 +225,7 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList,
199
225
limitSet := listOpts .Limit > 0
200
226
201
227
var resourceVersion string
202
- for ns , cache := range c .namespaceToCache {
203
- if ns == globalCache {
204
- continue
205
- }
228
+ for _ , cache := range c .namespaceToCache {
206
229
listObj := list .DeepCopyObject ().(client.ObjectList )
207
230
err = cache .List (ctx , listObj , & listOpts )
208
231
if err != nil {
0 commit comments