Handle feature compatibility of HAProxy server-state-file option
https://review.opendev.org/c/openstack/octavia/+/805955 introduced a new feature that requires HAProxy 1.6 or higher to work. This change ensures that with older HAProxy version this feature does not get enabled to avoid errors. Conflicts: octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py Story: 2010254 Task: 46145 Change-Id: Icc7dc9bb22187f908852c20415227574ded347aa (cherry picked from commit69ecdb1908
) (cherry picked from commit7f220d41ad
) (cherry picked from commit6346341b8e
)
This commit is contained in:
parent
28a6f28702
commit
bc2bded8c2
@ -792,6 +792,7 @@ AMP_NETNS_SVC_PREFIX = 'amphora-netns'
|
||||
|
||||
# Amphora Feature Compatibility
|
||||
HTTP_REUSE = 'has_http_reuse'
|
||||
SERVER_STATE_FILE = 'has_server_state_file'
|
||||
POOL_ALPN = 'has_pool_alpn'
|
||||
|
||||
# TODO(johnsom) convert these to octavia_lib constants
|
||||
|
@ -100,6 +100,7 @@ class JinjaTemplater(object):
|
||||
# Is it newer than haproxy 1.5?
|
||||
if not (int(haproxy_versions[0]) < 2 and int(haproxy_versions[1]) < 6):
|
||||
feature_compatibility[constants.HTTP_REUSE] = True
|
||||
feature_compatibility[constants.SERVER_STATE_FILE] = True
|
||||
if not (int(haproxy_versions[0]) < 2 and int(haproxy_versions[1]) < 9):
|
||||
feature_compatibility[constants.POOL_ALPN] = True
|
||||
|
||||
@ -164,7 +165,8 @@ class JinjaTemplater(object):
|
||||
listeners[0].load_balancer.id)
|
||||
state_file_path = '%s/%s/servers-state' % (
|
||||
self.base_amp_path,
|
||||
listeners[0].load_balancer.id)
|
||||
listeners[0].load_balancer.id) if feature_compatibility.get(
|
||||
constants.SERVER_STATE_FILE) else ''
|
||||
return self._get_template().render(
|
||||
{'loadbalancer': loadbalancer,
|
||||
'stats_sock': socket_path,
|
||||
|
@ -20,7 +20,9 @@ global
|
||||
log {{ log_http | default('/run/rsyslog/octavia/log', true)}} local{{ user_log_facility }}
|
||||
log {{ log_server | default('/run/rsyslog/octavia/log', true)}} local{{ administrative_log_facility }} notice
|
||||
stats socket {{ sock_path }} mode 0666 level user
|
||||
{% if state_file %}
|
||||
server-state-file {{ state_file }}
|
||||
{% endif %}
|
||||
{% if loadbalancer.global_connection_limit is defined %}
|
||||
maxconn {{ loadbalancer.global_connection_limit }}
|
||||
{% endif %}
|
||||
|
@ -33,7 +33,7 @@
|
||||
{% for listener in loadbalancer.listeners if listener.enabled %}
|
||||
{{- frontend_macro(constants, lib_consts, listener, loadbalancer.vip_address) }}
|
||||
{% for pool in listener.pools if pool.enabled %}
|
||||
{{- backend_macro(constants, lib_consts, listener, pool, loadbalancer) }}
|
||||
{{- backend_macro(constants, lib_consts, listener, pool, loadbalancer, state_file) }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
@ -298,7 +298,7 @@ frontend {{ listener.id }}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro backend_macro(constants, lib_consts, listener, pool, loadbalancer) %}
|
||||
{% macro backend_macro(constants, lib_consts, listener, pool, loadbalancer, state_file) %}
|
||||
backend {{ pool.id }}:{{ listener.id }}
|
||||
{% if pool.proxy_protocol is not none %}
|
||||
mode {{ listener.protocol_mode }}
|
||||
@ -340,7 +340,9 @@ backend {{ pool.id }}:{{ listener.id }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if pool.health_monitor and pool.health_monitor.enabled %}
|
||||
{% if state_file %}
|
||||
load-server-state-from-file global
|
||||
{% endif %}
|
||||
timeout check {{ pool.health_monitor.timeout }}s
|
||||
{% if (pool.health_monitor.type ==
|
||||
constants.HEALTH_MONITOR_HTTP or pool.health_monitor.type ==
|
||||
|
@ -31,8 +31,6 @@ class HAProxyCompatTestCase(base.TestCase):
|
||||
" log /run/rsyslog/octavia/log local1 notice\n"
|
||||
" stats socket /var/lib/octavia/sample_loadbalancer_id_1.sock"
|
||||
" mode 0666 level user\n"
|
||||
" server-state-file /var/lib/octavia/sample_loadbalancer_id_1"
|
||||
"/servers-state\n"
|
||||
" maxconn {maxconn}\n\n"
|
||||
"defaults\n"
|
||||
" log global\n"
|
||||
|
@ -64,7 +64,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -119,7 +118,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -170,7 +168,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -226,7 +223,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -280,7 +276,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -334,7 +329,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -386,7 +380,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -422,7 +415,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -449,7 +441,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -486,7 +477,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -522,7 +512,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -551,7 +540,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -592,7 +580,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode tcp\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -629,7 +616,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode tcp\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option ssl-hello-chk\n"
|
||||
" fullconn {maxconn}\n"
|
||||
@ -697,7 +683,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option external-check\n"
|
||||
" external-check command /var/lib/octavia/ping-wrapper.sh\n"
|
||||
@ -758,7 +743,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.1\\r\\nHost:\\ "
|
||||
"testlab.com\n"
|
||||
@ -836,7 +820,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" balance roundrobin\n"
|
||||
" stick-table type ip size 10k\n"
|
||||
" stick on src\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -864,7 +847,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" stick-table type string len 64 size 10k\n"
|
||||
" stick store-response res.cook(JSESSIONID)\n"
|
||||
" stick match req.cook(JSESSIONID)\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -988,7 +970,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1005,7 +986,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /healthmon.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1027,7 +1007,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1056,7 +1035,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1087,7 +1065,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" fullconn {maxconn}\n"
|
||||
" option allbackups\n"
|
||||
@ -1115,7 +1092,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1156,7 +1132,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1196,7 +1171,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1237,7 +1211,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1275,7 +1248,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1309,7 +1281,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1340,7 +1311,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1543,7 +1513,7 @@ class TestHaproxyCfg(base.TestCase):
|
||||
defaults=defaults, logging="\n"),
|
||||
rendered_obj)
|
||||
|
||||
def test_http_reuse(self):
|
||||
def test_haproxy_cfg_1_8_vs_1_5(self):
|
||||
j_cfg = jinja_cfg.JinjaTemplater(
|
||||
base_amp_path='/var/lib/octavia',
|
||||
base_crt_dir='/var/lib/octavia/certs')
|
||||
@ -1551,7 +1521,12 @@ class TestHaproxyCfg(base.TestCase):
|
||||
sample_amphora = sample_configs_combined.sample_amphora_tuple()
|
||||
sample_proxy_listener = sample_configs_combined.sample_listener_tuple(
|
||||
be_proto='PROXY')
|
||||
# With http-reuse
|
||||
# With http-reuse and server-state-file
|
||||
go = (
|
||||
" server-state-file /var/lib/octavia/sample_loadbalancer_id_1/"
|
||||
"servers-state\n"
|
||||
" maxconn {maxconn}\n\n").format(
|
||||
maxconn=constants.HAPROXY_DEFAULT_MAXCONN)
|
||||
be = ("backend {pool_id}:{listener_id}\n"
|
||||
" mode http\n"
|
||||
" http-reuse safe\n"
|
||||
@ -1578,15 +1553,15 @@ class TestHaproxyCfg(base.TestCase):
|
||||
tls_certs=None,
|
||||
haproxy_versions=("1", "8", "1"))
|
||||
self.assertEqual(
|
||||
sample_configs_combined.sample_base_expected_config(backend=be),
|
||||
sample_configs_combined.sample_base_expected_config(
|
||||
global_opts=go, backend=be),
|
||||
rendered_obj)
|
||||
|
||||
# Without http-reuse
|
||||
# Without http-reuse and server-state-file
|
||||
be = ("backend {pool_id}:{listener_id}\n"
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" fullconn {maxconn}\n"
|
||||
" option allbackups\n"
|
||||
@ -1660,7 +1635,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1676,7 +1650,6 @@ class TestHaproxyCfg(base.TestCase):
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /healthmon.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
|
@ -1213,7 +1213,6 @@ def sample_base_expected_config(frontend=None, logging=None, backend=None,
|
||||
" mode http\n"
|
||||
" balance roundrobin\n"
|
||||
" cookie SRV insert indirect nocache\n"
|
||||
" load-server-state-from-file global\n"
|
||||
" timeout check 31s\n"
|
||||
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
|
||||
" http-check expect rstatus 418\n"
|
||||
@ -1247,7 +1246,5 @@ def sample_base_expected_config(frontend=None, logging=None, backend=None,
|
||||
" log /run/rsyslog/octavia/log local0\n"
|
||||
" log /run/rsyslog/octavia/log local1 notice\n"
|
||||
" stats socket /var/lib/octavia/sample_loadbalancer_id_1.sock"
|
||||
" mode 0666 level user\n"
|
||||
" server-state-file /var/lib/octavia/sample_loadbalancer_id_1"
|
||||
"/servers-state\n" +
|
||||
" mode 0666 level user\n" +
|
||||
global_opts + defaults + peers + frontend + logging + backend)
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixed backwards compatibility issue with the feature that preserves HAProxy
|
||||
server states between reloads.
|
||||
HAProxy version 1.5 or below do not support this feature, so Octavia
|
||||
will not to activate it on amphorae with those versions.
|
Loading…
Reference in New Issue
Block a user