diff --git a/nova/network/neutronv2/api.py b/nova/network/neutronv2/api.py index a950558746bc..d4e6b9e77d21 100644 --- a/nova/network/neutronv2/api.py +++ b/nova/network/neutronv2/api.py @@ -73,8 +73,8 @@ def _load_auth_plugin(conf): class ClientWrapper(clientv20.Client): """A Neutron client wrapper class. - Wraps the callable methods, catches Unauthorized from Neutron and - convert it to a 401 for Nova clients. + Wraps the callable methods, catches Unauthorized,Forbidden from Neutron and + convert it to a 401,403 for Nova clients. """ def __init__(self, base_client, admin): # Expose all attributes from the base_client instance @@ -108,6 +108,8 @@ class ClientWrapper(clientv20.Client): "valid admin token, please verify Neutron " "admin credential located in nova.conf")) raise exception.NeutronAdminCredentialConfigurationInvalid() + except neutron_client_exc.Forbidden as e: + raise exception.Forbidden(e) return ret return wrapper diff --git a/nova/tests/functional/api_sample_tests/test_networks.py b/nova/tests/functional/api_sample_tests/test_networks.py index d48674af168f..df1e14587c7d 100644 --- a/nova/tests/functional/api_sample_tests/test_networks.py +++ b/nova/tests/functional/api_sample_tests/test_networks.py @@ -73,6 +73,13 @@ class NetworksJsonTests(api_sample_base.ApiSampleTestBaseV21): response = self._do_get('os-networks/%s' % uuid) self.assertEqual(401, response.status_code) + @mock.patch('nova.network.api.API.create', + side_effect=exception.Forbidden) + def test_network_create_forbidden(self, mock_create): + response = self._do_post("os-networks", + 'network-create-req', {}) + self.assertEqual(403, response.status_code) + def test_network_create(self): response = self._do_post("os-networks", 'network-create-req', {}) diff --git a/nova/tests/unit/network/test_neutronv2.py b/nova/tests/unit/network/test_neutronv2.py index 8fd7fe64224a..1eacc51cdec6 100644 --- a/nova/tests/unit/network/test_neutronv2.py +++ b/nova/tests/unit/network/test_neutronv2.py @@ -162,6 +162,17 @@ class TestNeutronClient(test.NoDBTestCase): exception.NeutronAdminCredentialConfigurationInvalid, client.list_networks) + @mock.patch.object(client.Client, "create_port", + side_effect=exceptions.Forbidden()) + def test_Forbidden(self, mock_create_port): + my_context = context.RequestContext('userid', uuids.my_tenant, + auth_token='token', + is_admin=False) + client = neutronapi.get_client(my_context) + self.assertRaises( + exception.Forbidden, + client.create_port) + def test_withtoken_context_is_admin(self): self.flags(url='http://anyhost/', group='neutron') self.flags(timeout=30, group='neutron')