diff --git a/pkg/cloud/cloud.go b/pkg/cloud/cloud.go index 09a9026ff3..705734c093 100644 --- a/pkg/cloud/cloud.go +++ b/pkg/cloud/cloud.go @@ -36,36 +36,41 @@ import ( "k8s.io/apimachinery/pkg/util/wait" ) +// AWS volume types const ( - // DefaultVolumeSize represents the default volume size. - // TODO: what should be the default size? - DefaultVolumeSize int64 = 1 * 1024 * 1024 * 1024 - - // VolumeNameTagKey is the key value that refers to the volume's name. - VolumeNameTagKey = "com.amazon.aws.csi.volume" - // VolumeTypeIO1 represents a provisioned IOPS SSD type of volume. VolumeTypeIO1 = "io1" - // VolumeTypeGP2 represents a general purpose SSD type of volume. VolumeTypeGP2 = "gp2" - // VolumeTypeSC1 represents a cold HDD (sc1) type of volume. VolumeTypeSC1 = "sc1" - // VolumeTypeST1 represents a throughput-optimized HDD type of volume. VolumeTypeST1 = "st1" +) +// AWS provisioning limits. +// Source: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html +const ( // MinTotalIOPS represents the minimum Input Output per second. - MinTotalIOPS int64 = 100 - + MinTotalIOPS = 100 // MaxTotalIOPS represents the maximum Input Output per second. - MaxTotalIOPS int64 = 20000 + MaxTotalIOPS = 20000 +) +// Defaults +const ( + // DefaultVolumeSize represents the default volume size. + DefaultVolumeSize int64 = 100 * 1024 * 1024 * 1024 // DefaultVolumeType specifies which storage to use for newly created Volumes. DefaultVolumeType = VolumeTypeGP2 ) +// Tags +const ( + // VolumeNameTagKey is the key value that refers to the volume's name. + VolumeNameTagKey = "com.amazon.aws.csi.volume" +) + var ( // ErrMultiDisks is an error that is returned when multiple // disks are found with the same volume name. @@ -95,7 +100,7 @@ type DiskOptions struct { CapacityBytes int64 Tags map[string]string VolumeType string - IOPSPerGB int64 + IOPSPerGB int AvailabilityZone string } @@ -177,7 +182,7 @@ func (c *cloud) CreateDisk(ctx context.Context, volumeName string, diskOptions * createType = diskOptions.VolumeType case VolumeTypeIO1: createType = diskOptions.VolumeType - iops = capacityGiB * diskOptions.IOPSPerGB + iops = capacityGiB * int64(diskOptions.IOPSPerGB) if iops < MinTotalIOPS { iops = MinTotalIOPS } diff --git a/pkg/driver/controller.go b/pkg/driver/controller.go index 24262386d9..97b6cdc59d 100644 --- a/pkg/driver/controller.go +++ b/pkg/driver/controller.go @@ -18,6 +18,7 @@ package driver import ( "context" + "strconv" csi "github.com/container-storage-interface/spec/lib/go/csi/v0" "github.com/golang/glog" @@ -75,16 +76,28 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) // create a new volume zone := pickAvailabilityZone(req.GetAccessibilityRequirements()) + volumeParams := req.GetParameters() + volumeType := volumeParams["type"] + iopsPerGB := 0 + if volumeType == cloud.VolumeTypeIO1 { + iopsPerGB, err = strconv.Atoi(volumeParams["iopsPerGB"]) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "Could not parse invalid iopsPerGB: %v", err) + } + } + opts := &cloud.DiskOptions{ CapacityBytes: volSizeBytes, - AvailabilityZone: zone, Tags: map[string]string{cloud.VolumeNameTagKey: volName}, + VolumeType: volumeType, + IOPSPerGB: iopsPerGB, + AvailabilityZone: zone, } disk, err = d.cloud.CreateDisk(ctx, volName, opts) if err != nil { return nil, status.Errorf(codes.Internal, "Could not create volume %q: %v", volName, err) } - fsType := req.GetParameters()["fsType"] + fsType := volumeParams["fsType"] disk.FsType = fsType return newCreateVolumeResponse(disk), nil } diff --git a/pkg/driver/controller_test.go b/pkg/driver/controller_test.go index a43c38ed77..c72d3cc54c 100644 --- a/pkg/driver/controller_test.go +++ b/pkg/driver/controller_test.go @@ -149,6 +149,39 @@ func TestCreateVolume(t *testing.T) { Attributes: map[string]string{"fsType": defaultFsType}, }, }, + { + name: "success with volume type io1", + req: &csi.CreateVolumeRequest{ + Name: "vol-test", + CapacityRange: stdCapRange, + VolumeCapabilities: stdVolCap, + Parameters: map[string]string{ + "type": cloud.VolumeTypeIO1, + "iopsPerGB": "5", + }, + }, + expVol: &csi.Volume{ + CapacityBytes: stdVolSize, + Id: "vol-test", + Attributes: map[string]string{"fsType": ""}, + }, + }, + { + name: "success with volume type sc1", + req: &csi.CreateVolumeRequest{ + Name: "vol-test", + CapacityRange: stdCapRange, + VolumeCapabilities: stdVolCap, + Parameters: map[string]string{ + "type": cloud.VolumeTypeSC1, + }, + }, + expVol: &csi.Volume{ + CapacityBytes: stdVolSize, + Id: "vol-test", + Attributes: map[string]string{"fsType": ""}, + }, + }, } for _, tc := range testCases {