[OVN] Update lsp host id when cr port is updated with chassis

When a chassisredirect port is updated with chassis, the
PortBindingChassisEvent event would only update the binding
host id in the neutron database, while it is also usefull to keep the
information in the OVN database up to date with the host information.

Similar to change [1], but for router's gateway ports.

[1] https://review.opendev.org/c/openstack/neutron/+/896883

Other plugins that connect to the OVN database can then also rely on the
information stored in the OVN DB's

Closes-Bug: #2083832

Change-Id: Ibe8bda2f81bda7a89e3a994db55cd394a18decb8
(cherry picked from commit 4b032bdbb2a6843b776c367486d1620ea6ae71a5)
This commit is contained in:
Aleksandr 2024-10-07 13:06:59 +03:00 committed by Rodolfo Alonso Hernandez
parent 32ef705e5b
commit e900e9923c
2 changed files with 35 additions and 2 deletions

View File

@ -250,7 +250,18 @@ class OVNL3RouterPlugin(service_base.ServicePluginBase,
port = self._plugin.update_port(
context, port['id'],
{'port': {portbindings.HOST_ID: host}})
# Updates OVN NB database with hostname for lsp router
# gateway port
with self._nb_ovn.transaction(check_error=True) as txn:
ext_ids = (
"external_ids",
{ovn_const.OVN_HOST_ID_EXT_ID_KEY: host},
)
txn.add(
self._nb_ovn.db_set(
"Logical_Switch_Port", port["id"], ext_ids
)
)
if port['status'] != status:
self._plugin.update_port_status(context, port['id'], status)

View File

@ -529,6 +529,12 @@ class TestRouter(base.TestOVNFunctionalBase):
# hosted in any chassis.
self.assertGreaterEqual(plugin_select.call_count, 2)
def _find_port_binding(self, port_id):
cmd = self.sb_api.db_find_rows('Port_Binding',
('logical_port', '=', port_id))
rows = cmd.execute(check_error=True)
return rows[0] if rows else None
def test_router_gateway_port_binding_host_id(self):
# Test setting chassis on chassisredirect port in Port_Binding table,
# will update host_id of corresponding router gateway port
@ -551,14 +557,30 @@ class TestRouter(base.TestOVNFunctionalBase):
may_exist=True).execute(check_error=True)
def check_port_binding_host_id(port_id):
# Get port from Neutron DB
port = core_plugin.get_ports(
self.context, filters={'id': [port_id]})[0]
return port[portbindings.HOST_ID] == host_id
# Get port from OVN DB
bp = self._find_port_binding(port_id)
ovn_host_id = bp.external_ids.get(ovn_const.OVN_HOST_ID_EXT_ID_KEY)
return port[portbindings.HOST_ID] == host_id == ovn_host_id
# Test if router gateway port updated with this chassis
n_utils.wait_until_true(lambda: check_port_binding_host_id(
gw_port_id))
# Simulate failover to another chassis and check host_id in Neutron DB
# and external_ids:neutron:host_id in OVN DB are updated
chassis = idlutils.row_by_value(
self.sb_api.idl, "Chassis", "name", self.chassis2
)
host_id = chassis.hostname
self.sb_api.lsp_unbind(logical_port).execute(check_error=True)
self.sb_api.lsp_bind(logical_port, self.chassis2).execute(
check_error=True
)
n_utils.wait_until_true(lambda: check_port_binding_host_id(gw_port_id))
def _validate_router_ipv6_ra_configs(self, lrp_name, expected_ra_confs):
lrp = idlutils.row_by_value(self.nb_api.idl,
'Logical_Router_Port', 'name', lrp_name)