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  }