Skip to content

Commit

Permalink
Fix MachinePool upgrade e2e test
Browse files Browse the repository at this point in the history
  • Loading branch information
Cecile Robert-Michon committed May 20, 2021
1 parent 19c30e6 commit ce34730
Showing 1 changed file with 36 additions and 42 deletions.
78 changes: 36 additions & 42 deletions test/framework/machinepool_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"context"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/cluster-api/test/framework/internal/log"
"sigs.k8s.io/cluster-api/util/patch"

Expand Down Expand Up @@ -92,7 +91,7 @@ type DiscoveryAndWaitForMachinePoolsInput struct {
Cluster *clusterv1.Cluster
}

// DiscoveryAndWaitForMachinePools discovers the MachinePools existing in a cluster and waits for them to be ready (all the machine provisioned).
// DiscoveryAndWaitForMachinePools discovers the MachinePools existing in a cluster and waits for them to be ready (all the machines provisioned).
func DiscoveryAndWaitForMachinePools(ctx context.Context, input DiscoveryAndWaitForMachinePoolsInput, intervals ...interface{}) []*clusterv1exp.MachinePool {
Expect(ctx).NotTo(BeNil(), "ctx is required for DiscoveryAndWaitForMachinePools")
Expect(input.Lister).ToNot(BeNil(), "Invalid argument. input.Lister can't be nil when calling DiscoveryAndWaitForMachinePools")
Expand Down Expand Up @@ -131,25 +130,23 @@ func UpgradeMachinePoolAndWait(ctx context.Context, input UpgradeMachinePoolAndW
mgmtClient := input.ClusterProxy.GetClient()
for i := range input.MachinePools {
mp := input.MachinePools[i]
log.Logf("Patching the new kubernetes version to Machine Pool %s/%s", mp.Namespace, mp.Name)
log.Logf("Patching the new Kubernetes version to Machine Pool %s/%s", mp.Namespace, mp.Name)
patchHelper, err := patch.NewHelper(mp, mgmtClient)
Expect(err).ToNot(HaveOccurred())

oldVersion := mp.Spec.Template.Spec.Version
mp.Spec.Template.Spec.Version = &input.UpgradeVersion
Expect(patchHelper.Patch(ctx, mp)).To(Succeed())
}

for i := range input.MachinePools {
mp := input.MachinePools[i]
oldVersion := mp.Spec.Template.Spec.Version
log.Logf("Waiting for Kubernetes versions of machines in MachinePool %s/%s to be upgraded from %s to %s",
mp.Namespace, mp.Name, *oldVersion, input.UpgradeVersion)
WaitForMachinePoolInstancesToBeUpgraded(ctx, WaitForMachinePoolInstancesToBeUpgradedInput{
Getter: mgmtClient,
WorkloadClusterGetter: input.ClusterProxy.GetWorkloadCluster(ctx, input.Cluster.Namespace, input.Cluster.Name).GetClient(),
Cluster: input.Cluster,
MachineCount: int(*mp.Spec.Replicas),
KubernetesUpgradeVersion: input.UpgradeVersion,
MachinePool: *mp,
MachinePool: mp,
}, input.WaitForMachinePoolToBeUpgraded...)
}
}
Expand Down Expand Up @@ -190,10 +187,11 @@ func ScaleMachinePoolAndWait(ctx context.Context, input ScaleMachinePoolAndWaitI
// WaitForMachinePoolInstancesToBeUpgradedInput is the input for WaitForMachinePoolInstancesToBeUpgraded.
type WaitForMachinePoolInstancesToBeUpgradedInput struct {
Getter Getter
WorkloadClusterGetter Getter
Cluster *clusterv1.Cluster
KubernetesUpgradeVersion string
MachineCount int
MachinePool clusterv1exp.MachinePool
MachinePool *clusterv1exp.MachinePool
}

// WaitForMachinePoolInstancesToBeUpgraded waits until all instances belonging to a MachinePool are upgraded to the correct kubernetes version.
Expand All @@ -207,10 +205,17 @@ func WaitForMachinePoolInstancesToBeUpgraded(ctx context.Context, input WaitForM

log.Logf("Ensuring all MachinePool Instances have upgraded kubernetes version %s", input.KubernetesUpgradeVersion)
Eventually(func() (int, error) {
versions := GetMachinePoolInstanceVersions(ctx, GetMachinesPoolInstancesInput{
Getter: input.Getter,
Namespace: input.Cluster.Namespace,
MachinePool: input.MachinePool,
nn := client.ObjectKey{
Namespace: input.MachinePool.Namespace,
Name: input.MachinePool.Name,
}
if err := input.Getter.Get(ctx, nn, input.MachinePool); err != nil {
return 0, err
}
versions := getMachinePoolInstanceVersions(ctx, GetMachinesPoolInstancesInput{
WorkloadClusterGetter: input.WorkloadClusterGetter,
Namespace: input.Cluster.Namespace,
MachinePool: input.MachinePool,
})

matches := 0
Expand All @@ -230,41 +235,30 @@ func WaitForMachinePoolInstancesToBeUpgraded(ctx context.Context, input WaitForM

// GetMachinesPoolInstancesInput is the input for GetMachinesPoolInstances.
type GetMachinesPoolInstancesInput struct {
Getter Getter
Namespace string
MachinePool clusterv1exp.MachinePool
WorkloadClusterGetter Getter
Namespace string
MachinePool *clusterv1exp.MachinePool
}

// GetMachinePoolInstanceVersions returns the.
func GetMachinePoolInstanceVersions(ctx context.Context, input GetMachinesPoolInstancesInput) []string {
Expect(ctx).NotTo(BeNil(), "ctx is required for GetMachinePoolInstanceVersions")
Expect(input.Namespace).ToNot(BeEmpty(), "Invalid argument. input.Namespace can't be empty when calling GetMachinePoolInstanceVersions")
Expect(input.MachinePool).ToNot(BeNil(), "Invalid argument. input.MachineDeployment can't be nil when calling GetMachinePoolInstanceVersions")

obj := getUnstructuredRef(ctx, input.Getter, &input.MachinePool.Spec.Template.Spec.InfrastructureRef, input.Namespace)
instances, found, err := unstructured.NestedSlice(obj.Object, "status", "instances")
Expect(err).ToNot(HaveOccurred(), "failed to extract machines from unstructured")
if !found {
return nil
}
// getMachinePoolInstanceVersions returns the Kubernetes versions of the machine pool instances.
func getMachinePoolInstanceVersions(ctx context.Context, input GetMachinesPoolInstancesInput) []string {
Expect(ctx).NotTo(BeNil(), "ctx is required for getMachinePoolInstanceVersions")
Expect(input.WorkloadClusterGetter).ToNot(BeNil(), "Invalid argument. input.Getter can't be nil when calling getMachinePoolInstanceVersions")
Expect(input.Namespace).ToNot(BeEmpty(), "Invalid argument. input.Namespace can't be empty when calling getMachinePoolInstanceVersions")
Expect(input.MachinePool).ToNot(BeNil(), "Invalid argument. input.MachineDeployment can't be nil when calling getMachinePoolInstanceVersions")

instances := input.MachinePool.Status.NodeRefs
versions := make([]string, len(instances))
for i, instance := range instances {
version, found, err := unstructured.NestedString(instance.(map[string]interface{}), "version")
Expect(err).ToNot(HaveOccurred(), "failed to extract versions from unstructured instance")
Expect(found).To(BeTrue(), "unable to find nested version string in unstructured instance")
versions[i] = version
node := &corev1.Node{}
err := input.WorkloadClusterGetter.Get(ctx, client.ObjectKey{Name: instance.Name}, node)
if err != nil {
versions[i] = "unknown"
} else {
versions[i] = node.Status.NodeInfo.KubeletVersion
}
log.Logf("Node %s version is %s", instance.Name, versions[i])
}

return versions
}

func getUnstructuredRef(ctx context.Context, getter Getter, ref *corev1.ObjectReference, namespace string) *unstructured.Unstructured {
obj := new(unstructured.Unstructured)
obj.SetAPIVersion(ref.APIVersion)
obj.SetKind(ref.Kind)
obj.SetName(ref.Name)
key := client.ObjectKey{Name: obj.GetName(), Namespace: namespace}
Expect(getter.Get(ctx, key, obj)).ToNot(HaveOccurred(), "failed to retrieve %s object %q/%q", obj.GetKind(), key.Namespace, key.Name)
return obj
}

0 comments on commit ce34730

Please sign in to comment.