@@ -32,6 +32,7 @@ import (
3232 runtimeschema "k8s.io/apimachinery/pkg/runtime/schema"
3333 "k8s.io/apimachinery/pkg/util/sets"
3434 "k8s.io/apimachinery/pkg/util/wait"
35+ "k8s.io/client-go/discovery"
3536 "k8s.io/client-go/rest"
3637 "sigs.k8s.io/controller-runtime/pkg/client"
3738 "sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -59,11 +60,11 @@ var _ = Describe("VirtualWorkspace Provider", Ordered, func() {
5960 ctx context.Context
6061 cancel context.CancelFunc
6162
62- cli clusterclient.ClusterClient
63- provider , consumer logicalcluster.Path
64- consumerWS * tenancyv1alpha1.Workspace
65- mgr mcmanager.Manager
66- vwEndpoint string
63+ cli clusterclient.ClusterClient
64+ provider , consumer , other logicalcluster.Path
65+ consumerWS * tenancyv1alpha1.Workspace
66+ mgr mcmanager.Manager
67+ vwEndpoint string
6768 )
6869
6970 BeforeAll (func () {
@@ -75,6 +76,7 @@ var _ = Describe("VirtualWorkspace Provider", Ordered, func() {
7576
7677 _ , provider = envtest .NewWorkspaceFixture (GinkgoT (), cli , core .RootCluster .Path (), envtest .WithNamePrefix ("provider" ))
7778 consumerWS , consumer = envtest .NewWorkspaceFixture (GinkgoT (), cli , core .RootCluster .Path (), envtest .WithNamePrefix ("consumer" ))
79+ _ , other = envtest .NewWorkspaceFixture (GinkgoT (), cli , core .RootCluster .Path (), envtest .WithNamePrefix ("other" ))
7880
7981 By (fmt .Sprintf ("creating a schema in the provider workspace %q" , provider ))
8082 schema := & apisv1alpha1.APIResourceSchema {
@@ -130,7 +132,7 @@ var _ = Describe("VirtualWorkspace Provider", Ordered, func() {
130132 err = cli .Cluster (provider ).Create (ctx , endpoitns )
131133 Expect (err ).NotTo (HaveOccurred ())
132134
133- By (fmt .Sprintf ("creating an APIBinding in the consumer workspace %q" , consumer ))
135+ By (fmt .Sprintf ("creating an APIBinding in the other workspace %q" , other ))
134136 binding := & apisv1alpha1.APIBinding {
135137 ObjectMeta : metav1.ObjectMeta {
136138 Name : "example.com" ,
@@ -144,6 +146,23 @@ var _ = Describe("VirtualWorkspace Provider", Ordered, func() {
144146 },
145147 },
146148 }
149+ err = cli .Cluster (other ).Create (ctx , binding )
150+ Expect (err ).NotTo (HaveOccurred ())
151+
152+ By (fmt .Sprintf ("creating an APIBinding in the consumer workspace %q" , consumer ))
153+ binding = & apisv1alpha1.APIBinding {
154+ ObjectMeta : metav1.ObjectMeta {
155+ Name : "example.com" ,
156+ },
157+ Spec : apisv1alpha1.APIBindingSpec {
158+ Reference : apisv1alpha1.BindingReference {
159+ Export : & apisv1alpha1.ExportBindingReference {
160+ Path : provider .String (),
161+ Name : export .Name ,
162+ },
163+ },
164+ },
165+ }
147166 err = cli .Cluster (consumer ).Create (ctx , binding )
148167 Expect (err ).NotTo (HaveOccurred ())
149168
@@ -187,24 +206,69 @@ var _ = Describe("VirtualWorkspace Provider", Ordered, func() {
187206 var (
188207 lock sync.RWMutex
189208 engaged = sets .NewString ()
209+ p * virtualworkspace.Provider
190210 g * errgroup.Group
191211 cancelGroup context.CancelFunc
192212 )
193213
194214 BeforeAll (func () {
215+ By ("creating a stone in the consumer workspace" , func () {
216+ thing := & unstructured.Unstructured {}
217+ thing .SetGroupVersionKind (runtimeschema.GroupVersionKind {Group : "example.com" , Version : "v1" , Kind : "Thing" })
218+ thing .SetName ("stone" )
219+ thing .SetLabels (map [string ]string {"color" : "gray" })
220+ err := cli .Cluster (consumer ).Create (ctx , thing )
221+ Expect (err ).NotTo (HaveOccurred ())
222+ })
223+
224+ By ("creating a box in the other workspace" , func () {
225+ thing := & unstructured.Unstructured {}
226+ thing .SetGroupVersionKind (runtimeschema.GroupVersionKind {Group : "example.com" , Version : "v1" , Kind : "Thing" })
227+ thing .SetName ("box" )
228+ thing .SetLabels (map [string ]string {"color" : "white" })
229+ err := cli .Cluster (other ).Create (ctx , thing )
230+ Expect (err ).NotTo (HaveOccurred ())
231+ })
232+
195233 By ("creating a multicluster provider for APIBindings against the apiexport virtual workspace" )
196234 vwConfig := rest .CopyConfig (kcpConfig )
197235 vwConfig .Host = vwEndpoint
198- p , err := virtualworkspace .New (vwConfig , & apisv1alpha1.APIBinding {}, virtualworkspace.Options {})
236+ var err error
237+ p , err = virtualworkspace .New (vwConfig , & apisv1alpha1.APIBinding {}, virtualworkspace.Options {})
199238 Expect (err ).NotTo (HaveOccurred ())
200239
240+ By ("waiting for discovery of the virtual workspace to show 'example.com'" )
241+ wildcardConfig := rest .CopyConfig (vwConfig )
242+ wildcardConfig .Host += logicalcluster .Wildcard .RequestPath ()
243+ disc , err := discovery .NewDiscoveryClientForConfig (wildcardConfig )
244+ Expect (err ).NotTo (HaveOccurred ())
245+ envtest .Eventually (GinkgoT (), func () (bool , string ) {
246+ ret , err := disc .ServerGroups ()
247+ Expect (err ).NotTo (HaveOccurred ())
248+ for _ , g := range ret .Groups {
249+ if g .Name == "example.com" {
250+ return true , ""
251+ }
252+ }
253+ return false , fmt .Sprintf ("failed to find group example.com in:\n %s" , toYAML (GinkgoT (), ret ))
254+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to find group example.com in the virtual workspace" )
255+
201256 By ("creating a manager against the provider workspace" )
202257 rootConfig := rest .CopyConfig (kcpConfig )
203258 rootConfig .Host += provider .RequestPath ()
204259 mgr , err = mcmanager .New (rootConfig , p , mcmanager.Options {})
205260 Expect (err ).NotTo (HaveOccurred ())
206261
207- By ("creating a reconciler for the APIBinding" )
262+ By ("adding an index on label 'color'" )
263+ thing := & unstructured.Unstructured {}
264+ thing .SetGroupVersionKind (runtimeschema.GroupVersionKind {Group : "example.com" , Version : "v1" , Kind : "Thing" })
265+ err = mgr .GetFieldIndexer ().IndexField (ctx , thing , "color" , func (obj client.Object ) []string {
266+ u := obj .(* unstructured.Unstructured )
267+ return []string {u .GetLabels ()["color" ]}
268+ })
269+ Expect (err ).NotTo (HaveOccurred ())
270+
271+ By ("creating a reconciler for APIBindings" )
208272 err = mcbuilder .ControllerManagedBy (mgr ).
209273 Named ("things" ).
210274 For (& apisv1alpha1.APIBinding {}).
@@ -238,6 +302,46 @@ var _ = Describe("VirtualWorkspace Provider", Ordered, func() {
238302 }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see the consumer workspace %q as a cluster" , consumer )
239303 })
240304
305+ It ("sees only the stone in the consumer clusters" , func () {
306+ consumerCl , err := mgr .GetCluster (ctx , consumerWS .Spec .Cluster )
307+ Expect (err ).NotTo (HaveOccurred ())
308+
309+ envtest .Eventually (GinkgoT (), func () (success bool , reason string ) {
310+ l := & unstructured.UnstructuredList {}
311+ l .SetGroupVersionKind (runtimeschema.GroupVersionKind {Group : "example.com" , Version : "v1" , Kind : "ThingList" })
312+ err = consumerCl .GetCache ().List (ctx , l )
313+ if err != nil {
314+ return false , fmt .Sprintf ("failed to list things in the consumer cluster cache: %v" , err )
315+ }
316+ if len (l .Items ) != 1 {
317+ return false , fmt .Sprintf ("expected 1 item, got %d\n \n %s" , len (l .Items ), toYAML (GinkgoT (), l .Object ))
318+ } else if name := l .Items [0 ].GetName (); name != "stone" {
319+ return false , fmt .Sprintf ("expected item name to be stone, got %q\n \n %s" , name , toYAML (GinkgoT (), l .Items [0 ]))
320+ }
321+ return true , ""
322+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see the stone in the consumer cluster" )
323+ })
324+
325+ It ("sees only the stone as grey thing in the consumer clusters" , func () {
326+ consumerCl , err := mgr .GetCluster (ctx , consumerWS .Spec .Cluster )
327+ Expect (err ).NotTo (HaveOccurred ())
328+
329+ envtest .Eventually (GinkgoT (), func () (success bool , reason string ) {
330+ l := & unstructured.UnstructuredList {}
331+ l .SetGroupVersionKind (runtimeschema.GroupVersionKind {Group : "example.com" , Version : "v1" , Kind : "ThingList" })
332+ err = consumerCl .GetCache ().List (ctx , l , client.MatchingFields {"color" : "gray" })
333+ if err != nil {
334+ return false , fmt .Sprintf ("failed to list things in the consumer cluster cache: %v" , err )
335+ }
336+ if len (l .Items ) != 1 {
337+ return false , fmt .Sprintf ("expected 1 item, got %d\n \n %s" , len (l .Items ), toYAML (GinkgoT (), l .Object ))
338+ } else if name := l .Items [0 ].GetName (); name != "stone" {
339+ return false , fmt .Sprintf ("expected item name to be stone, got %q\n \n %s" , name , toYAML (GinkgoT (), l .Items [0 ]))
340+ }
341+ return true , ""
342+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see the stone as only thing of color 'grey' in the consumer cluster" )
343+ })
344+
241345 AfterAll (func () {
242346 cancelGroup ()
243347 err := g .Wait ()
0 commit comments