Add sync floating IP support
This patch add sync for FIP Also correct hm_sync for FIP Closes-Bug: #2045415 Co-authored-by: Fernando Royo <froyo@redhat.com> Co-authored-by: Rico Lin <ricolin@ricolky.com> Change-Id: I6dd6812e78b6ff42a27c6d1bf004250810e8b9ab
This commit is contained in:
@@ -88,7 +88,9 @@ REQ_TYPE_EXIT = 'exit'
|
|||||||
|
|
||||||
# Request information constants
|
# Request information constants
|
||||||
REQ_INFO_ACTION_ASSOCIATE = 'associate'
|
REQ_INFO_ACTION_ASSOCIATE = 'associate'
|
||||||
|
REQ_INFO_ACTION_SYNC = 'sync'
|
||||||
REQ_INFO_ACTION_DISASSOCIATE = 'disassociate'
|
REQ_INFO_ACTION_DISASSOCIATE = 'disassociate'
|
||||||
|
|
||||||
REQ_INFO_MEMBER_ADDED = 'member_added'
|
REQ_INFO_MEMBER_ADDED = 'member_added'
|
||||||
REQ_INFO_MEMBER_DELETED = 'member_deleted'
|
REQ_INFO_MEMBER_DELETED = 'member_deleted'
|
||||||
|
|
||||||
|
|||||||
@@ -798,6 +798,59 @@ class OvnProviderDriver(driver_base.ProviderDriver):
|
|||||||
ovn_lb)
|
ovn_lb)
|
||||||
self._ovn_helper._update_status_to_octavia(status)
|
self._ovn_helper._update_status_to_octavia(status)
|
||||||
|
|
||||||
|
def _fip_sync(self, loadbalancer):
|
||||||
|
LOG.info("Starting sync floating IP for loadbalancer "
|
||||||
|
f"{loadbalancer.loadbalancer_id}")
|
||||||
|
if not loadbalancer.vip_port_id or not loadbalancer.vip_network_id:
|
||||||
|
LOG.debug("VIP Port or Network not set for loadbalancer "
|
||||||
|
f"{loadbalancer.loadbalancer_id}, skip FIP sync.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Try to get FIP from neutron
|
||||||
|
fips = self._ovn_helper.get_fip_from_vip(loadbalancer)
|
||||||
|
|
||||||
|
# get FIP from LSP
|
||||||
|
vip_lsp = self._ovn_helper.get_lsp(
|
||||||
|
port_id=loadbalancer.vip_port_id,
|
||||||
|
network_id=loadbalancer.vip_network_id)
|
||||||
|
lsp_fip = vip_lsp.external_ids.get(
|
||||||
|
ovn_const.OVN_PORT_FIP_EXT_ID_KEY) if vip_lsp else None
|
||||||
|
|
||||||
|
if fips:
|
||||||
|
neutron_fip = fips[0].floating_ip_address
|
||||||
|
if not vip_lsp:
|
||||||
|
LOG.warn(
|
||||||
|
"Logic Switch Port not found for port "
|
||||||
|
f"{loadbalancer.vip_port_id}. "
|
||||||
|
"Skip sync FIP for loadbalancer "
|
||||||
|
f"{loadbalancer.loadbalancer_id}. Please "
|
||||||
|
"run command `neutron-ovn-db-sync-util` "
|
||||||
|
"first to sync OVN DB with Neutron DB.")
|
||||||
|
return
|
||||||
|
if lsp_fip != neutron_fip:
|
||||||
|
LOG.warn(
|
||||||
|
"Floating IP not consistent between Logic Switch "
|
||||||
|
f"Port and Neutron. Found FIP {lsp_fip} "
|
||||||
|
f"in LSP {vip_lsp.name}, but we have {neutron_fip} from "
|
||||||
|
"Neutron. Skip sync FIP for "
|
||||||
|
f"loadbalancer {loadbalancer.loadbalancer_id}. "
|
||||||
|
"Please run command `neutron-ovn-db-sync-util` "
|
||||||
|
"first to sync OVN DB with Neutron DB.")
|
||||||
|
return
|
||||||
|
self._ovn_helper.vip_port_update_handler(
|
||||||
|
vip_lp=vip_lsp, fip=lsp_fip,
|
||||||
|
action=ovn_const.REQ_INFO_ACTION_SYNC)
|
||||||
|
else:
|
||||||
|
LOG.warn("Floating IP not found for loadbalancer "
|
||||||
|
f"{loadbalancer.loadbalancer_id}")
|
||||||
|
if lsp_fip:
|
||||||
|
LOG.warn(
|
||||||
|
"Floating IP not consistent between Logic Switch "
|
||||||
|
f"Port and Neutron. Found FIP {lsp_fip} configured "
|
||||||
|
f"in LSP {vip_lsp.name}, but no FIP configured from "
|
||||||
|
"Neutron. Please run command `neutron-ovn-db-sync-util` "
|
||||||
|
"first to sync OVN DB with Neutron DB.")
|
||||||
|
|
||||||
def do_sync(self, **lb_filters):
|
def do_sync(self, **lb_filters):
|
||||||
LOG.info(f"Starting sync OVN DB with Loadbalancer filter {lb_filters}")
|
LOG.info(f"Starting sync OVN DB with Loadbalancer filter {lb_filters}")
|
||||||
octavia_client = clients.get_octavia_client()
|
octavia_client = clients.get_octavia_client()
|
||||||
@@ -841,3 +894,4 @@ class OvnProviderDriver(driver_base.ProviderDriver):
|
|||||||
provider_pools if provider_pools else o_datamodels.Unset
|
provider_pools if provider_pools else o_datamodels.Unset
|
||||||
)
|
)
|
||||||
self._ensure_loadbalancer(provider_lb)
|
self._ensure_loadbalancer(provider_lb)
|
||||||
|
self._fip_sync(provider_lb)
|
||||||
|
|||||||
@@ -355,8 +355,11 @@ class OvnProviderHelper():
|
|||||||
if port:
|
if port:
|
||||||
request_info['vip_related'] = [
|
request_info['vip_related'] = [
|
||||||
ip['ip_address'] for ip in port.fixed_ips]
|
ip['ip_address'] for ip in port.fixed_ips]
|
||||||
self.add_request({'type': ovn_const.REQ_TYPE_HANDLE_VIP_FIP,
|
if action != ovn_const.REQ_INFO_ACTION_SYNC:
|
||||||
'info': request_info})
|
self.add_request({'type': ovn_const.REQ_TYPE_HANDLE_VIP_FIP,
|
||||||
|
'info': request_info})
|
||||||
|
else:
|
||||||
|
self.handle_vip_fip(request_info)
|
||||||
|
|
||||||
def _find_lb_in_ls(self, network):
|
def _find_lb_in_ls(self, network):
|
||||||
"""Find LB associated to a Network using Network information
|
"""Find LB associated to a Network using Network information
|
||||||
@@ -2966,8 +2969,13 @@ class OvnProviderHelper():
|
|||||||
additional_vip_fip = fip_info.get('additional_vip_fip', False)
|
additional_vip_fip = fip_info.get('additional_vip_fip', False)
|
||||||
external_ids = copy.deepcopy(ovn_lb.external_ids)
|
external_ids = copy.deepcopy(ovn_lb.external_ids)
|
||||||
commands = []
|
commands = []
|
||||||
|
need_ext_set = True
|
||||||
|
need_hc_set = True
|
||||||
|
|
||||||
if fip_info['action'] == ovn_const.REQ_INFO_ACTION_ASSOCIATE:
|
if fip_info['action'] in (
|
||||||
|
ovn_const.REQ_INFO_ACTION_ASSOCIATE,
|
||||||
|
ovn_const.REQ_INFO_ACTION_SYNC
|
||||||
|
):
|
||||||
if additional_vip_fip:
|
if additional_vip_fip:
|
||||||
existing_addi_vip_fip = external_ids.get(
|
existing_addi_vip_fip = external_ids.get(
|
||||||
ovn_const.LB_EXT_IDS_ADDIT_VIP_FIP_KEY, [])
|
ovn_const.LB_EXT_IDS_ADDIT_VIP_FIP_KEY, [])
|
||||||
@@ -2984,31 +2992,51 @@ class OvnProviderHelper():
|
|||||||
fip_info['vip_fip'])
|
fip_info['vip_fip'])
|
||||||
vip_fip_info = {
|
vip_fip_info = {
|
||||||
ovn_const.LB_EXT_IDS_VIP_FIP_KEY: fip_info['vip_fip']}
|
ovn_const.LB_EXT_IDS_VIP_FIP_KEY: fip_info['vip_fip']}
|
||||||
commands.append(
|
if fip_info['action'] == ovn_const.REQ_INFO_ACTION_SYNC:
|
||||||
self.ovn_nbdb_api.db_set('Load_Balancer', ovn_lb.uuid,
|
# Don't need to trigger OVN DB set if external_ids not changed
|
||||||
('external_ids', vip_fip_info)))
|
need_ext_set = not all(
|
||||||
for lb_hc in ovn_lb.health_check:
|
ovn_lb.external_ids.get(k) ==
|
||||||
if self._get_vip_lbhc(lb_hc) in fip_info['vip_related']:
|
v for k, v in vip_fip_info.items()
|
||||||
vip = fip_info['vip_fip']
|
)
|
||||||
lb_hc_external_ids = copy.deepcopy(lb_hc.external_ids)
|
# For sync scenario, check if FIP VIP already in health_check
|
||||||
lb_hc_external_ids[ovn_const.LB_EXT_IDS_HM_VIP] = vip
|
for lb_hc in ovn_lb.health_check:
|
||||||
if self._check_lbhc_vip_format(lb_hc.vip):
|
# All lbhc in health_check are already checked
|
||||||
port = lb_hc.vip.rsplit(':')[-1]
|
# at this stage of sync workflow in hm_purge.
|
||||||
vip += ':' + port
|
# So we should be able to just check health_check.
|
||||||
else:
|
if self._get_vip_lbhc(lb_hc) == fip_info['vip_fip']:
|
||||||
vip = ''
|
need_hc_set = False
|
||||||
kwargs = {
|
break
|
||||||
'vip': vip,
|
|
||||||
'options': lb_hc.options,
|
if need_ext_set:
|
||||||
'external_ids': lb_hc_external_ids}
|
commands.append(
|
||||||
with self.ovn_nbdb_api.transaction(
|
self.ovn_nbdb_api.db_set(
|
||||||
check_error=True) as txn:
|
'Load_Balancer', ovn_lb.uuid, (
|
||||||
fip_lbhc = txn.add(self.ovn_nbdb_api.db_create(
|
'external_ids', vip_fip_info)))
|
||||||
'Load_Balancer_Health_Check', **kwargs))
|
|
||||||
txn.add(self.ovn_nbdb_api.db_add(
|
if need_hc_set:
|
||||||
'Load_Balancer', ovn_lb.uuid,
|
for lb_hc in ovn_lb.health_check:
|
||||||
'health_check', fip_lbhc))
|
if self._get_vip_lbhc(lb_hc) in fip_info['vip_related']:
|
||||||
|
vip = fip_info['vip_fip']
|
||||||
|
lb_hc_external_ids = copy.deepcopy(lb_hc.external_ids)
|
||||||
|
lb_hc_external_ids[ovn_const.LB_EXT_IDS_HM_VIP] = vip
|
||||||
|
if self._check_lbhc_vip_format(lb_hc.vip):
|
||||||
|
port = lb_hc.vip.rsplit(':')[-1]
|
||||||
|
vip += ':' + port
|
||||||
|
else:
|
||||||
|
vip = ''
|
||||||
|
kwargs = {
|
||||||
|
'vip': vip,
|
||||||
|
'options': lb_hc.options,
|
||||||
|
'external_ids': lb_hc_external_ids}
|
||||||
|
with self.ovn_nbdb_api.transaction(
|
||||||
|
check_error=True) as txn:
|
||||||
|
fip_lbhc = txn.add(self.ovn_nbdb_api.db_create(
|
||||||
|
'Load_Balancer_Health_Check', **kwargs))
|
||||||
|
txn.add(self.ovn_nbdb_api.db_add(
|
||||||
|
'Load_Balancer', ovn_lb.uuid,
|
||||||
|
'health_check', fip_lbhc))
|
||||||
else:
|
else:
|
||||||
|
# For disassociate case
|
||||||
existing_addi_vip_fip_need_updated = False
|
existing_addi_vip_fip_need_updated = False
|
||||||
existing_addi_vip_fip = external_ids.get(
|
existing_addi_vip_fip = external_ids.get(
|
||||||
ovn_const.LB_EXT_IDS_ADDIT_VIP_FIP_KEY, [])
|
ovn_const.LB_EXT_IDS_ADDIT_VIP_FIP_KEY, [])
|
||||||
@@ -3052,8 +3080,14 @@ class OvnProviderHelper():
|
|||||||
commands.append(self.ovn_nbdb_api.db_destroy(
|
commands.append(self.ovn_nbdb_api.db_destroy(
|
||||||
'Load_Balancer_Health_Check', lb_hc.uuid))
|
'Load_Balancer_Health_Check', lb_hc.uuid))
|
||||||
break
|
break
|
||||||
|
commands.extend(
|
||||||
commands.extend(self._refresh_lb_vips(ovn_lb, external_ids))
|
self._refresh_lb_vips(
|
||||||
|
ovn_lb,
|
||||||
|
external_ids,
|
||||||
|
is_sync=(
|
||||||
|
fip_info['action'] == ovn_const.REQ_INFO_ACTION_SYNC)
|
||||||
|
)
|
||||||
|
)
|
||||||
self._execute_commands(commands)
|
self._execute_commands(commands)
|
||||||
|
|
||||||
def handle_member_dvr(self, info):
|
def handle_member_dvr(self, info):
|
||||||
@@ -3140,6 +3174,18 @@ class OvnProviderHelper():
|
|||||||
{'member': info['id'],
|
{'member': info['id'],
|
||||||
'fip': fip.external_ip})
|
'fip': fip.external_ip})
|
||||||
|
|
||||||
|
def get_lsp(self, port_id, network_id):
|
||||||
|
ls_name = utils.ovn_name(network_id)
|
||||||
|
try:
|
||||||
|
ls = self.ovn_nbdb_api.lookup('Logical_Switch', ls_name)
|
||||||
|
except idlutils.RowNotFound:
|
||||||
|
LOG.warn(f"Logical Switch {ls_name} not found.")
|
||||||
|
return
|
||||||
|
for port in ls.ports:
|
||||||
|
if port_id in port.name:
|
||||||
|
# We found particular port
|
||||||
|
return port
|
||||||
|
|
||||||
def _get_member_lsp(self, member_ip, member_subnet_id):
|
def _get_member_lsp(self, member_ip, member_subnet_id):
|
||||||
neutron_client = clients.get_neutron_client()
|
neutron_client = clients.get_neutron_client()
|
||||||
try:
|
try:
|
||||||
@@ -3160,6 +3206,15 @@ class OvnProviderHelper():
|
|||||||
# We found particular port
|
# We found particular port
|
||||||
return port
|
return port
|
||||||
|
|
||||||
|
def get_fip_from_vip(self, lb):
|
||||||
|
neutron_client = clients.get_neutron_client()
|
||||||
|
try:
|
||||||
|
return list(neutron_client.ips(port_id=lb.vip_port_id))
|
||||||
|
except openstack.exceptions.HttpException as e:
|
||||||
|
LOG.warn("Error on fetch fip for "
|
||||||
|
f"{lb.loadbalancer_id} "
|
||||||
|
f"Error: {str(e)}")
|
||||||
|
|
||||||
def _add_lbhc(self, ovn_lb, pool_key, info):
|
def _add_lbhc(self, ovn_lb, pool_key, info):
|
||||||
hm_id = info[constants.ID]
|
hm_id = info[constants.ID]
|
||||||
status = {constants.ID: hm_id,
|
status = {constants.ID: hm_id,
|
||||||
@@ -3586,7 +3641,7 @@ class OvnProviderHelper():
|
|||||||
raise idlutils.RowNotFound(table='Load_Balancer_Health_Check',
|
raise idlutils.RowNotFound(table='Load_Balancer_Health_Check',
|
||||||
col='external_ids', match=hm_id)
|
col='external_ids', match=hm_id)
|
||||||
|
|
||||||
def _find_ovn_lb_from_hm_id(self, hm_id):
|
def _find_ovn_lb_from_hm_id(self, hm_id, lbhc_vip=None):
|
||||||
lbs = self.ovn_nbdb_api.db_list_rows(
|
lbs = self.ovn_nbdb_api.db_list_rows(
|
||||||
'Load_Balancer').execute(check_error=True)
|
'Load_Balancer').execute(check_error=True)
|
||||||
ovn_lb = None
|
ovn_lb = None
|
||||||
@@ -3597,7 +3652,14 @@ class OvnProviderHelper():
|
|||||||
break
|
break
|
||||||
|
|
||||||
try:
|
try:
|
||||||
lbhcs = self._lookup_lbhcs_by_hm_id(hm_id)
|
lbhcs_by_hm_id = self._lookup_lbhcs_by_hm_id(hm_id)
|
||||||
|
if lbhc_vip:
|
||||||
|
lbhcs = []
|
||||||
|
for lbhc in lbhcs_by_hm_id:
|
||||||
|
if lbhc.vip == lbhc_vip:
|
||||||
|
lbhcs.append(lbhc)
|
||||||
|
else:
|
||||||
|
lbhcs = lbhcs_by_hm_id
|
||||||
except idlutils.RowNotFound:
|
except idlutils.RowNotFound:
|
||||||
LOG.debug("Loadbalancer health check %s not found!", hm_id)
|
LOG.debug("Loadbalancer health check %s not found!", hm_id)
|
||||||
return [], ovn_lb
|
return [], ovn_lb
|
||||||
@@ -4112,17 +4174,17 @@ class OvnProviderHelper():
|
|||||||
continue
|
continue
|
||||||
fetch_hc_ids.extend([str(lbhc.uuid) for lbhc in lbhcs])
|
fetch_hc_ids.extend([str(lbhc.uuid) for lbhc in lbhcs])
|
||||||
|
|
||||||
for hc_id in ovn_lb.health_check:
|
for lbhc in ovn_lb.health_check:
|
||||||
if str(hc_id.uuid) not in fetch_hc_ids:
|
if str(lbhc.uuid) not in fetch_hc_ids:
|
||||||
commands = []
|
commands = []
|
||||||
commands.append(
|
commands.append(
|
||||||
self.ovn_nbdb_api.db_remove(
|
self.ovn_nbdb_api.db_remove(
|
||||||
'Load_Balancer', ovn_lb.uuid,
|
'Load_Balancer', ovn_lb.uuid,
|
||||||
'health_check', hc_id.uuid))
|
'health_check', lbhc.uuid))
|
||||||
commands.append(
|
commands.append(
|
||||||
self.ovn_nbdb_api.db_destroy(
|
self.ovn_nbdb_api.db_destroy(
|
||||||
'Load_Balancer_Health_Check',
|
'Load_Balancer_Health_Check',
|
||||||
hc_id.uuid))
|
lbhc.uuid))
|
||||||
try:
|
try:
|
||||||
self._execute_commands(commands)
|
self._execute_commands(commands)
|
||||||
except idlutils.RowNotFound:
|
except idlutils.RowNotFound:
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from octavia_lib.api.drivers import data_models
|
|||||||
from octavia_lib.api.drivers import driver_lib as o_driver_lib
|
from octavia_lib.api.drivers import driver_lib as o_driver_lib
|
||||||
from octavia_lib.api.drivers import exceptions
|
from octavia_lib.api.drivers import exceptions
|
||||||
from octavia_lib.common import constants
|
from octavia_lib.common import constants
|
||||||
|
import openstack
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
from ovsdbapp.backend.ovs_idl import idlutils
|
from ovsdbapp.backend.ovs_idl import idlutils
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ from ovn_octavia_provider.common import exceptions as ovn_exc
|
|||||||
from ovn_octavia_provider import driver as ovn_driver
|
from ovn_octavia_provider import driver as ovn_driver
|
||||||
from ovn_octavia_provider import helper as ovn_helper
|
from ovn_octavia_provider import helper as ovn_helper
|
||||||
from ovn_octavia_provider.tests.unit import base as ovn_base
|
from ovn_octavia_provider.tests.unit import base as ovn_base
|
||||||
|
from ovn_octavia_provider.tests.unit import fakes
|
||||||
|
|
||||||
|
|
||||||
class TestOvnProviderDriver(ovn_base.TestOvnOctaviaBase):
|
class TestOvnProviderDriver(ovn_base.TestOvnOctaviaBase):
|
||||||
@@ -46,8 +48,9 @@ class TestOvnProviderDriver(ovn_base.TestOvnOctaviaBase):
|
|||||||
self.member_port, self.member_subnet_id))
|
self.member_port, self.member_subnet_id))
|
||||||
self.ovn_lb = mock.MagicMock()
|
self.ovn_lb = mock.MagicMock()
|
||||||
self.ovn_lb.name = 'foo_ovn_lb'
|
self.ovn_lb.name = 'foo_ovn_lb'
|
||||||
|
self.fake_vip = '10.22.33.4'
|
||||||
self.ovn_lb.external_ids = {
|
self.ovn_lb.external_ids = {
|
||||||
ovn_const.LB_EXT_IDS_VIP_KEY: '10.22.33.4',
|
ovn_const.LB_EXT_IDS_VIP_KEY: self.fake_vip,
|
||||||
'pool_%s' % self.pool_id: self.member_line,
|
'pool_%s' % self.pool_id: self.member_line,
|
||||||
'listener_%s' % self.listener_id: '80:pool_%s' % self.pool_id}
|
'listener_%s' % self.listener_id: '80:pool_%s' % self.pool_id}
|
||||||
self.ovn_lb_addi_vips = mock.MagicMock()
|
self.ovn_lb_addi_vips = mock.MagicMock()
|
||||||
@@ -282,6 +285,36 @@ class TestOvnProviderDriver(ovn_base.TestOvnOctaviaBase):
|
|||||||
ovn_helper.OvnProviderHelper,
|
ovn_helper.OvnProviderHelper,
|
||||||
'_check_ip_in_subnet',
|
'_check_ip_in_subnet',
|
||||||
return_value=True).start()
|
return_value=True).start()
|
||||||
|
self.fake_fip = '1.2.3.4'
|
||||||
|
self.lsp = fakes.FakeOvsdbRow.create_one_ovsdb_row(
|
||||||
|
attrs={
|
||||||
|
'external_ids': {
|
||||||
|
ovn_const.OVN_PORT_FIP_EXT_ID_KEY: self.fake_fip,
|
||||||
|
ovn_const.OVN_PORT_NAME_EXT_ID_KEY:
|
||||||
|
'ovn-lb-vip-d571f37e-5708-48a1-8ba8-fc5d9ce36eac',
|
||||||
|
},
|
||||||
|
'type': 'localnet',
|
||||||
|
'options': {},
|
||||||
|
})
|
||||||
|
self.lsp_addi = fakes.FakeOvsdbRow.create_one_ovsdb_row(
|
||||||
|
attrs={
|
||||||
|
'external_ids': {
|
||||||
|
ovn_const.OVN_PORT_FIP_EXT_ID_KEY: self.fake_fip,
|
||||||
|
ovn_const.OVN_PORT_NAME_EXT_ID_KEY:
|
||||||
|
'ovn-lb-vip-additional--\
|
||||||
|
19d4c20e-05ff-4534-9d5c-214f2979db40',
|
||||||
|
},
|
||||||
|
'type': 'localnet',
|
||||||
|
'options': {},
|
||||||
|
})
|
||||||
|
self.mock_get_lsp = mock.patch.object(
|
||||||
|
ovn_helper.OvnProviderHelper,
|
||||||
|
'get_lsp',
|
||||||
|
return_value=self.lsp).start()
|
||||||
|
self.mock_find_ovn_lbs_with_retry = mock.patch.object(
|
||||||
|
ovn_helper.OvnProviderHelper,
|
||||||
|
'_find_ovn_lbs_with_retry',
|
||||||
|
return_value=[self.ovn_lb]).start()
|
||||||
|
|
||||||
def test_check_for_allowed_cidrs_exception(self):
|
def test_check_for_allowed_cidrs_exception(self):
|
||||||
self.assertRaises(exceptions.UnsupportedOptionError,
|
self.assertRaises(exceptions.UnsupportedOptionError,
|
||||||
@@ -798,6 +831,167 @@ class TestOvnProviderDriver(ovn_base.TestOvnOctaviaBase):
|
|||||||
self.driver.loadbalancer_create(self.ref_lb0)
|
self.driver.loadbalancer_create(self.ref_lb0)
|
||||||
self.mock_add_request.assert_has_calls(calls)
|
self.mock_add_request.assert_has_calls(calls)
|
||||||
|
|
||||||
|
@mock.patch.object(ovn_helper.OvnProviderHelper, 'vip_port_update_handler')
|
||||||
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
|
def test_fip_sync_basic(self, net_cli, m_vpu):
|
||||||
|
net_cli.return_value.ips.return_value = [
|
||||||
|
mock.Mock(floating_ip_address=self.fake_fip)]
|
||||||
|
self.ref_lb_fully_sync_populated.vip_port_id = 'foo'
|
||||||
|
self.driver._fip_sync(self.ref_lb_fully_sync_populated)
|
||||||
|
m_vpu.assert_called_once_with(
|
||||||
|
vip_lp=self.lsp, fip=self.fake_fip,
|
||||||
|
action=ovn_const.REQ_INFO_ACTION_SYNC)
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
|
def test_fip_sync(self, net_cli):
|
||||||
|
net_cli.return_value.ips.return_value = [
|
||||||
|
mock.Mock(floating_ip_address=self.fake_fip)]
|
||||||
|
fake_port = fakes.FakePort.create_one_port()
|
||||||
|
|
||||||
|
fake_port['fixed_ips'][0]['ip_address'] = self.fake_vip
|
||||||
|
|
||||||
|
net_cli.return_value.get_port.return_value = fake_port
|
||||||
|
self.ref_lb_fully_sync_populated.vip_port_id = 'foo'
|
||||||
|
|
||||||
|
with mock.patch.object(ovn_helper.OvnProviderHelper,
|
||||||
|
'handle_vip_fip') as mock_handle_vip_fip:
|
||||||
|
info = {
|
||||||
|
'ovn_lb': self.ovn_lb,
|
||||||
|
'vip_fip': self.fake_fip,
|
||||||
|
'vip_related': [self.fake_vip],
|
||||||
|
'additional_vip_fip': False,
|
||||||
|
'action': ovn_const.REQ_INFO_ACTION_SYNC
|
||||||
|
}
|
||||||
|
self.driver._fip_sync(self.ref_lb_fully_sync_populated)
|
||||||
|
mock_handle_vip_fip.assert_called_once_with(info)
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
|
def test_fip_sync_ovn_lb_not_found(self, net_cli):
|
||||||
|
self.mock_find_ovn_lbs_with_retry.side_effect = [
|
||||||
|
idlutils.RowNotFound]
|
||||||
|
net_cli.return_value.ips.return_value = [
|
||||||
|
mock.Mock(floating_ip_address=self.fake_fip)]
|
||||||
|
self.ref_lb_fully_sync_populated.vip_port_id = 'foo'
|
||||||
|
with mock.patch.object(ovn_helper, 'LOG') as m_l:
|
||||||
|
self.driver._fip_sync(self.ref_lb_fully_sync_populated)
|
||||||
|
m_l.debug.assert_called()
|
||||||
|
self.mock_add_request.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
|
def test_fip_sync_addi(self, net_cli):
|
||||||
|
net_cli.return_value.ips.return_value = [
|
||||||
|
mock.Mock(floating_ip_address=self.fake_fip)]
|
||||||
|
fake_port = fakes.FakePort.create_one_port()
|
||||||
|
self.mock_get_lsp.return_value = self.lsp_addi
|
||||||
|
fake_port['fixed_ips'][0]['ip_address'] = self.fake_vip
|
||||||
|
|
||||||
|
net_cli.return_value.get_port.return_value = fake_port
|
||||||
|
self.ref_lb_fully_sync_populated.vip_port_id = 'foo'
|
||||||
|
|
||||||
|
with mock.patch.object(ovn_helper.OvnProviderHelper,
|
||||||
|
'handle_vip_fip') as mock_handle_vip_fip:
|
||||||
|
info = {
|
||||||
|
'ovn_lb': self.ovn_lb,
|
||||||
|
'vip_fip': self.fake_fip,
|
||||||
|
'vip_related': [self.fake_vip],
|
||||||
|
'additional_vip_fip': True,
|
||||||
|
'action': ovn_const.REQ_INFO_ACTION_SYNC
|
||||||
|
}
|
||||||
|
self.driver._fip_sync(self.ref_lb_fully_sync_populated)
|
||||||
|
mock_handle_vip_fip.assert_called_once_with(info)
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
|
def test_fip_sync_os_err(self, net_cli):
|
||||||
|
net_cli.return_value.ips.side_effect = [
|
||||||
|
openstack.exceptions.HttpException]
|
||||||
|
self.ref_lb_fully_sync_populated.vip_port_id = 'foo'
|
||||||
|
|
||||||
|
calls = [
|
||||||
|
mock.call('Floating IP not found for loadbalancer '
|
||||||
|
f'{self.ref_lb_fully_sync_populated.loadbalancer_id}'),
|
||||||
|
mock.call('Floating IP not consistent between Logic Switch Port '
|
||||||
|
f'and Neutron. Found FIP {self.fake_fip} configured in '
|
||||||
|
f'LSP {self.lsp.name}, but no FIP configured from '
|
||||||
|
'Neutron. Please run command `neutron-ovn-db-sync-util` '
|
||||||
|
'first to sync OVN DB with Neutron DB.')]
|
||||||
|
|
||||||
|
with mock.patch.object(ovn_driver, 'LOG') as m_l:
|
||||||
|
self.driver._fip_sync(self.ref_lb_fully_sync_populated)
|
||||||
|
m_l.warn.assert_has_calls(calls)
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
|
def test_fip_sync_lsp_mismatch(self, net_cli):
|
||||||
|
net_cli.return_value.ips.return_value = [
|
||||||
|
mock.Mock(floating_ip_address='1.2.3.5')]
|
||||||
|
self.ref_lb_fully_sync_populated.vip_port_id = 'foo'
|
||||||
|
msg = ('Floating IP not consistent between Logic Switch Port and '
|
||||||
|
f'Neutron. Found FIP {self.fake_fip} in LSP {self.lsp.name}, '
|
||||||
|
'but we have 1.2.3.5 from Neutron. Skip sync FIP for '
|
||||||
|
'loadbalancer '
|
||||||
|
f'{self.ref_lb_fully_sync_populated.loadbalancer_id}. '
|
||||||
|
'Please run command `neutron-ovn-db-sync-util` first to '
|
||||||
|
'sync OVN DB with Neutron DB.')
|
||||||
|
|
||||||
|
with mock.patch.object(ovn_driver, 'LOG') as m_l:
|
||||||
|
self.driver._fip_sync(self.ref_lb_fully_sync_populated)
|
||||||
|
m_l.warn.assert_called_once_with(msg)
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
|
def test_fip_sync_lsp_not_found(self, net_cli):
|
||||||
|
net_cli.return_value.ips.return_value = [
|
||||||
|
mock.Mock(floating_ip_address='1.2.3.4')]
|
||||||
|
self.ref_lb_fully_sync_populated.vip_port_id = 'foo'
|
||||||
|
|
||||||
|
self.mock_get_lsp.return_value = None
|
||||||
|
msg = (
|
||||||
|
'Logic Switch Port not found for port foo. Skip sync FIP for '
|
||||||
|
'loadbalancer '
|
||||||
|
f'{self.ref_lb_fully_sync_populated.loadbalancer_id}. Please '
|
||||||
|
'run command `neutron-ovn-db-sync-util` first to sync OVN DB '
|
||||||
|
'with Neutron DB.')
|
||||||
|
|
||||||
|
with mock.patch.object(ovn_driver, 'LOG') as m_l:
|
||||||
|
self.driver._fip_sync(self.ref_lb_fully_sync_populated)
|
||||||
|
m_l.warn.assert_called_once_with(msg)
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
|
def test_fip_sync_no_neutron_fip(self, net_cli):
|
||||||
|
net_cli.return_value.ips.return_value = []
|
||||||
|
self.ref_lb_fully_sync_populated.vip_port_id = 'foo'
|
||||||
|
|
||||||
|
calls = [
|
||||||
|
mock.call('Floating IP not found for loadbalancer '
|
||||||
|
f'{self.ref_lb_fully_sync_populated.loadbalancer_id}'),
|
||||||
|
mock.call('Floating IP not consistent between Logic Switch Port '
|
||||||
|
f'and Neutron. Found FIP {self.fake_fip} configured in '
|
||||||
|
f'LSP {self.lsp.name}, but no FIP configured from '
|
||||||
|
'Neutron. Please run command `neutron-ovn-db-sync-util` '
|
||||||
|
'first to sync OVN DB with Neutron DB.')]
|
||||||
|
self.driver.pool_create(self.ref_pool)
|
||||||
|
self.mock_add_request
|
||||||
|
with mock.patch.object(ovn_driver, 'LOG') as m_l:
|
||||||
|
self.driver._fip_sync(self.ref_lb_fully_sync_populated)
|
||||||
|
m_l.warn.assert_has_calls(calls)
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
|
def test_fip_sync_no_neutron_fip_no_lsp(self, net_cli):
|
||||||
|
net_cli.return_value.ips.return_value = []
|
||||||
|
self.ref_lb_fully_sync_populated.vip_port_id = 'foo'
|
||||||
|
self.mock_get_lsp.return_value = None
|
||||||
|
self.driver._fip_sync(self.ref_lb_fully_sync_populated)
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
|
def test_fip_sync_no_port_id(self, net_cli):
|
||||||
|
net_cli.return_value.ips.return_value = [
|
||||||
|
mock.Mock(floating_ip_address='1.2.3.4')]
|
||||||
|
|
||||||
|
msg = ('VIP Port or Network not set for loadbalancer '
|
||||||
|
f'{self.ref_lb_fully_sync_populated.loadbalancer_id}, '
|
||||||
|
'skip FIP sync.')
|
||||||
|
with mock.patch.object(ovn_driver, 'LOG') as m_l:
|
||||||
|
self.driver._fip_sync(self.ref_lb_fully_sync_populated)
|
||||||
|
m_l.debug.assert_called_once_with(msg)
|
||||||
|
|
||||||
def test_loadbalancer_create_additional_vips(self):
|
def test_loadbalancer_create_additional_vips(self):
|
||||||
info = {'id': self.ref_lb2.loadbalancer_id,
|
info = {'id': self.ref_lb2.loadbalancer_id,
|
||||||
'vip_address': self.ref_lb2.vip_address,
|
'vip_address': self.ref_lb2.vip_address,
|
||||||
|
|||||||
@@ -4006,6 +4006,42 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
self.switch_port_event.run(mock.ANY, row, old)
|
self.switch_port_event.run(mock.ANY, row, old)
|
||||||
self.mock_add_request.assert_not_called()
|
self.mock_add_request.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
||||||
|
'_find_ovn_lbs')
|
||||||
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
|
def test_vip_port_update_handler_no_port(self, net_cli, lb):
|
||||||
|
lb1 = mock.MagicMock()
|
||||||
|
lb.return_value = [lb1]
|
||||||
|
self.switch_port_event = ovn_event.LogicalSwitchPortUpdateEvent(
|
||||||
|
self.helper)
|
||||||
|
|
||||||
|
net_cli.return_value.get_port.return_value = None
|
||||||
|
|
||||||
|
port_name = '%s%s' % (ovn_const.LB_VIP_PORT_PREFIX, 'foo')
|
||||||
|
attrs = {'external_ids':
|
||||||
|
{ovn_const.OVN_PORT_NAME_EXT_ID_KEY: port_name}}
|
||||||
|
row = fakes.FakeOvsdbRow.create_one_ovsdb_row(
|
||||||
|
attrs=attrs)
|
||||||
|
attrs_old = {'external_ids':
|
||||||
|
{ovn_const.OVN_PORT_NAME_EXT_ID_KEY: port_name,
|
||||||
|
ovn_const.OVN_PORT_FIP_EXT_ID_KEY: '172.24.4.40'}}
|
||||||
|
old = fakes.FakeOvsdbRow.create_one_ovsdb_row(
|
||||||
|
attrs=attrs_old)
|
||||||
|
self.switch_port_event.run(mock.ANY, row, old)
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'type': 'handle_vip_fip',
|
||||||
|
'info': {
|
||||||
|
'action': ovn_const.REQ_INFO_ACTION_DISASSOCIATE,
|
||||||
|
'vip_fip': '172.24.4.40',
|
||||||
|
'vip_related': [],
|
||||||
|
'additional_vip_fip': False,
|
||||||
|
'ovn_lb': lb1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.mock_add_request.assert_called_once_with(expected)
|
||||||
|
|
||||||
@mock.patch.object(ovn_helper.OvnProviderHelper, '_execute_commands')
|
@mock.patch.object(ovn_helper.OvnProviderHelper, '_execute_commands')
|
||||||
def test__update_lb_to_lr_association_retry(self, execute):
|
def test__update_lb_to_lr_association_retry(self, execute):
|
||||||
self._update_lb_to_lr_association.stop()
|
self._update_lb_to_lr_association.stop()
|
||||||
@@ -4047,7 +4083,7 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
self.router)
|
self.router)
|
||||||
|
|
||||||
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
||||||
'_find_ovn_lbs')
|
'_find_ovn_lbs_with_retry')
|
||||||
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
def test_vip_port_update_handler_multiple_lbs(self, net_cli, lb):
|
def test_vip_port_update_handler_multiple_lbs(self, net_cli, lb):
|
||||||
lb1 = mock.MagicMock()
|
lb1 = mock.MagicMock()
|
||||||
@@ -4074,7 +4110,7 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
def expected_call(lb):
|
def expected_call(lb):
|
||||||
return {'type': 'handle_vip_fip',
|
return {'type': 'handle_vip_fip',
|
||||||
'info':
|
'info':
|
||||||
{'action': mock.ANY,
|
{'action': ovn_const.REQ_INFO_ACTION_DISASSOCIATE,
|
||||||
'vip_fip': '172.24.4.40',
|
'vip_fip': '172.24.4.40',
|
||||||
'vip_related': [fake_port.fixed_ips[0]['ip_address']],
|
'vip_related': [fake_port.fixed_ips[0]['ip_address']],
|
||||||
'additional_vip_fip': False,
|
'additional_vip_fip': False,
|
||||||
@@ -4110,17 +4146,16 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
attrs=attrs_old)
|
attrs=attrs_old)
|
||||||
self.switch_port_event.run(mock.ANY, row, old)
|
self.switch_port_event.run(mock.ANY, row, old)
|
||||||
|
|
||||||
def expected_call(lb):
|
expected = {
|
||||||
return {'type': 'handle_vip_fip',
|
'type': 'handle_vip_fip',
|
||||||
'info':
|
'info': {
|
||||||
{'action': ovn_const.REQ_INFO_ACTION_DISASSOCIATE,
|
'action': ovn_const.REQ_INFO_ACTION_DISASSOCIATE,
|
||||||
'vip_fip': fip,
|
'vip_fip': fip,
|
||||||
'vip_related': [fake_port.fixed_ips[0]['ip_address']],
|
'vip_related': [fake_port.fixed_ips[0]['ip_address']],
|
||||||
'additional_vip_fip': True,
|
'additional_vip_fip': True,
|
||||||
'ovn_lb': lb}}
|
'ovn_lb': lb1}}
|
||||||
|
|
||||||
self.mock_add_request.assert_has_calls([
|
self.mock_add_request.assert_has_calls([mock.call(expected)])
|
||||||
mock.call(expected_call(lb1))])
|
|
||||||
|
|
||||||
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
||||||
'_find_ovn_lbs')
|
'_find_ovn_lbs')
|
||||||
@@ -4147,17 +4182,16 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
attrs=attrs_old)
|
attrs=attrs_old)
|
||||||
self.switch_port_event.run(mock.ANY, row, old)
|
self.switch_port_event.run(mock.ANY, row, old)
|
||||||
|
|
||||||
def expected_call(lb):
|
expected = {
|
||||||
return {'type': 'handle_vip_fip',
|
'type': 'handle_vip_fip',
|
||||||
'info':
|
'info': {
|
||||||
{'action': ovn_const.REQ_INFO_ACTION_ASSOCIATE,
|
'action': ovn_const.REQ_INFO_ACTION_ASSOCIATE,
|
||||||
'vip_fip': '10.0.0.99',
|
'vip_fip': '10.0.0.99',
|
||||||
'vip_related': [fake_port.fixed_ips[0]['ip_address']],
|
'vip_related': [fake_port.fixed_ips[0]['ip_address']],
|
||||||
'additional_vip_fip': True,
|
'additional_vip_fip': True,
|
||||||
'ovn_lb': lb}}
|
'ovn_lb': lb1}}
|
||||||
|
|
||||||
self.mock_add_request.assert_has_calls([
|
self.mock_add_request.assert_has_calls([mock.call(expected)])
|
||||||
mock.call(expected_call(lb1))])
|
|
||||||
|
|
||||||
lb1 = mock.MagicMock()
|
lb1 = mock.MagicMock()
|
||||||
vip_fip = '10.0.0.123'
|
vip_fip = '10.0.0.123'
|
||||||
@@ -4172,7 +4206,7 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
self.switch_port_event.run(mock.ANY, row, old)
|
self.switch_port_event.run(mock.ANY, row, old)
|
||||||
self.mock_add_request.reset()
|
self.mock_add_request.reset()
|
||||||
self.mock_add_request.assert_has_calls([
|
self.mock_add_request.assert_has_calls([
|
||||||
mock.call(expected_call(lb1))])
|
mock.call(expected)])
|
||||||
|
|
||||||
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
||||||
'_find_ovn_lbs')
|
'_find_ovn_lbs')
|
||||||
@@ -4271,6 +4305,149 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
mock.call.db_set('Load_Balancer', lb.uuid, ('vips', {}))]
|
mock.call.db_set('Load_Balancer', lb.uuid, ('vips', {}))]
|
||||||
self.helper.ovn_nbdb_api.assert_has_calls(calls)
|
self.helper.ovn_nbdb_api.assert_has_calls(calls)
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
||||||
|
'_find_ovn_lbs')
|
||||||
|
def test_handle_vip_fip_sync(self, fb):
|
||||||
|
lb = mock.MagicMock()
|
||||||
|
fip_info = {
|
||||||
|
'action': 'sync',
|
||||||
|
'vip_fip': '10.0.0.123',
|
||||||
|
'ovn_lb': lb}
|
||||||
|
members = 'member_%s_%s:%s_%s' % (self.member_id,
|
||||||
|
self.member_address,
|
||||||
|
self.member_port,
|
||||||
|
self.member_subnet_id)
|
||||||
|
external_ids = {
|
||||||
|
'listener_foo': '80:pool_%s' % self.pool_id,
|
||||||
|
'pool_%s' % self.pool_id: members,
|
||||||
|
'neutron:vip': '172.26.21.20'}
|
||||||
|
|
||||||
|
lb.external_ids = external_ids
|
||||||
|
fb.return_value = lb
|
||||||
|
|
||||||
|
self.helper.handle_vip_fip(fip_info)
|
||||||
|
|
||||||
|
expected_db_set_calls = [
|
||||||
|
mock.call('Load_Balancer', lb.uuid,
|
||||||
|
('external_ids', {'neutron:vip_fip': '10.0.0.123'})),
|
||||||
|
mock.call('Load_Balancer', lb.uuid,
|
||||||
|
('vips', {'10.0.0.123:80': '192.168.2.149:1010',
|
||||||
|
'172.26.21.20:80': '192.168.2.149:1010'}))
|
||||||
|
]
|
||||||
|
self.helper.ovn_nbdb_api.db_set.assert_has_calls(expected_db_set_calls)
|
||||||
|
self.helper.ovn_nbdb_api.db_clear.assert_called_once_with(
|
||||||
|
'Load_Balancer', lb.uuid, 'vips')
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
||||||
|
'_find_ovn_lbs')
|
||||||
|
def test_handle_vip_fip_sync_same_ext(self, fb):
|
||||||
|
lb = mock.MagicMock()
|
||||||
|
fip_info = {
|
||||||
|
'action': 'sync',
|
||||||
|
'vip_fip': '10.0.0.123',
|
||||||
|
'ovn_lb': lb}
|
||||||
|
members = 'member_%s_%s:%s_%s' % (self.member_id,
|
||||||
|
self.member_address,
|
||||||
|
self.member_port,
|
||||||
|
self.member_subnet_id)
|
||||||
|
external_ids = {
|
||||||
|
'listener_foo': '80:pool_%s' % self.pool_id,
|
||||||
|
'pool_%s' % self.pool_id: members,
|
||||||
|
'neutron:vip': '172.26.21.20',
|
||||||
|
'neutron:vip_fip': '10.0.0.123',
|
||||||
|
}
|
||||||
|
|
||||||
|
lb.external_ids = external_ids
|
||||||
|
fb.return_value = lb
|
||||||
|
|
||||||
|
self.helper.handle_vip_fip(fip_info)
|
||||||
|
|
||||||
|
expected_db_set_calls = [
|
||||||
|
mock.call('Load_Balancer', lb.uuid,
|
||||||
|
('vips', {'10.0.0.123:80': '192.168.2.149:1010',
|
||||||
|
'172.26.21.20:80': '192.168.2.149:1010'}))
|
||||||
|
]
|
||||||
|
self.helper.ovn_nbdb_api.db_set.assert_has_calls(expected_db_set_calls)
|
||||||
|
self.helper.ovn_nbdb_api.db_clear.assert_called_once_with(
|
||||||
|
'Load_Balancer', lb.uuid, 'vips')
|
||||||
|
|
||||||
|
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
||||||
|
'_find_ovn_lbs')
|
||||||
|
def test_handle_vip_fip_sync_hm_exist(self, fb):
|
||||||
|
lb = mock.MagicMock()
|
||||||
|
vip_fip = '10.0.0.123'
|
||||||
|
fip_info = {
|
||||||
|
'action': 'sync',
|
||||||
|
'vip_fip': '10.0.0.123',
|
||||||
|
'ovn_lb': lb}
|
||||||
|
members = 'member_%s_%s:%s_%s' % (self.member_id,
|
||||||
|
self.member_address,
|
||||||
|
self.member_port,
|
||||||
|
self.member_subnet_id)
|
||||||
|
external_ids = {
|
||||||
|
'listener_foo': '80:pool_%s' % self.pool_id,
|
||||||
|
'pool_%s' % self.pool_id: members,
|
||||||
|
'neutron:vip': '172.26.21.20',
|
||||||
|
'neutron:vip_fip': '10.0.0.123',
|
||||||
|
}
|
||||||
|
lb_hc_fip = mock.MagicMock()
|
||||||
|
lb_hc_fip.uuid = "fake_lb_hc_fip"
|
||||||
|
lb_hc_fip.vip = f"{vip_fip}:80"
|
||||||
|
lb_hc_fip.external_ids = {
|
||||||
|
ovn_const.LB_EXT_IDS_HM_KEY: 'foo',
|
||||||
|
ovn_const.LB_EXT_IDS_HM_POOL_KEY: 'pool_foo',
|
||||||
|
ovn_const.LB_EXT_IDS_HM_VIP: vip_fip}
|
||||||
|
lb.health_check = [lb_hc_fip]
|
||||||
|
lb.vips = {
|
||||||
|
'172.26.21.20:80': '192.168.2.149:1010',
|
||||||
|
'10.0.0.123:80': '192.168.2.149:1010'
|
||||||
|
}
|
||||||
|
lb.external_ids = external_ids
|
||||||
|
fb.return_value = lb
|
||||||
|
|
||||||
|
self.helper.handle_vip_fip(fip_info)
|
||||||
|
self.helper.ovn_nbdb_api.db_set.assert_not_called()
|
||||||
|
self.helper.ovn_nbdb_api.db_clear.assert_not_called()
|
||||||
|
|
||||||
|
def test_get_lsp(self):
|
||||||
|
self.helper.ovn_nbdb_api.lookup.side_effect = [idlutils.RowNotFound]
|
||||||
|
port_id = '664224ab-a7c4-4918-8d81-0712947eb600'
|
||||||
|
network_id = 'c75cb020-f789-432e-b50e-89a20e5e463d'
|
||||||
|
with mock.patch.object(ovn_helper, 'LOG') as m_l:
|
||||||
|
self.assertIsNone(self.helper.get_lsp(port_id=port_id,
|
||||||
|
network_id=network_id))
|
||||||
|
m_l.warn.assert_called_once_with(
|
||||||
|
f'Logical Switch neutron-{network_id} not found.')
|
||||||
|
|
||||||
|
def test_get_lsp_port_not_found(self):
|
||||||
|
self.helper.ovn_nbdb_api.lookup.return_value = mock.MagicMock(ports=[])
|
||||||
|
port_id = '664224ab-a7c4-4918-8d81-0712947eb600'
|
||||||
|
network_id = 'c75cb020-f789-432e-b50e-89a20e5e463d'
|
||||||
|
self.assertIsNone(self.helper.get_lsp(port_id=port_id,
|
||||||
|
network_id=network_id))
|
||||||
|
|
||||||
|
def test_get_lsp_port_found(self):
|
||||||
|
port_id = '664224ab-a7c4-4918-8d81-0712947eb600'
|
||||||
|
network_id = 'c75cb020-f789-432e-b50e-89a20e5e463d'
|
||||||
|
port = mock.MagicMock()
|
||||||
|
port.name = port_id
|
||||||
|
self.helper.ovn_nbdb_api.lookup.return_value = mock.MagicMock(
|
||||||
|
ports=[port])
|
||||||
|
self.assertEqual(self.helper.get_lsp(
|
||||||
|
port_id=port_id, network_id=network_id), port)
|
||||||
|
|
||||||
|
def test_get_lsp_port_found_many_ports(self):
|
||||||
|
port_id = '664224ab-a7c4-4918-8d81-0712947eb600'
|
||||||
|
network_id = 'c75cb020-f789-432e-b50e-89a20e5e463d'
|
||||||
|
port = mock.MagicMock()
|
||||||
|
port.name = port_id
|
||||||
|
port2 = mock.MagicMock()
|
||||||
|
port2.name = 'foo'
|
||||||
|
self.helper.ovn_nbdb_api.lookup.return_value = mock.MagicMock(
|
||||||
|
ports=[port2, port])
|
||||||
|
self.assertEqual(self.helper.get_lsp(
|
||||||
|
port_id=port_id, network_id=network_id), port)
|
||||||
|
|
||||||
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
@mock.patch('ovn_octavia_provider.helper.OvnProviderHelper.'
|
||||||
'_find_ovn_lbs')
|
'_find_ovn_lbs')
|
||||||
def test_handle_vip_fip_associate(self, fb):
|
def test_handle_vip_fip_associate(self, fb):
|
||||||
@@ -5047,8 +5224,7 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
@mock.patch('ovn_octavia_provider.common.clients.get_neutron_client')
|
||||||
@mock.patch.object(ovn_helper.OvnProviderHelper, '_update_hm_member')
|
@mock.patch.object(ovn_helper.OvnProviderHelper, '_update_hm_member')
|
||||||
@mock.patch.object(ovn_helper.OvnProviderHelper, '_find_ovn_lb_by_pool_id')
|
@mock.patch.object(ovn_helper.OvnProviderHelper, '_find_ovn_lb_by_pool_id')
|
||||||
def _test_hm_create(self, protocol, members, fip, folbpi, uhm,
|
def _test_hm_create(self, protocol, members, fip, folbpi, uhm, net_cli):
|
||||||
net_cli):
|
|
||||||
self._get_pool_listeners.stop()
|
self._get_pool_listeners.stop()
|
||||||
fake_subnet = fakes.FakeSubnet.create_one_subnet()
|
fake_subnet = fakes.FakeSubnet.create_one_subnet()
|
||||||
pool_key = 'pool_%s' % self.pool_id
|
pool_key = 'pool_%s' % self.pool_id
|
||||||
|
|||||||
Reference in New Issue
Block a user