From 65393c2c3cbbb142685965ee1f4177e0c2f0893e Mon Sep 17 00:00:00 2001 From: Aaron Rosen Date: Mon, 1 Apr 2013 15:26:12 -0700 Subject: [PATCH] Fix lb-vip does not get route to default gw Previously when creating a lb-vip it would be created without a default gw. This patch fixes that and adds unit tests to check that route add is called if the subnet has a gateway_ip. Fixes bug 1162626 Change-Id: I155749fa6d9c843fca87a73f3cf85720aac26cfa (cherry picked from commit 37b41833bf4f9500ee6be53d15298d0f4b964ea3) --- .../drivers/haproxy/namespace_driver.py | 7 +++ .../driver/haproxy/test_namespace_driver.py | 43 ++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) 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 d262b23224..a266ae4c0c 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 b7cb98042c..0a3471cc6c 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'