from neutron.extensions import portbindings
from neutron.i18n import _LW
from neutron.openstack.common import log
+from neutron.plugins.common import constants as p_constants
from neutron.plugins.ml2 import driver_api as api
LOG = log.getLogger(__name__)
return False
@abc.abstractmethod
+ def get_allowed_network_types(self, agent=None):
+ """Return the agent's or driver's allowed network types.
+
+ For example: return ('flat', ...). You can also refer to the
+ configuration the given agent exposes.
+ """
+ pass
+
+ @abc.abstractmethod
+ def get_mappings(self, agent):
+ """Return the agent's bridge or interface mappings.
+
+ For example: agent['configurations'].get('bridge_mappings', {}).
+ """
+ pass
+
+ def physnet_in_mappings(self, physnet, mappings):
+ """Is the physical network part of the given mappings?"""
+ return physnet in mappings
+
def check_segment_for_agent(self, segment, agent):
"""Check if segment can be bound for agent.
determine whether or not the specified network segment can be
bound for the agent.
"""
+
+ mappings = self.get_mappings(agent)
+ allowed_network_types = self.get_allowed_network_types(agent)
+
+ LOG.debug("Checking segment: %(segment)s "
+ "for mappings: %(mappings)s "
+ "with network types: %(network_types)s",
+ {'segment': segment, 'mappings': mappings,
+ 'network_types': allowed_network_types})
+
+ network_type = segment[api.NETWORK_TYPE]
+ if network_type not in allowed_network_types:
+ LOG.debug(
+ 'Network %(network_id)s is of type %(network_type)s '
+ 'but agent %(agent)s or mechanism driver only '
+ 'support %(allowed_network_types)s.',
+ {'network_id': segment['id'],
+ 'network_type': network_type,
+ 'agent': agent['host'],
+ 'allowed_network_types': allowed_network_types})
+ return False
+
+ if network_type in [p_constants.TYPE_FLAT, p_constants.TYPE_VLAN]:
+ physnet = segment[api.PHYSICAL_NETWORK]
+ if not self.physnet_in_mappings(physnet, mappings):
+ LOG.debug(
+ 'Network %(network_id)s is connected to physical '
+ 'network %(physnet)s, but agent %(agent)s reported '
+ 'physical networks %(mappings)s. '
+ 'The physical network must be configured on the '
+ 'agent if binding is to succeed.',
+ {'network_id': segment['id'],
+ 'physnet': physnet,
+ 'agent': agent['host'],
+ 'mappings': mappings})
+ return False
+
+ return True
from neutron.common import constants
from neutron.extensions import portbindings
from neutron.openstack.common import log
-from neutron.plugins.ml2 import driver_api as api
+from neutron.plugins.common import constants as p_constants
from neutron.plugins.ml2.drivers import mech_agent
LOG = log.getLogger(__name__)
portbindings.VIF_TYPE_HYPERV,
{portbindings.CAP_PORT_FILTER: False})
- def check_segment_for_agent(self, segment, agent):
- mappings = agent['configurations'].get('vswitch_mappings', {})
- LOG.debug("Checking segment: %(segment)s "
- "for mappings: %(mappings)s",
- {'segment': segment, 'mappings': mappings})
- network_type = segment[api.NETWORK_TYPE]
- if network_type == 'local':
- return True
- elif network_type in ['flat', 'vlan']:
- for pattern in mappings:
- if re.match(pattern, segment[api.PHYSICAL_NETWORK]):
- return True
- return False
+ def get_allowed_network_types(self, agent=None):
+ return [p_constants.TYPE_LOCAL, p_constants.TYPE_FLAT,
+ p_constants.TYPE_VLAN]
+
+ def get_mappings(self, agent):
+ return agent['configurations'].get('vswitch_mappings', {})
+
+ def physnet_in_mappings(self, physnet, mappings):
+ return any(re.match(pattern, physnet) for pattern in mappings)
from neutron.agent import securitygroups_rpc
from neutron.common import constants
from neutron.extensions import portbindings
-from neutron.i18n import _LW
from neutron.openstack.common import log
-from neutron.plugins.ml2 import driver_api as api
+from neutron.plugins.common import constants as p_constants
from neutron.plugins.ml2.drivers import mech_agent
LOG = log.getLogger(__name__)
portbindings.VIF_TYPE_BRIDGE,
{portbindings.CAP_PORT_FILTER: sg_enabled})
- def check_segment_for_agent(self, segment, agent):
- mappings = agent['configurations'].get('interface_mappings', {})
- tunnel_types = agent['configurations'].get('tunnel_types', [])
- LOG.debug("Checking segment: %(segment)s "
- "for mappings: %(mappings)s "
- "with tunnel_types: %(tunnel_types)s",
- {'segment': segment, 'mappings': mappings,
- 'tunnel_types': tunnel_types})
- network_type = segment[api.NETWORK_TYPE]
- if network_type == 'local':
- return True
- elif network_type in tunnel_types:
- return True
- elif network_type in ['flat', 'vlan']:
- is_mapping_present = segment[api.PHYSICAL_NETWORK] in mappings
- if not is_mapping_present:
- LOG.warn(_LW("Failed to find %(seg)s in mappings %(map)s"),
- {'seg': segment[api.PHYSICAL_NETWORK],
- 'map': mappings})
- return is_mapping_present
- else:
- return False
+ def get_allowed_network_types(self, agent):
+ return (agent['configurations'].get('tunnel_types', []) +
+ [p_constants.TYPE_LOCAL, p_constants.TYPE_FLAT,
+ p_constants.TYPE_VLAN])
+
+ def get_mappings(self, agent):
+ return agent['configurations'].get('interface_mappings', {})
from neutron.common import constants
from neutron.extensions import portbindings
from neutron.openstack.common import log
-from neutron.plugins.common import constants as p_const
-from neutron.plugins.ml2 import driver_api as api
+from neutron.plugins.common import constants as p_constants
from neutron.plugins.ml2.drivers import mech_agent
LOG = log.getLogger(__name__)
portbindings.VIF_TYPE_OVS,
vif_details)
- def check_segment_for_agent(self, segment, agent):
- interface_mappings = agent['configurations'].get('interface_mappings',
- {})
- tunnel_types = agent['configurations'].get('tunnel_types', [])
- LOG.debug("Checking segment: %(segment)s "
- "for interface_mappings: %(interface_mappings)s "
- "with tunnel_types: %(tunnel_types)s",
- {'segment': segment,
- 'interface_mappings': interface_mappings,
- 'tunnel_types': tunnel_types})
- network_type = segment[api.NETWORK_TYPE]
- return (
- network_type == p_const.TYPE_LOCAL or
- network_type in tunnel_types or
- (network_type in [p_const.TYPE_FLAT, p_const.TYPE_VLAN] and
- segment[api.PHYSICAL_NETWORK] in interface_mappings)
- )
+ def get_allowed_network_types(self, agent):
+ return (agent['configurations'].get('tunnel_types', []) +
+ [p_constants.TYPE_LOCAL, p_constants.TYPE_FLAT,
+ p_constants.TYPE_VLAN])
+
+ def get_mappings(self, agent):
+ return dict(agent['configurations'].get('interface_mappings', {}))
from neutron.agent import securitygroups_rpc
from neutron.common import constants
from neutron.extensions import portbindings
-from neutron.i18n import _LW
from neutron.openstack.common import log
-from neutron.plugins.ml2 import driver_api as api
+from neutron.plugins.common import constants as p_constants
from neutron.plugins.ml2.drivers import mech_agent
LOG = log.getLogger(__name__)
portbindings.VIF_TYPE_OVS,
vif_details)
- def check_segment_for_agent(self, segment, agent):
- mappings = agent['configurations'].get('bridge_mappings', {})
- tunnel_types = agent['configurations'].get('tunnel_types', [])
- LOG.debug("Checking segment: %(segment)s "
- "for mappings: %(mappings)s "
- "with tunnel_types: %(tunnel_types)s",
- {'segment': segment, 'mappings': mappings,
- 'tunnel_types': tunnel_types})
- network_type = segment[api.NETWORK_TYPE]
- if network_type == 'local':
- return True
- elif network_type in tunnel_types:
- return True
- elif network_type in ['flat', 'vlan']:
- is_mapping_present = segment[api.PHYSICAL_NETWORK] in mappings
- if not is_mapping_present:
- LOG.warn(_LW("Failed to find %(seg)s in mappings %(map)s"),
- {'seg': segment[api.PHYSICAL_NETWORK],
- 'map': mappings})
- return is_mapping_present
- else:
- return False
+ def get_allowed_network_types(self, agent):
+ return (agent['configurations'].get('tunnel_types', []) +
+ [p_constants.TYPE_LOCAL, p_constants.TYPE_FLAT,
+ p_constants.TYPE_VLAN])
+
+ def get_mappings(self, agent):
+ return agent['configurations'].get('bridge_mappings', {})
from neutron.common import constants
from neutron.extensions import portbindings
from neutron.openstack.common import log
+from neutron.plugins.common import constants as p_constants
from neutron.plugins.ml2 import driver_api as api
from neutron.plugins.ml2.drivers import mech_agent
from neutron.plugins.ml2.drivers.mlnx import config # noqa
{portbindings.CAP_PORT_FILTER: False},
portbindings.VNIC_TYPES)
- def check_segment_for_agent(self, segment, agent):
- mappings = agent['configurations'].get('interface_mappings', {})
- LOG.debug("Checking segment: %(segment)s "
- "for mappings: %(mappings)s ",
- {'segment': segment, 'mappings': mappings})
+ def get_allowed_network_types(self, agent=None):
+ return [p_constants.TYPE_LOCAL, p_constants.TYPE_FLAT,
+ p_constants.TYPE_VLAN]
- network_type = segment[api.NETWORK_TYPE]
- if network_type == 'local':
- return True
- elif network_type in ['flat', 'vlan']:
- return segment[api.PHYSICAL_NETWORK] in mappings
- else:
- return False
+ def get_mappings(self, agent):
+ return agent['configurations'].get('interface_mappings', {})
def try_to_bind_segment_for_agent(self, context, segment, agent):
if self.check_segment_for_agent(segment, agent):
from neutron.extensions import multiprovidernet as mpnet
from neutron.extensions import portbindings
from neutron.extensions import providernet as provider
-from neutron.i18n import _LE, _LI, _LW
+from neutron.i18n import _LE, _LI
from neutron.openstack.common import log
from neutron.plugins.ml2.common import exceptions as ml2_exc
from neutron.plugins.ml2 import db
"bind_port"),
driver.name)
binding.vif_type = portbindings.VIF_TYPE_BINDING_FAILED
- LOG.warning(_LW("Failed to bind port %(port)s on host %(host)s"),
- {'port': context._port['id'],
- 'host': binding.host})
+ LOG.error(_LE("Failed to bind port %(port)s on host %(host)s"),
+ {'port': context._port['id'],
+ 'host': binding.host})
class ExtensionManager(stevedore.named.NamedExtensionManager):
BAD_CONFIGS = {'interface_mappings': BAD_MAPPINGS}
AGENTS = [{'alive': True,
- 'configurations': GOOD_CONFIGS}]
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'host'}]
AGENTS_DEAD = [{'alive': False,
- 'configurations': GOOD_CONFIGS}]
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'dead_host'}]
AGENTS_BAD = [{'alive': False,
- 'configurations': GOOD_CONFIGS},
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'bad_host_1'},
{'alive': True,
- 'configurations': BAD_CONFIGS}]
+ 'configurations': BAD_CONFIGS,
+ 'host': 'bad_host_2'}]
def setUp(self):
super(MlnxMechanismBaseTestCase, self).setUp()
'tunnel_types': BAD_TUNNEL_TYPES}
AGENTS = [{'alive': True,
- 'configurations': GOOD_CONFIGS}]
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'host'}]
AGENTS_DEAD = [{'alive': False,
- 'configurations': GOOD_CONFIGS}]
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'dead_host'}]
AGENTS_BAD = [{'alive': False,
- 'configurations': GOOD_CONFIGS},
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'bad_host_1'},
{'alive': True,
- 'configurations': BAD_CONFIGS}]
+ 'configurations': BAD_CONFIGS,
+ 'host': 'bad_host_2'}]
def setUp(self):
super(OfagentMechanismBaseTestCase, self).setUp()
BAD_CONFIGS = {'vswitch_mappings': BAD_MAPPINGS}
AGENTS = [{'alive': True,
- 'configurations': GOOD_CONFIGS}]
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'host'}]
AGENTS_DEAD = [{'alive': False,
- 'configurations': GOOD_CONFIGS}]
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'dead_host'}]
AGENTS_BAD = [{'alive': False,
- 'configurations': GOOD_CONFIGS},
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'bad_host_1'},
{'alive': True,
- 'configurations': BAD_CONFIGS}]
+ 'configurations': BAD_CONFIGS,
+ 'host': 'bad_host_2'}]
def setUp(self):
super(HypervMechanismBaseTestCase, self).setUp()
'tunnel_types': BAD_TUNNEL_TYPES}
AGENTS = [{'alive': True,
- 'configurations': GOOD_CONFIGS}]
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'host'}]
AGENTS_DEAD = [{'alive': False,
- 'configurations': GOOD_CONFIGS}]
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'dead_host'}]
AGENTS_BAD = [{'alive': False,
- 'configurations': GOOD_CONFIGS},
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'bad_host_1'},
{'alive': True,
- 'configurations': BAD_CONFIGS}]
+ 'configurations': BAD_CONFIGS,
+ 'host': 'bad_host_2'}]
def setUp(self):
super(LinuxbridgeMechanismBaseTestCase, self).setUp()
'tunnel_types': BAD_TUNNEL_TYPES}
AGENTS = [{'alive': True,
- 'configurations': GOOD_CONFIGS}]
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'host'}]
AGENTS_DEAD = [{'alive': False,
- 'configurations': GOOD_CONFIGS}]
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'dead_host'}]
AGENTS_BAD = [{'alive': False,
- 'configurations': GOOD_CONFIGS},
+ 'configurations': GOOD_CONFIGS,
+ 'host': 'bad_host_1'},
{'alive': True,
- 'configurations': BAD_CONFIGS}]
+ 'configurations': BAD_CONFIGS,
+ 'host': 'bad_host_2'}]
def setUp(self):
super(OpenvswitchMechanismBaseTestCase, self).setUp()