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

     1  //go:build e2e
     2  // +build e2e
     3  
     4  /*
     5  Copyright 2020 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  	"os"
    26  	"time"
    27  
    28  	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    29  	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi"
    30  	. "github.com/onsi/ginkgo/v2"
    31  	. "github.com/onsi/gomega"
    32  	"k8s.io/utils/ptr"
    33  	capi_e2e "sigs.k8s.io/cluster-api/test/e2e"
    34  	"sigs.k8s.io/cluster-api/test/framework"
    35  	"sigs.k8s.io/cluster-api/test/framework/clusterctl"
    36  	"sigs.k8s.io/cluster-api/util"
    37  )
    38  
    39  const (
    40  	IdentitySecretName = "cluster-identity-secret"
    41  )
    42  
    43  var _ = Describe("Running the Cluster API E2E tests", func() {
    44  	var (
    45  		ctx       = context.TODO()
    46  		specTimes = map[string]time.Time{}
    47  	)
    48  	BeforeEach(func() {
    49  		Expect(e2eConfig.Variables).To(HaveKey(capi_e2e.CNIPath))
    50  		rgName := fmt.Sprintf("capz-e2e-%s", util.RandomString(6))
    51  		Expect(os.Setenv(AzureResourceGroup, rgName)).To(Succeed())
    52  		Expect(os.Setenv(AzureVNetName, fmt.Sprintf("%s-vnet", rgName))).To(Succeed())
    53  
    54  		Expect(e2eConfig.Variables).To(HaveKey(capi_e2e.KubernetesVersionUpgradeFrom))
    55  		Expect(os.Setenv("WINDOWS_WORKER_MACHINE_COUNT", "2")).To(Succeed())
    56  
    57  		identityName := e2eConfig.GetVariable(ClusterIdentityName)
    58  		Expect(os.Setenv(ClusterIdentityName, identityName)).To(Succeed())
    59  
    60  		logCheckpoint(specTimes)
    61  	})
    62  
    63  	AfterEach(func() {
    64  		CheckTestBeforeCleanup()
    65  		redactLogs()
    66  
    67  		Expect(os.Unsetenv(AzureResourceGroup)).To(Succeed())
    68  		Expect(os.Unsetenv(AzureVNetName)).To(Succeed())
    69  		Expect(os.Unsetenv(ClusterIdentityName)).To(Succeed())
    70  
    71  		logCheckpoint(specTimes)
    72  	})
    73  
    74  	Context("Running the quick-start spec", func() {
    75  		capi_e2e.QuickStartSpec(context.TODO(), func() capi_e2e.QuickStartSpecInput {
    76  			return capi_e2e.QuickStartSpecInput{
    77  				E2EConfig:             e2eConfig,
    78  				ClusterctlConfigPath:  clusterctlConfigPath,
    79  				BootstrapClusterProxy: bootstrapClusterProxy,
    80  				ArtifactFolder:        artifactFolder,
    81  				SkipCleanup:           skipCleanup,
    82  				ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
    83  					WaitForControlPlaneInitialized: EnsureControlPlaneInitializedNoAddons,
    84  				},
    85  			}
    86  		})
    87  	})
    88  
    89  	Context("Running the MachineDeployment rollout spec", func() {
    90  		capi_e2e.MachineDeploymentRolloutSpec(context.TODO(), func() capi_e2e.MachineDeploymentRolloutSpecInput {
    91  			return capi_e2e.MachineDeploymentRolloutSpecInput{
    92  				E2EConfig:             e2eConfig,
    93  				ClusterctlConfigPath:  clusterctlConfigPath,
    94  				BootstrapClusterProxy: bootstrapClusterProxy,
    95  				ArtifactFolder:        artifactFolder,
    96  				SkipCleanup:           skipCleanup,
    97  				ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
    98  					WaitForControlPlaneInitialized: EnsureControlPlaneInitializedNoAddons,
    99  				},
   100  			}
   101  		})
   102  	})
   103  
   104  	if os.Getenv("USE_LOCAL_KIND_REGISTRY") != "true" {
   105  		Context("Running the self-hosted spec", func() {
   106  			SelfHostedSpec(context.TODO(), func() SelfHostedSpecInput {
   107  				return SelfHostedSpecInput{
   108  					E2EConfig:             e2eConfig,
   109  					ClusterctlConfigPath:  clusterctlConfigPath,
   110  					BootstrapClusterProxy: bootstrapClusterProxy,
   111  					ArtifactFolder:        artifactFolder,
   112  					SkipCleanup:           skipCleanup,
   113  					ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
   114  						WaitForControlPlaneInitialized: EnsureControlPlaneInitializedNoAddons,
   115  					},
   116  				}
   117  			})
   118  		})
   119  	}
   120  
   121  	// TODO: Add test using KCPRemediationSpec
   122  	Context("Should successfully remediate unhealthy worker machines with MachineHealthCheck", func() {
   123  		capi_e2e.MachineDeploymentRemediationSpec(context.TODO(), func() capi_e2e.MachineDeploymentRemediationSpecInput {
   124  			return capi_e2e.MachineDeploymentRemediationSpecInput{
   125  				E2EConfig:             e2eConfig,
   126  				ClusterctlConfigPath:  clusterctlConfigPath,
   127  				BootstrapClusterProxy: bootstrapClusterProxy,
   128  				ArtifactFolder:        artifactFolder,
   129  				SkipCleanup:           skipCleanup,
   130  				ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
   131  					WaitForControlPlaneInitialized: EnsureControlPlaneInitializedNoAddons,
   132  				},
   133  			}
   134  		})
   135  	})
   136  
   137  	Context("Should successfully exercise machine pools", func() {
   138  		capi_e2e.MachinePoolSpec(context.TODO(), func() capi_e2e.MachinePoolInput {
   139  			return capi_e2e.MachinePoolInput{
   140  				E2EConfig:             e2eConfig,
   141  				ClusterctlConfigPath:  clusterctlConfigPath,
   142  				BootstrapClusterProxy: bootstrapClusterProxy,
   143  				ArtifactFolder:        artifactFolder,
   144  				SkipCleanup:           skipCleanup,
   145  				ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
   146  					WaitForControlPlaneInitialized: EnsureControlPlaneInitializedNoAddons,
   147  				},
   148  			}
   149  		})
   150  	})
   151  
   152  	Context("Should successfully scale out and scale in a MachineDeployment", func() {
   153  		capi_e2e.MachineDeploymentScaleSpec(context.TODO(), func() capi_e2e.MachineDeploymentScaleSpecInput {
   154  			return capi_e2e.MachineDeploymentScaleSpecInput{
   155  				E2EConfig:             e2eConfig,
   156  				ClusterctlConfigPath:  clusterctlConfigPath,
   157  				BootstrapClusterProxy: bootstrapClusterProxy,
   158  				ArtifactFolder:        artifactFolder,
   159  				SkipCleanup:           skipCleanup,
   160  				ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
   161  					WaitForControlPlaneInitialized: EnsureControlPlaneInitializedNoAddons,
   162  				},
   163  			}
   164  		})
   165  	})
   166  
   167  	Context("Should successfully set and use node drain timeout", func() {
   168  		capi_e2e.NodeDrainTimeoutSpec(context.TODO(), func() capi_e2e.NodeDrainTimeoutSpecInput {
   169  			return capi_e2e.NodeDrainTimeoutSpecInput{
   170  				E2EConfig:             e2eConfig,
   171  				ClusterctlConfigPath:  clusterctlConfigPath,
   172  				BootstrapClusterProxy: bootstrapClusterProxy,
   173  				ArtifactFolder:        artifactFolder,
   174  				SkipCleanup:           skipCleanup,
   175  				ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
   176  					WaitForControlPlaneInitialized: EnsureControlPlaneInitializedNoAddons,
   177  				},
   178  			}
   179  		})
   180  	})
   181  
   182  	if os.Getenv("USE_LOCAL_KIND_REGISTRY") != "true" {
   183  		Context("API Version Upgrade", func() {
   184  			BeforeEach(func() {
   185  				// Unset resource group and vnet env variables, since the upgrade test creates 2 clusters,
   186  				// and will result in both the clusters using the same vnet and resource group.
   187  				Expect(os.Unsetenv(AzureResourceGroup)).To(Succeed())
   188  				Expect(os.Unsetenv(AzureVNetName)).To(Succeed())
   189  
   190  				// Unset windows specific variables
   191  				Expect(os.Unsetenv("WINDOWS_WORKER_MACHINE_COUNT")).To(Succeed())
   192  
   193  				cred, err := azidentity.NewDefaultAzureCredential(nil)
   194  				Expect(err).NotTo(HaveOccurred())
   195  				identityClient, err := armmsi.NewUserAssignedIdentitiesClient(getSubscriptionID(Default), cred, nil)
   196  				Expect(err).NotTo(HaveOccurred())
   197  				identityRG := e2eConfig.GetVariable(AzureIdentityResourceGroup)
   198  				identityName := e2eConfig.GetVariable(AzureUserIdentity)
   199  				identity, err := identityClient.Get(ctx, identityRG, identityName, nil)
   200  				Expect(err).NotTo(HaveOccurred())
   201  				os.Setenv("AZURE_CLIENT_ID_CLOUD_PROVIDER", *identity.Properties.ClientID)
   202  			})
   203  
   204  			Context("upgrade from an old version of v1beta1 to current, and scale workload clusters created in the old version", func() {
   205  				capi_e2e.ClusterctlUpgradeSpec(ctx, func() capi_e2e.ClusterctlUpgradeSpecInput {
   206  					return capi_e2e.ClusterctlUpgradeSpecInput{
   207  						E2EConfig:                 e2eConfig,
   208  						ClusterctlConfigPath:      clusterctlConfigPath,
   209  						BootstrapClusterProxy:     bootstrapClusterProxy,
   210  						ArtifactFolder:            artifactFolder,
   211  						SkipCleanup:               skipCleanup,
   212  						PreInit:                   getPreInitFunc(ctx),
   213  						InitWithProvidersContract: "v1beta1",
   214  						ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
   215  							WaitForControlPlaneInitialized: EnsureControlPlaneInitialized,
   216  						},
   217  						InitWithKubernetesVersion:       e2eConfig.GetVariable(KubernetesVersionAPIUpgradeFrom),
   218  						InitWithBinary:                  fmt.Sprintf("https://github.com/kubernetes-sigs/cluster-api/releases/download/%s/clusterctl-{OS}-{ARCH}", e2eConfig.GetVariable(OldCAPIUpgradeVersion)),
   219  						InitWithCoreProvider:            "cluster-api:" + e2eConfig.GetVariable(OldCAPIUpgradeVersion),
   220  						InitWithBootstrapProviders:      []string{"kubeadm:" + e2eConfig.GetVariable(OldCAPIUpgradeVersion)},
   221  						InitWithControlPlaneProviders:   []string{"kubeadm:" + e2eConfig.GetVariable(OldCAPIUpgradeVersion)},
   222  						InitWithInfrastructureProviders: []string{"azure:" + e2eConfig.GetVariable(OldProviderUpgradeVersion)},
   223  						InitWithAddonProviders:          []string{"helm:" + e2eConfig.GetVariable(OldAddonProviderUpgradeVersion)},
   224  					}
   225  				})
   226  			})
   227  
   228  			Context("upgrade from the latest version of v1beta1 to current, and scale workload clusters created in the old version", func() {
   229  				capi_e2e.ClusterctlUpgradeSpec(ctx, func() capi_e2e.ClusterctlUpgradeSpecInput {
   230  					return capi_e2e.ClusterctlUpgradeSpecInput{
   231  						E2EConfig:                 e2eConfig,
   232  						ClusterctlConfigPath:      clusterctlConfigPath,
   233  						BootstrapClusterProxy:     bootstrapClusterProxy,
   234  						ArtifactFolder:            artifactFolder,
   235  						SkipCleanup:               skipCleanup,
   236  						PreInit:                   getPreInitFunc(ctx),
   237  						InitWithProvidersContract: "v1beta1",
   238  						ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
   239  							WaitForControlPlaneInitialized: EnsureControlPlaneInitialized,
   240  						},
   241  						InitWithKubernetesVersion:       e2eConfig.GetVariable(KubernetesVersionAPIUpgradeFrom),
   242  						InitWithBinary:                  fmt.Sprintf("https://github.com/kubernetes-sigs/cluster-api/releases/download/%s/clusterctl-{OS}-{ARCH}", e2eConfig.GetVariable(LatestCAPIUpgradeVersion)),
   243  						InitWithCoreProvider:            "cluster-api:" + e2eConfig.GetVariable(LatestCAPIUpgradeVersion),
   244  						InitWithBootstrapProviders:      []string{"kubeadm:" + e2eConfig.GetVariable(LatestCAPIUpgradeVersion)},
   245  						InitWithControlPlaneProviders:   []string{"kubeadm:" + e2eConfig.GetVariable(LatestCAPIUpgradeVersion)},
   246  						InitWithInfrastructureProviders: []string{"azure:" + e2eConfig.GetVariable(LatestProviderUpgradeVersion)},
   247  						InitWithAddonProviders:          []string{"helm:" + e2eConfig.GetVariable(LatestAddonProviderUpgradeVersion)},
   248  					}
   249  				})
   250  			})
   251  		})
   252  	}
   253  
   254  	Context("Running the workload cluster upgrade spec [K8s-Upgrade]", func() {
   255  		capi_e2e.ClusterUpgradeConformanceSpec(ctx, func() capi_e2e.ClusterUpgradeConformanceSpecInput {
   256  			return capi_e2e.ClusterUpgradeConformanceSpecInput{
   257  				E2EConfig:             e2eConfig,
   258  				ClusterctlConfigPath:  clusterctlConfigPath,
   259  				BootstrapClusterProxy: bootstrapClusterProxy,
   260  				ArtifactFolder:        artifactFolder,
   261  				SkipCleanup:           skipCleanup,
   262  				SkipConformanceTests:  true,
   263  				ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
   264  					WaitForControlPlaneInitialized: EnsureControlPlaneInitialized,
   265  				},
   266  			}
   267  		})
   268  	})
   269  
   270  	Context("Running KCP upgrade in a HA cluster [K8s-Upgrade]", func() {
   271  		capi_e2e.ClusterUpgradeConformanceSpec(context.TODO(), func() capi_e2e.ClusterUpgradeConformanceSpecInput {
   272  			return capi_e2e.ClusterUpgradeConformanceSpecInput{
   273  				E2EConfig:                e2eConfig,
   274  				ClusterctlConfigPath:     clusterctlConfigPath,
   275  				BootstrapClusterProxy:    bootstrapClusterProxy,
   276  				ArtifactFolder:           artifactFolder,
   277  				ControlPlaneMachineCount: ptr.To[int64](3),
   278  				WorkerMachineCount:       ptr.To[int64](0),
   279  				SkipCleanup:              skipCleanup,
   280  				SkipConformanceTests:     true,
   281  				ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
   282  					WaitForControlPlaneInitialized: EnsureControlPlaneInitialized,
   283  				},
   284  			}
   285  		})
   286  	})
   287  
   288  	Context("Running KCP upgrade in a HA cluster using scale in rollout [K8s-Upgrade]", func() {
   289  		capi_e2e.ClusterUpgradeConformanceSpec(context.TODO(), func() capi_e2e.ClusterUpgradeConformanceSpecInput {
   290  			return capi_e2e.ClusterUpgradeConformanceSpecInput{
   291  				E2EConfig:                e2eConfig,
   292  				ClusterctlConfigPath:     clusterctlConfigPath,
   293  				BootstrapClusterProxy:    bootstrapClusterProxy,
   294  				ArtifactFolder:           artifactFolder,
   295  				ControlPlaneMachineCount: ptr.To[int64](3),
   296  				WorkerMachineCount:       ptr.To[int64](0),
   297  				SkipCleanup:              skipCleanup,
   298  				SkipConformanceTests:     true,
   299  				Flavor:                   ptr.To("kcp-scale-in"),
   300  				ControlPlaneWaiters: clusterctl.ControlPlaneWaiters{
   301  					WaitForControlPlaneInitialized: EnsureControlPlaneInitialized,
   302  				},
   303  			}
   304  		})
   305  	})
   306  })
   307  
   308  func getPreInitFunc(ctx context.Context) func(proxy framework.ClusterProxy) {
   309  	return func(clusterProxy framework.ClusterProxy) {
   310  		identityName := e2eConfig.GetVariable(ClusterIdentityName)
   311  		Expect(os.Setenv(ClusterIdentityName, identityName)).To(Succeed())
   312  	}
   313  }