Virtual Private Gateway functionality
This commit is contained in:
parent
1a015d0e39
commit
166fd69515
@ -80,6 +80,14 @@ class InvalidNetworkAclIdError(EC2ClientError):
|
||||
.format(network_acl_id))
|
||||
|
||||
|
||||
class InvalidVpnGatewayIdError(EC2ClientError):
|
||||
def __init__(self, network_acl_id):
|
||||
super(InvalidVpnGatewayIdError, self).__init__(
|
||||
"InvalidVpnGatewayID.NotFound",
|
||||
"The virtual private gateway ID '{0}' does not exist"
|
||||
.format(network_acl_id))
|
||||
|
||||
|
||||
class InvalidNetworkInterfaceIdError(EC2ClientError):
|
||||
def __init__(self, eni_id):
|
||||
super(InvalidNetworkInterfaceIdError, self).__init__(
|
||||
|
@ -53,7 +53,8 @@ from .exceptions import (
|
||||
TagLimitExceeded,
|
||||
InvalidID,
|
||||
InvalidCIDRSubnetError,
|
||||
InvalidNetworkAclIdError
|
||||
InvalidNetworkAclIdError,
|
||||
InvalidVpnGatewayIdError
|
||||
)
|
||||
from .utils import (
|
||||
EC2_RESOURCE_TO_PREFIX,
|
||||
@ -89,7 +90,8 @@ from .utils import (
|
||||
filter_internet_gateways,
|
||||
filter_reservations,
|
||||
random_network_acl_id,
|
||||
random_network_acl_subnet_association_id)
|
||||
random_network_acl_subnet_association_id,
|
||||
random_vpn_gateway_id)
|
||||
|
||||
|
||||
def validate_resource_ids(resource_ids):
|
||||
@ -2442,6 +2444,57 @@ class NetworkAclEntry(TaggedEC2Resource):
|
||||
self.port_range_to = port_range_to
|
||||
|
||||
|
||||
class VpnGateway(TaggedEC2Resource):
|
||||
def __init__(self, ec2_backend, id, type):
|
||||
self.ec2_backend = ec2_backend
|
||||
self.id = id
|
||||
self.type = type
|
||||
self.attachments = {}
|
||||
super(VpnGateway, self).__init__()
|
||||
|
||||
|
||||
class VpnGatewayAttachment(object):
|
||||
def __init__(self, vpc_id, state):
|
||||
self.vpc_id = vpc_id
|
||||
self.state = state
|
||||
super(VpnGatewayAttachment, self).__init__()
|
||||
|
||||
|
||||
class VpnGatewayBackend(object):
|
||||
def __init__(self):
|
||||
self.vpn_gateways = {}
|
||||
super(VpnGatewayBackend, self).__init__()
|
||||
|
||||
def create_vpn_gateway(self, type='ipsec.1'):
|
||||
vpn_gateway_id = random_vpn_gateway_id()
|
||||
vpn_gateway = VpnGateway(self, vpn_gateway_id, type)
|
||||
self.vpn_gateways[vpn_gateway_id] = vpn_gateway
|
||||
return vpn_gateway
|
||||
|
||||
def get_all_vpn_gateways(self, filters=None):
|
||||
vpn_gateways = self.vpn_gateways.values()
|
||||
return generic_filter(filters, vpn_gateways)
|
||||
|
||||
def get_vpn_gateway(self, vpn_gateway_id):
|
||||
vpn_gateway = self.vpn_gateways.get(vpn_gateway_id, None)
|
||||
if not vpn_gateway:
|
||||
raise InvalidVpnGatewayIdError(vpn_gateway_id)
|
||||
return vpn_gateway
|
||||
|
||||
def attach_vpn_gateway(self, vpn_gateway_id, vpc_id):
|
||||
vpn_gateway = self.get_vpn_gateway(vpn_gateway_id)
|
||||
self.get_vpc(vpc_id)
|
||||
attachment = VpnGatewayAttachment(vpc_id, state='attached')
|
||||
vpn_gateway.attachments[vpc_id] = attachment
|
||||
return attachment
|
||||
|
||||
def delete_vpn_gateway(self, vpn_gateway_id):
|
||||
deleted = self.vpn_gateways.pop(vpn_gateway_id, None)
|
||||
if not deleted:
|
||||
raise InvalidVpnGatewayIdError(vpn_gateway_id)
|
||||
return deleted
|
||||
|
||||
|
||||
class EC2Backend(BaseBackend, InstanceBackend, TagBackend, AmiBackend,
|
||||
RegionsAndZonesBackend, SecurityGroupBackend, EBSBackend,
|
||||
VPCBackend, SubnetBackend, SubnetRouteTableAssociationBackend,
|
||||
@ -2450,7 +2503,7 @@ class EC2Backend(BaseBackend, InstanceBackend, TagBackend, AmiBackend,
|
||||
RouteTableBackend, RouteBackend, InternetGatewayBackend,
|
||||
VPCGatewayAttachmentBackend, SpotRequestBackend,
|
||||
ElasticAddressBackend, KeyPairBackend, DHCPOptionsSetBackend,
|
||||
NetworkAclBackend):
|
||||
NetworkAclBackend, VpnGatewayBackend):
|
||||
|
||||
def __init__(self, region_name):
|
||||
super(EC2Backend, self).__init__()
|
||||
@ -2509,7 +2562,7 @@ class EC2Backend(BaseBackend, InstanceBackend, TagBackend, AmiBackend,
|
||||
elif resource_prefix == EC2_RESOURCE_TO_PREFIX['vpn-connection']:
|
||||
self.raise_not_implemented_error('DescribeVpnConnections')
|
||||
elif resource_prefix == EC2_RESOURCE_TO_PREFIX['vpn-gateway']:
|
||||
self.raise_not_implemented_error('DescribeVpnGateways')
|
||||
self.get_vpn_gateway(vpn_gateway_id=resource_id)
|
||||
return True
|
||||
|
||||
ec2_backends = {}
|
||||
|
@ -1,19 +1,110 @@
|
||||
from __future__ import unicode_literals
|
||||
from jinja2 import Template
|
||||
from moto.core.responses import BaseResponse
|
||||
from moto.ec2.utils import filters_from_querystring
|
||||
|
||||
|
||||
class VirtualPrivateGateways(BaseResponse):
|
||||
def attach_vpn_gateway(self):
|
||||
raise NotImplementedError('VirtualPrivateGateways(AmazonVPC).attach_vpn_gateway is not yet implemented')
|
||||
vpn_gateway_id = self.querystring.get('VpnGatewayId')[0]
|
||||
vpc_id = self.querystring.get('VpcId')[0]
|
||||
attachment = self.ec2_backend.attach_vpn_gateway(
|
||||
vpn_gateway_id,
|
||||
vpc_id
|
||||
)
|
||||
template = Template(ATTACH_VPN_GATEWAY_RESPONSE)
|
||||
return template.render(attachment=attachment)
|
||||
|
||||
def create_vpn_gateway(self):
|
||||
raise NotImplementedError('VirtualPrivateGateways(AmazonVPC).create_vpn_gateway is not yet implemented')
|
||||
type = self.querystring.get('Type', None)[0]
|
||||
vpn_gateway = self.ec2_backend.create_vpn_gateway(type)
|
||||
template = Template(CREATE_VPN_GATEWAY_RESPONSE)
|
||||
return template.render(vpn_gateway=vpn_gateway)
|
||||
|
||||
def delete_vpn_gateway(self):
|
||||
raise NotImplementedError('VirtualPrivateGateways(AmazonVPC).delete_vpn_gateway is not yet implemented')
|
||||
vpn_gateway_id = self.querystring.get('VpnGatewayId')[0]
|
||||
vpn_gateway = self.ec2_backend.delete_vpn_gateway(vpn_gateway_id)
|
||||
template = Template(DELETE_VPN_GATEWAY_RESPONSE)
|
||||
return template.render(vpn_gateway=vpn_gateway)
|
||||
|
||||
def describe_vpn_gateways(self):
|
||||
raise NotImplementedError('VirtualPrivateGateways(AmazonVPC).describe_vpn_gateways is not yet implemented')
|
||||
filters = filters_from_querystring(self.querystring)
|
||||
vpn_gateways = self.ec2_backend.get_all_vpn_gateways(filters)
|
||||
template = Template(DESCRIBE_VPN_GATEWAYS_RESPONSE)
|
||||
return template.render(vpn_gateways=vpn_gateways)
|
||||
|
||||
def detach_vpn_gateway(self):
|
||||
raise NotImplementedError('VirtualPrivateGateways(AmazonVPC).detach_vpn_gateway is not yet implemented')
|
||||
|
||||
|
||||
CREATE_VPN_GATEWAY_RESPONSE = """
|
||||
<CreateVpnGatewayResponse xmlns="http://ec2.amazonaws.com/doc/2014-10-01/">
|
||||
<requestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</requestId>
|
||||
<vpnGateway>
|
||||
<vpnGatewayId>{{ vpn_gateway.id }}</vpnGatewayId>
|
||||
<state>available</state>
|
||||
<type>{{ vpn_gateway.type }}</type>
|
||||
<availabilityZone>us-east-1a</availabilityZone>
|
||||
<attachments/>
|
||||
<tagSet>
|
||||
{% for tag in vpn_gateway.get_tags() %}
|
||||
<item>
|
||||
<resourceId>{{ tag.resource_id }}</resourceId>
|
||||
<resourceType>{{ tag.resource_type }}</resourceType>
|
||||
<key>{{ tag.key }}</key>
|
||||
<value>{{ tag.value }}</value>
|
||||
</item>
|
||||
{% endfor %}
|
||||
</tagSet>
|
||||
</vpnGateway>
|
||||
</CreateVpnGatewayResponse>"""
|
||||
|
||||
DESCRIBE_VPN_GATEWAYS_RESPONSE = """
|
||||
<DescribeVpnGatewaysResponse xmlns="http://ec2.amazonaws.com/doc/2014-10-01/">
|
||||
<requestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</requestId>
|
||||
<vpnGatewaySet>
|
||||
{% for vpn_gateway in vpn_gateways %}
|
||||
<item>
|
||||
<vpnGatewayId>{{ vpn_gateway.id }}</vpnGatewayId>
|
||||
<state>available</state>
|
||||
<type>{{ vpn_gateway.id }}</type>
|
||||
<availabilityZone>us-east-1a</availabilityZone>
|
||||
<attachments>
|
||||
{% for attachment in vpn_gateway.attachments.values() %}
|
||||
<item>
|
||||
<vpcId>{{ attachment.vpc_id }}</vpcId>
|
||||
<state>{{ attachment.state }}</state>
|
||||
</item>
|
||||
{% endfor %}
|
||||
</attachments>
|
||||
<tagSet/>
|
||||
<tagSet>
|
||||
{% for tag in vpn_gateway.get_tags() %}
|
||||
<item>
|
||||
<resourceId>{{ tag.resource_id }}</resourceId>
|
||||
<resourceType>{{ tag.resource_type }}</resourceType>
|
||||
<key>{{ tag.key }}</key>
|
||||
<value>{{ tag.value }}</value>
|
||||
</item>
|
||||
{% endfor %}
|
||||
</tagSet>
|
||||
</item>
|
||||
{% endfor %}
|
||||
</vpnGatewaySet>
|
||||
</DescribeVpnGatewaysResponse>"""
|
||||
|
||||
ATTACH_VPN_GATEWAY_RESPONSE = """
|
||||
<AttachVpnGatewayResponse xmlns="http://ec2.amazonaws.com/doc/2014-10-01/">
|
||||
<requestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</requestId>
|
||||
<attachment>
|
||||
<vpcId>{{ attachment.vpc_id }}</vpcId>
|
||||
<state>{{ attachment.state }}</state>
|
||||
</attachment>
|
||||
</AttachVpnGatewayResponse>"""
|
||||
|
||||
DELETE_VPN_GATEWAY_RESPONSE = """
|
||||
<DeleteVpnGatewayResponse xmlns="http://ec2.amazonaws.com/doc/2014-10-01/">
|
||||
<requestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</requestId>
|
||||
<return>true</return>
|
||||
</DeleteVpnGatewayResponse>
|
||||
"""
|
@ -81,6 +81,10 @@ def random_network_acl_subnet_association_id():
|
||||
return random_id(prefix=EC2_RESOURCE_TO_PREFIX['network-acl-subnet-assoc'])
|
||||
|
||||
|
||||
def random_vpn_gateway_id():
|
||||
return random_id(prefix=EC2_RESOURCE_TO_PREFIX['vpn-gateway'])
|
||||
|
||||
|
||||
def random_volume_id():
|
||||
return random_id(prefix=EC2_RESOURCE_TO_PREFIX['volume'])
|
||||
|
||||
|
@ -7,4 +7,70 @@ from moto import mock_ec2
|
||||
|
||||
@mock_ec2
|
||||
def test_virtual_private_gateways():
|
||||
pass
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
|
||||
vpn_gateway = conn.create_vpn_gateway('ipsec.1', 'us-east-1a')
|
||||
vpn_gateway.should_not.be.none
|
||||
vpn_gateway.id.should.match(r'vgw-\w+')
|
||||
vpn_gateway.type.should.equal('ipsec.1')
|
||||
vpn_gateway.state.should.equal('available')
|
||||
vpn_gateway.availability_zone.should.equal('us-east-1a')
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_vpn_gateway():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
vpn_gateway = conn.create_vpn_gateway('ipsec.1', 'us-east-1a')
|
||||
|
||||
vgws = conn.get_all_vpn_gateways()
|
||||
vgws.should.have.length_of(1)
|
||||
|
||||
gateway = vgws[0]
|
||||
gateway.id.should.match(r'vgw-\w+')
|
||||
gateway.id.should.equal(vpn_gateway.id)
|
||||
vpn_gateway.type.should.equal('ipsec.1')
|
||||
vpn_gateway.state.should.equal('available')
|
||||
vpn_gateway.availability_zone.should.equal('us-east-1a')
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_vpn_gateway_vpc_attachment():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
vpc = conn.create_vpc("10.0.0.0/16")
|
||||
vpn_gateway = conn.create_vpn_gateway('ipsec.1', 'us-east-1a')
|
||||
|
||||
conn.attach_vpn_gateway(
|
||||
vpn_gateway_id=vpn_gateway.id,
|
||||
vpc_id=vpc.id
|
||||
)
|
||||
|
||||
gateway = conn.get_all_vpn_gateways()[0]
|
||||
attachments = gateway.attachments
|
||||
attachments.should.have.length_of(1)
|
||||
attachments[0].vpc_id.should.equal(vpc.id)
|
||||
attachments[0].state.should.equal('attached')
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_delete_vpn_gateway():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
vpn_gateway = conn.create_vpn_gateway('ipsec.1', 'us-east-1a')
|
||||
|
||||
conn.delete_vpn_gateway(vpn_gateway.id)
|
||||
vgws = conn.get_all_vpn_gateways()
|
||||
vgws.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_vpn_gateway_tagging():
|
||||
conn = boto.connect_vpc('the_key', 'the_secret')
|
||||
vpn_gateway = conn.create_vpn_gateway('ipsec.1', 'us-east-1a')
|
||||
vpn_gateway.add_tag("a key", "some value")
|
||||
|
||||
tag = conn.get_all_tags()[0]
|
||||
tag.name.should.equal("a key")
|
||||
tag.value.should.equal("some value")
|
||||
|
||||
# Refresh the subnet
|
||||
vpn_gateway = conn.get_all_vpn_gateways()[0]
|
||||
vpn_gateway.tags.should.have.length_of(1)
|
||||
vpn_gateway.tags["a key"].should.equal("some value")
|
||||
|
Loading…
Reference in New Issue
Block a user