@@ -353,6 +353,139 @@ func TestServiceSDKToLaunchTemplate(t *testing.T) {
353353 wantHash : testUserDataHash ,
354354 wantDataSecretKey : nil , // respective tag is not given
355355 },
356+ {
357+ name : "spot market options" ,
358+ input : & ec2.LaunchTemplateVersion {
359+ LaunchTemplateId : aws .String ("lt-12345" ),
360+ LaunchTemplateName : aws .String ("foo" ),
361+ LaunchTemplateData : & ec2.ResponseLaunchTemplateData {
362+ ImageId : aws .String ("foo-image" ),
363+ IamInstanceProfile : & ec2.LaunchTemplateIamInstanceProfileSpecification {
364+ Arn : aws .String ("instance-profile/foo-profile" ),
365+ },
366+ KeyName : aws .String ("foo-keyname" ),
367+ InstanceMarketOptions : & ec2.LaunchTemplateInstanceMarketOptions {
368+ MarketType : aws .String (ec2 .MarketTypeSpot ),
369+ SpotOptions : & ec2.LaunchTemplateSpotMarketOptions {
370+ MaxPrice : aws .String ("0.05" ),
371+ },
372+ },
373+ UserData : aws .String (base64 .StdEncoding .EncodeToString ([]byte (testUserData ))),
374+ },
375+ VersionNumber : aws .Int64 (1 ),
376+ },
377+ wantLT : & expinfrav1.AWSLaunchTemplate {
378+ Name : "foo" ,
379+ AMI : infrav1.AMIReference {
380+ ID : aws .String ("foo-image" ),
381+ },
382+ IamInstanceProfile : "foo-profile" ,
383+ SSHKeyName : aws .String ("foo-keyname" ),
384+ VersionNumber : aws .Int64 (1 ),
385+ SpotMarketOptions : & infrav1.SpotMarketOptions {
386+ MaxPrice : aws .String ("0.05" ),
387+ },
388+ },
389+ wantHash : testUserDataHash ,
390+ wantDataSecretKey : nil ,
391+ },
392+ {
393+ name : "spot market options with no max price" ,
394+ input : & ec2.LaunchTemplateVersion {
395+ LaunchTemplateId : aws .String ("lt-12345" ),
396+ LaunchTemplateName : aws .String ("foo" ),
397+ LaunchTemplateData : & ec2.ResponseLaunchTemplateData {
398+ ImageId : aws .String ("foo-image" ),
399+ IamInstanceProfile : & ec2.LaunchTemplateIamInstanceProfileSpecification {
400+ Arn : aws .String ("instance-profile/foo-profile" ),
401+ },
402+ KeyName : aws .String ("foo-keyname" ),
403+ InstanceMarketOptions : & ec2.LaunchTemplateInstanceMarketOptions {
404+ MarketType : aws .String (ec2 .MarketTypeSpot ),
405+ SpotOptions : & ec2.LaunchTemplateSpotMarketOptions {},
406+ },
407+ UserData : aws .String (base64 .StdEncoding .EncodeToString ([]byte (testUserData ))),
408+ },
409+ VersionNumber : aws .Int64 (1 ),
410+ },
411+ wantLT : & expinfrav1.AWSLaunchTemplate {
412+ Name : "foo" ,
413+ AMI : infrav1.AMIReference {
414+ ID : aws .String ("foo-image" ),
415+ },
416+ IamInstanceProfile : "foo-profile" ,
417+ SSHKeyName : aws .String ("foo-keyname" ),
418+ VersionNumber : aws .Int64 (1 ),
419+ SpotMarketOptions : & infrav1.SpotMarketOptions {},
420+ },
421+ wantHash : testUserDataHash ,
422+ wantDataSecretKey : nil ,
423+ },
424+ {
425+ name : "spot market options without SpotOptions" ,
426+ input : & ec2.LaunchTemplateVersion {
427+ LaunchTemplateId : aws .String ("lt-12345" ),
428+ LaunchTemplateName : aws .String ("foo" ),
429+ LaunchTemplateData : & ec2.ResponseLaunchTemplateData {
430+ ImageId : aws .String ("foo-image" ),
431+ IamInstanceProfile : & ec2.LaunchTemplateIamInstanceProfileSpecification {
432+ Arn : aws .String ("instance-profile/foo-profile" ),
433+ },
434+ KeyName : aws .String ("foo-keyname" ),
435+ InstanceMarketOptions : & ec2.LaunchTemplateInstanceMarketOptions {
436+ MarketType : aws .String (ec2 .MarketTypeSpot ),
437+ },
438+ UserData : aws .String (base64 .StdEncoding .EncodeToString ([]byte (testUserData ))),
439+ },
440+ VersionNumber : aws .Int64 (1 ),
441+ },
442+ wantLT : & expinfrav1.AWSLaunchTemplate {
443+ Name : "foo" ,
444+ AMI : infrav1.AMIReference {
445+ ID : aws .String ("foo-image" ),
446+ },
447+ IamInstanceProfile : "foo-profile" ,
448+ SSHKeyName : aws .String ("foo-keyname" ),
449+ VersionNumber : aws .Int64 (1 ),
450+ SpotMarketOptions : & infrav1.SpotMarketOptions {},
451+ },
452+ wantHash : testUserDataHash ,
453+ wantDataSecretKey : nil ,
454+ },
455+ {
456+ name : "non-spot market type" ,
457+ input : & ec2.LaunchTemplateVersion {
458+ LaunchTemplateId : aws .String ("lt-12345" ),
459+ LaunchTemplateName : aws .String ("foo" ),
460+ LaunchTemplateData : & ec2.ResponseLaunchTemplateData {
461+ ImageId : aws .String ("foo-image" ),
462+ IamInstanceProfile : & ec2.LaunchTemplateIamInstanceProfileSpecification {
463+ Arn : aws .String ("instance-profile/foo-profile" ),
464+ },
465+ KeyName : aws .String ("foo-keyname" ),
466+ InstanceMarketOptions : & ec2.LaunchTemplateInstanceMarketOptions {
467+ MarketType : aws .String ("different-market-type" ),
468+ SpotOptions : & ec2.LaunchTemplateSpotMarketOptions {
469+ MaxPrice : aws .String ("0.05" ),
470+ },
471+ },
472+ UserData : aws .String (base64 .StdEncoding .EncodeToString ([]byte (testUserData ))),
473+ },
474+ VersionNumber : aws .Int64 (1 ),
475+ },
476+ wantLT : & expinfrav1.AWSLaunchTemplate {
477+ Name : "foo" ,
478+ AMI : infrav1.AMIReference {
479+ ID : aws .String ("foo-image" ),
480+ },
481+ IamInstanceProfile : "foo-profile" ,
482+ SSHKeyName : aws .String ("foo-keyname" ),
483+ VersionNumber : aws .Int64 (1 ),
484+ SpotMarketOptions : nil , // Should be nil since market type is not "spot"
485+ },
486+ wantHash : testUserDataHash ,
487+ wantDataSecretKey : nil ,
488+ },
356489 {
357490 name : "tag of bootstrap secret" ,
358491 input : & ec2.LaunchTemplateVersion {
@@ -440,6 +573,20 @@ func TestServiceLaunchTemplateNeedsUpdate(t *testing.T) {
440573 want bool
441574 wantErr bool
442575 }{
576+ {
577+ name : "only core security groups, order shouldn't matter" ,
578+ incoming : & expinfrav1.AWSLaunchTemplate {
579+ AdditionalSecurityGroups : []infrav1.AWSResourceReference {},
580+ },
581+ existing : & expinfrav1.AWSLaunchTemplate {
582+ AdditionalSecurityGroups : []infrav1.AWSResourceReference {
583+ {ID : aws .String ("sg-222" )},
584+ {ID : aws .String ("sg-111" )},
585+ },
586+ },
587+ want : false ,
588+ wantErr : false ,
589+ },
443590 {
444591 name : "the same security groups" ,
445592 incoming : & expinfrav1.AWSLaunchTemplate {
@@ -497,6 +644,10 @@ func TestServiceLaunchTemplateNeedsUpdate(t *testing.T) {
497644 IamInstanceProfile : DefaultAmiNameFormat ,
498645 },
499646 existing : & expinfrav1.AWSLaunchTemplate {
647+ AdditionalSecurityGroups : []infrav1.AWSResourceReference {
648+ {ID : aws .String ("sg-111" )},
649+ {ID : aws .String ("sg-222" )},
650+ },
500651 IamInstanceProfile : "some-other-profile" ,
501652 },
502653 want : true ,
@@ -507,6 +658,10 @@ func TestServiceLaunchTemplateNeedsUpdate(t *testing.T) {
507658 InstanceType : "t3.micro" ,
508659 },
509660 existing : & expinfrav1.AWSLaunchTemplate {
661+ AdditionalSecurityGroups : []infrav1.AWSResourceReference {
662+ {ID : aws .String ("sg-111" )},
663+ {ID : aws .String ("sg-222" )},
664+ },
510665 InstanceType : "t3.large" ,
511666 },
512667 want : true ,
@@ -540,9 +695,14 @@ func TestServiceLaunchTemplateNeedsUpdate(t *testing.T) {
540695 HTTPTokens : infrav1 .HTTPTokensStateRequired ,
541696 },
542697 },
543- existing : & expinfrav1.AWSLaunchTemplate {},
544- want : true ,
545- wantErr : false ,
698+ existing : & expinfrav1.AWSLaunchTemplate {
699+ AdditionalSecurityGroups : []infrav1.AWSResourceReference {
700+ {ID : aws .String ("sg-111" )},
701+ {ID : aws .String ("sg-222" )},
702+ },
703+ },
704+ want : true ,
705+ wantErr : false ,
546706 },
547707 {
548708 name : "new launch template instance metadata options, removing IMDSv2 requirement" ,
@@ -556,6 +716,59 @@ func TestServiceLaunchTemplateNeedsUpdate(t *testing.T) {
556716 want : true ,
557717 wantErr : false ,
558718 },
719+ {
720+ name : "Should return true if incoming SpotMarketOptions is different from existing SpotMarketOptions" ,
721+ incoming : & expinfrav1.AWSLaunchTemplate {
722+ SpotMarketOptions : & infrav1.SpotMarketOptions {
723+ MaxPrice : aws .String ("0.10" ),
724+ },
725+ },
726+ existing : & expinfrav1.AWSLaunchTemplate {
727+ AdditionalSecurityGroups : []infrav1.AWSResourceReference {
728+ {ID : aws .String ("sg-111" )},
729+ {ID : aws .String ("sg-222" )},
730+ },
731+ SpotMarketOptions : & infrav1.SpotMarketOptions {
732+ MaxPrice : aws .String ("0.05" ),
733+ },
734+ },
735+ want : true ,
736+ wantErr : false ,
737+ },
738+ {
739+ name : "Should return true if incoming adds SpotMarketOptions and existing has none" ,
740+ incoming : & expinfrav1.AWSLaunchTemplate {
741+ SpotMarketOptions : & infrav1.SpotMarketOptions {
742+ MaxPrice : aws .String ("0.10" ),
743+ },
744+ },
745+ existing : & expinfrav1.AWSLaunchTemplate {
746+ AdditionalSecurityGroups : []infrav1.AWSResourceReference {
747+ {ID : aws .String ("sg-111" )},
748+ {ID : aws .String ("sg-222" )},
749+ },
750+ SpotMarketOptions : nil ,
751+ },
752+ want : true ,
753+ wantErr : false ,
754+ },
755+ {
756+ name : "Should return true if incoming removes SpotMarketOptions and existing has some" ,
757+ incoming : & expinfrav1.AWSLaunchTemplate {
758+ SpotMarketOptions : nil ,
759+ },
760+ existing : & expinfrav1.AWSLaunchTemplate {
761+ AdditionalSecurityGroups : []infrav1.AWSResourceReference {
762+ {ID : aws .String ("sg-111" )},
763+ {ID : aws .String ("sg-222" )},
764+ },
765+ SpotMarketOptions : & infrav1.SpotMarketOptions {
766+ MaxPrice : aws .String ("0.05" ),
767+ },
768+ },
769+ want : true ,
770+ wantErr : false ,
771+ },
559772 }
560773 for _ , tt := range tests {
561774 t .Run (tt .name , func (t * testing.T ) {
0 commit comments