Merge "Add customer gateway configuration to VPN connection output"
This commit is contained in:
commit
033b5c3560
|
@ -15,6 +15,8 @@
|
|||
import random
|
||||
import string
|
||||
|
||||
from lxml import etree
|
||||
import netaddr
|
||||
from neutronclient.common import exceptions as neutron_exception
|
||||
from oslo_log import log as logging
|
||||
|
||||
|
@ -33,6 +35,8 @@ Validator = common.Validator
|
|||
|
||||
|
||||
SHARED_KEY_CHARS = string.ascii_letters + '_.' + string.digits
|
||||
AWS_MSS = 1387
|
||||
MTU_MSS_DELTA = 40 # 20 byte IP and 20 byte TCP headers
|
||||
|
||||
|
||||
def create_vpn_connection(context, customer_gateway_id, vpn_gateway_id,
|
||||
|
@ -47,7 +51,10 @@ def create_vpn_connection(context, customer_gateway_id, vpn_gateway_id,
|
|||
None)
|
||||
if vpn_connection:
|
||||
if vpn_connection['vpn_gateway_id'] == vpn_gateway_id:
|
||||
return {'vpnConnection': _format_vpn_connection(vpn_connection)}
|
||||
ec2_vpn_connections = describe_vpn_connections(
|
||||
context, vpn_connection_id=[vpn_connection['id']])
|
||||
return {
|
||||
'vpnConnection': ec2_vpn_connections['vpnConnectionSet'][0]}
|
||||
else:
|
||||
raise exception.InvalidCustomerGatewayDuplicateIpAddress()
|
||||
neutron = clients.neutron(context)
|
||||
|
@ -95,7 +102,10 @@ def create_vpn_connection(context, customer_gateway_id, vpn_gateway_id,
|
|||
_reset_vpn_connections(context, neutron, cleaner,
|
||||
vpn_gateway, vpn_connections=[vpn_connection])
|
||||
|
||||
return {'vpnConnection': _format_vpn_connection(vpn_connection)}
|
||||
ec2_vpn_connections = describe_vpn_connections(
|
||||
context, vpn_connection_id=[vpn_connection['id']])
|
||||
return {
|
||||
'vpnConnection': ec2_vpn_connections['vpnConnectionSet'][0]}
|
||||
|
||||
|
||||
def create_vpn_connection_route(context, vpn_connection_id,
|
||||
|
@ -180,7 +190,9 @@ class VpnConnectionDescriber(common.TaggableItemsDescriber,
|
|||
common.NonOpenstackItemsDescriber):
|
||||
|
||||
KIND = 'vpn'
|
||||
FILTER_MAP = {'customer-gateway-id': 'customerGatewayId',
|
||||
FILTER_MAP = {'customer-gateway-configuration': (
|
||||
'customerGatewayConfiguration'),
|
||||
'customer-gateway-id': 'customerGatewayId',
|
||||
'state': 'state',
|
||||
'option.static-routes-only': ('options', 'staticRoutesOnly'),
|
||||
'route.destination-cidr-block': ['routes',
|
||||
|
@ -189,11 +201,44 @@ class VpnConnectionDescriber(common.TaggableItemsDescriber,
|
|||
'vpn-connection-id': 'vpnConnectionId',
|
||||
'vpn-gateway-id': 'vpnGatewayId'}
|
||||
|
||||
def get_db_items(self):
|
||||
self.customer_gateways = {
|
||||
cgw['id']: cgw
|
||||
for cgw in db_api.get_items(self.context, 'cgw')}
|
||||
neutron = clients.neutron(self.context)
|
||||
self.os_ikepolicies = {
|
||||
ike['id']: ike
|
||||
for ike in neutron.list_ikepolicies(
|
||||
tenant_id=self.context.project_id)['ikepolicies']}
|
||||
self.os_ipsecpolicies = {
|
||||
ipsec['id']: ipsec
|
||||
for ipsec in neutron.list_ipsecpolicies(
|
||||
tenant_id=self.context.project_id)['ipsecpolicies']}
|
||||
self.os_ipsec_site_connections = {
|
||||
conn['id']: conn
|
||||
for conn in neutron.list_ipsec_site_connections(
|
||||
tenant_id=self.context.project_id)['ipsec_site_connections']}
|
||||
self.external_ips = _get_vpn_gateways_external_ips(
|
||||
self.context, neutron)
|
||||
return super(VpnConnectionDescriber, self).get_db_items()
|
||||
|
||||
def format(self, vpn_connection):
|
||||
return _format_vpn_connection(vpn_connection)
|
||||
return _format_vpn_connection(
|
||||
vpn_connection, self.customer_gateways, self.os_ikepolicies,
|
||||
self.os_ipsecpolicies, self.os_ipsec_site_connections,
|
||||
self.external_ips)
|
||||
|
||||
|
||||
def _format_vpn_connection(vpn_connection):
|
||||
def _format_vpn_connection(vpn_connection, customer_gateways, os_ikepolicies,
|
||||
os_ipsecpolicies, os_ipsec_site_connections,
|
||||
external_ips):
|
||||
config_dict = _format_customer_config(
|
||||
vpn_connection, customer_gateways, os_ikepolicies, os_ipsecpolicies,
|
||||
os_ipsec_site_connections, external_ips)
|
||||
config = ec2utils.dict_to_lxml(config_dict, 'vpn_connection')
|
||||
config.attrib['id'] = vpn_connection['id']
|
||||
config_str = etree.tostring(config, xml_declaration=True, encoding='UTF-8',
|
||||
pretty_print=True)
|
||||
return {'vpnConnectionId': vpn_connection['id'],
|
||||
'vpnGatewayId': vpn_connection['vpn_gateway_id'],
|
||||
'customerGatewayId': vpn_connection['customer_gateway_id'],
|
||||
|
@ -203,7 +248,70 @@ def _format_vpn_connection(vpn_connection):
|
|||
'state': 'available'}
|
||||
for cidr in vpn_connection['cidrs']],
|
||||
'vgwTelemetry': [],
|
||||
'options': {'staticRoutesOnly': True}}
|
||||
'options': {'staticRoutesOnly': True},
|
||||
'customerGatewayConfiguration': config_str}
|
||||
|
||||
|
||||
def _format_customer_config(vpn_connection, customer_gateways, os_ikepolicies,
|
||||
os_ipsecpolicies, os_ipsec_site_connections,
|
||||
external_ips):
|
||||
customer_gateway = customer_gateways[vpn_connection['customer_gateway_id']]
|
||||
os_connections_ids = vpn_connection['os_ipsec_site_connections'].values()
|
||||
if os_connections_ids:
|
||||
os_ipsec_site_connection = next(
|
||||
(os_ipsec_site_connections[conn_id]
|
||||
for conn_id in os_connections_ids
|
||||
if os_ipsec_site_connections.get(conn_id)),
|
||||
None)
|
||||
else:
|
||||
os_ipsec_site_connection = None
|
||||
|
||||
# TODO(ft): figure out and add to the output tunnel internal addresses
|
||||
config_dict = {
|
||||
'customer_gateway_id': vpn_connection['customer_gateway_id'],
|
||||
'vpn_gateway_id': vpn_connection['vpn_gateway_id'],
|
||||
'vpn_connection_type': 'ipsec.1',
|
||||
'vpn_connection_attributes': 'NoBGPVPNConnection',
|
||||
'ipsec_tunnel': {
|
||||
'customer_gateway': {
|
||||
'tunnel_outside_address': {
|
||||
'ip_address': (
|
||||
os_ipsec_site_connection['peer_address']
|
||||
if os_ipsec_site_connection else
|
||||
customer_gateway['ip_address'])}},
|
||||
'vpn_gateway': {
|
||||
'tunnel_outside_address': {
|
||||
'ip_address': external_ips.get(
|
||||
vpn_connection['vpn_gateway_id'])}}},
|
||||
}
|
||||
os_ikepolicy = os_ikepolicies.get(vpn_connection['os_ikepolicy_id'])
|
||||
if os_ikepolicy:
|
||||
config_dict['ipsec_tunnel']['ike'] = {
|
||||
'authentication_protocol': os_ikepolicy['auth_algorithm'],
|
||||
'encryption_protocol': os_ikepolicy['encryption_algorithm'],
|
||||
'lifetime': os_ikepolicy['lifetime']['value'],
|
||||
'perfect_forward_secrecy': os_ikepolicy['pfs'],
|
||||
'mode': os_ikepolicy['phase1_negotiation_mode'],
|
||||
'pre_shared_key': (
|
||||
os_ipsec_site_connection['psk']
|
||||
if os_ipsec_site_connection else
|
||||
vpn_connection['pre_shared_key']),
|
||||
}
|
||||
os_ipsecpolicy = os_ipsecpolicies.get(vpn_connection['os_ipsecpolicy_id'])
|
||||
if os_ipsecpolicy:
|
||||
config_dict['ipsec_tunnel']['ipsec'] = {
|
||||
'protocol': os_ipsecpolicy['transform_protocol'],
|
||||
'authentication_protocol': os_ipsecpolicy['auth_algorithm'],
|
||||
'encryption_protocol': os_ipsecpolicy['encryption_algorithm'],
|
||||
'lifetime': os_ipsecpolicy['lifetime']['value'],
|
||||
'perfect_forward_secrecy': os_ipsecpolicy['pfs'],
|
||||
'mode': os_ipsecpolicy['encapsulation_mode'],
|
||||
'tcp_mss_adjustment': (
|
||||
os_ipsec_site_connection['mtu'] - MTU_MSS_DELTA
|
||||
if os_ipsec_site_connection else
|
||||
AWS_MSS),
|
||||
}
|
||||
return config_dict
|
||||
|
||||
|
||||
def _stop_vpn_connection(neutron, vpn_connection):
|
||||
|
@ -300,7 +408,7 @@ def _set_subnet_vpn(context, neutron, cleaner, subnet, vpn_connection,
|
|||
'psk': vpn_connection['pre_shared_key'],
|
||||
'name': '%s/%s' % (vpn_connection['id'], subnet['id']),
|
||||
'peer_id': customer_gateway['ip_address'],
|
||||
'mtu': 1387 + 40, # AWS MSS + 20 byte IP and 20 byte TCP headers
|
||||
'mtu': AWS_MSS + MTU_MSS_DELTA,
|
||||
'initiator': 'response-only',
|
||||
}
|
||||
os_connection = (neutron.create_ipsec_site_connection(
|
||||
|
@ -348,6 +456,23 @@ def _get_route_table_vpn_cidrs(route_table, vpn_gateway, vpn_connections):
|
|||
return vpn_cidrs
|
||||
|
||||
|
||||
def _get_vpn_gateways_external_ips(context, neutron):
|
||||
vpcs = {vpc['id']: vpc
|
||||
for vpc in db_api.get_items(context, 'vpc')}
|
||||
external_ips = {}
|
||||
routers = neutron.list_routers(
|
||||
tenant_id=context.project_id)['routers']
|
||||
for router in routers:
|
||||
info = router['external_gateway_info']
|
||||
if info:
|
||||
for ip in info['external_fixed_ips']:
|
||||
if netaddr.valid_ipv4(ip['ip_address']):
|
||||
external_ips[router['id']] = ip['ip_address']
|
||||
return {vgw['id']: external_ips.get(vpcs[vgw['vpc_id']]['os_id'])
|
||||
for vgw in db_api.get_items(context, 'vgw')
|
||||
if vgw['vpc_id']}
|
||||
|
||||
|
||||
def _add_cidr_to_vpn_connection_item(context, vpn_connection, cidr):
|
||||
vpn_connection['cidrs'].append(cidr)
|
||||
db_api.update_item(context, vpn_connection)
|
||||
|
|
|
@ -18,6 +18,7 @@ import json
|
|||
import random
|
||||
import uuid
|
||||
|
||||
from lxml import etree
|
||||
from oslo_utils import timeutils
|
||||
|
||||
from ec2api.tests.unit import tools
|
||||
|
@ -60,6 +61,8 @@ CIDR_VPC_1 = '10.10.0.0/16'
|
|||
CIDR_VPC_2 = '10.20.0.0/16'
|
||||
ID_OS_PUBLIC_NETWORK = random_os_id()
|
||||
NAME_OS_PUBLIC_NETWORK = 'public_external'
|
||||
IP_ROUTER_1_EXTERNAL_V4 = '172.20.12.25'
|
||||
IP_ROUTER_1_EXTERNAL_V6 = '::ffff:172.20.12.25'
|
||||
|
||||
|
||||
# internet gateway constants
|
||||
|
@ -270,6 +273,92 @@ CIDR_VPN_1_PROPAGATED_1 = '192.168.110.0/24'
|
|||
CIDR_VPN_2_PROPAGATED_1 = '192.168.210.0/24'
|
||||
CIDR_VPN_2_PROPAGATED_2 = '192.168.220.0/24'
|
||||
|
||||
CUSTOMER_GATEWAY_CONFIGURATION_1 = etree.tostring(etree.fromstring(
|
||||
'<?xml version=\'1.0\' encoding=\'UTF-8\'?>'
|
||||
'<vpn_connection id="' + ID_EC2_VPN_CONNECTION_1 + '">'
|
||||
' <customer_gateway_id>' + (ID_EC2_CUSTOMER_GATEWAY_1 +
|
||||
'</customer_gateway_id>') +
|
||||
' <vpn_gateway_id>' + (ID_EC2_VPN_GATEWAY_1 +
|
||||
'</vpn_gateway_id>') +
|
||||
' <vpn_connection_type>ipsec.1</vpn_connection_type>'
|
||||
' <vpn_connection_attributes>' + ('NoBGPVPNConnection'
|
||||
'</vpn_connection_attributes>') +
|
||||
' <ipsec_tunnel>'
|
||||
' <customer_gateway>'
|
||||
' <tunnel_outside_address>'
|
||||
' <ip_address>' + IP_CUSTOMER_GATEWAY_ADDRESS_1 + '</ip_address>'
|
||||
' </tunnel_outside_address>'
|
||||
' </customer_gateway>'
|
||||
' <vpn_gateway>'
|
||||
' <tunnel_outside_address>'
|
||||
' <ip_address>' + IP_ROUTER_1_EXTERNAL_V4 + '</ip_address>'
|
||||
' </tunnel_outside_address>'
|
||||
' </vpn_gateway>'
|
||||
' <ike>'
|
||||
' <authentication_protocol>sha1</authentication_protocol>'
|
||||
' <encryption_protocol>aes-128</encryption_protocol>'
|
||||
' <lifetime>28800</lifetime>'
|
||||
' <perfect_forward_secrecy>group2</perfect_forward_secrecy>'
|
||||
' <mode>main</mode>'
|
||||
' <pre_shared_key>' + PRE_SHARED_KEY_1 + '</pre_shared_key>'
|
||||
' </ike>'
|
||||
' <ipsec>'
|
||||
' <protocol>esp</protocol>'
|
||||
' <authentication_protocol>sha1</authentication_protocol>'
|
||||
' <encryption_protocol>aes-128</encryption_protocol>'
|
||||
' <lifetime>3600</lifetime>'
|
||||
' <perfect_forward_secrecy>group2</perfect_forward_secrecy>'
|
||||
' <mode>tunnel</mode>'
|
||||
' <tcp_mss_adjustment>1387</tcp_mss_adjustment>'
|
||||
' </ipsec>'
|
||||
' </ipsec_tunnel>'
|
||||
'</vpn_connection>',
|
||||
parser=etree.XMLParser(remove_blank_text=True)
|
||||
), xml_declaration=True, encoding='UTF-8', pretty_print=True)
|
||||
CUSTOMER_GATEWAY_CONFIGURATION_2 = etree.tostring(etree.fromstring(
|
||||
'<?xml version=\'1.0\' encoding=\'UTF-8\'?>'
|
||||
'<vpn_connection id="' + ID_EC2_VPN_CONNECTION_2 + '">'
|
||||
' <customer_gateway_id>' + (ID_EC2_CUSTOMER_GATEWAY_2 +
|
||||
'</customer_gateway_id>') +
|
||||
' <vpn_gateway_id>' + (ID_EC2_VPN_GATEWAY_2 +
|
||||
'</vpn_gateway_id>') +
|
||||
' <vpn_connection_type>ipsec.1</vpn_connection_type>'
|
||||
' <vpn_connection_attributes>' + ('NoBGPVPNConnection'
|
||||
'</vpn_connection_attributes>') +
|
||||
' <ipsec_tunnel>'
|
||||
' <customer_gateway>'
|
||||
' <tunnel_outside_address>'
|
||||
' <ip_address>' + IP_CUSTOMER_GATEWAY_ADDRESS_2 + '</ip_address>'
|
||||
' </tunnel_outside_address>'
|
||||
' </customer_gateway>'
|
||||
' <vpn_gateway>'
|
||||
' <tunnel_outside_address>'
|
||||
' <ip_address/>'
|
||||
' </tunnel_outside_address>'
|
||||
' </vpn_gateway>'
|
||||
' <ike>'
|
||||
' <authentication_protocol>sha1</authentication_protocol>'
|
||||
' <encryption_protocol>aes-128</encryption_protocol>'
|
||||
' <lifetime>28800</lifetime>'
|
||||
' <perfect_forward_secrecy>group2</perfect_forward_secrecy>'
|
||||
' <mode>main</mode>'
|
||||
' <pre_shared_key>' + PRE_SHARED_KEY_2 + '</pre_shared_key>'
|
||||
' </ike>'
|
||||
' <ipsec>'
|
||||
' <protocol>esp</protocol>'
|
||||
' <authentication_protocol>sha1</authentication_protocol>'
|
||||
' <encryption_protocol>aes-128</encryption_protocol>'
|
||||
' <lifetime>3600</lifetime>'
|
||||
' <perfect_forward_secrecy>group2</perfect_forward_secrecy>'
|
||||
' <mode>tunnel</mode>'
|
||||
' <tcp_mss_adjustment>1387</tcp_mss_adjustment>'
|
||||
' </ipsec>'
|
||||
' </ipsec_tunnel>'
|
||||
'</vpn_connection>',
|
||||
parser=etree.XMLParser(remove_blank_text=True)
|
||||
), xml_declaration=True, encoding='UTF-8', pretty_print=True)
|
||||
|
||||
|
||||
# Object constants section
|
||||
# Constant name notation:
|
||||
# [<subtype>]<object_name>
|
||||
|
@ -305,9 +394,14 @@ EC2_VPC_2 = {'vpcId': ID_EC2_VPC_2,
|
|||
'dhcpOptionsId': 'default'}
|
||||
|
||||
OS_ROUTER_1 = {'id': ID_OS_ROUTER_1,
|
||||
'name': ID_EC2_VPC_1}
|
||||
'name': ID_EC2_VPC_1,
|
||||
'external_gateway_info': {
|
||||
'external_fixed_ips': [
|
||||
{'ip_address': IP_ROUTER_1_EXTERNAL_V6},
|
||||
{'ip_address': IP_ROUTER_1_EXTERNAL_V4}]}}
|
||||
OS_ROUTER_2 = {'id': ID_OS_ROUTER_2,
|
||||
'name': ID_EC2_VPC_2}
|
||||
'name': ID_EC2_VPC_2,
|
||||
'external_gateway_info': None}
|
||||
|
||||
|
||||
# internet gateway objects
|
||||
|
@ -1666,6 +1760,7 @@ EC2_VPN_CONNECTION_1 = {
|
|||
'state': 'available'}],
|
||||
'vgwTelemetry': None,
|
||||
'options': {'staticRoutesOnly': True},
|
||||
'customerGatewayConfiguration': CUSTOMER_GATEWAY_CONFIGURATION_1,
|
||||
}
|
||||
EC2_VPN_CONNECTION_2 = {
|
||||
'vpnConnectionId': ID_EC2_VPN_CONNECTION_2,
|
||||
|
@ -1679,6 +1774,7 @@ EC2_VPN_CONNECTION_2 = {
|
|||
'state': 'available'}],
|
||||
'vgwTelemetry': None,
|
||||
'options': {'staticRoutesOnly': True},
|
||||
'customerGatewayConfiguration': CUSTOMER_GATEWAY_CONFIGURATION_2,
|
||||
}
|
||||
|
||||
OS_IKEPOLICY_1 = {
|
||||
|
|
|
@ -445,15 +445,24 @@ class XMLMatches(object):
|
|||
|
||||
"""Compare XML strings. More complete than string comparison."""
|
||||
|
||||
def __init__(self, expected):
|
||||
def __init__(self, expected, orderless_sequence=False):
|
||||
self.expected_xml = expected
|
||||
self.orderless_sequence = orderless_sequence
|
||||
self.expected = etree.fromstring(expected)
|
||||
if self.orderless_sequence:
|
||||
self._sort_xml(self.expected)
|
||||
|
||||
def __str__(self):
|
||||
return 'XMLMatches(%r)' % self.expected_xml
|
||||
|
||||
def _sort_xml(self, xml):
|
||||
for parent in xml.xpath('//*[./*]'):
|
||||
parent[:] = sorted(parent, key=lambda x: x.tag)
|
||||
|
||||
def match(self, actual_xml):
|
||||
actual = etree.fromstring(actual_xml)
|
||||
if self.orderless_sequence:
|
||||
self._sort_xml(actual)
|
||||
|
||||
state = XMLMatchState(self.expected_xml, actual_xml)
|
||||
result = self._compare_node(self.expected, actual, state, None)
|
||||
|
|
|
@ -27,10 +27,12 @@ from ec2api.tests.unit import tools
|
|||
|
||||
class VpnConnectionTestCase(base.ApiTestCase):
|
||||
|
||||
@mock.patch('ec2api.api.vpn_connection.describe_vpn_connections')
|
||||
@mock.patch('ec2api.api.vpn_connection._reset_vpn_connections',
|
||||
wraps=vpn_connection_api._reset_vpn_connections)
|
||||
@mock.patch('random.choice')
|
||||
def test_create_vpn_connection(self, random_choice, reset_vpn_connections):
|
||||
def test_create_vpn_connection(self, random_choice, reset_vpn_connections,
|
||||
describe_vpn_connections):
|
||||
self.set_mock_db_items(
|
||||
fakes.DB_VPN_GATEWAY_1, fakes.DB_VPN_GATEWAY_2,
|
||||
fakes.DB_CUSTOMER_GATEWAY_1, fakes.DB_CUSTOMER_GATEWAY_2,
|
||||
|
@ -42,6 +44,8 @@ class VpnConnectionTestCase(base.ApiTestCase):
|
|||
self.db_api.add_item.side_effect = (
|
||||
tools.get_db_api_add_item(fakes.ID_EC2_VPN_CONNECTION_1))
|
||||
random_choice.side_effect = iter(fakes.PRE_SHARED_KEY_1)
|
||||
describe_vpn_connections.return_value = {
|
||||
'vpnConnectionSet': [fakes.EC2_VPN_CONNECTION_1]}
|
||||
|
||||
resp = self.execute(
|
||||
'CreateVpnConnection',
|
||||
|
@ -52,9 +56,7 @@ class VpnConnectionTestCase(base.ApiTestCase):
|
|||
self.assertThat(
|
||||
resp,
|
||||
matchers.DictMatches(
|
||||
{'vpnConnection': (
|
||||
tools.update_dict(fakes.EC2_VPN_CONNECTION_1,
|
||||
{'routes': None}))}))
|
||||
{'vpnConnection': fakes.EC2_VPN_CONNECTION_1}))
|
||||
|
||||
self.neutron.create_ikepolicy.assert_called_once_with(
|
||||
{'ikepolicy': tools.purge_dict(fakes.OS_IKEPOLICY_1, ('id',))})
|
||||
|
@ -79,11 +81,16 @@ class VpnConnectionTestCase(base.ApiTestCase):
|
|||
vpn_connections=[new_vpn_connection_1])
|
||||
self.assertIsInstance(reset_vpn_connections.call_args[0][2],
|
||||
common.OnCrashCleaner)
|
||||
describe_vpn_connections.assert_called_once_with(
|
||||
mock.ANY, vpn_connection_id=[fakes.ID_EC2_VPN_CONNECTION_1])
|
||||
|
||||
def test_create_vpn_connection_idempotent(self):
|
||||
@mock.patch('ec2api.api.vpn_connection.describe_vpn_connections')
|
||||
def test_create_vpn_connection_idempotent(self, describe_vpn_connections):
|
||||
self.set_mock_db_items(
|
||||
fakes.DB_VPN_GATEWAY_1, fakes.DB_CUSTOMER_GATEWAY_1,
|
||||
fakes.DB_VPN_CONNECTION_1)
|
||||
describe_vpn_connections.return_value = {
|
||||
'vpnConnectionSet': [fakes.EC2_VPN_CONNECTION_1]}
|
||||
|
||||
resp = self.execute(
|
||||
'CreateVpnConnection',
|
||||
|
@ -96,6 +103,8 @@ class VpnConnectionTestCase(base.ApiTestCase):
|
|||
self.assertFalse(self.neutron.create_ikepolicy.called)
|
||||
self.assertFalse(self.neutron.create_ipsecpolicy.called)
|
||||
self.assertFalse(self.db_api.add_item.called)
|
||||
describe_vpn_connections.assert_called_once_with(
|
||||
mock.ANY, vpn_connection_id=[fakes.ID_EC2_VPN_CONNECTION_1])
|
||||
|
||||
def test_create_vpn_connection_invalid_parameters(self):
|
||||
self.assert_execution_error(
|
||||
|
@ -284,16 +293,48 @@ class VpnConnectionTestCase(base.ApiTestCase):
|
|||
self.assertFalse(self.neutron.create_ikepolicy.called)
|
||||
|
||||
def test_describe_vpn_connections(self):
|
||||
self.set_mock_db_items(fakes.DB_VPN_CONNECTION_1,
|
||||
fakes.DB_VPN_CONNECTION_2)
|
||||
self.set_mock_db_items(
|
||||
fakes.DB_VPN_CONNECTION_1, fakes.DB_VPN_CONNECTION_2,
|
||||
fakes.DB_CUSTOMER_GATEWAY_1, fakes.DB_CUSTOMER_GATEWAY_2,
|
||||
fakes.DB_VPN_GATEWAY_1, fakes.DB_VPN_GATEWAY_2,
|
||||
fakes.DB_VPC_1, fakes.DB_VPC_2)
|
||||
self.neutron.list_ikepolicies.return_value = {
|
||||
'ikepolicies': [fakes.OS_IKEPOLICY_1, fakes.OS_IKEPOLICY_2]}
|
||||
self.neutron.list_ipsecpolicies.return_value = {
|
||||
'ipsecpolicies': [fakes.OS_IPSECPOLICY_1, fakes.OS_IPSECPOLICY_2]}
|
||||
self.neutron.list_ipsec_site_connections.return_value = {
|
||||
'ipsec_site_connections': []}
|
||||
self.neutron.list_routers.return_value = {
|
||||
'routers': [fakes.OS_ROUTER_1, fakes.OS_ROUTER_2]}
|
||||
|
||||
resp = self.execute('DescribeVpnConnections', {})
|
||||
vpns = [tools.update_dict(
|
||||
vpn, {'customerGatewayConfiguration': 'DONTCARE'})
|
||||
for vpn in (fakes.EC2_VPN_CONNECTION_1,
|
||||
fakes.EC2_VPN_CONNECTION_2)]
|
||||
self.assertThat(
|
||||
resp,
|
||||
matchers.DictMatches(
|
||||
{'vpnConnectionSet': [fakes.EC2_VPN_CONNECTION_1,
|
||||
fakes.EC2_VPN_CONNECTION_2]},
|
||||
{'vpnConnectionSet': vpns},
|
||||
orderless_lists=True))
|
||||
for vpn in (fakes.EC2_VPN_CONNECTION_1, fakes.EC2_VPN_CONNECTION_2):
|
||||
config = next(v['customerGatewayConfiguration']
|
||||
for v in resp['vpnConnectionSet']
|
||||
if v['vpnConnectionId'] == vpn['vpnConnectionId'])
|
||||
self.assertThat(
|
||||
config,
|
||||
matchers.XMLMatches(vpn['customerGatewayConfiguration'],
|
||||
orderless_sequence=True))
|
||||
self.assertTrue(config.startswith(
|
||||
'<?xml version=\'1.0\' encoding=\'UTF-8\'?>'))
|
||||
self.neutron.list_ikepolicies.assert_called_once_with(
|
||||
tenant_id=fakes.ID_OS_PROJECT)
|
||||
self.neutron.list_ipsecpolicies.assert_called_once_with(
|
||||
tenant_id=fakes.ID_OS_PROJECT)
|
||||
self.neutron.list_ipsec_site_connections.assert_called_once_with(
|
||||
tenant_id=fakes.ID_OS_PROJECT)
|
||||
self.neutron.list_routers.assert_called_once_with(
|
||||
tenant_id=fakes.ID_OS_PROJECT)
|
||||
|
||||
resp = self.execute(
|
||||
'DescribeVpnConnections',
|
||||
|
@ -301,12 +342,14 @@ class VpnConnectionTestCase(base.ApiTestCase):
|
|||
self.assertThat(
|
||||
resp,
|
||||
matchers.DictMatches(
|
||||
{'vpnConnectionSet': [fakes.EC2_VPN_CONNECTION_1]},
|
||||
{'vpnConnectionSet': [vpns[0]]},
|
||||
orderless_lists=True))
|
||||
|
||||
self.check_filtering(
|
||||
'DescribeVpnConnections', 'vpnConnectionSet',
|
||||
[('customer-gateway-id', fakes.ID_EC2_CUSTOMER_GATEWAY_1),
|
||||
[('customer-gateway-configuration',
|
||||
'*' + fakes.PRE_SHARED_KEY_1 + '*'),
|
||||
('customer-gateway-id', fakes.ID_EC2_CUSTOMER_GATEWAY_1),
|
||||
('state', 'available'),
|
||||
('option.static-routes-only', True),
|
||||
('route.destination-cidr-block', fakes.CIDR_VPN_2_PROPAGATED_1),
|
||||
|
@ -321,13 +364,67 @@ class VpnConnectionTestCase(base.ApiTestCase):
|
|||
def test_format_vpn_connection(self):
|
||||
db_vpn_connection_1 = tools.update_dict(fakes.DB_VPN_CONNECTION_1,
|
||||
{'cidrs': []})
|
||||
ec2_vpn_connection_1 = tools.update_dict(fakes.EC2_VPN_CONNECTION_1,
|
||||
{'routes': [],
|
||||
'vgwTelemetry': []})
|
||||
ec2_vpn_connection_1 = tools.patch_dict(
|
||||
fakes.EC2_VPN_CONNECTION_1,
|
||||
{'routes': [], 'vgwTelemetry': []},
|
||||
('customerGatewayConfiguration',))
|
||||
formatted = vpn_connection_api._format_vpn_connection(
|
||||
db_vpn_connection_1)
|
||||
db_vpn_connection_1,
|
||||
{fakes.ID_EC2_CUSTOMER_GATEWAY_1: fakes.DB_CUSTOMER_GATEWAY_1},
|
||||
{}, {}, {}, {})
|
||||
formatted.pop('customerGatewayConfiguration')
|
||||
self.assertThat(ec2_vpn_connection_1, matchers.DictMatches(formatted))
|
||||
|
||||
def test_format_customer_config(self):
|
||||
ikepolicy = {
|
||||
'auth_algorithm': 'sha1-fake',
|
||||
'encryption_algorithm': '3des',
|
||||
'lifetime': {'value': 1111},
|
||||
'pfs': 'group5',
|
||||
'phase1_negotiation_mode': 'main-fake',
|
||||
}
|
||||
ipsecpolicy = {
|
||||
'transform_protocol': 'ah-esp',
|
||||
'auth_algorithm': 'sha1-fake',
|
||||
'encryption_algorithm': 'aes-256',
|
||||
'lifetime': {'value': 2222},
|
||||
'pfs': 'group14',
|
||||
'encapsulation_mode': 'transport',
|
||||
}
|
||||
ipsec_site_connection = {
|
||||
'peer_address': '1.2.3.4',
|
||||
'psk': 'password',
|
||||
'mtu': 1400,
|
||||
}
|
||||
conf = vpn_connection_api._format_customer_config(
|
||||
fakes.DB_VPN_CONNECTION_1,
|
||||
{fakes.ID_EC2_CUSTOMER_GATEWAY_1: fakes.DB_CUSTOMER_GATEWAY_1},
|
||||
{fakes.ID_OS_IKEPOLICY_1: ikepolicy},
|
||||
{fakes.ID_OS_IPSECPOLICY_1: ipsecpolicy},
|
||||
{fakes.ID_OS_IPSEC_SITE_CONNECTION_2: ipsec_site_connection},
|
||||
{fakes.ID_EC2_VPN_GATEWAY_1: '5.6.7.8'})
|
||||
|
||||
self.assertThat(
|
||||
{'ipsec_tunnel': {
|
||||
'customer_gateway': {
|
||||
'tunnel_outside_address': {'ip_address': '1.2.3.4'}},
|
||||
'vpn_gateway': {
|
||||
'tunnel_outside_address': {'ip_address': '5.6.7.8'}},
|
||||
'ike': {'authentication_protocol': 'sha1-fake',
|
||||
'encryption_protocol': '3des',
|
||||
'lifetime': 1111,
|
||||
'perfect_forward_secrecy': 'group5',
|
||||
'mode': 'main-fake',
|
||||
'pre_shared_key': 'password'},
|
||||
'ipsec': {'protocol': 'ah-esp',
|
||||
'authentication_protocol': 'sha1-fake',
|
||||
'encryption_protocol': 'aes-256',
|
||||
'lifetime': 2222,
|
||||
'perfect_forward_secrecy': 'group14',
|
||||
'mode': 'transport',
|
||||
'tcp_mss_adjustment': 1400 - 40}}},
|
||||
matchers.IsSubDictOf(conf))
|
||||
|
||||
def test_stop_vpn_connection(self):
|
||||
# delete several connections
|
||||
os_conn_ids = [fakes.random_os_id() for _x in range(3)]
|
||||
|
|
Loading…
Reference in New Issue