Merge "Implement "RouterInfo.update_routing_table" with Pyroute2"
This commit is contained in:
commit
82339b9211
@ -230,8 +230,7 @@ class DvrEdgeRouter(dvr_local_router.DvrLocalRouter):
|
||||
# NOTE: For now let us apply the static routes both in SNAT
|
||||
# namespace and Router Namespace, to reduce the complexity.
|
||||
if self.snat_namespace.exists():
|
||||
super(DvrEdgeRouter, self)._update_routing_table(
|
||||
operation, route, namespace=ns_name)
|
||||
self._update_routing_table(operation, route, ns_name)
|
||||
else:
|
||||
LOG.error("The SNAT namespace %s does not exist for "
|
||||
"the router.", ns_name)
|
||||
|
@ -20,6 +20,7 @@ from neutron_lib import constants as lib_constants
|
||||
from neutron_lib.exceptions import l3 as l3_exc
|
||||
from neutron_lib.utils import helpers
|
||||
from oslo_log import log as logging
|
||||
from pyroute2.netlink import exceptions as pyroute2_exc
|
||||
|
||||
from neutron._i18n import _
|
||||
from neutron.agent.l3 import namespaces
|
||||
@ -173,10 +174,12 @@ class RouterInfo(BaseRouterInfo):
|
||||
return True
|
||||
|
||||
def _update_routing_table(self, operation, route, namespace):
|
||||
cmd = ['ip', 'route', operation, 'to', route['destination'],
|
||||
'via', route['nexthop']]
|
||||
ip_wrapper = ip_lib.IPWrapper(namespace=namespace)
|
||||
ip_wrapper.netns.execute(cmd, check_exit_code=False)
|
||||
method = (ip_lib.add_ip_route if operation == 'replace' else
|
||||
ip_lib.delete_ip_route)
|
||||
try:
|
||||
method(namespace, route['destination'], via=route['nexthop'])
|
||||
except (RuntimeError, OSError, pyroute2_exc.NetlinkError):
|
||||
pass
|
||||
|
||||
def update_routing_table(self, operation, route):
|
||||
self._update_routing_table(operation, route, self.ns_name)
|
||||
|
@ -37,13 +37,20 @@ class TestRouterInfo(base.BaseTestCase):
|
||||
ip_cls = self.ip_cls_p.start()
|
||||
self.mock_ip = mock.MagicMock()
|
||||
ip_cls.return_value = self.mock_ip
|
||||
self.mock_add_ip_route = mock.patch.object(
|
||||
ip_lib, 'add_ip_route').start()
|
||||
self.mock_delete_ip_route = mock.patch.object(
|
||||
ip_lib, 'delete_ip_route').start()
|
||||
self.ri_kwargs = {'agent_conf': conf,
|
||||
'interface_driver': mock.sentinel.interface_driver}
|
||||
|
||||
def _check_agent_method_called(self, calls):
|
||||
self.mock_ip.netns.execute.assert_has_calls(
|
||||
[mock.call(call, check_exit_code=False) for call in calls],
|
||||
any_order=True)
|
||||
def _check_agent_method_called(self, router, action_calls):
|
||||
for action, calls in action_calls.items():
|
||||
mock_calls = [mock.call(router.ns_name, c[0], via=c[1])
|
||||
for c in calls]
|
||||
mock_method = (self.mock_add_ip_route if action == 'replace' else
|
||||
self.mock_delete_ip_route)
|
||||
mock_method.assert_has_calls(mock_calls, any_order=True)
|
||||
|
||||
def test_routing_table_update(self):
|
||||
ri = router_info.RouterInfo(mock.Mock(), _uuid(), {}, **self.ri_kwargs)
|
||||
@ -55,24 +62,20 @@ class TestRouterInfo(base.BaseTestCase):
|
||||
'nexthop': '1.2.3.4'}
|
||||
|
||||
ri.update_routing_table('replace', fake_route1)
|
||||
expected = [['ip', 'route', 'replace', 'to', '135.207.0.0/16',
|
||||
'via', '1.2.3.4']]
|
||||
self._check_agent_method_called(expected)
|
||||
expected = {'replace': [('135.207.0.0/16', '1.2.3.4')]}
|
||||
self._check_agent_method_called(ri, expected)
|
||||
|
||||
ri.update_routing_table('delete', fake_route1)
|
||||
expected = [['ip', 'route', 'delete', 'to', '135.207.0.0/16',
|
||||
'via', '1.2.3.4']]
|
||||
self._check_agent_method_called(expected)
|
||||
expected = {'delete': [('135.207.0.0/16', '1.2.3.4')]}
|
||||
self._check_agent_method_called(ri, expected)
|
||||
|
||||
ri.update_routing_table('replace', fake_route2)
|
||||
expected = [['ip', 'route', 'replace', 'to', '135.207.111.111/32',
|
||||
'via', '1.2.3.4']]
|
||||
self._check_agent_method_called(expected)
|
||||
expected = {'replace': [('135.207.111.111/32', '1.2.3.4')]}
|
||||
self._check_agent_method_called(ri, expected)
|
||||
|
||||
ri.update_routing_table('delete', fake_route2)
|
||||
expected = [['ip', 'route', 'delete', 'to', '135.207.111.111/32',
|
||||
'via', '1.2.3.4']]
|
||||
self._check_agent_method_called(expected)
|
||||
expected = {'delete': [('135.207.111.111/32', '1.2.3.4')]}
|
||||
self._check_agent_method_called(ri, expected)
|
||||
|
||||
def test_update_routing_table(self):
|
||||
# Just verify the correct namespace was used in the call
|
||||
@ -103,28 +106,22 @@ class TestRouterInfo(base.BaseTestCase):
|
||||
ri.router['routes'] = fake_new_routes
|
||||
ri.routes_updated(fake_old_routes, fake_new_routes)
|
||||
|
||||
expected = [['ip', 'route', 'replace', 'to', '110.100.30.0/24',
|
||||
'via', '10.100.10.30'],
|
||||
['ip', 'route', 'replace', 'to', '110.100.31.0/24',
|
||||
'via', '10.100.10.30']]
|
||||
|
||||
self._check_agent_method_called(expected)
|
||||
expected = {'replace': [('110.100.30.0/24', '10.100.10.30'),
|
||||
('110.100.31.0/24', '10.100.10.30')]}
|
||||
self._check_agent_method_called(ri, expected)
|
||||
ri.routes = fake_new_routes
|
||||
fake_new_routes = [{'destination': "110.100.30.0/24",
|
||||
'nexthop': "10.100.10.30"}]
|
||||
ri.router['routes'] = fake_new_routes
|
||||
ri.routes_updated(ri.routes, fake_new_routes)
|
||||
expected = [['ip', 'route', 'delete', 'to', '110.100.31.0/24',
|
||||
'via', '10.100.10.30']]
|
||||
|
||||
self._check_agent_method_called(expected)
|
||||
expected = {'delete': [('110.100.31.0/24', '10.100.10.30')]}
|
||||
self._check_agent_method_called(ri, expected)
|
||||
fake_new_routes = []
|
||||
ri.router['routes'] = fake_new_routes
|
||||
ri.routes_updated(ri.routes, fake_new_routes)
|
||||
|
||||
expected = [['ip', 'route', 'delete', 'to', '110.100.30.0/24',
|
||||
'via', '10.100.10.30']]
|
||||
self._check_agent_method_called(expected)
|
||||
expected = {'delete': [('110.100.30.0/24', '10.100.10.30')]}
|
||||
self._check_agent_method_called(ri, expected)
|
||||
|
||||
def test__process_pd_iptables_rules(self):
|
||||
subnet_id = _uuid()
|
||||
|
Loading…
Reference in New Issue
Block a user