From cdb7456e3c84084acebd23c00b8cddb3e253fc12 Mon Sep 17 00:00:00 2001 From: Kevin Benton Date: Sun, 9 Feb 2014 11:39:39 -0800 Subject: [PATCH] BigSwitch: Fix tenant_id for shared net requests The URI port requests are sent to on the backend contains the tenant_id of the network. This corrects a bug where, on port updates and deletes, the tenant_id of the port rather than the network was being used, which was incorrect when attached to a shared network. Closes-Bug: #1278530 Change-Id: I09ffc767c669416555867e975d0b7057a5cfa0cb --- neutron/plugins/bigswitch/plugin.py | 25 +++++++++++-------- .../unit/bigswitch/test_restproxy_plugin.py | 24 ++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/neutron/plugins/bigswitch/plugin.py b/neutron/plugins/bigswitch/plugin.py index af9d0feaa..5fcc11c61 100644 --- a/neutron/plugins/bigswitch/plugin.py +++ b/neutron/plugins/bigswitch/plugin.py @@ -311,6 +311,11 @@ class NeutronRestProxyV2Base(db_base_plugin_v2.NeutronDbPluginV2, return v return False + def _get_port_net_tenantid(self, context, port): + net = super(NeutronRestProxyV2Base, + self).get_network(context, port["network_id"]) + return net['tenant_id'] + class NeutronRestProxyV2(NeutronRestProxyV2Base, extradhcpopt_db.ExtraDhcpOptMixin, @@ -504,8 +509,7 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base, self._process_port_create_extra_dhcp_opts(context, new_port, dhcp_opts) new_port = self._extend_port_dict_binding(context, new_port) - net = super(NeutronRestProxyV2, - self).get_network(context, new_port["network_id"]) + net_tenant_id = self._get_port_net_tenantid(context, new_port) if self.add_meta_server_route: if new_port['device_owner'] == 'network:dhcp': destination = METADATA_SERVER_IP + '/32' @@ -513,7 +517,7 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base, # create on network ctrl mapped_port = self._map_state_and_status(new_port) - self.servers.rest_create_port(net["tenant_id"], + self.servers.rest_create_port(net_tenant_id, new_port["network_id"], mapped_port) return new_port @@ -588,9 +592,11 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base, ctrl_update_required = True if ctrl_update_required: + # tenant_id must come from network in case network is shared + net_tenant_id = self._get_port_net_tenantid(context, new_port) new_port = self._extend_port_dict_binding(context, new_port) mapped_port = self._map_state_and_status(new_port) - self.servers.rest_update_port(new_port["tenant_id"], + self.servers.rest_update_port(net_tenant_id, new_port["network_id"], mapped_port) @@ -620,15 +626,14 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base, def _delete_port(self, context, port_id): port = super(NeutronRestProxyV2, self).get_port(context, port_id) - tenant_id = port['tenant_id'] - net_id = port['network_id'] - if tenant_id == '': - net = super(NeutronRestProxyV2, self).get_network(context, net_id) - tenant_id = net['tenant_id'] + + # Tenant ID must come from network in case the network is shared + tenant_id = self._get_port_net_tenantid(context, port) + # Delete from DB ret_val = super(NeutronRestProxyV2, self)._delete_port(context, port_id) - self.servers.rest_delete_port(tenant_id, net_id, port_id) + self.servers.rest_delete_port(tenant_id, port['network_id'], port_id) return ret_val def create_subnet(self, context, subnet): diff --git a/neutron/tests/unit/bigswitch/test_restproxy_plugin.py b/neutron/tests/unit/bigswitch/test_restproxy_plugin.py index 4f55a2a76..831cccb0b 100644 --- a/neutron/tests/unit/bigswitch/test_restproxy_plugin.py +++ b/neutron/tests/unit/bigswitch/test_restproxy_plugin.py @@ -118,6 +118,30 @@ class TestBigSwitchProxyPortsV2(test_plugin.TestPortsV2, port = self._get_ports(n['network']['id'])[0] self.assertEqual('ACTIVE', port['status']) + def test_correct_shared_net_tenant_id(self): + # tenant_id in port requests should match network tenant_id instead + # of port tenant_id + def rest_port_op(self, ten_id, netid, port): + if ten_id != 'SHARED': + raise Exception('expecting tenant_id SHARED. got %s' % ten_id) + with self.network(tenant_id='SHARED', shared=True) as net: + with self.subnet(network=net) as sub: + pref = 'neutron.plugins.bigswitch.servermanager.ServerPool.%s' + tomock = [pref % 'rest_create_port', + pref % 'rest_update_port', + pref % 'rest_delete_port'] + patches = [patch(f, create=True, new=rest_port_op) + for f in tomock] + for restp in patches: + restp.start() + with self.port(subnet=sub, tenant_id='port-owner') as port: + data = {'port': {'binding:host_id': 'someotherhost', + 'device_id': 'override_dev'}} + req = self.new_update_request('ports', data, + port['port']['id']) + res = req.get_response(self.api) + self.assertEqual(res.status_int, 200) + class TestBigSwitchProxyPortsV2IVS(test_plugin.TestPortsV2, BigSwitchProxyPluginV2TestCase, -- 2.45.2