From 2d8e56ba64e328c71ef541da9c327d5bf23ced44 Mon Sep 17 00:00:00 2001 From: Akihiro MOTOKI Date: Wed, 13 Feb 2013 22:42:29 +0900 Subject: [PATCH] Disable secgroup extension when Noop Firewall driver is used When Noop Firewall driver is used, Quantum security group actually does nothing in OVS and Linux Bridge plugin. It would be better to disable security group extension for such case to avoid confusion. By this we can determine whether quantum security group is enabled by checking the extension list. This commit changes OVS/LB/NEC/Ryu plugins with agent firewall_driver based security group implementation. Fixes bug #1124117 Change-Id: I2182289c1e27987b686f1adb7d6e2ad4e154caa2 --- quantum/agent/securitygroups_rpc.py | 12 ++++++ .../plugins/linuxbridge/lb_quantum_plugin.py | 14 +++++-- quantum/plugins/nec/nec_plugin.py | 15 ++++++-- .../plugins/openvswitch/ovs_quantum_plugin.py | 14 +++++-- quantum/plugins/ryu/ryu_quantum_plugin.py | 10 ++++- .../linuxbridge/test_lb_security_group.py | 2 +- .../linuxbridge/test_linuxbridge_plugin.py | 30 +++++++++++---- quantum/tests/unit/nec/test_nec_plugin.py | 20 +++++++++- quantum/tests/unit/nec/test_security_group.py | 1 + .../openvswitch/test_openvswitch_plugin.py | 23 +++++++++--- .../openvswitch/test_ovs_security_group.py | 1 + .../tests/unit/ryu/test_ryu_security_group.py | 1 + .../tests/unit/test_security_groups_rpc.py | 37 ++++++++++++++++++- 13 files changed, 151 insertions(+), 29 deletions(-) diff --git a/quantum/agent/securitygroups_rpc.py b/quantum/agent/securitygroups_rpc.py index 1b84c788cc..51cc0fecda 100644 --- a/quantum/agent/securitygroups_rpc.py +++ b/quantum/agent/securitygroups_rpc.py @@ -33,6 +33,18 @@ security_group_opts = [ cfg.CONF.register_opts(security_group_opts, 'SECURITYGROUP') +def is_firewall_enabled(): + return (cfg.CONF.SECURITYGROUP.firewall_driver != + 'quantum.agent.firewall.NoopFirewallDriver') + + +def disable_security_group_extension_if_noop_driver( + supported_extension_aliases): + if not is_firewall_enabled(): + LOG.debug(_('Disabled security-group extension.')) + supported_extension_aliases.remove('security-group') + + class SecurityGroupServerRpcApiMixin(object): """A mix-in that enable SecurityGroup support in plugin rpc """ diff --git a/quantum/plugins/linuxbridge/lb_quantum_plugin.py b/quantum/plugins/linuxbridge/lb_quantum_plugin.py index 2e4f4824db..6f2875af14 100644 --- a/quantum/plugins/linuxbridge/lb_quantum_plugin.py +++ b/quantum/plugins/linuxbridge/lb_quantum_plugin.py @@ -202,9 +202,17 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2, __native_pagination_support = True __native_sorting_support = True - supported_extension_aliases = ["provider", "router", "binding", "quotas", - "security-group", "agent", "extraroute", - "agent_scheduler"] + _supported_extension_aliases = ["provider", "router", "binding", "quotas", + "security-group", "agent", "extraroute", + "agent_scheduler"] + + @property + def supported_extension_aliases(self): + if not hasattr(self, '_aliases'): + aliases = self._supported_extension_aliases[:] + sg_rpc.disable_security_group_extension_if_noop_driver(aliases) + self._aliases = aliases + return self._aliases network_view = "extension:provider_network:view" network_set = "extension:provider_network:set" diff --git a/quantum/plugins/nec/nec_plugin.py b/quantum/plugins/nec/nec_plugin.py index 0a89bfff48..d2cd6e6a9b 100644 --- a/quantum/plugins/nec/nec_plugin.py +++ b/quantum/plugins/nec/nec_plugin.py @@ -79,11 +79,18 @@ class NECPluginV2(nec_plugin_base.NECPluginV2Base, The port binding extension enables an external application relay information to and from the plugin. """ + _supported_extension_aliases = ["router", "quotas", "binding", + "security-group", "extraroute", + "agent", "agent_scheduler", + ] - supported_extension_aliases = ["router", "quotas", "binding", - "security-group", "extraroute", - "agent", "agent_scheduler", - ] + @property + def supported_extension_aliases(self): + if not hasattr(self, '_aliases'): + aliases = self._supported_extension_aliases[:] + sg_rpc.disable_security_group_extension_if_noop_driver(aliases) + self._aliases = aliases + return self._aliases binding_view = "extension:port_binding:view" binding_set = "extension:port_binding:set" diff --git a/quantum/plugins/openvswitch/ovs_quantum_plugin.py b/quantum/plugins/openvswitch/ovs_quantum_plugin.py index 941d6341f4..7fe93644c3 100644 --- a/quantum/plugins/openvswitch/ovs_quantum_plugin.py +++ b/quantum/plugins/openvswitch/ovs_quantum_plugin.py @@ -241,9 +241,17 @@ class OVSQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2, __native_pagination_support = True __native_sorting_support = True - supported_extension_aliases = ["provider", "router", - "binding", "quotas", "security-group", - "agent", "extraroute", "agent_scheduler"] + _supported_extension_aliases = ["provider", "router", + "binding", "quotas", "security-group", + "agent", "extraroute", "agent_scheduler"] + + @property + def supported_extension_aliases(self): + if not hasattr(self, '_aliases'): + aliases = self._supported_extension_aliases[:] + sg_rpc.disable_security_group_extension_if_noop_driver(aliases) + self._aliases = aliases + return self._aliases network_view = "extension:provider_network:view" network_set = "extension:provider_network:set" diff --git a/quantum/plugins/ryu/ryu_quantum_plugin.py b/quantum/plugins/ryu/ryu_quantum_plugin.py index 06a50e0cd7..2bedf3eb32 100644 --- a/quantum/plugins/ryu/ryu_quantum_plugin.py +++ b/quantum/plugins/ryu/ryu_quantum_plugin.py @@ -89,7 +89,15 @@ class RyuQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2, extraroute_db.ExtraRoute_db_mixin, sg_db_rpc.SecurityGroupServerRpcMixin): - supported_extension_aliases = ["router", "extraroute", "security-group"] + _supported_extension_aliases = ["router", "extraroute", "security-group"] + + @property + def supported_extension_aliases(self): + if not hasattr(self, '_aliases'): + aliases = self._supported_extension_aliases[:] + sg_rpc.disable_security_group_extension_if_noop_driver(aliases) + self._aliases = aliases + return self._aliases def __init__(self, configfile=None): db.configure_db() diff --git a/quantum/tests/unit/linuxbridge/test_lb_security_group.py b/quantum/tests/unit/linuxbridge/test_lb_security_group.py index 56accecf50..24f50a0341 100644 --- a/quantum/tests/unit/linuxbridge/test_lb_security_group.py +++ b/quantum/tests/unit/linuxbridge/test_lb_security_group.py @@ -16,7 +16,6 @@ # under the License. import mock -from mock import call from quantum.api.v2 import attributes from quantum.extensions import securitygroup as ext_sg @@ -37,6 +36,7 @@ class LinuxBridgeSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): _plugin_name = PLUGIN_NAME def setUp(self, plugin=None): + test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_IPTABLES_DRIVER) notifier_p = mock.patch(NOTIFIER) notifier_cls = notifier_p.start() self.notifier = mock.Mock() diff --git a/quantum/tests/unit/linuxbridge/test_linuxbridge_plugin.py b/quantum/tests/unit/linuxbridge/test_linuxbridge_plugin.py index bd41d4f0ae..a4c1b48e05 100644 --- a/quantum/tests/unit/linuxbridge/test_linuxbridge_plugin.py +++ b/quantum/tests/unit/linuxbridge/test_linuxbridge_plugin.py @@ -16,6 +16,8 @@ from quantum.extensions import portbindings from quantum.tests.unit import _test_extension_portbindings as test_bindings from quantum.tests.unit import test_db_plugin as test_plugin +from quantum.tests.unit import test_security_groups_rpc as test_sg_rpc + PLUGIN_NAME = ('quantum.plugins.linuxbridge.' 'lb_quantum_plugin.LinuxBridgePluginV2') @@ -39,12 +41,13 @@ class TestLinuxBridgeV2HTTPResponse(test_plugin.TestV2HTTPResponse, pass -class TestLinuxBridgePortsV2(test_plugin.TestPortsV2, - LinuxBridgePluginV2TestCase, - test_bindings.PortBindingsTestCase): +class TestLinuxBridgeNetworksV2(test_plugin.TestNetworksV2, + LinuxBridgePluginV2TestCase): + pass - VIF_TYPE = portbindings.VIF_TYPE_BRIDGE - HAS_PORT_FILTER = True + +class TestLinuxBridgePortsV2(test_plugin.TestPortsV2, + LinuxBridgePluginV2TestCase): def test_update_port_status_build(self): with self.port() as port: @@ -52,6 +55,17 @@ class TestLinuxBridgePortsV2(test_plugin.TestPortsV2, self.assertEqual(self.port_create_status, 'DOWN') -class TestLinuxBridgeNetworksV2(test_plugin.TestNetworksV2, - LinuxBridgePluginV2TestCase): - pass +class TestLinuxBridgePortBinding(LinuxBridgePluginV2TestCase, + test_bindings.PortBindingsTestCase): + VIF_TYPE = portbindings.VIF_TYPE_BRIDGE + HAS_PORT_FILTER = True + FIREWALL_DRIVER = test_sg_rpc.FIREWALL_IPTABLES_DRIVER + + def setUp(self): + test_sg_rpc.set_firewall_driver(self.FIREWALL_DRIVER) + super(TestLinuxBridgePortBinding, self).setUp() + + +class TestLinuxBridgePortBindingNoSG(TestLinuxBridgePortBinding): + HAS_PORT_FILTER = False + FIREWALL_DRIVER = test_sg_rpc.FIREWALL_NOOP_DRIVER diff --git a/quantum/tests/unit/nec/test_nec_plugin.py b/quantum/tests/unit/nec/test_nec_plugin.py index 080a5cc814..45a9f09c25 100644 --- a/quantum/tests/unit/nec/test_nec_plugin.py +++ b/quantum/tests/unit/nec/test_nec_plugin.py @@ -16,6 +16,7 @@ from quantum.extensions import portbindings from quantum.tests.unit import _test_extension_portbindings as test_bindings from quantum.tests.unit import test_db_plugin as test_plugin +from quantum.tests.unit import test_security_groups_rpc as test_sg_rpc PLUGIN_NAME = 'quantum.plugins.nec.nec_plugin.NECPluginV2' @@ -38,8 +39,7 @@ class TestNecV2HTTPResponse(test_plugin.TestV2HTTPResponse, pass -class TestNecPortsV2(test_plugin.TestPortsV2, NecPluginV2TestCase, - test_bindings.PortBindingsTestCase): +class TestNecPortsV2(test_plugin.TestPortsV2, NecPluginV2TestCase): VIF_TYPE = portbindings.VIF_TYPE_OVS HAS_PORT_FILTER = True @@ -47,3 +47,19 @@ class TestNecPortsV2(test_plugin.TestPortsV2, NecPluginV2TestCase, class TestNecNetworksV2(test_plugin.TestNetworksV2, NecPluginV2TestCase): pass + + +class TestNecPortBinding(test_bindings.PortBindingsTestCase, + NecPluginV2TestCase): + VIF_TYPE = portbindings.VIF_TYPE_OVS + HAS_PORT_FILTER = True + FIREWALL_DRIVER = test_sg_rpc.FIREWALL_HYBRID_DRIVER + + def setUp(self): + test_sg_rpc.set_firewall_driver(self.FIREWALL_DRIVER) + super(TestNecPortBinding, self).setUp() + + +class TestNecPortBindingNoSG(TestNecPortBinding): + HAS_PORT_FILTER = False + FIREWALL_DRIVER = test_sg_rpc.FIREWALL_NOOP_DRIVER diff --git a/quantum/tests/unit/nec/test_security_group.py b/quantum/tests/unit/nec/test_security_group.py index 8b1512ed6a..e1c98a4095 100644 --- a/quantum/tests/unit/nec/test_security_group.py +++ b/quantum/tests/unit/nec/test_security_group.py @@ -35,6 +35,7 @@ class NecSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): _plugin_name = PLUGIN_NAME def setUp(self, plugin=None): + test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_HYBRID_DRIVER) self.addCleanup(mock.patch.stopall) notifier_p = mock.patch(NOTIFIER) notifier_cls = notifier_p.start() diff --git a/quantum/tests/unit/openvswitch/test_openvswitch_plugin.py b/quantum/tests/unit/openvswitch/test_openvswitch_plugin.py index 7d7300f877..d8aaed4527 100644 --- a/quantum/tests/unit/openvswitch/test_openvswitch_plugin.py +++ b/quantum/tests/unit/openvswitch/test_openvswitch_plugin.py @@ -16,6 +16,7 @@ from quantum.extensions import portbindings from quantum.tests.unit import _test_extension_portbindings as test_bindings from quantum.tests.unit import test_db_plugin as test_plugin +from quantum.tests.unit import test_security_groups_rpc as test_sg_rpc class OpenvswitchPluginV2TestCase(test_plugin.QuantumDbPluginV2TestCase): @@ -39,11 +40,7 @@ class TestOpenvswitchV2HTTPResponse(test_plugin.TestV2HTTPResponse, class TestOpenvswitchPortsV2(test_plugin.TestPortsV2, - OpenvswitchPluginV2TestCase, - test_bindings.PortBindingsTestCase): - - VIF_TYPE = portbindings.VIF_TYPE_OVS - HAS_PORT_FILTER = True + OpenvswitchPluginV2TestCase): def test_update_port_status_build(self): with self.port() as port: @@ -54,3 +51,19 @@ class TestOpenvswitchPortsV2(test_plugin.TestPortsV2, class TestOpenvswitchNetworksV2(test_plugin.TestNetworksV2, OpenvswitchPluginV2TestCase): pass + + +class TestOpenvswitchPortBinding(OpenvswitchPluginV2TestCase, + test_bindings.PortBindingsTestCase): + VIF_TYPE = portbindings.VIF_TYPE_OVS + HAS_PORT_FILTER = True + FIREWALL_DRIVER = test_sg_rpc.FIREWALL_HYBRID_DRIVER + + def setUp(self, firewall_driver=None): + test_sg_rpc.set_firewall_driver(self.FIREWALL_DRIVER) + super(TestOpenvswitchPortBinding, self).setUp() + + +class TestOpenvswitchPortBindingNoSG(TestOpenvswitchPortBinding): + HAS_PORT_FILTER = False + FIREWALL_DRIVER = test_sg_rpc.FIREWALL_NOOP_DRIVER diff --git a/quantum/tests/unit/openvswitch/test_ovs_security_group.py b/quantum/tests/unit/openvswitch/test_ovs_security_group.py index 32bb96b931..c58a2bc805 100644 --- a/quantum/tests/unit/openvswitch/test_ovs_security_group.py +++ b/quantum/tests/unit/openvswitch/test_ovs_security_group.py @@ -35,6 +35,7 @@ class OpenvswitchSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): _plugin_name = PLUGIN_NAME def setUp(self, plugin=None): + test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_HYBRID_DRIVER) self.addCleanup(mock.patch.stopall) notifier_p = mock.patch(NOTIFIER) notifier_cls = notifier_p.start() diff --git a/quantum/tests/unit/ryu/test_ryu_security_group.py b/quantum/tests/unit/ryu/test_ryu_security_group.py index 64f6963d5f..4a1a9571bc 100644 --- a/quantum/tests/unit/ryu/test_ryu_security_group.py +++ b/quantum/tests/unit/ryu/test_ryu_security_group.py @@ -38,6 +38,7 @@ class RyuSecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase): _plugin_name = PLUGIN_NAME def setUp(self, plugin=None): + test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_HYBRID_DRIVER) self.addCleanup(mock.patch.stopall) notifier_p = mock.patch(NOTIFIER) notifier_cls = notifier_p.start() diff --git a/quantum/tests/unit/test_security_groups_rpc.py b/quantum/tests/unit/test_security_groups_rpc.py index 79dcad1b51..f99d0c52b8 100644 --- a/quantum/tests/unit/test_security_groups_rpc.py +++ b/quantum/tests/unit/test_security_groups_rpc.py @@ -971,10 +971,19 @@ IPTABLES_FILTER_V6_EMPTY = """:%(bn)s-(%(chains)s) - [0:0] """ % IPTABLES_ARG FIREWALL_BASE_PACKAGE = 'quantum.agent.linux.iptables_firewall.' +FIREWALL_IPTABLES_DRIVER = FIREWALL_BASE_PACKAGE + 'IptablesFirewallDriver' +FIREWALL_HYBRID_DRIVER = (FIREWALL_BASE_PACKAGE + + 'OVSHybridIptablesFirewallDriver') +FIREWALL_NOOP_DRIVER = 'quantum.agent.firewall.NoopFirewallDriver' + + +def set_firewall_driver(firewall_driver): + cfg.CONF.set_override('firewall_driver', firewall_driver, + group='SECURITYGROUP') class TestSecurityGroupAgentWithIptables(base.BaseTestCase): - FIREWALL_DRIVER = FIREWALL_BASE_PACKAGE + 'IptablesFirewallDriver' + FIREWALL_DRIVER = FIREWALL_IPTABLES_DRIVER PHYSDEV_INGRESS = 'physdev-out' PHYSDEV_EGRESS = 'physdev-in' @@ -1200,7 +1209,7 @@ class SGNotificationTestMixin(): class TestSecurityGroupAgentWithOVSIptables( TestSecurityGroupAgentWithIptables): - FIREWALL_DRIVER = FIREWALL_BASE_PACKAGE + 'OVSHybridIptablesFirewallDriver' + FIREWALL_DRIVER = FIREWALL_HYBRID_DRIVER def _regex(self, value): #Note(nati): tap is prefixed on the device @@ -1212,3 +1221,27 @@ class TestSecurityGroupAgentWithOVSIptables( return super( TestSecurityGroupAgentWithOVSIptables, self)._regex(value) + + +class TestSecurityGroupExtensionControl(base.BaseTestCase): + def test_firewall_enabled_noop_driver(self): + set_firewall_driver(FIREWALL_NOOP_DRIVER) + self.assertFalse(sg_rpc.is_firewall_enabled()) + + def test_firewall_enabled_iptables_driver(self): + set_firewall_driver(FIREWALL_IPTABLES_DRIVER) + self.assertTrue(sg_rpc.is_firewall_enabled()) + + def test_disable_security_group_extension_noop_driver(self): + set_firewall_driver(FIREWALL_NOOP_DRIVER) + exp_aliases = ['dummy1', 'dummy2'] + ext_aliases = ['dummy1', 'security-group', 'dummy2'] + sg_rpc.disable_security_group_extension_if_noop_driver(ext_aliases) + self.assertEqual(ext_aliases, exp_aliases) + + def test_disable_security_group_extension_iptables_driver(self): + set_firewall_driver(FIREWALL_IPTABLES_DRIVER) + exp_aliases = ['dummy1', 'security-group', 'dummy2'] + ext_aliases = ['dummy1', 'security-group', 'dummy2'] + sg_rpc.disable_security_group_extension_if_noop_driver(ext_aliases) + self.assertEqual(ext_aliases, exp_aliases)