From 59bff25343aa9ba51db0d41c9dde631aeed2a5ec Mon Sep 17 00:00:00 2001 From: Akihiro Motoki Date: Thu, 14 Aug 2014 15:53:47 +0900 Subject: [PATCH] Skip FWaaS config mismatch check if RPC method is unsupported In this commit FWaaS config check skip is skipped if neutron server does not support this API. Commit d6f014d introduced FWaaS config mismatch check between server and agent. It added a new RPC method get_service_plugin_list and bumped l3-agent RPC version to 1.3, but this version RPC is only supported by L3 router service plugin and it breaks existing plugins using L3 router mixin. Bumping l3-agent RPC version requires detailed investigation on all affected plugins and it can be done by plugin maintainer later. Change-Id: I388a24b0c6a507203674ef108bb14cea0534f98c Closes-Bug: #1353309 --- neutron/agent/l3_agent.py | 14 ++++++-- .../agents/l3reference/firewall_l3_agent.py | 22 +++++++------ .../l3reference/test_firewall_l3_agent.py | 32 +++++++++++++------ neutron/tests/unit/test_l3_agent.py | 16 ++++++++++ 4 files changed, 64 insertions(+), 20 deletions(-) diff --git a/neutron/agent/l3_agent.py b/neutron/agent/l3_agent.py index 52720ac99c..3491a24f79 100644 --- a/neutron/agent/l3_agent.py +++ b/neutron/agent/l3_agent.py @@ -426,8 +426,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 d1f846b769..d64bf2e0d6 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 @@ -1947,6 +1949,20 @@ class TestBasicRouterOperations(base.BaseTestCase): '11.22.33.42', 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):