Merge "Preserve floating ips when initializing l3 gateway interface"
This commit is contained in:
commit
771646884d
@ -534,8 +534,17 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, manager.Manager):
|
|||||||
bridge=self.conf.external_network_bridge,
|
bridge=self.conf.external_network_bridge,
|
||||||
namespace=ri.ns_name(),
|
namespace=ri.ns_name(),
|
||||||
prefix=EXTERNAL_DEV_PREFIX)
|
prefix=EXTERNAL_DEV_PREFIX)
|
||||||
|
|
||||||
|
# Compute a list of addresses this router is supposed to have.
|
||||||
|
# This avoids unnecessarily removing those addresses and
|
||||||
|
# causing a momentarily network outage.
|
||||||
|
floating_ips = ri.router.get(l3_constants.FLOATINGIP_KEY, [])
|
||||||
|
preserve_ips = [ip['floating_ip_address'] + FLOATING_IP_CIDR_SUFFIX
|
||||||
|
for ip in floating_ips]
|
||||||
|
|
||||||
self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']],
|
self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']],
|
||||||
namespace=ri.ns_name())
|
namespace=ri.ns_name(),
|
||||||
|
preserve_ips=preserve_ips)
|
||||||
ip_address = ex_gw_port['ip_cidr'].split('/')[0]
|
ip_address = ex_gw_port['ip_cidr'].split('/')[0]
|
||||||
self._send_gratuitous_arp_packet(ri, interface_name, ip_address)
|
self._send_gratuitous_arp_packet(ri, interface_name, ip_address)
|
||||||
|
|
||||||
|
@ -71,10 +71,12 @@ class LinuxInterfaceDriver(object):
|
|||||||
self.conf = conf
|
self.conf = conf
|
||||||
self.root_helper = config.get_root_helper(conf)
|
self.root_helper = config.get_root_helper(conf)
|
||||||
|
|
||||||
def init_l3(self, device_name, ip_cidrs, namespace=None):
|
def init_l3(self, device_name, ip_cidrs, namespace=None,
|
||||||
|
preserve_ips=[]):
|
||||||
"""Set the L3 settings for the interface using data from the port.
|
"""Set the L3 settings for the interface using data from the port.
|
||||||
|
|
||||||
ip_cidrs: list of 'X.X.X.X/YY' strings
|
ip_cidrs: list of 'X.X.X.X/YY' strings
|
||||||
|
preserve_ips: list of ip cidrs that should not be removed from device
|
||||||
"""
|
"""
|
||||||
device = ip_lib.IPDevice(device_name,
|
device = ip_lib.IPDevice(device_name,
|
||||||
self.root_helper,
|
self.root_helper,
|
||||||
@ -96,7 +98,8 @@ class LinuxInterfaceDriver(object):
|
|||||||
|
|
||||||
# clean up any old addresses
|
# clean up any old addresses
|
||||||
for ip_cidr, ip_version in previous.items():
|
for ip_cidr, ip_version in previous.items():
|
||||||
device.addr.delete(ip_version, ip_cidr)
|
if ip_cidr not in preserve_ips:
|
||||||
|
device.addr.delete(ip_version, ip_cidr)
|
||||||
|
|
||||||
def check_bridge_exists(self, bridge):
|
def check_bridge_exists(self, bridge):
|
||||||
if not ip_lib.device_exists(bridge):
|
if not ip_lib.device_exists(bridge):
|
||||||
|
@ -167,12 +167,20 @@ class TestBasicRouterOperations(base.BaseTestCase):
|
|||||||
|
|
||||||
if action == 'add':
|
if action == 'add':
|
||||||
self.device_exists.return_value = False
|
self.device_exists.return_value = False
|
||||||
|
ri.router = mock.Mock()
|
||||||
|
ri.router.get.return_value = [{'floating_ip_address':
|
||||||
|
'192.168.1.34'}]
|
||||||
agent.external_gateway_added(ri, ex_gw_port,
|
agent.external_gateway_added(ri, ex_gw_port,
|
||||||
interface_name, internal_cidrs)
|
interface_name, internal_cidrs)
|
||||||
self.assertEqual(self.mock_driver.plug.call_count, 1)
|
self.assertEqual(self.mock_driver.plug.call_count, 1)
|
||||||
self.assertEqual(self.mock_driver.init_l3.call_count, 1)
|
self.assertEqual(self.mock_driver.init_l3.call_count, 1)
|
||||||
self.send_arp.assert_called_once_with(ri, interface_name,
|
self.send_arp.assert_called_once_with(ri, interface_name,
|
||||||
'20.0.0.30')
|
'20.0.0.30')
|
||||||
|
kwargs = {'preserve_ips': ['192.168.1.34/32'],
|
||||||
|
'namespace': 'qrouter-' + router_id}
|
||||||
|
self.mock_driver.init_l3.assert_called_with(interface_name,
|
||||||
|
['20.0.0.30/24'],
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
elif action == 'remove':
|
elif action == 'remove':
|
||||||
self.device_exists.return_value = True
|
self.device_exists.return_value = True
|
||||||
|
@ -94,6 +94,21 @@ class TestABCDriver(TestBase):
|
|||||||
mock.call().addr.add(4, '192.168.1.2/24', '192.168.1.255'),
|
mock.call().addr.add(4, '192.168.1.2/24', '192.168.1.255'),
|
||||||
mock.call().addr.delete(4, '172.16.77.240/24')])
|
mock.call().addr.delete(4, '172.16.77.240/24')])
|
||||||
|
|
||||||
|
def test_l3_init_with_preserve(self):
|
||||||
|
addresses = [dict(ip_version=4, scope='global',
|
||||||
|
dynamic=False, cidr='192.168.1.3/32')]
|
||||||
|
self.ip_dev().addr.list = mock.Mock(return_value=addresses)
|
||||||
|
|
||||||
|
bc = BaseChild(self.conf)
|
||||||
|
ns = '12345678-1234-5678-90ab-ba0987654321'
|
||||||
|
bc.init_l3('tap0', ['192.168.1.2/24'], namespace=ns,
|
||||||
|
preserve_ips=['192.168.1.3/32'])
|
||||||
|
self.ip_dev.assert_has_calls(
|
||||||
|
[mock.call('tap0', 'sudo', namespace=ns),
|
||||||
|
mock.call().addr.list(scope='global', filters=['permanent']),
|
||||||
|
mock.call().addr.add(4, '192.168.1.2/24', '192.168.1.255')])
|
||||||
|
self.assertFalse(self.ip_dev().addr.delete.called)
|
||||||
|
|
||||||
|
|
||||||
class TestOVSInterfaceDriver(TestBase):
|
class TestOVSInterfaceDriver(TestBase):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user