ML2: Call _dict_extend in create_(net|port) ops
The extensions fields were not being added to the response being sent back to the user for ports and networks that weren't from ML2 extensions (e.g. availability zones). This created an inconsistent response between creates and updates/gets. It also resulted in incomplete data in the AMQP create notification emitted in the API layer. This patch adjusts ML2 to call the _apply_dict_extend_functions method after creating ports and networks. To make this work, another DB lookup to get the latest model state was necessary. However, this is part of an already expensive operation (create) so the performance impact should be minimal. This issue stems from the fact that db_base_plugin_v2 does not process extensions when its create_port, create_network methods are called. This original skipping behavior was added back in patch If0f0277191884aab4dcb1ee36826df7f7d66a8fa as a performance improvement to deal with dictionary extension functions that performed DB lookups. However, at this point the dictionary extension functions should have been optimized to skip any DB lookups to avoid the massive performance penalties they incur during list operations. An alternative to this patch was to adjust the db_base_plugin_v2 to stop skipping extensions. However, because this is usually called by inheriting plugins before they process extensions for the new port/network, the extensions do not yet have the required information to extend the dict and will fail. So each core plugin will need to apply similar logic to support extensions that rely on the extend_dict functions. Closes-Bug: #1541774 Change-Id: Iea2c0e7f9ee5eeae28b99797874ca8a8e5790ec2
This commit is contained in:
parent
e720bc29f3
commit
b6d091279f
neutron
plugins/ml2
tests/unit
@ -671,6 +671,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
result['id'], {'network': {'vlan_transparent': vlt}})
|
||||
result['vlan_transparent'] = vlt
|
||||
|
||||
# NOTE(kevinbenton): this extra lookup is necessary to get the
|
||||
# latest db model for the extension functions
|
||||
net_model = self._get_network(context, result['id'])
|
||||
self._apply_dict_extend_functions('networks', result, net_model)
|
||||
return result, mech_context
|
||||
|
||||
def create_network(self, context, network):
|
||||
@ -1063,6 +1067,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
dhcp_opts)
|
||||
self.mechanism_manager.create_port_precommit(mech_context)
|
||||
|
||||
# NOTE(kevinbenton): this extra lookup is necessary to get the
|
||||
# latest db model for the extension functions
|
||||
port_model = self._get_port(context, result['id'])
|
||||
self._apply_dict_extend_functions('ports', result, port_model)
|
||||
return result, mech_context
|
||||
|
||||
def create_port(self, context, port):
|
||||
|
@ -98,6 +98,11 @@ class TestAZNetworkCase(AZTestCommon):
|
||||
ext_mgr = AZExtensionManager()
|
||||
super(TestAZNetworkCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr)
|
||||
|
||||
def test_availability_zones_in_create_response(self):
|
||||
with self.network() as net:
|
||||
self.assertIn('availability_zone_hints', net['network'])
|
||||
self.assertIn('availability_zones', net['network'])
|
||||
|
||||
def test_create_network_with_az(self):
|
||||
self._register_azs()
|
||||
az_hints = ['nova1']
|
||||
|
@ -81,7 +81,7 @@ class ExtensionDriverTestCase(test_plugin.Ml2PluginV2TestCase):
|
||||
def test_faulty_extend_dict(self):
|
||||
with mock.patch.object(ext_test.TestExtensionDriver,
|
||||
'extend_network_dict',
|
||||
side_effect=[None, TypeError]):
|
||||
side_effect=[None, None, TypeError]):
|
||||
network, tid = self._verify_network_create(201, None)
|
||||
self._verify_network_update(network, 400, 'ExtensionDriverError')
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user