Merge "Set trunk status to DOWN when parent port is unbound"
This commit is contained in:
commit
86f7cfefb0
|
@ -25,6 +25,7 @@ from neutron.db import api as db_api
|
||||||
from neutron.db import common_db_mixin
|
from neutron.db import common_db_mixin
|
||||||
from neutron.db import db_base_plugin_common
|
from neutron.db import db_base_plugin_common
|
||||||
from neutron.db import db_base_plugin_v2
|
from neutron.db import db_base_plugin_v2
|
||||||
|
from neutron.extensions import portbindings
|
||||||
from neutron.objects import base as objects_base
|
from neutron.objects import base as objects_base
|
||||||
from neutron.objects import trunk as trunk_objects
|
from neutron.objects import trunk as trunk_objects
|
||||||
from neutron.services import service_base
|
from neutron.services import service_base
|
||||||
|
@ -70,6 +71,11 @@ class TrunkPlugin(service_base.ServicePluginBase,
|
||||||
drivers.register()
|
drivers.register()
|
||||||
registry.subscribe(rules.enforce_port_deletion_rules,
|
registry.subscribe(rules.enforce_port_deletion_rules,
|
||||||
resources.PORT, events.BEFORE_DELETE)
|
resources.PORT, events.BEFORE_DELETE)
|
||||||
|
# NOTE(tidwellr) Consider keying off of PRECOMMIT_UPDATE if we find
|
||||||
|
# AFTER_UPDATE to be problematic for setting trunk status when a
|
||||||
|
# a parent port becomes unbound.
|
||||||
|
registry.subscribe(self._trigger_trunk_status_change,
|
||||||
|
resources.PORT, events.AFTER_UPDATE)
|
||||||
registry.notify(constants.TRUNK_PLUGIN, events.AFTER_INIT, self)
|
registry.notify(constants.TRUNK_PLUGIN, events.AFTER_INIT, self)
|
||||||
for driver in self._drivers:
|
for driver in self._drivers:
|
||||||
LOG.debug('Trunk plugin loaded with driver %s', driver.name)
|
LOG.debug('Trunk plugin loaded with driver %s', driver.name)
|
||||||
|
@ -345,3 +351,22 @@ class TrunkPlugin(service_base.ServicePluginBase,
|
||||||
raise trunk_exc.TrunkNotFound(trunk_id=trunk_id)
|
raise trunk_exc.TrunkNotFound(trunk_id=trunk_id)
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
def _trigger_trunk_status_change(self, resource, event, trigger, **kwargs):
|
||||||
|
updated_port = kwargs['port']
|
||||||
|
trunk_details = updated_port.get('trunk_details')
|
||||||
|
# If no trunk_details, the port is not the parent of a trunk.
|
||||||
|
if not trunk_details:
|
||||||
|
return
|
||||||
|
|
||||||
|
context = kwargs['context']
|
||||||
|
original_port = kwargs['original_port']
|
||||||
|
orig_vif_type = original_port.get(portbindings.VIF_TYPE)
|
||||||
|
new_vif_type = updated_port.get(portbindings.VIF_TYPE)
|
||||||
|
vif_type_changed = orig_vif_type != new_vif_type
|
||||||
|
if vif_type_changed and new_vif_type == portbindings.VIF_TYPE_UNBOUND:
|
||||||
|
trunk = self._get_trunk(context, trunk_details['trunk_id'])
|
||||||
|
# NOTE(status_police) Trunk status goes to DOWN when the parent
|
||||||
|
# port is unbound. This means there are no more physical resources
|
||||||
|
# associated with the logical resource.
|
||||||
|
trunk.update(status=constants.DOWN_STATUS)
|
||||||
|
|
|
@ -19,6 +19,8 @@ import testtools
|
||||||
|
|
||||||
from neutron.callbacks import events
|
from neutron.callbacks import events
|
||||||
from neutron.callbacks import registry
|
from neutron.callbacks import registry
|
||||||
|
from neutron.callbacks import resources
|
||||||
|
from neutron.extensions import portbindings
|
||||||
from neutron import manager
|
from neutron import manager
|
||||||
from neutron.objects import trunk as trunk_objects
|
from neutron.objects import trunk as trunk_objects
|
||||||
from neutron.services.trunk import callbacks
|
from neutron.services.trunk import callbacks
|
||||||
|
@ -266,6 +268,51 @@ class TrunkPluginTestCase(test_plugin.Ml2PluginV2TestCase):
|
||||||
{'sub_ports': [{'port_id': subport['port']['id']}]})
|
{'sub_ports': [{'port_id': subport['port']['id']}]})
|
||||||
self.assertEqual(constants.DOWN_STATUS, trunk['status'])
|
self.assertEqual(constants.DOWN_STATUS, trunk['status'])
|
||||||
|
|
||||||
|
def test__trigger_trunk_status_change_vif_type_changed_unbound(self):
|
||||||
|
with self.port() as parent:
|
||||||
|
parent[portbindings.VIF_TYPE] = portbindings.VIF_TYPE_UNBOUND
|
||||||
|
original_port = {portbindings.VIF_TYPE: 'fakeviftype'}
|
||||||
|
self._test__trigger_trunk_status_change(parent,
|
||||||
|
original_port,
|
||||||
|
constants.ACTIVE_STATUS,
|
||||||
|
constants.DOWN_STATUS)
|
||||||
|
|
||||||
|
def test__trigger_trunk_status_change_vif_type_unchanged(self):
|
||||||
|
with self.port() as parent:
|
||||||
|
parent[portbindings.VIF_TYPE] = 'fakeviftype'
|
||||||
|
original_port = {portbindings.VIF_TYPE: 'fakeviftype'}
|
||||||
|
self._test__trigger_trunk_status_change(parent,
|
||||||
|
original_port,
|
||||||
|
constants.ACTIVE_STATUS,
|
||||||
|
constants.ACTIVE_STATUS)
|
||||||
|
|
||||||
|
def test__trigger_trunk_status_change_vif_type_changed(self):
|
||||||
|
with self.port() as parent:
|
||||||
|
parent[portbindings.VIF_TYPE] = 'realviftype'
|
||||||
|
original_port = {portbindings.VIF_TYPE: 'fakeviftype'}
|
||||||
|
self._test__trigger_trunk_status_change(parent,
|
||||||
|
original_port,
|
||||||
|
constants.ACTIVE_STATUS,
|
||||||
|
constants.ACTIVE_STATUS)
|
||||||
|
|
||||||
|
def _test__trigger_trunk_status_change(self, new_parent,
|
||||||
|
original_parent,
|
||||||
|
initial_trunk_status,
|
||||||
|
final_trunk_status):
|
||||||
|
trunk = self._create_test_trunk(new_parent)
|
||||||
|
trunk = self._get_trunk_obj(trunk['id'])
|
||||||
|
trunk.update(status=initial_trunk_status)
|
||||||
|
trunk_details = {'trunk_id': trunk.id}
|
||||||
|
new_parent['trunk_details'] = trunk_details
|
||||||
|
original_parent['trunk_details'] = trunk_details
|
||||||
|
kwargs = {'context': self.context, 'port': new_parent,
|
||||||
|
'original_port': original_parent}
|
||||||
|
self.trunk_plugin._trigger_trunk_status_change(resources.PORT,
|
||||||
|
events.AFTER_UPDATE,
|
||||||
|
None, **kwargs)
|
||||||
|
trunk = self._get_trunk_obj(trunk.id)
|
||||||
|
self.assertEqual(final_trunk_status, trunk.status)
|
||||||
|
|
||||||
|
|
||||||
class TrunkPluginDriversTestCase(test_plugin.Ml2PluginV2TestCase):
|
class TrunkPluginDriversTestCase(test_plugin.Ml2PluginV2TestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue