EC2: create_volume(): support Throughput-parameter (#6379)

This commit is contained in:
Hisashi Kamezawa 2023-06-08 04:35:57 -07:00 committed by GitHub
parent 08e509506a
commit 681873d177
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 0 deletions

View File

@ -23,6 +23,7 @@ from ..utils import (
IOPS_REQUIRED_VOLUME_TYPES = ["io1", "io2"]
IOPS_SUPPORTED_VOLUME_TYPES = ["gp3", "io1", "io2"]
THROUGHPUT_SUPPORTED_VOLUME_TYPES = ["gp3"]
GP3_DEFAULT_IOPS = 3000
@ -114,6 +115,7 @@ class Volume(TaggedEC2Resource, CloudFormationModel):
kms_key_id: Optional[str] = None,
volume_type: Optional[str] = None,
iops: Optional[int] = None,
throughput: Optional[int] = None,
):
self.id = volume_id
self.volume_type = volume_type or "gp2"
@ -127,6 +129,7 @@ class Volume(TaggedEC2Resource, CloudFormationModel):
self.kms_key_id = kms_key_id
self.modifications: List[VolumeModification] = []
self.iops = iops
self.throughput = throughput
def modify(
self,
@ -272,6 +275,7 @@ class EBSBackend:
kms_key_id: Optional[str] = None,
volume_type: Optional[str] = None,
iops: Optional[int] = None,
throughput: Optional[int] = None,
) -> Volume:
if kms_key_id and not encrypted:
raise InvalidParameterDependency("KmsKeyId", "Encrypted")
@ -283,6 +287,8 @@ class EBSBackend:
iops = GP3_DEFAULT_IOPS
elif volume_type not in IOPS_SUPPORTED_VOLUME_TYPES and iops:
raise InvalidParameterDependency("VolumeType", "Iops")
if volume_type not in THROUGHPUT_SUPPORTED_VOLUME_TYPES and throughput:
raise InvalidParameterDependency("VolumeType", "Throughput")
volume_id = random_volume_id()
zone = self.get_zone_by_name(zone_name) # type: ignore[attr-defined]
@ -302,6 +308,7 @@ class EBSBackend:
kms_key_id=kms_key_id,
volume_type=volume_type,
iops=iops,
throughput=throughput,
)
self.volumes[volume_id] = volume
return volume

View File

@ -67,6 +67,7 @@ class ElasticBlockStore(EC2BaseResponse):
encrypted = self._get_bool_param("Encrypted", if_none=False)
kms_key_id = self._get_param("KmsKeyId")
iops = self._get_param("Iops")
throughput = self._get_param("Throughput")
self.error_on_dryrun()
@ -78,6 +79,7 @@ class ElasticBlockStore(EC2BaseResponse):
kms_key_id=kms_key_id,
volume_type=volume_type,
iops=iops,
throughput=throughput,
)
volume.add_tags(volume_tags)
template = self.response_template(CREATE_VOLUME_RESPONSE)
@ -246,6 +248,9 @@ CREATE_VOLUME_RESPONSE = """<CreateVolumeResponse xmlns="http://ec2.amazonaws.co
{% if volume.iops %}
<iops>{{ volume.iops }}</iops>
{% endif %}
{% if volume.throughput %}
<throughput>{{ volume.throughput }}</throughput>
{% endif %}
</CreateVolumeResponse>"""
DESCRIBE_VOLUMES_RESPONSE = """<DescribeVolumesResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
@ -295,6 +300,9 @@ DESCRIBE_VOLUMES_RESPONSE = """<DescribeVolumesResponse xmlns="http://ec2.amazon
{% if volume.iops %}
<iops>{{ volume.iops }}</iops>
{% endif %}
{% if volume.throughput %}
<throughput>{{ volume.throughput }}</throughput>
{% endif %}
</item>
{% endfor %}
</volumeSet>

View File

@ -1101,3 +1101,26 @@ def test_create_volume_with_iops():
volume = ec2.describe_volumes(VolumeIds=[volume["VolumeId"]])["Volumes"][0]
volume["Iops"].should.equal(4000)
@mock_ec2
def test_create_volume_with_throughput():
ec2 = boto3.client("ec2", region_name="us-east-1")
volume = ec2.create_volume(
AvailabilityZone="us-east-1a", Size=10, VolumeType="gp3", Throughput=200
)
volume["Throughput"].should.equal(200)
volume = ec2.describe_volumes(VolumeIds=[volume["VolumeId"]])["Volumes"][0]
volume["Throughput"].should.equal(200)
@mock_ec2
def test_create_volume_with_throughput_fails():
resource = boto3.resource("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
resource.create_volume(
AvailabilityZone="us-east-1a", Size=10, VolumeType="gp2", Throughput=200
)
ex.value.response["Error"]["Code"].should.equal("InvalidParameterDependency")
ex.value.response["Error"]["Message"].should.contain("Throughput")