@@ -33,7 +33,9 @@ import (
33
33
"github.com/pkg/errors"
34
34
corev1 "k8s.io/api/core/v1"
35
35
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
36
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
36
37
"k8s.io/apimachinery/pkg/runtime"
38
+ "k8s.io/apimachinery/pkg/runtime/schema"
37
39
apimachinerytypes "k8s.io/apimachinery/pkg/types"
38
40
"k8s.io/client-go/tools/record"
39
41
utilfeature "k8s.io/component-base/featuregate/testing"
@@ -145,6 +147,14 @@ func TestAWSMachinePoolReconciler(t *testing.T) {
145
147
scope.MachinePoolScopeParams {
146
148
Client : testEnv .Client ,
147
149
Cluster : & clusterv1.Cluster {
150
+ Spec : clusterv1.ClusterSpec {
151
+ ControlPlaneRef : & corev1.ObjectReference {
152
+ Name : "test" ,
153
+ Kind : "KubeadmControlPlane" ,
154
+ APIVersion : "controlplane.cluster.x-k8s.io/v1beta1" ,
155
+ Namespace : "default" ,
156
+ },
157
+ },
148
158
Status : clusterv1.ClusterStatus {
149
159
InfrastructureReady : true ,
150
160
},
@@ -167,6 +177,8 @@ func TestAWSMachinePoolReconciler(t *testing.T) {
167
177
Bootstrap : clusterv1.Bootstrap {
168
178
DataSecretName : ptr.To [string ]("bootstrap-data" ),
169
179
},
180
+ // This version should be older or equal to the version used for the control plane, or workers won't be upgraded
181
+ Version : ptr.To [string ]("1.30.0" ),
170
182
},
171
183
},
172
184
},
@@ -879,6 +891,65 @@ func TestAWSMachinePoolReconciler(t *testing.T) {
879
891
g .Expect (err ).To (Succeed ())
880
892
})
881
893
894
+ t .Run ("launch template and ASG exist, but control plane k8s version is older than machinepool k8s version, should not update ASG" , func (t * testing.T ) {
895
+ g := NewWithT (t )
896
+ setup (t , g )
897
+ reconciler .reconcileServiceFactory = nil // use real implementation, but keep EC2 calls mocked (`ec2ServiceFactory`)
898
+ reconSvc = nil // not used
899
+ defer teardown (t , g )
900
+
901
+ // Latest ID and version already stored, no need to retrieve it
902
+ ms .AWSMachinePool .Status .LaunchTemplateID = launchTemplateIDExisting
903
+ ms .AWSMachinePool .Status .LaunchTemplateVersion = ptr.To [string ]("1" )
904
+ // Set the MachinePool k8s version to a version that is newer than the control plane k8s version
905
+ ms .MachinePool .Spec .Template .Spec .Version = ptr.To [string ]("99.99.99" )
906
+
907
+ ec2Svc .EXPECT ().GetLaunchTemplate (gomock .Eq ("test" )).Return (
908
+ & expinfrav1.AWSLaunchTemplate {
909
+ Name : "test" ,
910
+ AMI : infrav1.AMIReference {
911
+ ID : ptr.To [string ]("ami-existing" ),
912
+ },
913
+ },
914
+ // No change to user data
915
+ userdata .ComputeHash ([]byte ("shell-script" )),
916
+ // But the name of the secret changes from `previous-secret-name` to `bootstrap-data`
917
+ & apimachinerytypes.NamespacedName {Namespace : "default" , Name : "previous-secret-name" },
918
+ nil ,
919
+ nil )
920
+ ec2Svc .EXPECT ().DiscoverLaunchTemplateAMI (gomock .Any ()).Return (ptr.To [string ]("ami-existing" ), nil )
921
+ // Mock changes to the launch template, ASG would be updated, but k8s version skew will prevent it
922
+ ec2Svc .EXPECT ().LaunchTemplateNeedsUpdate (gomock .Any (), gomock .Any (), gomock .Any ()).Return (true , nil )
923
+
924
+ // Control plane kubernetes version skew is checked before, so it won't be called
925
+ asgSvc .EXPECT ().CanStartASGInstanceRefresh (gomock .Any ()).Times (0 )
926
+ // Won't be called due to version skew
927
+ ec2Svc .EXPECT ().CreateLaunchTemplateVersion (gomock .Any (), gomock .Any (), gomock .Any (), gomock .Any (), gomock .Any (), gomock .Any ()).Times (0 )
928
+ // Won't be called due to version skew
929
+ asgSvc .EXPECT ().StartASGInstanceRefresh (gomock .Any ()).Times (0 )
930
+
931
+ asgSvc .EXPECT ().GetASGByName (gomock .Any ()).DoAndReturn (func (scope * scope.MachinePoolScope ) (* expinfrav1.AutoScalingGroup , error ) {
932
+ g .Expect (scope .Name ()).To (Equal ("test" ))
933
+
934
+ // Add differences to `AWSMachinePool.spec`, ASG would be updated, but k8s version skew will prevent it
935
+ return & expinfrav1.AutoScalingGroup {
936
+ Name : scope .Name (),
937
+ Subnets : []string {
938
+ "subnet-1" ,
939
+ },
940
+ MinSize : awsMachinePool .Spec .MinSize - 1 ,
941
+ MaxSize : awsMachinePool .Spec .MaxSize + 1 ,
942
+ MixedInstancesPolicy : awsMachinePool .Spec .MixedInstancesPolicy .DeepCopy (),
943
+ }, nil
944
+ })
945
+ // No upgrade
946
+ asgSvc .EXPECT ().UpdateASG (gomock .Any ()).Times (0 )
947
+
948
+ _ , err := reconciler .reconcileNormal (context .Background (), ms , cs , cs , cs )
949
+ // We expect an error because the workers use a k8s version newer than the control plane version
950
+ g .Expect (err ).To (HaveOccurred ())
951
+ })
952
+
882
953
t .Run ("launch template and ASG created from zero, then bootstrap config reference changes" , func (t * testing.T ) {
883
954
g := NewWithT (t )
884
955
setup (t , g )
@@ -1389,13 +1460,42 @@ func setupCluster(clusterName string) (*scope.ClusterScope, error) {
1389
1460
ObjectMeta : metav1.ObjectMeta {Name : "test" },
1390
1461
Spec : infrav1.AWSClusterSpec {},
1391
1462
}
1392
- client := fake .NewClientBuilder ().WithScheme (scheme ).WithObjects (awsCluster ).Build ()
1463
+ controlPlane := & unstructured.Unstructured {}
1464
+ controlPlane .Object = map [string ]interface {}{
1465
+ "metadata" : map [string ]interface {}{
1466
+ "name" : "test" ,
1467
+ "namespace" : "default" ,
1468
+ },
1469
+ "spec" : map [string ]interface {}{},
1470
+ "status" : map [string ]interface {}{
1471
+ "version" : "1.30.0" ,
1472
+ },
1473
+ }
1474
+ controlPlane .SetGroupVersionKind (schema.GroupVersionKind {
1475
+ Group : "controlplane.cluster.x-k8s.io" ,
1476
+ Kind : "KubeadmControlPlane" ,
1477
+ Version : "v1beta1" ,
1478
+ })
1479
+ fakeClient := fake .NewClientBuilder ().WithScheme (scheme ).WithObjects (awsCluster ).Build ()
1480
+ err := fakeClient .Create (context .Background (), controlPlane )
1481
+ if err != nil {
1482
+ return nil , err
1483
+ }
1484
+
1393
1485
return scope .NewClusterScope (scope.ClusterScopeParams {
1394
1486
Cluster : & clusterv1.Cluster {
1395
1487
ObjectMeta : metav1.ObjectMeta {Name : clusterName },
1488
+ Spec : clusterv1.ClusterSpec {
1489
+ ControlPlaneRef : & corev1.ObjectReference {
1490
+ Kind : "KubeadmControlPlane" ,
1491
+ Namespace : "default" ,
1492
+ Name : "test" ,
1493
+ APIVersion : "controlplane.cluster.x-k8s.io/v1beta1" ,
1494
+ },
1495
+ },
1396
1496
},
1397
1497
AWSCluster : awsCluster ,
1398
- Client : client ,
1498
+ Client : fakeClient ,
1399
1499
})
1400
1500
}
1401
1501
0 commit comments