Allow custom per-service listen_options for haproxy

There are situations where it would be advantageous to let
an operator specify custom per-service options.
One such use case seen in the wild is to extend the timeout of the cinder
because due to the specific storage backend these cinder operations
sometimes take a bit longer. Letting the user tweak the
haproxy_default_timeout is likely not what we want as for the case
above we only want to tweak a single service.

We explored another approach to fix this by adding a bunch of
<service>_options class parameters in the tripleo::haproxy class but it
made it extremely bloated and confusing, so we opted for this approach
which is much less invasive both code-wise and complexity-wise

Tested by deploying with:
ExtraConfig:
  tripleo::haproxy::cinder::options:
    "timeout client": '90m'
    'timeout server': '90m'

And observing the following cinder haproxy stanza:
listen cinder
  bind 10.0.0.4:8776 transparent
  bind 172.16.2.9:8776 transparent
  mode http
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
  option httpchk
  option httplog
  timeout client 90m
  timeout server 90m
  server overcloud-controller-0.internalapi.localdomain 172.16.2.7:8776 check fall 5 inter 2000 rise 2
  server overcloud-controller-1.internalapi.localdomain 172.16.2.16:8776 check fall 5 inter 2000 rise 2
  server overcloud-controller-2.internalapi.localdomain 172.16.2.13:8776 check fall 5 inter 2000 rise 2

Closes-Bug: #1755711

Change-Id: Icb7f026190b310d34c47dc059e2fdb22031b0963
This commit is contained in:
Michele Baldessari 2018-03-14 08:31:40 +01:00
parent 0f70e273d2
commit ce4576375d
5 changed files with 34 additions and 12 deletions

View File

@ -118,6 +118,8 @@ define tripleo::haproxy::endpoint (
$manage_firewall = hiera('tripleo::firewall::manage_firewall', true),
$authorized_userlist = undef,
) {
# Let users override the options on a per-service basis
$custom_options = hiera("tripleo::haproxy::${name}::options", undef)
if $public_virtual_ip {
# service exposed to the public network
@ -128,20 +130,20 @@ define tripleo::haproxy::endpoint (
'redirect' => "scheme https code 301 if { hdr(host) -i ${public_virtual_ip} } !{ ssl_fc }",
'option' => 'forwardfor',
}
$listen_options_real = merge($tls_listen_options, $listen_options)
$listen_options_real = merge($tls_listen_options, $listen_options, $custom_options)
} else {
$listen_options_real = $listen_options
$listen_options_real = merge($listen_options, $custom_options)
}
$public_bind_opts = list_to_hash(suffix(any2array($public_virtual_ip), ":${public_ssl_port}"),
union($haproxy_listen_bind_param, ['ssl', 'crt', $public_certificate]))
} else {
$listen_options_real = $listen_options
$listen_options_real = merge($listen_options, $custom_options)
$public_bind_opts = list_to_hash(suffix(any2array($public_virtual_ip), ":${service_port}"), $haproxy_listen_bind_param)
}
} else {
# internal service only
$public_bind_opts = {}
$listen_options_real = $listen_options
$listen_options_real = merge($listen_options, $custom_options)
}
if $use_internal_certificates {

View File

@ -78,6 +78,8 @@ class tripleo::haproxy::horizon_endpoint (
$internal_certificates_specs = {},
$service_network = undef,
) {
# Let users override the options on a per-service basis
$custom_options = hiera('tripleo::haproxy::horizon::options', undef)
# service exposed to the public network
if $public_certificate {
if $use_internal_certificates {
@ -110,7 +112,7 @@ class tripleo::haproxy::horizon_endpoint (
"${public_virtual_ip}:80" => $haproxy_listen_bind_param,
"${public_virtual_ip}:443" => union($haproxy_listen_bind_param, ['ssl', 'crt', $public_certificate]),
}
$horizon_options = {
$horizon_options = merge({
'cookie' => 'SERVERID insert indirect nocache',
'rsprep' => '^Location:\ http://(.*) Location:\ https://\1',
# NOTE(jaosorior): We always redirect to https for the public_virtual_ip.
@ -119,16 +121,16 @@ class tripleo::haproxy::horizon_endpoint (
'http-request' => [
'set-header X-Forwarded-Proto https if { ssl_fc }',
'set-header X-Forwarded-Proto http if !{ ssl_fc }'],
}
}, $custom_options)
} else {
$horizon_bind_opts = {
"${internal_ip}:80" => $haproxy_listen_bind_param,
"${public_virtual_ip}:80" => $haproxy_listen_bind_param,
}
$horizon_options = {
$horizon_options = merge({
'cookie' => 'SERVERID insert indirect nocache',
'option' => [ 'forwardfor', 'httpchk' ],
}
}, $custom_options)
}
if $use_internal_certificates {

View File

@ -0,0 +1,9 @@
---
features:
- |
Add support via hiera keys like 'tripleo::haproxy::${name}::listen_options' to
customize the options of an haproxy service stanza. For example passing the by setting
the 'tripleo::haproxy::cinder::options' hiera key to a hash made composed of:
'timeout client': '90m'
'timeout server': '90m'

View File

@ -29,7 +29,10 @@ describe 'tripleo::haproxy::endpoint' do
['10.0.0.1:9696', ['transparent']],
['192.168.0.1:9696', ['transparent']]
],
:options => {'option' => []},
:options => {'option' => [],
'timeout client' => '90m',
'timeout server' => '90m',
},
)
end
end
@ -67,9 +70,11 @@ describe 'tripleo::haproxy::endpoint' do
is_expected.to compile.with_all_deps
is_expected.to contain_haproxy__listen('neutron').with(
:options => {
'option' => [],
'acl' => 'acl Authneutron http_auth(starwars)',
'http-request' => 'auth realm neutron if !Authneutron',
'option' => [],
'timeout client' => '90m',
'timeout server' => '90m',
'acl' => 'acl Authneutron http_auth(starwars)',
'http-request' => 'auth realm neutron if !Authneutron',
}
)
end

View File

@ -89,6 +89,10 @@ tripleo::dynamic_stuff::haproxy_endpoints:
public_ssl_port: 19696
member_options: [ 'check', 'inter 2000', 'rise 2', 'fall 5' ]
haproxy_listen_bind_param: ['transparent']
tripleo::haproxy::neutron::options:
'timeout client': '90m'
'timeout server': '90m'
tripleo::haproxy_basic_auth::haproxy_endpoints:
starwars:
public_virtual_ip: '192.168.0.1'