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

     1  //go:build e2e
     2  // +build e2e
     3  
     4  /*
     5  Copyright 2023 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  	"fmt"
    25  	"sync"
    26  
    27  	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    28  	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4"
    29  	. "github.com/onsi/ginkgo/v2"
    30  	. "github.com/onsi/gomega"
    31  	corev1 "k8s.io/api/core/v1"
    32  	"k8s.io/apimachinery/pkg/types"
    33  	"k8s.io/utils/ptr"
    34  	infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
    35  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    36  	expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
    37  	"sigs.k8s.io/controller-runtime/pkg/client"
    38  )
    39  
    40  type AKSNodeTaintsSpecInput struct {
    41  	Cluster       *clusterv1.Cluster
    42  	MachinePools  []*expv1.MachinePool
    43  	WaitForUpdate []interface{}
    44  }
    45  
    46  func AKSNodeTaintsSpec(ctx context.Context, inputGetter func() AKSNodeTaintsSpecInput) {
    47  	input := inputGetter()
    48  
    49  	cred, err := azidentity.NewDefaultAzureCredential(nil)
    50  	Expect(err).NotTo(HaveOccurred())
    51  
    52  	agentpoolsClient, err := armcontainerservice.NewAgentPoolsClient(getSubscriptionID(Default), cred, nil)
    53  	Expect(err).NotTo(HaveOccurred())
    54  
    55  	mgmtClient := bootstrapClusterProxy.GetClient()
    56  	Expect(mgmtClient).NotTo(BeNil())
    57  
    58  	infraControlPlane := &infrav1.AzureManagedControlPlane{}
    59  	err = mgmtClient.Get(ctx, client.ObjectKey{
    60  		Namespace: input.Cluster.Spec.ControlPlaneRef.Namespace,
    61  		Name:      input.Cluster.Spec.ControlPlaneRef.Name,
    62  	}, infraControlPlane)
    63  	Expect(err).NotTo(HaveOccurred())
    64  
    65  	var wg sync.WaitGroup
    66  
    67  	for _, mp := range input.MachinePools {
    68  		wg.Add(1)
    69  		go func(mp *expv1.MachinePool) {
    70  			defer GinkgoRecover()
    71  			defer wg.Done()
    72  
    73  			ammp := &infrav1.AzureManagedMachinePool{}
    74  			Expect(mgmtClient.Get(ctx, types.NamespacedName{
    75  				Namespace: mp.Spec.Template.Spec.InfrastructureRef.Namespace,
    76  				Name:      mp.Spec.Template.Spec.InfrastructureRef.Name,
    77  			}, ammp)).To(Succeed())
    78  			initialTaints := ammp.Spec.Taints
    79  
    80  			var expectedTaints infrav1.Taints
    81  			checkTaints := func(g Gomega) {
    82  				var expectedTaintStrs []*string
    83  				if expectedTaints != nil {
    84  					expectedTaintStrs = make([]*string, 0, len(expectedTaints))
    85  					for _, taint := range expectedTaints {
    86  						expectedTaintStrs = append(expectedTaintStrs, ptr.To(fmt.Sprintf("%s=%s:%s", taint.Key, taint.Value, taint.Effect)))
    87  					}
    88  				}
    89  
    90  				resp, err := agentpoolsClient.Get(ctx, infraControlPlane.Spec.ResourceGroupName, infraControlPlane.Name, *ammp.Spec.Name, nil)
    91  				g.Expect(err).NotTo(HaveOccurred())
    92  				g.Expect(resp.Properties.ProvisioningState).To(Equal(ptr.To("Succeeded")))
    93  				actualTaintStrs := resp.AgentPool.Properties.NodeTaints
    94  				if expectedTaintStrs == nil {
    95  					g.Expect(actualTaintStrs).To(BeNil())
    96  				} else {
    97  					g.Expect(actualTaintStrs).To(Equal(expectedTaintStrs))
    98  				}
    99  			}
   100  
   101  			Byf("Deleting all node taints for machine pool %s", mp.Name)
   102  			expectedTaints = nil
   103  			Eventually(func(g Gomega) {
   104  				g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(ammp), ammp)).To(Succeed())
   105  				ammp.Spec.Taints = expectedTaints
   106  				g.Expect(mgmtClient.Update(ctx, ammp)).To(Succeed())
   107  			}, inputGetter().WaitForUpdate...).Should(Succeed())
   108  			Eventually(checkTaints, input.WaitForUpdate...).Should(Succeed())
   109  
   110  			Byf("Creating taints for machine pool %s", mp.Name)
   111  			expectedTaints = infrav1.Taints{
   112  				{
   113  					Effect: infrav1.TaintEffect(corev1.TaintEffectPreferNoSchedule),
   114  					Key:    "capz-e2e-1",
   115  					Value:  "test1",
   116  				},
   117  				{
   118  					Effect: infrav1.TaintEffect(corev1.TaintEffectPreferNoSchedule),
   119  					Key:    "capz-e2e-2",
   120  					Value:  "test2",
   121  				},
   122  			}
   123  			Eventually(func(g Gomega) {
   124  				g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(ammp), ammp)).To(Succeed())
   125  				ammp.Spec.Taints = expectedTaints
   126  				g.Expect(mgmtClient.Update(ctx, ammp)).To(Succeed())
   127  				Eventually(checkTaints, input.WaitForUpdate...).Should(Succeed())
   128  			}, input.WaitForUpdate...).Should(Succeed())
   129  
   130  			Byf("Updating taints for machine pool %s", mp.Name)
   131  			expectedTaints = expectedTaints[:1]
   132  			Eventually(func(g Gomega) {
   133  				g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(ammp), ammp)).To(Succeed())
   134  				ammp.Spec.Taints = expectedTaints
   135  				g.Expect(mgmtClient.Update(ctx, ammp)).To(Succeed())
   136  			}, input.WaitForUpdate...).Should(Succeed())
   137  			Eventually(checkTaints, input.WaitForUpdate...).Should(Succeed())
   138  
   139  			Byf("Restoring initial taints for machine pool %s", mp.Name)
   140  			expectedTaints = initialTaints
   141  			Eventually(func(g Gomega) {
   142  				g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(ammp), ammp)).To(Succeed())
   143  				ammp.Spec.Taints = expectedTaints
   144  				g.Expect(mgmtClient.Update(ctx, ammp)).To(Succeed())
   145  			}, input.WaitForUpdate...).Should(Succeed())
   146  			Eventually(checkTaints, input.WaitForUpdate...).Should(Succeed())
   147  		}(mp)
   148  	}
   149  
   150  	wg.Wait()
   151  }