@@ -17,15 +17,17 @@ limitations under the License.
17
17
package aws
18
18
19
19
import (
20
+ "context"
20
21
"fmt"
21
22
"reflect"
22
23
"strings"
23
24
"sync"
24
25
"time"
25
26
26
- "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/aws/aws-sdk-go/aws"
27
- "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/aws/aws-sdk-go/service/autoscaling"
28
- "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/aws/aws-sdk-go/service/ec2"
27
+ "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/aws/aws-sdk-go-v2/aws"
28
+ "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/aws/aws-sdk-go-v2/service/autoscaling"
29
+ autoscalingtypes "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/aws/aws-sdk-go-v2/service/autoscaling/types"
30
+ ec2types "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/aws/aws-sdk-go-v2/service/ec2/types"
29
31
"k8s.io/autoscaler/cluster-autoscaler/config/dynamic"
30
32
klog "k8s.io/klog/v2"
31
33
)
@@ -41,7 +43,7 @@ type asgCache struct {
41
43
asgToInstances map [AwsRef ][]AwsInstanceRef
42
44
instanceToAsg map [AwsInstanceRef ]* asg
43
45
instanceStatus map [AwsInstanceRef ]* string
44
- instanceLifecycle map [AwsInstanceRef ]* string
46
+ instanceLifecycle map [AwsInstanceRef ]autoscalingtypes. LifecycleState
45
47
asgInstanceTypeCache * instanceTypeExpirationStore
46
48
mutex sync.Mutex
47
49
awsService * awsWrapper
@@ -60,8 +62,8 @@ type launchTemplate struct {
60
62
type mixedInstancesPolicy struct {
61
63
launchTemplate * launchTemplate
62
64
instanceTypesOverrides []string
63
- instanceRequirementsOverrides * autoscaling .InstanceRequirements
64
- instanceRequirements * ec2 .InstanceRequirements
65
+ instanceRequirementsOverrides * autoscalingtypes .InstanceRequirements
66
+ instanceRequirements * ec2types .InstanceRequirements
65
67
}
66
68
67
69
type asg struct {
@@ -76,7 +78,7 @@ type asg struct {
76
78
LaunchConfigurationName string
77
79
LaunchTemplate * launchTemplate
78
80
MixedInstancesPolicy * mixedInstancesPolicy
79
- Tags []* autoscaling .TagDescription
81
+ Tags []autoscalingtypes .TagDescription
80
82
}
81
83
82
84
func newASGCache (awsService * awsWrapper , explicitSpecs []string , autoDiscoverySpecs []asgAutoDiscoveryConfig ) (* asgCache , error ) {
@@ -86,7 +88,7 @@ func newASGCache(awsService *awsWrapper, explicitSpecs []string, autoDiscoverySp
86
88
asgToInstances : make (map [AwsRef ][]AwsInstanceRef ),
87
89
instanceToAsg : make (map [AwsInstanceRef ]* asg ),
88
90
instanceStatus : make (map [AwsInstanceRef ]* string ),
89
- instanceLifecycle : make (map [AwsInstanceRef ]* string ),
91
+ instanceLifecycle : make (map [AwsInstanceRef ]autoscalingtypes. LifecycleState ),
90
92
asgInstanceTypeCache : newAsgInstanceTypeCache (awsService ),
91
93
interrupt : make (chan struct {}),
92
94
asgAutoDiscoverySpecs : autoDiscoverySpecs ,
@@ -243,12 +245,12 @@ func (m *asgCache) InstanceStatus(ref AwsInstanceRef) (*string, error) {
243
245
return nil , fmt .Errorf ("could not find instance %v" , ref )
244
246
}
245
247
246
- func (m * asgCache ) findInstanceLifecycle (ref AwsInstanceRef ) (* string , error ) {
248
+ func (m * asgCache ) findInstanceLifecycle (ref AwsInstanceRef ) (autoscalingtypes. LifecycleState , error ) {
247
249
if lifecycle , found := m .instanceLifecycle [ref ]; found {
248
250
return lifecycle , nil
249
251
}
250
252
251
- return nil , fmt .Errorf ("could not find instance %v" , ref )
253
+ return "" , fmt .Errorf ("could not find instance %v" , ref )
252
254
}
253
255
254
256
func (m * asgCache ) SetAsgSize (asg * asg , size int ) error {
@@ -261,12 +263,12 @@ func (m *asgCache) SetAsgSize(asg *asg, size int) error {
261
263
func (m * asgCache ) setAsgSizeNoLock (asg * asg , size int ) error {
262
264
params := & autoscaling.SetDesiredCapacityInput {
263
265
AutoScalingGroupName : aws .String (asg .Name ),
264
- DesiredCapacity : aws .Int64 ( int64 (size )),
266
+ DesiredCapacity : aws .Int32 ( int32 (size )),
265
267
HonorCooldown : aws .Bool (false ),
266
268
}
267
269
klog .V (0 ).Infof ("Setting asg %s size to %d" , asg .Name , size )
268
270
start := time .Now ()
269
- _ , err := m .awsService .SetDesiredCapacity (params )
271
+ _ , err := m .awsService .SetDesiredCapacity (context . Background (), params )
270
272
observeAWSRequest ("SetDesiredCapacity" , err , start )
271
273
if err != nil {
272
274
return err
@@ -356,12 +358,11 @@ func (m *asgCache) DeleteInstances(instances []*AwsInstanceRef) error {
356
358
return err
357
359
}
358
360
359
- if lifecycle != nil &&
360
- * lifecycle == autoscaling .LifecycleStateTerminated ||
361
- * lifecycle == autoscaling .LifecycleStateTerminating ||
362
- * lifecycle == autoscaling .LifecycleStateTerminatingWait ||
363
- * lifecycle == autoscaling .LifecycleStateTerminatingProceed {
364
- klog .V (2 ).Infof ("instance %s is already terminating in state %s, will skip instead" , instance .Name , * lifecycle )
361
+ if lifecycle == autoscalingtypes .LifecycleStateTerminated ||
362
+ lifecycle == autoscalingtypes .LifecycleStateTerminating ||
363
+ lifecycle == autoscalingtypes .LifecycleStateTerminatingWait ||
364
+ lifecycle == autoscalingtypes .LifecycleStateTerminatingProceed {
365
+ klog .V (2 ).Infof ("instance %s is already terminating in state %s, will skip instead" , instance .Name , lifecycle )
365
366
continue
366
367
}
367
368
@@ -370,12 +371,12 @@ func (m *asgCache) DeleteInstances(instances []*AwsInstanceRef) error {
370
371
ShouldDecrementDesiredCapacity : aws .Bool (true ),
371
372
}
372
373
start := time .Now ()
373
- resp , err := m .awsService .TerminateInstanceInAutoScalingGroup (params )
374
+ resp , err := m .awsService .TerminateInstanceInAutoScalingGroup (context . Background (), params )
374
375
observeAWSRequest ("TerminateInstanceInAutoScalingGroup" , err , start )
375
376
if err != nil {
376
377
return err
377
378
}
378
- klog .V (4 ).Infof (* resp .Activity .Description )
379
+ klog .V (4 ).Infof ("Terminated instance %s in autoscaling group: %s" , instance . Name , aws . ToString ( resp .Activity .Description ) )
379
380
380
381
// Proactively decrement the size so autoscaler makes better decisions
381
382
commonAsg .curSize --
@@ -421,7 +422,7 @@ func (m *asgCache) regenerate() error {
421
422
newInstanceToAsgCache := make (map [AwsInstanceRef ]* asg )
422
423
newAsgToInstancesCache := make (map [AwsRef ][]AwsInstanceRef )
423
424
newInstanceStatusMap := make (map [AwsInstanceRef ]* string )
424
- newInstanceLifecycleMap := make (map [AwsInstanceRef ]* string )
425
+ newInstanceLifecycleMap := make (map [AwsInstanceRef ]autoscalingtypes. LifecycleState )
425
426
426
427
// Fetch details of all ASGs
427
428
refreshNames := m .buildAsgNames ()
@@ -448,7 +449,7 @@ func (m *asgCache) regenerate() error {
448
449
// Register or update ASGs
449
450
exists := make (map [AwsRef ]bool )
450
451
for _ , group := range groups {
451
- asg , err := m .buildAsgFromAWS (group )
452
+ asg , err := m .buildAsgFromAWS (& group )
452
453
if err != nil {
453
454
return err
454
455
}
@@ -497,19 +498,21 @@ func (m *asgCache) regenerate() error {
497
498
return nil
498
499
}
499
500
500
- func (m * asgCache ) createPlaceholdersForDesiredNonStartedInstances (groups []* autoscaling.Group ) []* autoscaling.Group {
501
+ func (m * asgCache ) createPlaceholdersForDesiredNonStartedInstances (groups []autoscalingtypes.AutoScalingGroup ) []autoscalingtypes.AutoScalingGroup {
502
+ var updatedGroups []autoscalingtypes.AutoScalingGroup
501
503
for _ , g := range groups {
502
504
desired := * g .DesiredCapacity
503
- realInstances := int64 (len (g .Instances ))
505
+ realInstances := int32 (len (g .Instances ))
504
506
if desired <= realInstances {
507
+ updatedGroups = append (updatedGroups , g )
505
508
continue
506
509
}
507
510
508
511
klog .V (4 ).Infof ("Instance group %s has only %d instances created while requested count is %d. " +
509
512
"Creating placeholder instances." , * g .AutoScalingGroupName , realInstances , desired )
510
513
511
514
healthStatus := ""
512
- isAvailable , err := m .isNodeGroupAvailable (g )
515
+ isAvailable , err := m .isNodeGroupAvailable (& g )
513
516
if err != nil {
514
517
klog .V (4 ).Infof ("Could not check instance availability, creating placeholder node anyways: %v" , err )
515
518
} else if ! isAvailable {
@@ -519,23 +522,24 @@ func (m *asgCache) createPlaceholdersForDesiredNonStartedInstances(groups []*aut
519
522
520
523
for i := realInstances ; i < desired ; i ++ {
521
524
id := fmt .Sprintf ("%s-%s-%d" , placeholderInstanceNamePrefix , * g .AutoScalingGroupName , i )
522
- g .Instances = append (g .Instances , & autoscaling .Instance {
525
+ g .Instances = append (g .Instances , autoscalingtypes .Instance {
523
526
InstanceId : & id ,
524
- AvailabilityZone : g .AvailabilityZones [0 ],
527
+ AvailabilityZone : aws . String ( g .AvailabilityZones [0 ]) ,
525
528
HealthStatus : & healthStatus ,
526
529
})
527
530
}
531
+ updatedGroups = append (updatedGroups , g )
528
532
}
529
- return groups
533
+ return updatedGroups
530
534
}
531
535
532
- func (m * asgCache ) isNodeGroupAvailable (group * autoscaling. Group ) (bool , error ) {
536
+ func (m * asgCache ) isNodeGroupAvailable (group * autoscalingtypes. AutoScalingGroup ) (bool , error ) {
533
537
input := & autoscaling.DescribeScalingActivitiesInput {
534
538
AutoScalingGroupName : group .AutoScalingGroupName ,
535
539
}
536
540
537
541
start := time .Now ()
538
- response , err := m .awsService .DescribeScalingActivities (input )
542
+ response , err := m .awsService .DescribeScalingActivities (context . Background (), input )
539
543
observeAWSRequest ("DescribeScalingActivities" , err , start )
540
544
if err != nil {
541
545
return true , err // If we can't describe the scaling activities we assume the node group is available
@@ -547,8 +551,8 @@ func (m *asgCache) isNodeGroupAvailable(group *autoscaling.Group) (bool, error)
547
551
lut := a .lastUpdateTime
548
552
if activity .StartTime .Before (lut ) {
549
553
break
550
- } else if * activity .StatusCode == "Failed" {
551
- klog .Warningf ("ASG %s scaling failed with %s" , asgRef .Name , * activity )
554
+ } else if activity .StatusCode == autoscalingtypes . ScalingActivityStatusCodeFailed {
555
+ klog .Warningf ("ASG %s scaling failed with description: %s" , asgRef .Name , aws . ToString ( activity . Description ) )
552
556
return false , nil
553
557
}
554
558
} else {
@@ -558,11 +562,11 @@ func (m *asgCache) isNodeGroupAvailable(group *autoscaling.Group) (bool, error)
558
562
return true , nil
559
563
}
560
564
561
- func (m * asgCache ) buildAsgFromAWS (g * autoscaling. Group ) (* asg , error ) {
565
+ func (m * asgCache ) buildAsgFromAWS (g * autoscalingtypes. AutoScalingGroup ) (* asg , error ) {
562
566
spec := dynamic.NodeGroupSpec {
563
- Name : aws .StringValue (g .AutoScalingGroupName ),
564
- MinSize : int (aws .Int64Value (g .MinSize )),
565
- MaxSize : int (aws .Int64Value (g .MaxSize )),
567
+ Name : aws .ToString (g .AutoScalingGroupName ),
568
+ MinSize : int (aws .ToInt32 (g .MinSize )),
569
+ MaxSize : int (aws .ToInt32 (g .MaxSize )),
566
570
SupportScaleToZero : scaleToZeroSupported ,
567
571
}
568
572
@@ -575,9 +579,9 @@ func (m *asgCache) buildAsgFromAWS(g *autoscaling.Group) (*asg, error) {
575
579
minSize : spec .MinSize ,
576
580
maxSize : spec .MaxSize ,
577
581
578
- curSize : int (aws .Int64Value (g .DesiredCapacity )),
579
- AvailabilityZones : aws . StringValueSlice ( g .AvailabilityZones ) ,
580
- LaunchConfigurationName : aws .StringValue (g .LaunchConfigurationName ),
582
+ curSize : int (aws .ToInt32 (g .DesiredCapacity )),
583
+ AvailabilityZones : g .AvailabilityZones ,
584
+ LaunchConfigurationName : aws .ToString (g .LaunchConfigurationName ),
581
585
Tags : g .Tags ,
582
586
}
583
587
@@ -586,8 +590,8 @@ func (m *asgCache) buildAsgFromAWS(g *autoscaling.Group) (*asg, error) {
586
590
}
587
591
588
592
if g .MixedInstancesPolicy != nil {
589
- getInstanceTypes := func (overrides []* autoscaling .LaunchTemplateOverrides ) []string {
590
- res := []string {}
593
+ getInstanceTypes := func (overrides []autoscalingtypes .LaunchTemplateOverrides ) []string {
594
+ var res []string
591
595
for _ , override := range overrides {
592
596
if override .InstanceType != nil {
593
597
res = append (res , * override .InstanceType )
@@ -596,7 +600,7 @@ func (m *asgCache) buildAsgFromAWS(g *autoscaling.Group) (*asg, error) {
596
600
return res
597
601
}
598
602
599
- getInstanceTypeRequirements := func (overrides []* autoscaling .LaunchTemplateOverrides ) * autoscaling .InstanceRequirements {
603
+ getInstanceTypeRequirements := func (overrides []autoscalingtypes .LaunchTemplateOverrides ) * autoscalingtypes .InstanceRequirements {
600
604
if len (overrides ) == 1 && overrides [0 ].InstanceRequirements != nil {
601
605
return overrides [0 ].InstanceRequirements
602
606
}
@@ -625,8 +629,8 @@ func (m *asgCache) buildAsgFromAWS(g *autoscaling.Group) (*asg, error) {
625
629
return asg , nil
626
630
}
627
631
628
- func (m * asgCache ) getInstanceRequirementsFromMixedInstancesPolicy (policy * mixedInstancesPolicy ) (* ec2 .InstanceRequirements , error ) {
629
- instanceRequirements := & ec2 .InstanceRequirements {}
632
+ func (m * asgCache ) getInstanceRequirementsFromMixedInstancesPolicy (policy * mixedInstancesPolicy ) (* ec2types .InstanceRequirements , error ) {
633
+ instanceRequirements := & ec2types .InstanceRequirements {}
630
634
if policy .instanceRequirementsOverrides != nil {
631
635
var err error
632
636
instanceRequirements , err = m .awsService .getEC2RequirementsFromAutoscaling (policy .instanceRequirementsOverrides )
@@ -646,11 +650,11 @@ func (m *asgCache) getInstanceRequirementsFromMixedInstancesPolicy(policy *mixed
646
650
return instanceRequirements , nil
647
651
}
648
652
649
- func (m * asgCache ) buildInstanceRefFromAWS (instance * autoscaling .Instance ) AwsInstanceRef {
650
- providerID := fmt .Sprintf ("aws:///%s/%s" , aws .StringValue (instance .AvailabilityZone ), aws .StringValue (instance .InstanceId ))
653
+ func (m * asgCache ) buildInstanceRefFromAWS (instance autoscalingtypes .Instance ) AwsInstanceRef {
654
+ providerID := fmt .Sprintf ("aws:///%s/%s" , aws .ToString (instance .AvailabilityZone ), aws .ToString (instance .InstanceId ))
651
655
return AwsInstanceRef {
652
656
ProviderID : providerID ,
653
- Name : aws .StringValue (instance .InstanceId ),
657
+ Name : aws .ToString (instance .InstanceId ),
654
658
}
655
659
}
656
660
0 commit comments