lbaas on a network without gateway

Not only check the gateway_ip in subnet, but also
check the host_routes. If there is a default route in host_routes
then the next hop of the default route is also a gateway_ip.

Closes-Bug: 1300017
DocImpact

Change-Id: Id3ae04bfa6cefb1c030857894f0594828b8e856d
This commit is contained in:
LipingMao 2014-03-31 05:49:18 +00:00 committed by Liping Mao
parent 26182d6819
commit 4f4fef9c21
2 changed files with 45 additions and 0 deletions

View File

@ -257,6 +257,14 @@ class HaproxyNSDriver(agent_device_driver.AgentDeviceDriver):
self.vif_driver.init_l3(interface_name, cidrs, namespace=namespace) self.vif_driver.init_l3(interface_name, cidrs, namespace=namespace)
gw_ip = port['fixed_ips'][0]['subnet'].get('gateway_ip') gw_ip = port['fixed_ips'][0]['subnet'].get('gateway_ip')
if not gw_ip:
host_routes = port['fixed_ips'][0]['subnet'].get('host_routes', [])
for host_route in host_routes:
if host_route['destination'] == "0.0.0.0/0":
gw_ip = host_route['nexthop']
break
if gw_ip: if gw_ip:
cmd = ['route', 'add', 'default', 'gw', gw_ip] cmd = ['route', 'add', 'default', 'gw', gw_ip]
ip_wrapper = ip_lib.IPWrapper(self.root_helper, ip_wrapper = ip_lib.IPWrapper(self.root_helper,

View File

@ -322,6 +322,43 @@ class TestHaproxyNSDriver(base.BaseTestCase):
self.assertRaises(exceptions.PreexistingDeviceFailure, self.assertRaises(exceptions.PreexistingDeviceFailure,
self.driver._plug, 'test_ns', test_port, False) self.driver._plug, 'test_ns', test_port, False)
def test_plug_gw_in_host_routes(self):
test_port = {'id': 'port_id',
'network_id': 'net_id',
'mac_address': 'mac_addr',
'fixed_ips': [{'ip_address': '10.0.0.2',
'subnet': {'cidr': '10.0.0.0/24',
'host_routes':
[{'destination': '0.0.0.0/0',
'nexthop': '10.0.0.1'}]}}]}
with contextlib.nested(
mock.patch('neutron.agent.linux.ip_lib.device_exists'),
mock.patch('netaddr.IPNetwork'),
mock.patch('neutron.agent.linux.ip_lib.IPWrapper'),
) as (dev_exists, ip_net, ip_wrap):
self.vif_driver.get_device_name.return_value = 'test_interface'
dev_exists.return_value = False
ip_net.return_value = ip_net
ip_net.prefixlen = 24
self.driver._plug('test_ns', test_port)
self.rpc_mock.plug_vip_port.assert_called_once_with(
test_port['id'])
self.assertTrue(dev_exists.called)
self.vif_driver.plug.assert_called_once_with('net_id', 'port_id',
'test_interface',
'mac_addr',
namespace='test_ns')
self.vif_driver.init_l3.assert_called_once_with('test_interface',
['10.0.0.2/24'],
namespace=
'test_ns')
cmd = ['route', 'add', 'default', 'gw', '10.0.0.1']
ip_wrap.assert_has_calls([
mock.call('sudo_test', namespace='test_ns'),
mock.call().netns.execute(cmd, check_exit_code=False),
])
def test_unplug(self): def test_unplug(self):
self.vif_driver.get_device_name.return_value = 'test_interface' self.vif_driver.get_device_name.return_value = 'test_interface'