Skip to content

Commit 5a6a864

Browse files
committed
make aks k8s version dynamic based on supported versions
1 parent 76537af commit 5a6a864

File tree

6 files changed

+133
-29
lines changed

6 files changed

+133
-29
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ require (
3232
go.opentelemetry.io/otel/sdk v0.20.1-0.20210504183141-c99d5e999c69
3333
go.opentelemetry.io/otel/trace v0.20.0
3434
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
35+
golang.org/x/mod v0.4.2
3536
k8s.io/api v0.21.1
3637
k8s.io/apimachinery v0.21.1
3738
k8s.io/client-go v0.21.1

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
780780
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
781781
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
782782
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
783+
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
784+
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
783785
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
784786
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
785787
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

test/e2e/aks.go

Lines changed: 102 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@ package e2e
2020

2121
import (
2222
"context"
23-
24-
"github.com/onsi/ginkgo"
25-
"github.com/onsi/gomega"
23+
"errors"
24+
"fmt"
25+
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-06-30/compute"
26+
"github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2020-02-01/containerservice"
27+
"github.com/Azure/go-autorest/autorest/azure/auth"
28+
. "github.com/onsi/ginkgo"
29+
. "github.com/onsi/gomega"
30+
"golang.org/x/mod/semver"
31+
corev1 "k8s.io/api/core/v1"
2632
"k8s.io/apimachinery/pkg/types"
2733
infraexpv1 "sigs.k8s.io/cluster-api-provider-azure/exp/api/v1alpha4"
2834
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha4"
@@ -64,16 +70,16 @@ type DiscoverAndWaitForControlPlaneMachinesInput struct {
6470
// DiscoverAndWaitForControlPlaneInitialized gets the azure managed control plane associated with the cluster,
6571
// and waits for atleast one control plane machine to be up.
6672
func DiscoverAndWaitForControlPlaneInitialized(ctx context.Context, input DiscoverAndWaitForControlPlaneMachinesInput, intervals ...interface{}) {
67-
gomega.Expect(ctx).NotTo(gomega.BeNil(), "ctx is required for DiscoverAndWaitForControlPlaneInitialized")
68-
gomega.Expect(input.Lister).ToNot(gomega.BeNil(), "Invalid argument. input.Lister can't be nil when calling DiscoverAndWaitForControlPlaneInitialized")
69-
gomega.Expect(input.Cluster).ToNot(gomega.BeNil(), "Invalid argument. input.Cluster can't be nil when calling DiscoverAndWaitForControlPlaneInitialized")
73+
Expect(ctx).NotTo(BeNil(), "ctx is required for DiscoverAndWaitForControlPlaneInitialized")
74+
Expect(input.Lister).ToNot(BeNil(), "Invalid argument. input.Lister can't be nil when calling DiscoverAndWaitForControlPlaneInitialized")
75+
Expect(input.Cluster).ToNot(BeNil(), "Invalid argument. input.Cluster can't be nil when calling DiscoverAndWaitForControlPlaneInitialized")
7076

7177
controlPlane := GetAzureManagedControlPlaneByCluster(ctx, GetAzureManagedControlPlaneByClusterInput{
7278
Lister: input.Lister,
7379
ClusterName: input.Cluster.Name,
7480
Namespace: input.Cluster.Namespace,
7581
})
76-
gomega.Expect(controlPlane).ToNot(gomega.BeNil())
82+
Expect(controlPlane).ToNot(BeNil())
7783

7884
Logf("Waiting for the first control plane machine managed by %s/%s to be provisioned", controlPlane.Namespace, controlPlane.Name)
7985
WaitForAtLeastOneControlPlaneAndMachineToExist(ctx, WaitForControlPlaneAndMachinesReadyInput{
@@ -87,16 +93,16 @@ func DiscoverAndWaitForControlPlaneInitialized(ctx context.Context, input Discov
8793
// DiscoverAndWaitForControlPlaneReady gets the azure managed control plane associated with the cluster,
8894
// and waits for all the control plane machines to be up.
8995
func DiscoverAndWaitForControlPlaneReady(ctx context.Context, input DiscoverAndWaitForControlPlaneMachinesInput, intervals ...interface{}) {
90-
gomega.Expect(ctx).NotTo(gomega.BeNil(), "ctx is required for DiscoverAndWaitForControlPlaneReady")
91-
gomega.Expect(input.Lister).ToNot(gomega.BeNil(), "Invalid argument. input.Lister can't be nil when calling DiscoverAndWaitForControlPlaneReady")
92-
gomega.Expect(input.Cluster).ToNot(gomega.BeNil(), "Invalid argument. input.Cluster can't be nil when calling DiscoverAndWaitForControlPlaneReady")
96+
Expect(ctx).NotTo(BeNil(), "ctx is required for DiscoverAndWaitForControlPlaneReady")
97+
Expect(input.Lister).ToNot(BeNil(), "Invalid argument. input.Lister can't be nil when calling DiscoverAndWaitForControlPlaneReady")
98+
Expect(input.Cluster).ToNot(BeNil(), "Invalid argument. input.Cluster can't be nil when calling DiscoverAndWaitForControlPlaneReady")
9399

94100
controlPlane := GetAzureManagedControlPlaneByCluster(ctx, GetAzureManagedControlPlaneByClusterInput{
95101
Lister: input.Lister,
96102
ClusterName: input.Cluster.Name,
97103
Namespace: input.Cluster.Namespace,
98104
})
99-
gomega.Expect(controlPlane).ToNot(gomega.BeNil())
105+
Expect(controlPlane).ToNot(BeNil())
100106

101107
Logf("Waiting for the first control plane machine managed by %s/%s to be provisioned", controlPlane.Namespace, controlPlane.Name)
102108
WaitForAllControlPlaneAndMachinesToExist(ctx, WaitForControlPlaneAndMachinesReadyInput{
@@ -119,8 +125,8 @@ type GetAzureManagedControlPlaneByClusterInput struct {
119125
// it is necessary to ensure this is already happened before calling it.
120126
func GetAzureManagedControlPlaneByCluster(ctx context.Context, input GetAzureManagedControlPlaneByClusterInput) *infraexpv1.AzureManagedControlPlane {
121127
controlPlaneList := &infraexpv1.AzureManagedControlPlaneList{}
122-
gomega.Expect(input.Lister.List(ctx, controlPlaneList, byClusterOptions(input.ClusterName, input.Namespace)...)).To(gomega.Succeed(), "Failed to list AzureManagedControlPlane object for Cluster %s/%s", input.Namespace, input.ClusterName)
123-
gomega.Expect(len(controlPlaneList.Items)).ToNot(gomega.BeNumerically(">", 1), "Cluster %s/%s should not have more than 1 AzureManagedControlPlane object", input.Namespace, input.ClusterName)
128+
Expect(input.Lister.List(ctx, controlPlaneList, byClusterOptions(input.ClusterName, input.Namespace)...)).To(Succeed(), "Failed to list AzureManagedControlPlane object for Cluster %s/%s", input.Namespace, input.ClusterName)
129+
Expect(len(controlPlaneList.Items)).ToNot(BeNumerically(">", 1), "Cluster %s/%s should not have more than 1 AzureManagedControlPlane object", input.Namespace, input.ClusterName)
124130
if len(controlPlaneList.Items) == 1 {
125131
return &controlPlaneList.Items[0]
126132
}
@@ -137,13 +143,13 @@ type WaitForControlPlaneAndMachinesReadyInput struct {
137143

138144
// WaitForAtLeastOneControlPlaneAndMachineToExist waits for atleast one control plane machine to be provisioned.
139145
func WaitForAtLeastOneControlPlaneAndMachineToExist(ctx context.Context, input WaitForControlPlaneAndMachinesReadyInput, intervals ...interface{}) {
140-
ginkgo.By("Waiting for atleast one control plane node to exist")
146+
By("Waiting for atleast one control plane node to exist")
141147
WaitForControlPlaneMachinesToExist(ctx, input, atLeastOne, intervals...)
142148
}
143149

144150
// WaitForAllControlPlaneAndMachinesToExist waits for all control plane machines to be provisioned.
145151
func WaitForAllControlPlaneAndMachinesToExist(ctx context.Context, input WaitForControlPlaneAndMachinesReadyInput, intervals ...interface{}) {
146-
ginkgo.By("Waiting for all control plane nodes to exist")
152+
By("Waiting for all control plane nodes to exist")
147153
WaitForControlPlaneMachinesToExist(ctx, input, all, intervals...)
148154
}
149155

@@ -168,7 +174,7 @@ func (r controlPlaneReplicas) value(mp *clusterv1exp.MachinePool) int {
168174

169175
// WaitForControlPlaneMachinesToExist waits for a certain number of control plane machines to be provisioned represented.
170176
func WaitForControlPlaneMachinesToExist(ctx context.Context, input WaitForControlPlaneAndMachinesReadyInput, minReplicas controlPlaneReplicas, intervals ...interface{}) {
171-
gomega.Eventually(func() (bool, error) {
177+
Eventually(func() (bool, error) {
172178
controlPlaneMachinePool := &clusterv1exp.MachinePool{}
173179
if err := input.Getter.Get(ctx, types.NamespacedName{Namespace: input.Namespace, Name: input.ControlPlane.Spec.DefaultPoolRef.Name},
174180
controlPlaneMachinePool); err != nil {
@@ -177,7 +183,50 @@ func WaitForControlPlaneMachinesToExist(ctx context.Context, input WaitForContro
177183
}
178184
return len(controlPlaneMachinePool.Status.NodeRefs) >= minReplicas.value(controlPlaneMachinePool), nil
179185

180-
}, intervals...).Should(gomega.Equal(true))
186+
}, intervals...).Should(Equal(true))
187+
}
188+
189+
// GetAKSKubernetesVersion gets the kubernetes version for AKS clusters.
190+
func GetAKSKubernetesVersion(ctx context.Context, e2eConfig *clusterctl.E2EConfig) (string, error) {
191+
e2eAKSVersion := e2eConfig.GetVariable(AKSKubernetesVersion)
192+
193+
location := e2eConfig.GetVariable(AzureLocation)
194+
195+
settings, err := auth.GetSettingsFromEnvironment()
196+
Expect(err).NotTo(HaveOccurred())
197+
subscriptionID := settings.GetSubscriptionID()
198+
authorizer, err := settings.GetAuthorizer()
199+
Expect(err).NotTo(HaveOccurred())
200+
containerServiceClient := containerservice.NewContainerServicesClient(subscriptionID)
201+
containerServiceClient.Authorizer = authorizer
202+
203+
result, err := containerServiceClient.ListOrchestrators(ctx, location, ManagedClustersResourceType)
204+
if err != nil {
205+
return "", err
206+
}
207+
208+
// For 1.19 release this will be 1.19.0
209+
baseVersion := fmt.Sprintf("%s.0", semver.MajorMinor(e2eAKSVersion))
210+
maxVersion := fmt.Sprintf("%s.0", semver.MajorMinor(e2eAKSVersion))
211+
for _, o := range *result.Orchestrators {
212+
orchVersion := fmt.Sprintf("v%s", *o.OrchestratorVersion)
213+
// test k8s version matches with one of the supported aks versions.
214+
if orchVersion == e2eAKSVersion {
215+
return e2eAKSVersion, nil
216+
}
217+
218+
// find the highest aks version for a given major.minor
219+
if semver.MajorMinor(orchVersion) == semver.MajorMinor(maxVersion) && semver.Compare(orchVersion, maxVersion) > 0 {
220+
maxVersion = orchVersion
221+
}
222+
}
223+
224+
// This means there is no version supported by AKS for this major.minor
225+
if semver.Compare(maxVersion, baseVersion) == 0 {
226+
return "", errors.New(fmt.Sprintf("No AKS versions found for %s", semver.MajorMinor(baseVersion)))
227+
}
228+
229+
return maxVersion, nil
181230
}
182231

183232
// byClusterOptions returns a set of ListOptions that allows to identify all the objects belonging to a Cluster.
@@ -189,3 +238,39 @@ func byClusterOptions(name, namespace string) []client.ListOption {
189238
},
190239
}
191240
}
241+
242+
// AKSResourcesValidationSpecInput is the input for AKSResourcesValidationSpec
243+
type AKSResourcesValidationSpecInput struct {
244+
BootstrapClusterProxy framework.ClusterProxy
245+
Namespace *corev1.Namespace
246+
ClusterName string
247+
}
248+
249+
// AKSResourcesValidationSpec implements a test that verifies the resources created by an AKS cluster.
250+
func AKSResourcesValidationSpec(ctx context.Context, inputGetter func() AKSResourcesValidationSpecInput) {
251+
var (
252+
specName = "aks-resources-validation"
253+
input AKSResourcesValidationSpecInput
254+
)
255+
256+
input = inputGetter()
257+
Expect(input.ClusterName).NotTo(BeEmpty(), "Invalid argument. input.ClusterName can't be empty when calling %s spec", specName)
258+
259+
By("creating Azure clients with the workload cluster's subscription, and querying for vmss")
260+
var controlPlane = &infraexpv1.AzureManagedControlPlane{}
261+
Expect(input.BootstrapClusterProxy.GetClient().Get(ctx,
262+
types.NamespacedName{input.Namespace.Name, input.ClusterName}, controlPlane)).To(Succeed())
263+
264+
settings, err := auth.GetSettingsFromEnvironment()
265+
Expect(err).NotTo(HaveOccurred())
266+
subscriptionID := settings.GetSubscriptionID()
267+
authorizer, err := settings.GetAuthorizer()
268+
Expect(err).NotTo(HaveOccurred())
269+
vmssClient := compute.NewVirtualMachineScaleSetsClient(subscriptionID)
270+
vmssClient.Authorizer = authorizer
271+
272+
rgName := controlPlane.Spec.NodeResourceGroupName
273+
scalesets, err := vmssClient.List(ctx, rgName)
274+
Expect(err).NotTo(HaveOccurred())
275+
Expect(len(scalesets.Values())).To(BeNumerically(">", 0))
276+
}

test/e2e/azure_test.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,9 @@ var _ = Describe("Workload cluster creation", func() {
478478
os.Setenv("AZURE_CLUSTER_IDENTITY_SECRET_NAME", "sp-identity-secret")
479479
os.Setenv("AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE", namespace.Name)
480480

481+
kubernetesVersion, err := GetAKSKubernetesVersion(ctx, e2eConfig)
482+
Expect(err).To(BeNil())
483+
481484
clusterctl.ApplyClusterTemplateAndWait(ctx, clusterctl.ApplyClusterTemplateAndWaitInput{
482485
ClusterProxy: bootstrapClusterProxy,
483486
ConfigCluster: clusterctl.ConfigClusterInput{
@@ -488,7 +491,7 @@ var _ = Describe("Workload cluster creation", func() {
488491
Flavor: "aks-multi-tenancy",
489492
Namespace: namespace.Name,
490493
ClusterName: clusterName,
491-
KubernetesVersion: e2eConfig.GetVariable(capi_e2e.KubernetesVersion),
494+
KubernetesVersion: kubernetesVersion,
492495
ControlPlaneMachineCount: pointer.Int64Ptr(1),
493496
WorkerMachineCount: pointer.Int64Ptr(1),
494497
},
@@ -500,6 +503,16 @@ var _ = Describe("Workload cluster creation", func() {
500503
WaitForControlPlaneMachinesReady: WaitForControlPlaneMachinesReady,
501504
},
502505
}, result)
506+
507+
Context("Validating AKS Resources", func() {
508+
AKSResourcesValidationSpec(ctx, func() AKSResourcesValidationSpecInput {
509+
return AKSResourcesValidationSpecInput{
510+
BootstrapClusterProxy: bootstrapClusterProxy,
511+
Namespace: namespace,
512+
ClusterName: clusterName,
513+
}
514+
})
515+
})
503516
})
504517
})
505518

test/e2e/common.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,18 @@ import (
4343

4444
// Test suite constants for e2e config variables
4545
const (
46-
RedactLogScriptPath = "REDACT_LOG_SCRIPT"
47-
AzureLocation = "AZURE_LOCATION"
48-
AzureResourceGroup = "AZURE_RESOURCE_GROUP"
49-
AzureVNetName = "AZURE_VNET_NAME"
50-
AzureInternalLBIP = "AZURE_INTERNAL_LB_IP"
51-
AzureCPSubnetCidr = "AZURE_CP_SUBNET_CIDR"
52-
AzureNodeSubnetCidr = "AZURE_NODE_SUBNET_CIDR"
53-
MultiTenancyIdentityName = "MULTI_TENANCY_IDENTITY_NAME"
54-
JobName = "JOB_NAME"
55-
Timestamp = "TIMESTAMP"
46+
RedactLogScriptPath = "REDACT_LOG_SCRIPT"
47+
AzureLocation = "AZURE_LOCATION"
48+
AzureResourceGroup = "AZURE_RESOURCE_GROUP"
49+
AzureVNetName = "AZURE_VNET_NAME"
50+
AzureInternalLBIP = "AZURE_INTERNAL_LB_IP"
51+
AzureCPSubnetCidr = "AZURE_CP_SUBNET_CIDR"
52+
AzureNodeSubnetCidr = "AZURE_NODE_SUBNET_CIDR"
53+
MultiTenancyIdentityName = "MULTI_TENANCY_IDENTITY_NAME"
54+
JobName = "JOB_NAME"
55+
Timestamp = "TIMESTAMP"
56+
AKSKubernetesVersion = "AKS_KUBERNETES_VERSION"
57+
ManagedClustersResourceType = "managedClusters"
5658
)
5759

5860
func Byf(format string, a ...interface{}) {

test/e2e/config/azure-dev.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ providers:
9090
targetName: "cluster-template-aks-multi-tenancy.yaml"
9191

9292
variables:
93-
KUBERNETES_VERSION: "${KUBERNETES_VERSION:-v1.19.9}"
93+
KUBERNETES_VERSION: "${KUBERNETES_VERSION:-v1.19.7}"
94+
AKS_KUBERNETES_VERSION: "${KUBERNETES_VERSION:-v1.19.9}"
9495
ETCD_VERSION_UPGRADE_TO: "3.4.3-0"
9596
COREDNS_VERSION_UPGRADE_TO: "1.6.7"
9697
KUBERNETES_VERSION_UPGRADE_TO: "${KUBERNETES_VERSION_UPGRADE_TO:-v1.19.11}"

0 commit comments

Comments
 (0)