When using L3 HA and keepalived neutron is no longer directly managing
the floating IP addresses itself. Neutron should not check against
which addresses are currently configured on the system, but the
addresses the keepalived object has configured.
Co-Authored-By: Benoit Page-Guitard <benoit.page@gmail.com>
Change-Id: I56045ede3a3dc1a7044a22913ee38ed382a81052
Closes-Bug: #
1400217
if ri.router['distributed']:
self.floating_ip_removed_dist(ri, ip_cidr)
+ def _get_router_cidrs(self, ri, device):
+ if ri.is_ha:
+ return set(self._ha_get_existing_cidrs(ri, device.name))
+ else:
+ return set([addr['cidr'] for addr in device.addr.list()])
+
def process_router_floating_ip_addresses(self, ri, ex_gw_port):
"""Configure IP addresses on router's external gateway interface.
device = ip_lib.IPDevice(interface_name, self.root_helper,
namespace=ri.ns_name)
- existing_cidrs = set([addr['cidr'] for addr in device.addr.list()])
+ existing_cidrs = self._get_router_cidrs(ri, device)
new_cidrs = set()
# Loop once to ensure that floating ips are configured.
instance = ri.keepalived_manager.config.get_instance(ri.ha_vr_id)
instance.remove_vips_vroutes_by_interface(interface)
+ def _ha_get_existing_cidrs(self, ri, interface_name):
+ instance = ri.keepalived_manager.config.get_instance(ri.ha_vr_id)
+ return instance.get_existing_vip_ip_addresses(interface_name)
+
def _add_keepalived_notifiers(self, ri):
callback = (
metadata_driver.MetadataDriver._get_metadata_proxy_callback(
self.vips = [vip for vip in self.vips
if vip.ip_address != ip_address]
+ def get_existing_vip_ip_addresses(self, interface_name):
+ return [vip.ip_address for vip in self.vips
+ if vip.interface_name == interface_name]
+
def _build_track_interface_config(self):
return itertools.chain(
[' track_interface {'],
config.reset()
self.assertEqual('', config.get_config_str())
+ def test_get_existing_vip_ip_addresses_returns_list(self):
+ config = self._get_config()
+ instance = config.get_instance(1)
+ current_vips = sorted(instance.get_existing_vip_ip_addresses('eth2'))
+ self.assertEqual(['192.168.2.0/24', '192.168.3.0/24'], current_vips)
+
class KeepalivedStateExceptionTestCase(base.BaseTestCase):
def test_state_exception(self):
)
self._test_process_router_floating_ip_addresses_add(ri, agent)
+ def test_get_router_cidrs_returns_cidrs(self):
+ agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+ ri = mock.MagicMock()
+ ri.is_ha = False
+ addresses = ['15.1.2.2/24', '15.1.2.3/32']
+ device = mock.MagicMock()
+ device.addr.list.return_value = [{'cidr': addresses[0]},
+ {'cidr': addresses[1]}]
+ self.assertEqual(set(addresses), agent._get_router_cidrs(ri, device))
+
+ def test_get_router_cidrs_returns_ha_cidrs(self):
+ agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+ ri = mock.MagicMock()
+ ri.is_ha = True
+ device = mock.MagicMock()
+ device.name.return_value = 'eth2'
+ addresses = ['15.1.2.2/24', '15.1.2.3/32']
+ agent._ha_get_existing_cidrs = mock.MagicMock()
+ agent._ha_get_existing_cidrs.return_value = addresses
+ self.assertEqual(set(addresses), agent._get_router_cidrs(ri, device))
+
# TODO(mrsmith): refactor for DVR cases
@mock.patch('neutron.agent.linux.ip_lib.IPDevice')
def test_process_router_floating_ip_addresses_remove(self, IPDevice):