Skip to content

Commit 9d8d219

Browse files
authored
Merge pull request #3134 from sbueringer/pr-block-pagination
🐛 Return error if pagination is used with the cached client
2 parents ab38193 + cc72159 commit 9d8d219

File tree

3 files changed

+67
-2
lines changed

3 files changed

+67
-2
lines changed

pkg/cache/cache_test.go

+50
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,19 @@ func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (ca
861861
Expect(listObj.Items).Should(HaveLen(1))
862862
})
863863

864+
It("should return an error if pagination is used", func() {
865+
listObj := &corev1.PodList{}
866+
By("verifying that the first list works and returns a sentinel continue")
867+
err := informerCache.List(context.Background(), listObj)
868+
Expect(err).ToNot(HaveOccurred())
869+
Expect(listObj.Continue).To(Equal("continue-not-supported"))
870+
871+
By("verifying that an error is returned")
872+
err = informerCache.List(context.Background(), listObj, client.Continue(listObj.Continue))
873+
Expect(err).To(HaveOccurred())
874+
Expect(err.Error()).To(Equal("continue list option is not supported by the cache"))
875+
})
876+
864877
It("should return an error if the continue list options is set", func() {
865878
listObj := &corev1.PodList{}
866879
continueOpt := client.Continue("token")
@@ -1182,6 +1195,25 @@ func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (ca
11821195
Expect(nodeList.Items).NotTo(BeEmpty())
11831196
Expect(len(nodeList.Items)).To(BeEquivalentTo(2))
11841197
})
1198+
1199+
It("should return an error if pagination is used", func() {
1200+
nodeList := &unstructured.UnstructuredList{}
1201+
nodeList.SetGroupVersionKind(schema.GroupVersionKind{
1202+
Group: "",
1203+
Version: "v1",
1204+
Kind: "NodeList",
1205+
})
1206+
By("verifying that the first list works and returns a sentinel continue")
1207+
err := informerCache.List(context.Background(), nodeList)
1208+
Expect(err).ToNot(HaveOccurred())
1209+
Expect(nodeList.GetContinue()).To(Equal("continue-not-supported"))
1210+
1211+
By("verifying that an error is returned")
1212+
err = informerCache.List(context.Background(), nodeList, client.Continue(nodeList.GetContinue()))
1213+
Expect(err).To(HaveOccurred())
1214+
Expect(err.Error()).To(Equal("continue list option is not supported by the cache"))
1215+
})
1216+
11851217
It("should return an error if the continue list options is set", func() {
11861218
podList := &unstructured.Unstructured{}
11871219
continueOpt := client.Continue("token")
@@ -1511,6 +1543,24 @@ func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (ca
15111543
err := informerCache.Get(context.Background(), svcKey, svc)
15121544
Expect(err).To(HaveOccurred())
15131545
})
1546+
1547+
It("should return an error if pagination is used", func() {
1548+
nodeList := &metav1.PartialObjectMetadataList{}
1549+
nodeList.SetGroupVersionKind(schema.GroupVersionKind{
1550+
Group: "",
1551+
Version: "v1",
1552+
Kind: "NodeList",
1553+
})
1554+
By("verifying that the first list works and returns a sentinel continue")
1555+
err := informerCache.List(context.Background(), nodeList)
1556+
Expect(err).ToNot(HaveOccurred())
1557+
Expect(nodeList.GetContinue()).To(Equal("continue-not-supported"))
1558+
1559+
By("verifying that an error is returned")
1560+
err = informerCache.List(context.Background(), nodeList, client.Continue(nodeList.GetContinue()))
1561+
Expect(err).To(HaveOccurred())
1562+
Expect(err.Error()).To(Equal("continue list option is not supported by the cache"))
1563+
})
15141564
})
15151565
type selectorsTestCase struct {
15161566
options cache.Options

pkg/cache/internal/cache_reader.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,13 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
174174
}
175175
runtimeObjs = append(runtimeObjs, outObj)
176176
}
177-
return apimeta.SetList(out, runtimeObjs)
177+
178+
if err := apimeta.SetList(out, runtimeObjs); err != nil {
179+
return err
180+
}
181+
182+
out.SetContinue("continue-not-supported")
183+
return nil
178184
}
179185

180186
func byIndexes(indexer cache.Indexer, requires fields.Requirements, namespace string) ([]interface{}, error) {

pkg/cache/multi_namespace_cache.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList,
249249
listOpts := client.ListOptions{}
250250
listOpts.ApplyOptions(opts)
251251

252+
if listOpts.Continue != "" {
253+
return fmt.Errorf("continue list option is not supported by the cache")
254+
}
255+
252256
isNamespaced, err := apiutil.IsObjectNamespaced(list, c.Scheme, c.RESTMapper)
253257
if err != nil {
254258
return err
@@ -316,7 +320,12 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList,
316320
}
317321
listAccessor.SetResourceVersion(resourceVersion)
318322

319-
return apimeta.SetList(list, allItems)
323+
if err := apimeta.SetList(list, allItems); err != nil {
324+
return err
325+
}
326+
327+
list.SetContinue("continue-not-supported")
328+
return nil
320329
}
321330

322331
// multiNamespaceInformer knows how to handle interacting with the underlying informer across multiple namespaces.

0 commit comments

Comments
 (0)