Add RDS Subnet groups
This commit is contained in:
parent
809046e00e
commit
7559fbe0d1
@ -29,3 +29,10 @@ class DBSecurityGroupNotFoundError(RDSClientError):
|
|||||||
super(DBSecurityGroupNotFoundError, self).__init__(
|
super(DBSecurityGroupNotFoundError, self).__init__(
|
||||||
'DBSecurityGroupNotFound',
|
'DBSecurityGroupNotFound',
|
||||||
"Security Group {0} not found.".format(security_group_name))
|
"Security Group {0} not found.".format(security_group_name))
|
||||||
|
|
||||||
|
|
||||||
|
class DBSubnetGroupNotFoundError(RDSClientError):
|
||||||
|
def __init__(self, subnet_group_name):
|
||||||
|
super(DBSubnetGroupNotFoundError, self).__init__(
|
||||||
|
'DBSubnetGroupNotFound',
|
||||||
|
"Subnet Group {0} not found.".format(subnet_group_name))
|
||||||
|
@ -4,7 +4,7 @@ import boto.rds
|
|||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
|
|
||||||
from moto.core import BaseBackend
|
from moto.core import BaseBackend
|
||||||
from .exceptions import DBInstanceNotFoundError, DBSecurityGroupNotFoundError
|
from .exceptions import DBInstanceNotFoundError, DBSecurityGroupNotFoundError, DBSubnetGroupNotFoundError
|
||||||
|
|
||||||
|
|
||||||
class Database(object):
|
class Database(object):
|
||||||
@ -118,11 +118,42 @@ class SecurityGroup(object):
|
|||||||
self.ip_ranges.append(cidr_ip)
|
self.ip_ranges.append(cidr_ip)
|
||||||
|
|
||||||
|
|
||||||
|
class SubnetGroup(object):
|
||||||
|
def __init__(self, subnet_name, description, subnets):
|
||||||
|
self.subnet_name = subnet_name
|
||||||
|
self.description = description
|
||||||
|
self.subnets = subnets
|
||||||
|
|
||||||
|
self.vpc_id = self.subnets[0].vpc_id
|
||||||
|
|
||||||
|
def to_xml(self):
|
||||||
|
template = Template("""<DBSubnetGroup>
|
||||||
|
<VpcId>{{ subnet_group.vpc_id }}</VpcId>
|
||||||
|
<SubnetGroupStatus>Complete</SubnetGroupStatus>
|
||||||
|
<DBSubnetGroupDescription>{{ subnet_group.description }}</DBSubnetGroupDescription>
|
||||||
|
<DBSubnetGroupName>{{ subnet_group.subnet_name }}</DBSubnetGroupName>
|
||||||
|
<Subnets>
|
||||||
|
{% for subnet in subnet_group.subnets %}
|
||||||
|
<Subnet>
|
||||||
|
<SubnetStatus>Active</SubnetStatus>
|
||||||
|
<SubnetIdentifier>{{ subnet.id }}</SubnetIdentifier>
|
||||||
|
<SubnetAvailabilityZone>
|
||||||
|
<Name>{{ subnet.availability_zone }}</Name>
|
||||||
|
<ProvisionedIopsCapable>false</ProvisionedIopsCapable>
|
||||||
|
</SubnetAvailabilityZone>
|
||||||
|
</Subnet>
|
||||||
|
{% endfor %}
|
||||||
|
</Subnets>
|
||||||
|
</DBSubnetGroup>""")
|
||||||
|
return template.render(subnet_group=self)
|
||||||
|
|
||||||
|
|
||||||
class RDSBackend(BaseBackend):
|
class RDSBackend(BaseBackend):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.databases = {}
|
self.databases = {}
|
||||||
self.security_groups = {}
|
self.security_groups = {}
|
||||||
|
self.subnet_groups = {}
|
||||||
|
|
||||||
def create_database(self, db_kwargs):
|
def create_database(self, db_kwargs):
|
||||||
database_id = db_kwargs['db_instance_identifier']
|
database_id = db_kwargs['db_instance_identifier']
|
||||||
@ -173,6 +204,26 @@ class RDSBackend(BaseBackend):
|
|||||||
security_group.authorize(cidr_ip)
|
security_group.authorize(cidr_ip)
|
||||||
return security_group
|
return security_group
|
||||||
|
|
||||||
|
def create_subnet_group(self, subnet_name, description, subnets):
|
||||||
|
subnet_group = SubnetGroup(subnet_name, description, subnets)
|
||||||
|
self.subnet_groups[subnet_name] = subnet_group
|
||||||
|
return subnet_group
|
||||||
|
|
||||||
|
def describe_subnet_groups(self, subnet_group_name):
|
||||||
|
if subnet_group_name:
|
||||||
|
if subnet_group_name in self.subnet_groups:
|
||||||
|
return [self.subnet_groups[subnet_group_name]]
|
||||||
|
else:
|
||||||
|
raise DBSubnetGroupNotFoundError(subnet_group_name)
|
||||||
|
return self.subnet_groups.values()
|
||||||
|
|
||||||
|
def delete_subnet_group(self, subnet_name):
|
||||||
|
if subnet_name in self.subnet_groups:
|
||||||
|
return self.subnet_groups.pop(subnet_name)
|
||||||
|
else:
|
||||||
|
raise DBSubnetGroupNotFoundError(subnet_name)
|
||||||
|
|
||||||
|
|
||||||
rds_backends = {}
|
rds_backends = {}
|
||||||
for region in boto.rds.regions():
|
for region in boto.rds.regions():
|
||||||
rds_backends[region.name] = RDSBackend()
|
rds_backends[region.name] = RDSBackend()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from moto.core.responses import BaseResponse
|
from moto.core.responses import BaseResponse
|
||||||
|
from moto.ec2.models import ec2_backends
|
||||||
from .models import rds_backends
|
from .models import rds_backends
|
||||||
|
|
||||||
|
|
||||||
@ -94,6 +95,27 @@ class RDSResponse(BaseResponse):
|
|||||||
template = self.response_template(AUTHORIZE_SECURITY_GROUP_TEMPLATE)
|
template = self.response_template(AUTHORIZE_SECURITY_GROUP_TEMPLATE)
|
||||||
return template.render(security_group=security_group)
|
return template.render(security_group=security_group)
|
||||||
|
|
||||||
|
def create_dbsubnet_group(self):
|
||||||
|
subnet_name = self._get_param('DBSubnetGroupName')
|
||||||
|
description = self._get_param('DBSubnetGroupDescription')
|
||||||
|
subnet_ids = self._get_multi_param('SubnetIds.member')
|
||||||
|
subnets = [ec2_backends[self.region].get_subnet(subnet_id) for subnet_id in subnet_ids]
|
||||||
|
subnet_group = self.backend.create_subnet_group(subnet_name, description, subnets)
|
||||||
|
template = self.response_template(CREATE_SUBNET_GROUP_TEMPLATE)
|
||||||
|
return template.render(subnet_group=subnet_group)
|
||||||
|
|
||||||
|
def describe_dbsubnet_groups(self):
|
||||||
|
subnet_name = self._get_param('DBSubnetGroupName')
|
||||||
|
subnet_groups = self.backend.describe_subnet_groups(subnet_name)
|
||||||
|
template = self.response_template(DESCRIBE_SUBNET_GROUPS_TEMPLATE)
|
||||||
|
return template.render(subnet_groups=subnet_groups)
|
||||||
|
|
||||||
|
def delete_dbsubnet_group(self):
|
||||||
|
subnet_name = self._get_param('DBSubnetGroupName')
|
||||||
|
subnet_group = self.backend.delete_subnet_group(subnet_name)
|
||||||
|
template = self.response_template(DELETE_SUBNET_GROUP_TEMPLATE)
|
||||||
|
return template.render(subnet_group=subnet_group)
|
||||||
|
|
||||||
|
|
||||||
CREATE_DATABASE_TEMPLATE = """<CreateDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
|
CREATE_DATABASE_TEMPLATE = """<CreateDBInstanceResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
|
||||||
<CreateDBInstanceResult>
|
<CreateDBInstanceResult>
|
||||||
@ -171,3 +193,31 @@ AUTHORIZE_SECURITY_GROUP_TEMPLATE = """<AuthorizeDBSecurityGroupIngressResponse
|
|||||||
<RequestId>6176b5f8-bfed-11d3-f92b-31fa5e8dbc99</RequestId>
|
<RequestId>6176b5f8-bfed-11d3-f92b-31fa5e8dbc99</RequestId>
|
||||||
</ResponseMetadata>
|
</ResponseMetadata>
|
||||||
</AuthorizeDBSecurityGroupIngressResponse>"""
|
</AuthorizeDBSecurityGroupIngressResponse>"""
|
||||||
|
|
||||||
|
CREATE_SUBNET_GROUP_TEMPLATE = """<CreateDBSubnetGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
|
||||||
|
<CreateDBSubnetGroupResult>
|
||||||
|
{{ subnet_group.to_xml() }}
|
||||||
|
</CreateDBSubnetGroupResult>
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>3a401b3f-bb9e-11d3-f4c6-37db295f7674</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</CreateDBSubnetGroupResponse>"""
|
||||||
|
|
||||||
|
DESCRIBE_SUBNET_GROUPS_TEMPLATE = """<DescribeDBSubnetGroupsResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
|
||||||
|
<DescribeDBSubnetGroupsResult>
|
||||||
|
<DBSubnetGroups>
|
||||||
|
{% for subnet_group in subnet_groups %}
|
||||||
|
{{ subnet_group.to_xml() }}
|
||||||
|
{% endfor %}
|
||||||
|
</DBSubnetGroups>
|
||||||
|
</DescribeDBSubnetGroupsResult>
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>b783db3b-b98c-11d3-fbc7-5c0aad74da7c</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</DescribeDBSubnetGroupsResponse>"""
|
||||||
|
|
||||||
|
DELETE_SUBNET_GROUP_TEMPLATE = """<DeleteDBSubnetGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>6295e5ab-bbf3-11d3-f4c6-37db295f7674</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</DeleteDBSubnetGroupResponse>"""
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import boto.rds
|
import boto.rds
|
||||||
|
import boto.vpc
|
||||||
from boto.exception import BotoServerError
|
from boto.exception import BotoServerError
|
||||||
import sure # noqa
|
import sure # noqa
|
||||||
|
|
||||||
from moto import mock_rds
|
from moto import mock_ec2, mock_rds
|
||||||
|
|
||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
@ -138,3 +139,55 @@ def test_add_security_group_to_database():
|
|||||||
list(database.security_groups).should.have.length_of(1)
|
list(database.security_groups).should.have.length_of(1)
|
||||||
|
|
||||||
database.security_groups[0].name.should.equal("db_sg")
|
database.security_groups[0].name.should.equal("db_sg")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
@mock_rds
|
||||||
|
def test_add_database_subnet_group():
|
||||||
|
vpc_conn = boto.vpc.connect_to_region("us-west-2")
|
||||||
|
vpc = vpc_conn.create_vpc("10.0.0.0/16")
|
||||||
|
subnet1 = vpc_conn.create_subnet(vpc.id, "10.1.0.0/24")
|
||||||
|
subnet2 = vpc_conn.create_subnet(vpc.id, "10.2.0.0/24")
|
||||||
|
|
||||||
|
subnet_ids = [subnet1.id, subnet2.id]
|
||||||
|
conn = boto.rds.connect_to_region("us-west-2")
|
||||||
|
subnet_group = conn.create_db_subnet_group("db_subnet", "my db subnet", subnet_ids)
|
||||||
|
subnet_group.name.should.equal('db_subnet')
|
||||||
|
subnet_group.description.should.equal("my db subnet")
|
||||||
|
list(subnet_group.subnet_ids).should.equal(subnet_ids)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
@mock_rds
|
||||||
|
def test_describe_database_subnet_group():
|
||||||
|
vpc_conn = boto.vpc.connect_to_region("us-west-2")
|
||||||
|
vpc = vpc_conn.create_vpc("10.0.0.0/16")
|
||||||
|
subnet = vpc_conn.create_subnet(vpc.id, "10.1.0.0/24")
|
||||||
|
|
||||||
|
conn = boto.rds.connect_to_region("us-west-2")
|
||||||
|
conn.create_db_subnet_group("db_subnet1", "my db subnet", [subnet.id])
|
||||||
|
conn.create_db_subnet_group("db_subnet2", "my db subnet", [subnet.id])
|
||||||
|
|
||||||
|
list(conn.get_all_db_subnet_groups()).should.have.length_of(2)
|
||||||
|
list(conn.get_all_db_subnet_groups("db_subnet1")).should.have.length_of(1)
|
||||||
|
|
||||||
|
conn.get_all_db_subnet_groups.when.called_with("not-a-subnet").should.throw(BotoServerError)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
@mock_rds
|
||||||
|
def test_delete_database_subnet_group():
|
||||||
|
vpc_conn = boto.vpc.connect_to_region("us-west-2")
|
||||||
|
vpc = vpc_conn.create_vpc("10.0.0.0/16")
|
||||||
|
subnet = vpc_conn.create_subnet(vpc.id, "10.1.0.0/24")
|
||||||
|
|
||||||
|
conn = boto.rds.connect_to_region("us-west-2")
|
||||||
|
conn.create_db_subnet_group("db_subnet1", "my db subnet", [subnet.id])
|
||||||
|
list(conn.get_all_db_subnet_groups()).should.have.length_of(1)
|
||||||
|
|
||||||
|
conn.delete_db_subnet_group("db_subnet1")
|
||||||
|
list(conn.get_all_db_subnet_groups()).should.have.length_of(0)
|
||||||
|
|
||||||
|
conn.delete_db_subnet_group.when.called_with("db_subnet1").should.throw(BotoServerError)
|
||||||
|
|
||||||
|
# TODO incorporate subnet groups with actual DBs
|
||||||
|
Loading…
Reference in New Issue
Block a user