ML2 tunnel drivers validate provider networks correctly

there was a copy/paste error in GRE/VXlan type drivers implementation.
the segment wasn't returned while validating the provider network.

Change-Id: I7df6d2e714d09618644f935a9ed41354b62de9d0
Fixes: bug #1202244
This commit is contained in:
mathieu-rohon 2013-07-25 10:38:16 +02:00 committed by Mark McClain
parent e4ddee8e82
commit c1b1af72e9
9 changed files with 30 additions and 40 deletions

View File

@ -67,7 +67,6 @@ class TypeDriver(object):
"""Validate attributes of a provider network segment. """Validate attributes of a provider network segment.
:param segment: segment dictionary using keys defined above :param segment: segment dictionary using keys defined above
:returns: segment dictionary with any defaulted attributes added
:raises: neutron.common.exceptions.InvalidInput if invalid :raises: neutron.common.exceptions.InvalidInput if invalid
Called outside transaction context to validate the provider Called outside transaction context to validate the provider

View File

@ -96,8 +96,6 @@ class FlatTypeDriver(api.TypeDriver):
msg = _("%s prohibited for flat provider network") % key msg = _("%s prohibited for flat provider network") % key
raise exc.InvalidInput(error_message=msg) raise exc.InvalidInput(error_message=msg)
return segment
def reserve_provider_segment(self, session, segment): def reserve_provider_segment(self, session, segment):
physical_network = segment[api.PHYSICAL_NETWORK] physical_network = segment[api.PHYSICAL_NETWORK]
with session.begin(subtransactions=True): with session.begin(subtransactions=True):

View File

@ -58,8 +58,7 @@ class GreEndpoints(model_base.BASEV2):
return "<GreTunnelEndpoint(%s)>" % self.ip_address return "<GreTunnelEndpoint(%s)>" % self.ip_address
class GreTypeDriver(api.TypeDriver, class GreTypeDriver(type_tunnel.TunnelTypeDriver):
type_tunnel.TunnelTypeDriver):
def get_type(self): def get_type(self):
return TYPE_GRE return TYPE_GRE
@ -73,18 +72,6 @@ class GreTypeDriver(api.TypeDriver,
) )
self._sync_gre_allocations() self._sync_gre_allocations()
def validate_provider_segment(self, segment):
physical_network = segment.get(api.PHYSICAL_NETWORK)
if physical_network:
msg = _("provider:physical_network specified for GRE "
"network")
raise exc.InvalidInput(error_message=msg)
segmentation_id = segment.get(api.SEGMENTATION_ID)
if not segmentation_id:
msg = _("segmentation_id required for GRE provider network")
raise exc.InvalidInput(error_message=msg)
def reserve_provider_segment(self, session, segment): def reserve_provider_segment(self, session, segment):
segmentation_id = segment.get(api.SEGMENTATION_ID) segmentation_id = segment.get(api.SEGMENTATION_ID)
with session.begin(subtransactions=True): with session.begin(subtransactions=True):

View File

@ -47,8 +47,6 @@ class LocalTypeDriver(api.TypeDriver):
msg = _("%s prohibited for local provider network") % key msg = _("%s prohibited for local provider network") % key
raise exc.InvalidInput(error_message=msg) raise exc.InvalidInput(error_message=msg)
return segment
def reserve_provider_segment(self, session, segment): def reserve_provider_segment(self, session, segment):
# No resources to reserve # No resources to reserve
pass pass

View File

@ -17,13 +17,14 @@ from abc import ABCMeta, abstractmethod
from neutron.common import exceptions as exc from neutron.common import exceptions as exc
from neutron.common import topics from neutron.common import topics
from neutron.openstack.common import log from neutron.openstack.common import log
from neutron.plugins.ml2 import driver_api as api
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
TUNNEL = 'tunnel' TUNNEL = 'tunnel'
class TunnelTypeDriver(object): class TunnelTypeDriver(api.TypeDriver):
"""Define stable abstract interface for ML2 type drivers. """Define stable abstract interface for ML2 type drivers.
tunnel type networks rely on tunnel endpoints. This class defines abstract tunnel type networks rely on tunnel endpoints. This class defines abstract
@ -63,6 +64,26 @@ class TunnelTypeDriver(object):
LOG.info(_("%(type)s ID ranges: %(range)s"), LOG.info(_("%(type)s ID ranges: %(range)s"),
{'type': tunnel_type, 'range': current_range}) {'type': tunnel_type, 'range': current_range})
def validate_provider_segment(self, segment):
physical_network = segment.get(api.PHYSICAL_NETWORK)
if physical_network:
msg = _("provider:physical_network specified for %s "
"network") % segment.get(api.NETWORK_TYPE)
raise exc.InvalidInput(error_message=msg)
segmentation_id = segment.get(api.SEGMENTATION_ID)
if not segmentation_id:
msg = _("segmentation_id required for %s provider "
"network") % segment.get(api.NETWORK_TYPE)
raise exc.InvalidInput(error_message=msg)
for key, value in segment.items():
if value and key not in [api.NETWORK_TYPE,
api.SEGMENTATION_ID]:
msg = (_("%(key)s prohibited for %(tunnel)s provider network"),
{'key': key, 'tunnel': segment.get(api.NETWORK_TYPE)})
raise exc.InvalidInput(error_message=msg)
class TunnelRpcCallbackMixin(object): class TunnelRpcCallbackMixin(object):

View File

@ -107,7 +107,7 @@ class VlanTypeDriver(api.TypeDriver):
# process vlan ranges for each configured physical network # process vlan ranges for each configured physical network
for (physical_network, for (physical_network,
vlan_ranges) in self.network_vlan_ranges.iteritems(): vlan_ranges) in self.network_vlan_ranges.items():
# determine current configured allocatable vlans for # determine current configured allocatable vlans for
# this physical network # this physical network
vlan_ids = set() vlan_ids = set()
@ -181,15 +181,13 @@ class VlanTypeDriver(api.TypeDriver):
'max': q_const.MAX_VLAN_TAG}) 'max': q_const.MAX_VLAN_TAG})
raise exc.InvalidInput(error_message=msg) raise exc.InvalidInput(error_message=msg)
for key, value in segment.iteritems(): for key, value in segment.items():
if value and key not in [api.NETWORK_TYPE, if value and key not in [api.NETWORK_TYPE,
api.PHYSICAL_NETWORK, api.PHYSICAL_NETWORK,
api.SEGMENTATION_ID]: api.SEGMENTATION_ID]:
msg = _("%s prohibited for VLAN provider network") % key msg = _("%s prohibited for VLAN provider network") % key
raise exc.InvalidInput(error_message=msg) raise exc.InvalidInput(error_message=msg)
return segment
def reserve_provider_segment(self, session, segment): def reserve_provider_segment(self, session, segment):
physical_network = segment[api.PHYSICAL_NETWORK] physical_network = segment[api.PHYSICAL_NETWORK]
vlan_id = segment[api.SEGMENTATION_ID] vlan_id = segment[api.SEGMENTATION_ID]

View File

@ -65,8 +65,7 @@ class VxlanEndpoints(model_base.BASEV2):
return "<VxlanTunnelEndpoint(%s)>" % self.ip_address return "<VxlanTunnelEndpoint(%s)>" % self.ip_address
class VxlanTypeDriver(api.TypeDriver, class VxlanTypeDriver(type_tunnel.TunnelTypeDriver):
type_tunnel.TunnelTypeDriver):
def get_type(self): def get_type(self):
return TYPE_VXLAN return TYPE_VXLAN
@ -80,18 +79,6 @@ class VxlanTypeDriver(api.TypeDriver,
) )
self._sync_vxlan_allocations() self._sync_vxlan_allocations()
def validate_provider_segment(self, segment):
physical_network = segment.get(api.PHYSICAL_NETWORK)
if physical_network:
msg = _("provider:physical_network specified for VXLAN "
"network")
raise exc.InvalidInput(error_message=msg)
segmentation_id = segment.get(api.SEGMENTATION_ID)
if segmentation_id is None:
msg = _("segmentation_id required for VXLAN provider network")
raise exc.InvalidInput(error_message=msg)
def reserve_provider_segment(self, session, segment): def reserve_provider_segment(self, session, segment):
segmentation_id = segment.get(api.SEGMENTATION_ID) segmentation_id = segment.get(api.SEGMENTATION_ID)
with session.begin(subtransactions=True): with session.begin(subtransactions=True):

View File

@ -82,7 +82,7 @@ class TypeManager(stevedore.named.NamedExtensionManager):
network_type = segment[api.NETWORK_TYPE] network_type = segment[api.NETWORK_TYPE]
driver = self.drivers.get(network_type) driver = self.drivers.get(network_type)
if driver: if driver:
return driver.obj.validate_provider_segment(segment) driver.obj.validate_provider_segment(segment)
else: else:
msg = _("network_type value '%s' not supported") % network_type msg = _("network_type value '%s' not supported") % network_type
raise exc.InvalidInput(error_message=msg) raise exc.InvalidInput(error_message=msg)

View File

@ -131,7 +131,9 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
segment = {api.NETWORK_TYPE: network_type, segment = {api.NETWORK_TYPE: network_type,
api.PHYSICAL_NETWORK: physical_network, api.PHYSICAL_NETWORK: physical_network,
api.SEGMENTATION_ID: segmentation_id} api.SEGMENTATION_ID: segmentation_id}
return self.type_manager.validate_provider_segment(segment) self.type_manager.validate_provider_segment(segment)
return segment
if (attributes.is_attr_set(attrs.get(provider.PHYSICAL_NETWORK)) or if (attributes.is_attr_set(attrs.get(provider.PHYSICAL_NETWORK)) or
attributes.is_attr_set(attrs.get(provider.SEGMENTATION_ID))): attributes.is_attr_set(attrs.get(provider.SEGMENTATION_ID))):