vmware-nsx/vmware_nsx/tests/unit/services/dynamic_routing/test_nsxv_bgp_driver.py

308 lines
13 KiB
Python

# Copyright 2017 VMware, Inc.
# All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import contextlib
import mock
from neutron.api import extensions
from neutron_dynamic_routing.db import bgp_db # noqa
from neutron_dynamic_routing import extensions as dr_extensions
from neutron_dynamic_routing.extensions import bgp as ext_bgp
from neutron_dynamic_routing.tests.unit.db import test_bgp_db
from neutron_lib.api.definitions import address_scope
from neutron_lib import context
from neutron_lib import exceptions as n_exc
from neutron_lib.plugins import directory
from vmware_nsx.common import exceptions as exc
from vmware_nsx.db import nsxv_db
from vmware_nsx.plugins.nsx_v.drivers import (
shared_router_driver as router_driver)
from vmware_nsx.services.dynamic_routing import bgp_plugin
from vmware_nsx.services.dynamic_routing.nsx_v import driver as bgp_driver
from vmware_nsx.tests.unit.nsx_v import test_plugin
BGP_PLUGIN = 'vmware_nsx.services.dynamic_routing.bgp_plugin.NSXvBgpPlugin'
class TestNSXvBgpPlugin(test_plugin.NsxVPluginV2TestCase,
test_bgp_db.BgpTests):
def setUp(self):
extensions.append_api_extensions_path(dr_extensions.__path__)
service_plugins = {ext_bgp.BGP_EXT_ALIAS: BGP_PLUGIN}
super(TestNSXvBgpPlugin, self).setUp(service_plugins=service_plugins)
self.bgp_plugin = bgp_plugin.NSXvBgpPlugin()
self.nsxv_driver = self.bgp_plugin.drivers['nsx-v']
self.nsxv_driver._validate_gateway_network = mock.Mock()
self.nsxv_driver._validate_bgp_configuration_on_peer_esg = (
mock.Mock())
self.plugin = directory.get_plugin()
self.l3plugin = self.plugin
self.plugin.init_is_complete = True
self.context = context.get_admin_context()
self.project_id = 'dummy_project'
@contextlib.contextmanager
def gw_network(self, external=True, **kwargs):
with super(TestNSXvBgpPlugin, self).gw_network(external=external,
**kwargs) as gw_net:
if external:
gw_net['network']['router:external'] = True
gw_net['network'][address_scope.IPV4_ADDRESS_SCOPE] = True
yield gw_net
@contextlib.contextmanager
def subnet(self, network=None, **kwargs):
if network and network['network'].get('router:external'):
kwargs['gateway_ip'] = None
kwargs['enable_dhcp'] = False
with super(TestNSXvBgpPlugin, self).subnet(network=network,
**kwargs) as sub:
yield sub
@contextlib.contextmanager
def router(self, **kwargs):
if 'external_gateway_info' in kwargs:
kwargs['external_gateway_info']['enable_snat'] = False
with super(TestNSXvBgpPlugin, self).router(**kwargs) as r:
yield r
@contextlib.contextmanager
def esg_bgp_peer(self, esg_id):
data = {'name': '',
'peer_ip': '192.168.1.10',
'remote_as': '65000',
'esg_id': esg_id,
'auth_type': 'none',
'password': '',
'tenant_id': self.project_id}
bgp_peer = self.bgp_plugin.create_bgp_peer(self.context,
{'bgp_peer': data})
yield bgp_peer
self.bgp_plugin.delete_bgp_peer(self.context, bgp_peer['id'])
@contextlib.contextmanager
def bgp_speaker(self, ip_version, local_as, name='my-speaker',
advertise_fip_host_routes=True,
advertise_tenant_networks=True,
networks=None, peers=None):
data = {'ip_version': ip_version,
test_bgp_db.ADVERTISE_FIPS_KEY: advertise_fip_host_routes,
'advertise_tenant_networks': advertise_tenant_networks,
'local_as': local_as, 'name': name,
'tenant_id': self.project_id}
bgp_speaker = self.bgp_plugin.create_bgp_speaker(self.context,
{'bgp_speaker': data})
bgp_speaker_id = bgp_speaker['id']
if networks:
for network_id in networks:
self.bgp_plugin.add_gateway_network(
self.context,
bgp_speaker_id,
{'network_id': network_id})
if peers:
for peer_id in peers:
self.bgp_plugin.add_bgp_peer(self.context, bgp_speaker_id,
{'bgp_peer_id': peer_id})
yield self.bgp_plugin.get_bgp_speaker(self.context, bgp_speaker_id)
def test_create_v6_bgp_speaker(self):
fake_bgp_speaker = {
"bgp_speaker": {
"ip_version": 6,
"local_as": "1000",
"name": "bgp-speaker",
"tenant_id": self.project_id
}
}
self.assertRaises(n_exc.InvalidInput,
self.bgp_plugin.create_bgp_speaker,
self.context, fake_bgp_speaker)
def test_create_v6_bgp_peer(self):
fake_bgp_peer = {
"bgp_peer": {
"auth_type": "none",
"remote_as": "1000",
"name": "bgp-peer",
"peer_ip": "fc00::/7",
"tenant_id": self.project_id
}
}
self.assertRaises(n_exc.InvalidInput,
self.bgp_plugin.create_bgp_peer,
self.context, fake_bgp_peer)
def test_bgp_peer_esg_id(self):
edge_id = 'edge-123'
with self.esg_bgp_peer(esg_id='edge-123') as esg_peer:
self.assertEqual(edge_id, esg_peer['esg_id'])
peer_id = esg_peer['id']
bgp_peer = self.bgp_plugin.get_bgp_peer(self.context, peer_id)
self.assertEqual(edge_id, bgp_peer['esg_id'])
def test_create_bgp_peer_md5_auth_no_password(self):
bgp_peer = {'bgp_peer':
{'auth_type': 'md5', 'password': None,
'peer_ip': '10.0.0.3',
'tenant_id': self.project_id}}
self.assertRaises(ext_bgp.InvalidBgpPeerMd5Authentication,
self.bgp_plugin.create_bgp_peer,
self.context, bgp_peer)
def test_add_non_external_gateway_network(self):
self.nsxv_driver._validate_gateway_network = (
bgp_driver.NSXvBgpDriver(
self.bgp_plugin)._validate_gateway_network)
with self.gw_network(external=False) as net,\
self.subnetpool_with_address_scope(4,
prefixes=['8.0.0.0/8']) as sp:
network_id = net['network']['id']
with self.bgp_speaker(sp['ip_version'], 1234) as speaker:
self.assertRaises(exc.NsxBgpNetworkNotExternal,
self.bgp_plugin.add_gateway_network,
self.context, speaker['id'],
{'network_id': network_id})
@mock.patch.object(nsxv_db, 'get_nsxv_bgp_speaker_binding',
return_value={'bgp_identifier': '10.0.0.11'})
def test_shared_router_on_gateway_clear(self, m1):
with self.gw_network(external=True) as net,\
self.subnetpool_with_address_scope(4,
prefixes=['10.0.0.0/24']) as sp:
with self.subnet(network=net,
subnetpool_id=sp['id']) as s1,\
self.bgp_speaker(sp['ip_version'], 1234,
networks=[net['network']['id']]):
subnet_id = s1['subnet']['id']
gw_info1 = {'network_id': net['network']['id'],
'external_fixed_ips': [{'ip_address': '10.0.0.11',
'subnet_id': subnet_id}]}
gw_info2 = {'network_id': net['network']['id'],
'external_fixed_ips': [{'ip_address': '10.0.0.12',
'subnet_id': subnet_id}]}
router_obj = router_driver.RouterSharedDriver(self.plugin)
with mock.patch.object(self.plugin, '_find_router_driver',
return_value=router_obj):
with self.router(external_gateway_info=gw_info1) as rtr1,\
self.router(external_gateway_info=gw_info2) as rtr2,\
mock.patch.object(
self.nsxv_driver, '_get_router_edge_info',
return_value=('edge-1', False)),\
mock.patch.object(
self.plugin.edge_manager,
'get_routers_on_same_edge',
return_value=[rtr1['id'], rtr2['id']]),\
mock.patch.object(
self.nsxv_driver,
'_update_edge_bgp_identifier') as up_bgp:
gw_clear = {u'router': {u'external_gateway_info': {}}}
self.plugin.update_router(self.context,
rtr1['id'],
gw_clear)
up_bgp.assert_called_once_with(mock.ANY,
mock.ANY,
mock.ANY,
'10.0.0.12')
def test__bgp_speakers_for_gateway_network_by_ip_version(self):
# REVISIT(roeyc): Base class test use ipv6 which is not supported.
pass
def test__bgp_speakers_for_gateway_network_by_ip_version_no_binding(self):
# REVISIT(roeyc): Base class test use ipv6 which is not supported.
pass
def test__tenant_prefixes_by_router_no_gateway_port(self):
# REVISIT(roeyc): Base class test use ipv6 which is not supported.
pass
def test_all_routes_by_bgp_speaker_different_tenant_address_scope(self):
# REVISIT(roeyc): Base class test use ipv6 which is not supported.
pass
def test__get_address_scope_ids_for_bgp_speaker(self):
pass
def test__get_dvr_fip_host_routes_by_binding(self):
pass
def test__get_dvr_fip_host_routes_by_router(self):
pass
def test__get_fip_next_hop_dvr(self):
pass
def test__get_fip_next_hop_legacy(self):
pass
def test_get_routes_by_bgp_speaker_id_with_fip_dvr(self):
pass
def test_ha_router_fips_has_no_next_hop_to_fip_agent_gateway(self):
pass
def test_legacy_router_fips_has_no_next_hop_to_fip_agent_gateway(self):
pass
def test_floatingip_update_callback(self):
pass
def test_get_ipv6_tenant_subnet_routes_by_bgp_speaker_ipv6(self):
pass
def test_get_routes_by_bgp_speaker_id_with_fip(self):
# base class tests uses no-snat router with floating ips
self.skipTest('No SNAT with floating ips not supported')
def test_get_routes_by_bgp_speaker_binding_with_fip(self):
# base class tests uses no-snat router with floating ips
self.skipTest('No SNAT with floating ips not supported')
def test__get_routes_by_router_with_fip(self):
# base class tests uses no-snat router with floating ips
self.skipTest('No SNAT with floating ips not supported')
def test_get_external_networks_for_port_same_address_scope_v6(self):
self.skipTest('No IPv6 support')
def test_get_external_networks_for_port_different_address_scope_v6(self):
self.skipTest('No IPv6 support')
def test__get_dvr_fixed_ip_routes_by_bgp_speaker_different_scope(self):
self.skipTest('Not supported')
def test_get_external_networks_for_port_different_address_scope_v4(self):
self.skipTest('Not supported')
def test__get_dvr_fixed_ip_routes_by_bgp_speaker_no_scope(self):
self.skipTest('Not supported')
def test__get_dvr_fixed_ip_routes_by_bgp_speaker_same_scope(self):
self.skipTest('Not supported')
def test_add_bgp_peer_with_bad_id(self):
with self.subnetpool_with_address_scope(
4, prefixes=['8.0.0.0/8']) as sp:
with self.bgp_speaker(sp['ip_version'], 1234) as speaker:
self.assertRaises(ext_bgp.BgpPeerNotFound,
self.bgp_plugin.add_bgp_peer,
self.context,
speaker['id'],
{'bgp_peer_id': 'aaa'})