sigs.k8s.io/cluster-api-provider-azure@v1.14.3/test/e2e/aks_patches.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 "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 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 30 "k8s.io/apimachinery/pkg/types" 31 infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" 32 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" 33 expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1" 34 "sigs.k8s.io/controller-runtime/pkg/client" 35 ) 36 37 type AKSPatchSpecInput struct { 38 Cluster *clusterv1.Cluster 39 MachinePools []*expv1.MachinePool 40 WaitForUpdate []interface{} 41 } 42 43 func AKSPatchSpec(ctx context.Context, inputGetter func() AKSPatchSpecInput) { 44 input := inputGetter() 45 46 mgmtClient := bootstrapClusterProxy.GetClient() 47 Expect(mgmtClient).NotTo(BeNil()) 48 49 infraControlPlane := &infrav1.AzureManagedControlPlane{} 50 err := mgmtClient.Get(ctx, client.ObjectKey{ 51 Namespace: input.Cluster.Spec.ControlPlaneRef.Namespace, 52 Name: input.Cluster.Spec.ControlPlaneRef.Name, 53 }, infraControlPlane) 54 Expect(err).NotTo(HaveOccurred()) 55 56 var wg sync.WaitGroup 57 58 type CheckInput struct { 59 exist map[string]string 60 doNotExist []string 61 } 62 63 checkAnnotations := func(obj client.Object, c CheckInput) func(Gomega) { 64 return func(g Gomega) { 65 err := mgmtClient.Get(ctx, client.ObjectKeyFromObject(obj), obj) 66 g.Expect(err).NotTo(HaveOccurred()) 67 for k, v := range c.exist { 68 g.Expect(obj.GetAnnotations()).To(HaveKeyWithValue(k, v)) 69 } 70 for _, k := range c.doNotExist { 71 g.Expect(obj.GetAnnotations()).NotTo(HaveKey(k)) 72 } 73 } 74 } 75 76 wg.Add(1) 77 go func() { 78 defer GinkgoRecover() 79 defer wg.Done() 80 81 managedCluster := &asocontainerservicev1.ManagedCluster{ 82 ObjectMeta: metav1.ObjectMeta{ 83 Namespace: infraControlPlane.Namespace, 84 Name: infraControlPlane.Name, 85 }, 86 } 87 88 var initialPatches []string 89 By("Deleting patches for control plane") 90 Eventually(func(g Gomega) { 91 g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(infraControlPlane), infraControlPlane)).To(Succeed()) 92 initialPatches = infraControlPlane.Spec.ASOManagedClusterPatches 93 infraControlPlane.Spec.ASOManagedClusterPatches = nil 94 g.Expect(mgmtClient.Update(ctx, infraControlPlane)).To(Succeed()) 95 }, inputGetter().WaitForUpdate...).Should(Succeed()) 96 97 By("Creating patches for control plane") 98 Eventually(func(g Gomega) { 99 g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(infraControlPlane), infraControlPlane)).To(Succeed()) 100 infraControlPlane.Spec.ASOManagedClusterPatches = []string{ 101 `{"metadata": {"annotations": {"capzpatchtest": "value"}}}`, 102 } 103 g.Expect(mgmtClient.Update(ctx, infraControlPlane)).To(Succeed()) 104 }, inputGetter().WaitForUpdate...).Should(Succeed()) 105 Eventually(checkAnnotations(managedCluster, CheckInput{exist: map[string]string{"capzpatchtest": "value"}}), input.WaitForUpdate...).Should(Succeed()) 106 107 By("Updating patches for control plane") 108 Eventually(func(g Gomega) { 109 g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(infraControlPlane), infraControlPlane)).To(Succeed()) 110 infraControlPlane.Spec.ASOManagedClusterPatches = append(infraControlPlane.Spec.ASOManagedClusterPatches, `{"metadata": {"annotations": {"capzpatchtest": null}}}`) 111 g.Expect(mgmtClient.Update(ctx, infraControlPlane)).To(Succeed()) 112 }, inputGetter().WaitForUpdate...).Should(Succeed()) 113 Eventually(checkAnnotations(managedCluster, CheckInput{doNotExist: []string{"capzpatchtest"}}), input.WaitForUpdate...).Should(Succeed()) 114 115 By("Restoring initial patches for control plane") 116 Eventually(func(g Gomega) { 117 g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(infraControlPlane), infraControlPlane)).To(Succeed()) 118 infraControlPlane.Spec.ASOManagedClusterPatches = initialPatches 119 g.Expect(mgmtClient.Update(ctx, infraControlPlane)).To(Succeed()) 120 }, inputGetter().WaitForUpdate...).Should(Succeed()) 121 }() 122 123 for _, mp := range input.MachinePools { 124 wg.Add(1) 125 go func(mp *expv1.MachinePool) { 126 defer GinkgoRecover() 127 defer wg.Done() 128 129 ammp := &infrav1.AzureManagedMachinePool{} 130 Expect(mgmtClient.Get(ctx, types.NamespacedName{ 131 Namespace: mp.Spec.Template.Spec.InfrastructureRef.Namespace, 132 Name: mp.Spec.Template.Spec.InfrastructureRef.Name, 133 }, ammp)).To(Succeed()) 134 135 agentPool := &asocontainerservicev1.ManagedClustersAgentPool{ 136 ObjectMeta: metav1.ObjectMeta{ 137 Namespace: ammp.Namespace, 138 Name: ammp.Name, 139 }, 140 } 141 142 var initialPatches []string 143 Byf("Deleting all patches for machine pool %s", mp.Name) 144 Eventually(func(g Gomega) { 145 g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(ammp), ammp)).To(Succeed()) 146 initialPatches = ammp.Spec.ASOManagedClustersAgentPoolPatches 147 ammp.Spec.ASOManagedClustersAgentPoolPatches = nil 148 g.Expect(mgmtClient.Update(ctx, ammp)).To(Succeed()) 149 }, inputGetter().WaitForUpdate...).Should(Succeed()) 150 151 Byf("Creating patches for machine pool %s", mp.Name) 152 Eventually(func(g Gomega) { 153 g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(ammp), ammp)).To(Succeed()) 154 ammp.Spec.ASOManagedClustersAgentPoolPatches = []string{ 155 `{"metadata": {"annotations": {"capzpatchtest": "value"}}}`, 156 } 157 g.Expect(mgmtClient.Update(ctx, ammp)).To(Succeed()) 158 }, inputGetter().WaitForUpdate...).Should(Succeed()) 159 Eventually(checkAnnotations(agentPool, CheckInput{exist: map[string]string{"capzpatchtest": "value"}}), input.WaitForUpdate...).Should(Succeed()) 160 161 Byf("Updating patches for machine pool %s", mp.Name) 162 Eventually(func(g Gomega) { 163 g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(ammp), ammp)).To(Succeed()) 164 ammp.Spec.ASOManagedClustersAgentPoolPatches = append(ammp.Spec.ASOManagedClustersAgentPoolPatches, `{"metadata": {"annotations": {"capzpatchtest": null}}}`) 165 g.Expect(mgmtClient.Update(ctx, ammp)).To(Succeed()) 166 }, inputGetter().WaitForUpdate...).Should(Succeed()) 167 Eventually(checkAnnotations(agentPool, CheckInput{doNotExist: []string{"capzpatchtest"}}), input.WaitForUpdate...).Should(Succeed()) 168 169 Byf("Restoring initial patches for machine pool %s", mp.Name) 170 Eventually(func(g Gomega) { 171 g.Expect(mgmtClient.Get(ctx, client.ObjectKeyFromObject(ammp), ammp)).To(Succeed()) 172 ammp.Spec.ASOManagedClustersAgentPoolPatches = initialPatches 173 g.Expect(mgmtClient.Update(ctx, ammp)).To(Succeed()) 174 }, inputGetter().WaitForUpdate...).Should(Succeed()) 175 }(mp) 176 } 177 178 wg.Wait() 179 }