diff --git a/octavia/amphorae/drivers/haproxy/rest_api_driver.py b/octavia/amphorae/drivers/haproxy/rest_api_driver.py index 0d97015151..63eb6d4eb0 100644 --- a/octavia/amphorae/drivers/haproxy/rest_api_driver.py +++ b/octavia/amphorae/drivers/haproxy/rest_api_driver.py @@ -145,6 +145,7 @@ class HaproxyAmphoraLoadBalancerDriver( 'process mode.', amphora.id, loadbalancer.id) has_tcp = False + certs = {} for listener in loadbalancer.listeners: LOG.debug("%s updating listener %s on amphora %s", self.__class__.__name__, listener.id, amphora.id) @@ -162,8 +163,10 @@ class HaproxyAmphoraLoadBalancerDriver( else: obj_id = loadbalancer.id - certs = self._process_tls_certificates( - listener, amphora, obj_id) + certs.update({ + listener.tls_certificate_id: + self._process_tls_certificates( + listener, amphora, obj_id)['tls_cert']}) client_ca_filename = self._process_secret( listener, listener.client_ca_tls_certificate_id, amphora, obj_id) @@ -176,7 +179,7 @@ class HaproxyAmphoraLoadBalancerDriver( if split_config: config = self.jinja_split.build_config( host_amphora=amphora, listener=listener, - tls_cert=certs['tls_cert'], + tls_cert=certs[listener.tls_certificate_id], haproxy_versions=haproxy_versions, client_ca_filename=client_ca_filename, client_crl=crl_filename, @@ -191,7 +194,7 @@ class HaproxyAmphoraLoadBalancerDriver( # Generate HaProxy configuration from listener object config = self.jinja_combo.build_config( host_amphora=amphora, listeners=loadbalancer.listeners, - tls_cert=certs['tls_cert'], + tls_certs=certs, haproxy_versions=haproxy_versions, client_ca_filename=client_ca_filename, client_crl=crl_filename, diff --git a/octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py b/octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py index dc8181eee7..d19005f0b5 100644 --- a/octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py +++ b/octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py @@ -81,7 +81,7 @@ class JinjaTemplater(object): self.log_server = log_server self.connection_logging = connection_logging - def build_config(self, host_amphora, listeners, tls_cert, + def build_config(self, host_amphora, listeners, tls_certs, haproxy_versions, socket_path=None, client_ca_filename=None, client_crl=None, pool_tls_certs=None): @@ -89,7 +89,7 @@ class JinjaTemplater(object): :param host_amphora: The Amphora this configuration is hosted on :param listener: The listener configuration - :param tls_cert: The TLS certificates for the listener + :param tls_certs: Dict of the TLS certificates for the listeners :param socket_path: The socket path for Haproxy process :return: Rendered configuration """ @@ -104,7 +104,7 @@ class JinjaTemplater(object): feature_compatibility[constants.HTTP_REUSE] = True return self.render_loadbalancer_obj( - host_amphora, listeners, tls_cert=tls_cert, + host_amphora, listeners, tls_certs=tls_certs, socket_path=socket_path, feature_compatibility=feature_compatibility, client_ca_filename=client_ca_filename, client_crl=client_crl, @@ -144,7 +144,7 @@ class JinjaTemplater(object): return log_format def render_loadbalancer_obj(self, host_amphora, listeners, - tls_cert=None, socket_path=None, + tls_certs=None, socket_path=None, feature_compatibility=None, client_ca_filename=None, client_crl=None, pool_tls_certs=None): @@ -152,7 +152,7 @@ class JinjaTemplater(object): :param host_amphora: The Amphora this configuration is hosted on :param listener: The listener configuration - :param tls_cert: The TLS certificates for the listener + :param tls_certs: Dict of the TLS certificates for the listener :param client_ca_filename: The CA certificate for client authorization :param socket_path: The socket path for Haproxy process :return: Rendered configuration @@ -162,7 +162,7 @@ class JinjaTemplater(object): host_amphora, listeners[0].load_balancer, listeners, - tls_cert, + tls_certs, feature_compatibility, client_ca_filename=client_ca_filename, client_crl=client_crl, @@ -182,7 +182,7 @@ class JinjaTemplater(object): constants=constants) def _transform_loadbalancer(self, host_amphora, loadbalancer, listeners, - tls_cert, feature_compatibility, + tls_certs, feature_compatibility, client_ca_filename=None, client_crl=None, pool_tls_certs=None): """Transforms a load balancer into an object that will @@ -194,7 +194,7 @@ class JinjaTemplater(object): if listener.protocol == constants.PROTOCOL_UDP: continue listener_transforms.append(self._transform_listener( - listener, tls_cert, feature_compatibility, loadbalancer, + listener, tls_certs, feature_compatibility, loadbalancer, client_ca_filename=client_ca_filename, client_crl=client_crl, pool_tls_certs=pool_tls_certs)) @@ -246,7 +246,7 @@ class JinjaTemplater(object): 'vrrp_priority': amphora.vrrp_priority } - def _transform_listener(self, listener, tls_cert, feature_compatibility, + def _transform_listener(self, listener, tls_certs, feature_compatibility, loadbalancer, client_ca_filename=None, client_crl=None, pool_tls_certs=None): """Transforms a listener into an object that will @@ -278,11 +278,11 @@ class JinjaTemplater(object): ret_value['connection_limit'] = listener.connection_limit else: ret_value['connection_limit'] = constants.HAPROXY_MAX_MAXCONN - if listener.tls_certificate_id: + if listener.tls_certificate_id and tls_certs is not None: ret_value['default_tls_path'] = '%s.pem' % ( os.path.join(self.base_crt_dir, loadbalancer.id, - tls_cert.id)) + tls_certs[listener.tls_certificate_id].id)) if listener.sni_containers: ret_value['crt_dir'] = os.path.join( self.base_crt_dir, loadbalancer.id) diff --git a/octavia/tests/unit/amphorae/backends/agent/api_server/test_amphora_info.py b/octavia/tests/unit/amphorae/backends/agent/api_server/test_amphora_info.py index 8eacfc429d..32321b0bde 100644 --- a/octavia/tests/unit/amphorae/backends/agent/api_server/test_amphora_info.py +++ b/octavia/tests/unit/amphorae/backends/agent/api_server/test_amphora_info.py @@ -50,10 +50,11 @@ class TestAmphoraInfo(base.TestCase): templater = jinja_cfg.JinjaTemplater( base_amp_path=self.BASE_AMP_PATH, base_crt_dir=self.BASE_CRT_PATH) - tls_tupel = sample_configs_combined.sample_tls_container_tuple( - id='tls_container_id', - certificate='imaCert1', private_key='imaPrivateKey1', - primary_cn='FakeCN') + tls_tupel = {'cont_id_1': + sample_configs_combined.sample_tls_container_tuple( + id='tls_container_id', + certificate='imaCert1', private_key='imaPrivateKey1', + primary_cn='FakeCN')} self.rendered_haproxy_cfg = templater.render_loadbalancer_obj( sample_configs_combined.sample_amphora_tuple(), [sample_configs_combined.sample_listener_tuple( diff --git a/octavia/tests/unit/amphorae/backends/agent/api_server/test_util.py b/octavia/tests/unit/amphorae/backends/agent/api_server/test_util.py index 8854209609..990c4fd429 100644 --- a/octavia/tests/unit/amphorae/backends/agent/api_server/test_util.py +++ b/octavia/tests/unit/amphorae/backends/agent/api_server/test_util.py @@ -204,10 +204,11 @@ class TestUtil(base.TestCase): def test_parse_haproxy_config(self): # template_tls - tls_tupe = sample_configs_combined.sample_tls_container_tuple( - id='tls_container_id', - certificate='imaCert1', private_key='imaPrivateKey1', - primary_cn='FakeCN') + 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( sample_configs_combined.sample_amphora_tuple(), [sample_configs_combined.sample_listener_tuple( @@ -233,11 +234,12 @@ class TestUtil(base.TestCase): sample_configs_combined.sample_amphora_tuple(), [sample_configs_combined.sample_listener_tuple( proto='TERMINATED_HTTPS', tls=True)], - tls_cert=sample_configs_combined.sample_tls_container_tuple( - id='tls_container_id', - certificate='ImAalsdkfjCert', - private_key='ImAsdlfksdjPrivateKey', - primary_cn="FakeCN")) + 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)) diff --git a/octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py b/octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py index 3058401ea1..e513510b4d 100644 --- a/octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py +++ b/octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py @@ -70,10 +70,11 @@ class TestHaproxyCfg(base.TestCase): "weight 13 check inter 30s fall 3 rise 2 cookie " "sample_member_id_2\n\n").format( maxconn=constants.HAPROXY_MAX_MAXCONN) - tls_tupe = sample_configs_combined.sample_tls_container_tuple( - id='tls_container_id', - certificate='imaCert1', private_key='imaPrivateKey1', - primary_cn='FakeCN') + 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( sample_configs_combined.sample_amphora_tuple(), [sample_configs_combined.sample_listener_tuple( @@ -123,11 +124,12 @@ class TestHaproxyCfg(base.TestCase): sample_configs_combined.sample_amphora_tuple(), [sample_configs_combined.sample_listener_tuple( proto='TERMINATED_HTTPS', tls=True)], - tls_cert=sample_configs_combined.sample_tls_container_tuple( - id='tls_container_id', - certificate='ImAalsdkfjCert', - private_key='ImAsdlfksdjPrivateKey', - primary_cn="FakeCN")) + 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( sample_configs_combined.sample_base_expected_config( frontend=fe, backend=be), @@ -1083,7 +1085,7 @@ class TestHaproxyCfg(base.TestCase): rendered_obj = j_cfg.build_config( sample_amphora, [sample_proxy_listener], - tls_cert=None, + tls_certs=None, haproxy_versions=("1", "8", "1")) self.assertEqual( sample_configs_combined.sample_base_expected_config(backend=be), @@ -1111,7 +1113,7 @@ class TestHaproxyCfg(base.TestCase): rendered_obj = j_cfg.build_config( sample_amphora, [sample_proxy_listener], - tls_cert=None, + tls_certs=None, haproxy_versions=("1", "5", "18")) self.assertEqual( sample_configs_combined.sample_base_expected_config(backend=be), @@ -1197,7 +1199,7 @@ class TestHaproxyCfg(base.TestCase): rendered_obj = j_cfg.build_config( sample_configs_combined.sample_amphora_tuple(), [sample_listener], - tls_cert=None, + tls_certs=None, haproxy_versions=("1", "5", "18")) self.assertEqual( sample_configs_combined.sample_base_expected_config(