Skip to content

Commit

Permalink
Merge pull request #5047 from athiruma/support_capacity_reservation
Browse files Browse the repository at this point in the history
✨ Added the CapacityReservation support
  • Loading branch information
k8s-ci-robot authored Jul 29, 2024
2 parents 0159435 + 5e44fa5 commit 6ad02ef
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 0 deletions.
1 change: 1 addition & 0 deletions api/v1beta1/awscluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
dst.Status.Bastion.PlacementGroupPartition = restored.Status.Bastion.PlacementGroupPartition
dst.Status.Bastion.PrivateDNSName = restored.Status.Bastion.PrivateDNSName
dst.Status.Bastion.PublicIPOnLaunch = restored.Status.Bastion.PublicIPOnLaunch
dst.Status.Bastion.CapacityReservationID = restored.Status.Bastion.CapacityReservationID
}
dst.Spec.Partition = restored.Spec.Partition

Expand Down
2 changes: 2 additions & 0 deletions api/v1beta1/awsmachine_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func (src *AWSMachine) ConvertTo(dstRaw conversion.Hub) error {
dst.Spec.PlacementGroupPartition = restored.Spec.PlacementGroupPartition
dst.Spec.PrivateDNSName = restored.Spec.PrivateDNSName
dst.Spec.SecurityGroupOverrides = restored.Spec.SecurityGroupOverrides
dst.Spec.CapacityReservationID = restored.Spec.CapacityReservationID
if restored.Spec.ElasticIPPool != nil {
if dst.Spec.ElasticIPPool == nil {
dst.Spec.ElasticIPPool = &infrav1.ElasticIPPool{}
Expand Down Expand Up @@ -102,6 +103,7 @@ func (r *AWSMachineTemplate) ConvertTo(dstRaw conversion.Hub) error {
dst.Spec.Template.Spec.PlacementGroupPartition = restored.Spec.Template.Spec.PlacementGroupPartition
dst.Spec.Template.Spec.PrivateDNSName = restored.Spec.Template.Spec.PrivateDNSName
dst.Spec.Template.Spec.SecurityGroupOverrides = restored.Spec.Template.Spec.SecurityGroupOverrides
dst.Spec.Template.Spec.CapacityReservationID = restored.Spec.Template.Spec.CapacityReservationID
if restored.Spec.Template.Spec.ElasticIPPool != nil {
if dst.Spec.Template.Spec.ElasticIPPool == nil {
dst.Spec.Template.Spec.ElasticIPPool = &infrav1.ElasticIPPool{}
Expand Down
2 changes: 2 additions & 0 deletions api/v1beta1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions api/v1beta2/awsmachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ type AWSMachineSpec struct {
// PrivateDNSName is the options for the instance hostname.
// +optional
PrivateDNSName *PrivateDNSName `json:"privateDnsName,omitempty"`

// CapacityReservationID specifies the target Capacity Reservation into which the instance should be launched.
// +optional
CapacityReservationID *string `json:"capacityReservationId,omitempty"`
}

// CloudInit defines options related to the bootstrapping systems where
Expand Down
4 changes: 4 additions & 0 deletions api/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ type Instance struct {
// PublicIPOnLaunch is the option to associate a public IP on instance launch
// +optional
PublicIPOnLaunch *bool `json:"publicIPOnLaunch,omitempty"`

// CapacityReservationID specifies the target Capacity Reservation into which the instance should be launched.
// +optional
CapacityReservationID *string `json:"capacityReservationId,omitempty"`
}

// InstanceMetadataState describes the state of InstanceMetadataOptions.HttpEndpoint and InstanceMetadataOptions.InstanceMetadataTags
Expand Down
10 changes: 10 additions & 0 deletions api/v1beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,10 @@ spec:
availabilityZone:
description: Availability zone of instance
type: string
capacityReservationId:
description: CapacityReservationID specifies the target Capacity
Reservation into which the instance should be launched.
type: string
ebsOptimized:
description: Indicates whether the instance is optimized for Amazon
EBS I/O.
Expand Down Expand Up @@ -3118,6 +3122,10 @@ spec:
availabilityZone:
description: Availability zone of instance
type: string
capacityReservationId:
description: CapacityReservationID specifies the target Capacity
Reservation into which the instance should be launched.
type: string
ebsOptimized:
description: Indicates whether the instance is optimized for Amazon
EBS I/O.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2087,6 +2087,10 @@ spec:
availabilityZone:
description: Availability zone of instance
type: string
capacityReservationId:
description: CapacityReservationID specifies the target Capacity
Reservation into which the instance should be launched.
type: string
ebsOptimized:
description: Indicates whether the instance is optimized for Amazon
EBS I/O.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,10 @@ spec:
description: ID of resource
type: string
type: object
capacityReservationId:
description: CapacityReservationID specifies the target Capacity Reservation
into which the instance should be launched.
type: string
cloudInit:
description: |-
CloudInit defines options related to the bootstrapping systems where
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,10 @@ spec:
description: ID of resource
type: string
type: object
capacityReservationId:
description: CapacityReservationID specifies the target Capacity
Reservation into which the instance should be launched.
type: string
cloudInit:
description: |-
CloudInit defines options related to the bootstrapping systems where
Expand Down
16 changes: 16 additions & 0 deletions pkg/cloud/services/ec2/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ func (s *Service) CreateInstance(scope *scope.MachineScope, userData []byte, use

input.PrivateDNSName = scope.AWSMachine.Spec.PrivateDNSName

input.CapacityReservationID = scope.AWSMachine.Spec.CapacityReservationID

s.scope.Debug("Running instance", "machine-role", scope.Role())
s.scope.Debug("Running instance with instance metadata options", "metadata options", input.InstanceMetadataOptions)
out, err := s.runInstance(scope.Role(), input)
Expand Down Expand Up @@ -640,6 +642,7 @@ func (s *Service) runInstance(role string, i *infrav1.Instance) (*infrav1.Instan
input.InstanceMarketOptions = getInstanceMarketOptionsRequest(i.SpotMarketOptions)
input.MetadataOptions = getInstanceMetadataOptionsRequest(i.InstanceMetadataOptions)
input.PrivateDnsNameOptions = getPrivateDNSNameOptionsRequest(i.PrivateDNSName)
input.CapacityReservationSpecification = getCapacityReservationSpecification(i.CapacityReservationID)

if i.Tenancy != "" {
input.Placement = &ec2.Placement{
Expand Down Expand Up @@ -1123,6 +1126,19 @@ func filterGroups(list []string, strToFilter string) (newList []string) {
return
}

func getCapacityReservationSpecification(capacityReservationID *string) *ec2.CapacityReservationSpecification {
if capacityReservationID == nil {
// Not targeting any specific Capacity Reservation
return nil
}

return &ec2.CapacityReservationSpecification{
CapacityReservationTarget: &ec2.CapacityReservationTarget{
CapacityReservationId: capacityReservationID,
},
}
}

func getInstanceMarketOptionsRequest(spotMarketOptions *infrav1.SpotMarketOptions) *ec2.InstanceMarketOptionsRequest {
if spotMarketOptions == nil {
// Instance is not a Spot instance
Expand Down
33 changes: 33 additions & 0 deletions pkg/cloud/services/ec2/instances_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5620,3 +5620,36 @@ func mockedGetPrivateDNSDomainNameFromDHCPOptionsEmptyCalls(m *mocks.MockEC2APIM
},
}, nil)
}

func TestGetCapacityReservationSpecification(t *testing.T) {
mockCapacityReservationID := "cr-123"
mockCapacityReservationIDPtr := &mockCapacityReservationID
testCases := []struct {
name string
capacityReservationID *string
expectedRequest *ec2.CapacityReservationSpecification
}{
{
name: "with no CapacityReservationID options specified",
capacityReservationID: nil,
expectedRequest: nil,
},
{
name: "with a valid CapacityReservationID specified",
capacityReservationID: mockCapacityReservationIDPtr,
expectedRequest: &ec2.CapacityReservationSpecification{
CapacityReservationTarget: &ec2.CapacityReservationTarget{
CapacityReservationId: aws.String(mockCapacityReservationID),
},
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
request := getCapacityReservationSpecification(tc.capacityReservationID)
if !cmp.Equal(request, tc.expectedRequest) {
t.Errorf("Case: %s. Got: %v, expected: %v", tc.name, request, tc.expectedRequest)
}
})
}
}

0 comments on commit 6ad02ef

Please sign in to comment.