diff options
-rw-r--r-- | manifests/haproxy.pp | 65 | ||||
-rw-r--r-- | manifests/haproxy/horizon_endpoint.pp | 154 |
2 files changed, 170 insertions, 49 deletions
diff --git a/manifests/haproxy.pp b/manifests/haproxy.pp index a3d088a..83ca930 100644 --- a/manifests/haproxy.pp +++ b/manifests/haproxy.pp @@ -402,6 +402,10 @@ # (optional) Specify the network heat_cloudwatch is running on. # Defaults to hiera('heat_api_cloudwatch_network', undef) # +# [*horizon_network*] +# (optional) Specify the network horizon is running on. +# Defaults to hiera('horizon_network', undef) +# # [*ironic_inspector_network*] # (optional) Specify the network ironic_inspector is running on. # Defaults to hiera('ironic_inspector_network', undef) @@ -644,6 +648,7 @@ class tripleo::haproxy ( $heat_api_network = hiera('heat_api_network', undef), $heat_cfn_network = hiera('heat_api_cfn_network', undef), $heat_cloudwatch_network = hiera('heat_api_cloudwatch_network', undef), + $horizon_network = hiera('horizon_network', undef), $ironic_inspector_network = hiera('ironic_inspector_network', undef), $ironic_network = hiera('ironic_api_network', undef), $keystone_admin_network = hiera('keystone_admin_api_network', undef), @@ -772,43 +777,6 @@ class tripleo::haproxy ( $controller_hosts_names_real = downcase(any2array(split($controller_hosts_names, ','))) } - $horizon_vip = hiera('horizon_vip', $controller_virtual_ip) - if $service_certificate { - # NOTE(jaosorior): If the horizon_vip and the public_virtual_ip are the - # same, the first option takes precedence. Which is the case when network - # isolation is not enabled. This is not a problem as both options are - # identical. If network isolation is enabled, this works correctly and - # will add a TLS binding to both the horizon_vip and the - # public_virtual_ip. - # Even though for the public_virtual_ip the port 80 is listening, we - # redirect to https in the horizon_options below. - $horizon_bind_opts = { - "${horizon_vip}:80" => $haproxy_listen_bind_param, - "${horizon_vip}:443" => union($haproxy_listen_bind_param, ['ssl', 'crt', $service_certificate]), - "${public_virtual_ip}:80" => $haproxy_listen_bind_param, - "${public_virtual_ip}:443" => union($haproxy_listen_bind_param, ['ssl', 'crt', $service_certificate]), - } - $horizon_options = { - 'cookie' => 'SERVERID insert indirect nocache', - 'rsprep' => '^Location:\ http://(.*) Location:\ https://\1', - # NOTE(jaosorior): We always redirect to https for the public_virtual_ip. - 'redirect' => 'scheme https code 301 if !{ ssl_fc }', - 'option' => [ 'forwardfor', 'httpchk' ], - 'http-request' => [ - 'set-header X-Forwarded-Proto https if { ssl_fc }', - 'set-header X-Forwarded-Proto http if !{ ssl_fc }'], - } - } else { - $horizon_bind_opts = { - "${horizon_vip}:80" => $haproxy_listen_bind_param, - "${public_virtual_ip}:80" => $haproxy_listen_bind_param, - } - $horizon_options = { - 'cookie' => 'SERVERID insert indirect nocache', - 'option' => [ 'forwardfor', 'httpchk' ], - } - } - $mysql_vip = hiera('mysql_vip', $controller_virtual_ip) $mysql_bind_opts = { "${mysql_vip}:3306" => $haproxy_listen_bind_param, @@ -1274,18 +1242,17 @@ class tripleo::haproxy ( } if $horizon { - haproxy::listen { 'horizon': - bind => $horizon_bind_opts, - options => $horizon_options, - mode => 'http', - collect_exported => false, - } - haproxy::balancermember { 'horizon': - listening_service => 'horizon', - ports => '80', - ipaddresses => hiera('horizon_node_ips', $controller_hosts_real), - server_names => hiera('horizon_node_names', $controller_hosts_names_real), - options => union($haproxy_member_options, ["cookie ${::hostname}"]), + class { '::tripleo::haproxy::horizon_endpoint': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('horizon_vip', $controller_virtual_ip), + haproxy_listen_bind_param => $haproxy_listen_bind_param, + ip_addresses => hiera('horizon_node_ips', $controller_hosts_real), + server_names => hiera('horizon_node_names', $controller_hosts_names_real), + member_options => union($haproxy_member_options, $internal_tls_member_options), + public_certificate => $service_certificate, + use_internal_certificates => $use_internal_certificates, + internal_certificates_specs => $internal_certificates_specs, + service_network => $horizon_network, } } diff --git a/manifests/haproxy/horizon_endpoint.pp b/manifests/haproxy/horizon_endpoint.pp new file mode 100644 index 0000000..c7dfd88 --- /dev/null +++ b/manifests/haproxy/horizon_endpoint.pp @@ -0,0 +1,154 @@ +# Copyright 2014 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +# == Class: tripleo::haproxy::endpoint +# +# Configure a HAProxy listen endpoint +# +# [*internal_ip*] +# The IP in which the proxy endpoint will be listening in the internal +# network. +# +# [*ip_addresses*] +# The ordered list of IPs to be used to contact the balancer member. +# +# [*server_names*] +# The names of the balancer members, which usually should be the hostname. +# +# [*member_options*] +# Options for the balancer member, specified after the server declaration. +# These should go in the member's configuration block. +# +# [*public_virtual_ip*] +# Address in which the proxy endpoint will be listening in the public network. +# If this service is internal only this should be ommitted. +# Defaults to undef. +# +# [*haproxy_listen_bind_param*] +# A list of params to be added to the HAProxy listener bind directive. +# Defaults to undef. +# +# [*public_certificate*] +# Certificate path used to enable TLS for the public proxy endpoint. +# Defaults to undef. +# +# [*use_internal_certificates*] +# Flag that indicates if we'll use an internal certificate for this specific +# service. When set, enables SSL on the internal API endpoints using the file +# that certmonger is tracking; this is derived from the network the service is +# listening on. +# Defaults to false +# +# [*internal_certificates_specs*] +# A hash that should contain the specs that were used to create the +# certificates. As the name indicates, only the internal certificates will be +# fetched from here. And the keys should follow the following pattern +# "haproxy-<network name>". The network name should be as it was defined in +# tripleo-heat-templates. +# Note that this is only taken into account if the $use_internal_certificates +# flag is set. +# Defaults to {} +# +# [*service_network*] +# (optional) Indicates the network that the service is running on. Used for +# fetching the certificate for that specific network. +# Defaults to undef +# +class tripleo::haproxy::horizon_endpoint ( + $internal_ip, + $ip_addresses, + $server_names, + $member_options, + $public_virtual_ip, + $haproxy_listen_bind_param = undef, + $public_certificate = undef, + $use_internal_certificates = false, + $internal_certificates_specs = {}, + $service_network = undef, +) { + # service exposed to the public network + if $public_certificate { + if $use_internal_certificates { + if !$service_network { + fail("The service_network for this service is undefined. Can't configure TLS for the internal network.") + } + # NOTE(jaosorior): The key of the internal_certificates_specs hash must + # must match the convention haproxy-<network name> or else this + # will fail. Futherly, it must contain the path that we'll use under + # 'service_pem'. + $internal_cert_path = $internal_certificates_specs["haproxy-${service_network}"]['service_pem'] + $internal_bind_opts = union($haproxy_listen_bind_param, ['ssl', 'crt', $internal_cert_path]) + } else { + # If no internal cert is given, we still configure TLS for the internal + # network, however, we expect that the public certificate has appropriate + # subjectaltnames set. + $internal_bind_opts = union($haproxy_listen_bind_param, ['ssl', 'crt', $public_certificate]) + } + # NOTE(jaosorior): If the internal_ip and the public_virtual_ip are the + # same, the first option takes precedence. Which is the case when network + # isolation is not enabled. This is not a problem as both options are + # identical. If network isolation is enabled, this works correctly and + # will add a TLS binding to both the internal_ip and the + # public_virtual_ip. + # Even though for the public_virtual_ip the port 80 is listening, we + # redirect to https in the horizon_options below. + $horizon_bind_opts = { + "${internal_ip}:80" => $haproxy_listen_bind_param, + "${internal_ip}:443" => $internal_bind_opts, + "${public_virtual_ip}:80" => $haproxy_listen_bind_param, + "${public_virtual_ip}:443" => union($haproxy_listen_bind_param, ['ssl', 'crt', $public_certificate]), + } + $horizon_options = { + 'cookie' => 'SERVERID insert indirect nocache', + 'rsprep' => '^Location:\ http://(.*) Location:\ https://\1', + # NOTE(jaosorior): We always redirect to https for the public_virtual_ip. + 'redirect' => 'scheme https code 301 if !{ ssl_fc }', + 'option' => [ 'forwardfor', 'httpchk' ], + 'http-request' => [ + 'set-header X-Forwarded-Proto https if { ssl_fc }', + 'set-header X-Forwarded-Proto http if !{ ssl_fc }'], + } + } else { + $horizon_bind_opts = { + "${internal_ip}:80" => $haproxy_listen_bind_param, + "${public_virtual_ip}:80" => $haproxy_listen_bind_param, + } + $horizon_options = { + 'cookie' => 'SERVERID insert indirect nocache', + 'option' => [ 'forwardfor', 'httpchk' ], + } + } + + if $use_internal_certificates { + # Use SSL port if TLS in the internal network is enabled. + $backend_port = '443' + } else { + $backend_port = '80' + } + + haproxy::listen { 'horizon': + bind => $horizon_bind_opts, + options => $horizon_options, + mode => 'http', + collect_exported => false, + } + haproxy::balancermember { 'horizon': + listening_service => 'horizon', + ports => $backend_port, + ipaddresses => $ip_addresses, + server_names => $server_names, + options => union($member_options, ["cookie ${::hostname}"]), + } +} |