Fix listeners with SNI certificates

The single process patch changed the way listeners and load balancers
are deployed inside the amphora. This caused listeners with SNI
enabled to load all of the certificates for all of the TLS enabled
listeners on a load balancer.
This patch corrects that by configuring each listener with a
specific list of certificates.

Change-Id: I2f3c7ab4137dbd84d77a6a6b675975af406249d0
Story: 2006758
Task: 37252
This commit is contained in:
Michael Johnson 2019-10-22 16:15:45 -07:00
parent 6a15e14d25
commit 3c05ce1297
12 changed files with 130 additions and 160 deletions

View File

@ -30,7 +30,7 @@ LOG = logging.getLogger(__name__)
FRONTEND_BACKEND_PATTERN = re.compile(r'\n(frontend|backend)\s+(\S+)\n') FRONTEND_BACKEND_PATTERN = re.compile(r'\n(frontend|backend)\s+(\S+)\n')
LISTENER_MODE_PATTERN = re.compile(r'^\s+mode\s+(.*)$', re.MULTILINE) LISTENER_MODE_PATTERN = re.compile(r'^\s+mode\s+(.*)$', re.MULTILINE)
TLS_CERT_PATTERN = re.compile(r'^\s+bind\s+\S+\s+ssl crt\s+(.*)$', TLS_CERT_PATTERN = re.compile(r'^\s+bind\s+\S+\s+ssl crt-list\s+(.*)$',
re.MULTILINE) re.MULTILINE)
STATS_SOCKET_PATTERN = re.compile(r'stats socket\s+(\S+)') STATS_SOCKET_PATTERN = re.compile(r'stats socket\s+(\S+)')

View File

@ -145,7 +145,6 @@ class HaproxyAmphoraLoadBalancerDriver(
'process mode.', amphora.id, loadbalancer.id) 'process mode.', amphora.id, loadbalancer.id)
has_tcp = False has_tcp = False
certs = {}
for listener in loadbalancer.listeners: for listener in loadbalancer.listeners:
LOG.debug("%s updating listener %s on amphora %s", LOG.debug("%s updating listener %s on amphora %s",
self.__class__.__name__, listener.id, amphora.id) self.__class__.__name__, listener.id, amphora.id)
@ -163,10 +162,8 @@ class HaproxyAmphoraLoadBalancerDriver(
else: else:
obj_id = loadbalancer.id obj_id = loadbalancer.id
certs.update({ self._process_tls_certificates(listener, amphora, obj_id)
listener.tls_certificate_id:
self._process_tls_certificates(
listener, amphora, obj_id)['tls_cert']})
client_ca_filename = self._process_secret( client_ca_filename = self._process_secret(
listener, listener.client_ca_tls_certificate_id, listener, listener.client_ca_tls_certificate_id,
amphora, obj_id) amphora, obj_id)
@ -179,7 +176,6 @@ class HaproxyAmphoraLoadBalancerDriver(
if split_config: if split_config:
config = self.jinja_split.build_config( config = self.jinja_split.build_config(
host_amphora=amphora, listener=listener, host_amphora=amphora, listener=listener,
tls_cert=certs[listener.tls_certificate_id],
haproxy_versions=haproxy_versions, haproxy_versions=haproxy_versions,
client_ca_filename=client_ca_filename, client_ca_filename=client_ca_filename,
client_crl=crl_filename, client_crl=crl_filename,
@ -194,7 +190,6 @@ class HaproxyAmphoraLoadBalancerDriver(
# Generate HaProxy configuration from listener object # Generate HaProxy configuration from listener object
config = self.jinja_combo.build_config( config = self.jinja_combo.build_config(
host_amphora=amphora, listeners=loadbalancer.listeners, host_amphora=amphora, listeners=loadbalancer.listeners,
tls_certs=certs,
haproxy_versions=haproxy_versions, haproxy_versions=haproxy_versions,
client_ca_filename=client_ca_filename, client_ca_filename=client_ca_filename,
client_crl=crl_filename, client_crl=crl_filename,
@ -414,11 +409,13 @@ class HaproxyAmphoraLoadBalancerDriver(
tls_cert = None tls_cert = None
sni_certs = [] sni_certs = []
certs = [] certs = []
cert_filename_list = []
data = cert_parser.load_certificates_data( data = cert_parser.load_certificates_data(
self.cert_manager, listener) self.cert_manager, listener)
if data['tls_cert'] is not None: if data['tls_cert'] is not None:
tls_cert = data['tls_cert'] tls_cert = data['tls_cert']
# Note, the first cert is the TLS default cert
certs.append(tls_cert) certs.append(tls_cert)
if data['sni_certs']: if data['sni_certs']:
sni_certs = data['sni_certs'] sni_certs = data['sni_certs']
@ -429,7 +426,17 @@ class HaproxyAmphoraLoadBalancerDriver(
pem = cert_parser.build_pem(cert) pem = cert_parser.build_pem(cert)
md5 = hashlib.md5(pem).hexdigest() # nosec md5 = hashlib.md5(pem).hexdigest() # nosec
name = '{id}.pem'.format(id=cert.id) name = '{id}.pem'.format(id=cert.id)
cert_filename_list.append(
os.path.join(
CONF.haproxy_amphora.base_cert_dir, obj_id, name))
self._upload_cert(amphora, obj_id, pem, md5, name) self._upload_cert(amphora, obj_id, pem, md5, name)
if certs:
# Build and upload the crt-list file for haproxy
crt_list = "\n".join(cert_filename_list).encode('utf-8')
md5 = hashlib.md5(crt_list).hexdigest() # nosec
name = '{id}.pem'.format(id=listener.id)
self._upload_cert(amphora, obj_id, crt_list, md5, name)
return {'tls_cert': tls_cert, 'sni_certs': sni_certs} return {'tls_cert': tls_cert, 'sni_certs': sni_certs}
def _process_secret(self, listener, secret_ref, amphora=None, obj_id=None): def _process_secret(self, listener, secret_ref, amphora=None, obj_id=None):

View File

@ -81,15 +81,13 @@ class JinjaTemplater(object):
self.log_server = log_server self.log_server = log_server
self.connection_logging = connection_logging self.connection_logging = connection_logging
def build_config(self, host_amphora, listeners, tls_certs, def build_config(self, host_amphora, listeners, haproxy_versions,
haproxy_versions, socket_path=None, socket_path=None, client_ca_filename=None,
client_ca_filename=None, client_crl=None, client_crl=None, pool_tls_certs=None):
pool_tls_certs=None):
"""Convert a logical configuration to the HAProxy version """Convert a logical configuration to the HAProxy version
:param host_amphora: The Amphora this configuration is hosted on :param host_amphora: The Amphora this configuration is hosted on
:param listener: The listener configuration :param listener: The listener configuration
:param tls_certs: Dict of the TLS certificates for the listeners
:param socket_path: The socket path for Haproxy process :param socket_path: The socket path for Haproxy process
:return: Rendered configuration :return: Rendered configuration
""" """
@ -104,8 +102,7 @@ class JinjaTemplater(object):
feature_compatibility[constants.HTTP_REUSE] = True feature_compatibility[constants.HTTP_REUSE] = True
return self.render_loadbalancer_obj( return self.render_loadbalancer_obj(
host_amphora, listeners, tls_certs=tls_certs, host_amphora, listeners, socket_path=socket_path,
socket_path=socket_path,
feature_compatibility=feature_compatibility, feature_compatibility=feature_compatibility,
client_ca_filename=client_ca_filename, client_crl=client_crl, client_ca_filename=client_ca_filename, client_crl=client_crl,
pool_tls_certs=pool_tls_certs) pool_tls_certs=pool_tls_certs)
@ -144,15 +141,13 @@ class JinjaTemplater(object):
return log_format return log_format
def render_loadbalancer_obj(self, host_amphora, listeners, def render_loadbalancer_obj(self, host_amphora, listeners,
tls_certs=None, socket_path=None, socket_path=None, feature_compatibility=None,
feature_compatibility=None,
client_ca_filename=None, client_crl=None, client_ca_filename=None, client_crl=None,
pool_tls_certs=None): pool_tls_certs=None):
"""Renders a templated configuration from a load balancer object """Renders a templated configuration from a load balancer object
:param host_amphora: The Amphora this configuration is hosted on :param host_amphora: The Amphora this configuration is hosted on
:param listener: The listener configuration :param listener: The listener configuration
:param tls_certs: Dict of the TLS certificates for the listener
:param client_ca_filename: The CA certificate for client authorization :param client_ca_filename: The CA certificate for client authorization
:param socket_path: The socket path for Haproxy process :param socket_path: The socket path for Haproxy process
:return: Rendered configuration :return: Rendered configuration
@ -162,7 +157,6 @@ class JinjaTemplater(object):
host_amphora, host_amphora,
listeners[0].load_balancer, listeners[0].load_balancer,
listeners, listeners,
tls_certs,
feature_compatibility, feature_compatibility,
client_ca_filename=client_ca_filename, client_ca_filename=client_ca_filename,
client_crl=client_crl, client_crl=client_crl,
@ -182,9 +176,8 @@ class JinjaTemplater(object):
constants=constants) constants=constants)
def _transform_loadbalancer(self, host_amphora, loadbalancer, listeners, def _transform_loadbalancer(self, host_amphora, loadbalancer, listeners,
tls_certs, feature_compatibility, feature_compatibility, client_ca_filename=None,
client_ca_filename=None, client_crl=None, client_crl=None, pool_tls_certs=None):
pool_tls_certs=None):
"""Transforms a load balancer into an object that will """Transforms a load balancer into an object that will
be processed by the templating system be processed by the templating system
@ -194,7 +187,7 @@ class JinjaTemplater(object):
if listener.protocol == constants.PROTOCOL_UDP: if listener.protocol == constants.PROTOCOL_UDP:
continue continue
listener_transforms.append(self._transform_listener( listener_transforms.append(self._transform_listener(
listener, tls_certs, feature_compatibility, loadbalancer, listener, feature_compatibility, loadbalancer,
client_ca_filename=client_ca_filename, client_crl=client_crl, client_ca_filename=client_ca_filename, client_crl=client_crl,
pool_tls_certs=pool_tls_certs)) pool_tls_certs=pool_tls_certs))
@ -246,7 +239,7 @@ class JinjaTemplater(object):
'vrrp_priority': amphora.vrrp_priority 'vrrp_priority': amphora.vrrp_priority
} }
def _transform_listener(self, listener, tls_certs, feature_compatibility, def _transform_listener(self, listener, feature_compatibility,
loadbalancer, client_ca_filename=None, loadbalancer, client_ca_filename=None,
client_crl=None, pool_tls_certs=None): client_crl=None, pool_tls_certs=None):
"""Transforms a listener into an object that will """Transforms a listener into an object that will
@ -279,14 +272,12 @@ class JinjaTemplater(object):
ret_value['connection_limit'] = listener.connection_limit ret_value['connection_limit'] = listener.connection_limit
else: else:
ret_value['connection_limit'] = constants.HAPROXY_MAX_MAXCONN ret_value['connection_limit'] = constants.HAPROXY_MAX_MAXCONN
if listener.tls_certificate_id and tls_certs is not None:
ret_value['default_tls_path'] = '%s.pem' % ( if listener.tls_certificate_id:
os.path.join(self.base_crt_dir, ret_value['crt_list_filename'] = os.path.join(
loadbalancer.id, CONF.haproxy_amphora.base_cert_dir,
tls_certs[listener.tls_certificate_id].id)) loadbalancer.id, '{}.pem'.format(listener.id))
if listener.sni_containers:
ret_value['crt_dir'] = os.path.join(
self.base_crt_dir, loadbalancer.id)
if listener.client_ca_tls_certificate_id: if listener.client_ca_tls_certificate_id:
ret_value['client_ca_tls_path'] = '%s' % ( ret_value['client_ca_tls_path'] = '%s' % (
os.path.join(self.base_crt_dir, loadbalancer.id, os.path.join(self.base_crt_dir, loadbalancer.id,

View File

@ -27,17 +27,12 @@ peers {{ "%s_peers"|format(loadbalancer.id.replace("-", ""))|trim() }}
{% macro bind_macro(constants, listener, lb_vip_address) %} {% macro bind_macro(constants, listener, lb_vip_address) %}
{% if listener.default_tls_path %} {% if listener.crt_list_filename is defined %}
{% set def_crt_opt = ("ssl crt %s"|format( {% set def_crt_opt = ("ssl crt-list %s"|format(
listener.default_tls_path)|trim()) %} listener.crt_list_filename)|trim()) %}
{% else %} {% else %}
{% set def_crt_opt = "" %} {% set def_crt_opt = "" %}
{% endif %} {% endif %}
{% if listener.crt_dir %}
{% set crt_dir_opt = "crt %s"|format(listener.crt_dir)|trim() %}
{% else %}
{% set crt_dir_opt = "" %}
{% endif %}
{% if listener.client_ca_tls_path and listener.client_auth %} {% if listener.client_ca_tls_path and listener.client_auth %}
{% set client_ca_opt = "ca-file %s verify %s"|format(listener.client_ca_tls_path, listener.client_auth)|trim() %} {% set client_ca_opt = "ca-file %s verify %s"|format(listener.client_ca_tls_path, listener.client_auth)|trim() %}
{% else %} {% else %}
@ -49,7 +44,7 @@ peers {{ "%s_peers"|format(loadbalancer.id.replace("-", ""))|trim() }}
{% set ca_crl_opt = "" %} {% set ca_crl_opt = "" %}
{% endif %} {% endif %}
bind {{ lb_vip_address }}:{{ listener.protocol_port }} {{ bind {{ lb_vip_address }}:{{ listener.protocol_port }} {{
"%s %s %s %s"|format(def_crt_opt, crt_dir_opt, client_ca_opt, ca_crl_opt)|trim() }} "%s %s %s"|format(def_crt_opt, client_ca_opt, ca_crl_opt)|trim() }}
{% endmacro %} {% endmacro %}

View File

@ -81,15 +81,13 @@ class JinjaTemplater(object):
self.log_server = log_server self.log_server = log_server
self.connection_logging = connection_logging self.connection_logging = connection_logging
def build_config(self, host_amphora, listener, tls_cert, def build_config(self, host_amphora, listener, haproxy_versions,
haproxy_versions, socket_path=None, socket_path=None, client_ca_filename=None,
client_ca_filename=None, client_crl=None, client_crl=None, pool_tls_certs=None):
pool_tls_certs=None):
"""Convert a logical configuration to the HAProxy version """Convert a logical configuration to the HAProxy version
:param host_amphora: The Amphora this configuration is hosted on :param host_amphora: The Amphora this configuration is hosted on
:param listener: The listener configuration :param listener: The listener configuration
:param tls_cert: The TLS certificates for the listener
:param socket_path: The socket path for Haproxy process :param socket_path: The socket path for Haproxy process
:return: Rendered configuration :return: Rendered configuration
""" """
@ -104,7 +102,7 @@ class JinjaTemplater(object):
feature_compatibility[constants.HTTP_REUSE] = True feature_compatibility[constants.HTTP_REUSE] = True
return self.render_loadbalancer_obj( return self.render_loadbalancer_obj(
host_amphora, listener, tls_cert=tls_cert, socket_path=socket_path, host_amphora, listener, socket_path=socket_path,
feature_compatibility=feature_compatibility, feature_compatibility=feature_compatibility,
client_ca_filename=client_ca_filename, client_crl=client_crl, client_ca_filename=client_ca_filename, client_crl=client_crl,
pool_tls_certs=pool_tls_certs) pool_tls_certs=pool_tls_certs)
@ -142,8 +140,7 @@ class JinjaTemplater(object):
log_format = log_format.replace(' ', '\\ ') log_format = log_format.replace(' ', '\\ ')
return log_format return log_format
def render_loadbalancer_obj(self, host_amphora, listener, def render_loadbalancer_obj(self, host_amphora, listener, socket_path=None,
tls_cert=None, socket_path=None,
feature_compatibility=None, feature_compatibility=None,
client_ca_filename=None, client_crl=None, client_ca_filename=None, client_crl=None,
pool_tls_certs=None): pool_tls_certs=None):
@ -151,21 +148,15 @@ class JinjaTemplater(object):
:param host_amphora: The Amphora this configuration is hosted on :param host_amphora: The Amphora this configuration is hosted on
:param listener: The listener configuration :param listener: The listener configuration
:param tls_cert: The TLS certificates for the listener
:param client_ca_filename: The CA certificate for client authorization :param client_ca_filename: The CA certificate for client authorization
:param socket_path: The socket path for Haproxy process :param socket_path: The socket path for Haproxy process
:return: Rendered configuration :return: Rendered configuration
""" """
feature_compatibility = feature_compatibility or {} feature_compatibility = feature_compatibility or {}
loadbalancer = self._transform_loadbalancer( loadbalancer = self._transform_loadbalancer(
host_amphora, host_amphora, listener.load_balancer, listener,
listener.load_balancer, feature_compatibility, client_ca_filename=client_ca_filename,
listener, client_crl=client_crl, pool_tls_certs=pool_tls_certs)
tls_cert,
feature_compatibility,
client_ca_filename=client_ca_filename,
client_crl=client_crl,
pool_tls_certs=pool_tls_certs)
if not socket_path: if not socket_path:
socket_path = '%s/%s.sock' % (self.base_amp_path, listener.id) socket_path = '%s/%s.sock' % (self.base_amp_path, listener.id)
return self._get_template().render( return self._get_template().render(
@ -180,15 +171,14 @@ class JinjaTemplater(object):
constants=constants) constants=constants)
def _transform_loadbalancer(self, host_amphora, loadbalancer, listener, def _transform_loadbalancer(self, host_amphora, loadbalancer, listener,
tls_cert, feature_compatibility, feature_compatibility, client_ca_filename=None,
client_ca_filename=None, client_crl=None, client_crl=None, pool_tls_certs=None):
pool_tls_certs=None):
"""Transforms a load balancer into an object that will """Transforms a load balancer into an object that will
be processed by the templating system be processed by the templating system
""" """
t_listener = self._transform_listener( t_listener = self._transform_listener(
listener, tls_cert, feature_compatibility, loadbalancer, listener, feature_compatibility, loadbalancer,
client_ca_filename=client_ca_filename, client_crl=client_crl, client_ca_filename=client_ca_filename, client_crl=client_crl,
pool_tls_certs=pool_tls_certs) pool_tls_certs=pool_tls_certs)
ret_value = { ret_value = {
@ -229,7 +219,7 @@ class JinjaTemplater(object):
'vrrp_priority': amphora.vrrp_priority 'vrrp_priority': amphora.vrrp_priority
} }
def _transform_listener(self, listener, tls_cert, feature_compatibility, def _transform_listener(self, listener, feature_compatibility,
loadbalancer, client_ca_filename=None, loadbalancer, client_ca_filename=None,
client_crl=None, pool_tls_certs=None): client_crl=None, pool_tls_certs=None):
"""Transforms a listener into an object that will """Transforms a listener into an object that will
@ -265,13 +255,12 @@ class JinjaTemplater(object):
ret_value['connection_limit'] = listener.connection_limit ret_value['connection_limit'] = listener.connection_limit
else: else:
ret_value['connection_limit'] = constants.HAPROXY_MAX_MAXCONN ret_value['connection_limit'] = constants.HAPROXY_MAX_MAXCONN
if listener.tls_certificate_id: if listener.tls_certificate_id:
ret_value['default_tls_path'] = '%s.pem' % ( ret_value['crt_list_filename'] = os.path.join(
os.path.join(self.base_crt_dir, CONF.haproxy_amphora.base_cert_dir,
listener.id, listener.id, '{}.pem'.format(listener.id))
tls_cert.id))
if listener.sni_containers:
ret_value['crt_dir'] = os.path.join(self.base_crt_dir, listener.id)
if listener.client_ca_tls_certificate_id: if listener.client_ca_tls_certificate_id:
ret_value['client_ca_tls_path'] = '%s' % ( ret_value['client_ca_tls_path'] = '%s' % (
os.path.join(self.base_crt_dir, listener.id, os.path.join(self.base_crt_dir, listener.id,

View File

@ -27,17 +27,12 @@ peers {{ "%s_peers"|format(listener.id.replace("-", ""))|trim() }}
{% macro bind_macro(constants, listener, lb_vip_address) %} {% macro bind_macro(constants, listener, lb_vip_address) %}
{% if listener.default_tls_path %} {% if listener.crt_list_filename is defined %}
{% set def_crt_opt = ("ssl crt %s"|format( {% set def_crt_opt = ("ssl crt-list %s"|format(
listener.default_tls_path)|trim()) %} listener.crt_list_filename)|trim()) %}
{% else %} {% else %}
{% set def_crt_opt = "" %} {% set def_crt_opt = "" %}
{% endif %} {% endif %}
{% if listener.crt_dir %}
{% set crt_dir_opt = "crt %s"|format(listener.crt_dir)|trim() %}
{% else %}
{% set crt_dir_opt = "" %}
{% endif %}
{% if listener.client_ca_tls_path and listener.client_auth %} {% if listener.client_ca_tls_path and listener.client_auth %}
{% set client_ca_opt = "ca-file %s verify %s"|format(listener.client_ca_tls_path, listener.client_auth)|trim() %} {% set client_ca_opt = "ca-file %s verify %s"|format(listener.client_ca_tls_path, listener.client_auth)|trim() %}
{% else %} {% else %}
@ -49,7 +44,7 @@ peers {{ "%s_peers"|format(listener.id.replace("-", ""))|trim() }}
{% set ca_crl_opt = "" %} {% set ca_crl_opt = "" %}
{% endif %} {% endif %}
bind {{ lb_vip_address }}:{{ listener.protocol_port }} {{ bind {{ lb_vip_address }}:{{ listener.protocol_port }} {{
"%s %s %s %s"|format(def_crt_opt, crt_dir_opt, client_ca_opt, ca_crl_opt)|trim() }} "%s %s %s"|format(def_crt_opt, client_ca_opt, ca_crl_opt)|trim() }}
{% endmacro %} {% endmacro %}

View File

@ -203,44 +203,33 @@ class TestUtil(base.TestCase):
self.assertIsNone(result) self.assertIsNone(result)
def test_parse_haproxy_config(self): def test_parse_haproxy_config(self):
# template_tls self.CONF.config(group="haproxy_amphora",
tls_tupe = {'cont_id_1': base_cert_dir='/fake_cert_dir')
sample_configs_combined.sample_tls_container_tuple( FAKE_CRT_LIST_FILENAME = os.path.join(
id='tls_container_id', CONF.haproxy_amphora.base_cert_dir,
certificate='imaCert1', private_key='imaPrivateKey1', 'sample_loadbalancer_id_1/sample_listener_id_1.pem')
primary_cn='FakeCN')}
rendered_obj = self.jinja_cfg.render_loadbalancer_obj( rendered_obj = self.jinja_cfg.render_loadbalancer_obj(
sample_configs_combined.sample_amphora_tuple(), sample_configs_combined.sample_amphora_tuple(),
[sample_configs_combined.sample_listener_tuple( [sample_configs_combined.sample_listener_tuple(
proto='TERMINATED_HTTPS', tls=True, sni=True)], proto='TERMINATED_HTTPS', tls=True, sni=True)])
tls_tupe)
path = util.config_path(LISTENER_ID1) path = util.config_path(LISTENER_ID1)
self.useFixture(test_utils.OpenFixture(path, rendered_obj)) self.useFixture(test_utils.OpenFixture(path, rendered_obj))
res = util.parse_haproxy_file(LISTENER_ID1) res = util.parse_haproxy_file(LISTENER_ID1)
listener_dict = res[1]['sample_listener_id_1'] listener_dict = res[1]['sample_listener_id_1']
# NOTE: parse_haproxy_file makes mode TERMINATED_HTTPS even though
# the haproxy.cfg needs mode HTTP
self.assertEqual('TERMINATED_HTTPS', listener_dict['mode']) self.assertEqual('TERMINATED_HTTPS', listener_dict['mode'])
self.assertEqual('/var/lib/octavia/sample_loadbalancer_id_1.sock', self.assertEqual('/var/lib/octavia/sample_loadbalancer_id_1.sock',
res[0]) res[0])
self.assertEqual( self.assertEqual(FAKE_CRT_LIST_FILENAME, listener_dict['ssl_crt'])
'/var/lib/octavia/certs/sample_loadbalancer_id_1/'
'tls_container_id.pem crt /var/lib/octavia/certs/'
'sample_loadbalancer_id_1',
listener_dict['ssl_crt'])
# render_template_tls_no_sni # render_template_tls_no_sni
rendered_obj = self.jinja_cfg.render_loadbalancer_obj( rendered_obj = self.jinja_cfg.render_loadbalancer_obj(
sample_configs_combined.sample_amphora_tuple(), sample_configs_combined.sample_amphora_tuple(),
[sample_configs_combined.sample_listener_tuple( [sample_configs_combined.sample_listener_tuple(
proto='TERMINATED_HTTPS', tls=True)], proto='TERMINATED_HTTPS', tls=True)])
tls_certs={'cont_id_1':
sample_configs_combined.sample_tls_container_tuple(
id='tls_container_id',
certificate='ImAalsdkfjCert',
private_key='ImAsdlfksdjPrivateKey',
primary_cn="FakeCN")})
self.useFixture(test_utils.OpenFixture(path, rendered_obj)) self.useFixture(test_utils.OpenFixture(path, rendered_obj))
res = util.parse_haproxy_file(LISTENER_ID1) res = util.parse_haproxy_file(LISTENER_ID1)
@ -248,9 +237,7 @@ class TestUtil(base.TestCase):
self.assertEqual('TERMINATED_HTTPS', listener_dict['mode']) self.assertEqual('TERMINATED_HTTPS', listener_dict['mode'])
self.assertEqual(BASE_AMP_PATH + '/sample_loadbalancer_id_1.sock', self.assertEqual(BASE_AMP_PATH + '/sample_loadbalancer_id_1.sock',
res[0]) res[0])
self.assertEqual( self.assertEqual(FAKE_CRT_LIST_FILENAME, listener_dict['ssl_crt'])
BASE_CRT_PATH + '/sample_loadbalancer_id_1/tls_container_id.pem',
listener_dict['ssl_crt'])
# render_template_http # render_template_http
rendered_obj = self.jinja_cfg.render_loadbalancer_obj( rendered_obj = self.jinja_cfg.render_loadbalancer_obj(

View File

@ -275,7 +275,7 @@ class TestHaproxyAmphoraLoadBalancerDriverTest(base.TestCase):
'sni_certs': sconts 'sni_certs': sconts
} }
self.driver.clients[API_VERSION].get_cert_md5sum.side_effect = [ self.driver.clients[API_VERSION].get_cert_md5sum.side_effect = [
exc.NotFound, 'Fake_MD5', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'] exc.NotFound, 'Fake_MD5', 'aaaaa', 'aaaaaaaa']
self.driver._process_tls_certificates( self.driver._process_tls_certificates(
sample_listener, self.amp, sample_listener.load_balancer.id) sample_listener, self.amp, sample_listener.load_balancer.id)
gcm_calls = [ gcm_calls = [
@ -309,7 +309,7 @@ class TestHaproxyAmphoraLoadBalancerDriverTest(base.TestCase):
self.driver.clients[API_VERSION].upload_cert_pem.assert_has_calls( self.driver.clients[API_VERSION].upload_cert_pem.assert_has_calls(
ucp_calls, any_order=True) ucp_calls, any_order=True)
self.assertEqual( self.assertEqual(
3, self.driver.clients[API_VERSION].upload_cert_pem.call_count) 4, self.driver.clients[API_VERSION].upload_cert_pem.call_count)
@mock.patch('oslo_context.context.RequestContext') @mock.patch('oslo_context.context.RequestContext')
@mock.patch('octavia.amphorae.drivers.haproxy.rest_api_driver.' @mock.patch('octavia.amphorae.drivers.haproxy.rest_api_driver.'

View File

@ -275,7 +275,7 @@ class TestHaproxyAmphoraLoadBalancerDriverTest(base.TestCase):
'sni_certs': sconts 'sni_certs': sconts
} }
self.driver.clients[API_VERSION].get_cert_md5sum.side_effect = [ self.driver.clients[API_VERSION].get_cert_md5sum.side_effect = [
exc.NotFound, 'Fake_MD5', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'] exc.NotFound, 'Fake_MD5', 'aaaaa', 'aaaaa']
self.driver._process_tls_certificates( self.driver._process_tls_certificates(
sample_listener, self.amp, sample_listener.load_balancer.id) sample_listener, self.amp, sample_listener.load_balancer.id)
gcm_calls = [ gcm_calls = [
@ -309,7 +309,7 @@ class TestHaproxyAmphoraLoadBalancerDriverTest(base.TestCase):
self.driver.clients[API_VERSION].upload_cert_pem.assert_has_calls( self.driver.clients[API_VERSION].upload_cert_pem.assert_has_calls(
ucp_calls, any_order=True) ucp_calls, any_order=True)
self.assertEqual( self.assertEqual(
3, self.driver.clients[API_VERSION].upload_cert_pem.call_count) 4, self.driver.clients[API_VERSION].upload_cert_pem.call_count)
@mock.patch('oslo_context.context.RequestContext') @mock.patch('oslo_context.context.RequestContext')
@mock.patch('octavia.amphorae.drivers.haproxy.rest_api_driver.' @mock.patch('octavia.amphorae.drivers.haproxy.rest_api_driver.'

View File

@ -16,11 +16,16 @@
import copy import copy
import os import os
from oslo_config import cfg
from oslo_config import fixture as oslo_fixture
from octavia.common import constants from octavia.common import constants
from octavia.common.jinja.haproxy.combined_listeners import jinja_cfg from octavia.common.jinja.haproxy.combined_listeners import jinja_cfg
from octavia.tests.unit import base from octavia.tests.unit import base
from octavia.tests.unit.common.sample_configs import sample_configs_combined from octavia.tests.unit.common.sample_configs import sample_configs_combined
CONF = cfg.CONF
class TestHaproxyCfg(base.TestCase): class TestHaproxyCfg(base.TestCase):
def setUp(self): def setUp(self):
@ -34,20 +39,24 @@ class TestHaproxyCfg(base.TestCase):
self.assertEqual('haproxy.cfg.j2', template.name) self.assertEqual('haproxy.cfg.j2', template.name)
def test_render_template_tls(self): def test_render_template_tls(self):
conf = oslo_fixture.Config(cfg.CONF)
conf.config(group="haproxy_amphora", base_cert_dir='/fake_cert_dir')
FAKE_CRT_LIST_FILENAME = os.path.join(
CONF.haproxy_amphora.base_cert_dir,
'sample_loadbalancer_id_1/sample_listener_id_1.pem')
fe = ("frontend sample_listener_id_1\n" fe = ("frontend sample_listener_id_1\n"
" maxconn {maxconn}\n" " maxconn {maxconn}\n"
" redirect scheme https if !{{ ssl_fc }}\n" " redirect scheme https if !{{ ssl_fc }}\n"
" bind 10.0.0.2:443 " " bind 10.0.0.2:443 "
"ssl crt /var/lib/octavia/certs/" "ssl crt-list {crt_list} "
"sample_loadbalancer_id_1/tls_container_id.pem "
"crt /var/lib/octavia/certs/sample_loadbalancer_id_1 "
"ca-file /var/lib/octavia/certs/sample_loadbalancer_id_1/" "ca-file /var/lib/octavia/certs/sample_loadbalancer_id_1/"
"client_ca.pem verify required crl-file /var/lib/octavia/" "client_ca.pem verify required crl-file /var/lib/octavia/"
"certs/sample_loadbalancer_id_1/SHA_ID.pem\n" "certs/sample_loadbalancer_id_1/SHA_ID.pem\n"
" mode http\n" " mode http\n"
" default_backend sample_pool_id_1:sample_listener_id_1\n" " default_backend sample_pool_id_1:sample_listener_id_1\n"
" timeout client 50000\n").format( " timeout client 50000\n").format(
maxconn=constants.HAPROXY_MAX_MAXCONN) maxconn=constants.HAPROXY_MAX_MAXCONN,
crt_list=FAKE_CRT_LIST_FILENAME)
be = ("backend sample_pool_id_1:sample_listener_id_1\n" be = ("backend sample_pool_id_1:sample_listener_id_1\n"
" mode http\n" " mode http\n"
" balance roundrobin\n" " balance roundrobin\n"
@ -66,34 +75,32 @@ class TestHaproxyCfg(base.TestCase):
"weight 13 check inter 30s fall 3 rise 2 cookie " "weight 13 check inter 30s fall 3 rise 2 cookie "
"sample_member_id_2\n\n").format( "sample_member_id_2\n\n").format(
maxconn=constants.HAPROXY_MAX_MAXCONN) maxconn=constants.HAPROXY_MAX_MAXCONN)
tls_tupe = {'cont_id_1':
sample_configs_combined.sample_tls_container_tuple(
id='tls_container_id',
certificate='imaCert1', private_key='imaPrivateKey1',
primary_cn='FakeCN')}
rendered_obj = self.jinja_cfg.render_loadbalancer_obj( rendered_obj = self.jinja_cfg.render_loadbalancer_obj(
sample_configs_combined.sample_amphora_tuple(), sample_configs_combined.sample_amphora_tuple(),
[sample_configs_combined.sample_listener_tuple( [sample_configs_combined.sample_listener_tuple(
proto='TERMINATED_HTTPS', tls=True, sni=True, proto='TERMINATED_HTTPS', tls=True, sni=True,
client_ca_cert=True, client_crl_cert=True)], client_ca_cert=True, client_crl_cert=True)],
tls_tupe, client_ca_filename='client_ca.pem', client_ca_filename='client_ca.pem', client_crl='SHA_ID.pem')
client_crl='SHA_ID.pem')
self.assertEqual( self.assertEqual(
sample_configs_combined.sample_base_expected_config( sample_configs_combined.sample_base_expected_config(
frontend=fe, backend=be), frontend=fe, backend=be),
rendered_obj) rendered_obj)
def test_render_template_tls_no_sni(self): def test_render_template_tls_no_sni(self):
conf = oslo_fixture.Config(cfg.CONF)
conf.config(group="haproxy_amphora", base_cert_dir='/fake_cert_dir')
FAKE_CRT_LIST_FILENAME = os.path.join(
CONF.haproxy_amphora.base_cert_dir,
'sample_loadbalancer_id_1/sample_listener_id_1.pem')
fe = ("frontend sample_listener_id_1\n" fe = ("frontend sample_listener_id_1\n"
" maxconn {maxconn}\n" " maxconn {maxconn}\n"
" redirect scheme https if !{{ ssl_fc }}\n" " redirect scheme https if !{{ ssl_fc }}\n"
" bind 10.0.0.2:443 " " bind 10.0.0.2:443 ssl crt-list {crt_list}\n"
"ssl crt /var/lib/octavia/certs/"
"sample_loadbalancer_id_1/tls_container_id.pem\n"
" mode http\n" " mode http\n"
" default_backend sample_pool_id_1:sample_listener_id_1\n" " default_backend sample_pool_id_1:sample_listener_id_1\n"
" timeout client 50000\n").format( " timeout client 50000\n").format(
maxconn=constants.HAPROXY_MAX_MAXCONN) maxconn=constants.HAPROXY_MAX_MAXCONN,
crt_list=FAKE_CRT_LIST_FILENAME)
be = ("backend sample_pool_id_1:sample_listener_id_1\n" be = ("backend sample_pool_id_1:sample_listener_id_1\n"
" mode http\n" " mode http\n"
" balance roundrobin\n" " balance roundrobin\n"
@ -115,13 +122,7 @@ class TestHaproxyCfg(base.TestCase):
rendered_obj = self.jinja_cfg.render_loadbalancer_obj( rendered_obj = self.jinja_cfg.render_loadbalancer_obj(
sample_configs_combined.sample_amphora_tuple(), sample_configs_combined.sample_amphora_tuple(),
[sample_configs_combined.sample_listener_tuple( [sample_configs_combined.sample_listener_tuple(
proto='TERMINATED_HTTPS', tls=True)], proto='TERMINATED_HTTPS', tls=True)])
tls_certs={'cont_id_1':
sample_configs_combined.sample_tls_container_tuple(
id='tls_container_id',
certificate='ImAalsdkfjCert',
private_key='ImAsdlfksdjPrivateKey',
primary_cn="FakeCN")})
self.assertEqual( self.assertEqual(
sample_configs_combined.sample_base_expected_config( sample_configs_combined.sample_base_expected_config(
frontend=fe, backend=be), frontend=fe, backend=be),
@ -922,13 +923,13 @@ class TestHaproxyCfg(base.TestCase):
def test_transform_listener(self): def test_transform_listener(self):
in_listener = sample_configs_combined.sample_listener_tuple() in_listener = sample_configs_combined.sample_listener_tuple()
ret = self.jinja_cfg._transform_listener(in_listener, None, {}, ret = self.jinja_cfg._transform_listener(in_listener, {},
in_listener.load_balancer) in_listener.load_balancer)
self.assertEqual(sample_configs_combined.RET_LISTENER, ret) self.assertEqual(sample_configs_combined.RET_LISTENER, ret)
def test_transform_listener_with_l7(self): def test_transform_listener_with_l7(self):
in_listener = sample_configs_combined.sample_listener_tuple(l7=True) in_listener = sample_configs_combined.sample_listener_tuple(l7=True)
ret = self.jinja_cfg._transform_listener(in_listener, None, {}, ret = self.jinja_cfg._transform_listener(in_listener, {},
in_listener.load_balancer) in_listener.load_balancer)
self.assertEqual(sample_configs_combined.RET_LISTENER_L7, ret) self.assertEqual(sample_configs_combined.RET_LISTENER_L7, ret)
@ -936,7 +937,7 @@ class TestHaproxyCfg(base.TestCase):
in_amphora = sample_configs_combined.sample_amphora_tuple() in_amphora = sample_configs_combined.sample_amphora_tuple()
in_listener = sample_configs_combined.sample_listener_tuple() in_listener = sample_configs_combined.sample_listener_tuple()
ret = self.jinja_cfg._transform_loadbalancer( ret = self.jinja_cfg._transform_loadbalancer(
in_amphora, in_listener.load_balancer, [in_listener], None, {}) in_amphora, in_listener.load_balancer, [in_listener], {})
self.assertEqual(sample_configs_combined.RET_LB, ret) self.assertEqual(sample_configs_combined.RET_LB, ret)
def test_transform_amphora(self): def test_transform_amphora(self):
@ -948,7 +949,7 @@ class TestHaproxyCfg(base.TestCase):
in_amphora = sample_configs_combined.sample_amphora_tuple() in_amphora = sample_configs_combined.sample_amphora_tuple()
in_listener = sample_configs_combined.sample_listener_tuple(l7=True) in_listener = sample_configs_combined.sample_listener_tuple(l7=True)
ret = self.jinja_cfg._transform_loadbalancer( ret = self.jinja_cfg._transform_loadbalancer(
in_amphora, in_listener.load_balancer, [in_listener], None, {}) in_amphora, in_listener.load_balancer, [in_listener], {})
self.assertEqual(sample_configs_combined.RET_LB_L7, ret) self.assertEqual(sample_configs_combined.RET_LB_L7, ret)
def test_transform_l7policy(self): def test_transform_l7policy(self):
@ -1066,7 +1067,6 @@ class TestHaproxyCfg(base.TestCase):
rendered_obj = j_cfg.build_config( rendered_obj = j_cfg.build_config(
sample_amphora, sample_amphora,
[sample_proxy_listener], [sample_proxy_listener],
tls_certs=None,
haproxy_versions=("1", "8", "1")) haproxy_versions=("1", "8", "1"))
self.assertEqual( self.assertEqual(
sample_configs_combined.sample_base_expected_config(backend=be), sample_configs_combined.sample_base_expected_config(backend=be),
@ -1094,7 +1094,6 @@ class TestHaproxyCfg(base.TestCase):
rendered_obj = j_cfg.build_config( rendered_obj = j_cfg.build_config(
sample_amphora, sample_amphora,
[sample_proxy_listener], [sample_proxy_listener],
tls_certs=None,
haproxy_versions=("1", "5", "18")) haproxy_versions=("1", "5", "18"))
self.assertEqual( self.assertEqual(
sample_configs_combined.sample_base_expected_config(backend=be), sample_configs_combined.sample_base_expected_config(backend=be),
@ -1176,7 +1175,6 @@ class TestHaproxyCfg(base.TestCase):
rendered_obj = j_cfg.build_config( rendered_obj = j_cfg.build_config(
sample_configs_combined.sample_amphora_tuple(), sample_configs_combined.sample_amphora_tuple(),
[sample_listener], [sample_listener],
tls_certs=None,
haproxy_versions=("1", "5", "18")) haproxy_versions=("1", "5", "18"))
self.assertEqual( self.assertEqual(
sample_configs_combined.sample_base_expected_config( sample_configs_combined.sample_base_expected_config(

View File

@ -16,11 +16,16 @@
import copy import copy
import os import os
from oslo_config import cfg
from oslo_config import fixture as oslo_fixture
from octavia.common import constants from octavia.common import constants
from octavia.common.jinja.haproxy.split_listeners import jinja_cfg from octavia.common.jinja.haproxy.split_listeners import jinja_cfg
from octavia.tests.unit import base from octavia.tests.unit import base
from octavia.tests.unit.common.sample_configs import sample_configs_split from octavia.tests.unit.common.sample_configs import sample_configs_split
CONF = cfg.CONF
class TestHaproxyCfg(base.TestCase): class TestHaproxyCfg(base.TestCase):
def setUp(self): def setUp(self):
@ -34,20 +39,24 @@ class TestHaproxyCfg(base.TestCase):
self.assertEqual('haproxy.cfg.j2', template.name) self.assertEqual('haproxy.cfg.j2', template.name)
def test_render_template_tls(self): def test_render_template_tls(self):
conf = oslo_fixture.Config(cfg.CONF)
conf.config(group="haproxy_amphora", base_cert_dir='/fake_cert_dir')
FAKE_CRT_LIST_FILENAME = os.path.join(
CONF.haproxy_amphora.base_cert_dir,
'sample_listener_id_1/sample_listener_id_1.pem')
fe = ("frontend sample_listener_id_1\n" fe = ("frontend sample_listener_id_1\n"
" maxconn {maxconn}\n" " maxconn {maxconn}\n"
" redirect scheme https if !{{ ssl_fc }}\n" " redirect scheme https if !{{ ssl_fc }}\n"
" bind 10.0.0.2:443 " " bind 10.0.0.2:443 "
"ssl crt /var/lib/octavia/certs/" "ssl crt-list {crt_list} "
"sample_listener_id_1/tls_container_id.pem "
"crt /var/lib/octavia/certs/sample_listener_id_1 "
"ca-file /var/lib/octavia/certs/sample_listener_id_1/" "ca-file /var/lib/octavia/certs/sample_listener_id_1/"
"client_ca.pem verify required crl-file /var/lib/octavia/" "client_ca.pem verify required crl-file /var/lib/octavia/"
"certs/sample_listener_id_1/SHA_ID.pem\n" "certs/sample_listener_id_1/SHA_ID.pem\n"
" mode http\n" " mode http\n"
" default_backend sample_pool_id_1\n" " default_backend sample_pool_id_1\n"
" timeout client 50000\n").format( " timeout client 50000\n").format(
maxconn=constants.HAPROXY_MAX_MAXCONN) maxconn=constants.HAPROXY_MAX_MAXCONN,
crt_list=FAKE_CRT_LIST_FILENAME)
be = ("backend sample_pool_id_1\n" be = ("backend sample_pool_id_1\n"
" mode http\n" " mode http\n"
" balance roundrobin\n" " balance roundrobin\n"
@ -66,16 +75,12 @@ class TestHaproxyCfg(base.TestCase):
"weight 13 check inter 30s fall 3 rise 2 cookie " "weight 13 check inter 30s fall 3 rise 2 cookie "
"sample_member_id_2\n\n").format( "sample_member_id_2\n\n").format(
maxconn=constants.HAPROXY_MAX_MAXCONN) maxconn=constants.HAPROXY_MAX_MAXCONN)
tls_tupe = sample_configs_split.sample_tls_container_tuple(
id='tls_container_id',
certificate='imaCert1', private_key='imaPrivateKey1',
primary_cn='FakeCN')
rendered_obj = self.jinja_cfg.render_loadbalancer_obj( rendered_obj = self.jinja_cfg.render_loadbalancer_obj(
sample_configs_split.sample_amphora_tuple(), sample_configs_split.sample_amphora_tuple(),
sample_configs_split.sample_listener_tuple( sample_configs_split.sample_listener_tuple(
proto='TERMINATED_HTTPS', tls=True, sni=True, proto='TERMINATED_HTTPS', tls=True, sni=True,
client_ca_cert=True, client_crl_cert=True), client_ca_cert=True, client_crl_cert=True),
tls_tupe, client_ca_filename='client_ca.pem', client_ca_filename='client_ca.pem',
client_crl='SHA_ID.pem') client_crl='SHA_ID.pem')
self.assertEqual( self.assertEqual(
sample_configs_split.sample_base_expected_config( sample_configs_split.sample_base_expected_config(
@ -83,16 +88,21 @@ class TestHaproxyCfg(base.TestCase):
rendered_obj) rendered_obj)
def test_render_template_tls_no_sni(self): def test_render_template_tls_no_sni(self):
conf = oslo_fixture.Config(cfg.CONF)
conf.config(group="haproxy_amphora", base_cert_dir='/fake_cert_dir')
FAKE_CRT_LIST_FILENAME = os.path.join(
CONF.haproxy_amphora.base_cert_dir,
'sample_listener_id_1/sample_listener_id_1.pem')
fe = ("frontend sample_listener_id_1\n" fe = ("frontend sample_listener_id_1\n"
" maxconn {maxconn}\n" " maxconn {maxconn}\n"
" redirect scheme https if !{{ ssl_fc }}\n" " redirect scheme https if !{{ ssl_fc }}\n"
" bind 10.0.0.2:443 " " bind 10.0.0.2:443 "
"ssl crt /var/lib/octavia/certs/" "ssl crt-list {crt_list}\n"
"sample_listener_id_1/tls_container_id.pem\n"
" mode http\n" " mode http\n"
" default_backend sample_pool_id_1\n" " default_backend sample_pool_id_1\n"
" timeout client 50000\n").format( " timeout client 50000\n").format(
maxconn=constants.HAPROXY_MAX_MAXCONN) maxconn=constants.HAPROXY_MAX_MAXCONN,
crt_list=FAKE_CRT_LIST_FILENAME)
be = ("backend sample_pool_id_1\n" be = ("backend sample_pool_id_1\n"
" mode http\n" " mode http\n"
" balance roundrobin\n" " balance roundrobin\n"
@ -114,12 +124,7 @@ class TestHaproxyCfg(base.TestCase):
rendered_obj = self.jinja_cfg.render_loadbalancer_obj( rendered_obj = self.jinja_cfg.render_loadbalancer_obj(
sample_configs_split.sample_amphora_tuple(), sample_configs_split.sample_amphora_tuple(),
sample_configs_split.sample_listener_tuple( sample_configs_split.sample_listener_tuple(
proto='TERMINATED_HTTPS', tls=True), proto='TERMINATED_HTTPS', tls=True))
tls_cert=sample_configs_split.sample_tls_container_tuple(
id='tls_container_id',
certificate='ImAalsdkfjCert',
private_key='ImAsdlfksdjPrivateKey',
primary_cn="FakeCN"))
self.assertEqual( self.assertEqual(
sample_configs_split.sample_base_expected_config( sample_configs_split.sample_base_expected_config(
frontend=fe, backend=be), frontend=fe, backend=be),
@ -913,13 +918,13 @@ class TestHaproxyCfg(base.TestCase):
def test_transform_listener(self): def test_transform_listener(self):
in_listener = sample_configs_split.sample_listener_tuple() in_listener = sample_configs_split.sample_listener_tuple()
ret = self.jinja_cfg._transform_listener(in_listener, None, {}, ret = self.jinja_cfg._transform_listener(in_listener, {},
in_listener.load_balancer) in_listener.load_balancer)
self.assertEqual(sample_configs_split.RET_LISTENER, ret) self.assertEqual(sample_configs_split.RET_LISTENER, ret)
def test_transform_listener_with_l7(self): def test_transform_listener_with_l7(self):
in_listener = sample_configs_split.sample_listener_tuple(l7=True) in_listener = sample_configs_split.sample_listener_tuple(l7=True)
ret = self.jinja_cfg._transform_listener(in_listener, None, {}, ret = self.jinja_cfg._transform_listener(in_listener, {},
in_listener.load_balancer) in_listener.load_balancer)
self.assertEqual(sample_configs_split.RET_LISTENER_L7, ret) self.assertEqual(sample_configs_split.RET_LISTENER_L7, ret)
@ -927,7 +932,7 @@ class TestHaproxyCfg(base.TestCase):
in_amphora = sample_configs_split.sample_amphora_tuple() in_amphora = sample_configs_split.sample_amphora_tuple()
in_listener = sample_configs_split.sample_listener_tuple() in_listener = sample_configs_split.sample_listener_tuple()
ret = self.jinja_cfg._transform_loadbalancer( ret = self.jinja_cfg._transform_loadbalancer(
in_amphora, in_listener.load_balancer, in_listener, None, {}) in_amphora, in_listener.load_balancer, in_listener, {})
self.assertEqual(sample_configs_split.RET_LB, ret) self.assertEqual(sample_configs_split.RET_LB, ret)
def test_transform_amphora(self): def test_transform_amphora(self):
@ -939,7 +944,7 @@ class TestHaproxyCfg(base.TestCase):
in_amphora = sample_configs_split.sample_amphora_tuple() in_amphora = sample_configs_split.sample_amphora_tuple()
in_listener = sample_configs_split.sample_listener_tuple(l7=True) in_listener = sample_configs_split.sample_listener_tuple(l7=True)
ret = self.jinja_cfg._transform_loadbalancer( ret = self.jinja_cfg._transform_loadbalancer(
in_amphora, in_listener.load_balancer, in_listener, None, {}) in_amphora, in_listener.load_balancer, in_listener, {})
self.assertEqual(sample_configs_split.RET_LB_L7, ret) self.assertEqual(sample_configs_split.RET_LB_L7, ret)
def test_transform_l7policy(self): def test_transform_l7policy(self):
@ -1052,7 +1057,6 @@ class TestHaproxyCfg(base.TestCase):
rendered_obj = j_cfg.build_config( rendered_obj = j_cfg.build_config(
sample_configs_split.sample_amphora_tuple(), sample_configs_split.sample_amphora_tuple(),
sample_configs_split.sample_listener_tuple(be_proto='PROXY'), sample_configs_split.sample_listener_tuple(be_proto='PROXY'),
tls_cert=None,
haproxy_versions=("1", "8", "1")) haproxy_versions=("1", "8", "1"))
self.assertEqual( self.assertEqual(
sample_configs_split.sample_base_expected_config(backend=be), sample_configs_split.sample_base_expected_config(backend=be),
@ -1078,7 +1082,6 @@ class TestHaproxyCfg(base.TestCase):
rendered_obj = j_cfg.build_config( rendered_obj = j_cfg.build_config(
sample_configs_split.sample_amphora_tuple(), sample_configs_split.sample_amphora_tuple(),
sample_configs_split.sample_listener_tuple(be_proto='PROXY'), sample_configs_split.sample_listener_tuple(be_proto='PROXY'),
tls_cert=None,
haproxy_versions=("1", "5", "18")) haproxy_versions=("1", "5", "18"))
self.assertEqual( self.assertEqual(
sample_configs_split.sample_base_expected_config(backend=be), sample_configs_split.sample_base_expected_config(backend=be),
@ -1159,7 +1162,6 @@ class TestHaproxyCfg(base.TestCase):
rendered_obj = j_cfg.build_config( rendered_obj = j_cfg.build_config(
sample_configs_split.sample_amphora_tuple(), sample_configs_split.sample_amphora_tuple(),
sample_listener, sample_listener,
tls_cert=None,
haproxy_versions=("1", "5", "18")) haproxy_versions=("1", "5", "18"))
self.assertEqual( self.assertEqual(
sample_configs_split.sample_base_expected_config( sample_configs_split.sample_base_expected_config(

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Fixes an issue where load balancers with more than one TLS enabled
listener, one or more SNI enabled, may load certificates from
other TLS enabled listeners for SNI use.