diff --git a/nova/network/neutronv2/api.py b/nova/network/neutronv2/api.py index 986a9c6b777a..4b1fd24603ed 100644 --- a/nova/network/neutronv2/api.py +++ b/nova/network/neutronv2/api.py @@ -22,6 +22,7 @@ from keystoneauth1 import loading as ks_loading from neutronclient.common import exceptions as neutron_client_exc from neutronclient.v2_0 import client as clientv20 from oslo_log import log as logging +from oslo_middleware import request_id from oslo_utils import excutils from oslo_utils import strutils from oslo_utils import uuidutils @@ -1290,7 +1291,7 @@ class API(base_api.NetworkAPI): binding['profile'] = port_profiles[port_id] data = dict(binding=binding) - resp = self._create_port_binding(client, port_id, data) + resp = self._create_port_binding(context, client, port_id, data) if resp: bindings_by_port_id[port_id] = resp.json()['binding'] else: @@ -1313,9 +1314,10 @@ class API(base_api.NetworkAPI): return bindings_by_port_id @staticmethod - def _create_port_binding(client, port_id, data): + def _create_port_binding(context, client, port_id, data): """Creates a port binding with the specified data. + :param context: The request context for the operation. :param client: keystoneauth1.adapter.Adapter :param port_id: The ID of the port on which to create the binding. :param data: dict of port binding data (requires at least the host), @@ -1324,8 +1326,9 @@ class API(base_api.NetworkAPI): {'binding': {'host': 'dest.host.com'}} :return: requests.Response object """ - return client.post('/v2.0/ports/%s/bindings' % port_id, - json=data, raise_exc=False) + return client.post( + '/v2.0/ports/%s/bindings' % port_id, json=data, raise_exc=False, + headers={request_id.INBOUND_HEADER: context.global_id}) def delete_port_binding(self, context, port_id, host): """Delete the port binding for the given port ID and host @@ -1340,7 +1343,7 @@ class API(base_api.NetworkAPI): response is received from neutron. """ client = _get_ksa_client(context, admin=True) - resp = self._delete_port_binding(client, port_id, host) + resp = self._delete_port_binding(context, client, port_id, host) if resp: LOG.debug('Deleted binding for port %s and host %s.', port_id, host) @@ -1357,16 +1360,18 @@ class API(base_api.NetworkAPI): port_id=port_id, host=host) @staticmethod - def _delete_port_binding(client, port_id, host): + def _delete_port_binding(context, client, port_id, host): """Deletes the binding for the given host on the given port. + :param context: The request context for the operation. :param client: keystoneauth1.adapter.Adapter :param port_id: ID of the port from which to delete the binding :param host: A string name of the host on which the port is bound :return: requests.Response object """ - return client.delete('/v2.0/ports/%s/bindings/%s' % (port_id, host), - raise_exc=False) + return client.delete( + '/v2.0/ports/%s/bindings/%s' % (port_id, host), raise_exc=False, + headers={request_id.INBOUND_HEADER: context.global_id}) def activate_port_binding(self, context, port_id, host): """Activates an inactive port binding. @@ -1387,7 +1392,8 @@ class API(base_api.NetworkAPI): # to ACTIVE, it's more like a POST action method in the compute API. resp = client.put( '/v2.0/ports/%s/bindings/%s/activate' % (port_id, host), - raise_exc=False) + raise_exc=False, + headers={request_id.INBOUND_HEADER: context.global_id}) if resp: LOG.debug('Activated binding for port %s and host %s.', port_id, host) @@ -2693,8 +2699,10 @@ class API(base_api.NetworkAPI): # Not all compute migration flows use the port binding-extended # API yet, so first check to see if there is a binding for the # port and destination host. - resp = client.get('/v2.0/ports/%s/bindings/%s' % - (vif['id'], dest_host), raise_exc=False) + resp = client.get( + '/v2.0/ports/%s/bindings/%s' % (vif['id'], dest_host), + raise_exc=False, + headers={request_id.INBOUND_HEADER: context.global_id}) if resp: if resp.json()['binding']['status'] != 'ACTIVE': self.activate_port_binding(context, vif['id'], dest_host) diff --git a/nova/tests/fixtures.py b/nova/tests/fixtures.py index 24f01af18b33..62211b98eb43 100644 --- a/nova/tests/fixtures.py +++ b/nova/tests/fixtures.py @@ -1503,13 +1503,13 @@ class NeutronFixture(fixtures.Fixture): lambda *args, **kwargs: self) @staticmethod - def fake_create_port_binding(client, port_id, data): + def fake_create_port_binding(context, client, port_id, data): # TODO(mriedem): Make this smarter by keeping track of our bindings # per port so we can reflect the status accurately. return fake_requests.FakeResponse(200, content=jsonutils.dumps(data)) @staticmethod - def fake_delete_port_binding(client, port_id, host): + def fake_delete_port_binding(context, client, port_id, host): # TODO(mriedem): Make this smarter by keeping track of our bindings # per port so we can reflect the status accurately. return fake_requests.FakeResponse(204) diff --git a/nova/tests/unit/network/test_neutronv2.py b/nova/tests/unit/network/test_neutronv2.py index f9248063efb9..85c74334ef40 100644 --- a/nova/tests/unit/network/test_neutronv2.py +++ b/nova/tests/unit/network/test_neutronv2.py @@ -5714,7 +5714,8 @@ class TestNeutronv2WithMock(TestNeutronv2Base): self.context, instance, migration) activate.assert_called_once_with(self.context, uuids.port_id, 'dest') get_client_mock.return_value.get.assert_called_once_with( - '/v2.0/ports/%s/bindings/dest' % uuids.port_id, raise_exc=False) + '/v2.0/ports/%s/bindings/dest' % uuids.port_id, raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}) @mock.patch('nova.network.neutronv2.api._get_ksa_client') def test_migrate_instance_start_already_active(self, get_client_mock): @@ -5736,7 +5737,8 @@ class TestNeutronv2WithMock(TestNeutronv2Base): self.api.migrate_instance_start( self.context, instance, migration) get_client_mock.return_value.get.assert_called_once_with( - '/v2.0/ports/%s/bindings/dest' % uuids.port_id, raise_exc=False) + '/v2.0/ports/%s/bindings/dest' % uuids.port_id, raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}) @mock.patch('nova.network.neutronv2.api._get_ksa_client') def test_migrate_instance_start_no_bindings(self, get_client_mock): @@ -5760,7 +5762,8 @@ class TestNeutronv2WithMock(TestNeutronv2Base): self.api.migrate_instance_start( self.context, instance, migration) get_client_mock.return_value.get.assert_called_once_with( - '/v2.0/ports/%s/bindings/dest' % uuids.port1, raise_exc=False) + '/v2.0/ports/%s/bindings/dest' % uuids.port1, raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}) @mock.patch('nova.network.neutronv2.api._get_ksa_client') def test_migrate_instance_start_get_error(self, get_client_mock): @@ -5782,10 +5785,14 @@ class TestNeutronv2WithMock(TestNeutronv2Base): self.context, instance, migration) self.assertEqual(2, get_client_mock.return_value.get.call_count) get_client_mock.return_value.get.assert_has_calls([ - mock.call('/v2.0/ports/%s/bindings/dest' % uuids.port1, - raise_exc=False), - mock.call('/v2.0/ports/%s/bindings/dest' % uuids.port2, - raise_exc=False)]) + mock.call( + '/v2.0/ports/%s/bindings/dest' % uuids.port1, + raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}), + mock.call( + '/v2.0/ports/%s/bindings/dest' % uuids.port2, + raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id})]) class TestNeutronv2ModuleMethods(test.NoDBTestCase): @@ -6286,7 +6293,8 @@ class TestNeutronv2Portbinding(TestNeutronv2Base): 'fake-host') mock_client.return_value.put.assert_called_once_with( '/v2.0/ports/%s/bindings/fake-host/activate' % uuids.port_id, - raise_exc=False) + raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}) @mock.patch('nova.network.neutronv2.api._get_ksa_client') @mock.patch('nova.network.neutronv2.api.LOG.warning') @@ -6298,7 +6306,8 @@ class TestNeutronv2Portbinding(TestNeutronv2Base): 'fake-host') mock_client.return_value.put.assert_called_once_with( '/v2.0/ports/%s/bindings/fake-host/activate' % uuids.port_id, - raise_exc=False) + raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}) self.assertEqual(1, mock_log_warning.call_count) self.assertIn('is already active', mock_log_warning.call_args[0][0]) @@ -6311,7 +6320,8 @@ class TestNeutronv2Portbinding(TestNeutronv2Base): self.context, uuids.port_id, 'fake-host') mock_client.return_value.put.assert_called_once_with( '/v2.0/ports/%s/bindings/fake-host/activate' % uuids.port_id, - raise_exc=False) + raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}) class TestAllocateForInstance(test.NoDBTestCase):