Merge "Catch neutronclient.NotFound on floating deletion" into stable/ocata

This commit is contained in:
Jenkins 2017-06-12 10:34:45 +00:00 committed by Gerrit Code Review
commit 9fd1fd7f43
4 changed files with 66 additions and 1 deletions

View File

@ -201,6 +201,8 @@ class FloatingIPController(wsgi.Controller):
except exception.CannotDisassociateAutoAssignedFloatingIP:
msg = _('Cannot disassociate auto assigned floating IP')
raise webob.exc.HTTPForbidden(explanation=msg)
except exception.FloatingIpNotFoundForAddress as exc:
raise webob.exc.HTTPNotFound(explanation=exc.format_message())
class FloatingIPActionController(wsgi.Controller):

View File

@ -2008,7 +2008,12 @@ class API(base_api.NetworkAPI):
if raise_if_associated and fip['port_id']:
raise exception.FloatingIpAssociated(address=address)
client.delete_floatingip(fip['id'])
try:
client.delete_floatingip(fip['id'])
except neutron_client_exc.NotFound:
raise exception.FloatingIpNotFoundForAddress(
address=address
)
@base_api.refresh_cache
def disassociate_floating_ip(self, context, instance, address,

View File

@ -159,6 +159,44 @@ class FloatingIpTestNeutronV21(test.NoDBTestCase):
ex = exception.InvalidID(id=1)
self._test_floatingip_delete_not_found(ex, webob.exc.HTTPBadRequest)
def _test_floatingip_delete_error_disassociate(self, raised_exc,
expected_exc):
"""Ensure that various exceptions are correctly transformed.
Handle the myriad exceptions that could be raised from the
'disassociate_and_release_floating_ip' call.
"""
req = fakes.HTTPRequest.blank('')
with mock.patch.object(self.controller.network_api,
'get_floating_ip',
return_value={'address': 'foo'}), \
mock.patch.object(self.controller.network_api,
'get_instance_id_by_floating_address',
return_value=None), \
mock.patch.object(self.controller.network_api,
'disassociate_and_release_floating_ip',
side_effect=raised_exc):
self.assertRaises(expected_exc,
self.controller.delete, req, 1)
def test_floatingip_delete_error_disassociate_1(self):
raised_exc = exception.Forbidden
expected_exc = webob.exc.HTTPForbidden
self._test_floatingip_delete_error_disassociate(raised_exc,
expected_exc)
def test_floatingip_delete_error_disassociate_2(self):
raised_exc = exception.CannotDisassociateAutoAssignedFloatingIP
expected_exc = webob.exc.HTTPForbidden
self._test_floatingip_delete_error_disassociate(raised_exc,
expected_exc)
def test_floatingip_delete_error_disassociate_3(self):
raised_exc = exception.FloatingIpNotFoundForAddress(address='1.1.1.1')
expected_exc = webob.exc.HTTPNotFound
self._test_floatingip_delete_error_disassociate(raised_exc,
expected_exc)
class FloatingIpTestV21(test.TestCase):
floating_ip = "10.10.10.10"

View File

@ -3516,6 +3516,26 @@ class TestNeutronv2WithMock(test.TestCase):
api.allocate_floating_ip, self.context,
'ext_net')
@mock.patch('nova.network.neutronv2.api.get_client')
@mock.patch('nova.network.neutronv2.api.API._get_floating_ip_by_address',
return_value={'port_id': None, 'id': 'abc'})
def test_release_floating_ip_not_found(self, mock_get_ip, mock_ntrn):
"""Ensure neutron's NotFound exception is correctly handled.
Sometimes, trying to delete a floating IP multiple times in a short
delay can trigger an exception because the operation is not atomic. If
neutronclient's call to delete fails with a NotFound error, then we
should correctly handle this.
"""
mock_nc = mock.Mock()
mock_ntrn.return_value = mock_nc
mock_nc.delete_floatingip.side_effect = exceptions.NotFound()
address = '172.24.4.227'
self.assertRaises(exception.FloatingIpNotFoundForAddress,
self.api.release_floating_ip,
self.context, address)
@mock.patch.object(client.Client, 'create_port')
def test_create_port_minimal_raise_no_more_ip(self, create_port_mock):
instance = fake_instance.fake_instance_obj(self.context)