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 }