diff options
-rw-r--r-- | data/templates/load-balancing/haproxy.cfg.j2 | 17 | ||||
-rw-r--r-- | interface-definitions/load-balancing_reverse-proxy.xml.in | 42 | ||||
-rw-r--r-- | smoketest/scripts/cli/base_vyostest_shim.py | 4 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_load-balancing_reverse-proxy.py | 23 | ||||
-rwxr-xr-x | src/conf_mode/load-balancing_reverse-proxy.py | 4 | ||||
-rwxr-xr-x | src/init/vyos-router | 1 |
6 files changed, 77 insertions, 14 deletions
diff --git a/data/templates/load-balancing/haproxy.cfg.j2 b/data/templates/load-balancing/haproxy.cfg.j2 index 83008e50a..dd93afba5 100644 --- a/data/templates/load-balancing/haproxy.cfg.j2 +++ b/data/templates/load-balancing/haproxy.cfg.j2 @@ -113,11 +113,22 @@ backend {{ back }} {% if back_config.http_check is vyos_defined %} option httpchk {% endif %} -{% if back_config.http_check.uri is vyos_defined and back_config.http_check.method is vyos_defined %} - http-check send meth {{ back_config.http_check.method | upper }} uri {{ back_config.http_check.uri }} +{% set send = '' %} +{% if back_config.http_check.method is vyos_defined %} +{% set send = send + ' meth ' + back_config.http_check.method | upper %} +{% endif %} +{% if back_config.http_check.uri is vyos_defined %} +{% set send = send + ' uri ' + back_config.http_check.uri %} +{% endif %} +{% if send != '' %} + http-check send{{ send }} {% endif %} {% if back_config.http_check.expect is vyos_defined %} - http-check expect {{ back_config.http_check.expect }} +{% if back_config.http_check.expect.status is vyos_defined %} + http-check expect status {{ back_config.http_check.expect.status }} +{% elif back_config.http_check.expect.string is vyos_defined %} + http-check expect string {{ back_config.http_check.expect.string }} +{% endif %} {% endif %} {% if back_config.balance is vyos_defined %} {% set balance_translate = {'least-connection': 'leastconn', 'round-robin': 'roundrobin', 'source-address': 'source'} %} diff --git a/interface-definitions/load-balancing_reverse-proxy.xml.in b/interface-definitions/load-balancing_reverse-proxy.xml.in index 645fe30c7..eb01580da 100644 --- a/interface-definitions/load-balancing_reverse-proxy.xml.in +++ b/interface-definitions/load-balancing_reverse-proxy.xml.in @@ -110,29 +110,55 @@ <leafNode name="method"> <properties> <help>HTTP method used for health check</help> + <completionHelp> + <list>options head get post put</list> + </completionHelp> <valueHelp> - <format>options|get|post|put</format> + <format>options|head|get|post|put</format> <description>HTTP method used for health checking</description> </valueHelp> <constraint> - <regex>options|get|post|put</regex> + <regex>(options|head|get|post|put)</regex> </constraint> </properties> </leafNode> <leafNode name="uri"> <properties> <help>URI used for HTTP health check (Example: '/' or '/health')</help> + <constraint> + <regex>^\/([^?#\s]*)(\?[^#\s]*)?$</regex> + </constraint> </properties> </leafNode> - <leafNode name="expect"> + <node name="expect"> <properties> <help>Expected response for the health check to pass</help> - <valueHelp> - <format>txt</format> - <description>expected response (Example: 'status 200-299' or 'string success')</description> - </valueHelp> </properties> - </leafNode> + <children> + <leafNode name="status"> + <properties> + <help>Expected response status code for the health check to pass</help> + <valueHelp> + <format>u32:200-399</format> + <description>Expected response code</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 200-399"/> + </constraint> + <constraintErrorMessage>Status code must be in range 200-399</constraintErrorMessage> + </properties> + </leafNode> + <leafNode name="string"> + <properties> + <help>Expected to be in response body for the health check to pass</help> + <valueHelp> + <format>txt</format> + <description>A string expected to be in the response</description> + </valueHelp> + </properties> + </leafNode> + </children> + </node> </children> </node> #include <include/haproxy/rule-backend.xml.i> diff --git a/smoketest/scripts/cli/base_vyostest_shim.py b/smoketest/scripts/cli/base_vyostest_shim.py index c49d3e76c..efaa74fe0 100644 --- a/smoketest/scripts/cli/base_vyostest_shim.py +++ b/smoketest/scripts/cli/base_vyostest_shim.py @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2023 VyOS maintainers and contributors +# Copyright (C) 2021-2024 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -47,6 +47,8 @@ class VyOSUnitTestSHIM: def setUpClass(cls): cls._session = ConfigSession(os.getpid()) cls._session.save_config(save_config) + if os.path.exists('/tmp/vyos.smoketest.debug'): + cls.debug = True pass @classmethod diff --git a/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py b/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py index 8ccf2cf97..737c07401 100755 --- a/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py +++ b/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py @@ -304,15 +304,34 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase): # Set http-check self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'method', 'get']) - self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'uri', '/health']) - self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'status 200']) self.cli_commit() # Test http-check config = read_file(HAPROXY_CONF) self.assertIn('option httpchk', config) + self.assertIn('http-check send meth GET', config) + + # Set http-check with uri and status + self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'uri', '/health']) + self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'status', '200']) + self.cli_commit() + + # Test http-check with uri and status + config = read_file(HAPROXY_CONF) + self.assertIn('option httpchk', config) self.assertIn('http-check send meth GET uri /health', config) self.assertIn('http-check expect status 200', config) + # Set http-check with string + self.cli_delete(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'status', '200']) + self.cli_set(base_path + ['backend', 'bk-01', 'http-check', 'expect', 'string', 'success']) + self.cli_commit() + + # Test http-check with string + config = read_file(HAPROXY_CONF) + self.assertIn('option httpchk', config) + self.assertIn('http-check send meth GET uri /health', config) + self.assertIn('http-check expect string success', config) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/load-balancing_reverse-proxy.py b/src/conf_mode/load-balancing_reverse-proxy.py index 9f895c4e2..1569d8d71 100755 --- a/src/conf_mode/load-balancing_reverse-proxy.py +++ b/src/conf_mode/load-balancing_reverse-proxy.py @@ -75,6 +75,10 @@ def verify(lb): raise ConfigError(f'"TCP" port "{tmp_port}" is used by another service') for back, back_config in lb['backend'].items(): + if 'http-check' in back_config: + http_check = back_config['http-check'] + if 'expect' in http_check and 'status' in http_check['expect'] and 'string' in http_check['expect']: + raise ConfigError(f'"expect status" and "expect string" can not be configured together!') if 'server' not in back_config: raise ConfigError(f'"{back} server" must be configured!') for bk_server, bk_server_conf in back_config['server'].items(): diff --git a/src/init/vyos-router b/src/init/vyos-router index 06fea140d..15e37df07 100755 --- a/src/init/vyos-router +++ b/src/init/vyos-router @@ -451,6 +451,7 @@ start () touch /tmp/vyos.ifconfig.debug touch /tmp/vyos.frr.debug touch /tmp/vyos.container.debug + touch /tmp/vyos.smoketest.debug fi log_action_begin_msg "Mounting VyOS Config" |