Set vif_details to reflect enable_security_group

While plugging vif, VIFDriver in Nova follows "ovs_hybrid_plug" and
"port_filter" in "binding:vif_detail" which is passed from Neutron, but
those are always true.  This patch make ML2 OVS mech driver set those
param depends on enable_security_group flag.  It enables users to avoid
ovs_hybrid plugging.

This patch also fixes the same issue in the following plugins/drivers:
  * NEC Plugin
  * BigSwitch Plugin
  * Ryu Plugin
  * ML2 Plugin - OFAgent Mech Driver

Closes-Bug: #1336624
Change-Id: I2b7fb526a6f1b730ad65289307b24fd28b996e1b
This commit is contained in:
Ryota MIBU 2014-07-03 00:10:32 +09:00
parent a76af4ade3
commit e73f8da072
10 changed files with 102 additions and 38 deletions

View File

@ -365,11 +365,12 @@ class NeutronRestProxyV2Base(db_base_plugin_v2.NeutronDbPluginV2,
cfg_vif_type = override
port[portbindings.VIF_TYPE] = cfg_vif_type
sg_enabled = sg_rpc.is_firewall_enabled()
port[portbindings.VIF_DETAILS] = {
# TODO(rkukura): Replace with new VIF security details
portbindings.CAP_PORT_FILTER:
'security-group' in self.supported_extension_aliases,
portbindings.OVS_HYBRID_PLUG: True
portbindings.OVS_HYBRID_PLUG: sg_enabled
}
return port

View File

@ -19,6 +19,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from neutron.agent import securitygroups_rpc
from neutron.common import constants
from neutron.extensions import portbindings
from neutron.openstack.common import log
@ -40,11 +41,13 @@ class OfagentMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
"""
def __init__(self):
sg_enabled = securitygroups_rpc.is_firewall_enabled()
vif_details = {portbindings.CAP_PORT_FILTER: sg_enabled,
portbindings.OVS_HYBRID_PLUG: sg_enabled}
super(OfagentMechanismDriver, self).__init__(
constants.AGENT_TYPE_OFA,
portbindings.VIF_TYPE_OVS,
{portbindings.CAP_PORT_FILTER: True,
portbindings.OVS_HYBRID_PLUG: True})
vif_details)
def check_segment_for_agent(self, segment, agent):
bridge_mappings = agent['configurations'].get('bridge_mappings', {})

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from neutron.agent import securitygroups_rpc
from neutron.common import constants
from neutron.extensions import portbindings
from neutron.openstack.common import log
@ -33,11 +34,13 @@ class OpenvswitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
"""
def __init__(self):
sg_enabled = securitygroups_rpc.is_firewall_enabled()
vif_details = {portbindings.CAP_PORT_FILTER: sg_enabled,
portbindings.OVS_HYBRID_PLUG: sg_enabled}
super(OpenvswitchMechanismDriver, self).__init__(
constants.AGENT_TYPE_OVS,
portbindings.VIF_TYPE_OVS,
{portbindings.CAP_PORT_FILTER: True,
portbindings.OVS_HYBRID_PLUG: True})
vif_details)
def check_segment_for_agent(self, segment, agent):
mappings = agent['configurations'].get('bridge_mappings', {})

View File

@ -421,15 +421,11 @@ class NECPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
self._cleanup_ofc_tenant(context, tenant_id)
def _get_base_binding_dict(self):
binding = {
portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS,
portbindings.VIF_DETAILS: {
# TODO(rkukura): Replace with new VIF security details
portbindings.CAP_PORT_FILTER:
'security-group' in self.supported_extension_aliases,
portbindings.OVS_HYBRID_PLUG: True
}
}
sg_enabled = sg_rpc.is_firewall_enabled()
vif_details = {portbindings.CAP_PORT_FILTER: sg_enabled,
portbindings.OVS_HYBRID_PLUG: sg_enabled}
binding = {portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS,
portbindings.VIF_DETAILS: vif_details}
return binding
def _extend_port_dict_binding_portinfo(self, port_res, portinfo):

View File

@ -107,15 +107,7 @@ class RyuNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
def __init__(self, configfile=None):
super(RyuNeutronPluginV2, self).__init__()
self.base_binding_dict = {
portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS,
portbindings.VIF_DETAILS: {
# TODO(rkukura): Replace with new VIF security details
portbindings.CAP_PORT_FILTER:
'security-group' in self.supported_extension_aliases,
portbindings.OVS_HYBRID_PLUG: True
}
}
self.base_binding_dict = self._get_base_binding_dict()
portbindings_base.register_port_dict_function()
self.tunnel_key = db_api_v2.TunnelKey(
cfg.CONF.OVS.tunnel_key_min, cfg.CONF.OVS.tunnel_key_max)
@ -134,6 +126,14 @@ class RyuNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
# register known all network list on startup
self._create_all_tenant_network()
def _get_base_binding_dict(self):
sg_enabled = sg_rpc.is_firewall_enabled()
vif_details = {portbindings.CAP_PORT_FILTER: sg_enabled,
portbindings.OVS_HYBRID_PLUG: sg_enabled}
binding = {portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS,
portbindings.VIF_DETAILS: vif_details}
return binding
def _setup_rpc(self):
self.service_topics = {svc_constants.CORE: topics.PLUGIN,
svc_constants.L3_ROUTER_NAT: topics.L3PLUGIN}

View File

@ -29,19 +29,27 @@ class PortBindingsTestCase(test_db_plugin.NeutronDbPluginV2TestCase):
# VIF_TYPE must be overridden according to plugin vif_type
VIF_TYPE = portbindings.VIF_TYPE_OTHER
# The plugin supports the port security feature such as
# security groups and anti spoofing.
HAS_PORT_FILTER = False
# VIF_DETAILS must be overridden according to plugin vif_details
VIF_DETAILS = None
def _check_response_portbindings(self, port):
self.assertEqual(port[portbindings.VIF_TYPE], self.VIF_TYPE)
vif_details = port[portbindings.VIF_DETAILS]
# REVISIT(rkukura): Consider reworking tests to enable ML2 to bind
if self.VIF_TYPE not in [portbindings.VIF_TYPE_UNBOUND,
portbindings.VIF_TYPE_BINDING_FAILED]:
# TODO(rkukura): Replace with new VIF security details
self.assertEqual(vif_details[portbindings.CAP_PORT_FILTER],
self.HAS_PORT_FILTER)
# NOTE(r-mibu): The following six lines are just for backward
# compatibility. In this class, HAS_PORT_FILTER has been replaced
# by VIF_DETAILS which can be set expected vif_details to check,
# but all replacement of HAS_PORT_FILTER in successor has not been
# completed.
if self.VIF_DETAILS is None:
expected = getattr(self, 'HAS_PORT_FILTER', False)
vif_details = port[portbindings.VIF_DETAILS]
port_filter = vif_details[portbindings.CAP_PORT_FILTER]
self.assertEqual(expected, port_filter)
return
self.assertEqual(self.VIF_DETAILS, port[portbindings.VIF_DETAILS])
def _check_response_no_portbindings(self, port):
self.assertIn('status', port)

View File

@ -120,7 +120,7 @@ class AgentMechanismBaseTestCase(base.BaseTestCase):
# The following must be overridden for the specific mechanism
# driver being tested:
VIF_TYPE = None
CAP_PORT_FILTER = None
VIF_DETAILS = None
AGENT_TYPE = None
AGENTS = None
AGENTS_DEAD = None
@ -136,8 +136,17 @@ class AgentMechanismBaseTestCase(base.BaseTestCase):
self.assertEqual(context._bound_vif_type, self.VIF_TYPE)
vif_details = context._bound_vif_details
self.assertIsNotNone(vif_details)
self.assertEqual(vif_details[portbindings.CAP_PORT_FILTER],
self.CAP_PORT_FILTER)
# NOTE(r-mibu): The following five lines are just for backward
# compatibility. In this class, HAS_PORT_FILTER has been replaced
# by VIF_DETAILS which can be set expected vif_details to check,
# but all replacement of HAS_PORT_FILTER in successor has not been
# completed.
if self.VIF_DETAILS is None:
expected = getattr(self, 'CAP_PORT_FILTER', None)
port_filter = vif_details[portbindings.CAP_PORT_FILTER]
self.assertEqual(expected, port_filter)
return
self.assertEqual(self.VIF_DETAILS, vif_details)
class AgentMechanismGenericTestCase(AgentMechanismBaseTestCase):

View File

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo.config import cfg
from neutron.common import constants
from neutron.extensions import portbindings
from neutron.plugins.ml2.drivers import mech_ofagent
@ -21,7 +23,8 @@ from neutron.tests.unit.ml2 import _test_mech_agent as base
class OfagentMechanismBaseTestCase(base.AgentMechanismBaseTestCase):
VIF_TYPE = portbindings.VIF_TYPE_OVS
CAP_PORT_FILTER = True
VIF_DETAILS = {portbindings.CAP_PORT_FILTER: True,
portbindings.OVS_HYBRID_PLUG: True}
AGENT_TYPE = constants.AGENT_TYPE_OFA
GOOD_MAPPINGS = {'fake_physical_network': 'fake_interface'}
@ -49,6 +52,17 @@ class OfagentMechanismBaseTestCase(base.AgentMechanismBaseTestCase):
self.driver.initialize()
class OfagentMechanismSGDisabledBaseTestCase(OfagentMechanismBaseTestCase):
VIF_DETAILS = {portbindings.CAP_PORT_FILTER: False,
portbindings.OVS_HYBRID_PLUG: False}
def setUp(self):
cfg.CONF.set_override('enable_security_group',
False,
group='SECURITYGROUP')
super(OfagentMechanismSGDisabledBaseTestCase, self).setUp()
class OfagentMechanismGenericTestCase(OfagentMechanismBaseTestCase,
base.AgentMechanismGenericTestCase):
pass
@ -74,12 +88,19 @@ class OfagentMechanismGreTestCase(OfagentMechanismBaseTestCase,
pass
class OfagentMechanismSGDisabledLocalTestCase(
OfagentMechanismSGDisabledBaseTestCase,
base.AgentMechanismLocalTestCase):
pass
# The following tests are for deprecated "bridge_mappings".
# TODO(yamamoto): Remove them.
class OfagentMechanismPhysBridgeTestCase(base.AgentMechanismBaseTestCase):
VIF_TYPE = portbindings.VIF_TYPE_OVS
CAP_PORT_FILTER = True
VIF_DETAILS = {portbindings.CAP_PORT_FILTER: True,
portbindings.OVS_HYBRID_PLUG: True}
AGENT_TYPE = constants.AGENT_TYPE_OFA
GOOD_MAPPINGS = {'fake_physical_network': 'fake_bridge'}

View File

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo.config import cfg
from neutron.common import constants
from neutron.extensions import portbindings
from neutron.plugins.ml2.drivers import mech_openvswitch
@ -21,7 +23,8 @@ from neutron.tests.unit.ml2 import _test_mech_agent as base
class OpenvswitchMechanismBaseTestCase(base.AgentMechanismBaseTestCase):
VIF_TYPE = portbindings.VIF_TYPE_OVS
CAP_PORT_FILTER = True
VIF_DETAILS = {portbindings.CAP_PORT_FILTER: True,
portbindings.OVS_HYBRID_PLUG: True}
AGENT_TYPE = constants.AGENT_TYPE_OVS
GOOD_MAPPINGS = {'fake_physical_network': 'fake_bridge'}
@ -49,6 +52,18 @@ class OpenvswitchMechanismBaseTestCase(base.AgentMechanismBaseTestCase):
self.driver.initialize()
class OpenvswitchMechanismSGDisabledBaseTestCase(
OpenvswitchMechanismBaseTestCase):
VIF_DETAILS = {portbindings.CAP_PORT_FILTER: False,
portbindings.OVS_HYBRID_PLUG: False}
def setUp(self):
cfg.CONF.set_override('enable_security_group',
False,
group='SECURITYGROUP')
super(OpenvswitchMechanismSGDisabledBaseTestCase, self).setUp()
class OpenvswitchMechanismGenericTestCase(OpenvswitchMechanismBaseTestCase,
base.AgentMechanismGenericTestCase):
pass
@ -72,3 +87,9 @@ class OpenvswitchMechanismVlanTestCase(OpenvswitchMechanismBaseTestCase,
class OpenvswitchMechanismGreTestCase(OpenvswitchMechanismBaseTestCase,
base.AgentMechanismGreTestCase):
pass
class OpenvswitchMechanismSGDisabledLocalTestCase(
OpenvswitchMechanismSGDisabledBaseTestCase,
base.AgentMechanismLocalTestCase):
pass

View File

@ -28,7 +28,8 @@ from neutron.tests.unit import test_security_groups_rpc as test_sg_rpc
class TestNecPortBinding(test_bindings.PortBindingsTestCase,
test_nec_plugin.NecPluginV2TestCase):
VIF_TYPE = portbindings.VIF_TYPE_OVS
HAS_PORT_FILTER = True
VIF_DETAILS = {portbindings.CAP_PORT_FILTER: True,
portbindings.OVS_HYBRID_PLUG: True}
ENABLE_SG = True
FIREWALL_DRIVER = test_sg_rpc.FIREWALL_HYBRID_DRIVER
@ -41,7 +42,8 @@ class TestNecPortBinding(test_bindings.PortBindingsTestCase,
class TestNecPortBindingNoSG(TestNecPortBinding):
HAS_PORT_FILTER = False
VIF_DETAILS = {portbindings.CAP_PORT_FILTER: False,
portbindings.OVS_HYBRID_PLUG: False}
ENABLE_SG = False
FIREWALL_DRIVER = test_sg_rpc.FIREWALL_NOOP_DRIVER