sigs.k8s.io/cluster-api-provider-azure@v1.17.0/test/e2e/aks_machinepools.go (about)

     1  //go:build e2e
     2  // +build e2e
     3  
     4  /*
     5  Copyright 2022 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  	"sync"
    25  
    26  	asocontainerservicev1 "github.com/Azure/azure-service-operator/v2/api/containerservice/v1api20231001"
    27  	. "github.com/onsi/ginkgo/v2"
    28  	. "github.com/onsi/gomega"
    29  	"k8s.io/apimachinery/pkg/types"
    30  	"k8s.io/utils/ptr"
    31  	infrav1alpha "sigs.k8s.io/cluster-api-provider-azure/api/v1alpha1"
    32  	infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
    33  	"sigs.k8s.io/cluster-api-provider-azure/pkg/mutators"
    34  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    35  	expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
    36  	"sigs.k8s.io/cluster-api/test/framework"
    37  	"sigs.k8s.io/controller-runtime/pkg/client"
    38  )
    39  
    40  type AKSMachinePoolSpecInput struct {
    41  	Cluster       *clusterv1.Cluster
    42  	MachinePools  []*expv1.MachinePool
    43  	WaitIntervals []interface{}
    44  }
    45  
    46  func AKSMachinePoolSpec(ctx context.Context, inputGetter func() AKSMachinePoolSpecInput) {
    47  	input := inputGetter()
    48  	var wg sync.WaitGroup
    49  
    50  	for _, mp := range input.MachinePools {
    51  		wg.Add(1)
    52  		go func(mp *expv1.MachinePool) {
    53  			defer GinkgoRecover()
    54  			defer wg.Done()
    55  
    56  			originalReplicas := ptr.Deref(mp.Spec.Replicas, 0)
    57  
    58  			Byf("Scaling machine pool %s out", mp.Name)
    59  			framework.ScaleMachinePoolAndWait(ctx, framework.ScaleMachinePoolAndWaitInput{
    60  				ClusterProxy:              bootstrapClusterProxy,
    61  				Cluster:                   input.Cluster,
    62  				Replicas:                  ptr.Deref(mp.Spec.Replicas, 0) + 1,
    63  				MachinePools:              []*expv1.MachinePool{mp},
    64  				WaitForMachinePoolToScale: input.WaitIntervals,
    65  			})
    66  
    67  			Byf("Scaling machine pool %s in", mp.Name)
    68  			framework.ScaleMachinePoolAndWait(ctx, framework.ScaleMachinePoolAndWaitInput{
    69  				ClusterProxy:              bootstrapClusterProxy,
    70  				Cluster:                   input.Cluster,
    71  				Replicas:                  ptr.Deref(mp.Spec.Replicas, 0) - 1,
    72  				MachinePools:              []*expv1.MachinePool{mp},
    73  				WaitForMachinePoolToScale: input.WaitIntervals,
    74  			})
    75  
    76  			// System node pools cannot be scaled to 0, so only include user node pools.
    77  			isUserPool := false
    78  			switch mp.Spec.Template.Spec.InfrastructureRef.Kind {
    79  			case infrav1.AzureManagedMachinePoolKind:
    80  				ammp := &infrav1.AzureManagedMachinePool{}
    81  				err := bootstrapClusterProxy.GetClient().Get(ctx, types.NamespacedName{
    82  					Namespace: mp.Spec.Template.Spec.InfrastructureRef.Namespace,
    83  					Name:      mp.Spec.Template.Spec.InfrastructureRef.Name,
    84  				}, ammp)
    85  				Expect(err).NotTo(HaveOccurred())
    86  
    87  				if ammp.Spec.Mode != string(infrav1.NodePoolModeSystem) {
    88  					isUserPool = true
    89  				}
    90  			case infrav1alpha.AzureASOManagedMachinePoolKind:
    91  				ammp := &infrav1alpha.AzureASOManagedMachinePool{}
    92  				err := bootstrapClusterProxy.GetClient().Get(ctx, types.NamespacedName{
    93  					Namespace: mp.Spec.Template.Spec.InfrastructureRef.Namespace,
    94  					Name:      mp.Spec.Template.Spec.InfrastructureRef.Name,
    95  				}, ammp)
    96  				Expect(err).NotTo(HaveOccurred())
    97  
    98  				resources, err := mutators.ToUnstructured(ctx, ammp.Spec.Resources)
    99  				Expect(err).NotTo(HaveOccurred())
   100  				for _, resource := range resources {
   101  					if resource.GetKind() != "ManagedClustersAgentPool" {
   102  						continue
   103  					}
   104  					// mode may not be set in spec. Get the ASO object and check in status.
   105  					resource.SetNamespace(ammp.Namespace)
   106  					agentPool := &asocontainerservicev1.ManagedClustersAgentPool{}
   107  					Expect(bootstrapClusterProxy.GetClient().Get(ctx, client.ObjectKeyFromObject(resource), agentPool)).To(Succeed())
   108  					if ptr.Deref(agentPool.Status.Mode, "") != asocontainerservicev1.AgentPoolMode_STATUS_System {
   109  						isUserPool = true
   110  					}
   111  					break
   112  				}
   113  			}
   114  
   115  			if isUserPool {
   116  				Byf("Scaling the machine pool %s to zero", mp.Name)
   117  				framework.ScaleMachinePoolAndWait(ctx, framework.ScaleMachinePoolAndWaitInput{
   118  					ClusterProxy:              bootstrapClusterProxy,
   119  					Cluster:                   input.Cluster,
   120  					Replicas:                  0,
   121  					MachinePools:              []*expv1.MachinePool{mp},
   122  					WaitForMachinePoolToScale: input.WaitIntervals,
   123  				})
   124  			}
   125  
   126  			Byf("Restoring initial replica count for machine pool %s", mp.Name)
   127  			framework.ScaleMachinePoolAndWait(ctx, framework.ScaleMachinePoolAndWaitInput{
   128  				ClusterProxy:              bootstrapClusterProxy,
   129  				Cluster:                   input.Cluster,
   130  				Replicas:                  originalReplicas,
   131  				MachinePools:              []*expv1.MachinePool{mp},
   132  				WaitForMachinePoolToScale: input.WaitIntervals,
   133  			})
   134  		}(mp)
   135  	}
   136  
   137  	wg.Wait()
   138  }