From ce4576375df1e49442e87ce26b8be436bd00b899 Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Wed, 14 Mar 2018 08:31:40 +0100 Subject: [PATCH] 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 _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 --- manifests/haproxy/endpoint.pp | 10 ++++++---- manifests/haproxy/horizon_endpoint.pp | 10 ++++++---- ...er-service-options-haproxy-75f5f00cf5243ecb.yaml | 9 +++++++++ spec/defines/tripleo_haproxy_endpoint_spec.rb | 13 +++++++++---- spec/fixtures/hieradata/default.yaml | 4 ++++ 5 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 releasenotes/notes/per-service-options-haproxy-75f5f00cf5243ecb.yaml diff --git a/manifests/haproxy/endpoint.pp b/manifests/haproxy/endpoint.pp index b90447304..8c6023ecd 100644 --- a/manifests/haproxy/endpoint.pp +++ b/manifests/haproxy/endpoint.pp @@ -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 { diff --git a/manifests/haproxy/horizon_endpoint.pp b/manifests/haproxy/horizon_endpoint.pp index 1e6e73bb6..82790f9f1 100644 --- a/manifests/haproxy/horizon_endpoint.pp +++ b/manifests/haproxy/horizon_endpoint.pp @@ -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 { diff --git a/releasenotes/notes/per-service-options-haproxy-75f5f00cf5243ecb.yaml b/releasenotes/notes/per-service-options-haproxy-75f5f00cf5243ecb.yaml new file mode 100644 index 000000000..fec8210ab --- /dev/null +++ b/releasenotes/notes/per-service-options-haproxy-75f5f00cf5243ecb.yaml @@ -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' + diff --git a/spec/defines/tripleo_haproxy_endpoint_spec.rb b/spec/defines/tripleo_haproxy_endpoint_spec.rb index e072fc67d..d608e3936 100644 --- a/spec/defines/tripleo_haproxy_endpoint_spec.rb +++ b/spec/defines/tripleo_haproxy_endpoint_spec.rb @@ -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 diff --git a/spec/fixtures/hieradata/default.yaml b/spec/fixtures/hieradata/default.yaml index 1a6c88b3f..c309c0de3 100644 --- a/spec/fixtures/hieradata/default.yaml +++ b/spec/fixtures/hieradata/default.yaml @@ -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'