Delete vip port if create_vip_port raise exception
Sometimes on heavy load over Neutron, operations over
neutron client could raise a NeutronClientException that
could cover, e.g. a timeout. In those case, sometimes the
request finish after the client timeout and we have
leftover resource.
create_vip_port is called from Octavia API just before
the create LB request, if this call raise a timeout
maybe the vip port is finally created and linked to a LB
that is not going to be created, so we have this port
unuse.
This patch will try to remove the leftover port for those
situations.
(manually cherry picked from commit
cd3264a07e
)
Closes-Bug: #1973765
Change-Id: Iad9839ce99d50b969924b3fe369301b6dfed369d
This commit is contained in:
parent
1b162af1ad
commit
4d15d0d2f6
|
@ -2009,6 +2009,18 @@ class OvnProviderHelper(object):
|
|||
port = ports['ports'][0]
|
||||
LOG.debug('VIP Port already exists, uuid: %s', port['id'])
|
||||
return {'port': port}
|
||||
except n_exc.NeutronClientException as e:
|
||||
# NOTE (froyo): whatever other exception as e.g. Timeout
|
||||
# we should try to ensure no leftover port remains
|
||||
ports = neutron_client.list_ports(
|
||||
network_id=vip_d['vip_network_id'],
|
||||
name=f'{ovn_const.LB_VIP_PORT_PREFIX}{lb_id}')
|
||||
if ports['ports']:
|
||||
port = ports['ports'][0]
|
||||
LOG.debug('Leftover port %s has been found. Trying to '
|
||||
'delete it', port['id'])
|
||||
self.delete_vip_port(port['id'])
|
||||
raise e
|
||||
|
||||
@tenacity.retry(
|
||||
retry=tenacity.retry_if_exception_type(
|
||||
|
|
|
@ -3856,6 +3856,31 @@ class TestOvnProviderHelper(TestOvnOctaviaBase):
|
|||
net_cli.assert_has_calls(expected_call)
|
||||
self.helper._update_status_to_octavia.assert_not_called()
|
||||
|
||||
@mock.patch('ovn_octavia_provider.driver.get_neutron_client')
|
||||
@mock.patch.object(ovn_driver.OvnProviderHelper, 'delete_vip_port')
|
||||
def test_create_vip_port_vip_neutron_client_other_exception(
|
||||
self, del_port, net_cli):
|
||||
net_cli.return_value.create_port.side_effect = [
|
||||
n_exc.NeutronClientException]
|
||||
net_cli.return_value.list_ports.return_value = {
|
||||
'ports': [
|
||||
{'name': 'ovn-lb-vip-' + self.loadbalancer_id,
|
||||
'id': self.loadbalancer_id}]}
|
||||
self.assertRaises(
|
||||
n_exc.NeutronClientException,
|
||||
self.helper.create_vip_port,
|
||||
self.project_id,
|
||||
self.loadbalancer_id,
|
||||
self.vip_dict)
|
||||
expected_call = [
|
||||
mock.call().list_ports(
|
||||
network_id='%s' % self.vip_dict['vip_network_id'],
|
||||
name='%s%s' % (ovn_const.LB_VIP_PORT_PREFIX,
|
||||
self.loadbalancer_id))]
|
||||
net_cli.assert_has_calls(expected_call)
|
||||
del_port.assert_called_once_with(self.loadbalancer_id)
|
||||
self.helper._update_status_to_octavia.assert_not_called()
|
||||
|
||||
def test_get_pool_member_id(self):
|
||||
ret = self.helper.get_pool_member_id(
|
||||
self.pool_id, mem_addr_port='192.168.2.149:1010')
|
||||
|
|
Loading…
Reference in New Issue