network: handle forbidden exception from neutron

Neutron will raise a forbidden exception when the neutron policy is not
allowed to for some operation like create_port. The operation is an RPC
call from nova-api to nova-compute. The Forbidden from neutron isn't
handled in nova-api so we get a 500 back instead of a 403. It should be
a 403 in this case.

Change-Id: Iea4feaeb7ea6860e892ef57a4443e814a74b1d9e
Closes-bug: #1603592
This commit is contained in:
liyingjun 2016-07-21 15:49:37 +08:00
parent 80d39a6506
commit ead6597274
3 changed files with 22 additions and 2 deletions

View File

@ -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

View File

@ -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', {})

View File

@ -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')