diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index d04b041226b..5c348ceecaf 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -931,6 +931,7 @@ def create(self, req, body): exception.InstanceTypeNotFound, exception.InvalidMetadata, exception.InvalidRequest, + exception.PortNotFound, exception.SecurityGroupNotFound) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) except exception.PortInUse as error: diff --git a/nova/network/neutronv2/api.py b/nova/network/neutronv2/api.py index 1a2d8b7b420..74350535347 100644 --- a/nova/network/neutronv2/api.py +++ b/nova/network/neutronv2/api.py @@ -496,9 +496,13 @@ def validate_networks(self, context, requested_networks): for (net_id, _i, port_id) in requested_networks: if port_id: - port = (neutronv2.get_client(context) - .show_port(port_id) - .get('port')) + try: + port = (neutronv2.get_client(context) + .show_port(port_id) + .get('port')) + except neutronv2.exceptions.NeutronClientException as e: + if e.status_code == 404: + port = None if not port: raise exception.PortNotFound(port_id=port_id) if port.get('device_id', None): diff --git a/nova/tests/api/openstack/compute/test_servers.py b/nova/tests/api/openstack/compute/test_servers.py index 42cebfdb775..e3308f48ab1 100644 --- a/nova/tests/api/openstack/compute/test_servers.py +++ b/nova/tests/api/openstack/compute/test_servers.py @@ -2779,6 +2779,20 @@ def fake_create(*args, **kwargs): self.assertRaises(webob.exc.HTTPConflict, self._test_create_extra, params) + def test_create_instance_with_neutronv2_port_not_found(self): + self.flags(network_api_class='nova.network.neutronv2.api.API') + network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' + port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' + requested_networks = [{'uuid': network, 'port': port}] + params = {'networks': requested_networks} + + def fake_create(*args, **kwargs): + raise exception.PortNotFound(port_id=port) + + self.stubs.Set(compute_api.API, 'create', fake_create) + self.assertRaises(webob.exc.HTTPBadRequest, + self._test_create_extra, params) + def test_create_instance_with_networks_disabled_neutronv2(self): self.flags(network_api_class='nova.network.neutronv2.api.API') net_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' diff --git a/nova/tests/network/test_neutronv2.py b/nova/tests/network/test_neutronv2.py index 06dec909c1c..b00da8b5f1e 100644 --- a/nova/tests/network/test_neutronv2.py +++ b/nova/tests/network/test_neutronv2.py @@ -942,6 +942,24 @@ def test_validate_networks_not_specified(self): api.validate_networks, self.context, requested_networks) + def test_validate_networks_port_not_found(self): + # Verify that the correct exception is thrown when a non existent + # port is passed to validate_networks. + + requested_networks = [('my_netid1', None, '3123-ad34-bc43-32332ca33e')] + + NeutronNotFound = neutronv2.exceptions.NeutronClientException( + status_code=404) + self.moxed_client.show_port(requested_networks[0][2]).AndRaise( + NeutronNotFound) + self.mox.ReplayAll() + # Expected call from setUp. + neutronv2.get_client(None) + api = neutronapi.API() + self.assertRaises(exception.PortNotFound, + api.validate_networks, + self.context, requested_networks) + def _mock_list_ports(self, port_data=None): if port_data is None: port_data = self.port_data2