@@ -20,12 +20,11 @@ import (
2020 "context"
2121 "fmt"
2222 "slices"
23- "sync"
2423 "time"
2524
2625 "golang.org/x/sync/errgroup"
26+ ctrl "sigs.k8s.io/controller-runtime"
2727
28- corev1 "k8s.io/api/core/v1"
2928 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3029 "k8s.io/apimachinery/pkg/util/sets"
3130 "k8s.io/apimachinery/pkg/util/wait"
@@ -37,9 +36,10 @@ import (
3736 mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager"
3837 mcreconcile "sigs.k8s.io/multicluster-runtime/pkg/reconcile"
3938
39+ "github.com/kcp-dev/kcp/sdk/apis/tenancy/initialization"
40+
4041 "github.com/kcp-dev/kcp/sdk/apis/core"
4142 kcpcorev1alpha1 "github.com/kcp-dev/kcp/sdk/apis/core/v1alpha1"
42- "github.com/kcp-dev/kcp/sdk/apis/tenancy/initialization"
4343 tenancyv1alpha1 "github.com/kcp-dev/kcp/sdk/apis/tenancy/v1alpha1"
4444 "github.com/kcp-dev/logicalcluster/v3"
4545
@@ -59,9 +59,10 @@ var _ = Describe("InitializingWorkspaces Provider", Ordered, func() {
5959 ctx context.Context
6060 cancel context.CancelFunc
6161
62- cli clusterclient.ClusterClient
63- workspace1 , workspace2 logicalcluster.Path
64- mgr mcmanager.Manager
62+ cli clusterclient.ClusterClient
63+ ws1Path , ws2Path logicalcluster.Path
64+ ws1 , ws2 * tenancyv1alpha1.Workspace
65+ mgr mcmanager.Manager
6566 )
6667
6768 BeforeAll (func () {
@@ -95,23 +96,23 @@ var _ = Describe("InitializingWorkspaces Provider", Ordered, func() {
9596 }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to wait for WorkspaceType to be ready" )
9697
9798 By ("creating Workspaces with the WorkspaceType with initializers" )
98- _ , workspace1 = envtest .NewInitializingWorkspaceFixture (GinkgoT (), cli , core .RootCluster .Path (),
99+ ws1 , ws1Path = envtest .NewInitializingWorkspaceFixture (GinkgoT (), cli , core .RootCluster .Path (),
99100 envtest .WithNamePrefix ("init-ws1" ),
100- envtest .WithType (core .RootCluster .Path (), tenancyv1alpha1 .WorkspaceTypeName ("e2e-test-ws-type" )))
101+ envtest .WithType (core .RootCluster .Path (), tenancyv1alpha1 .WorkspaceTypeName (workspaceTypeName )))
101102
102- _ , workspace2 = envtest .NewInitializingWorkspaceFixture (GinkgoT (), cli , core .RootCluster .Path (),
103+ ws2 , ws2Path = envtest .NewInitializingWorkspaceFixture (GinkgoT (), cli , core .RootCluster .Path (),
103104 envtest .WithNamePrefix ("init-ws2" ),
104- envtest .WithType (core .RootCluster .Path (), tenancyv1alpha1 .WorkspaceTypeName ("e2e-test-ws-type" )))
105+ envtest .WithType (core .RootCluster .Path (), tenancyv1alpha1 .WorkspaceTypeName (workspaceTypeName )))
105106 })
106107
107108 It ("sees both clusters with initializers" , func () {
108109 By ("getting LogicalCluster for workspaces and their cluster names" )
109110 lc1 := & kcpcorev1alpha1.LogicalCluster {}
110- err := cli .Cluster (workspace1 ).Get (ctx , client.ObjectKey {Name : "cluster" }, lc1 )
111+ err := cli .Cluster (ws1Path ).Get (ctx , client.ObjectKey {Name : "cluster" }, lc1 )
111112 Expect (err ).NotTo (HaveOccurred ())
112113
113114 lc2 := & kcpcorev1alpha1.LogicalCluster {}
114- err = cli .Cluster (workspace2 ).Get (ctx , client.ObjectKey {Name : "cluster" }, lc2 )
115+ err = cli .Cluster (ws2Path ).Get (ctx , client.ObjectKey {Name : "cluster" }, lc2 )
115116 Expect (err ).NotTo (HaveOccurred ())
116117 envtest .Eventually (GinkgoT (), func () (bool , string ) {
117118 return slices .Contains (lc1 .Status .Initializers , kcpcorev1alpha1 .LogicalClusterInitializer (initName )) && slices .Contains (lc2 .Status .Initializers , kcpcorev1alpha1 .LogicalClusterInitializer (initName )),
@@ -121,22 +122,21 @@ var _ = Describe("InitializingWorkspaces Provider", Ordered, func() {
121122
122123 Describe ("with a multicluster provider and manager" , func () {
123124 var (
124- lock sync.RWMutex
125125 engaged = sets .NewString ()
126126 p * initializingworkspaces.Provider
127127 g * errgroup.Group
128128 cancelGroup context.CancelFunc
129- configMapsCreated = sets .NewString ()
130129 initializersRemoved = sets .NewString ()
131130 )
132131
133132 BeforeAll (func () {
133+ cli , err := clusterclient .New (kcpConfig , client.Options {})
134+ Expect (err ).NotTo (HaveOccurred ())
134135 By ("creating a multicluster provider for initializing workspaces" )
135- var err error
136136
137137 // Get the initializing workspaces virtual workspace URL
138138 wt := & tenancyv1alpha1.WorkspaceType {}
139- err = cli .Cluster (core .RootCluster .Path ()).Get (ctx , client.ObjectKey {Name : "e2e-test-ws-type" }, wt )
139+ err = cli .Cluster (core .RootCluster .Path ()).Get (ctx , client.ObjectKey {Name : workspaceTypeName }, wt )
140140 Expect (err ).NotTo (HaveOccurred ())
141141 Expect (len (wt .Status .VirtualWorkspaces )).To (BeNumerically (">" , 0 ))
142142
@@ -155,55 +155,37 @@ var _ = Describe("InitializingWorkspaces Provider", Ordered, func() {
155155
156156 By ("creating a reconciler for LogicalClusters" )
157157 err = mcbuilder .ControllerManagedBy (mgr ).
158- Named ("logicalclusters " ).
158+ Named ("kcp-initializer-controller " ).
159159 For (& kcpcorev1alpha1.LogicalCluster {}).
160- Complete (mcreconcile .Func (func (ctx context.Context , request mcreconcile.Request ) (reconcile.Result , error ) {
161- By (fmt .Sprintf ("reconciling LogicalCluster %s in cluster %q" , request .Name , request .ClusterName ))
162- lock .Lock ()
163- defer lock .Unlock ()
164- engaged .Insert (request .ClusterName )
165- cl , err := mgr .GetCluster (ctx , request .ClusterName )
166- if err != nil {
167- return reconcile.Result {}, err
168- }
169-
170- lc := & kcpcorev1alpha1.LogicalCluster {}
171- if err := cl .GetClient ().Get (ctx , request .NamespacedName , lc ); err != nil {
172- return reconcile.Result {}, client .IgnoreNotFound (err )
173- }
174-
175- initializer := kcpcorev1alpha1 .LogicalClusterInitializer (initName )
176- hasInitializer := slices .Contains (lc .Status .Initializers , initializer )
177-
178- if hasInitializer {
179- cm := & corev1.ConfigMap {
180- ObjectMeta : metav1.ObjectMeta {
181- Name : "initializer-test-cm" ,
182- Namespace : "default" ,
183- },
184- Data : map [string ]string {
185- "cluster" : request .ClusterName ,
186- "test" : "value" ,
187- },
160+ Complete (mcreconcile .Func (
161+ func (ctx context.Context , request mcreconcile.Request ) (ctrl.Result , error ) {
162+ By (fmt .Sprintf ("reconciling LogicalCluster %s in cluster %q" , request .Name , request .ClusterName ))
163+ cl , err := mgr .GetCluster (ctx , request .ClusterName )
164+ if err != nil {
165+ return reconcile.Result {}, err
188166 }
167+ clusterClient := cl .GetClient ()
189168
190- if err := cl .GetClient ().Create (ctx , cm ); err == nil {
191- lock .Lock ()
192- configMapsCreated .Insert (request .ClusterName )
193- lock .Unlock ()
169+ lc := & kcpcorev1alpha1.LogicalCluster {}
170+ if err := clusterClient .Get (ctx , request .NamespacedName , lc ); err != nil {
171+ return reconcile.Result {}, err
194172 }
195173
196- patch := client .MergeFrom (lc .DeepCopy ())
197- lc .Status .Initializers = initialization .EnsureInitializerAbsent (initializer , lc .Status .Initializers )
198- if err := cl .GetClient ().Status ().Patch (ctx , lc , patch ); err == nil {
199- lock .Lock ()
174+ engaged .Insert (request .ClusterName )
175+ initializer := kcpcorev1alpha1 .LogicalClusterInitializer (initName )
176+
177+ if slices .Contains (lc .Status .Initializers , initializer ) {
178+ By (fmt .Sprintf ("removing initializer %q from LogicalCluster %s in cluster %q" , initName , request .Name , request .ClusterName ))
179+
180+ patch := client .MergeFrom (lc .DeepCopy ())
181+ lc .Status .Initializers = initialization .EnsureInitializerAbsent (initializer , lc .Status .Initializers )
182+ if err := clusterClient .Status ().Patch (ctx , lc , patch ); err != nil {
183+ return reconcile.Result {}, err
184+ }
200185 initializersRemoved .Insert (request .ClusterName )
201- lock .Unlock ()
202186 }
203- }
204-
205- return reconcile.Result {}, nil
206- }))
187+ return reconcile.Result {}, nil
188+ }))
207189 Expect (err ).NotTo (HaveOccurred ())
208190
209191 By ("starting the provider and manager" )
@@ -217,60 +199,41 @@ var _ = Describe("InitializingWorkspaces Provider", Ordered, func() {
217199 return mgr .Start (groupContext )
218200 })
219201 })
220- It ("creates ConfigMaps in both workspaces" , func () {
221- // Wait for ConfigMap in workspace1
202+ It ("engages both Logical Clusters with initializers" , func () {
222203 envtest .Eventually (GinkgoT (), func () (bool , string ) {
223- cm := & corev1.ConfigMap {}
224- err := cli .Cluster (workspace1 ).Get (ctx ,
225- client.ObjectKey {Namespace : "default" , Name : "initializer-test-cm" },
226- cm )
227- if err != nil {
228- return false , fmt .Sprintf ("failed to get ConfigMap in workspace1: %v" , err )
229- }
230- return true , ""
231- }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to create ConfigMap in workspace1" )
232-
233- // Wait for ConfigMap in workspace2
204+ return engaged .Has (ws1 .Spec .Cluster ), fmt .Sprintf ("failed to see workspace %q engaged as a cluster: %v" , ws1 .Spec .Cluster , engaged .List ())
205+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see workspace %q engaged as a cluster: %v" , ws1 .Spec .Cluster , engaged .List ())
206+
234207 envtest .Eventually (GinkgoT (), func () (bool , string ) {
235- cm := & corev1.ConfigMap {}
236- err := cli .Cluster (workspace2 ).Get (ctx ,
237- client.ObjectKey {Namespace : "default" , Name : "initializer-test-cm" },
238- cm )
239- if err != nil {
240- return false , fmt .Sprintf ("failed to get ConfigMap in workspace2: %v" , err )
241- }
242- return true , ""
243- }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to create ConfigMap in workspace2" )
208+ return engaged .Has (ws2 .Spec .Cluster ), fmt .Sprintf ("failed to see workspace %q engaged as a cluster: %v" , ws2 .Spec .Cluster , engaged .List ())
209+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see workspace %q engaged as a cluster: %v" , ws2 .Spec .Cluster , engaged .List ())
210+
211+ fmt .Println ("Engaged clusters:" , engaged .List ())
212+ fmt .Println ("Workspace 2:" , ws2 .Spec .Cluster )
244213 })
245214
246- It ("has removed initializers from both workspaces" , func () {
247- // Verify initializer removed in workspace1
215+ It ("removes initializers from the both clusters after engaging" , func () {
216+ envtest .Eventually (GinkgoT (), func () (bool , string ) {
217+ return initializersRemoved .Has (ws1 .Spec .Cluster ), fmt .Sprintf ("failed to see removed initializer from %q cluster: %v" , ws1 .Spec .Cluster , initializersRemoved .List ())
218+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see removed initializer from %q cluster: %v" , ws1 .Spec .Cluster , initializersRemoved .List ())
219+
220+ envtest .Eventually (GinkgoT (), func () (bool , string ) {
221+ return initializersRemoved .Has (ws2 .Spec .Cluster ), fmt .Sprintf ("failed to see removed initializer from %q cluster: %v" , ws2 .Spec .Cluster , initializersRemoved .List ())
222+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see removed initializer from %q cluster: %v" , ws2 .Spec .Cluster , initializersRemoved .List ())
223+
224+ By ("checking if LogicalClusters objects have no initializers left" )
225+ var err error
248226 lc1 := & kcpcorev1alpha1.LogicalCluster {}
249- err : = cli .Cluster (workspace1 ).Get (ctx , client.ObjectKey {Name : "cluster" }, lc1 )
227+ err = cli .Cluster (ws1Path ).Get (ctx , client.ObjectKey {Name : "cluster" }, lc1 )
250228 Expect (err ).NotTo (HaveOccurred ())
251229
252- hasInitializer := false
253- for _ , init := range lc1 .Status .Initializers {
254- if string (init ) == "root:e2e-test-ws-type" {
255- hasInitializer = true
256- break
257- }
258- }
259- Expect (hasInitializer ).To (BeFalse ())
260-
261- // Verify initializer removed in workspace2
262230 lc2 := & kcpcorev1alpha1.LogicalCluster {}
263- err = cli .Cluster (workspace2 ).Get (ctx , client.ObjectKey {Name : "cluster" }, lc2 )
231+ err = cli .Cluster (ws2Path ).Get (ctx , client.ObjectKey {Name : "cluster" }, lc2 )
264232 Expect (err ).NotTo (HaveOccurred ())
265-
266- hasInitializer = false
267- for _ , init := range lc2 .Status .Initializers {
268- if string (init ) == "root:e2e-test-ws-type" {
269- hasInitializer = true
270- break
271- }
272- }
273- Expect (hasInitializer ).To (BeFalse ())
233+ envtest .Eventually (GinkgoT (), func () (bool , string ) {
234+ return ! slices .Contains (lc1 .Status .Initializers , kcpcorev1alpha1 .LogicalClusterInitializer (initName )) && ! slices .Contains (lc2 .Status .Initializers , kcpcorev1alpha1 .LogicalClusterInitializer (initName )),
235+ fmt .Sprintf ("Initializer not set: %v" , lc1 .Status ) + " " + fmt .Sprintf ("%v" , lc2 .Status )
236+ }, wait .ForeverTestTimeout , time .Millisecond * 100 , "failed to see removed initializers in both clusters" )
274237 })
275238
276239 AfterAll (func () {
0 commit comments