@@ -113,17 +113,55 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
113
113
listOpts .ApplyOptions (opts )
114
114
115
115
switch {
116
- case listOpts .FieldSelector != nil :
116
+ case listOpts .FieldSelector != nil && ! listOpts . FieldSelector . Empty () :
117
117
// TODO(directxman12): support more complicated field selectors by
118
118
// combining multiple indices, GetIndexers, etc
119
- field , val , requiresExact := requiresExactMatch (listOpts .FieldSelector )
119
+ requiresExact := requiresExactMatch (listOpts .FieldSelector )
120
120
if ! requiresExact {
121
121
return fmt .Errorf ("non-exact field matches are not supported by the cache" )
122
122
}
123
- // list all objects by the field selector. If this is namespaced and we have one, ask for the
124
- // namespaced index key. Otherwise, ask for the non-namespaced variant by using the fake "all namespaces"
125
- // namespace.
126
- objs , err = c .indexer .ByIndex (FieldIndexName (field ), KeyToNamespacedKey (listOpts .Namespace , val ))
123
+
124
+ reqs := listOpts .FieldSelector .Requirements ()
125
+ // len(reqs) == 0 means, select nothing
126
+ if len (reqs ) > 0 {
127
+ req := reqs [0 ]
128
+ // list all objects by the field selector. If this is namespaced and we have one, ask for the
129
+ // namespaced index key. Otherwise, ask for the non-namespaced variant by using the fake "all namespaces"
130
+ // namespace.
131
+ list , err := c .indexer .ByIndex (FieldIndexName (req .Field ), KeyToNamespacedKey (listOpts .Namespace , req .Value ))
132
+ if err != nil {
133
+ return err
134
+ }
135
+ if len (reqs ) > 1 {
136
+ objmap := make (map [client.ObjectKey ]interface {}, len (list ))
137
+ for i := range list {
138
+ obj := list [i ].(client.Object )
139
+ objmap [client.ObjectKey {Namespace : obj .GetNamespace (), Name : obj .GetName ()}] = obj
140
+ }
141
+ for _ , req := range reqs [1 :] {
142
+ list , err := c .indexer .ByIndex (FieldIndexName (req .Field ), KeyToNamespacedKey (listOpts .Namespace , req .Value ))
143
+ if err != nil {
144
+ return err
145
+ }
146
+
147
+ numap := make (map [client.ObjectKey ]interface {}, len (list ))
148
+ for i := range list {
149
+ obj := list [i ].(client.Object )
150
+ key := client.ObjectKey {Namespace : obj .GetNamespace (), Name : obj .GetName ()}
151
+ if _ , exists := objmap [key ]; exists {
152
+ numap [key ] = obj
153
+ }
154
+ }
155
+ objmap = numap
156
+ }
157
+ objs = make ([]interface {}, 0 , len (objmap ))
158
+ for _ , obj := range objmap {
159
+ objs = append (objs , obj )
160
+ }
161
+ } else {
162
+ objs = list
163
+ }
164
+ }
127
165
case listOpts .Namespace != "" :
128
166
objs , err = c .indexer .ByIndex (cache .NamespaceIndex , listOpts .Namespace )
129
167
default :
@@ -187,16 +225,14 @@ func objectKeyToStoreKey(k client.ObjectKey) string {
187
225
}
188
226
189
227
// requiresExactMatch checks if the given field selector is of the form `k=v` or `k==v`.
190
- func requiresExactMatch (sel fields.Selector ) (field , val string , required bool ) {
228
+ func requiresExactMatch (sel fields.Selector ) (required bool ) {
191
229
reqs := sel .Requirements ()
192
- if len (reqs ) != 1 {
193
- return "" , "" , false
194
- }
195
- req := reqs [0 ]
196
- if req .Operator != selection .Equals && req .Operator != selection .DoubleEquals {
197
- return "" , "" , false
230
+ for _ , req := range reqs {
231
+ if req .Operator != selection .Equals && req .Operator != selection .DoubleEquals {
232
+ return false
233
+ }
198
234
}
199
- return req . Field , req . Value , true
235
+ return true
200
236
}
201
237
202
238
// FieldIndexName constructs the name of the index over the given field,
0 commit comments