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)