diff --git a/lib/puppet/functions/merge_hash_values.rb b/lib/puppet/functions/merge_hash_values.rb new file mode 100644 index 000000000..7d332d362 --- /dev/null +++ b/lib/puppet/functions/merge_hash_values.rb @@ -0,0 +1,30 @@ +# This function merges two hashes and concatenate the values of +# identical keys +# +# Example: +# $frontend = { 'option' => [ 'tcpka', 'tcplog' ], +# 'timeout client' => '90m' } +# $backend = { 'option' => [ 'httpchk' ], +# 'timeout server' => '90m' } +# +# Using this function: +# $merge = merge_hash_values($frontend, $backend) +# +# Would return: +# $merge = { 'option' => [ 'tcpka', 'tcplog', 'httpchk' ], +# 'timeout client' => '90m', +# 'timeout server' => '90m' } +# + +Puppet::Functions.create_function(:'merge_hash_values') do + dispatch :merge_hash_values do + param 'Hash', :hash1 + param 'Hash', :hash2 + return_type 'Hash' + end + + def merge_hash_values(hash1, hash2) + hh = hash1.merge(hash2) {|k, v1, v2| (v2 + v1).uniq()} + return hh + end +end diff --git a/manifests/haproxy.pp b/manifests/haproxy.pp index 261ff0de6..c4d087e56 100644 --- a/manifests/haproxy.pp +++ b/manifests/haproxy.pp @@ -108,6 +108,11 @@ # Can be a string or an array. # Defaults to undef # +# [*use_backend_syntax*] +# (optional) When set to true, generate a config with frontend and +# backend sections, otherwise use listen sections. +# Defaults to hiera('haproxy_backend_syntax', false) +# # [*haproxy_stats_user*] # Username for haproxy stats authentication. # A string. @@ -296,6 +301,14 @@ # Hash to pass to the mysql haproxy listen stanza to be deepmerged with the other options # Defaults to {} # +# [*mysql_custom_frontend_options*] +# Hash to pass to the mysql haproxy frontend stanza to be deepmerged with the other options +# Defaults to {} +# +# [*mysql_custom_backend_options*] +# Hash to pass to the mysql haproxy backend stanza to be deepmerged with the other options +# Defaults to {} +# # [*rabbitmq*] # (optional) Enable or not RabbitMQ binding # Defaults to false @@ -544,110 +557,113 @@ class tripleo::haproxy ( $controller_virtual_ip, $public_virtual_ip, - $haproxy_service_manage = true, - $haproxy_global_maxconn = 20480, - $haproxy_default_maxconn = 4096, - $haproxy_default_timeout = [ 'http-request 10s', 'queue 2m', 'connect 10s', 'client 2m', 'server 2m', 'check 10s' ], - $haproxy_listen_bind_param = [ 'transparent' ], - $haproxy_member_options = [ 'check', 'inter 2000', 'rise 2', 'fall 5' ], - $haproxy_log_address = '/dev/log', - $haproxy_log_facility = 'local0', - $activate_httplog = false, - $haproxy_globals_override = {}, - $haproxy_defaults_override = {}, - $haproxy_lb_mode_longrunning = 'leastconn', - $haproxy_daemon = true, - $haproxy_socket_access_level = 'user', - $haproxy_stats_user = 'admin', - $haproxy_stats_password = undef, - $haproxy_stats_bind_address = undef, - $manage_firewall = hiera('tripleo::firewall::manage_firewall', true), - $controller_hosts = hiera('controller_node_ips'), - $controller_hosts_names = hiera('controller_node_names', undef), - $service_certificate = undef, - $use_internal_certificates = false, - $internal_certificates_specs = {}, - $enable_internal_tls = hiera('enable_internal_tls', false), - $ssl_cipher_suite = '!SSLv2:kEECDH:kRSA:kEDH:kPSK:+3DES:!aNULL:!eNULL:!MD5:!EXP:!RC4:!SEED:!IDEA:!DES', - $ssl_options = 'no-sslv3 no-tlsv10', - $ca_bundle = '/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt', - $crl_file = undef, - $haproxy_stats_certificate = undef, - $haproxy_stats = true, - $keystone_admin = hiera('keystone_enabled', false), - $keystone_public = hiera('keystone_enabled', false), - $neutron = hiera('neutron_api_enabled', false), - $cinder = hiera('cinder_api_enabled', false), - $manila = hiera('manila_api_enabled', false), - $glance_api = hiera('glance_api_enabled', false), - $nova_osapi = hiera('nova_api_enabled', false), - $placement = hiera('placement_enabled', false), - $nova_metadata = hiera('nova_metadata_enabled', false), - $nova_novncproxy = hiera('nova_vnc_proxy_enabled', false), - $aodh = hiera('aodh_api_enabled', false), - $barbican = hiera('barbican_api_enabled', false), - $ceph_grafana = hiera('ceph_grafana_enabled', false), - $ceph_dashboard = hiera('ceph_grafana_enabled', false), - $gnocchi = hiera('gnocchi_api_enabled', false), - $mistral = hiera('mistral_api_enabled', false), - $swift_proxy_server = hiera('swift_proxy_enabled', false), - $heat_api = hiera('heat_api_enabled', false), - $heat_cfn = hiera('heat_api_cfn_enabled', false), - $horizon = hiera('horizon_enabled', false), - $ironic = hiera('ironic_api_enabled', false), - $ironic_inspector = hiera('ironic_inspector_enabled', false), - $octavia = hiera('octavia_api_enabled', false), - $designate = hiera('designate_api_enabled', false), - $metrics_qdr = hiera('metrics_qdr_enabled', false), - $mysql = hiera('mysql_enabled', false), - $mysql_clustercheck = false, - $mysql_max_conn = undef, - $mysql_member_options = undef, - $mysql_custom_listen_options = {}, - $rabbitmq = false, - $etcd = hiera('etcd_enabled', false), - $docker_registry = hiera('enable_docker_registry', false), - $redis = hiera('redis_enabled', false), - $redis_password = undef, - $zaqar_api = hiera('zaqar_api_enabled', false), - $ceph_rgw = hiera('ceph_rgw_enabled', false), - $ovn_dbs = hiera('ovn_dbs_enabled', false), - $ovn_dbs_manage_lb = false, - $zaqar_ws = hiera('zaqar_api_enabled', false), - $aodh_network = hiera('aodh_api_network', undef), - $barbican_network = hiera('barbican_api_network', false), - $ceph_rgw_network = hiera('ceph_rgw_network', undef), - $cinder_network = hiera('cinder_api_network', undef), - $designate_network = hiera('designate_api_network', undef), - $metrics_qdr_network = hiera('metrics_qdr_network', undef), - $docker_registry_network = hiera('docker_registry_network', undef), - $glance_api_network = hiera('glance_api_network', undef), - $gnocchi_network = hiera('gnocchi_api_network', undef), - $heat_api_network = hiera('heat_api_network', undef), - $ceph_grafana_network = hiera('ceph_grafana_network', undef), - $ceph_dashboard_network = hiera('ceph_dashboard_network', undef), - $heat_cfn_network = hiera('heat_api_cfn_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), - $keystone_public_network = hiera('keystone_public_api_network', undef), - $keystone_sticky_sessions = hiera('keystone_sticky_sessions', false), - $keystone_session_cookie = hiera('keystone_session_cookie,', 'KEYSTONESESSION'), - $manila_network = hiera('manila_api_network', undef), - $mistral_network = hiera('mistral_api_network', undef), - $neutron_network = hiera('neutron_api_network', undef), - $nova_metadata_network = hiera('nova_metadata_network', undef), - $nova_novncproxy_network = hiera('nova_vnc_proxy_network', hiera('nova_libvirt_network', undef)), - $nova_osapi_network = hiera('nova_api_network', undef), - $placement_network = hiera('placement_network', undef), - $octavia_network = hiera('octavia_api_network', undef), - $ovn_dbs_network = hiera('ovn_dbs_network', undef), - $etcd_network = hiera('etcd_network', undef), - $swift_proxy_server_network = hiera('swift_proxy_network', undef), - $zaqar_api_network = hiera('zaqar_api_network', undef), - $zaqar_ws_timeout_tunnel = hiera('zaqar_ws_timeout_tunnel', '14400'), - $service_ports = {} + $use_backend_syntax = hiera('haproxy_backend_syntax', false), + $haproxy_service_manage = true, + $haproxy_global_maxconn = 20480, + $haproxy_default_maxconn = 4096, + $haproxy_default_timeout = [ 'http-request 10s', 'queue 2m', 'connect 10s', 'client 2m', 'server 2m', 'check 10s' ], + $haproxy_listen_bind_param = [ 'transparent' ], + $haproxy_member_options = [ 'check', 'inter 2000', 'rise 2', 'fall 5' ], + $haproxy_log_address = '/dev/log', + $haproxy_log_facility = 'local0', + $activate_httplog = false, + $haproxy_globals_override = {}, + $haproxy_defaults_override = {}, + $haproxy_lb_mode_longrunning = 'leastconn', + $haproxy_daemon = true, + $haproxy_socket_access_level = 'user', + $haproxy_stats_user = 'admin', + $haproxy_stats_password = undef, + $haproxy_stats_bind_address = undef, + $manage_firewall = hiera('tripleo::firewall::manage_firewall', true), + $controller_hosts = hiera('controller_node_ips'), + $controller_hosts_names = hiera('controller_node_names', undef), + $service_certificate = undef, + $use_internal_certificates = false, + $internal_certificates_specs = {}, + $enable_internal_tls = hiera('enable_internal_tls', false), + $ssl_cipher_suite = '!SSLv2:kEECDH:kRSA:kEDH:kPSK:+3DES:!aNULL:!eNULL:!MD5:!EXP:!RC4:!SEED:!IDEA:!DES', + $ssl_options = 'no-sslv3 no-tlsv10', + $ca_bundle = '/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt', + $crl_file = undef, + $haproxy_stats_certificate = undef, + $haproxy_stats = true, + $keystone_admin = hiera('keystone_enabled', false), + $keystone_public = hiera('keystone_enabled', false), + $neutron = hiera('neutron_api_enabled', false), + $cinder = hiera('cinder_api_enabled', false), + $manila = hiera('manila_api_enabled', false), + $glance_api = hiera('glance_api_enabled', false), + $nova_osapi = hiera('nova_api_enabled', false), + $placement = hiera('placement_enabled', false), + $nova_metadata = hiera('nova_metadata_enabled', false), + $nova_novncproxy = hiera('nova_vnc_proxy_enabled', false), + $aodh = hiera('aodh_api_enabled', false), + $barbican = hiera('barbican_api_enabled', false), + $ceph_grafana = hiera('ceph_grafana_enabled', false), + $ceph_dashboard = hiera('ceph_grafana_enabled', false), + $gnocchi = hiera('gnocchi_api_enabled', false), + $mistral = hiera('mistral_api_enabled', false), + $swift_proxy_server = hiera('swift_proxy_enabled', false), + $heat_api = hiera('heat_api_enabled', false), + $heat_cfn = hiera('heat_api_cfn_enabled', false), + $horizon = hiera('horizon_enabled', false), + $ironic = hiera('ironic_api_enabled', false), + $ironic_inspector = hiera('ironic_inspector_enabled', false), + $octavia = hiera('octavia_api_enabled', false), + $designate = hiera('designate_api_enabled', false), + $metrics_qdr = hiera('metrics_qdr_enabled', false), + $mysql = hiera('mysql_enabled', false), + $mysql_clustercheck = false, + $mysql_max_conn = undef, + $mysql_member_options = undef, + $mysql_custom_listen_options = {}, + $mysql_custom_frontend_options = {}, + $mysql_custom_backend_options = {}, + $rabbitmq = false, + $etcd = hiera('etcd_enabled', false), + $docker_registry = hiera('enable_docker_registry', false), + $redis = hiera('redis_enabled', false), + $redis_password = undef, + $zaqar_api = hiera('zaqar_api_enabled', false), + $ceph_rgw = hiera('ceph_rgw_enabled', false), + $ovn_dbs = hiera('ovn_dbs_enabled', false), + $ovn_dbs_manage_lb = false, + $zaqar_ws = hiera('zaqar_api_enabled', false), + $aodh_network = hiera('aodh_api_network', undef), + $barbican_network = hiera('barbican_api_network', false), + $ceph_rgw_network = hiera('ceph_rgw_network', undef), + $cinder_network = hiera('cinder_api_network', undef), + $designate_network = hiera('designate_api_network', undef), + $metrics_qdr_network = hiera('metrics_qdr_network', undef), + $docker_registry_network = hiera('docker_registry_network', undef), + $glance_api_network = hiera('glance_api_network', undef), + $gnocchi_network = hiera('gnocchi_api_network', undef), + $heat_api_network = hiera('heat_api_network', undef), + $ceph_grafana_network = hiera('ceph_grafana_network', undef), + $ceph_dashboard_network = hiera('ceph_dashboard_network', undef), + $heat_cfn_network = hiera('heat_api_cfn_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), + $keystone_public_network = hiera('keystone_public_api_network', undef), + $keystone_sticky_sessions = hiera('keystone_sticky_sessions', false), + $keystone_session_cookie = hiera('keystone_session_cookie,', 'KEYSTONESESSION'), + $manila_network = hiera('manila_api_network', undef), + $mistral_network = hiera('mistral_api_network', undef), + $neutron_network = hiera('neutron_api_network', undef), + $nova_metadata_network = hiera('nova_metadata_network', undef), + $nova_novncproxy_network = hiera('nova_vnc_proxy_network', hiera('nova_libvirt_network', undef)), + $nova_osapi_network = hiera('nova_api_network', undef), + $placement_network = hiera('placement_network', undef), + $octavia_network = hiera('octavia_api_network', undef), + $ovn_dbs_network = hiera('ovn_dbs_network', undef), + $etcd_network = hiera('etcd_network', undef), + $swift_proxy_server_network = hiera('swift_proxy_network', undef), + $zaqar_api_network = hiera('zaqar_api_network', undef), + $zaqar_ws_timeout_tunnel = hiera('zaqar_ws_timeout_tunnel', '14400'), + $service_ports = {} ) { $default_service_ports = { aodh_api_port => 8042, @@ -789,13 +805,18 @@ class tripleo::haproxy ( } - $default_listen_options = { - 'option' => [ 'httpchk', 'httplog', ], + $default_frontend_options = { + 'option' => [ 'httplog', ], 'http-request' => [ 'set-header X-Forwarded-Proto https if { ssl_fc }', 'set-header X-Forwarded-Proto http if !{ ssl_fc }', 'set-header X-Forwarded-Port %[dst_port]'], } + $default_backend_options = { + 'option' => [ 'httpchk' ], + } + $default_listen_options = merge_hash_values($default_frontend_options, + $default_backend_options) Tripleo::Haproxy::Endpoint { haproxy_listen_bind_param => $haproxy_listen_bind_param, member_options => $haproxy_member_options, @@ -803,6 +824,8 @@ class tripleo::haproxy ( use_internal_certificates => $use_internal_certificates, internal_certificates_specs => $internal_certificates_specs, listen_options => $default_listen_options, + frontend_options => $default_frontend_options, + backend_options => $default_backend_options, manage_firewall => $manage_firewall, } @@ -830,23 +853,30 @@ class tripleo::haproxy ( } } - $keystone_listen_opts = { - 'option' => [ 'httpchk GET /healthcheck', 'httplog' ] + $keystone_frontend_opts = { + 'option' => [ 'httplog' ] } + $keystone_backend_opts = { + 'option' => [ 'httpchk GET /healthcheck' ] + } + $keystone_listen_opts = merge_hash_values($keystone_frontend_opts, + $keystone_backend_opts) if $keystone_admin { # NOTE(jaosorior): Given that the admin endpoint is in the same vhost # nowadays as the public/internal one. We can just loadbalance towards the # same IP. ::tripleo::haproxy::endpoint { 'keystone_admin': - internal_ip => hiera('keystone_admin_api_vip', $controller_virtual_ip), - service_port => $ports[keystone_public_api_port], - haproxy_port => $ports[keystone_admin_api_port], - ip_addresses => hiera('keystone_public_api_node_ips', $controller_hosts_real), - server_names => hiera('keystone_public_api_node_names', $controller_hosts_names_real), - mode => 'http', - listen_options => merge($default_listen_options, $keystone_listen_opts), - service_network => $keystone_admin_network, - member_options => union($haproxy_member_options, $internal_tls_member_options), + internal_ip => hiera('keystone_admin_api_vip', $controller_virtual_ip), + service_port => $ports[keystone_public_api_port], + haproxy_port => $ports[keystone_admin_api_port], + ip_addresses => hiera('keystone_public_api_node_ips', $controller_hosts_real), + server_names => hiera('keystone_public_api_node_names', $controller_hosts_names_real), + mode => 'http', + listen_options => merge($default_listen_options, $keystone_listen_opts), + frontend_options => merge($default_frontend_options, $keystone_frontend_opts), + backend_options => merge($default_backend_options, $keystone_backend_opts), + service_network => $keystone_admin_network, + member_options => union($haproxy_member_options, $internal_tls_member_options), } } @@ -859,6 +889,8 @@ class tripleo::haproxy ( server_names => hiera('keystone_public_api_node_names', $controller_hosts_names_real), mode => 'http', listen_options => merge($default_listen_options, $keystone_listen_opts), + frontend_options => merge($default_frontend_options, $keystone_frontend_opts), + backend_options => $keystone_backend_opts, public_ssl_port => $ports[keystone_public_api_ssl_port], service_network => $keystone_public_network, sticky_sessions => $keystone_sticky_sessions, @@ -868,10 +900,15 @@ class tripleo::haproxy ( } if $neutron { - $neutron_listen_opts = { - 'balance' => $haproxy_lb_mode_longrunning, - 'option' => [ 'httpchk GET /healthcheck', 'httplog' ] + $neutron_frontend_opts = { + 'option' => [ 'httplog' ] } + $neutron_backend_opts = { + 'balance' => $haproxy_lb_mode_longrunning, + 'option' => [ 'httpchk GET /healthcheck' ] + } + $neutron_listen_opts = merge_hash_values($neutron_frontend_opts, + $neutron_backend_opts) ::tripleo::haproxy::endpoint { 'neutron': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('neutron_api_vip', $controller_virtual_ip), @@ -880,6 +917,8 @@ class tripleo::haproxy ( server_names => hiera('neutron_api_node_names', $controller_hosts_names_real), mode => 'http', listen_options => merge($default_listen_options, $neutron_listen_opts), + frontend_options => merge($default_frontend_options, $neutron_frontend_opts), + backend_options => merge($default_backend_options, $neutron_backend_opts), public_ssl_port => $ports[neutron_api_ssl_port], service_network => $neutron_network, member_options => union($haproxy_member_options, $internal_tls_member_options), @@ -887,10 +926,15 @@ class tripleo::haproxy ( } if $cinder { - $cinder_listen_opts = { - 'balance' => $haproxy_lb_mode_longrunning, - 'option' => [ 'httpchk GET /healthcheck', 'httplog' ] + $cinder_frontend_opts = { + 'option' => [ 'httplog' ], } + $cinder_backend_opts = { + 'option' => [ 'httpchk GET /healthcheck' ], + 'balance' => $haproxy_lb_mode_longrunning, + } + $cinder_listen_opts = merge_hash_values($cinder_frontend_opts, + $cinder_backend_opts) ::tripleo::haproxy::endpoint { 'cinder': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('cinder_api_vip', $controller_virtual_ip), @@ -899,6 +943,8 @@ class tripleo::haproxy ( server_names => hiera('cinder_api_node_names', $controller_hosts_names_real), mode => 'http', listen_options => merge($default_listen_options, $cinder_listen_opts), + frontend_options => merge($default_frontend_options, $cinder_frontend_opts), + backend_options => merge($default_backend_options, $cinder_backend_opts), public_ssl_port => $ports[cinder_api_ssl_port], service_network => $cinder_network, member_options => union($haproxy_member_options, $internal_tls_member_options), @@ -906,9 +952,14 @@ class tripleo::haproxy ( } if $manila { - $manila_listen_opts = { - 'option' => [ 'httpchk GET /healthcheck', 'httplog' ], + $manila_frontend_opts = { + 'option' => [ 'httplog' ], } + $manila_backend_opts = { + 'option' => [ 'httpchk GET /healthcheck' ], + } + $manila_listen_opts = merge_hash_values($manila_frontend_opts, + $manila_backend_opts) ::tripleo::haproxy::endpoint { 'manila': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('manila_api_vip', $controller_virtual_ip), @@ -917,6 +968,8 @@ class tripleo::haproxy ( server_names => hiera('manila_api_node_names', $controller_hosts_names_real), mode => 'http', listen_options => merge($default_listen_options, $manila_listen_opts), + frontend_options => merge($default_frontend_options, $manila_frontend_opts), + backend_options => merge($default_backend_options, $manila_backend_opts), public_ssl_port => $ports[manila_api_ssl_port], service_network => $manila_network, member_options => union($haproxy_member_options, $internal_tls_member_options), @@ -924,9 +977,14 @@ class tripleo::haproxy ( } if $glance_api { - $glance_listen_opts = { - 'option' => [ 'httpchk GET /healthcheck', 'httplog' ], + $glance_frontend_opts = { + 'option' => [ 'httplog' ], } + $glance_backend_opts = { + 'option' => [ 'httpchk GET /healthcheck' ], + } + $glance_listen_opts = merge_hash_values($glance_frontend_opts, + $glance_backend_opts) ::tripleo::haproxy::endpoint { 'glance_api': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('glance_api_vip', $controller_virtual_ip), @@ -936,6 +994,8 @@ class tripleo::haproxy ( public_ssl_port => $ports[glance_api_ssl_port], mode => 'http', listen_options => merge($default_listen_options, $glance_listen_opts), + frontend_options => merge($default_frontend_options, $glance_frontend_opts), + backend_options => merge($default_backend_options, $glance_backend_opts), service_network => $glance_api_network, member_options => union($haproxy_member_options, $internal_tls_member_options), } @@ -943,46 +1003,61 @@ class tripleo::haproxy ( if $ceph_grafana { ::tripleo::haproxy::endpoint { 'ceph_grafana': - internal_ip => hiera('ceph_dashboard_vip', $controller_virtual_ip), - service_port => $ports[ceph_grafana_port], - ip_addresses => hiera('ceph_grafana_node_ips', $controller_hosts_real), - server_names => hiera('ceph_grafana_node_names', $controller_hosts_names_real), - mode => 'http', - public_ssl_port => $ports[ceph_grafana_ssl_port], - listen_options => merge($default_listen_options, { + internal_ip => hiera('ceph_dashboard_vip', $controller_virtual_ip), + service_port => $ports[ceph_grafana_port], + ip_addresses => hiera('ceph_grafana_node_ips', $controller_hosts_real), + server_names => hiera('ceph_grafana_node_names', $controller_hosts_names_real), + mode => 'http', + public_ssl_port => $ports[ceph_grafana_ssl_port], + listen_options => merge($default_listen_options, { 'option' => [ 'httpchk HEAD /', 'httplog' ], 'balance' => 'source', }), - service_network => $ceph_grafana_network, - member_options => union($haproxy_member_options, $internal_tls_member_options), + frontend_options => $default_frontend_options, + backend_options => merge($default_backend_options, { + 'option' => [ 'httpchk HEAD /' ], + 'balance' => 'source', + }), + service_network => $ceph_grafana_network, + member_options => union($haproxy_member_options, $internal_tls_member_options), } ::tripleo::haproxy::endpoint { 'ceph_prometheus': - internal_ip => hiera('ceph_grafana_vip', $controller_virtual_ip), - service_port => $ports[ceph_prometheus_port], - ip_addresses => hiera('ceph_grafana_node_ips', $controller_hosts_real), - server_names => hiera('ceph_grafana_node_names', $controller_hosts_names_real), - mode => 'http', - public_ssl_port => $ports[ceph_prometheus_ssl_port], - listen_options => merge($default_listen_options, { + internal_ip => hiera('ceph_grafana_vip', $controller_virtual_ip), + service_port => $ports[ceph_prometheus_port], + ip_addresses => hiera('ceph_grafana_node_ips', $controller_hosts_real), + server_names => hiera('ceph_grafana_node_names', $controller_hosts_names_real), + mode => 'http', + public_ssl_port => $ports[ceph_prometheus_ssl_port], + listen_options => merge($default_listen_options, { 'option' => [ 'httpchk GET /metrics', 'httplog' ], 'balance' => 'source', }), - service_network => $ceph_grafana_network, - member_options => $haproxy_member_options, + frontend_options => $default_frontend_options, + backend_options => merge($default_backend_options, { + 'option' => [ 'httpchk GET /metrics' ], + 'balance' => 'source', + }), + service_network => $ceph_grafana_network, + member_options => $haproxy_member_options, } ::tripleo::haproxy::endpoint { 'ceph_alertmanager': - internal_ip => hiera('ceph_grafana_vip', $controller_virtual_ip), - service_port => $ports[ceph_alertmanager_port], - ip_addresses => hiera('ceph_grafana_node_ips', $controller_hosts_real), - server_names => hiera('ceph_grafana_node_names', $controller_hosts_names_real), - mode => 'http', - public_ssl_port => $ports[ceph_alertmanager_ssl_port], - listen_options => merge($default_listen_options, { + internal_ip => hiera('ceph_grafana_vip', $controller_virtual_ip), + service_port => $ports[ceph_alertmanager_port], + ip_addresses => hiera('ceph_grafana_node_ips', $controller_hosts_real), + server_names => hiera('ceph_grafana_node_names', $controller_hosts_names_real), + mode => 'http', + public_ssl_port => $ports[ceph_alertmanager_ssl_port], + listen_options => merge($default_listen_options, { 'option' => [ 'httpchk GET /', 'httplog' ], 'balance' => 'source', }), - service_network => $ceph_grafana_network, - member_options => $haproxy_member_options, + frontend_options => $default_frontend_options, + backend_options => merge($default_backend_options, { + 'option' => [ 'httpchk GET /' ], + 'balance' => 'source', + }), + service_network => $ceph_grafana_network, + member_options => $haproxy_member_options, } } @@ -992,20 +1067,25 @@ class tripleo::haproxy ( } else { $ceph_dashboard_tls_member_options = [] } + $ceph_dashboard_backend_opts = { + 'option' => [ 'httpchk HEAD /' ], + 'balance' => 'source', + 'http-check' => 'expect rstatus 2[0-9][0-9]', + } + $ceph_dashboard_listen_opts = merge_hash_values($default_frontend_options, + $ceph_dashboard_backend_opts) ::tripleo::haproxy::endpoint { 'ceph_dashboard': - internal_ip => hiera('ceph_dashboard_vip', $controller_virtual_ip), - service_port => $ports[ceph_dashboard_port], - ip_addresses => hiera('ceph_grafana_node_ips', $controller_hosts_real), - server_names => hiera('ceph_grafana_node_names', $controller_hosts_names_real), - mode => 'http', - public_ssl_port => $ports[ceph_dashboard_ssl_port], - listen_options => merge($default_listen_options, { - 'option' => [ 'httpchk HEAD /', 'httplog' ], - 'balance' => 'source', - 'http-check' => 'expect rstatus 2[0-9][0-9]', - }), - service_network => $ceph_dashboard_network, - member_options => union($haproxy_member_options, $ceph_dashboard_tls_member_options), + internal_ip => hiera('ceph_dashboard_vip', $controller_virtual_ip), + service_port => $ports[ceph_dashboard_port], + ip_addresses => hiera('ceph_grafana_node_ips', $controller_hosts_real), + server_names => hiera('ceph_grafana_node_names', $controller_hosts_names_real), + mode => 'http', + public_ssl_port => $ports[ceph_dashboard_ssl_port], + listen_options => merge($default_listen_options, $ceph_dashboard_listen_opts), + frontend_options => $default_frontend_options, + backend_options => merge($default_backend_options, $ceph_dashboard_backend_opts), + service_network => $ceph_dashboard_network, + member_options => union($haproxy_member_options, $ceph_dashboard_tls_member_options), } } @@ -1048,18 +1128,23 @@ class tripleo::haproxy ( } else { $nova_metadata_server_names_real = hiera('nova_metadata_node_names', $controller_hosts_names_real) } + $nova_metadata_backend_opts = { + 'balance' => 'source', + 'hash-type' => 'consistent', + } + $nova_metadata_listen_opts = merge_hash_values($default_listen_options, + $nova_metadata_backend_opts) ::tripleo::haproxy::endpoint { 'nova_metadata': - internal_ip => hiera('nova_metadata_vip', $controller_virtual_ip), - service_port => $ports[nova_metadata_port], - ip_addresses => hiera('nova_metadata_node_ips', $controller_hosts_real), - server_names => $nova_metadata_server_names_real, - mode => 'http', - service_network => $nova_metadata_network, - member_options => union($haproxy_member_options, $internal_tls_member_options), - listen_options => merge($default_listen_options, { - 'balance' => 'source', - 'hash-type' => 'consistent', - }), + internal_ip => hiera('nova_metadata_vip', $controller_virtual_ip), + service_port => $ports[nova_metadata_port], + ip_addresses => hiera('nova_metadata_node_ips', $controller_hosts_real), + server_names => $nova_metadata_server_names_real, + mode => 'http', + service_network => $nova_metadata_network, + member_options => union($haproxy_member_options, $internal_tls_member_options), + listen_options => merge($default_listen_options, $nova_metadata_listen_opts), + frontend_options => $default_frontend_options, + backend_options => merge($default_backend_options, $nova_metadata_backend_opts), } } @@ -1079,6 +1164,15 @@ class tripleo::haproxy ( } else { $novncproxy_server_names_real = hiera('nova_vnc_proxy_node_names', $controller_hosts_names_real) } + $nova_vncproxy_frontend_opts = { + 'option' => [ 'tcpka', 'tcplog' ], + } + $nova_vncproxy_backend_opts = { + 'balance' => 'source', + 'timeout' => [ 'tunnel 1h' ], + } + $nova_vncproxy_listen_opts = merge_hash_values($nova_vncproxy_frontend_opts, + $nova_vncproxy_backend_opts) ::tripleo::haproxy::endpoint { 'nova_novncproxy': public_virtual_ip => $public_virtual_ip, internal_ip => $nova_vnc_proxy_vip, @@ -1086,11 +1180,9 @@ class tripleo::haproxy ( ip_addresses => hiera('nova_vnc_proxy_node_ips', $controller_hosts_real), server_names => $novncproxy_server_names_real, mode => 'http', - listen_options => merge($default_listen_options, { - 'option' => [ 'tcpka', 'tcplog' ], - 'balance' => 'source', - 'timeout' => [ 'tunnel 1h' ], - }), + listen_options => merge($default_listen_options, $nova_vncproxy_listen_opts), + frontend_options => merge($default_frontend_options, $nova_vncproxy_frontend_opts), + backend_options => merge($default_backend_options, $nova_vncproxy_backend_opts), public_ssl_port => $ports[nova_novnc_ssl_port], service_network => $nova_novncproxy_network, member_options => union($haproxy_member_options_real, $internal_tls_member_options, $novncproxy_ssl_member_options), @@ -1098,9 +1190,14 @@ class tripleo::haproxy ( } if $aodh { - $aodh_listen_opts = { - 'option' => [ 'httpchk GET /healthcheck', 'httplog' ], + $aodh_frontend_opts = { + 'option' => [ 'httplog' ], } + $aodh_backend_opts = { + 'option' => [ 'httpchk GET /healthcheck' ], + } + $aodh_listen_opts = merge_hash_values($aodh_frontend_opts, + $aodh_backend_opts) ::tripleo::haproxy::endpoint { 'aodh': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('aodh_api_vip', $controller_virtual_ip), @@ -1109,6 +1206,8 @@ class tripleo::haproxy ( server_names => hiera('aodh_api_node_names', $controller_hosts_names_real), mode => 'http', listen_options => merge($default_listen_options, $aodh_listen_opts), + frontend_options => merge($default_frontend_options, $aodh_frontend_opts), + backend_options => merge($default_backend_options, $aodh_backend_opts), public_ssl_port => $ports[aodh_api_ssl_port], service_network => $aodh_network, member_options => union($haproxy_member_options, $internal_tls_member_options), @@ -1116,9 +1215,14 @@ class tripleo::haproxy ( } if $barbican { - $barbican_listen_opts = { - 'option' => [ 'httpchk GET /healthcheck', 'httplog' ], + $barbican_frontend_opts = { + 'option' => [ 'httplog' ], } + $barbican_backend_opts = { + 'option' => [ 'httpchk GET /healthcheck' ], + } + $barbican_listen_opts = merge_hash_values($barbican_frontend_opts, + $barbican_backend_opts) ::tripleo::haproxy::endpoint { 'barbican': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('barbican_api_vip', $controller_virtual_ip), @@ -1129,6 +1233,8 @@ class tripleo::haproxy ( service_network => $barbican_network, mode => 'http', listen_options => merge($default_listen_options, $barbican_listen_opts), + frontend_options => merge($default_frontend_options, $barbican_frontend_opts), + backend_options => merge($default_backend_options, $barbican_backend_opts), member_options => union($haproxy_member_options, $internal_tls_member_options), } } @@ -1163,12 +1269,17 @@ class tripleo::haproxy ( } if $swift_proxy_server { - $swift_proxy_server_listen_options = { - 'option' => [ 'httpchk GET /healthcheck', 'httplog' ], - 'balance' => $haproxy_lb_mode_longrunning, + $swift_proxy_server_frontend_options = { + 'option' => [ 'httplog' ], 'timeout client' => '2m', + } + $swift_proxy_server_backend_options = { + 'option' => [ 'httpchk GET /healthcheck' ], + 'balance' => $haproxy_lb_mode_longrunning, 'timeout server' => '2m', } + $swift_proxy_server_listen_options = merge_hash_values($swift_proxy_server_frontend_options, + $swift_proxy_server_backend_options) ::tripleo::haproxy::endpoint { 'swift_proxy_server': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('swift_proxy_vip', $controller_virtual_ip), @@ -1177,6 +1288,8 @@ class tripleo::haproxy ( server_names => hiera('swift_proxy_node_names', $controller_hosts_names_real), mode => 'http', listen_options => merge($default_listen_options, $swift_proxy_server_listen_options), + frontend_options => merge($default_frontend_options, $swift_proxy_server_frontend_options), + backend_options => merge($default_backend_options, $swift_proxy_server_backend_options), public_ssl_port => $ports[swift_proxy_ssl_port], service_network => $swift_proxy_server_network, member_options => union($haproxy_member_options, $internal_tls_member_options), @@ -1197,11 +1310,14 @@ class tripleo::haproxy ( $heat_ssl_options = { 'rsprep' => "^Location:\\ http://${public_virtual_ip}(.*) Location:\\ https://${public_virtual_ip}\\1", } - $heat_options = merge($default_listen_options, $heat_ssl_options, $heat_timeout_options) + $heat_listen_options = merge($default_listen_options, $heat_ssl_options, $heat_timeout_options) + $heat_frontend_options = merge($default_frontend_options, $heat_ssl_options, $heat_timeout_options) } else { - $heat_options = merge($default_listen_options, $heat_timeout_options) + $heat_listen_options = merge($default_listen_options, $heat_timeout_options) + $heat_frontend_options = merge($default_frontend_options, $heat_timeout_options) } - $heat_options_real = merge($heat_options, $heat_durability_options) + $heat_listen_options_real = merge($heat_listen_options, $heat_durability_options) + $heat_frontend_options_real = merge($heat_frontend_options, $heat_durability_options) if $heat_api { ::tripleo::haproxy::endpoint { 'heat_api': @@ -1211,7 +1327,8 @@ class tripleo::haproxy ( ip_addresses => $heat_ip_addresses, server_names => hiera('heat_api_node_names', $controller_hosts_names_real), mode => 'http', - listen_options => $heat_options_real, + listen_options => $heat_listen_options_real, + frontend_options => $heat_frontend_options_real, public_ssl_port => $ports[heat_api_ssl_port], service_network => $heat_api_network, member_options => union($haproxy_member_options, $internal_tls_member_options), @@ -1226,7 +1343,8 @@ class tripleo::haproxy ( ip_addresses => $heat_ip_addresses, server_names => hiera('heat_api_node_names', $controller_hosts_names_real), mode => 'http', - listen_options => $heat_options_real, + listen_options => $heat_listen_options_real, + frontend_options => $heat_frontend_options_real, public_ssl_port => $ports[heat_cfn_ssl_port], service_network => $heat_cfn_network, member_options => union($haproxy_member_options, $internal_tls_member_options), @@ -1250,9 +1368,14 @@ class tripleo::haproxy ( } if $ironic { - $ironic_listen_opts = { - 'option' => [ 'httpchk GET /healthcheck', 'httplog' ], + $ironic_frontend_opts = { + 'option' => [ 'httplog' ], } + $ironic_backend_opts = { + 'option' => [ 'httpchk GET /healthcheck' ], + } + $ironic_listen_opts = merge_hash_values($ironic_frontend_opts, + $ironic_backend_opts) ::tripleo::haproxy::endpoint { 'ironic': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('ironic_api_vip', $controller_virtual_ip), @@ -1260,6 +1383,8 @@ class tripleo::haproxy ( ip_addresses => hiera('ironic_api_node_ips', $controller_hosts_real), server_names => hiera('ironic_api_node_names', $controller_hosts_names_real), mode => 'http', + frontend_options => merge($default_frontend_options, $ironic_frontend_opts), + backend_options => merge($default_backend_options, $ironic_backend_opts), listen_options => merge($default_listen_options, $ironic_listen_opts), public_ssl_port => $ports[ironic_api_ssl_port], service_network => $ironic_network, @@ -1268,6 +1393,15 @@ class tripleo::haproxy ( } if $ironic_inspector { + $ironic_inspector_frontend_opts = { + 'option' => [ 'httplog' ], + } + $ironic_inspector_backend_opts = { + 'option' => [ 'httpchk' ], + 'balance' => $haproxy_lb_mode_longrunning + } + $ironic_inspector_listen_opts = merge_hash_values($ironic_inspector_frontend_opts, + $ironic_inspector_backend_opts) # NOTE(tkajinam): Ironic-inspector doesn't provide healthcheck API ::tripleo::haproxy::endpoint { 'ironic-inspector': public_virtual_ip => $public_virtual_ip, @@ -1278,16 +1412,21 @@ class tripleo::haproxy ( public_ssl_port => $ports[ironic_inspector_ssl_port], service_network => $ironic_inspector_network, mode => 'http', - listen_options => merge($default_listen_options, { - 'balance' => $haproxy_lb_mode_longrunning - }), + listen_options => merge($default_listen_options, $ironic_inspector_listen_opts), + frontend_options => merge($default_frontend_options, $ironic_inspector_frontend_opts), + backend_options => merge($default_backend_options, $ironic_inspector_backend_opts), } } if $designate { - $designate_listen_opts = { - 'option' => [ 'httpchk GET /healthcheck', 'httplog' ], + $designate_frontend_opts = { + 'option' => [ 'httplog' ], } + $designate_backend_opts = { + 'option' => [ 'httpchk GET /healthcheck' ], + } + $designate_listen_opts = merge_hash_values($designate_frontend_opts, + $designate_backend_opts) ::tripleo::haproxy::endpoint { 'designate': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('designate_api_vip', $controller_virtual_ip), @@ -1296,6 +1435,8 @@ class tripleo::haproxy ( server_names => hiera('designate_api_node_names', $controller_hosts_names_real), mode => 'http', listen_options => merge($default_listen_options, $designate_listen_opts), + frontend_options => merge($default_frontend_options, $designate_frontend_opts), + backend_options => merge($default_backend_options, $designate_backend_opts), public_ssl_port => $ports[designate_api_ssl_port], service_network => $designate_network, } @@ -1305,13 +1446,29 @@ class tripleo::haproxy ( $metrics_bind_opts = { "${public_virtual_ip}:${ports[metrics_qdr_port]}" => $haproxy_listen_bind_param, } - haproxy::listen { 'metrics_qdr': - bind => $metrics_bind_opts, - options => { - 'option' => [ 'tcp-check', 'tcplog' ], - 'tcp-check' => ["connect port ${ports[metrics_qdr_port]}"], - }, - collect_exported => false, + if $use_backend_syntax { + haproxy::frontend { 'metrics_qdr': + bind => $metrics_bind_opts, + options => { 'default_backend' => 'metrics_qdr_be' }, + collect_exported => false, + } + haproxy::backend { 'metrics_qdr_be': + options => { + 'option' => [ 'tcp-check', 'tcplog' ], + 'tcp-check' => ["connect port ${ports[metrics_qdr_port]}"], + }, + } + $metrics_qdr_service = 'metrics_qdr_be' + } else { + haproxy::listen { 'metrics_qdr': + bind => $metrics_bind_opts, + options => { + 'option' => [ 'tcp-check', 'tcplog' ], + 'tcp-check' => ["connect port ${ports[metrics_qdr_port]}"], + }, + collect_exported => false, + } + $metrics_qdr_service = 'metrics_qdr' } # Note(mmagr): while MetricsQdr service runs on all overcloud nodes, we need load balancing # only on controllers as those are only QDRs forming mesh (listening on connection @@ -1321,7 +1478,7 @@ class tripleo::haproxy ( # MetricsQdr will be refactored (split to QDR running on controller or on other node) # to better integrate, but for now we need this hack to enable the feature haproxy::balancermember { 'metrics_qdr': - listening_service => 'metrics_qdr', + listening_service => $metrics_qdr_service, ports => $ports[metrics_qdr_port], ipaddresses => hiera('pacemaker_node_ips', $controller_hosts_real), server_names => hiera('pacemaker_node_names', $controller_hosts_names_real), @@ -1331,25 +1488,34 @@ class tripleo::haproxy ( } if $mysql_clustercheck { - $mysql_listen_options = { - 'option' => [ 'tcpka', 'httpchk', 'tcplog' ], + $mysql_frontend_opts = { + 'option' => [ 'tcpka', 'tcplog' ], 'timeout client' => '90m', - 'timeout server' => '90m', - 'stick-table' => 'type ip size 1000', - 'stick' => 'on dst', 'maxconn' => $mysql_max_conn } + $mysql_backend_opts = { + 'option' => [ 'tcpka', 'httpchk' ], + 'stick-table' => 'type ip size 1000', + 'stick' => 'on dst', + 'timeout server' => '90m', + } + $mysql_listen_opts = merge_hash_values($mysql_frontend_opts, + $mysql_backend_opts) if $mysql_member_options { $mysql_member_options_real = $mysql_member_options } else { $mysql_member_options_real = ['backup', 'port 9200', 'on-marked-down shutdown-sessions', 'check', 'inter 1s'] } } else { - $mysql_listen_options = { + $mysql_frontend_opts = { 'timeout client' => '90m', - 'timeout server' => '90m', 'maxconn' => $mysql_max_conn } + $mysql_backend_opts = { + 'timeout server' => '90m', + } + $mysql_listen_opts = merge_hash_values($mysql_frontend_opts, + $mysql_backend_opts) if $mysql_member_options { $mysql_member_options_real = $mysql_member_options } else { @@ -1363,13 +1529,28 @@ class tripleo::haproxy ( } else { $mysql_server_names_real = hiera('mysql_node_names', $controller_hosts_names_real) } - haproxy::listen { 'mysql': - bind => $mysql_bind_opts, - options => deep_merge($mysql_listen_options, $mysql_custom_listen_options), - collect_exported => false, + if $use_backend_syntax { + haproxy::frontend { 'mysql': + bind => $mysql_bind_opts, + options => deep_merge($mysql_frontend_opts, + { 'default_backend' => 'mysql_be' }, + $mysql_custom_frontend_options), + collect_exported => false, + } + haproxy::backend { 'mysql_be': + options => deep_merge($mysql_backend_opts, $mysql_custom_backend_options), + } + $mysql_service = 'mysql_be' + } else { + haproxy::listen { 'mysql': + bind => $mysql_bind_opts, + options => deep_merge($mysql_listen_opts, $mysql_custom_listen_options), + collect_exported => false, + } + $mysql_service = 'mysql' } haproxy::balancermember { 'mysql-backup': - listening_service => 'mysql', + listening_service => $mysql_service, ports => '3306', ipaddresses => hiera('mysql_node_ips', $controller_hosts_real), server_names => $mysql_server_names_real, @@ -1387,16 +1568,31 @@ class tripleo::haproxy ( } if $rabbitmq { - haproxy::listen { 'rabbitmq': - bind => $rabbitmq_bind_opts, - options => { - 'option' => [ 'tcpka', 'tcplog' ], - 'timeout' => [ 'client 0', 'server 0' ], - }, - collect_exported => false, + if $use_backend_syntax { + haproxy::frontend { 'rabbitmq': + bind => $rabbitmq_bind_opts, + collect_exported => false, + } + haproxy::backend { 'rabbitmq_be': + options => { + 'option' => [ 'tcpka', 'tcplog' ], + 'timeout' => [ 'client 0', 'server 0' ], + }, + } + $rabbitmq_service = 'rabbitmq_be' + } else { + haproxy::listen { 'rabbitmq': + bind => $rabbitmq_bind_opts, + options => { + 'option' => [ 'tcpka', 'tcplog' ], + 'timeout' => [ 'client 0', 'server 0' ], + }, + collect_exported => false, + } + $rabbitmq_service = 'rabbitmq' } haproxy::balancermember { 'rabbitmq': - listening_service => 'rabbitmq', + listening_service => $rabbitmq_service, ports => '5672', ipaddresses => hiera('rabbitmq_node_ips', $controller_hosts_real), server_names => hiera('rabbitmq_node_names', $controller_hosts_names_real), @@ -1414,6 +1610,9 @@ class tripleo::haproxy ( member_options => union($haproxy_member_options, $internal_tls_member_options), listen_options => { 'balance' => 'source', + }, + backend_options => { + 'balance' => 'source', } } } @@ -1457,17 +1656,33 @@ class tripleo::haproxy ( 'send QUIT\r\n', 'expect string +OK'] $redis_tcp_check_options = $redis_tcp_check_connect_options + $redis_tcp_check_common_options - haproxy::listen { 'redis': - bind => $redis_bind_opts, - options => { - 'balance' => 'first', - 'option' => [ 'tcp-check', 'tcplog', ], - 'tcp-check' => $redis_tcp_check_options, - }, - collect_exported => false, + if $use_backend_syntax { + haproxy::frontend { 'redis': + bind => $redis_bind_opts, + collect_exported => false, + } + haproxy::backend { 'redis_be': + options => { + 'balance' => 'first', + 'option' => [ 'tcp-check', 'tcplog', ], + 'tcp-check' => $redis_tcp_check_options, + }, + } + $redis_service = 'redis_be' + } else { + haproxy::listen { 'redis': + bind => $redis_bind_opts, + options => { + 'balance' => 'first', + 'option' => [ 'tcp-check', 'tcplog', ], + 'tcp-check' => $redis_tcp_check_options, + }, + collect_exported => false, + } + $redis_service = 'redis' } haproxy::balancermember { 'redis': - listening_service => 'redis', + listening_service => $redis_service, ports => '6379', ipaddresses => hiera('redis_node_ips', $controller_hosts_real), server_names => hiera('redis_node_names', $controller_hosts_names_real), @@ -1501,6 +1716,12 @@ class tripleo::haproxy ( } if $ceph_rgw { + $ceph_rgw_backend_opts = { + 'option' => [ 'httpchk GET /swift/healthcheck' ], + 'balance' => $haproxy_lb_mode_longrunning + } + $ceph_rgw_listen_opts = merge_hash_values($default_frontend_options, + $ceph_rgw_backend_opts) ::tripleo::haproxy::endpoint { 'ceph_rgw': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('ceph_rgw_vip', $controller_virtual_ip), @@ -1510,21 +1731,24 @@ class tripleo::haproxy ( mode => 'http', public_ssl_port => $ports[ceph_rgw_ssl_port], service_network => $ceph_rgw_network, - listen_options => merge($default_listen_options, { - 'option' => [ 'httpchk GET /swift/healthcheck', 'httplog' ], - 'balance' => $haproxy_lb_mode_longrunning - } - ), + listen_options => merge($default_listen_options, $ceph_rgw_listen_opts), + frontend_options => $default_frontend_options, + backend_options => merge($default_backend_options, $ceph_rgw_backend_opts), member_options => union($haproxy_member_options, $internal_tls_member_options), } } if $octavia { - $octavia_listen_opts = { + $octavia_frontend_opts = { + 'option' => [ 'httplog' ], + } + $octavia_backend_opts = { 'hash-type' => 'consistent', 'option' => [ 'httpchk GET /healthcheck', 'httplog' ], 'balance' => 'source', } + $octavia_listen_opts = merge_hash_values($octavia_frontend_opts, + $octavia_backend_opts) ::tripleo::haproxy::endpoint { 'octavia': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('octavia_api_vip', $controller_virtual_ip), @@ -1536,6 +1760,8 @@ class tripleo::haproxy ( mode => 'http', member_options => union($haproxy_member_options, $internal_tls_member_options), listen_options => merge($default_listen_options, $octavia_listen_opts), + frontend_options => merge($default_frontend_options, $octavia_frontend_opts), + backend_options => $octavia_backend_opts, } } @@ -1545,13 +1771,17 @@ class tripleo::haproxy ( # We only configure ovn_dbs_vip in haproxy if HA for OVN DB servers is # disabled. # If HA is enabled, pacemaker configures the OVN DB servers accordingly. - $ovn_db_listen_options = { + $ovn_db_frontend_opts = { 'option' => [ 'tcpka', 'tcplog' ], 'timeout client' => '90m', + } + $ovn_db_backend_opts = { 'timeout server' => '90m', 'stick-table' => 'type ip size 1000', 'stick' => 'on dst', } + $ovn_db_listen_opts = merge_hash_values($ovn_db_frontend_opts, + $ovn_db_backend_opts) ::tripleo::haproxy::endpoint { 'ovn_nbdb': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('ovn_dbs_vip', $controller_virtual_ip), @@ -1560,7 +1790,9 @@ class tripleo::haproxy ( server_names => hiera('ovn_dbs_node_names', $controller_hosts_names_real), service_network => $ovn_dbs_network, public_ssl_port => $ports[ovn_nbdb_ssl_port], - listen_options => $ovn_db_listen_options, + listen_options => $ovn_db_listen_opts, + frontend_options => $ovn_db_frontend_opts, + backend_options => $ovn_db_backend_opts, mode => 'tcp' } ::tripleo::haproxy::endpoint { 'ovn_sbdb': @@ -1571,12 +1803,29 @@ class tripleo::haproxy ( server_names => hiera('ovn_dbs_node_names', $controller_hosts_names_real), service_network => $ovn_dbs_network, public_ssl_port => $ports[ovn_sbdb_ssl_port], - listen_options => $ovn_db_listen_options, + listen_options => $ovn_db_listen_opts, + frontend_options => $ovn_db_frontend_opts, + backend_options => $ovn_db_backend_opts, mode => 'tcp' } } if $zaqar_ws { + $zaqar_ws_frontend_opts = { + # NOTE(jaosorior): Websockets have more overhead in establishing + # connections than regular HTTP connections. Also, since it begins + # as an HTTP connection and then "upgrades" to a TCP connection, some + # timeouts get overridden by others at certain times of the connection. + # The following values were taken from the following site: + # http://blog.haproxy.com/2012/11/07/websockets-load-balancing-with-haproxy/ + 'timeout' => ['connect 5s', 'client 25s'], + 'http-request' => [join(['set-header Host %[dst]:', $ports[zaqar_ws_port]])], + } + $zaqar_ws_backend_opts = { + 'timeout' => ['server 25s', regsubst('tunnel Xs', 'X', $zaqar_ws_timeout_tunnel)], + } + $zaqar_ws_listen_opts = merge_hash_values($zaqar_ws_frontend_opts, + $zaqar_ws_backend_opts) ::tripleo::haproxy::endpoint { 'zaqar_ws': public_virtual_ip => $public_virtual_ip, internal_ip => hiera('zaqar_ws_vip', $controller_virtual_ip), @@ -1585,16 +1834,9 @@ class tripleo::haproxy ( server_names => hiera('zaqar_ws_node_names', $controller_hosts_names_real), mode => 'http', haproxy_listen_bind_param => [], # We don't use a transparent proxy here - listen_options => { - # NOTE(jaosorior): Websockets have more overhead in establishing - # connections than regular HTTP connections. Also, since it begins - # as an HTTP connection and then "upgrades" to a TCP connection, some - # timeouts get overridden by others at certain times of the connection. - # The following values were taken from the following site: - # http://blog.haproxy.com/2012/11/07/websockets-load-balancing-with-haproxy/ - 'timeout' => ['connect 5s', 'client 25s', 'server 25s', regsubst('tunnel Xs', 'X', $zaqar_ws_timeout_tunnel)], - 'http-request' => [join(['set-header Host %[dst]:', $ports[zaqar_ws_port]])], - }, + listen_options => $zaqar_ws_listen_opts, + frontend_options => $zaqar_ws_frontend_opts, + backend_options => $zaqar_ws_backend_opts, public_ssl_port => $ports[zaqar_ws_ssl_port], service_network => $zaqar_api_network, } diff --git a/manifests/haproxy/endpoint.pp b/manifests/haproxy/endpoint.pp index 46682fd13..68790b6e6 100644 --- a/manifests/haproxy/endpoint.pp +++ b/manifests/haproxy/endpoint.pp @@ -28,6 +28,11 @@ # Options for the balancer member, specified after the server declaration. # These should go in the member's configuration block. # +# [*use_backend_syntax*] +# (optional) When set to true, generate a config with frontend and +# backend sections, otherwise use listen sections. +# Defaults to hiera('haproxy_backend_syntax', false) +# # [*haproxy_port*] # An alternative port, on which haproxy will listen for incoming requests. # Defaults to service_port. @@ -65,6 +70,14 @@ # HAproxy terms, the frontend). # defaults to {'option' => []} # +# [*frontend_options*] +# Options specified for the frontend service's configuration block +# defaults to {'option' => []} +# +# [*backend_options*] +# Options specified for the service's backend configuration block +# defaults to {'option' => []} +# # [*public_ssl_port*] # The port used for the public proxy endpoint if it differs from the default # one. This is used only if SSL is enabled, and it's used in order to avoid @@ -119,6 +132,7 @@ define tripleo::haproxy::endpoint ( $internal_ip, $service_port, $member_options, + $use_backend_syntax = hiera('haproxy_backend_syntax', false), $haproxy_port = undef, $base_service_name = undef, $ip_addresses = hiera("${name}_node_ips", undef), @@ -129,6 +143,12 @@ define tripleo::haproxy::endpoint ( $listen_options = { 'option' => [], }, + $frontend_options = { + 'option' => [], + }, + $backend_options = { + 'option' => [], + }, $public_ssl_port = undef, $public_certificate = undef, $use_internal_certificates = false, @@ -160,6 +180,8 @@ define tripleo::haproxy::endpoint ( } # Let users override the options on a per-service basis $custom_options = hiera("tripleo::haproxy::${name}::options", undef) + $custom_frontend_options = hiera("tripleo::haproxy::${name}::frontend_options", undef) + $custom_backend_options = hiera("tripleo::haproxy::${name}::backend_options", undef) $custom_bind_options_public = delete(any2array(hiera("tripleo::haproxy::${name}::public_bind_options", undef)), undef).flatten() $custom_bind_options_internal = delete(any2array(hiera("tripleo::haproxy::${name}::internal_bind_options", undef)), undef).flatten() if $public_virtual_ip { @@ -173,13 +195,16 @@ define tripleo::haproxy::endpoint ( 'option' => 'forwardfor', } $listen_options_precookie = merge($tls_listen_options, $listen_options, $custom_options) + $frontend_options_precookie = merge($tls_listen_options, $frontend_options, $custom_frontend_options) } else { $listen_options_precookie = merge($listen_options, $custom_options) + $frontend_options_precookie = merge($frontend_options, $custom_frontend_options) } $public_bind_opts = list_to_hash(suffix(any2array($public_virtual_ip), ":${public_ssl_port}"), union($haproxy_listen_bind_param, ['ssl', 'crt', $public_certificate], $custom_bind_options_public)) } else { $listen_options_precookie = merge($listen_options, $custom_options) + $frontend_options_precookie = merge($frontend_options, $custom_frontend_options) $public_bind_opts = list_to_hash(suffix(any2array($public_virtual_ip), ":${haproxy_port_real}"), union($haproxy_listen_bind_param, $custom_bind_options_public)) } @@ -187,14 +212,17 @@ define tripleo::haproxy::endpoint ( # internal service only $public_bind_opts = {} $listen_options_precookie = merge($listen_options, $custom_options) + $frontend_options_precookie = merge($frontend_options, $custom_frontend_options) } if $sticky_sessions { $cookie_options = { 'cookie' => "${session_cookie} insert indirect nocache", } $listen_options_real = merge($listen_options_precookie, $cookie_options) + $frontend_options_real = merge($frontend_options_precookie, $cookie_options) } else { $listen_options_real = $listen_options_precookie + $frontend_options_real = $frontend_options_precookie } if $use_internal_certificates { if !$service_network { @@ -231,22 +259,45 @@ define tripleo::haproxy::endpoint ( 'acl' => "acl Auth${name} http_auth(${authorized_userlist})", 'http-request' => "auth realm ${name} if !Auth${name}", } - Haproxy::Listen[$name] { - require => Tripleo::Haproxy::Userlist[$authorized_userlist], + if $use_backend_syntax { + Haproxy::Frontend[$name] { + require => Tripleo::Haproxy::Userlist[$authorized_userlist], + } + } else { + Haproxy::Listen[$name] { + require => Tripleo::Haproxy::Userlist[$authorized_userlist], + } } } else { $access_rules = {} } $_real_options = merge($listen_options_real, $access_rules) + $_real_frontend_options = merge($frontend_options_real, $access_rules, + { 'default_backend' => "${name}_be" }) $bind_opts = merge($internal_bind_opts, $public_bind_opts) - haproxy::listen { "${name}": - bind => $bind_opts, - collect_exported => false, - mode => $mode, - options => $_real_options, + if $use_backend_syntax { + haproxy::frontend { "${name}": + bind => $bind_opts, + collect_exported => false, + mode => $mode, + options => $_real_frontend_options, + } + haproxy::backend { "${name}_be": + mode => $mode, + options => merge($backend_options, $custom_backend_options), + } + $listening_service = "${name}_be" + } else { + haproxy::listen { "${name}": + bind => $bind_opts, + collect_exported => false, + mode => $mode, + options => $_real_options, + } + $listening_service = "${name}" } if $sticky_sessions { hash(zip($ip_addresses_real, $server_names_real)).each | $ip, $server | { @@ -254,7 +305,7 @@ define tripleo::haproxy::endpoint ( # which is a reserved character to reference manifests $non_colon_ip = regsubst($ip, ':', '-', 'G') haproxy::balancermember { "${name}_${non_colon_ip}_${server}": - listening_service => $name, + listening_service => $listening_service, ports => $service_port_real, ipaddresses => $ip, server_names => $server, @@ -263,7 +314,7 @@ define tripleo::haproxy::endpoint ( } } else { haproxy::balancermember { "${name}": - listening_service => $name, + listening_service => $listening_service, ports => $service_port_real, ipaddresses => $ip_addresses_real, server_names => $server_names_real, diff --git a/manifests/haproxy/horizon_endpoint.pp b/manifests/haproxy/horizon_endpoint.pp index 05e5d20cb..43f2acf34 100644 --- a/manifests/haproxy/horizon_endpoint.pp +++ b/manifests/haproxy/horizon_endpoint.pp @@ -36,6 +36,11 @@ # If this service is internal only this should be ommitted. # Defaults to undef. # +# [*use_backend_syntax*] +# (optional) When set to true, generate a config with frontend and +# backend sections, otherwise use listen sections. +# Defaults to hiera('haproxy_backend_syntax', false) +# # [*haproxy_listen_bind_param*] # A list of params to be added to the HAProxy listener bind directive. # Defaults to undef. @@ -77,6 +82,7 @@ class tripleo::haproxy::horizon_endpoint ( $server_names, $member_options, $public_virtual_ip, + $use_backend_syntax = hiera('haproxy_backend_syntax', false), $haproxy_listen_bind_param = undef, $public_certificate = undef, $use_internal_certificates = false, @@ -86,6 +92,8 @@ class tripleo::haproxy::horizon_endpoint ( ) { # Let users override the options on a per-service basis $custom_options = hiera('tripleo::haproxy::horizon::options', undef) + $custom_frontend_options = hiera('tripleo::haproxy::horizon::frontend_options', undef) + $custom_backend_options = hiera('tripleo::haproxy::horizon::backend_options', undef) $custom_bind_options_public = delete(any2array(hiera('tripleo::haproxy::horizon::public_bind_options', undef)), undef).flatten() $custom_bind_options_internal = delete(any2array(hiera('tripleo::haproxy::horizon::internal_bind_options', undef)), undef).flatten() # service exposed to the public network @@ -120,26 +128,30 @@ class tripleo::haproxy::horizon_endpoint ( "${public_virtual_ip}:80" => union($haproxy_listen_bind_param, $custom_bind_options_public), "${public_virtual_ip}:443" => union($haproxy_listen_bind_param, ['ssl', 'crt', $public_certificate], $custom_bind_options_public), } - $horizon_options = merge({ - 'cookie' => 'SERVERID insert indirect nocache', + $horizon_frontend_options = { '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' ], + 'option' => [ 'forwardfor' ], '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" => union($haproxy_listen_bind_param, $custom_bind_options_internal), "${public_virtual_ip}:80" => union($haproxy_listen_bind_param, $custom_bind_options_public), } - $horizon_options = merge({ - 'cookie' => 'SERVERID insert indirect nocache', - 'option' => [ 'forwardfor', 'httpchk' ], - }, $custom_options) + $horizon_frontend_options = { + 'option' => [ 'forwardfor' ], + } } + $horizon_backend_options = { + 'cookie' => 'SERVERID insert indirect nocache', + 'option' => [ 'httpchk' ], + } + $horizon_options = merge_hash_values($horizon_backend_options, + $horizon_frontend_options) if $use_internal_certificates { # Use SSL port if TLS in the internal network is enabled. @@ -148,18 +160,33 @@ class tripleo::haproxy::horizon_endpoint ( $backend_port = '80' } - haproxy::listen { 'horizon': - bind => $horizon_bind_opts, - options => $horizon_options, - mode => 'http', - collect_exported => false, + if $use_backend_syntax { + haproxy::frontend { 'horizon': + bind => $horizon_bind_opts, + options => merge($horizon_frontend_options, + { default_backend => 'horizon_be' }, + $custom_frontend_options), + mode => 'http', + collect_exported => false, + } + haproxy::backend { 'horizon_be': + options => merge($horizon_backend_options, $custom_backend_options), + mode => 'http', + } + } else { + haproxy::listen { 'horizon': + bind => $horizon_bind_opts, + options => merge($horizon_options, $custom_options), + mode => 'http', + collect_exported => false, + } } hash(zip($ip_addresses, $server_names)).each | $ip, $server | { # We need to be sure the IP (IPv6) don't have colons # which is a reserved character to reference manifests $non_colon_ip = regsubst($ip, ':', '-', 'G') haproxy::balancermember { "horizon_${non_colon_ip}_${server}": - listening_service => 'horizon', + listening_service => 'horizon_be', ports => $backend_port, ipaddresses => $ip, server_names => $server, diff --git a/manifests/haproxy/stats.pp b/manifests/haproxy/stats.pp index d6526b48c..0ce55404d 100644 --- a/manifests/haproxy/stats.pp +++ b/manifests/haproxy/stats.pp @@ -24,6 +24,11 @@ # IP Address(es) on which the stats interface is listening on. # Can be a string or a list of ip addresses # +# [*use_backend_syntax*] +# (optional) When set to true, generate a config with frontend and +# backend sections, otherwise use listen sections. +# Defaults to hiera('haproxy_backend_syntax', false) +# # [*port*] # Port on which to listen to for haproxy stats web interface # Defaults to '1993' @@ -47,6 +52,7 @@ class tripleo::haproxy::stats ( $haproxy_listen_bind_param, $ip, + $use_backend_syntax = hiera('haproxy_backend_syntax', false), $port = '1993', $password = undef, $certificate = undef, @@ -66,12 +72,29 @@ class tripleo::haproxy::stats ( } else { $stats_config = $stats_base } - haproxy::listen { 'haproxy.stats': - bind => $haproxy_stats_bind_opts, - mode => 'http', - options => { - 'stats' => $stats_config, - }, - collect_exported => false, + if $use_backend_syntax { + haproxy::frontend { 'haproxy.stats': + bind => $haproxy_stats_bind_opts, + mode => 'http', + options => { + 'stats' => $stats_config, + }, + collect_exported => false, + } + haproxy::backend { 'haproxy.stats_be': + mode => 'http', + options => { + 'stats' => $stats_config, + }, + } + } else { + haproxy::listen { 'haproxy.stats': + bind => $haproxy_stats_bind_opts, + mode => 'http', + options => { + 'stats' => $stats_config, + }, + collect_exported => false, + } } } diff --git a/releasenotes/notes/haproxy-frontend-backend-e3719b323e84fd2c.yaml b/releasenotes/notes/haproxy-frontend-backend-e3719b323e84fd2c.yaml new file mode 100644 index 000000000..767d7daba --- /dev/null +++ b/releasenotes/notes/haproxy-frontend-backend-e3719b323e84fd2c.yaml @@ -0,0 +1,12 @@ +--- +features: + - | + Haproxy configuration file can now use the frontend and backend + keywords to describe a service, rather than using the listen + keyword. The new format can be enabled via hiera parameter + `haproxy_backend_syntax`. When enabled, any frontend or backend + configuration can be overriden on a per service-basis via new + hiera keys `tripleo::haproxy::::frontend_options` and + `tripleo::haproxy::::frontend_options`. The original + hiera key `tripleo::haproxy::::options` has no effect + on the frontend and backend sections. diff --git a/spec/defines/tripleo_haproxy_endpoint_spec.rb b/spec/defines/tripleo_haproxy_endpoint_spec.rb index bcca6a44d..6e12fb76f 100644 --- a/spec/defines/tripleo_haproxy_endpoint_spec.rb +++ b/spec/defines/tripleo_haproxy_endpoint_spec.rb @@ -75,6 +75,31 @@ describe 'tripleo::haproxy::endpoint' do ) end end + + context 'with frontend/backend sections' do + before :each do + params.merge!({ + :use_backend_syntax => true, + }) + end + it 'should configure haproxy' do + is_expected.to compile.with_all_deps + is_expected.to contain_haproxy__frontend('neutron').with( + :collect_exported => false, + :bind => { "10.0.0.1:9696" => ["transparent"], + "192.168.0.1:9696" => ["transparent"] }, + :options => {'option' => [], + 'timeout client' => '90m', + 'default_backend' => 'neutron_be', + }, + ) + is_expected.to contain_haproxy__backend('neutron_be').with( + :options => {'option' => [], + 'timeout server' => '90m', + }, + ) + end + end end on_supported_os.each do |os, facts| diff --git a/spec/fixtures/hieradata/default.yaml b/spec/fixtures/hieradata/default.yaml index 75a77cdd2..cce31af8a 100644 --- a/spec/fixtures/hieradata/default.yaml +++ b/spec/fixtures/hieradata/default.yaml @@ -202,6 +202,10 @@ tripleo::dynamic_stuff::haproxy_endpoints: tripleo::haproxy::neutron::options: 'timeout client': '90m' 'timeout server': '90m' +tripleo::haproxy::neutron::frontend_options: + 'timeout client': '90m' +tripleo::haproxy::neutron::backend_options: + 'timeout server': '90m' tripleo::haproxy_basic_auth::haproxy_endpoints: starwars: