Virtual Private Gateway functionality
This commit is contained in:
parent
1a015d0e39
commit
166fd69515
@ -80,6 +80,14 @@ class InvalidNetworkAclIdError(EC2ClientError):
|
|||||||
.format(network_acl_id))
|
.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):
|
class InvalidNetworkInterfaceIdError(EC2ClientError):
|
||||||
def __init__(self, eni_id):
|
def __init__(self, eni_id):
|
||||||
super(InvalidNetworkInterfaceIdError, self).__init__(
|
super(InvalidNetworkInterfaceIdError, self).__init__(
|
||||||
|
@ -53,7 +53,8 @@ from .exceptions import (
|
|||||||
TagLimitExceeded,
|
TagLimitExceeded,
|
||||||
InvalidID,
|
InvalidID,
|
||||||
InvalidCIDRSubnetError,
|
InvalidCIDRSubnetError,
|
||||||
InvalidNetworkAclIdError
|
InvalidNetworkAclIdError,
|
||||||
|
InvalidVpnGatewayIdError
|
||||||
)
|
)
|
||||||
from .utils import (
|
from .utils import (
|
||||||
EC2_RESOURCE_TO_PREFIX,
|
EC2_RESOURCE_TO_PREFIX,
|
||||||
@ -89,7 +90,8 @@ from .utils import (
|
|||||||
filter_internet_gateways,
|
filter_internet_gateways,
|
||||||
filter_reservations,
|
filter_reservations,
|
||||||
random_network_acl_id,
|
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):
|
def validate_resource_ids(resource_ids):
|
||||||
@ -2442,6 +2444,57 @@ class NetworkAclEntry(TaggedEC2Resource):
|
|||||||
self.port_range_to = port_range_to
|
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,
|
class EC2Backend(BaseBackend, InstanceBackend, TagBackend, AmiBackend,
|
||||||
RegionsAndZonesBackend, SecurityGroupBackend, EBSBackend,
|
RegionsAndZonesBackend, SecurityGroupBackend, EBSBackend,
|
||||||
VPCBackend, SubnetBackend, SubnetRouteTableAssociationBackend,
|
VPCBackend, SubnetBackend, SubnetRouteTableAssociationBackend,
|
||||||
@ -2450,7 +2503,7 @@ class EC2Backend(BaseBackend, InstanceBackend, TagBackend, AmiBackend,
|
|||||||
RouteTableBackend, RouteBackend, InternetGatewayBackend,
|
RouteTableBackend, RouteBackend, InternetGatewayBackend,
|
||||||
VPCGatewayAttachmentBackend, SpotRequestBackend,
|
VPCGatewayAttachmentBackend, SpotRequestBackend,
|
||||||
ElasticAddressBackend, KeyPairBackend, DHCPOptionsSetBackend,
|
ElasticAddressBackend, KeyPairBackend, DHCPOptionsSetBackend,
|
||||||
NetworkAclBackend):
|
NetworkAclBackend, VpnGatewayBackend):
|
||||||
|
|
||||||
def __init__(self, region_name):
|
def __init__(self, region_name):
|
||||||
super(EC2Backend, self).__init__()
|
super(EC2Backend, self).__init__()
|
||||||
@ -2509,7 +2562,7 @@ class EC2Backend(BaseBackend, InstanceBackend, TagBackend, AmiBackend,
|
|||||||
elif resource_prefix == EC2_RESOURCE_TO_PREFIX['vpn-connection']:
|
elif resource_prefix == EC2_RESOURCE_TO_PREFIX['vpn-connection']:
|
||||||
self.raise_not_implemented_error('DescribeVpnConnections')
|
self.raise_not_implemented_error('DescribeVpnConnections')
|
||||||
elif resource_prefix == EC2_RESOURCE_TO_PREFIX['vpn-gateway']:
|
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
|
return True
|
||||||
|
|
||||||
ec2_backends = {}
|
ec2_backends = {}
|
||||||
|
@ -1,19 +1,110 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
from jinja2 import Template
|
||||||
from moto.core.responses import BaseResponse
|
from moto.core.responses import BaseResponse
|
||||||
|
from moto.ec2.utils import filters_from_querystring
|
||||||
|
|
||||||
|
|
||||||
class VirtualPrivateGateways(BaseResponse):
|
class VirtualPrivateGateways(BaseResponse):
|
||||||
def attach_vpn_gateway(self):
|
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):
|
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):
|
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):
|
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):
|
def detach_vpn_gateway(self):
|
||||||
raise NotImplementedError('VirtualPrivateGateways(AmazonVPC).detach_vpn_gateway is not yet implemented')
|
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'])
|
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():
|
def random_volume_id():
|
||||||
return random_id(prefix=EC2_RESOURCE_TO_PREFIX['volume'])
|
return random_id(prefix=EC2_RESOURCE_TO_PREFIX['volume'])
|
||||||
|
|
||||||
|
@ -7,4 +7,70 @@ from moto import mock_ec2
|
|||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_virtual_private_gateways():
|
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