Skip to content

Commit

Permalink
Support IOPS parameter for IO1/IO2 & IOPSPerGB for GP3
Browse files Browse the repository at this point in the history
Signed-off-by: Eddie Torres <[email protected]>
  • Loading branch information
torredil committed Aug 30, 2022
1 parent c05f2f8 commit 7295c19
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 24 deletions.
66 changes: 42 additions & 24 deletions pkg/cloud/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ const (
io2MinTotalIOPS = 100
io2MaxTotalIOPS = 64000
io2MaxIOPSPerGB = 500
gp3MaxTotalIOPS = 16000
gp3MinTotalIOPS = 3000
gp3MaxIOPSPerGB = 500
)

var (
Expand Down Expand Up @@ -115,8 +118,6 @@ const (
const (
// DefaultVolumeSize represents the default volume size.
DefaultVolumeSize int64 = 100 * util.GiB
// DefaultVolumeType specifies which storage to use for newly created Volumes.
DefaultVolumeType = VolumeTypeGP3
)

// Tags
Expand Down Expand Up @@ -276,40 +277,57 @@ func newEC2Cloud(region string, awsSdkDebugLog bool) (Cloud, error) {

func (c *cloud) CreateDisk(ctx context.Context, volumeName string, diskOptions *DiskOptions) (*Disk, error) {
var (
createType string
iops int64
throughput int64
err error
createType string
iops int64
throughput int64
err error
maxIops int64
minIops int64
maxIopsPerGb int64
)

capacityGiB := util.BytesToGiB(diskOptions.CapacityBytes)

switch diskOptions.VolumeType {
if diskOptions.IOPS > 0 && diskOptions.IOPSPerGB > 0 {
return nil, fmt.Errorf("invalid StorageClass parameters; specify either IOPS or IOPSPerGb, not both")
}

createType = diskOptions.VolumeType
// If no volume type is specified, GP3 is used as default for newly created volumes.
if createType == "" {
createType = VolumeTypeGP3
}

switch createType {
case VolumeTypeGP2, VolumeTypeSC1, VolumeTypeST1, VolumeTypeSBG1, VolumeTypeSBP1, VolumeTypeStandard:
createType = diskOptions.VolumeType
case VolumeTypeIO1:
createType = diskOptions.VolumeType
iops, err = capIOPS(diskOptions.VolumeType, capacityGiB, int64(diskOptions.IOPSPerGB), io1MinTotalIOPS, io1MaxTotalIOPS, io1MaxIOPSPerGB, diskOptions.AllowIOPSPerGBIncrease)
if err != nil {
return nil, err
}
maxIops = io1MaxTotalIOPS
minIops = io1MinTotalIOPS
maxIopsPerGb = io1MaxIOPSPerGB
case VolumeTypeIO2:
createType = diskOptions.VolumeType
iops, err = capIOPS(diskOptions.VolumeType, capacityGiB, int64(diskOptions.IOPSPerGB), io2MinTotalIOPS, io2MaxTotalIOPS, io2MaxIOPSPerGB, diskOptions.AllowIOPSPerGBIncrease)
if err != nil {
return nil, err
}
maxIops = io2MaxTotalIOPS
minIops = io2MinTotalIOPS
maxIopsPerGb = io2MaxIOPSPerGB
case VolumeTypeGP3:
createType = diskOptions.VolumeType
iops = int64(diskOptions.IOPS)
throughput = int64(diskOptions.Throughput)
case "":
createType = DefaultVolumeType
iops = int64(diskOptions.IOPS)
maxIops = gp3MaxTotalIOPS
minIops = gp3MinTotalIOPS
maxIopsPerGb = gp3MaxIOPSPerGB
throughput = int64(diskOptions.Throughput)
default:
return nil, fmt.Errorf("invalid AWS VolumeType %q", diskOptions.VolumeType)
}

if maxIops > 0 {
if diskOptions.IOPS > 0 {
iops = int64(diskOptions.IOPS)
} else if diskOptions.IOPSPerGB > 0 {
iops, err = capIOPS(createType, capacityGiB, int64(diskOptions.IOPSPerGB), minIops, maxIops, maxIopsPerGb, diskOptions.AllowIOPSPerGBIncrease)
if err != nil {
return nil, err
}
}
}

var tags []*ec2.Tag
for key, value := range diskOptions.Tags {
copiedKey := key
Expand Down
56 changes: 56 additions & 0 deletions pkg/cloud/cloud_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,44 @@ func TestCreateDisk(t *testing.T) {
},
expErr: nil,
},
{
name: "success: io1 with IOPS parameter",
volumeName: "vol-test-name",
diskOptions: &DiskOptions{
CapacityBytes: util.GiBToBytes(1),
Tags: map[string]string{VolumeNameTagKey: "vol-test", AwsEbsDriverTagKey: "true"},
VolumeType: VolumeTypeIO1,
IOPS: 100,
},
expDisk: &Disk{
VolumeID: "vol-test",
CapacityGiB: 1,
AvailabilityZone: defaultZone,
},
expCreateVolumeInput: &ec2.CreateVolumeInput{
Iops: aws.Int64(100),
},
expErr: nil,
},
{
name: "success: io2 with IOPS parameter",
volumeName: "vol-test-name",
diskOptions: &DiskOptions{
CapacityBytes: util.GiBToBytes(1),
Tags: map[string]string{VolumeNameTagKey: "vol-test", AwsEbsDriverTagKey: "true"},
VolumeType: VolumeTypeIO2,
IOPS: 100,
},
expDisk: &Disk{
VolumeID: "vol-test",
CapacityGiB: 1,
AvailabilityZone: defaultZone,
},
expCreateVolumeInput: &ec2.CreateVolumeInput{
Iops: aws.Int64(100),
},
expErr: nil,
},
{
name: "success: normal with gp3 options",
volumeName: "vol-test-name",
Expand Down Expand Up @@ -310,6 +348,24 @@ func TestCreateDisk(t *testing.T) {
},
expErr: nil,
},
{
name: "fail: invalid StorageClass parameters; specified both IOPS and IOPSPerGb",
volumeName: "vol-test-name",
diskOptions: &DiskOptions{
CapacityBytes: util.GiBToBytes(4),
Tags: map[string]string{VolumeNameTagKey: "vol-test", AwsEbsDriverTagKey: "true"},
VolumeType: VolumeTypeIO1,
IOPS: 1,
IOPSPerGB: 1,
},
expDisk: &Disk{
VolumeID: "vol-test",
CapacityGiB: 4,
AvailabilityZone: defaultZone,
},
expCreateVolumeInput: nil,
expErr: fmt.Errorf("invalid StorageClass parameters; specify either IOPS or IOPSPerGb, not both"),
},
{
name: "fail: io1 with too low iopsPerGB",
volumeName: "vol-test-name",
Expand Down

0 comments on commit 7295c19

Please sign in to comment.