diff --git a/quantum/plugins/services/agent_loadbalancer/drivers/haproxy/namespace_driver.py b/quantum/plugins/services/agent_loadbalancer/drivers/haproxy/namespace_driver.py index d262b2322..a266ae4c0 100644 --- a/quantum/plugins/services/agent_loadbalancer/drivers/haproxy/namespace_driver.py +++ b/quantum/plugins/services/agent_loadbalancer/drivers/haproxy/namespace_driver.py @@ -178,6 +178,13 @@ class HaproxyNSDriver(object): ] self.vif_driver.init_l3(interface_name, cidrs, namespace=namespace) + gw_ip = port['fixed_ips'][0]['subnet'].get('gateway_ip') + if gw_ip: + cmd = ['route', 'add', 'default', 'gw', gw_ip] + ip_wrapper = ip_lib.IPWrapper(self.root_helper, + namespace=namespace) + ip_wrapper.netns.execute(cmd, check_exit_code=False) + def _unplug(self, namespace, port_id): port_stub = {'id': port_id} self.vip_plug_callback('unplug', port_stub) diff --git a/quantum/tests/unit/services/agent_loadbalancer/driver/haproxy/test_namespace_driver.py b/quantum/tests/unit/services/agent_loadbalancer/driver/haproxy/test_namespace_driver.py index b7cb98042..0a3471cc6 100644 --- a/quantum/tests/unit/services/agent_loadbalancer/driver/haproxy/test_namespace_driver.py +++ b/quantum/tests/unit/services/agent_loadbalancer/driver/haproxy/test_namespace_driver.py @@ -186,11 +186,13 @@ class TestHaproxyNSDriver(base.BaseTestCase): 'network_id': 'net_id', 'mac_address': 'mac_addr', 'fixed_ips': [{'ip_address': '10.0.0.2', - 'subnet': {'cidr': 'cidr'}}]} + 'subnet': {'cidr': '10.0.0.0/24', + 'gateway_ip': '10.0.0.1'}}]} with contextlib.nested( mock.patch('quantum.agent.linux.ip_lib.device_exists'), mock.patch('netaddr.IPNetwork'), - ) as (dev_exists, ip_net): + mock.patch('quantum.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 @@ -207,11 +209,48 @@ class TestHaproxyNSDriver(base.BaseTestCase): ['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', namespace='test_ns'), + mock.call().netns.execute(cmd, check_exit_code=False), + ]) dev_exists.return_value = True self.assertRaises(exceptions.PreexistingDeviceFailure, self.driver._plug, 'test_ns', test_port, False) + def test_plug_no_gw(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'}}]} + with contextlib.nested( + mock.patch('quantum.agent.linux.ip_lib.device_exists'), + mock.patch('netaddr.IPNetwork'), + mock.patch('quantum.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.vip_plug_callback.assert_called_once_with('plug', test_port) + 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') + self.assertFalse(ip_wrap.called) + dev_exists.return_value = True + self.assertRaises(exceptions.PreexistingDeviceFailure, + self.driver._plug, 'test_ns', test_port, False) + def test_unplug(self): self.vif_driver.get_device_name.return_value = 'test_interface'