in pkg/fake/ec2api.go [126:247]
func (e *EC2API) CreateFleet(_ context.Context, input *ec2.CreateFleetInput, _ ...func(*ec2.Options)) (*ec2.CreateFleetOutput, error) {
if input.DryRun != nil && *input.DryRun {
err := e.CreateFleetBehavior.Error.Get()
if err == nil {
return &ec2.CreateFleetOutput{}, &smithy.GenericAPIError{
Code: "DryRunOperation",
Message: "Request would have succeeded, but DryRun flag is set",
}
}
return nil, err
}
return e.CreateFleetBehavior.Invoke(input, func(input *ec2.CreateFleetInput) (*ec2.CreateFleetOutput, error) {
if input.LaunchTemplateConfigs[0].LaunchTemplateSpecification.LaunchTemplateName == nil {
return nil, fmt.Errorf("missing launch template name")
}
var instanceIds []string
var icedPools []CapacityPool
var reservationExceededPools []CapacityPool
var spotInstanceRequestID *string
if string(input.TargetCapacitySpecification.DefaultTargetCapacityType) == karpv1.CapacityTypeSpot {
spotInstanceRequestID = aws.String(test.RandomName())
}
fulfilled := 0
for _, ltc := range input.LaunchTemplateConfigs {
for _, override := range ltc.Overrides {
skipInstance := false
e.InsufficientCapacityPools.Range(func(pool CapacityPool) bool {
if pool.InstanceType == string(override.InstanceType) &&
pool.Zone == aws.ToString(override.AvailabilityZone) &&
pool.CapacityType == string(input.TargetCapacitySpecification.DefaultTargetCapacityType) {
icedPools = append(icedPools, pool)
skipInstance = true
return false
}
return true
})
if skipInstance {
continue
}
if crID, ok := e.launchTemplatesToCapacityReservations.Load(*ltc.LaunchTemplateSpecification.LaunchTemplateName); ok {
if cr, ok := lo.Find(e.DescribeCapacityReservationsOutput.Clone().CapacityReservations, func(cr ec2types.CapacityReservation) bool {
return *cr.CapacityReservationId == crID.(string)
}); !ok || *cr.AvailableInstanceCount == 0 {
reservationExceededPools = append(reservationExceededPools, CapacityPool{
InstanceType: string(override.InstanceType),
Zone: lo.FromPtr(override.AvailabilityZone),
CapacityType: karpv1.CapacityTypeReserved,
ReservationID: crID.(string),
})
continue
}
}
amiID := lo.ToPtr("")
if e.CreateLaunchTemplateBehavior.CalledWithInput.Len() > 0 {
lt := e.CreateLaunchTemplateBehavior.CalledWithInput.Pop()
amiID = lt.LaunchTemplateData.ImageId
e.CreateLaunchTemplateBehavior.CalledWithInput.Add(lt)
}
instanceState := ec2types.InstanceStateNameRunning
for ; fulfilled < int(*input.TargetCapacitySpecification.TotalTargetCapacity); fulfilled++ {
instance := ec2types.Instance{
ImageId: aws.String(*amiID),
InstanceId: aws.String(test.RandomName()),
Placement: &ec2types.Placement{AvailabilityZone: input.LaunchTemplateConfigs[0].Overrides[0].AvailabilityZone},
PrivateDnsName: aws.String(randomdata.IpV4Address()),
InstanceType: input.LaunchTemplateConfigs[0].Overrides[0].InstanceType,
SpotInstanceRequestId: spotInstanceRequestID,
State: &ec2types.InstanceState{
Name: instanceState,
},
}
e.Instances.Store(*instance.InstanceId, instance)
instanceIds = append(instanceIds, *instance.InstanceId)
}
}
if fulfilled == int(*input.TargetCapacitySpecification.TotalTargetCapacity) {
break
}
}
result := &ec2.CreateFleetOutput{Instances: []ec2types.CreateFleetInstance{
{
InstanceIds: instanceIds,
InstanceType: input.LaunchTemplateConfigs[0].Overrides[0].InstanceType,
Lifecycle: ec2types.InstanceLifecycle(input.TargetCapacitySpecification.DefaultTargetCapacityType),
LaunchTemplateAndOverrides: &ec2types.LaunchTemplateAndOverridesResponse{
Overrides: &ec2types.FleetLaunchTemplateOverrides{
SubnetId: input.LaunchTemplateConfigs[0].Overrides[0].SubnetId,
ImageId: input.LaunchTemplateConfigs[0].Overrides[0].ImageId,
InstanceType: input.LaunchTemplateConfigs[0].Overrides[0].InstanceType,
AvailabilityZone: input.LaunchTemplateConfigs[0].Overrides[0].AvailabilityZone,
},
},
},
}}
for _, pool := range icedPools {
result.Errors = append(result.Errors, ec2types.CreateFleetError{
ErrorCode: aws.String("InsufficientInstanceCapacity"),
LaunchTemplateAndOverrides: &ec2types.LaunchTemplateAndOverridesResponse{
Overrides: &ec2types.FleetLaunchTemplateOverrides{
InstanceType: ec2types.InstanceType(pool.InstanceType),
AvailabilityZone: aws.String(pool.Zone),
},
},
})
}
for _, pool := range reservationExceededPools {
result.Errors = append(result.Errors, ec2types.CreateFleetError{
ErrorCode: lo.ToPtr("ReservationCapacityExceeded"),
LaunchTemplateAndOverrides: &ec2types.LaunchTemplateAndOverridesResponse{
Overrides: &ec2types.FleetLaunchTemplateOverrides{
InstanceType: ec2types.InstanceType(pool.InstanceType),
AvailabilityZone: lo.ToPtr(pool.Zone),
},
},
})
}
return result, nil
})
}