Return None in get_instance_id_by_floating_address

_show_port() can raise a PortNotFound exception, but the method
get_instance_id_by_floating_address() doesn't handle it. On the
other hand, the method returns None if fip doesn't contain
port_id as a normal case.
On the caller side, "Delete a floating ip" API can use the returned
value None to disassociate_and_release_floating_ip() and the method
handles the None as a normal value.

So this patch makes get_instance_id_by_floating_address return None
if PortNotFound happens.

Closes-Bug: #1586931

Change-Id: I03be8100155d343eb6a4ea9eda3f1498ad3fb4cf
(cherry picked from commit e72826123b)
This commit is contained in:
Ken'ichi Ohmichi 2016-08-12 10:15:29 -07:00 committed by Ken'ichi Ohmichi
parent 67cfb16a4f
commit daf281f95f
2 changed files with 26 additions and 1 deletions

View File

@ -1438,7 +1438,20 @@ class API(base_api.NetworkAPI):
fip = self._get_floating_ip_by_address(client, address)
if not fip['port_id']:
return None
port = self._show_port(context, fip['port_id'], neutron_client=client)
try:
port = self._show_port(context, fip['port_id'],
neutron_client=client)
except exception.PortNotFound:
# NOTE: Here is a potential race condition between _show_port() and
# _get_floating_ip_by_address(). fip['port_id'] shows a port which
# is the server instance's. At _get_floating_ip_by_address(),
# Neutron returns the list which includes the instance. Just after
# that, the deletion of the instance happens and Neutron returns
# 404 on _show_port().
LOG.debug('The port(%s) is not found', fip['port_id'])
return None
return port['device_id']
def get_vifs_by_instance(self, context, instance):

View File

@ -3840,6 +3840,18 @@ class TestNeutronv2WithMock(test.TestCase):
port_client.update_port.assert_called_once_with(
uuids.port_id, port_req_body)
@mock.patch('nova.network.neutronv2.api.API._get_floating_ip_by_address',
return_value={"port_id": "1"})
@mock.patch('nova.network.neutronv2.api.API._show_port',
side_effect=exception.PortNotFound(port_id='1'))
def test_get_instance_id_by_floating_address_port_not_found(self,
mock_show,
mock_get):
api = neutronapi.API()
fip = api.get_instance_id_by_floating_address(self.context,
'172.24.4.227')
self.assertIsNone(fip)
class TestNeutronv2ModuleMethods(test.NoDBTestCase):