Fix UDP pool's member status in LB with additional VIPs

With UDP LBs with additional VIPs, the status of the members included
only the IPv4 (or IPv6) members, but not both. The members were marked
as DOWN.

Partial-Bug: #2028751

Change-Id: Idccb8734c1acf9f05cca1ec5f184410e98b819c1
This commit is contained in:
Gregory Thiemonge 2023-07-26 05:51:57 -04:00
parent 72f59a34fe
commit 58d0ede1e5
3 changed files with 73 additions and 14 deletions

View File

@ -94,13 +94,10 @@ def get_listener_realserver_mapping(ns_name, listener_ip_ports,
if 'RemoteAddress:Port' in line: if 'RemoteAddress:Port' in line:
result_keys = re.split(r'\s+', result_keys = re.split(r'\s+',
LVS_KEY_REGEX.findall(line)[0].strip()) LVS_KEY_REGEX.findall(line)[0].strip())
elif ((line.startswith(constants.PROTOCOL_UDP) or elif (line.startswith(constants.PROTOCOL_UDP) or
line.startswith(lib_consts.PROTOCOL_SCTP)) and line.startswith(lib_consts.PROTOCOL_SCTP)):
find_target_block): find_target_block = re.match(r'^(UDP|SCTP)\s+%s\s+\w+' % idex,
break line) is not None
elif re.match(r'^(UDP|SCTP)\s+%s\s+\w+' % idex,
line):
find_target_block = True
elif find_target_block and line: elif find_target_block and line:
rs_is_ipv4 = True rs_is_ipv4 = True
all_values = V4_RS_VALUE_REGEX.findall(line) all_values = V4_RS_VALUE_REGEX.findall(line)
@ -136,7 +133,7 @@ def get_listener_realserver_mapping(ns_name, listener_ip_ports,
result_keys[index]] = result_values[index] result_keys[index]] = result_values[index]
continue continue
return find_target_block, actual_member_result return actual_member_result
def get_lvs_listener_resource_ipports_nsname(listener_id): def get_lvs_listener_resource_ipports_nsname(listener_id):
@ -267,7 +264,7 @@ def get_lvs_listener_pool_status(listener_id):
cfg = f.read() cfg = f.read()
hm_enabled = len(CHECKER_REGEX.findall(cfg)) > 0 hm_enabled = len(CHECKER_REGEX.findall(cfg)) > 0
_, realserver_result = get_listener_realserver_mapping( realserver_result = get_listener_realserver_mapping(
ns_name, resource_ipport_mapping['Listener']['ipports'], ns_name, resource_ipport_mapping['Listener']['ipports'],
hm_enabled) hm_enabled)
pool_status = constants.UP pool_status = constants.UP

View File

@ -52,6 +52,24 @@ KERNAL_FILE_SAMPLE_V6 = (
" -> [fd79:35e2::8f3f]:115C " " -> [fd79:35e2::8f3f]:115C "
"Masq 2 0 0") "Masq 2 0 0")
KERNEL_FILE_SAMPLE_MIXED = (
"IP Virtual Server version 1.2.1 (size=4096)\n"
"Prot LocalAddress:Port Scheduler Flags\n"
" -> RemoteAddress:Port Forward Weight ActiveConn InActConn\n"
"UDP [fd79:35e2:9963:0000:f816:3eff:fe6d:7a2a]:1E61 rr\n"
" -> [fd79:35e2:9963:0000:f816:3eff:feca:b7bf]:08AE "
"Masq 3 0 0\n"
" -> [fd79:35e2:9963:0000:f816:3eff:fe9d:94df]:0D05 "
"Masq 2 0 0\n"
" -> [fd79:35e2::8f3f]:115C "
"Masq 2 0 0\n"
"UDP 0A000025:1E61 rr\n"
" -> 0A000023:0D05 Masq 2 0 0\n"
" -> 0A000019:08AE Masq 3 0 0\n"
"UDP 0A000025:FF12 rr\n"
" -> 0A000023:12AB Masq 2 0 0\n"
" -> 0A000019:BF2E Masq 3 0 0")
CFG_FILE_TEMPLATE_v4 = ( CFG_FILE_TEMPLATE_v4 = (
"# Configuration for Listener %(listener_id)s\n\n" "# Configuration for Listener %(listener_id)s\n\n"
"net_namespace %(ns_name)s\n\n" "net_namespace %(ns_name)s\n\n"
@ -345,7 +363,7 @@ class LvsQueryTestCase(base.TestCase):
'Weight': '2', 'Weight': '2',
'ActiveConn': '0', 'ActiveConn': '0',
'InActConn': '0'}} 'InActConn': '0'}}
self.assertEqual((True, expected), result) self.assertEqual(expected, result)
# Ipv6 resolver # Ipv6 resolver
input_listener_ip_port = [ input_listener_ip_port = [
@ -372,7 +390,45 @@ class LvsQueryTestCase(base.TestCase):
'Weight': '2', 'Weight': '2',
'ActiveConn': '0', 'ActiveConn': '0',
'InActConn': '0'}} 'InActConn': '0'}}
self.assertEqual((True, expected), result) self.assertEqual(expected, result)
# mixed resolver
input_listener_ip_port = [
'[fd79:35e2:9963:0:f816:3eff:fe6d:7a2a]:7777',
'10.0.0.37:7777']
mock_check_output.return_value = KERNEL_FILE_SAMPLE_MIXED
result = lvs_query.get_listener_realserver_mapping(
target_ns, input_listener_ip_port,
health_monitor_enabled=True)
expected = {'[fd79:35e2:9963:0:f816:3eff:feca:b7bf]:2222':
{'status': constants.UP,
'Forward': 'Masq',
'Weight': '3',
'ActiveConn': '0',
'InActConn': '0'},
'[fd79:35e2:9963:0:f816:3eff:fe9d:94df]:3333':
{'status': constants.UP,
'Forward': 'Masq',
'Weight': '2',
'ActiveConn': '0',
'InActConn': '0'},
'[fd79:35e2::8f3f]:4444':
{'status': constants.UP,
'Forward': 'Masq',
'Weight': '2',
'ActiveConn': '0',
'InActConn': '0'},
'10.0.0.25:2222': {'status': 'UP',
'Forward': 'Masq',
'Weight': '3',
'ActiveConn': '0',
'InActConn': '0'},
'10.0.0.35:3333': {'status': 'UP',
'Forward': 'Masq',
'Weight': '2',
'ActiveConn': '0',
'InActConn': '0'}}
self.assertEqual(expected, result)
# negetive cases # negetive cases
mock_check_output.return_value = KERNAL_FILE_SAMPLE_V4 mock_check_output.return_value = KERNAL_FILE_SAMPLE_V4
@ -380,7 +436,7 @@ class LvsQueryTestCase(base.TestCase):
result = lvs_query.get_listener_realserver_mapping( result = lvs_query.get_listener_realserver_mapping(
target_ns, [listener_ip_port], target_ns, [listener_ip_port],
health_monitor_enabled=True) health_monitor_enabled=True)
self.assertEqual((False, {}), result) self.assertEqual({}, result)
mock_check_output.return_value = KERNAL_FILE_SAMPLE_V6 mock_check_output.return_value = KERNAL_FILE_SAMPLE_V6
for listener_ip_port in [ for listener_ip_port in [
@ -389,7 +445,7 @@ class LvsQueryTestCase(base.TestCase):
result = lvs_query.get_listener_realserver_mapping( result = lvs_query.get_listener_realserver_mapping(
target_ns, [listener_ip_port], target_ns, [listener_ip_port],
health_monitor_enabled=True) health_monitor_enabled=True)
self.assertEqual((False, {}), result) self.assertEqual({}, result)
def test_get_lvs_listener_resource_ipports_nsname(self): def test_get_lvs_listener_resource_ipports_nsname(self):
# ipv4 # ipv4
@ -571,7 +627,7 @@ class LvsQueryTestCase(base.TestCase):
mock.Mock(st_mtime=1234), mock.Mock(st_mtime=1234),
mock.Mock(st_mtime=1234), mock.Mock(st_mtime=1234),
) )
mock_get_mapping.return_value = (False, {}) mock_get_mapping.return_value = {}
res = lvs_query.get_lvs_listener_pool_status(self.listener_id_v4) res = lvs_query.get_lvs_listener_pool_status(self.listener_id_v4)
expected = { expected = {
'lvs': 'lvs':

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Fixed a bug with the status of the members of UDP pools in load balancer
with IPv4 and IPv6 VIPs. Some members may have been incorrectly reported as
DOWN by the Amphora.