diff --git a/ovn_bgp_agent/drivers/openstack/utils/driver_utils.py b/ovn_bgp_agent/drivers/openstack/utils/driver_utils.py index e020f9ff..8e5cd756 100644 --- a/ovn_bgp_agent/drivers/openstack/utils/driver_utils.py +++ b/ovn_bgp_agent/drivers/openstack/utils/driver_utils.py @@ -59,3 +59,16 @@ def get_prefixes_from_ips(ips: 'list[str]') -> 'list[str]': return ['/'.join([ipaddress.ip_network(ip, strict=False)[0].compressed, ip.split('/')[-1]]) for ip in ips] + + +def remove_port_from_ip(ip_address): + last_colon_index = ip_address.rfind(':') + # no port + if last_colon_index == -1: + return ip_address + # check if right side from index is a digit, in positive case remove it. + # For IPv6 it will come on format [ipv6]:port, so will also remove + # correctly just only the port + if ip_address[last_colon_index + 1:].isdigit(): + return ip_address[:last_colon_index] + return ip_address diff --git a/ovn_bgp_agent/drivers/openstack/watchers/base_watcher.py b/ovn_bgp_agent/drivers/openstack/watchers/base_watcher.py index f1864e74..10e05de9 100644 --- a/ovn_bgp_agent/drivers/openstack/watchers/base_watcher.py +++ b/ovn_bgp_agent/drivers/openstack/watchers/base_watcher.py @@ -16,6 +16,7 @@ from oslo_log import log as logging from ovsdbapp.backend.ovs_idl import event as row_event from ovn_bgp_agent import constants +from ovn_bgp_agent.drivers.openstack.utils import driver_utils LOG = logging.getLogger(__name__) @@ -56,11 +57,32 @@ class OVNLBEvent(Event): except (AttributeError, KeyError): return - def _get_vip_fip(self, row): + def _get_ip_from_vips(self, row): + return [driver_utils.remove_port_from_ip(ipport) + for ipport in getattr(row, 'vips', {}).keys()] + + def _get_diff_ip_from_vips(self, new, old): + """Returns a list of IPs that are present in 'new' but not in 'old' + + Note: As LB VIP contains a port (e.g., '192.168.1.1:80'), the port part + is removed before comparison. + """ + return list(set(self._get_ip_from_vips(new)) - + set(self._get_ip_from_vips(old))) + + def _is_vip_or_fip(self, row, ip, key): try: - return row.external_ids[constants.OVN_LB_VIP_FIP_EXT_ID_KEY] - except (AttributeError, KeyError): - return + return ip == row.external_ids.get(key) + except AttributeError: + pass + + def _is_vip(self, row, ip): + return self._is_vip_or_fip(row, ip, constants.OVN_LB_VIP_IP_EXT_ID_KEY) + + def _is_fip(self, row, ip): + return self._is_vip_or_fip(row, + ip, + constants.OVN_LB_VIP_FIP_EXT_ID_KEY) class LSPChassisEvent(Event): diff --git a/ovn_bgp_agent/drivers/openstack/watchers/nb_bgp_watcher.py b/ovn_bgp_agent/drivers/openstack/watchers/nb_bgp_watcher.py index 2f1c3851..59010031 100644 --- a/ovn_bgp_agent/drivers/openstack/watchers/nb_bgp_watcher.py +++ b/ovn_bgp_agent/drivers/openstack/watchers/nb_bgp_watcher.py @@ -632,10 +632,14 @@ class OVNLBCreateEvent(base_watcher.OVNLBEvent): if lb_router not in self.agent.ovn_local_cr_lrps.keys(): return False - # Only expose if there is a modification in the VIPS - # And only expose if it is the first item on VIPs + # Expose if there is a modification in the VIPS, first new item ( + # that could happend with and non existing vips on old event or + # empty one) or additional items because a bigger row.vips is + # including old.vips if hasattr(old, 'vips'): - if not old.vips and row.vips: + if ((not old.vips and row.vips) or + (old.vips != row.vips and + set(old.vips.keys()).issubset(set(row.vips.keys())))): return True if hasattr(old, 'external_ids'): @@ -643,25 +647,28 @@ class OVNLBCreateEvent(base_watcher.OVNLBEvent): old_lb_router = self._get_router(old) if lb_router != old_lb_router: return True - # Also check if there is a vip_fip addition to expose the FIP - vip_fip = self._get_vip_fip(row) - if not vip_fip: - return False - old_vip_fip = self._get_vip_fip(old) - if vip_fip != old_vip_fip: - return True - except (IndexError, AttributeError): + except AttributeError: return False return False def _run(self, event, row, old): - vip_fip = self._get_vip_fip(row) - old_vip_fip = self._get_vip_fip(old) - with _SYNC_STATE_LOCK.read_lock(): - if hasattr(old, 'external_ids') and vip_fip != old_vip_fip: - self.agent.expose_ovn_lb_fip(row) - else: - self.agent.expose_ovn_lb_vip(row) + # vips field grows + diff = self._get_diff_ip_from_vips(row, old) + for ip in diff: + with _SYNC_STATE_LOCK.read_lock(): + if self._is_vip(row, ip): + self.agent.expose_ovn_lb_vip(row) + elif self._is_fip(row, ip): + self.agent.expose_ovn_lb_fip(row) + + # router set ext-gw + # NOTE(froyo): Not needed to check/call to expose_ovn_lb_fip, since up + # to this point this LB could not have been associated with a FIP + # since the subnet did not have access to the public network + if hasattr(old, 'external_ids'): + with _SYNC_STATE_LOCK.read_lock(): + if self._get_router(old) != self._get_router(row): + self.agent.expose_ovn_lb_vip(row) class OVNLBDeleteEvent(base_watcher.OVNLBEvent): @@ -685,9 +692,7 @@ class OVNLBDeleteEvent(base_watcher.OVNLBEvent): # ROW UPDATE EVENT lb_router = self._get_router(row) - old_external_ids = False if hasattr(old, 'external_ids'): - old_external_ids = True old_lb_router = self._get_router(old) if not old_lb_router: return False @@ -697,40 +702,44 @@ class OVNLBDeleteEvent(base_watcher.OVNLBEvent): # Router should not be removed, but if that is the case we # should remove the loadbalancer return True - # Also check if the vip_fip is removed to withdraw the FIP - vip_fip = self._get_vip_fip(row) - old_vip_fip = self._get_vip_fip(old) - if old_vip_fip and old_vip_fip != vip_fip: - return True - # Withdraw IP if VIPs is removed + # Whatever the change removing any field from vips should be manage if hasattr(old, 'vips'): - if old.vips and not row.vips: - if old_external_ids: - old_lb_router = self._get_router(old) - return (old_lb_router in - self.agent.ovn_local_cr_lrps.keys()) - else: - return (lb_router in - self.agent.ovn_local_cr_lrps.keys()) - except (IndexError, AttributeError): + if ((old.vips != row.vips and + set(row.vips.keys()).issubset( + set(old.vips.keys())))): + return True + except AttributeError: return False return False def _run(self, event, row, old): - vip_fip = self._get_vip_fip(row) - old_vip_fip = self._get_vip_fip(old) - with _SYNC_STATE_LOCK.read_lock(): - if event == self.ROW_DELETE: - self.agent.withdraw_ovn_lb_vip(row) - if vip_fip: - self.agent.withdraw_ovn_lb_fip(row) - else: - if not vip_fip and vip_fip != old_vip_fip: + # DELETE event need drop all + if event == self.ROW_DELETE: + diff = self._get_ip_from_vips(row) + for ip in diff: + with _SYNC_STATE_LOCK.read_lock(): + if self._is_vip(row, ip): + self.agent.withdraw_ovn_lb_vip(row) + elif self._is_fip(row, ip): + self.agent.withdraw_ovn_lb_fip(row) + return + + # UPDATE event + # vips field decrease + diff = self._get_diff_ip_from_vips(old, row) + for ip in diff: + with _SYNC_STATE_LOCK.read_lock(): + if self._is_vip(old, ip): + self.agent.withdraw_ovn_lb_vip(old) + elif self._is_fip(old, ip): self.agent.withdraw_ovn_lb_fip(old) - if hasattr(old, 'vips'): - self.agent.withdraw_ovn_lb_vip(row) + # router unset ext-gw + if hasattr(old, 'external_ids'): + with _SYNC_STATE_LOCK.read_lock(): + if self._get_router(old) != self._get_router(row): + self.agent.withdraw_ovn_lb_vip(old) class OVNPFBaseEvent(base_watcher.OVNLBEvent): diff --git a/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_base_watcher.py b/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_base_watcher.py index 429941a9..955cd921 100644 --- a/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_base_watcher.py +++ b/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_base_watcher.py @@ -69,12 +69,38 @@ class TestOVNLBEvent(test_base.TestCase): row = utils.create_row(external_ids={}) self.assertEqual(None, self.ovnlb_event._get_router(row)) - def test__get_vip_fip(self): + def test__is_vip(self): row = utils.create_row( - external_ids={constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip'}) - self.assertEqual('fip', self.ovnlb_event._get_vip_fip(row)) + external_ids={constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5'}, + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) + self.assertFalse(self.ovnlb_event._is_vip(row, '172.24.4.5')) + self.assertTrue(self.ovnlb_event._is_vip(row, '192.168.1.50')) row = utils.create_row(external_ids={}) - self.assertEqual(None, self.ovnlb_event._get_vip_fip(row)) + self.assertFalse(self.ovnlb_event._is_vip(row, '172.24.4.5')) + self.assertFalse(self.ovnlb_event._is_vip(row, '192.168.1.50')) + + def test__is_fip(self): + row = utils.create_row( + external_ids={constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5'}, + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) + self.assertTrue(self.ovnlb_event._is_fip(row, '172.24.4.5')) + self.assertFalse(self.ovnlb_event._is_fip(row, '192.168.1.50')) + row = utils.create_row(external_ids={}) + self.assertFalse(self.ovnlb_event._is_fip(row, '172.24.4.5')) + self.assertFalse(self.ovnlb_event._is_fip(row, '192.168.1.50')) + + def test__get_ip_from_vips(self): + row = utils.create_row( + external_ids={constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5'}, + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) + self.assertEqual(self.ovnlb_event._get_ip_from_vips(row), + ['192.168.1.50', '172.24.4.5']) class FakeLSPChassisEvent(base_watcher.LSPChassisEvent): diff --git a/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_nb_bgp_watcher.py b/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_nb_bgp_watcher.py index 3bc5deae..0166371a 100644 --- a/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_nb_bgp_watcher.py +++ b/ovn_bgp_agent/tests/unit/drivers/openstack/watchers/test_nb_bgp_watcher.py @@ -1,4 +1,3 @@ - # Copyright 2023 Red Hat, Inc. # All Rights Reserved. # @@ -1189,9 +1188,10 @@ class TestOVNLBCreateEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) old = utils.create_row(vips={}) self.assertTrue(self.event.match_fn(mock.Mock(), row, old)) @@ -1199,9 +1199,10 @@ class TestOVNLBCreateEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) old = utils.create_row(external_ids={}) self.assertTrue(self.event.match_fn(mock.Mock(), row, old)) @@ -1209,18 +1210,34 @@ class TestOVNLBCreateEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) - old = utils.create_row(external_ids={ - constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1'}) + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) + old = utils.create_row( + external_ids={ + constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1'}, + vips={'192.168.1.50:80': '192.168.1.100:80'}) self.assertTrue(self.event.match_fn(mock.Mock(), row, old)) + def test_match_fn_vips_no_change(self): + row = utils.create_row( + external_ids={ + constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', + constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) + old = utils.create_row( + external_ids={ + constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1'}) + self.assertFalse(self.event.match_fn(mock.Mock(), row, old)) + def test_match_fn_no_vips(self): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, vips={}) self.assertFalse(self.event.match_fn(mock.Mock(), row, mock.Mock())) @@ -1229,18 +1246,19 @@ class TestOVNLBCreateEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router2', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) self.assertFalse(self.event.match_fn(mock.Mock(), row, mock.Mock())) def test_run_vip(self): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) + vips={'192.168.1.50:80': '192.168.1.100:80'}) old = utils.create_row(vips={}) self.event.run(None, row, old) @@ -1248,19 +1266,37 @@ class TestOVNLBCreateEvent(test_base.TestCase): self.agent.expose_ovn_lb_vip.assert_called_once_with(row) self.agent.expose_ovn_lb_fip.assert_not_called() + def test_run_vip_and_fip(self): + row = utils.create_row( + external_ids={ + constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', + constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50', + constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) + old = utils.create_row(vips={}) + + self.event.run(None, row, old) + + self.agent.expose_ovn_lb_vip.assert_called_once_with(row) + self.agent.expose_ovn_lb_fip.assert_called_once_with(row) + def test_run_vip_added_router(self): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1', 'other': 'info'}, - vips={'vip': 'member', 'fip': 'member'}) + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) old = utils.create_row( external_ids={ - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', - constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}) - + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', + constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) self.event.run(None, row, old) self.agent.expose_ovn_lb_vip.assert_called_once_with(row) @@ -1270,9 +1306,10 @@ class TestOVNLBCreateEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) old = utils.create_row(external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1'}) @@ -1300,10 +1337,12 @@ class TestOVNLBDeleteEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, vips={}) - old = utils.create_row(vips={'vip': 'member', 'fip': 'member'}) + old = utils.create_row( + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) self.assertTrue(self.event.match_fn(mock.Mock(), row, old)) def test_match_fn_delete(self): @@ -1311,9 +1350,10 @@ class TestOVNLBDeleteEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) self.assertTrue(self.event.match_fn(event, row, mock.Mock())) def test_match_fn_delete_no_vips(self): @@ -1321,7 +1361,7 @@ class TestOVNLBDeleteEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, vips={}) self.assertFalse(self.event.match_fn(event, row, mock.Mock())) @@ -1331,17 +1371,19 @@ class TestOVNLBDeleteEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router2', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) self.assertFalse(self.event.match_fn(event, row, mock.Mock())) def test_match_fn_router_deleted(self): row = utils.create_row( external_ids={ - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) old = utils.create_row(external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1' }) @@ -1351,18 +1393,20 @@ class TestOVNLBDeleteEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) old = utils.create_row(external_ids={}) self.assertFalse(self.event.match_fn(mock.Mock(), row, old)) def test_match_fn_old_router_non_local(self): row = utils.create_row( external_ids={ - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) old = utils.create_row(external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router2', }) @@ -1372,41 +1416,48 @@ class TestOVNLBDeleteEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) - old = utils.create_row(external_ids={ - constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip'}) + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', + constants.OVN_LS_NAME_EXT_ID_KEY: 'net1', + constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50'}, + vips={'192.168.1.50:80': '192.168.1.100:80'}) + old = utils.create_row( + external_ids={ + constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', + constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50'}, + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) self.assertTrue(self.event.match_fn(mock.Mock(), row, old)) def test_match_fn_vip_deleted_with_ext_id_update(self): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, vips={}) old = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1', - 'other': 'info'}, - vips={'vip': 'member', 'fip': 'member'}) + constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50'}, + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) self.assertTrue(self.event.match_fn(mock.Mock(), row, old)) - def test_run_vip(self): + def test_run_vip_delete_without_external_ids_on_old(self): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, vips={}) - old = utils.create_row(vips={'vip': 'member'}) + old = utils.create_row(vips={'192.168.1.50:80': '192.168.1.100:80'}) self.event.run(None, row, old) - self.agent.withdraw_ovn_lb_vip.assert_called_once_with(row) + self.agent.withdraw_ovn_lb_vip.assert_not_called() self.agent.withdraw_ovn_lb_fip.assert_not_called() def test_run_vip_delete(self): @@ -1414,43 +1465,47 @@ class TestOVNLBDeleteEvent(test_base.TestCase): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', - constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={}) - + constants.OVN_LS_NAME_EXT_ID_KEY: 'net1', + constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50'}, + vips={'192.168.1.50:80': '192.168.1.100:80'}) self.event.run(event, row, None) self.agent.withdraw_ovn_lb_vip.assert_called_once_with(row) - self.agent.withdraw_ovn_lb_fip.assert_called_once_with(row) def test_run_vip_deleted_extra_ext_id_info(self): - row = utils.create_row( - external_ids={ - constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', - constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) old = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', + constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50', + constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) + row = utils.create_row( + external_ids={ + constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1', - 'other': 'info'}) + 'other': 'info'}, + vips={}) self.event.run(None, row, old) - self.agent.withdraw_ovn_lb_vip.assert_not_called() - self.agent.withdraw_ovn_lb_fip.assert_not_called() + self.agent.withdraw_ovn_lb_vip.assert_called_once_with(old) + self.agent.withdraw_ovn_lb_fip.assert_called_once_with(old) def test_run_fip(self): row = utils.create_row( external_ids={ constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', constants.OVN_LS_NAME_EXT_ID_KEY: 'net1'}, - vips={'vip': 'member', 'fip': 'member'}) - old = utils.create_row(external_ids={ - constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', - constants.OVN_LB_VIP_FIP_EXT_ID_KEY: 'fip'}) + vips={'192.168.1.50:80': '192.168.1.100:80'}) + old = utils.create_row( + external_ids={ + constants.OVN_LB_LR_REF_EXT_ID_KEY: 'neutron-router1', + constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5'}, + vips={'192.168.1.50:80': '192.168.1.100:80', + '172.24.4.5:80': '192.168.1.100:80'}) self.event.run(None, row, old)