From 8b210bb52a6c44b3bd69acdf2202d1625e763fb6 Mon Sep 17 00:00:00 2001 From: Gregory Thiemonge Date: Fri, 5 Feb 2021 22:03:21 +0100 Subject: [PATCH] Fix incorrect ERROR status with IPv6 UDP members Some IPv6 UDP members were incorrectly marked in ERROR status because of a formatting issue between the keepalived configuration file and the ipvsadm output. Both are used to compute the state of the members and when a member's address contained '*:0:*', parsing was incorrect. Now the health message generation function uses only the compressed IPv6 notation instead of mixing notations. Story: 2008604 Task: 41783 Change-Id: I2fe94cd4c000f143c59c69e82d03c690acf5e0c3 (cherry picked from commit e5f9f6708c70313bd7e0c570f3541c0afb7fc09c) --- .../backends/utils/keepalivedlvs_query.py | 13 +++++----- .../utils/test_keepalivedlvs_query.py | 25 +++++++++++++++++-- ...6-udp-health-message-ed94b35bbea396ec.yaml | 5 ++++ 3 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 releasenotes/notes/fix-ipv6-udp-health-message-ed94b35bbea396ec.yaml diff --git a/octavia/amphorae/backends/utils/keepalivedlvs_query.py b/octavia/amphorae/backends/utils/keepalivedlvs_query.py index 34cc1240c2..0f424d8a54 100644 --- a/octavia/amphorae/backends/utils/keepalivedlvs_query.py +++ b/octavia/amphorae/backends/utils/keepalivedlvs_query.py @@ -206,19 +206,20 @@ def get_udp_listener_resource_ipports_nsname(listener_id): if rs_ip_port_list: rs_ip_port_count = len(rs_ip_port_list) for index in range(rs_ip_port_count): - if ipaddress.ip_address( - rs_ip_port_list[index][0]).version == 6: + member_ip = ipaddress.ip_address( + rs_ip_port_list[index][0]) + if member_ip.version == 6: rs_ip_port_list[index] = ( - '[' + rs_ip_port_list[index][0] + ']', + '[' + member_ip.compressed + ']', rs_ip_port_list[index][1]) resource_ipport_mapping['Members'][index]['ipport'] = ( rs_ip_port_list[index][0] + ':' + rs_ip_port_list[index][1]) - if ipaddress.ip_address( - listener_ip_port[0]).version == 6: + listener_ip = ipaddress.ip_address(listener_ip_port[0]) + if listener_ip.version == 6: listener_ip_port = ( - '[' + listener_ip_port[0] + ']', listener_ip_port[1]) + '[' + listener_ip.compressed + ']', listener_ip_port[1]) resource_ipport_mapping['Listener']['ipport'] = ( listener_ip_port[0] + ':' + listener_ip_port[1]) diff --git a/octavia/tests/unit/amphorae/backends/utils/test_keepalivedlvs_query.py b/octavia/tests/unit/amphorae/backends/utils/test_keepalivedlvs_query.py index 4d66846052..7708a0ae74 100644 --- a/octavia/tests/unit/amphorae/backends/utils/test_keepalivedlvs_query.py +++ b/octavia/tests/unit/amphorae/backends/utils/test_keepalivedlvs_query.py @@ -48,6 +48,8 @@ KERNAL_FILE_SAMPLE_V6 = ( " -> [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") CFG_FILE_TEMPLATE_v4 = ( @@ -124,6 +126,14 @@ CFG_FILE_TEMPLATE_v6 = ( " }\n\n" " }\n\n" " # Member %(member_id4)s is disabled\n\n" + " # Configuration for Member %(member_id5)s\n" + " real_server fd79:35e2:0:0:0:0:0:8f3f 4444 {\n" + " weight 2\n" + " MISC_CHECK {\n\n" + " misc_path \"/usr/bin/check_script.sh\"\n\n" + " misc_timeout 5\n\n" + " }\n\n" + " }\n\n" "}") CFG_FILE_TEMPLATE_DISABLED_LISTENER = ( @@ -167,6 +177,7 @@ class LvsQueryTestCase(base.TestCase): self.member_id2_v6 = uuidutils.generate_uuid() self.member_id3_v6 = uuidutils.generate_uuid() self.member_id4_v6 = uuidutils.generate_uuid() + self.member_id5_v6 = uuidutils.generate_uuid() self.disabled_listener_id = uuidutils.generate_uuid() cfg_content_v4 = CFG_FILE_TEMPLATE_v4 % { 'listener_id': self.listener_id_v4, @@ -184,7 +195,8 @@ class LvsQueryTestCase(base.TestCase): 'member_id1': self.member_id1_v6, 'member_id2': self.member_id2_v6, 'member_id3': self.member_id3_v6, - 'member_id4': self.member_id4_v6 + 'member_id4': self.member_id4_v6, + 'member_id5': self.member_id5_v6 } cfg_content_disabled_listener = ( CFG_FILE_TEMPLATE_DISABLED_LISTENER % { @@ -234,6 +246,12 @@ class LvsQueryTestCase(base.TestCase): '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', @@ -289,6 +307,8 @@ class LvsQueryTestCase(base.TestCase): 'ipport': '[fd79:35e2:9963:0:f816:3eff:fe9d:94df]:3333'}, {'id': self.member_id3_v6, 'ipport': '[fd79:35e2:9963:0:f816:3eff:fe9d:8f3f]:4444'}, + {'id': self.member_id5_v6, + 'ipport': '[fd79:35e2::8f3f]:4444'}, {'id': self.member_id4_v6, 'ipport': None}]} self.assertEqual((expected, constants.AMPHORA_NAMESPACE), res) @@ -334,7 +354,8 @@ class LvsQueryTestCase(base.TestCase): 'members': {self.member_id1_v6: constants.UP, self.member_id2_v6: constants.UP, self.member_id3_v6: constants.DOWN, - self.member_id4_v6: constants.MAINT}}} + self.member_id4_v6: constants.MAINT, + self.member_id5_v6: constants.UP}}} self.assertEqual(expected, res) @mock.patch('os.stat') diff --git a/releasenotes/notes/fix-ipv6-udp-health-message-ed94b35bbea396ec.yaml b/releasenotes/notes/fix-ipv6-udp-health-message-ed94b35bbea396ec.yaml new file mode 100644 index 0000000000..e7d9d93213 --- /dev/null +++ b/releasenotes/notes/fix-ipv6-udp-health-message-ed94b35bbea396ec.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Some IPv6 UDP members were incorrectly marked in ERROR status, because of + a formatting issue while generating the health message in the amphora.