From 63a12ec96430f03b80411106428cd744d2957f04 Mon Sep 17 00:00:00 2001 From: Gary Kotton Date: Sun, 6 Mar 2016 07:47:23 -0800 Subject: [PATCH] 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 Change-Id: I15bff78610681d3ad36766138316a249efb21ae6 --- vmware_nsx/plugins/dvs/plugin.py | 11 +++++++ vmware_nsx/plugins/nsx_mh/plugin.py | 10 +++++- vmware_nsx/plugins/nsx_v/plugin.py | 9 ++++++ vmware_nsx/plugins/nsx_v3/plugin.py | 8 +++++ .../tests/unit/extensions/test_metadata.py | 31 ++++++++++--------- vmware_nsx/tests/unit/nsx_v3/test_plugin.py | 4 +-- 6 files changed, 55 insertions(+), 18 deletions(-) diff --git a/vmware_nsx/plugins/dvs/plugin.py b/vmware_nsx/plugins/dvs/plugin.py index 65cd27f12d..798112c088 100644 --- a/vmware_nsx/plugins/dvs/plugin.py +++ b/vmware_nsx/plugins/dvs/plugin.py @@ -160,6 +160,12 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin, new_net[pnet.NETWORK_TYPE] = net_data.get(pnet.NETWORK_TYPE) new_net[pnet.PHYSICAL_NETWORK] = 'dvs' 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, action='create_network') return new_net @@ -300,6 +306,11 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin, # DB Operation is complete, perform DVS operation 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') return port_data diff --git a/vmware_nsx/plugins/nsx_mh/plugin.py b/vmware_nsx/plugins/nsx_mh/plugin.py index ce29b0ce84..acbd735a61 100644 --- a/vmware_nsx/plugins/nsx_mh/plugin.py +++ b/vmware_nsx/plugins/nsx_mh/plugin.py @@ -981,6 +981,11 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin, self._extend_network_dict_provider(context, new_net, provider_type, 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, action='create_network') return new_net @@ -1168,7 +1173,10 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin, "attachment in NSX.")) with context.session.begin(subtransactions=True): 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') return port_data diff --git a/vmware_nsx/plugins/nsx_v/plugin.py b/vmware_nsx/plugins/nsx_v/plugin.py index f004c1444d..7f0bb91674 100644 --- a/vmware_nsx/plugins/nsx_v/plugin.py +++ b/vmware_nsx/plugins/nsx_v/plugin.py @@ -684,6 +684,10 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, self._delete_backend_network(net_moref) 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 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')) # Revert what we have created and raise the exception 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 def update_port(self, context, id, port): diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index 07775f5827..3651ccf321 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -472,6 +472,10 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin, if net_type != utils.NetworkTypes.L3_EXT: 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 def _retry_delete_network(self, context, network_id): @@ -847,6 +851,10 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin, super(NsxV3Plugin, self).delete_port(context, 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) return port_data diff --git a/vmware_nsx/tests/unit/extensions/test_metadata.py b/vmware_nsx/tests/unit/extensions/test_metadata.py index 407de7e324..ed59008b1b 100644 --- a/vmware_nsx/tests/unit/extensions/test_metadata.py +++ b/vmware_nsx/tests/unit/extensions/test_metadata.py @@ -131,20 +131,23 @@ class MetaDataTestCase(object): r['router']['id'], s['subnet']['id'], None) - # Verify that the metadata network gets scheduled, so that - # an active dhcp agent can pick it up. - expected_meta_net = { - 'status': 'ACTIVE', - 'subnets': [], - 'name': 'meta-%s' % r['router']['id'], - 'admin_state_up': True, - 'tenant_id': '', - 'port_security_enabled': False, - 'shared': False, - 'id': mock.ANY, - 'mtu': mock.ANY - } - f.assert_any_call(mock.ANY, expected_meta_net) + # Verify that there has been a schedule_network all for the + # metadata network + expected_net_name = 'meta-%s' % r['router']['id'] + found = False + for call in f.call_args_list: + # The network data are the last of the positional arguments + net_dict = call[0][-1] + if net_dict['name'] == expected_net_name: + self.assertFalse(net_dict['port_security_enabled']) + self.assertFalse(net_dict['shared']) + self.assertFalse(net_dict['tenant_id']) + found = True + break + else: + self.fail("Expected schedule_network call for metadata " + "network %s not found" % expected_net_name) + self.assertTrue(found) self._metadata_teardown() def test_metadata_network_create_rollback_on_create_subnet_failure(self): diff --git a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py index fa65eacdfe..a64942ebcb 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py @@ -19,7 +19,6 @@ import webob.exc from neutron.api.v2 import attributes from neutron import context 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 extraroute from neutron.extensions import l3 @@ -192,8 +191,7 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxV3PluginTestCaseMixin): mock_validate_az.return_value = None with self.network(name=name, availability_zone_hints=zone) as net: az_hints = net['network']['availability_zone_hints'] - az_hints_list = az_ext.convert_az_string_to_list(az_hints) - self.assertListEqual(az_hints_list, zone) + self.assertListEqual(az_hints, zone) class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin,