[L3] Check agent gateway port robustly
In patch [1] it introduced a binding of DB uniq constraint for L3 agent gateway. In some extreme case the DvrFipGatewayPortAgentBinding is in DB while the gateway port not. The current code path only checks the binding existence which will pass a "None" port to the following code path that results an AttributeError. This patch adds a simple check for that gateway port, if it is not created, new one. [1] https://review.opendev.org/#/c/702547/ Closes-Bug: #1883089 Change-Id: Ia90f2ee435b0a3476dbea028d3200cefe11e35e4
This commit is contained in:
parent
f260d2aef3
commit
5fdfd4cbfc
|
@ -1065,13 +1065,14 @@ class _DVRAgentInterfaceMixin(object):
|
|||
try:
|
||||
fip_agent_port_obj.create()
|
||||
except o_exc.NeutronDbObjectDuplicateEntry:
|
||||
LOG.debug("Floating IP Agent Gateway port for network "
|
||||
LOG.debug("Floating IP Gateway port agent binding for network "
|
||||
"%(network)s already exists on host %(host)s. "
|
||||
"Probably it was just created by other worker.",
|
||||
{'network': network_id,
|
||||
'host': host})
|
||||
agent_port = self._get_agent_gw_ports_exist_for_network(
|
||||
context, network_id, host, l3_agent_db['id'])
|
||||
if agent_port:
|
||||
LOG.debug("Floating IP Agent Gateway port %(gw)s found "
|
||||
"for the destination host: %(dest_host)s",
|
||||
{'gw': agent_port,
|
||||
|
|
|
@ -763,6 +763,42 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
|
|||
mock.call(self.ctx, network_id, 'host', fipagent['id'])])
|
||||
self.assertIsNotNone(fport)
|
||||
|
||||
def test_create_fip_agent_gw_port_agent_binding_exists(self):
|
||||
network_id = _uuid()
|
||||
fport_db = {'id': _uuid()}
|
||||
self.mixin._get_agent_gw_ports_exist_for_network = mock.Mock(
|
||||
side_effect=[None, None])
|
||||
fipagent = agent_obj.Agent(
|
||||
self.ctx,
|
||||
id=_uuid(),
|
||||
binary='foo-agent',
|
||||
host='host',
|
||||
agent_type='L3 agent',
|
||||
topic='foo_topic',
|
||||
configurations={"agent_mode": "dvr"})
|
||||
self.mixin._get_agent_by_type_and_host = mock.Mock(
|
||||
return_value=fipagent)
|
||||
self.mixin._populate_mtu_and_subnets_for_ports = mock.Mock()
|
||||
|
||||
with mock.patch.object(
|
||||
router_obj.DvrFipGatewayPortAgentBinding, 'create',
|
||||
side_effect=o_exc.NeutronDbObjectDuplicateEntry(
|
||||
mock.Mock(), mock.Mock())
|
||||
) as dvr_fip_gateway_port_agent_binding_create,\
|
||||
mock.patch.object(
|
||||
plugin_utils, "create_port", return_value=fport_db):
|
||||
fport = self.mixin.create_fip_agent_gw_port_if_not_exists(
|
||||
self.ctx,
|
||||
network_id,
|
||||
'host')
|
||||
dvr_fip_gateway_port_agent_binding_create.assert_called_once_with()
|
||||
self.mixin._get_agent_gw_ports_exist_for_network.assert_has_calls([
|
||||
mock.call(self.ctx, network_id, 'host', fipagent['id']),
|
||||
mock.call(self.ctx, network_id, 'host', fipagent['id'])])
|
||||
self.mixin._populate_mtu_and_subnets_for_ports.assert_has_calls([
|
||||
mock.call(self.ctx, [fport_db])])
|
||||
self.assertIsNotNone(fport)
|
||||
|
||||
def test_create_floatingip_agent_gw_port_with_non_dvr_router(self):
|
||||
floatingip = {
|
||||
'id': _uuid(),
|
||||
|
|
Loading…
Reference in New Issue