sigs.k8s.io/cluster-api-provider-azure@v1.17.0/test/e2e/aks_adopt.go (about) 1 //go:build e2e 2 // +build e2e 3 4 /* 5 Copyright 2024 The Kubernetes Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 */ 19 20 package e2e 21 22 import ( 23 "context" 24 25 . "github.com/onsi/gomega" 26 apierrors "k8s.io/apimachinery/pkg/api/errors" 27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 28 infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" 29 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" 30 clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3" 31 expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1" 32 "sigs.k8s.io/cluster-api/test/framework/clusterctl" 33 "sigs.k8s.io/controller-runtime/pkg/client" 34 ) 35 36 type AKSAdoptSpecInput struct { 37 ApplyInput clusterctl.ApplyClusterTemplateAndWaitInput 38 ApplyResult *clusterctl.ApplyClusterTemplateAndWaitResult 39 Cluster *clusterv1.Cluster 40 MachinePools []*expv1.MachinePool 41 } 42 43 // AKSAdoptSpec tests adopting an existing AKS cluster into management by CAPZ. It first relies on a CAPZ AKS 44 // cluster having already been created. Then, it will orphan that cluster such that the CAPI and CAPZ 45 // resources are deleted but the Azure resources remain. Finally, it applies the cluster template again and 46 // waits for the cluster to become ready. 47 func AKSAdoptSpec(ctx context.Context, inputGetter func() AKSAdoptSpecInput) { 48 input := inputGetter() 49 50 mgmtClient := bootstrapClusterProxy.GetClient() 51 Expect(mgmtClient).NotTo(BeNil()) 52 53 updateResource := []any{"30s", "5s"} 54 55 waitForNoBlockMove := func(obj client.Object) { 56 waitForBlockMoveGone := []any{"30s", "5s"} 57 Eventually(func(g Gomega) { 58 g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(obj), obj)).To(Succeed()) 59 g.Expect(obj.GetAnnotations()).NotTo(HaveKey(clusterctlv1.BlockMoveAnnotation)) 60 }, waitForBlockMoveGone...).Should(Succeed()) 61 } 62 63 removeFinalizers := func(obj client.Object) { 64 Eventually(func(g Gomega) { 65 g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(obj), obj)).To(Succeed()) 66 obj.SetFinalizers([]string{}) 67 g.Expect(mgmtClient.Update(ctx, obj)).To(Succeed()) 68 }, updateResource...).Should(Succeed()) 69 } 70 71 waitForImmediateDelete := []any{"30s", "5s"} 72 beginDelete := func(obj client.Object) { 73 Eventually(func(g Gomega) { 74 err := mgmtClient.Delete(ctx, obj) 75 g.Expect(err).NotTo(HaveOccurred()) 76 }, updateResource...).Should(Succeed()) 77 } 78 shouldNotExist := func(obj client.Object) { 79 waitForGone := []any{"30s", "5s"} 80 Eventually(func(g Gomega) { 81 err := mgmtClient.Get(ctx, client.ObjectKeyFromObject(obj), obj) 82 g.Expect(apierrors.IsNotFound(err)).To(BeTrue()) 83 }, waitForGone...).Should(Succeed()) 84 } 85 deleteAndWait := func(obj client.Object) { 86 Eventually(func(g Gomega) { 87 err := mgmtClient.Delete(ctx, obj) 88 g.Expect(apierrors.IsNotFound(err)).To(BeTrue()) 89 }, waitForImmediateDelete...).Should(Succeed()) 90 } 91 92 cluster := input.Cluster 93 Eventually(func(g Gomega) { 94 g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(cluster), cluster)).To(Succeed()) 95 cluster.Spec.Paused = true 96 g.Expect(mgmtClient.Update(ctx, cluster)).To(Succeed()) 97 }, updateResource...).Should(Succeed()) 98 99 // wait for the pause to take effect before deleting anything 100 amcp := &infrav1.AzureManagedControlPlane{ 101 ObjectMeta: metav1.ObjectMeta{ 102 Namespace: cluster.Spec.ControlPlaneRef.Namespace, 103 Name: cluster.Spec.ControlPlaneRef.Name, 104 }, 105 } 106 waitForNoBlockMove(amcp) 107 for _, mp := range input.MachinePools { 108 ammp := &infrav1.AzureManagedMachinePool{ 109 ObjectMeta: metav1.ObjectMeta{ 110 Namespace: mp.Spec.Template.Spec.InfrastructureRef.Namespace, 111 Name: mp.Spec.Template.Spec.InfrastructureRef.Name, 112 }, 113 } 114 waitForNoBlockMove(ammp) 115 } 116 117 beginDelete(cluster) 118 119 for _, mp := range input.MachinePools { 120 beginDelete(mp) 121 122 ammp := &infrav1.AzureManagedMachinePool{ 123 ObjectMeta: metav1.ObjectMeta{ 124 Namespace: mp.Spec.Template.Spec.InfrastructureRef.Namespace, 125 Name: mp.Spec.Template.Spec.InfrastructureRef.Name, 126 }, 127 } 128 removeFinalizers(ammp) 129 deleteAndWait(ammp) 130 131 removeFinalizers(mp) 132 shouldNotExist(mp) 133 } 134 135 removeFinalizers(amcp) 136 deleteAndWait(amcp) 137 // AzureManagedCluster never gets a finalizer 138 deleteAndWait(&infrav1.AzureManagedCluster{ 139 ObjectMeta: metav1.ObjectMeta{ 140 Namespace: cluster.Spec.InfrastructureRef.Namespace, 141 Name: cluster.Spec.InfrastructureRef.Name, 142 }, 143 }) 144 145 removeFinalizers(cluster) 146 shouldNotExist(cluster) 147 148 clusterctl.ApplyClusterTemplateAndWait(ctx, input.ApplyInput, input.ApplyResult) 149 }