diff --git a/pkg/cache/cache_test.go b/pkg/cache/cache_test.go index 9049129cc4..9efd04877c 100644 --- a/pkg/cache/cache_test.go +++ b/pkg/cache/cache_test.go @@ -861,6 +861,19 @@ func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (ca Expect(listObj.Items).Should(HaveLen(1)) }) + It("should return an error if pagination is used", func() { + listObj := &corev1.PodList{} + By("verifying that the first list works and returns a sentinel continue") + err := informerCache.List(context.Background(), listObj) + Expect(err).ToNot(HaveOccurred()) + Expect(listObj.Continue).To(Equal("continue-not-supported")) + + By("verifying that an error is returned") + err = informerCache.List(context.Background(), listObj, client.Continue(listObj.Continue)) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("continue list option is not supported by the cache")) + }) + It("should return an error if the continue list options is set", func() { listObj := &corev1.PodList{} continueOpt := client.Continue("token") @@ -1182,6 +1195,25 @@ func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (ca Expect(nodeList.Items).NotTo(BeEmpty()) Expect(len(nodeList.Items)).To(BeEquivalentTo(2)) }) + + It("should return an error if pagination is used", func() { + nodeList := &unstructured.UnstructuredList{} + nodeList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "NodeList", + }) + By("verifying that the first list works and returns a sentinel continue") + err := informerCache.List(context.Background(), nodeList) + Expect(err).ToNot(HaveOccurred()) + Expect(nodeList.GetContinue()).To(Equal("continue-not-supported")) + + By("verifying that an error is returned") + err = informerCache.List(context.Background(), nodeList, client.Continue(nodeList.GetContinue())) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("continue list option is not supported by the cache")) + }) + It("should return an error if the continue list options is set", func() { podList := &unstructured.Unstructured{} continueOpt := client.Continue("token") @@ -1511,6 +1543,24 @@ func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (ca err := informerCache.Get(context.Background(), svcKey, svc) Expect(err).To(HaveOccurred()) }) + + It("should return an error if pagination is used", func() { + nodeList := &metav1.PartialObjectMetadataList{} + nodeList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "NodeList", + }) + By("verifying that the first list works and returns a sentinel continue") + err := informerCache.List(context.Background(), nodeList) + Expect(err).ToNot(HaveOccurred()) + Expect(nodeList.GetContinue()).To(Equal("continue-not-supported")) + + By("verifying that an error is returned") + err = informerCache.List(context.Background(), nodeList, client.Continue(nodeList.GetContinue())) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("continue list option is not supported by the cache")) + }) }) type selectorsTestCase struct { options cache.Options diff --git a/pkg/cache/internal/cache_reader.go b/pkg/cache/internal/cache_reader.go index 81ee960b73..33ce8a830a 100644 --- a/pkg/cache/internal/cache_reader.go +++ b/pkg/cache/internal/cache_reader.go @@ -174,7 +174,13 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli } runtimeObjs = append(runtimeObjs, outObj) } - return apimeta.SetList(out, runtimeObjs) + + if err := apimeta.SetList(out, runtimeObjs); err != nil { + return err + } + + out.SetContinue("continue-not-supported") + return nil } func byIndexes(indexer cache.Indexer, requires fields.Requirements, namespace string) ([]interface{}, error) { diff --git a/pkg/cache/multi_namespace_cache.go b/pkg/cache/multi_namespace_cache.go index aeeeb66937..f1e14a131c 100644 --- a/pkg/cache/multi_namespace_cache.go +++ b/pkg/cache/multi_namespace_cache.go @@ -249,6 +249,10 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList, listOpts := client.ListOptions{} listOpts.ApplyOptions(opts) + if listOpts.Continue != "" { + return fmt.Errorf("continue list option is not supported by the cache") + } + isNamespaced, err := apiutil.IsObjectNamespaced(list, c.Scheme, c.RESTMapper) if err != nil { return err @@ -316,7 +320,12 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList, } listAccessor.SetResourceVersion(resourceVersion) - return apimeta.SetList(list, allItems) + if err := apimeta.SetList(list, allItems); err != nil { + return err + } + + list.SetContinue("continue-not-supported") + return nil } // multiNamespaceInformer knows how to handle interacting with the underlying informer across multiple namespaces.