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  }