Add extension fields on network and port create

Add extension fields to the response on network and port create.
This patch set is based on [1] which calls for each core plugin
to apply similar logic to support extensions that rely on
extend_dict functions.

We saw the issue with CI failures after the addition of the
timestamp extension.

[1] https://review.openstack.org/#/c/276219/

Co-Authored-by: Salvatore Orlando <salv.orlando@gmail.com>

Change-Id: I15bff78610681d3ad36766138316a249efb21ae6
This commit is contained in:
Gary Kotton 2016-03-06 07:47:23 -08:00
parent de9b2de472
commit 63a12ec964
6 changed files with 55 additions and 18 deletions

View File

@ -160,6 +160,12 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
new_net[pnet.NETWORK_TYPE] = net_data.get(pnet.NETWORK_TYPE) new_net[pnet.NETWORK_TYPE] = net_data.get(pnet.NETWORK_TYPE)
new_net[pnet.PHYSICAL_NETWORK] = 'dvs' new_net[pnet.PHYSICAL_NETWORK] = 'dvs'
new_net[pnet.SEGMENTATION_ID] = vlan_tag new_net[pnet.SEGMENTATION_ID] = vlan_tag
# this extra lookup is necessary to get the
# latest db model for the extension functions
net_model = self._get_network(context, net_data['id'])
self._apply_dict_extend_functions('networks', new_net, net_model)
self.handle_network_dhcp_access(context, new_net, self.handle_network_dhcp_access(context, new_net,
action='create_network') action='create_network')
return new_net return new_net
@ -300,6 +306,11 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
# DB Operation is complete, perform DVS operation # DB Operation is complete, perform DVS operation
port_data = port['port'] port_data = port['port']
# this extra lookup is necessary to get the
# latest db model for the extension functions
port_model = self._get_port(context, port_data['id'])
self._apply_dict_extend_functions('ports', port_data, port_model)
self.handle_port_dhcp_access(context, port_data, action='create_port') self.handle_port_dhcp_access(context, port_data, action='create_port')
return port_data return port_data

View File

@ -981,6 +981,11 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
self._extend_network_dict_provider(context, new_net, self._extend_network_dict_provider(context, new_net,
provider_type, provider_type,
net_bindings) net_bindings)
# this extra lookup is necessary to get the
# latest db model for the extension functions
net_model = self._get_network(context, new_net['id'])
self._apply_dict_extend_functions('networks', new_net, net_model)
self.handle_network_dhcp_access(context, new_net, self.handle_network_dhcp_access(context, new_net,
action='create_network') action='create_network')
return new_net return new_net
@ -1168,7 +1173,10 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
"attachment in NSX.")) "attachment in NSX."))
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
self.ipam.delete_port(context, neutron_port_id) self.ipam.delete_port(context, neutron_port_id)
# this extra lookup is necessary to get the
# latest db model for the extension functions
port_model = self._get_port(context, neutron_port_id)
self._apply_dict_extend_functions('ports', port_data, port_model)
self.handle_port_dhcp_access(context, port_data, action='create_port') self.handle_port_dhcp_access(context, port_data, action='create_port')
return port_data return port_data

View File

@ -684,6 +684,10 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
self._delete_backend_network(net_moref) self._delete_backend_network(net_moref)
LOG.exception(_LE('Failed to create network')) LOG.exception(_LE('Failed to create network'))
# this extra lookup is necessary to get the
# latest db model for the extension functions
net_model = self._get_network(context, new_net['id'])
self._apply_dict_extend_functions('networks', new_net, net_model)
return new_net return new_net
def _cleanup_dhcp_edge_before_deletion(self, context, net_id): def _cleanup_dhcp_edge_before_deletion(self, context, net_id):
@ -890,6 +894,11 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
LOG.exception(_LE('Failed to create port')) LOG.exception(_LE('Failed to create port'))
# Revert what we have created and raise the exception # Revert what we have created and raise the exception
self.delete_port(context, port_data['id']) self.delete_port(context, port_data['id'])
# this extra lookup is necessary to get the
# latest db model for the extension functions
port_model = self._get_port(context, port_data['id'])
self._apply_dict_extend_functions('ports', port_data, port_model)
return port_data return port_data
def update_port(self, context, id, port): def update_port(self, context, id, port):

View File

@ -472,6 +472,10 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
if net_type != utils.NetworkTypes.L3_EXT: if net_type != utils.NetworkTypes.L3_EXT:
nsxlib.delete_logical_switch(created_net['id']) nsxlib.delete_logical_switch(created_net['id'])
# this extra lookup is necessary to get the
# latest db model for the extension functions
net_model = self._get_network(context, created_net['id'])
self._apply_dict_extend_functions('networks', created_net, net_model)
return created_net return created_net
def _retry_delete_network(self, context, network_id): def _retry_delete_network(self, context, network_id):
@ -847,6 +851,10 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
super(NsxV3Plugin, self).delete_port(context, super(NsxV3Plugin, self).delete_port(context,
neutron_db['id']) neutron_db['id'])
# this extra lookup is necessary to get the
# latest db model for the extension functions
port_model = self._get_port(context, port_data['id'])
self._apply_dict_extend_functions('ports', port_data, port_model)
nsx_rpc.handle_port_metadata_access(self, context, neutron_db) nsx_rpc.handle_port_metadata_access(self, context, neutron_db)
return port_data return port_data

View File

@ -131,20 +131,23 @@ class MetaDataTestCase(object):
r['router']['id'], r['router']['id'],
s['subnet']['id'], s['subnet']['id'],
None) None)
# Verify that the metadata network gets scheduled, so that # Verify that there has been a schedule_network all for the
# an active dhcp agent can pick it up. # metadata network
expected_meta_net = { expected_net_name = 'meta-%s' % r['router']['id']
'status': 'ACTIVE', found = False
'subnets': [], for call in f.call_args_list:
'name': 'meta-%s' % r['router']['id'], # The network data are the last of the positional arguments
'admin_state_up': True, net_dict = call[0][-1]
'tenant_id': '', if net_dict['name'] == expected_net_name:
'port_security_enabled': False, self.assertFalse(net_dict['port_security_enabled'])
'shared': False, self.assertFalse(net_dict['shared'])
'id': mock.ANY, self.assertFalse(net_dict['tenant_id'])
'mtu': mock.ANY found = True
} break
f.assert_any_call(mock.ANY, expected_meta_net) else:
self.fail("Expected schedule_network call for metadata "
"network %s not found" % expected_net_name)
self.assertTrue(found)
self._metadata_teardown() self._metadata_teardown()
def test_metadata_network_create_rollback_on_create_subnet_failure(self): def test_metadata_network_create_rollback_on_create_subnet_failure(self):

View File

@ -19,7 +19,6 @@ import webob.exc
from neutron.api.v2 import attributes from neutron.api.v2 import attributes
from neutron import context from neutron import context
from neutron.db import models_v2 from neutron.db import models_v2
from neutron.extensions import availability_zone as az_ext
from neutron.extensions import external_net from neutron.extensions import external_net
from neutron.extensions import extraroute from neutron.extensions import extraroute
from neutron.extensions import l3 from neutron.extensions import l3
@ -192,8 +191,7 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxV3PluginTestCaseMixin):
mock_validate_az.return_value = None mock_validate_az.return_value = None
with self.network(name=name, availability_zone_hints=zone) as net: with self.network(name=name, availability_zone_hints=zone) as net:
az_hints = net['network']['availability_zone_hints'] az_hints = net['network']['availability_zone_hints']
az_hints_list = az_ext.convert_az_string_to_list(az_hints) self.assertListEqual(az_hints, zone)
self.assertListEqual(az_hints_list, zone)
class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin, class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin,