Merge "Don't fail if VIP already exist or has been deleted before"
This commit is contained in:
commit
b7503fcb18
|
@ -1015,12 +1015,8 @@ class OvnProviderHelper(object):
|
||||||
'loadbalancers': [{"id": loadbalancer['id'],
|
'loadbalancers': [{"id": loadbalancer['id'],
|
||||||
"provisioning_status": constants.ERROR,
|
"provisioning_status": constants.ERROR,
|
||||||
"operating_status": constants.ERROR}]}
|
"operating_status": constants.ERROR}]}
|
||||||
try:
|
# Delete VIP port from neutron.
|
||||||
# Delete VIP port from neutron.
|
self.delete_vip_port(port_id)
|
||||||
self.delete_vip_port(port_id)
|
|
||||||
except n_exc.PortNotFoundClient:
|
|
||||||
LOG.warning("Port %s could not be found. Please "
|
|
||||||
"check Neutron logs", port_id)
|
|
||||||
return status
|
return status
|
||||||
|
|
||||||
def _lb_delete(self, loadbalancer, ovn_lb, status):
|
def _lb_delete(self, loadbalancer, ovn_lb, status):
|
||||||
|
@ -1756,11 +1752,36 @@ class OvnProviderHelper(object):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
network_driver = get_network_driver()
|
network_driver = get_network_driver()
|
||||||
return network_driver.neutron_client.create_port(port)
|
try:
|
||||||
|
return network_driver.neutron_client.create_port(port)
|
||||||
|
except n_exc.IpAddressAlreadyAllocatedClient:
|
||||||
|
# Sometimes the VIP is already created (race-conditions)
|
||||||
|
# Lets get the it from Neutron API.
|
||||||
|
ports = network_driver.neutron_client.list_ports(
|
||||||
|
network_id=vip_d['vip_network_id'],
|
||||||
|
name='%s%s' % (ovn_const.LB_VIP_PORT_PREFIX, lb_id))
|
||||||
|
if not ports['ports']:
|
||||||
|
LOG.error('Cannot create/get LoadBalancer VIP port with '
|
||||||
|
'fixed IP: %s', vip_d['vip_address'])
|
||||||
|
status = {'loadbalancers': [{
|
||||||
|
"id": lb_id,
|
||||||
|
"provisioning_status": constants.ERROR,
|
||||||
|
"operating_status": constants.ERROR}]}
|
||||||
|
self._update_status_to_octavia(status)
|
||||||
|
return
|
||||||
|
# there should only be one port returned
|
||||||
|
port = ports['ports'][0]
|
||||||
|
LOG.debug('VIP Port already exists, uuid: %s', port['id'])
|
||||||
|
return {'port': port}
|
||||||
|
|
||||||
def delete_vip_port(self, port_id):
|
def delete_vip_port(self, port_id):
|
||||||
network_driver = get_network_driver()
|
network_driver = get_network_driver()
|
||||||
network_driver.neutron_client.delete_port(port_id)
|
try:
|
||||||
|
network_driver.neutron_client.delete_port(port_id)
|
||||||
|
except n_exc.PortNotFoundClient:
|
||||||
|
LOG.warning("Port %s could not be found. Please "
|
||||||
|
"check Neutron logs. Perhaps port "
|
||||||
|
"was already deleted.", port_id)
|
||||||
|
|
||||||
def handle_vip_fip(self, fip_info):
|
def handle_vip_fip(self, fip_info):
|
||||||
ovn_lb = fip_info['ovn_lb']
|
ovn_lb = fip_info['ovn_lb']
|
||||||
|
|
|
@ -1004,8 +1004,8 @@ class TestOvnProviderHelper(TestOvnOctaviaBase):
|
||||||
@mock.patch('ovn_octavia_provider.driver.get_network_driver')
|
@mock.patch('ovn_octavia_provider.driver.get_network_driver')
|
||||||
@mock.patch.object(ovn_driver.OvnProviderHelper, 'delete_vip_port')
|
@mock.patch.object(ovn_driver.OvnProviderHelper, 'delete_vip_port')
|
||||||
def test_lb_delete_port_not_found(self, del_port, net_dr):
|
def test_lb_delete_port_not_found(self, del_port, net_dr):
|
||||||
net_dr.return_value.neutron_client.delete_port.return_value = None
|
net_dr.return_value.neutron_client.delete_port.side_effect = (
|
||||||
del_port.side_effect = [n_exc.PortNotFoundClient]
|
[n_exc.PortNotFoundClient])
|
||||||
status = self.helper.lb_delete(self.ovn_lb)
|
status = self.helper.lb_delete(self.ovn_lb)
|
||||||
self.assertEqual(status['loadbalancers'][0]['provisioning_status'],
|
self.assertEqual(status['loadbalancers'][0]['provisioning_status'],
|
||||||
constants.DELETED)
|
constants.DELETED)
|
||||||
|
@ -2519,6 +2519,56 @@ class TestOvnProviderHelper(TestOvnOctaviaBase):
|
||||||
mock.call().neutron_client.create_port(expected_dict)]
|
mock.call().neutron_client.create_port(expected_dict)]
|
||||||
gn.assert_has_calls(expected_call)
|
gn.assert_has_calls(expected_call)
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.driver.get_network_driver')
|
||||||
|
def test_create_vip_port_vip_selected_already_exist(self, net_dr):
|
||||||
|
net_dr.return_value.neutron_client.create_port.side_effect = [
|
||||||
|
n_exc.IpAddressAlreadyAllocatedClient]
|
||||||
|
net_dr.return_value.neutron_client.list_ports.return_value = {
|
||||||
|
'ports': [
|
||||||
|
{'name': 'ovn-lb-vip-' + self.loadbalancer_id,
|
||||||
|
'id': self.loadbalancer_id}]}
|
||||||
|
self.vip_dict['vip_address'] = '10.1.10.1'
|
||||||
|
ret = self.helper.create_vip_port(
|
||||||
|
self.project_id,
|
||||||
|
self.loadbalancer_id,
|
||||||
|
self.vip_dict)
|
||||||
|
expected = {
|
||||||
|
'port': {
|
||||||
|
'name': '%s%s' % (ovn_const.LB_VIP_PORT_PREFIX,
|
||||||
|
self.loadbalancer_id),
|
||||||
|
'id': self.loadbalancer_id}}
|
||||||
|
self.assertDictEqual(expected, ret)
|
||||||
|
expected_call = [
|
||||||
|
mock.call().neutron_client.list_ports(
|
||||||
|
network_id='%s' % self.vip_dict['vip_network_id'],
|
||||||
|
name='%s%s' % (ovn_const.LB_VIP_PORT_PREFIX,
|
||||||
|
self.loadbalancer_id))]
|
||||||
|
net_dr.assert_has_calls(expected_call)
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.driver.get_network_driver')
|
||||||
|
def test_create_vip_port_vip_selected_other_allocation_exist(self, net_dr):
|
||||||
|
net_dr.return_value.neutron_client.create_port.side_effect = [
|
||||||
|
n_exc.IpAddressAlreadyAllocatedClient]
|
||||||
|
net_dr.return_value.neutron_client.list_ports.return_value = {
|
||||||
|
'ports': []}
|
||||||
|
self.vip_dict['vip_address'] = '10.1.10.1'
|
||||||
|
ret = self.helper.create_vip_port(
|
||||||
|
self.project_id,
|
||||||
|
self.loadbalancer_id,
|
||||||
|
self.vip_dict)
|
||||||
|
self.assertIsNone(ret)
|
||||||
|
expected_call = [
|
||||||
|
mock.call().neutron_client.list_ports(
|
||||||
|
network_id='%s' % self.vip_dict['vip_network_id'],
|
||||||
|
name='%s%s' % (ovn_const.LB_VIP_PORT_PREFIX,
|
||||||
|
self.loadbalancer_id))]
|
||||||
|
net_dr.assert_has_calls(expected_call)
|
||||||
|
self.helper._update_status_to_octavia.assert_called_once_with(
|
||||||
|
{'loadbalancers':
|
||||||
|
[{'id': self.loadbalancer_id,
|
||||||
|
'provisioning_status': 'ERROR',
|
||||||
|
'operating_status': 'ERROR'}]})
|
||||||
|
|
||||||
def test_get_member_info(self):
|
def test_get_member_info(self):
|
||||||
ret = self.helper.get_member_info(self.pool_id)
|
ret = self.helper.get_member_info(self.pool_id)
|
||||||
self.assertEqual([(self.member_id, '%s:%s' % (self.member_address,
|
self.assertEqual([(self.member_id, '%s:%s' % (self.member_address,
|
||||||
|
|
Loading…
Reference in New Issue