diff --git a/moto/ec2/exceptions.py b/moto/ec2/exceptions.py index 348c3f72..e4bbbafb 100644 --- a/moto/ec2/exceptions.py +++ b/moto/ec2/exceptions.py @@ -198,6 +198,13 @@ class InvalidInstanceIdError(EC2ClientError): ) +class InvalidInstanceTypeError(EC2ClientError): + def __init__(self, instance_type): + super(InvalidInstanceTypeError, self).__init__( + "InvalidInstanceType.NotFound", + "The instance type '{0}' does not exist".format(instance_type), + ) + class InvalidAMIIdError(EC2ClientError): def __init__(self, ami_id): super(InvalidAMIIdError, self).__init__( diff --git a/moto/ec2/models.py b/moto/ec2/models.py index fbd11210..d39606ec 100644 --- a/moto/ec2/models.py +++ b/moto/ec2/models.py @@ -51,6 +51,7 @@ from .exceptions import ( InvalidDomainError, InvalidID, InvalidInstanceIdError, + InvalidInstanceTypeError, InvalidInternetGatewayIdError, InvalidKeyPairDuplicateError, InvalidKeyPairFormatError, @@ -1126,8 +1127,6 @@ class InstanceBackend(object): return reservations -<<<<<<< HEAD -======= class InstanceTypeBackend(object): def __init__(self): super(InstanceTypeBackend, self).__init__() diff --git a/moto/ec2/responses/instances.py b/moto/ec2/responses/instances.py index ef45ee47..0f62ff84 100644 --- a/moto/ec2/responses/instances.py +++ b/moto/ec2/responses/instances.py @@ -144,9 +144,8 @@ class InstanceResponse(BaseResponse): return template.render(instances=instances) def describe_instance_types(self): - instance_types = [ - InstanceType(name="t1.micro", cores=1, memory=644874240, disk=0) - ] + instance_type_filters = self._get_multi_param("InstanceType") + instance_types = self.ec2_backend.describe_instance_types(instance_type_filters) template = self.response_template(EC2_DESCRIBE_INSTANCE_TYPES) return template.render(instance_types=instance_types) @@ -826,17 +825,17 @@ EC2_DESCRIBE_INSTANCE_TYPES = """ {% for instance_type in instance_types %} - {{ instance_type.name }} + {{ instance_type.apiname }} - {{ instance_type.cores }} - {{ instance_type.cores }} + {{ instance_type.vcpus|int }} + {{ instance_type.vcpus|int }} 1 - {{ instance_type.memory }} + {{ instance_type.memory|int }} - {{ instance_type.disk }} + {{ instance_type.storage|int }} diff --git a/tests/test_ec2/test_instance_types.py b/tests/test_ec2/test_instance_types.py index 1385d611..9f1205c9 100644 --- a/tests/test_ec2/test_instance_types.py +++ b/tests/test_ec2/test_instance_types.py @@ -2,6 +2,9 @@ from __future__ import unicode_literals import boto3 import sure # noqa +import pytest + +from botocore.exceptions import ClientError from moto import mock_ec2 @@ -16,3 +19,28 @@ def test_describe_instance_types(): instance_types["InstanceTypes"][0].should.have.key("InstanceType") instance_types["InstanceTypes"][0].should.have.key("MemoryInfo") instance_types["InstanceTypes"][0]["MemoryInfo"].should.have.key("SizeInMiB") + + +@mock_ec2 +def test_describe_instance_types_filter_by_type(): + client = boto3.client("ec2", "us-east-1") + instance_types = client.describe_instance_types(InstanceTypes=['t1.micro', 't2.nano']) + + instance_types.should.have.key("InstanceTypes") + instance_types["InstanceTypes"].should_not.be.empty + instance_types["InstanceTypes"].should.have.length_of(2) + instance_types["InstanceTypes"][0]['InstanceType'].should.equal('t1.micro') + instance_types["InstanceTypes"][1]['InstanceType'].should.equal('t2.nano') + + +@mock_ec2 +def test_describe_instance_types_unknown_type(): + client = boto3.client("ec2", "us-east-1") + + with pytest.raises(ClientError) as err: + client.describe_instance_types(InstanceTypes=['t1.non_existent']) + err.response["Error"]["Code"].should.equal("ValidationException") + err.response["Error"]["Message"].split(":")[0].should.look_like( + "The instance type '{'t1.non_existent'}' does not exist" + ) + err.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)