diff --git a/moto/ec2/models.py b/moto/ec2/models.py
index a921fc571..c254e1716 100644
--- a/moto/ec2/models.py
+++ b/moto/ec2/models.py
@@ -9,6 +9,7 @@ from .utils import (
random_reservation_id,
random_security_group_id,
random_snapshot_id,
+ random_subnet_id,
random_volume_id,
random_vpc_id,
)
@@ -408,6 +409,9 @@ class VPCBackend(object):
self.vpcs[vpc_id] = vpc
return vpc
+ def get_vpc(self, vpc_id):
+ return self.vpcs.get(vpc_id)
+
def get_all_vpcs(self):
return self.vpcs.values()
@@ -415,9 +419,35 @@ class VPCBackend(object):
return self.vpcs.pop(vpc_id, None)
+class Subnet(object):
+ def __init__(self, subnet_id, vpc, cidr_block):
+ self.id = subnet_id
+ self.vpc = vpc
+ self.cidr_block = cidr_block
+
+
+class SubnetBackend(object):
+ def __init__(self):
+ self.subnets = {}
+ super(SubnetBackend, self).__init__()
+
+ def create_subnet(self, vpc_id, cidr_block):
+ subnet_id = random_subnet_id()
+ vpc = self.get_vpc(vpc_id)
+ subnet = Subnet(subnet_id, vpc, cidr_block)
+ self.subnets[subnet_id] = subnet
+ return subnet
+
+ def get_all_subnets(self):
+ return self.subnets.values()
+
+ def delete_subnet(self, subnet_id):
+ return self.subnets.pop(subnet_id, None)
+
+
class EC2Backend(BaseBackend, InstanceBackend, TagBackend, AmiBackend,
RegionsAndZonesBackend, SecurityGroupBackend, EBSBackend,
- VPCBackend):
+ VPCBackend, SubnetBackend):
pass
diff --git a/moto/ec2/responses/subnets.py b/moto/ec2/responses/subnets.py
index 6cbe9c7f8..97a5da287 100644
--- a/moto/ec2/responses/subnets.py
+++ b/moto/ec2/responses/subnets.py
@@ -1,15 +1,68 @@
from jinja2 import Template
from moto.ec2.models import ec2_backend
-from moto.ec2.utils import resource_ids_from_querystring
class Subnets(object):
+ def __init__(self, querystring):
+ self.querystring = querystring
+
def create_subnet(self):
- raise NotImplementedError('Subnets(AmazonVPC).create_subnet is not yet implemented')
+ vpc_id = self.querystring.get('VpcId')[0]
+ cidr_block = self.querystring.get('CidrBlock')[0]
+ subnet = ec2_backend.create_subnet(vpc_id, cidr_block)
+ template = Template(CREATE_SUBNET_RESPONSE)
+ return template.render(subnet=subnet)
def delete_subnet(self):
- raise NotImplementedError('Subnets(AmazonVPC).delete_subnet is not yet implemented')
+ subnet_id = self.querystring.get('SubnetId')[0]
+ subnet = ec2_backend.delete_subnet(subnet_id)
+ if subnet:
+ template = Template(DELETE_SUBNET_RESPONSE)
+ return template.render(subnet=subnet)
+ else:
+ return "", dict(status=404)
def describe_subnets(self):
- raise NotImplementedError('Subnets(AmazonVPC).describe_subnets is not yet implemented')
+ subnets = ec2_backend.get_all_subnets()
+ template = Template(DESCRIBE_SUBNETS_RESPONSE)
+ return template.render(subnets=subnets)
+
+
+CREATE_SUBNET_RESPONSE = """
+
+ 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE
+
+ {{ subnet.id }}
+ pending
+ {{ subnet.vpc.id }}
+ {{ subnet.cidr_block }}
+ 251
+ us-east-1a
+
+
+"""
+
+DELETE_SUBNET_RESPONSE = """
+
+ 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE
+ true
+"""
+
+DESCRIBE_SUBNETS_RESPONSE = """
+
+ 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE
+
+ {% for subnet in subnets %}
+ -
+ {{ subnet.id }}
+ available
+ {{ subnet.vpc.id }}
+ {{ subnet.cidr_block }}
+ 251
+ us-east-1a
+
+
+ {% endfor %}
+
+"""
diff --git a/moto/ec2/utils.py b/moto/ec2/utils.py
index a12ac153b..258927f05 100644
--- a/moto/ec2/utils.py
+++ b/moto/ec2/utils.py
@@ -33,6 +33,10 @@ def random_vpc_id():
return random_id(prefix='vpc')
+def random_subnet_id():
+ return random_id(prefix='subnet')
+
+
def random_snapshot_id():
return random_id(prefix='snap')
diff --git a/tests/test_ec2/test_subnets.py b/tests/test_ec2/test_subnets.py
index f73a8feda..e6ebebc6b 100644
--- a/tests/test_ec2/test_subnets.py
+++ b/tests/test_ec2/test_subnets.py
@@ -1,4 +1,5 @@
import boto
+from boto.exception import EC2ResponseError
import sure # flake8: noqa
from moto import mock_ec2
@@ -6,4 +7,17 @@ from moto import mock_ec2
@mock_ec2
def test_subnets():
- pass
+ conn = boto.connect_vpc('the_key', 'the_secret')
+ vpc = conn.create_vpc("10.0.0.0/16")
+ subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
+
+ all_subnets = conn.get_all_subnets()
+ all_subnets.should.have.length_of(1)
+
+ conn.delete_subnet(subnet.id)
+
+ all_subnets = conn.get_all_subnets()
+ all_subnets.should.have.length_of(0)
+
+ conn.delete_subnet.when.called_with(
+ subnet.id).should.throw(EC2ResponseError)