Merge "ML2 mechanism driver access to binding details"
This commit is contained in:
commit
24ac4a7de8
@ -218,7 +218,7 @@ class PortContext(object):
|
|||||||
|
|
||||||
@abstractproperty
|
@abstractproperty
|
||||||
def original(self):
|
def original(self):
|
||||||
"""Return the original state of the port
|
"""Return the original state of the port.
|
||||||
|
|
||||||
Return the original state of the port, prior to a call to
|
Return the original state of the port, prior to a call to
|
||||||
update_port. Method is only valid within calls to
|
update_port. Method is only valid within calls to
|
||||||
@ -236,6 +236,31 @@ class PortContext(object):
|
|||||||
"""Return the currently bound segment dictionary."""
|
"""Return the currently bound segment dictionary."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractproperty
|
||||||
|
def original_bound_segment(self):
|
||||||
|
"""Return the original bound segment dictionary.
|
||||||
|
|
||||||
|
Return the original bound segment dictionary, prior to a call
|
||||||
|
to update_port. Method is only valid within calls to
|
||||||
|
update_port_precommit and update_port_postcommit.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractproperty
|
||||||
|
def bound_driver(self):
|
||||||
|
"""Return the currently bound mechanism driver name."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractproperty
|
||||||
|
def original_bound_driver(self):
|
||||||
|
"""Return the original bound mechanism driver name.
|
||||||
|
|
||||||
|
Return the original bound mechanism driver name, prior to a
|
||||||
|
call to update_port. Method is only valid within calls to
|
||||||
|
update_port_precommit and update_port_postcommit.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def host_agents(self, agent_type):
|
def host_agents(self, agent_type):
|
||||||
"""Get agents of the specified type on port's host.
|
"""Get agents of the specified type on port's host.
|
||||||
|
@ -78,6 +78,12 @@ class PortContext(MechanismDriverContext, api.PortContext):
|
|||||||
network)
|
network)
|
||||||
self._binding = db.ensure_port_binding(plugin_context.session,
|
self._binding = db.ensure_port_binding(plugin_context.session,
|
||||||
port['id'])
|
port['id'])
|
||||||
|
if original_port:
|
||||||
|
self._original_bound_segment_id = self._binding.segment
|
||||||
|
self._original_bound_driver = self._binding.driver
|
||||||
|
else:
|
||||||
|
self._original_bound_segment_id = None
|
||||||
|
self._original_bound_driver = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current(self):
|
def current(self):
|
||||||
@ -99,6 +105,21 @@ class PortContext(MechanismDriverContext, api.PortContext):
|
|||||||
if segment[api.ID] == id:
|
if segment[api.ID] == id:
|
||||||
return segment
|
return segment
|
||||||
|
|
||||||
|
@property
|
||||||
|
def original_bound_segment(self):
|
||||||
|
if self._original_bound_segment_id:
|
||||||
|
for segment in self._network_context.network_segments:
|
||||||
|
if segment[api.ID] == self._original_bound_segment_id:
|
||||||
|
return segment
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bound_driver(self):
|
||||||
|
return self._binding.driver
|
||||||
|
|
||||||
|
@property
|
||||||
|
def original_bound_driver(self):
|
||||||
|
return self._original_bound_driver
|
||||||
|
|
||||||
def host_agents(self, agent_type):
|
def host_agents(self, agent_type):
|
||||||
return self._plugin.get_agents(self._plugin_context,
|
return self._plugin.get_agents(self._plugin_context,
|
||||||
filters={'agent_type': [agent_type],
|
filters={'agent_type': [agent_type],
|
||||||
|
@ -70,6 +70,18 @@ class FakePortContext(api.PortContext):
|
|||||||
if segment[api.ID] == self._bound_segment_id:
|
if segment[api.ID] == self._bound_segment_id:
|
||||||
return segment
|
return segment
|
||||||
|
|
||||||
|
@property
|
||||||
|
def original_bound_segment(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bound_driver(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def original_bound_driver(self):
|
||||||
|
return None
|
||||||
|
|
||||||
def host_agents(self, agent_type):
|
def host_agents(self, agent_type):
|
||||||
if agent_type == self._agent_type:
|
if agent_type == self._agent_type:
|
||||||
return self._agents
|
return self._agents
|
||||||
|
@ -83,11 +83,19 @@ class LoggerMechanismDriver(api.MechanismDriver):
|
|||||||
def _log_port_call(self, method_name, context):
|
def _log_port_call(self, method_name, context):
|
||||||
network_context = context.network
|
network_context = context.network
|
||||||
LOG.info(_("%(method)s called with port settings %(current)s "
|
LOG.info(_("%(method)s called with port settings %(current)s "
|
||||||
"(original settings %(original)s) on network %(network)s"),
|
"(original settings %(original)s) "
|
||||||
|
"bound to segment %(segment)s "
|
||||||
|
"(original segment %(original_segment)s) "
|
||||||
|
"using driver %(driver)s "
|
||||||
|
"(original driver %(original_driver)s) "
|
||||||
|
"on network %(network)s"),
|
||||||
{'method': method_name,
|
{'method': method_name,
|
||||||
'current': context.current,
|
'current': context.current,
|
||||||
'original': context.original,
|
'original': context.original,
|
||||||
'segment': context.bound_segment,
|
'segment': context.bound_segment,
|
||||||
|
'original_segment': context.original_bound_segment,
|
||||||
|
'driver': context.bound_driver,
|
||||||
|
'original_driver': context.original_bound_driver,
|
||||||
'network': network_context.current})
|
'network': network_context.current})
|
||||||
|
|
||||||
def create_port_precommit(self, context):
|
def create_port_precommit(self, context):
|
||||||
|
@ -84,11 +84,34 @@ class TestMechanismDriver(api.MechanismDriver):
|
|||||||
assert(isinstance(context, api.PortContext))
|
assert(isinstance(context, api.PortContext))
|
||||||
assert(isinstance(context.current, dict))
|
assert(isinstance(context.current, dict))
|
||||||
assert(context.current['id'] is not None)
|
assert(context.current['id'] is not None)
|
||||||
|
|
||||||
|
vif_type = context.current.get(portbindings.VIF_TYPE)
|
||||||
|
assert(vif_type is not None)
|
||||||
|
if vif_type in (portbindings.VIF_TYPE_UNBOUND,
|
||||||
|
portbindings.VIF_TYPE_BINDING_FAILED):
|
||||||
|
assert(context.bound_segment is None)
|
||||||
|
assert(context.bound_driver is None)
|
||||||
|
else:
|
||||||
|
assert(isinstance(context.bound_segment, dict))
|
||||||
|
assert(context.bound_driver == 'test')
|
||||||
|
|
||||||
if original_expected:
|
if original_expected:
|
||||||
assert(isinstance(context.original, dict))
|
assert(isinstance(context.original, dict))
|
||||||
assert(context.current['id'] == context.original['id'])
|
assert(context.current['id'] == context.original['id'])
|
||||||
|
vif_type = context.original.get(portbindings.VIF_TYPE)
|
||||||
|
assert(vif_type is not None)
|
||||||
|
if vif_type in (portbindings.VIF_TYPE_UNBOUND,
|
||||||
|
portbindings.VIF_TYPE_BINDING_FAILED):
|
||||||
|
assert(context.original_bound_segment is None)
|
||||||
|
assert(context.original_bound_driver is None)
|
||||||
else:
|
else:
|
||||||
assert(not context.original)
|
assert(isinstance(context.original_bound_segment, dict))
|
||||||
|
assert(context.original_bound_driver == 'test')
|
||||||
|
else:
|
||||||
|
assert(context.original is None)
|
||||||
|
assert(context.original_bound_segment is None)
|
||||||
|
assert(context.original_bound_driver is None)
|
||||||
|
|
||||||
network_context = context.network
|
network_context = context.network
|
||||||
assert(isinstance(network_context, api.NetworkContext))
|
assert(isinstance(network_context, api.NetworkContext))
|
||||||
self._check_network_context(network_context, False)
|
self._check_network_context(network_context, False)
|
||||||
@ -112,7 +135,12 @@ class TestMechanismDriver(api.MechanismDriver):
|
|||||||
self._check_port_context(context, False)
|
self._check_port_context(context, False)
|
||||||
|
|
||||||
def bind_port(self, context):
|
def bind_port(self, context):
|
||||||
self._check_port_context(context, False)
|
# REVISIT(rkukura): Currently, bind_port() is called as part
|
||||||
|
# of either a create or update transaction. The fix for bug
|
||||||
|
# 1276391 will change it to be called outside any transaction,
|
||||||
|
# so the context.original* will no longer be available.
|
||||||
|
self._check_port_context(context, context.original is not None)
|
||||||
|
|
||||||
host = context.current.get(portbindings.HOST_ID, None)
|
host = context.current.get(portbindings.HOST_ID, None)
|
||||||
segment = context.network.network_segments[0][api.ID]
|
segment = context.network.network_segments[0][api.ID]
|
||||||
if host == "host-ovs-no_filter":
|
if host == "host-ovs-no_filter":
|
||||||
@ -123,8 +151,18 @@ class TestMechanismDriver(api.MechanismDriver):
|
|||||||
{portbindings.CAP_PORT_FILTER: True})
|
{portbindings.CAP_PORT_FILTER: True})
|
||||||
|
|
||||||
def validate_port_binding(self, context):
|
def validate_port_binding(self, context):
|
||||||
self._check_port_context(context, False)
|
# REVISIT(rkukura): Currently, validate_port_binding() is
|
||||||
|
# called as part of either a create or update transaction. The
|
||||||
|
# fix for bug 1276391 will change it to be called outside any
|
||||||
|
# transaction (or eliminate it altogether), so the
|
||||||
|
# context.original* will no longer be available.
|
||||||
|
self._check_port_context(context, context.original is not None)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def unbind_port(self, context):
|
def unbind_port(self, context):
|
||||||
self._check_port_context(context, False)
|
# REVISIT(rkukura): Currently, unbind_port() is called as part
|
||||||
|
# of either an update or delete transaction. The fix for bug
|
||||||
|
# 1276391 will change it to be called outside any transaction
|
||||||
|
# (or eliminate it altogether), so the context.original* will
|
||||||
|
# no longer be available.
|
||||||
|
self._check_port_context(context, context.original is not None)
|
||||||
|
@ -109,18 +109,18 @@ class PortBindingTestCase(test_plugin.NeutronDbPluginV2TestCase):
|
|||||||
self.assertFalse(notify_mock.called)
|
self.assertFalse(notify_mock.called)
|
||||||
|
|
||||||
def test_update_with_new_host_binding_notifies_agent(self):
|
def test_update_with_new_host_binding_notifies_agent(self):
|
||||||
self._test_update_port_binding('host-ovs-no-filter',
|
self._test_update_port_binding('host-ovs-no_filter',
|
||||||
'host-bridge-no-filter')
|
'host-bridge-filter')
|
||||||
|
|
||||||
def test_update_with_same_host_binding_does_not_notify(self):
|
def test_update_with_same_host_binding_does_not_notify(self):
|
||||||
self._test_update_port_binding('host-ovs-no-filter',
|
self._test_update_port_binding('host-ovs-no_filter',
|
||||||
'host-ovs-no-filter')
|
'host-ovs-no_filter')
|
||||||
|
|
||||||
def test_update_without_binding_does_not_notify(self):
|
def test_update_without_binding_does_not_notify(self):
|
||||||
self._test_update_port_binding('host-ovs-no-filter')
|
self._test_update_port_binding('host-ovs-no_filter')
|
||||||
|
|
||||||
def testt_update_from_empty_to_host_binding_notifies_agent(self):
|
def testt_update_from_empty_to_host_binding_notifies_agent(self):
|
||||||
self._test_update_port_binding('', 'host-ovs-no-filter')
|
self._test_update_port_binding('', 'host-ovs-no_filter')
|
||||||
|
|
||||||
def test_update_from_host_to_empty_binding_notifies_agent(self):
|
def test_update_from_host_to_empty_binding_notifies_agent(self):
|
||||||
self._test_update_port_binding('host-ovs-no-filter', '')
|
self._test_update_port_binding('host-ovs-no_filter', '')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user