DVR: FloatingIP create throws an error if no l3 agent
FloatingIP create throws an error if the L3 agent is not running
on the given host for DVR Routers.
This happens when we try to create a DVR Router in the Legacy
Router deployed cloud.
FloatingIP create checks for the agent type based on the host,
and when agents are not available on the given host, it raises
an exception.
This patch will fixes by handling the exception raised, when the
agent is not available.
Change-Id: I80522d12087495861e832cf1c7a3fe9a7830d386
Closes-Bug: #1776566
(cherry picked from commit 5ceca4d9d1
)
This commit is contained in:
parent
e8b937aca0
commit
65fcbc212d
|
@ -23,6 +23,7 @@ from neutron_lib.callbacks import registry
|
|||
from neutron_lib.callbacks import resources
|
||||
from neutron_lib import constants as const
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from neutron_lib.exceptions import agent as agent_exc
|
||||
from neutron_lib.exceptions import l3 as l3_exc
|
||||
from neutron_lib.plugins import constants as plugin_constants
|
||||
from neutron_lib.plugins import directory
|
||||
|
@ -860,8 +861,15 @@ class _DVRAgentInterfaceMixin(object):
|
|||
will return the existing port and will not
|
||||
create a new one.
|
||||
"""
|
||||
l3_agent_db = self._get_agent_by_type_and_host(
|
||||
context, const.AGENT_TYPE_L3, host)
|
||||
try:
|
||||
l3_agent_db = self._get_agent_by_type_and_host(
|
||||
context, const.AGENT_TYPE_L3, host)
|
||||
except agent_exc.AgentNotFoundByTypeHost(
|
||||
agent_type=const.AGENT_TYPE_L3, host=host):
|
||||
LOG.warning("%(ag)s agent not found for the given host: %(host)s",
|
||||
{'ag': const.AGENT_TYPE_L3,
|
||||
'host': host})
|
||||
return
|
||||
l3_agent_mode = self._get_agent_mode(l3_agent_db)
|
||||
if l3_agent_mode == l3_const.L3_AGENT_MODE_DVR_NO_EXTERNAL:
|
||||
return
|
||||
|
@ -1049,6 +1057,10 @@ class L3_NAT_with_dvr_db_mixin(_DVRAgentInterfaceMixin,
|
|||
if host is not None:
|
||||
l3_agent_on_host = self.get_dvr_agent_on_host(
|
||||
context, host)
|
||||
if not l3_agent_on_host:
|
||||
LOG.warning("No valid L3 agent found for the given host: "
|
||||
"%s", host)
|
||||
return
|
||||
agent_mode = self._get_agent_mode(l3_agent_on_host[0])
|
||||
if agent_mode == l3_const.L3_AGENT_MODE_DVR_NO_EXTERNAL:
|
||||
# If the agent hosting the fixed port is in
|
||||
|
|
|
@ -19,6 +19,7 @@ from neutron_lib.api.definitions import portbindings
|
|||
from neutron_lib.callbacks import events
|
||||
from neutron_lib.callbacks import registry
|
||||
from neutron_lib.callbacks import resources
|
||||
from neutron_lib.exceptions import agent as agent_exc
|
||||
|
||||
from neutron_lib import constants
|
||||
from neutron_lib import context
|
||||
|
@ -305,6 +306,10 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
|||
self.l3_plugin._get_agent_gw_ports_exist_for_network(
|
||||
self.context, ext_net_id, "", self.l3_agent['id']))
|
||||
|
||||
def test_create_floating_ip_with_no_dvr_agents(self):
|
||||
self._test_create_floating_ip_agent_notification(
|
||||
test_agent_mode=None)
|
||||
|
||||
def _test_create_floating_ip_agent_notification(
|
||||
self, dvr=True, test_agent_mode=constants.L3_AGENT_MODE_DVR):
|
||||
with self.subnet() as ext_subnet,\
|
||||
|
@ -315,8 +320,9 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
|||
self.context, int_port['port']['id'],
|
||||
{'port': {portbindings.HOST_ID: 'host1'}})
|
||||
# and create l3 agents on corresponding hosts
|
||||
helpers.register_l3_agent(host='host1',
|
||||
agent_mode=test_agent_mode)
|
||||
if test_agent_mode is not None:
|
||||
helpers.register_l3_agent(host='host1',
|
||||
agent_mode=test_agent_mode)
|
||||
|
||||
# make net external
|
||||
ext_net_id = ext_subnet['subnet']['network_id']
|
||||
|
@ -331,6 +337,14 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
|||
self.l3_plugin.add_router_interface(
|
||||
self.context, router['id'],
|
||||
{'subnet_id': int_subnet['subnet']['id']})
|
||||
if test_agent_mode is None:
|
||||
self.assertRaises(
|
||||
agent_exc.AgentNotFoundByTypeHost,
|
||||
self.l3_plugin.create_fip_agent_gw_port_if_not_exists,
|
||||
self.context,
|
||||
ext_net_id,
|
||||
'host1')
|
||||
return
|
||||
floating_ip = {'floating_network_id': ext_net_id,
|
||||
'router_id': router['id'],
|
||||
'port_id': int_port['port']['id'],
|
||||
|
@ -498,6 +512,10 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
|||
def test_update_floating_ip_agent_notification_non_dvr(self):
|
||||
self._test_update_floating_ip_agent_notification(dvr=False)
|
||||
|
||||
def test_delete_floating_ip_with_no_agents(self):
|
||||
self._test_delete_floating_ip_agent_notification(
|
||||
test_agent_mode=None)
|
||||
|
||||
def _test_delete_floating_ip_agent_notification(
|
||||
self, dvr=True, test_agent_mode=constants.L3_AGENT_MODE_DVR):
|
||||
with self.subnet() as ext_subnet,\
|
||||
|
@ -531,8 +549,19 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
|||
'dns_name': '', 'dns_domain': ''}
|
||||
floating_ip = self.l3_plugin.create_floatingip(
|
||||
self.context, {'floatingip': floating_ip})
|
||||
if test_agent_mode is None:
|
||||
with mock.patch.object(
|
||||
self.l3_plugin, 'get_dvr_agent_on_host') as a_mock,\
|
||||
mock.patch.object(self.l3_plugin,
|
||||
'_l3_rpc_notifier') as l3_notif:
|
||||
a_mock.return_value = None
|
||||
self.l3_plugin.delete_floatingip(
|
||||
self.context, floating_ip['id'])
|
||||
self.assertFalse(
|
||||
l3_notif.routers_updated_on_host.called)
|
||||
return
|
||||
with mock.patch.object(
|
||||
self.l3_plugin, '_l3_rpc_notifier') as l3_notif:
|
||||
self.l3_plugin, '_l3_rpc_notifier') as l3_notif:
|
||||
self.l3_plugin.delete_floatingip(
|
||||
self.context, floating_ip['id'])
|
||||
if dvr:
|
||||
|
@ -552,7 +581,8 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
|||
assert_called_once_with(
|
||||
self.context, [router['id']], 'host0')
|
||||
self.assertFalse(l3_notif.routers_updated.called)
|
||||
else:
|
||||
if test_agent_mode == (
|
||||
constants.L3_AGENT_MODE_DVR):
|
||||
l3_notif.routers_updated_on_host.\
|
||||
assert_called_once_with(
|
||||
self.context, [router['id']], 'host1')
|
||||
|
|
Loading…
Reference in New Issue