From d96a8f0e6b524c10e563418c2770069030455c25 Mon Sep 17 00:00:00 2001 From: Haiwei Xu Date: Thu, 7 Aug 2014 19:33:36 +0900 Subject: [PATCH] Handle ExternalNetworkAttachForbidden exception When creating an instance and assigning a public network to it without admin authority, ExternalNetworkAttachForbidden will be raised. But this exception is not handled in V3 api. Change-Id: Id70d8eaa704fd82cef1afdb65756d75cb56fbdce Closes-Bug: #1353949 --- nova/api/openstack/compute/plugins/v3/servers.py | 4 +++- .../api/openstack/compute/plugins/v3/test_servers.py | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/compute/plugins/v3/servers.py b/nova/api/openstack/compute/plugins/v3/servers.py index 2e2f27fbdb52..292c7c50b48c 100644 --- a/nova/api/openstack/compute/plugins/v3/servers.py +++ b/nova/api/openstack/compute/plugins/v3/servers.py @@ -427,7 +427,7 @@ class ServersController(wsgi.Controller): req.cache_db_instance(instance) return self._view_builder.show(req, instance) - @extensions.expected_errors((400, 409, 413)) + @extensions.expected_errors((400, 403, 409, 413)) @wsgi.response(202) @validation.schema(schema_server_create) def create(self, req, body): @@ -525,6 +525,8 @@ class ServersController(wsgi.Controller): except exception.ConfigDriveInvalidValue: msg = _("Invalid config_drive provided.") raise exc.HTTPBadRequest(explanation=msg) + except exception.ExternalNetworkAttachForbidden as error: + raise exc.HTTPForbidden(explanation=error.format_message()) except messaging.RemoteError as err: msg = "%(err_type)s: %(err_msg)s" % {'err_type': err.exc_type, 'err_msg': err.value} diff --git a/nova/tests/api/openstack/compute/plugins/v3/test_servers.py b/nova/tests/api/openstack/compute/plugins/v3/test_servers.py index 6368cb649b32..f80e2408b538 100644 --- a/nova/tests/api/openstack/compute/plugins/v3/test_servers.py +++ b/nova/tests/api/openstack/compute/plugins/v3/test_servers.py @@ -2462,6 +2462,16 @@ class ServersControllerCreateTest(test.TestCase): self.assertRaises(webob.exc.HTTPConflict, self._test_create_extra, params) + @mock.patch.object(compute_api.API, 'create') + def test_create_instance_public_network_non_admin(self, mock_create): + public_network_uuid = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' + params = {'networks': [{'uuid': public_network_uuid}]} + self.req.body = jsonutils.dumps(self.body) + mock_create.side_effect = exception.ExternalNetworkAttachForbidden( + network_uuid=public_network_uuid) + self.assertRaises(webob.exc.HTTPForbidden, + self._test_create_extra, params) + @mock.patch.object(compute_api.API, 'create') def test_create_multiple_instance_with_specified_ip_neutronv2(self, _api_mock):