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 }