Browse Source

Fix pool ALPN compatibility with older amphora

The ALPN for pools patch introduced a bug that causes amphora to
fail if the HAProxy version running inside the amphroa does not
support ALPN on backend members (bionic images for example).
This patch adds compatibility support for those older HAProxy versions
by removing the ALPN configuration settings if the HAProxy version
is too old to support the functionality.

Story: 2008780
Task: 42171
Change-Id: Iac949431f0901aaa0a60e5c39c2aab44cb9c1970
changes/16/783916/1 8.0.0
Michael Johnson 3 weeks ago
parent
commit
d463897551
4 changed files with 64 additions and 5 deletions
  1. +1
    -0
      octavia/common/constants.py
  2. +4
    -1
      octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py
  3. +51
    -4
      octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py
  4. +8
    -0
      releasenotes/notes/Fix-pool-alpn-older-haproxy-50514c1df4f77bcd.yaml

+ 1
- 0
octavia/common/constants.py View File

@ -794,6 +794,7 @@ AMP_NETNS_SVC_PREFIX = 'amphora-netns'
# Amphora Feature Compatibility
HTTP_REUSE = 'has_http_reuse'
POOL_ALPN = 'has_pool_alpn'
# TODO(johnsom) convert these to octavia_lib constants
# once octavia is transitioned to use octavia_lib


+ 4
- 1
octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py View File

@ -100,6 +100,8 @@ 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
if not (int(haproxy_versions[0]) < 2 and int(haproxy_versions[1]) < 9):
feature_compatibility[constants.POOL_ALPN] = True
return self.render_loadbalancer_obj(
host_amphora, listeners, tls_certs=tls_certs,
@ -370,7 +372,8 @@ class JinjaTemplater(object):
ret_value['tls_ciphers'] = pool.tls_ciphers
if pool.tls_versions is not None:
ret_value['tls_versions'] = pool.tls_versions
if pool.alpn_protocols is not None:
if (pool.alpn_protocols is not None and
feature_compatibility.get(constants.POOL_ALPN, False)):
ret_value['alpn_protocols'] = ",".join(pool.alpn_protocols)
if (pool.ca_tls_certificate_id and pool_tls_certs and
pool_tls_certs.get('ca_cert')):


+ 51
- 4
octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py View File

@ -1085,6 +1085,7 @@ class TestHaproxyCfg(base.TestCase):
rendered_obj)
def test_render_template_pool_cert(self):
feature_compatibility = {constants.POOL_ALPN: True}
cert_file_path = os.path.join(self.jinja_cfg.base_crt_dir,
'sample_listener_id_1', 'fake path')
be = ("backend sample_pool_id_1:sample_listener_id_1\n"
@ -1117,12 +1118,53 @@ class TestHaproxyCfg(base.TestCase):
tls_certs={
'sample_pool_id_1':
{'client_cert': cert_file_path,
'ca_cert': None, 'crl': None}})
'ca_cert': None, 'crl': None}},
feature_compatibility=feature_compatibility)
self.assertEqual(
sample_configs_combined.sample_base_expected_config(backend=be),
rendered_obj)
def test_render_template_pool_cert_no_alpn(self):
feature_compatibility = {constants.POOL_ALPN: False}
cert_file_path = os.path.join(self.jinja_cfg.base_crt_dir,
'sample_listener_id_1', 'fake path')
be = ("backend sample_pool_id_1:sample_listener_id_1\n"
" mode http\n"
" balance roundrobin\n"
" cookie SRV insert indirect nocache\n"
" timeout check 31s\n"
" option httpchk GET /index.html HTTP/1.0\\r\\n\n"
" http-check expect rstatus 418\n"
" fullconn {maxconn}\n"
" option allbackups\n"
" timeout connect 5000\n"
" timeout server 50000\n"
" server sample_member_id_1 10.0.0.99:82 weight 13 "
"check inter 30s fall 3 rise 2 cookie sample_member_id_1 "
"{opts}\n"
" server sample_member_id_2 10.0.0.98:82 weight 13 "
"check inter 30s fall 3 rise 2 cookie sample_member_id_2 "
"{opts}\n\n").format(
maxconn=constants.HAPROXY_DEFAULT_MAXCONN,
opts="ssl crt %s verify none sni ssl_fc_sni" % cert_file_path +
" ciphers " + constants.CIPHERS_OWASP_SUITE_B +
" no-sslv3 no-tlsv10 no-tlsv11")
rendered_obj = self.jinja_cfg.render_loadbalancer_obj(
sample_configs_combined.sample_amphora_tuple(),
[sample_configs_combined.sample_listener_tuple(
pool_cert=True, tls_enabled=True,
backend_tls_ciphers=constants.CIPHERS_OWASP_SUITE_B)],
tls_certs={
'sample_pool_id_1':
{'client_cert': cert_file_path,
'ca_cert': None, 'crl': None}},
feature_compatibility=feature_compatibility)
self.assertEqual(
sample_configs_combined.sample_base_expected_config(backend=be),
rendered_obj)
def test_render_template_pool_cert_no_versions(self):
feature_compatibility = {constants.POOL_ALPN: True}
cert_file_path = os.path.join(self.jinja_cfg.base_crt_dir,
'sample_listener_id_1', 'fake path')
be = ("backend sample_pool_id_1:sample_listener_id_1\n"
@ -1155,12 +1197,14 @@ class TestHaproxyCfg(base.TestCase):
tls_certs={
'sample_pool_id_1':
{'client_cert': cert_file_path,
'ca_cert': None, 'crl': None}})
'ca_cert': None, 'crl': None}},
feature_compatibility=feature_compatibility)
self.assertEqual(
sample_configs_combined.sample_base_expected_config(backend=be),
rendered_obj)
def test_render_template_pool_cert_no_ciphers(self):
feature_compatibility = {constants.POOL_ALPN: True}
cert_file_path = os.path.join(self.jinja_cfg.base_crt_dir,
'sample_listener_id_1', 'fake path')
be = ("backend sample_pool_id_1:sample_listener_id_1\n"
@ -1191,7 +1235,8 @@ class TestHaproxyCfg(base.TestCase):
tls_certs={
'sample_pool_id_1':
{'client_cert': cert_file_path,
'ca_cert': None, 'crl': None}})
'ca_cert': None, 'crl': None}},
feature_compatibility=feature_compatibility)
self.assertEqual(
sample_configs_combined.sample_base_expected_config(backend=be),
rendered_obj)
@ -1258,6 +1303,7 @@ class TestHaproxyCfg(base.TestCase):
rendered_obj)
def test_render_template_with_full_pool_cert(self):
feature_compatibility = {constants.POOL_ALPN: True}
pool_client_cert = '/foo/cert.pem'
pool_ca_cert = '/foo/ca.pem'
pool_crl = '/foo/crl.pem'
@ -1294,7 +1340,8 @@ class TestHaproxyCfg(base.TestCase):
'sample_pool_id_1':
{'client_cert': pool_client_cert,
'ca_cert': pool_ca_cert,
'crl': pool_crl}})
'crl': pool_crl}},
feature_compatibility=feature_compatibility)
self.assertEqual(
sample_configs_combined.sample_base_expected_config(backend=be),
rendered_obj)


+ 8
- 0
releasenotes/notes/Fix-pool-alpn-older-haproxy-50514c1df4f77bcd.yaml View File

@ -0,0 +1,8 @@
---
fixes:
- |
Fixed amphora driver pool ALPN compatibity with older amphora images.
upgrade:
- |
Support for new features, such as ALPN on pools, HTTP/2 on pools,
gRPC, and SCTP require an updated amphora image.

Loading…
Cancel
Save