From 9562726b1b0c4fcd1b3279c1475ce81c64299b36 Mon Sep 17 00:00:00 2001 From: Slawek Kaplonski Date: Fri, 13 May 2022 11:56:02 +0200 Subject: [PATCH] [L3HA] Don't update HA router's ports if router isn't active on agents In case when HA router isn't active on any L3 agent, _ensure_host_set_on_port method shouldn't try to update port's host to the host from which there was an rpc message sent, as this can be host on which router is in the "standby" mode. This method should only update port's host to the router's "active_host" if there is such active_host found already. Depends-On: https://review.opendev.org/c/openstack/requirements/+/841489 Closes-Bug: #1973162 Closes-Bug: #1942190 Change-Id: Ib3945d294601b35f9b268c25841cd284b52c4ca3 (cherry picked from commit cd8bf18150c8b0a4bc64979d800726483d9cdb6e) --- neutron/api/rpc/handlers/l3_rpc.py | 17 ++++++++--------- neutron/tests/unit/db/test_l3_hamode_db.py | 12 +++++++++++- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/neutron/api/rpc/handlers/l3_rpc.py b/neutron/api/rpc/handlers/l3_rpc.py index 8702a91284a..16b8d2554a5 100644 --- a/neutron/api/rpc/handlers/l3_rpc.py +++ b/neutron/api/rpc/handlers/l3_rpc.py @@ -218,22 +218,21 @@ class L3RpcCallback(object): active_host = ( self.l3plugin.get_active_host_for_ha_router( context, router_id)) - if active_host: - host = active_host - # If there is currently no active router instance (For - # example it's a new router), the host that requested - # the routers (Essentially a random host) will do. The - # port binding will be corrected when an active is - # elected. + if not active_host: + LOG.debug("Router %(router)s is not active on any " + "host. Port %(port)s will not be updated " + "now.", + {'router': router_id, 'port': port['id']}) + return try: LOG.debug("Updating router %(router)s port %(port)s " "binding host %(host)s", {"router": router_id, "port": port['id'], - "host": host}) + "host": active_host}) self.plugin.update_port( context, port['id'], - {'port': {portbindings.HOST_ID: host}}) + {'port': {portbindings.HOST_ID: active_host}}) except exceptions.PortNotFound: LOG.debug("Port %(port)s not found while updating " "agent binding for router %(router)s.", diff --git a/neutron/tests/unit/db/test_l3_hamode_db.py b/neutron/tests/unit/db/test_l3_hamode_db.py index 0c052b7fde8..45cebbbb7c1 100644 --- a/neutron/tests/unit/db/test_l3_hamode_db.py +++ b/neutron/tests/unit/db/test_l3_hamode_db.py @@ -1304,9 +1304,19 @@ class L3HAModeDbTestCase(L3HATestFramework): self.plugin.list_active_sync_routers_on_active_l3_agent( self.admin_ctx, self.agent1['host'], [router['id']]))[0] - # ensure_host_set_on_ports binds an unbound port callback = l3_rpc.L3RpcCallback() callback._l3plugin = self.plugin + # First ensure that port is not bound if router is not active on any + # agent + callback._ensure_host_set_on_ports( + self.admin_ctx, self.agent1['host'], [router]) + port = self._get_first_interface(router['id']) + self.assertEqual('', port[portbindings.HOST_ID]) + + # Now update router to be active on agent1 + # and ensure_host_set_on_ports binds an unbound port + self.plugin.update_routers_states( + self.admin_ctx, {router['id']: 'active'}, self.agent1['host']) callback._ensure_host_set_on_ports( self.admin_ctx, self.agent1['host'], [router]) port = self._get_first_interface(router['id'])