From bb4f50f798dd5619185cebc5f3db9a55e7f6122e Mon Sep 17 00:00:00 2001 From: Gregory Thiemonge Date: Wed, 5 Aug 2020 08:14:24 +0200 Subject: [PATCH] Fix operational status for disabled UDP listeners Disabled UDP listeners appeared as ONLINE, as the heartbeat message always showed listeners as OPEN, even if disabled. This commit fixes the configuration file for UDP listeners, previously enabling or disabling a UDP listener created the same config file. Now disabling a UDP listener explicitly adds a comment in the file. Based on this comment, the heartbeat message doesn't include status updates for disabled UDP listeners. Story: 2007979 Task: 40605 Change-Id: I400dde533f78bc14ee568bfd9714eafac97e8a39 --- .../backends/utils/keepalivedlvs_query.py | 22 +++++++++++-- octavia/common/jinja/lvs/templates/base.j2 | 4 +++ .../utils/test_keepalivedlvs_query.py | 31 +++++++++++++++++++ .../common/jinja/lvs/test_lvs_jinja_cfg.py | 15 +++++++++ ...-udp-listener-status-3d34a5596e62da1c.yaml | 6 ++++ 5 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/fix-disable-udp-listener-status-3d34a5596e62da1c.yaml diff --git a/octavia/amphorae/backends/utils/keepalivedlvs_query.py b/octavia/amphorae/backends/utils/keepalivedlvs_query.py index 390bb4eb93..56dae54844 100644 --- a/octavia/amphorae/backends/utils/keepalivedlvs_query.py +++ b/octavia/amphorae/backends/utils/keepalivedlvs_query.py @@ -34,8 +34,8 @@ V6_VS_REGEX = re.compile(r"virtual_server\s([\w*:]+\b)\s(\d{1,5})") V6_RS_REGEX = re.compile(r"real_server\s([\w*:]+\b)\s(\d{1,5})") CONFIG_COMMENT_REGEX = re.compile( r"#\sConfiguration\sfor\s(\w+)\s(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})") -DISABLED_MEMBER_COMMENT_REGEX = re.compile( - r"#\sMember\s(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}) is disabled") +DISABLED_CONFIG_COMMENT_REGEX = re.compile( + r"#\s(\w+)\s(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}) is disabled") CHECKER_REGEX = re.compile(r"(MISC_CHECK|HTTP_GET|TCP_CHECK)") @@ -151,6 +151,14 @@ def get_udp_listener_resource_ipports_nsname(listener_id): listener_ip_port = V6_VS_REGEX.findall(cfg) listener_ip_port = listener_ip_port[0] if listener_ip_port else [] + disabled_resource_ids = DISABLED_CONFIG_COMMENT_REGEX.findall(cfg) + + listener_disabled = any(True + for resource in disabled_resource_ids + if resource[0] == 'Listener') + if listener_disabled: + return None, ns_name + if not listener_ip_port: # If not get listener_ip_port from the lvs config file, # that means the udp listener's default pool have no enabled member @@ -180,7 +188,11 @@ def get_udp_listener_resource_ipports_nsname(listener_id): elif resource_type == 'Members': resource_ipport_mapping[resource_type].append(value) - disabled_member_ids = DISABLED_MEMBER_COMMENT_REGEX.findall(cfg) + disabled_member_ids = [ + resource[1] + for resource in disabled_resource_ids + if resource[0] == 'Member' + ] resource_type = 'Members' for member_id in disabled_member_ids: @@ -362,6 +374,10 @@ def get_udp_listeners_stats(): (resource_ipport_mapping, ns_name) = get_udp_listener_resource_ipports_nsname(check_listener_id) + # Listener is disabled, we don't need to send an update + if resource_ipport_mapping is None: + continue + # Since we found the keepalived running, acknowledge the listener # in the heartbeat. If this listener has a pool and members, # the stats will be updated later in the code flow. diff --git a/octavia/common/jinja/lvs/templates/base.j2 b/octavia/common/jinja/lvs/templates/base.j2 index 6ee5016da9..b3a5d71773 100644 --- a/octavia/common/jinja/lvs/templates/base.j2 +++ b/octavia/common/jinja/lvs/templates/base.j2 @@ -14,7 +14,11 @@ # #} # Configuration for Loadbalancer {{ loadbalancer.id }} +{% if loadbalancer.listener.enabled %} # Configuration for Listener {{ udp_listener_id }} +{% else %} +# Listener {{ udp_listener_id }} is disabled +{% endif %} {% block global_definitions %}{% endblock global_definitions %} 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 54a060ce0a..f033a61041 100644 --- a/octavia/tests/unit/amphorae/backends/utils/test_keepalivedlvs_query.py +++ b/octavia/tests/unit/amphorae/backends/utils/test_keepalivedlvs_query.py @@ -126,6 +126,11 @@ CFG_FILE_TEMPLATE_v6 = ( " # Member %(member_id4)s is disabled\n\n" "}") +CFG_FILE_TEMPLATE_DISABLED_LISTENER = ( + "# Listener %(listener_id)s is disabled \n\n" + "net_namespace %(ns_name)s\n\n" +) + IPVSADM_OUTPUT_TEMPLATE = ( "IP Virtual Server version 1.2.1 (size=4096)\n" "Prot LocalAddress:Port Scheduler Flags\n" @@ -162,6 +167,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.disabled_listener_id = uuidutils.generate_uuid() cfg_content_v4 = CFG_FILE_TEMPLATE_v4 % { 'listener_id': self.listener_id_v4, 'ns_name': constants.AMPHORA_NAMESPACE, @@ -180,10 +186,19 @@ class LvsQueryTestCase(base.TestCase): 'member_id3': self.member_id3_v6, 'member_id4': self.member_id4_v6 } + cfg_content_disabled_listener = ( + CFG_FILE_TEMPLATE_DISABLED_LISTENER % { + 'listener_id': self.listener_id_v6, + 'ns_name': constants.AMPHORA_NAMESPACE, + } + ) self.useFixture(test_utils.OpenFixture( util.keepalived_lvs_cfg_path(self.listener_id_v4), cfg_content_v4)) self.useFixture(test_utils.OpenFixture( util.keepalived_lvs_cfg_path(self.listener_id_v6), cfg_content_v6)) + self.useFixture(test_utils.OpenFixture( + util.keepalived_lvs_cfg_path(self.disabled_listener_id), + cfg_content_disabled_listener)) @mock.patch('subprocess.check_output') def test_get_listener_realserver_mapping(self, mock_check_output): @@ -278,6 +293,11 @@ class LvsQueryTestCase(base.TestCase): 'ipport': None}]} self.assertEqual((expected, constants.AMPHORA_NAMESPACE), res) + # disabled + res = lvs_query.get_udp_listener_resource_ipports_nsname( + self.disabled_listener_id) + self.assertEqual((None, constants.AMPHORA_NAMESPACE), res) + @mock.patch('subprocess.check_output') def test_get_udp_listener_pool_status(self, mock_check_output): # test with ipv4 and ipv6 @@ -456,3 +476,14 @@ class LvsQueryTestCase(base.TestCase): mock_is_running.return_value = False res = lvs_query.get_udp_listeners_stats() self.assertEqual({}, res) + + @mock.patch('subprocess.check_output') + @mock.patch("octavia.amphorae.backends.agent.api_server.util." + "is_udp_listener_running", return_value=True) + @mock.patch("octavia.amphorae.backends.agent.api_server.util." + "get_udp_listeners") + def test_get_udp_listeners_stats_disabled_listener( + self, mock_get_listener, mock_is_running, mock_check_output): + mock_get_listener.return_value = [self.disabled_listener_id] + res = lvs_query.get_udp_listeners_stats() + self.assertEqual({}, res) diff --git a/octavia/tests/unit/common/jinja/lvs/test_lvs_jinja_cfg.py b/octavia/tests/unit/common/jinja/lvs/test_lvs_jinja_cfg.py index 2a9985e879..21376e28b0 100644 --- a/octavia/tests/unit/common/jinja/lvs/test_lvs_jinja_cfg.py +++ b/octavia/tests/unit/common/jinja/lvs/test_lvs_jinja_cfg.py @@ -410,3 +410,18 @@ class TestLvsCfg(base.TestCase): rendered_obj = self.udp_jinja_cfg.render_loadbalancer_obj(listener) self.assertEqual(exp, rendered_obj) + + def test_render_template_disabled_udp_listener(self): + exp = ("# Configuration for Loadbalancer sample_loadbalancer_id_1\n" + "# Listener sample_listener_id_1 is disabled\n\n" + "net_namespace amphora-haproxy\n\n") + rendered_obj = self.udp_jinja_cfg.render_loadbalancer_obj( + sample_configs_combined.sample_listener_tuple( + enabled=False, + proto=constants.PROTOCOL_UDP, + persistence_type=constants.SESSION_PERSISTENCE_SOURCE_IP, + persistence_timeout=33, + persistence_granularity='255.255.0.0', + monitor_proto=constants.HEALTH_MONITOR_UDP_CONNECT, + connection_limit=98)) + self.assertEqual(exp, rendered_obj) diff --git a/releasenotes/notes/fix-disable-udp-listener-status-3d34a5596e62da1c.yaml b/releasenotes/notes/fix-disable-udp-listener-status-3d34a5596e62da1c.yaml new file mode 100644 index 0000000000..f2cb52425c --- /dev/null +++ b/releasenotes/notes/fix-disable-udp-listener-status-3d34a5596e62da1c.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fix operational status for disabled UDP listeners. The operating status of + disabled UDP listeners is now OFFLINE instead of ONLINE, the behavior is now + similary to the behavior of HTTP/HTTPS/TCP/... listeners.