diff --git a/neutron/agent/l3_agent.py b/neutron/agent/l3_agent.py index c9bc84c6b1..d94ffe6d20 100644 --- a/neutron/agent/l3_agent.py +++ b/neutron/agent/l3_agent.py @@ -518,8 +518,18 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, manager.Manager): self.sync_progress = False # Get the list of service plugins from Neutron Server - self.neutron_service_plugins = ( - self.plugin_rpc.get_service_plugin_list(self.context)) + try: + self.neutron_service_plugins = ( + self.plugin_rpc.get_service_plugin_list(self.context)) + except n_rpc.RemoteError as e: + LOG.warning(_('l3-agent cannot check service plugins ' + 'enabled at the neutron server when startup ' + 'due to RPC error. It happens when the server ' + 'does not support this RPC API. If the error ' + 'is UnsupportedVersion you can ignore ' + 'this warning. Detail message: %s'), e) + self.neutron_service_plugins = None + self._clean_stale_namespaces = self.conf.use_namespaces # dvr data diff --git a/neutron/services/firewall/agents/l3reference/firewall_l3_agent.py b/neutron/services/firewall/agents/l3reference/firewall_l3_agent.py index f47cf24584..cfcdb4b17d 100644 --- a/neutron/services/firewall/agents/l3reference/firewall_l3_agent.py +++ b/neutron/services/firewall/agents/l3reference/firewall_l3_agent.py @@ -62,16 +62,20 @@ class FWaaSL3AgentRpcCallback(api.FWaaSAgentRpcCallbackMixin): LOG.debug(_("Initializing firewall agent")) self.conf = conf fwaas_driver_class_path = cfg.CONF.fwaas.driver - fwaas_enabled = cfg.CONF.fwaas.enabled - fwaas_plugin_configured = (constants.FIREWALL - in self.neutron_service_plugins) - if fwaas_plugin_configured and not fwaas_enabled: - msg = _("FWaaS plugin is configured in the server side, but " - "FWaaS is disabled in L3-agent.") - LOG.error(msg) - raise SystemExit(1) + self.fwaas_enabled = cfg.CONF.fwaas.enabled + + # None means l3-agent has no information on the server + # configuration due to the lack of RPC support. + if self.neutron_service_plugins is not None: + fwaas_plugin_configured = (constants.FIREWALL + in self.neutron_service_plugins) + if fwaas_plugin_configured and not self.fwaas_enabled: + msg = _("FWaaS plugin is configured in the server side, but " + "FWaaS is disabled in L3-agent.") + LOG.error(msg) + raise SystemExit(1) + self.fwaas_enabled = self.fwaas_enabled and fwaas_plugin_configured - self.fwaas_enabled = fwaas_enabled and fwaas_plugin_configured if self.fwaas_enabled: try: self.fwaas_driver = importutils.import_object( diff --git a/neutron/tests/unit/services/firewall/agents/l3reference/test_firewall_l3_agent.py b/neutron/tests/unit/services/firewall/agents/l3reference/test_firewall_l3_agent.py index 8bb4358291..a69ef54a9a 100644 --- a/neutron/tests/unit/services/firewall/agents/l3reference/test_firewall_l3_agent.py +++ b/neutron/tests/unit/services/firewall/agents/l3reference/test_firewall_l3_agent.py @@ -28,6 +28,7 @@ from neutron.agent.linux import ip_lib from neutron.common import config as base_config from neutron import context from neutron.plugins.common import constants +from neutron.services.firewall.agents import firewall_agent_api from neutron.services.firewall.agents.l3reference import firewall_l3_agent from neutron.tests import base from neutron.tests.unit.services.firewall.agents import test_firewall_agent_api @@ -41,14 +42,13 @@ class FWaasHelper(object): class FWaasAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, FWaasHelper): neutron_service_plugins = [] - def __init__(self, conf=None): - super(FWaasAgent, self).__init__(conf) +def _setup_test_agent_class(service_plugins): + class FWaasTestAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, + FWaasHelper): + neutron_service_plugins = service_plugins -class FWaasTestAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, FWaasHelper): - def __init__(self, conf=None): - self.neutron_service_plugins = [constants.FIREWALL] - super(FWaasTestAgent, self).__init__(conf) + return FWaasTestAgent class TestFwaasL3AgentRpcCallback(base.BaseTestCase): @@ -61,12 +61,26 @@ class TestFwaasL3AgentRpcCallback(base.BaseTestCase): agent_config.register_use_namespaces_opts_helper(self.conf) agent_config.register_root_helper(self.conf) self.conf.root_helper = 'sudo' + self.conf.register_opts(firewall_agent_api.FWaaSOpts, 'fwaas') self.api = FWaasAgent(self.conf) self.api.fwaas_driver = test_firewall_agent_api.NoopFwaasDriver() - def test_missing_fw_config(self): - self.conf.fwaas_enabled = False - self.assertRaises(SystemExit, FWaasTestAgent, self.conf) + def test_fw_config_match(self): + test_agent_class = _setup_test_agent_class([constants.FIREWALL]) + cfg.CONF.set_override('enabled', True, 'fwaas') + with mock.patch('neutron.openstack.common.importutils.import_object'): + test_agent_class(cfg.CONF) + + def test_fw_config_mismatch_plugin_enabled_agent_disabled(self): + test_agent_class = _setup_test_agent_class([constants.FIREWALL]) + cfg.CONF.set_override('enabled', False, 'fwaas') + self.assertRaises(SystemExit, test_agent_class, cfg.CONF) + + def test_fw_plugin_list_unavailable(self): + test_agent_class = _setup_test_agent_class(None) + cfg.CONF.set_override('enabled', False, 'fwaas') + with mock.patch('neutron.openstack.common.importutils.import_object'): + test_agent_class(cfg.CONF) def test_create_firewall(self): fake_firewall = {'id': 0} diff --git a/neutron/tests/unit/test_l3_agent.py b/neutron/tests/unit/test_l3_agent.py index 664b6e8c82..6f15e9c02e 100644 --- a/neutron/tests/unit/test_l3_agent.py +++ b/neutron/tests/unit/test_l3_agent.py @@ -28,8 +28,10 @@ from neutron.agent.linux import interface from neutron.common import config as base_config from neutron.common import constants as l3_constants from neutron.common import exceptions as n_exc +from neutron.common import rpc as n_rpc from neutron.openstack.common import processutils from neutron.openstack.common import uuidutils +from neutron.plugins.common import constants as p_const from neutron.tests import base @@ -2044,6 +2046,20 @@ class TestBasicRouterOperations(base.BaseTestCase): str(fip_to_rtr.ip), table=16) f.assert_called_once_with(fip_ns_name) + def test_get_service_plugin_list(self): + service_plugins = [p_const.L3_ROUTER_NAT] + self.plugin_api.get_service_plugin_list.return_value = service_plugins + agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) + self.assertEqual(service_plugins, agent.neutron_service_plugins) + self.assertTrue(self.plugin_api.get_service_plugin_list.called) + + def test_get_service_plugin_list_failed(self): + raise_rpc = n_rpc.RemoteError() + self.plugin_api.get_service_plugin_list.side_effect = raise_rpc + agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) + self.assertIsNone(agent.neutron_service_plugins) + self.assertTrue(self.plugin_api.get_service_plugin_list.called) + class TestL3AgentEventHandler(base.BaseTestCase):