@@ -27,9 +27,12 @@ import (
27
27
28
28
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
29
29
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
30
31
"k8s.io/apimachinery/pkg/runtime"
32
+ runtimeschema "k8s.io/apimachinery/pkg/runtime/schema"
31
33
"k8s.io/apimachinery/pkg/util/sets"
32
34
"k8s.io/apimachinery/pkg/util/wait"
35
+ "k8s.io/client-go/discovery"
33
36
"k8s.io/client-go/rest"
34
37
"sigs.k8s.io/controller-runtime/pkg/client"
35
38
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -57,11 +60,11 @@ var _ = Describe("VirtualWorkspace Provider", Ordered, func() {
57
60
ctx context.Context
58
61
cancel context.CancelFunc
59
62
60
- cli clusterclient.ClusterClient
61
- provider , consumer logicalcluster.Path
62
- consumerWS * tenancyv1alpha1.Workspace
63
- mgr mcmanager.Manager
64
- vwEndpoint string
63
+ cli clusterclient.ClusterClient
64
+ provider , consumer , other logicalcluster.Path
65
+ consumerWS * tenancyv1alpha1.Workspace
66
+ mgr mcmanager.Manager
67
+ vwEndpoint string
65
68
)
66
69
67
70
BeforeAll (func () {
@@ -73,6 +76,7 @@ var _ = Describe("VirtualWorkspace Provider", Ordered, func() {
73
76
74
77
_ , provider = envtest .NewWorkspaceFixture (GinkgoT (), cli , core .RootCluster .Path (), envtest .WithNamePrefix ("provider" ))
75
78
consumerWS , consumer = envtest .NewWorkspaceFixture (GinkgoT (), cli , core .RootCluster .Path (), envtest .WithNamePrefix ("consumer" ))
79
+ _ , other = envtest .NewWorkspaceFixture (GinkgoT (), cli , core .RootCluster .Path (), envtest .WithNamePrefix ("other" ))
76
80
77
81
By (fmt .Sprintf ("creating a schema in the provider workspace %q" , provider ))
78
82
schema := & apisv1alpha1.APIResourceSchema {
@@ -154,12 +158,32 @@ var _ = Describe("VirtualWorkspace Provider", Ordered, func() {
154
158
return len (endpoints .Status .APIExportEndpoints ) > 0 , toYAML (GinkgoT (), endpoints )
155
159
}, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see endpoints in APIExportEndpointSlice in %s" , provider )
156
160
vwEndpoint = endpoints .Status .APIExportEndpoints [0 ].URL
161
+
162
+ By (fmt .Sprintf ("waiting until the APIBinding in the consumer workspace %q to be ready" , consumer ))
163
+ envtest .Eventually (GinkgoT (), func () (bool , string ) {
164
+ current := & apisv1alpha1.APIBinding {}
165
+ err := cli .Cluster (consumer ).Get (ctx , client.ObjectKey {Name : "example.com" }, current )
166
+ if err != nil {
167
+ return false , fmt .Sprintf ("failed to get APIBinding in %s: %v" , consumer , err )
168
+ }
169
+ if current .Status .Phase != apisv1alpha1 .APIBindingPhaseBound {
170
+ return false , fmt .Sprintf ("binding not bound:\n \n %s" , toYAML (GinkgoT (), current ))
171
+ }
172
+ u := & unstructured.UnstructuredList {}
173
+ u .SetGroupVersionKind (runtimeschema.GroupVersionKind {Group : "example.com" , Version : "v1" , Kind : "ThingList" })
174
+ err = cli .Cluster (consumer ).List (ctx , u )
175
+ if err != nil {
176
+ return false , fmt .Sprintf ("failed to list things in %s: %v\n \n %s" , consumer , err , toYAML (GinkgoT (), current ))
177
+ }
178
+ return true , ""
179
+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to list things in %s workspace" , consumer )
157
180
})
158
181
159
182
Describe ("with a multicluster provider and manager" , func () {
160
183
var (
161
184
lock sync.RWMutex
162
185
engaged = sets .NewString ()
186
+ p * virtualworkspace.Provider
163
187
g * errgroup.Group
164
188
cancelGroup context.CancelFunc
165
189
)
@@ -168,16 +192,42 @@ var _ = Describe("VirtualWorkspace Provider", Ordered, func() {
168
192
By ("creating a multicluster provider for APIBindings against the apiexport virtual workspace" )
169
193
vwConfig := rest .CopyConfig (kcpConfig )
170
194
vwConfig .Host = vwEndpoint
171
- p , err := virtualworkspace .New (vwConfig , & apisv1alpha1.APIBinding {}, virtualworkspace.Options {})
195
+ var err error
196
+ p , err = virtualworkspace .New (vwConfig , & apisv1alpha1.APIBinding {}, virtualworkspace.Options {})
172
197
Expect (err ).NotTo (HaveOccurred ())
173
198
199
+ By ("waiting for discovery of the virtual workspace to show 'example.com'" )
200
+ wildcardConfig := rest .CopyConfig (vwConfig )
201
+ wildcardConfig .Host += logicalcluster .Wildcard .RequestPath ()
202
+ disc , err := discovery .NewDiscoveryClientForConfig (wildcardConfig )
203
+ Expect (err ).NotTo (HaveOccurred ())
204
+ envtest .Eventually (GinkgoT (), func () (bool , string ) {
205
+ ret , err := disc .ServerGroups ()
206
+ Expect (err ).NotTo (HaveOccurred ())
207
+ for _ , g := range ret .Groups {
208
+ if g .Name == "example.com" {
209
+ return true , ""
210
+ }
211
+ }
212
+ return false , fmt .Sprintf ("failed to find group example.com in:\n %s" , toYAML (GinkgoT (), ret ))
213
+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to find group example.com in the virtual workspace" )
214
+
174
215
By ("creating a manager against the provider workspace" )
175
216
rootConfig := rest .CopyConfig (kcpConfig )
176
217
rootConfig .Host += provider .RequestPath ()
177
218
mgr , err = mcmanager .New (rootConfig , p , mcmanager.Options {})
178
219
Expect (err ).NotTo (HaveOccurred ())
179
220
180
- By ("creating a reconciler for the APIBinding" )
221
+ By ("adding an index on label 'color'" )
222
+ thing := & unstructured.Unstructured {}
223
+ thing .SetGroupVersionKind (runtimeschema.GroupVersionKind {Group : "example.com" , Version : "v1" , Kind : "Thing" })
224
+ err = mgr .GetFieldIndexer ().IndexField (ctx , thing , "color" , func (obj client.Object ) []string {
225
+ u := obj .(* unstructured.Unstructured )
226
+ return []string {u .GetLabels ()["color" ]}
227
+ })
228
+ Expect (err ).NotTo (HaveOccurred ())
229
+
230
+ By ("creating a reconciler for APIBindings" )
181
231
err = mcbuilder .ControllerManagedBy (mgr ).
182
232
Named ("things" ).
183
233
For (& apisv1alpha1.APIBinding {}).
@@ -211,6 +261,60 @@ var _ = Describe("VirtualWorkspace Provider", Ordered, func() {
211
261
}, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see the consumer workspace %q as a cluster" , consumer )
212
262
})
213
263
264
+ It ("sees only the stone in the consumer clusters" , func () {
265
+ By ("creating a stone in the consumer workspace" , func () {
266
+ thing := & unstructured.Unstructured {}
267
+ thing .SetGroupVersionKind (runtimeschema.GroupVersionKind {Group : "example.com" , Version : "v1" , Kind : "Thing" })
268
+ thing .SetNamespace ("stone" )
269
+ thing .SetLabels (map [string ]string {"color" : "gray" })
270
+ err := cli .Cluster (consumer ).Create (ctx , thing )
271
+ Expect (err ).NotTo (HaveOccurred ())
272
+ })
273
+
274
+ By ("creating a box in the other workspace" , func () {
275
+ thing := & unstructured.Unstructured {}
276
+ thing .SetGroupVersionKind (runtimeschema.GroupVersionKind {Group : "example.com" , Version : "v1" , Kind : "Thing" })
277
+ thing .SetNamespace ("box" )
278
+ thing .SetLabels (map [string ]string {"color" : "white" })
279
+ err := cli .Cluster (other ).Create (ctx , thing )
280
+ Expect (err ).NotTo (HaveOccurred ())
281
+ })
282
+
283
+ consumerCl , err := mgr .GetCluster (ctx , consumerWS .Spec .Cluster )
284
+ Expect (err ).NotTo (HaveOccurred ())
285
+
286
+ envtest .Eventually (GinkgoT (), func () (success bool , reason string ) {
287
+ l := & unstructured.UnstructuredList {}
288
+ l .SetGroupVersionKind (runtimeschema.GroupVersionKind {Group : "example.com" , Version : "v1" , Kind : "ThingList" })
289
+ err = consumerCl .GetCache ().List (ctx , l )
290
+ Expect (err ).NotTo (HaveOccurred ())
291
+ if len (l .Items ) != 1 {
292
+ return false , fmt .Sprintf ("expected 1 item, got %d\n \n %s" , len (l .Items ), toYAML (GinkgoT (), l .Object ))
293
+ } else if name := l .Items [0 ].GetName (); name != "stone" {
294
+ return false , fmt .Sprintf ("expected item name to be stone, got %q\n \n %s" , name , toYAML (GinkgoT (), l .Items [0 ]))
295
+ }
296
+ return true , ""
297
+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see the stone in the consumer cluster" )
298
+ })
299
+
300
+ It ("sees only the stone as grey thing in the consumer clusters" , func () {
301
+ consumerCl , err := mgr .GetCluster (ctx , consumerWS .Spec .Cluster )
302
+ Expect (err ).NotTo (HaveOccurred ())
303
+
304
+ envtest .Eventually (GinkgoT (), func () (success bool , reason string ) {
305
+ l := & unstructured.UnstructuredList {}
306
+ l .SetGroupVersionKind (runtimeschema.GroupVersionKind {Group : "example.com" , Version : "v1" , Kind : "ThingList" })
307
+ err = consumerCl .GetCache ().List (ctx , l , client.MatchingFields {"color" : "gray" })
308
+ Expect (err ).NotTo (HaveOccurred ())
309
+ if len (l .Items ) != 1 {
310
+ return false , fmt .Sprintf ("expected 1 item, got %d\n \n %s" , len (l .Items ), toYAML (GinkgoT (), l .Object ))
311
+ } else if name := l .Items [0 ].GetName (); name != "stone" {
312
+ return false , fmt .Sprintf ("expected item name to be stone, got %q\n \n %s" , name , toYAML (GinkgoT (), l .Items [0 ]))
313
+ }
314
+ return true , ""
315
+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see the stone as only thing of color 'grey' in the consumer cluster" )
316
+ })
317
+
214
318
AfterAll (func () {
215
319
cancelGroup ()
216
320
err := g .Wait ()
0 commit comments