diff options
-rw-r--r-- | Gemfile | 1 | ||||
-rw-r--r-- | lib/facter/netmask_ipv6.rb | 2 | ||||
-rw-r--r-- | manifests/loadbalancer.pp | 957 | ||||
-rw-r--r-- | manifests/loadbalancer/endpoint.pp | 128 | ||||
-rw-r--r-- | manifests/pacemaker/haproxy_with_vip.pp | 64 | ||||
-rw-r--r-- | manifests/packages.pp | 15 | ||||
-rw-r--r-- | manifests/profile/base/database/schemas.pp | 101 | ||||
-rw-r--r-- | manifests/profile/base/keystone.pp | 118 | ||||
-rw-r--r-- | manifests/profile/pacemaker/database/schemas.pp | 50 | ||||
-rw-r--r-- | manifests/profile/pacemaker/keystone.pp | 88 | ||||
-rw-r--r-- | manifests/ssl/cinder_config.pp | 28 | ||||
-rw-r--r-- | spec/classes/tripleo_packages_spec.rb | 6 | ||||
-rw-r--r-- | spec/spec_helper.rb | 1 |
13 files changed, 962 insertions, 597 deletions
@@ -13,7 +13,6 @@ group :development, :test do gem 'puppet-lint-variable_contains_upcase', :require => 'false' gem 'puppet-lint-numericvariable', :require => 'false' gem 'json', :require => 'false' - gem 'webmock', :require => 'false' # adding 'psych' explicitly # https://github.com/bundler/bundler/issues/2068 # TODO: drop it in a future release of 'bundle'. diff --git a/lib/facter/netmask_ipv6.rb b/lib/facter/netmask_ipv6.rb index 5261485..598641f 100644 --- a/lib/facter/netmask_ipv6.rb +++ b/lib/facter/netmask_ipv6.rb @@ -8,6 +8,8 @@ def netmask6(value) end if Facter.value('facterversion')[0].to_i < 3 + Facter::Util::IP::REGEX_MAP[:linux][:ipaddress6] = + /inet6 (?:addr: )?((?!(?:fe80|::1))(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/ Facter::Util::IP.get_interfaces.each do |interface| Facter.add('netmask6_' + Facter::Util::IP.alphafy(interface)) do setcode do diff --git a/manifests/loadbalancer.pp b/manifests/loadbalancer.pp index 2690a6e..e91e611 100644 --- a/manifests/loadbalancer.pp +++ b/manifests/loadbalancer.pp @@ -103,79 +103,40 @@ # A string. # Defaults to false # -# [*service_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the public API endpoints using the specified file. -# Any service-specific certificates take precedence over this one. -# Defaults to undef -# -# [*keystone_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Keystone public API endpoint using the specified file. -# Defaults to undef -# -# [*neutron_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Neutron public API endpoint using the specified file. -# Defaults to undef -# -# [*cinder_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Cinder public API endpoint using the specified file. -# Defaults to undef -# -# [*manila_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Manila public API endpoint using the specified file. -# Defaults to undef -# -# [*glance_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Glance public API endpoint using the specified file. -# Defaults to undef +# [*haproxy_stats_user*] +# Username for haproxy stats authentication. +# A string. +# Defaults to 'admin' # -# [*nova_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Nova public API endpoint using the specified file. +# [*haproxy_stats_password*] +# Password for haproxy stats authentication. When set, authentication is +# enabled on the haproxy stats endpoint. +# A string. # Defaults to undef # -# [*ceilometer_certificate*] +# [*service_certificate*] # Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Ceilometer public API endpoint using the specified file. +# When set, enables SSL on the public API endpoints using the specified file. # Defaults to undef # -# [*aodh_certificate*] +# [*internal_certificate*] # Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Aodh public API endpoint using the specified file. -# -# [*sahara_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Sahara public API endpoint using the specified file. +# When set, enables SSL on the internal API endpoints using the specified file. # Defaults to undef # -# [*trove_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Trove public API endpoint using the specified file. -# Defaults to undef +# [*ssl_cipher_suite*] +# The default string describing the list of cipher algorithms ("cipher suite") +# that are negotiated during the SSL/TLS handshake for all "bind" lines. This +# value comes from the Fedora system crypto policy. +# Defaults to '!SSLv2:kEECDH:kRSA:kEDH:kPSK:+3DES:!aNULL:!eNULL:!MD5:!EXP:!RC4:!SEED:!IDEA:!DES' # -# [*swift_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Swift public API endpoint using the specified file. -# Defaults to undef +# [*ssl_options*] +# String that sets the default ssl options to force on all "bind" lines. +# Defaults to 'no-sslv3' # -# [*heat_certificate*] +# [*haproxy_stats_certificate*] # Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Heat public API endpoint using the specified file. -# Defaults to undef -# -# [*horizon_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Horizon public API endpoint using the specified file. -# Defaults to undef -# -# [*ironic_certificate*] -# Filename of an HAProxy-compatible certificate and key file -# When set, enables SSL on the Ironic public API endpoint using the specified file. +# When set, enables SSL on the haproxy stats endpoint using the specified file. # Defaults to undef # # [*keystone_admin*] @@ -238,6 +199,10 @@ # (optional) Enable or not Aodh API binding # Defaults to false # +# [*gnocchi*] +# (optional) Enable or not Gnocchi API binding +# Defaults to false +# # [*swift_proxy_server*] # (optional) Enable or not Swift API binding # Defaults to false @@ -278,10 +243,60 @@ # (optional) Enable or not Redis binding # Defaults to false # +# [*redis_password*] +# (optional) Password for Redis authentication, eventually needed by the +# specific monitoring we do from HAProxy for Redis +# Defaults to undef +# # [*midonet_api*] # (optional) Enable or not MidoNet API binding # Defaults to false # +# [*service_ports*] +# (optional) Hash that contains the values to override from the service ports +# The available keys to modify the services' ports are: +# 'aodh_api_port' (Defaults to 8042) +# 'aodh_api_ssl_port' (Defaults to 13042) +# 'ceilometer_api_port' (Defaults to 8777) +# 'ceilometer_api_ssl_port' (Defaults to 13777) +# 'cinder_api_port' (Defaults to 8776) +# 'cinder_api_ssl_port' (Defaults to 13776) +# 'glance_api_port' (Defaults to 9292) +# 'glance_api_ssl_port' (Defaults to 13292) +# 'glance_registry_port' (Defaults to 9191) +# 'gnocchi_api_port' (Defaults to 8041) +# 'gnocchi_api_ssl_port' (Defaults to 13041) +# 'heat_api_port' (Defaults to 8004) +# 'heat_api_ssl_port' (Defaults to 13004) +# 'heat_cfn_port' (Defaults to 8000) +# 'heat_cfn_ssl_port' (Defaults to 13800) +# 'heat_cw_port' (Defaults to 8003) +# 'heat_cw_ssl_port' (Defaults to 13003) +# 'ironic_api_port' (Defaults to 6385) +# 'ironic_api_ssl_port' (Defaults to 13385) +# 'keystone_admin_api_port' (Defaults to 35357) +# 'keystone_admin_api_ssl_port' (Defaults to 13357) +# 'keystone_public_api_port' (Defaults to 5000) +# 'keystone_public_api_ssl_port' (Defaults to 13000) +# 'manila_api_port' (Defaults to 8786) +# 'manila_api_ssl_port' (Defaults to 13786) +# 'neutron_api_port' (Defaults to 9696) +# 'neutron_api_ssl_port' (Defaults to 13696) +# 'nova_api_port' (Defaults to 8774) +# 'nova_api_ssl_port' (Defaults to 13774) +# 'nova_ec2_port' (Defaults to 8773) +# 'nova_ec2_ssl_port' (Defaults to 13773) +# 'nova_metadata_port' (Defaults to 8775) +# 'nova_novnc_port' (Defaults to 6080) +# 'nova_novnc_ssl_port' (Defaults to 13080) +# 'sahara_api_port' (Defaults to 8386) +# 'sahara_api_ssl_port' (Defaults to 13386) +# 'swift_proxy_port' (Defaults to 8080) +# 'swift_proxy_ssl_port' (Defaults to 13808) +# 'trove_api_port' (Defaults to 8779) +# 'trove_api_ssl_port' (Defaults to 13779) +# Defaults to {} +# class tripleo::loadbalancer ( $controller_virtual_ip, $control_virtual_interface, @@ -298,24 +313,16 @@ class tripleo::loadbalancer ( $haproxy_listen_bind_param = [ 'transparent' ], $haproxy_member_options = [ 'check', 'inter 2000', 'rise 2', 'fall 5' ], $haproxy_log_address = '/dev/log', + $haproxy_stats_user = 'admin', + $haproxy_stats_password = undef, $controller_host = undef, $controller_hosts = undef, $controller_hosts_names = undef, $service_certificate = undef, - $keystone_certificate = undef, - $neutron_certificate = undef, - $cinder_certificate = undef, - $sahara_certificate = undef, - $trove_certificate = undef, - $manila_certificate = undef, - $glance_certificate = undef, - $nova_certificate = undef, - $ceilometer_certificate = undef, - $aodh_certificate = undef, - $swift_certificate = undef, - $heat_certificate = undef, - $horizon_certificate = undef, - $ironic_certificate = undef, + $internal_certificate = undef, + $ssl_cipher_suite = '!SSLv2:kEECDH:kRSA:kEDH:kPSK:+3DES:!aNULL:!eNULL:!MD5:!EXP:!RC4:!SEED:!IDEA:!DES', + $ssl_options = 'no-sslv3', + $haproxy_stats_certificate = undef, $keystone_admin = false, $keystone_public = false, $neutron = false, @@ -331,6 +338,7 @@ class tripleo::loadbalancer ( $nova_novncproxy = false, $ceilometer = false, $aodh = false, + $gnocchi = false, $swift_proxy_server = false, $heat_api = false, $heat_cloudwatch = false, @@ -341,8 +349,53 @@ class tripleo::loadbalancer ( $mysql_clustercheck = false, $rabbitmq = false, $redis = false, + $redis_password = undef, $midonet_api = false, + $service_ports = {} ) { + $default_service_ports = { + aodh_api_port => 8042, + aodh_api_ssl_port => 13042, + ceilometer_api_port => 8777, + ceilometer_api_ssl_port => 13777, + cinder_api_port => 8776, + cinder_api_ssl_port => 13776, + glance_api_port => 9292, + glance_api_ssl_port => 13292, + glance_registry_port => 9191, + gnocchi_api_port => 8041, + gnocchi_api_ssl_port => 13041, + heat_api_port => 8004, + heat_api_ssl_port => 13004, + heat_cfn_port => 8000, + heat_cfn_ssl_port => 13800, + heat_cw_port => 8003, + heat_cw_ssl_port => 13003, + ironic_api_port => 6385, + ironic_api_ssl_port => 13385, + keystone_admin_api_port => 35357, + keystone_admin_api_ssl_port => 13357, + keystone_public_api_port => 5000, + keystone_public_api_ssl_port => 13000, + manila_api_port => 8786, + manila_api_ssl_port => 13786, + neutron_api_port => 9696, + neutron_api_ssl_port => 13696, + nova_api_port => 8774, + nova_api_ssl_port => 13774, + nova_ec2_port => 8773, + nova_ec2_ssl_port => 13773, + nova_metadata_port => 8775, + nova_novnc_port => 6080, + nova_novnc_ssl_port => 13080, + sahara_api_port => 8386, + sahara_api_ssl_port => 13386, + swift_proxy_port => 8080, + swift_proxy_ssl_port => 13808, + trove_api_port => 8779, + trove_api_ssl_port => 13779, + } + $ports = merge($default_service_ports, $service_ports) if !$controller_host and !$controller_hosts { fail('$controller_hosts or $controller_host (now deprecated) is a mandatory parameter') @@ -402,7 +455,7 @@ class tripleo::loadbalancer ( } - if $internal_api_virtual_ip and $internal_api_virtual_ip != $control_virtual_interface { + if $internal_api_virtual_ip and $internal_api_virtual_ip != $controller_virtual_ip { $internal_api_virtual_interface = interface_for_ip($internal_api_virtual_ip) # KEEPALIVE INTERNAL API NETWORK keepalived::instance { '53': @@ -414,7 +467,7 @@ class tripleo::loadbalancer ( } } - if $storage_virtual_ip and $storage_virtual_ip != $control_virtual_interface { + if $storage_virtual_ip and $storage_virtual_ip != $controller_virtual_ip { $storage_virtual_interface = interface_for_ip($storage_virtual_ip) # KEEPALIVE STORAGE NETWORK keepalived::instance { '54': @@ -426,7 +479,7 @@ class tripleo::loadbalancer ( } } - if $storage_mgmt_virtual_ip and $storage_mgmt_virtual_ip != $control_virtual_interface { + if $storage_mgmt_virtual_ip and $storage_mgmt_virtual_ip != $controller_virtual_ip { $storage_mgmt_virtual_interface = interface_for_ip($storage_mgmt_virtual_ip) # KEEPALIVE STORAGE MANAGEMENT NETWORK keepalived::instance { '55': @@ -440,312 +493,51 @@ class tripleo::loadbalancer ( } - if $keystone_certificate { - $keystone_bind_certificate = $keystone_certificate - } else { - $keystone_bind_certificate = $service_certificate - } - if $neutron_certificate { - $neutron_bind_certificate = $neutron_certificate - } else { - $neutron_bind_certificate = $service_certificate - } - if $cinder_certificate { - $cinder_bind_certificate = $cinder_certificate - } else { - $cinder_bind_certificate = $service_certificate - } - if $sahara_certificate { - $sahara_bind_certificate = $sahara_certificate - } else { - $sahara_bind_certificate = $service_certificate - } - if $trove_certificate { - $trove_bind_certificate = $trove_certificate - } else { - $trove_bind_certificate = $trove_certificate - } - if $manila_certificate { - $manila_bind_certificate = $manila_certificate - } else { - $manila_bind_certificate = $service_certificate - } - if $glance_certificate { - $glance_bind_certificate = $glance_certificate - } else { - $glance_bind_certificate = $service_certificate - } - if $nova_certificate { - $nova_bind_certificate = $nova_certificate - } else { - $nova_bind_certificate = $service_certificate - } - if $ceilometer_certificate { - $ceilometer_bind_certificate = $ceilometer_certificate - } else { - $ceilometer_bind_certificate = $service_certificate - } - if $aodh_certificate { - $aodh_bind_certificate = $aodh_certificate - } else { - $aodh_bind_certificate = $service_certificate - } - if $swift_certificate { - $swift_bind_certificate = $swift_certificate - } else { - $swift_bind_certificate = $service_certificate - } - if $heat_certificate { - $heat_bind_certificate = $heat_certificate - } else { - $heat_bind_certificate = $service_certificate - } - if $horizon_certificate { - $horizon_bind_certificate = $horizon_certificate - } else { - $horizon_bind_certificate = $service_certificate - } - if $ironic_certificate { - $ironic_bind_certificate = $ironic_certificate - } else { - $ironic_bind_certificate = $service_certificate - } - - $keystone_public_api_vip = hiera('keystone_public_api_vip', $controller_virtual_ip) - $keystone_admin_api_vip = hiera('keystone_admin_api_vip', $controller_virtual_ip) - if $keystone_bind_certificate { - $keystone_public_bind_opts = { - "${keystone_public_api_vip}:5000" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13000" => union($haproxy_listen_bind_param, ['ssl', 'crt', $keystone_bind_certificate]), - } - $keystone_admin_bind_opts = { - "${keystone_admin_api_vip}:35357" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13357" => union($haproxy_listen_bind_param, ['ssl', 'crt', $keystone_bind_certificate]), - } - } else { - $keystone_public_bind_opts = { - "${keystone_public_api_vip}:5000" => $haproxy_listen_bind_param, - "${public_virtual_ip}:5000" => $haproxy_listen_bind_param, - } - $keystone_admin_bind_opts = { - "${keystone_admin_api_vip}:35357" => $haproxy_listen_bind_param, - "${public_virtual_ip}:35357" => $haproxy_listen_bind_param, - } - } - - $neutron_api_vip = hiera('neutron_api_vip', $controller_virtual_ip) - if $neutron_bind_certificate { - $neutron_bind_opts = { - "${neutron_api_vip}:9696" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13696" => union($haproxy_listen_bind_param, ['ssl', 'crt', $neutron_bind_certificate]), - } - } else { - $neutron_bind_opts = { - "${neutron_api_vip}:9696" => $haproxy_listen_bind_param, - "${public_virtual_ip}:9696" => $haproxy_listen_bind_param, - } - } - - $cinder_api_vip = hiera('cinder_api_vip', $controller_virtual_ip) - if $cinder_bind_certificate { - $cinder_bind_opts = { - "${cinder_api_vip}:8776" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13776" => union($haproxy_listen_bind_param, ['ssl', 'crt', $cinder_bind_certificate]), - } - } else { - $cinder_bind_opts = { - "${cinder_api_vip}:8776" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8776" => $haproxy_listen_bind_param, - } - } - - $manila_api_vip = hiera('manila_api_vip', $controller_virtual_ip) - if $manila_bind_certificate { - $manila_bind_opts = { - "${manila_api_vip}:8786" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13786" => union($haproxy_listen_bind_param, ['ssl', 'crt', $manila_bind_certificate]), - } - } else { - $manila_bind_opts = { - "${manila_api_vip}:8786" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8786" => $haproxy_listen_bind_param, - } - } - - $glance_api_vip = hiera('glance_api_vip', $controller_virtual_ip) - if $glance_bind_certificate { - $glance_bind_opts = { - "${glance_api_vip}:9292" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13292" => union($haproxy_listen_bind_param, ['ssl', 'crt', $glance_bind_certificate]), - } - } else { - $glance_bind_opts = { - "${glance_api_vip}:9292" => $haproxy_listen_bind_param, - "${public_virtual_ip}:9292" => $haproxy_listen_bind_param, - } - } - - $glance_registry_vip = hiera('glance_registry_vip', $controller_virtual_ip) - $glance_registry_bind_opts = { - "${glance_registry_vip}:9191" => $haproxy_listen_bind_param, - } - - $sahara_api_vip = hiera('sahara_api_vip', $controller_virtual_ip) - if $sahara_bind_certificate { - $sahara_bind_opts = { - "${sahara_api_vip}:8386" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13786" => union($haproxy_listen_bind_param, ['ssl', 'crt', $sahara_bind_certificate]), - } - } else { - $sahara_bind_opts = { - "${sahara_api_vip}:8386" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8386" => $haproxy_listen_bind_param, - } - } - - $trove_api_vip = hiera('$trove_api_vip', $controller_virtual_ip) - if $trove_bind_certificate { - $trove_bind_opts = { - "${trove_api_vip}:8779" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13779" => union($haproxy_listen_bind_param, ['ssl', 'crt', $trove_bind_certificate]), - } - } else { - $trove_bind_opts = { - "${trove_api_vip}:8779" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8779" => $haproxy_listen_bind_param, - } - } - - $nova_api_vip = hiera('nova_api_vip', $controller_virtual_ip) - if $nova_bind_certificate { - $nova_osapi_bind_opts = { - "${nova_api_vip}:8774" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13774" => union($haproxy_listen_bind_param, ['ssl', 'crt', $nova_bind_certificate]), - } - $nova_ec2_bind_opts = { - "${nova_api_vip}:8773" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13773" => union($haproxy_listen_bind_param, ['ssl', 'crt', $nova_bind_certificate]), - } - $nova_novnc_bind_opts = { - "${nova_api_vip}:6080" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13080" => union($haproxy_listen_bind_param, ['ssl', 'crt', $nova_bind_certificate]), - } - } else { - $nova_osapi_bind_opts = { - "${nova_api_vip}:8774" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8774" => $haproxy_listen_bind_param, - } - $nova_ec2_bind_opts = { - "${nova_api_vip}:8773" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8773" => $haproxy_listen_bind_param, - } - $nova_novnc_bind_opts = { - "${nova_api_vip}:6080" => $haproxy_listen_bind_param, - "${public_virtual_ip}:6080" => $haproxy_listen_bind_param, - } - } - - $nova_metadata_vip = hiera('nova_metadata_vip', $controller_virtual_ip) - $nova_metadata_bind_opts = { - "${nova_metadata_vip}:8775" => $haproxy_listen_bind_param, - } - - $ceilometer_api_vip = hiera('ceilometer_api_vip', $controller_virtual_ip) - if $ceilometer_bind_certificate { - $ceilometer_bind_opts = { - "${ceilometer_api_vip}:8777" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13777" => union($haproxy_listen_bind_param, ['ssl', 'crt', $ceilometer_bind_certificate]), - } - } else { - $ceilometer_bind_opts = { - "${ceilometer_api_vip}:8777" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8777" => $haproxy_listen_bind_param, - } - } - - $aodh_api_vip = hiera('aodh_api_vip', $controller_virtual_ip) - if $aodh_bind_certificate { - $aodh_bind_opts = { - "${aodh_api_vip}:8042" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13042" => union($haproxy_listen_bind_param, ['ssl', 'crt', $aodh_bind_certificate]), - } - } else { - $aodh_bind_opts = { - "${aodh_api_vip}:8042" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8042" => $haproxy_listen_bind_param, - } - } - - $swift_proxy_vip = hiera('swift_proxy_vip', $controller_virtual_ip) - if $swift_bind_certificate { - $swift_bind_opts = { - "${swift_proxy_vip}:8080" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13808" => union($haproxy_listen_bind_param, ['ssl', 'crt', $swift_bind_certificate]), - } - } else { - $swift_bind_opts = { - "${swift_proxy_vip}:8080" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8080" => $haproxy_listen_bind_param, - } - } - - $heat_api_vip = hiera('heat_api_vip', $controller_virtual_ip) - if $heat_bind_certificate { - $heat_bind_opts = { - "${heat_api_vip}:8004" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13004" => union($haproxy_listen_bind_param, ['ssl', 'crt', $heat_bind_certificate]), - } - $heat_options = { - 'rsprep' => "^Location:\\ http://${public_virtual_ip}(.*) Location:\\ https://${public_virtual_ip}\\1", - 'http-request' => ['set-header X-Forwarded-Proto https if { ssl_fc }'], - } - $heat_cw_bind_opts = { - "${heat_api_vip}:8003" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13003" => union($haproxy_listen_bind_param, ['ssl', 'crt', $heat_bind_certificate]), - } - $heat_cfn_bind_opts = { - "${heat_api_vip}:8000" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13800" => union($haproxy_listen_bind_param, ['ssl', 'crt', $heat_bind_certificate]), - } - } else { - $heat_bind_opts = { - "${heat_api_vip}:8004" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8004" => $haproxy_listen_bind_param, - } - $heat_options = {} - $heat_cw_bind_opts = { - "${heat_api_vip}:8003" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8003" => $haproxy_listen_bind_param, - } - $heat_cfn_bind_opts = { - "${heat_api_vip}:8000" => $haproxy_listen_bind_param, - "${public_virtual_ip}:8000" => $haproxy_listen_bind_param, - } + # TODO(bnemec): When we have support for SSL on private and admin endpoints, + # have the haproxy stats endpoint use that certificate by default. + if $haproxy_stats_certificate { + $haproxy_stats_bind_certificate = $haproxy_stats_certificate } $horizon_vip = hiera('horizon_vip', $controller_virtual_ip) - if $horizon_bind_certificate { + 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, - "${public_virtual_ip}:443" => union($haproxy_listen_bind_param, ['ssl', 'crt', $horizon_bind_certificate]), + "${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 { hdr(host) -i ${public_virtual_ip} } !{ 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', + } } - $ironic_api_vip = hiera('ironic_api_vip', $controller_virtual_ip) - if $ironic_bind_certificate { - $ironic_bind_opts = { - "${ironic_api_vip}:6385" => $haproxy_listen_bind_param, - "${public_virtual_ip}:13385" => union($haproxy_listen_bind_param, ['ssl', 'crt', $ironic_bind_certificate]), + if $haproxy_stats_bind_certificate { + $haproxy_stats_bind_opts = { + "${controller_virtual_ip}:1993" => union($haproxy_listen_bind_param, ['ssl', 'crt', $haproxy_stats_bind_certificate]), } } else { - $ironic_bind_opts = { - "${ironic_api_vip}:6385" => $haproxy_listen_bind_param, - "${public_virtual_ip}:6385" => $haproxy_listen_bind_param, + $haproxy_stats_bind_opts = { + "${controller_virtual_ip}:1993" => $haproxy_listen_bind_param, } } @@ -767,12 +559,14 @@ class tripleo::loadbalancer ( class { '::haproxy': service_manage => $haproxy_service_manage, global_options => { - 'log' => "${haproxy_log_address} local0", - 'pidfile' => '/var/run/haproxy.pid', - 'user' => 'haproxy', - 'group' => 'haproxy', - 'daemon' => '', - 'maxconn' => $haproxy_global_maxconn, + 'log' => "${haproxy_log_address} local0", + 'pidfile' => '/var/run/haproxy.pid', + 'user' => 'haproxy', + 'group' => 'haproxy', + 'daemon' => '', + 'maxconn' => $haproxy_global_maxconn, + 'ssl-default-bind-ciphers' => $ssl_cipher_suite, + 'ssl-default-bind-options' => $ssl_options, }, defaults_options => { 'mode' => 'tcp', @@ -783,308 +577,298 @@ class tripleo::loadbalancer ( }, } - Haproxy::Listen { - options => { - 'option' => [], - } + Tripleo::Loadbalancer::Endpoint { + haproxy_listen_bind_param => $haproxy_listen_bind_param, + member_options => $haproxy_member_options, + public_certificate => $service_certificate, + internal_certificate => $internal_certificate, } + $stats_base = ['enable', 'uri /'] + if $haproxy_stats_password { + $stats_config = union($stats_base, ["auth ${haproxy_stats_user}:${haproxy_stats_password}"]) + } else { + $stats_config = $stats_base + } haproxy::listen { 'haproxy.stats': - ipaddress => $controller_virtual_ip, - ports => '1993', + bind => $haproxy_stats_bind_opts, mode => 'http', options => { - 'stats' => ['enable', 'uri /'], + 'stats' => $stats_config, }, collect_exported => false, } if $keystone_admin { - haproxy::listen { 'keystone_admin': - bind => $keystone_admin_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'keystone_admin': - listening_service => 'keystone_admin', - ports => '35357', - ipaddresses => hiera('keystone_admin_api_node_ips',$controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'keystone_admin': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('keystone_admin_api_vip', $controller_virtual_ip), + service_port => $ports[keystone_admin_api_port], + ip_addresses => hiera('keystone_admin_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + mode => 'http', + listen_options => { + 'http-request' => [ + 'set-header X-Forwarded-Proto https if { ssl_fc }', + 'set-header X-Forwarded-Proto http if !{ ssl_fc }'], + }, + public_ssl_port => $ports[keystone_admin_api_ssl_port], } } if $keystone_public { - haproxy::listen { 'keystone_public': - bind => $keystone_public_bind_opts, - collect_exported => false, - mode => 'http', # Needed for http-request option - options => { - 'http-request' => ['set-header X-Forwarded-Proto https if { ssl_fc }'], - }, - } - haproxy::balancermember { 'keystone_public': - listening_service => 'keystone_public', - ports => '5000', - ipaddresses => hiera('keystone_public_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'keystone_public': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('keystone_public_api_vip', $controller_virtual_ip), + service_port => $ports[keystone_public_api_port], + ip_addresses => hiera('keystone_public_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + mode => 'http', + listen_options => { + 'http-request' => [ + 'set-header X-Forwarded-Proto https if { ssl_fc }', + 'set-header X-Forwarded-Proto http if !{ ssl_fc }'], + }, + public_ssl_port => $ports[keystone_public_api_ssl_port], } } if $neutron { - haproxy::listen { 'neutron': - bind => $neutron_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'neutron': - listening_service => 'neutron', - ports => '9696', - ipaddresses => hiera('neutron_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'neutron': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('neutron_api_vip', $controller_virtual_ip), + service_port => $ports[neutron_api_port], + ip_addresses => hiera('neutron_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + public_ssl_port => $ports[neutron_api_ssl_port], } } if $cinder { - haproxy::listen { 'cinder': - bind => $cinder_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'cinder': - listening_service => 'cinder', - ports => '8776', - ipaddresses => hiera('cinder_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'cinder': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('cinder_api_vip', $controller_virtual_ip), + service_port => $ports[cinder_api_port], + ip_addresses => hiera('cinder_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + mode => 'http', + listen_options => { + 'http-request' => [ + 'set-header X-Forwarded-Proto https if { ssl_fc }', + 'set-header X-Forwarded-Proto http if !{ ssl_fc }'], + }, + public_ssl_port => $ports[cinder_api_ssl_port], } } if $manila { - haproxy::listen { 'manila': - bind => $manila_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'manila': - listening_service => 'manila', - ports => '8786', - ipaddresses => hiera('manila_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'manila': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('manila_api_vip', $controller_virtual_ip), + service_port => $ports[manila_api_port], + ip_addresses => hiera('manila_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + public_ssl_port => $ports[manila_api_ssl_port], } } if $sahara { - haproxy::listen { 'sahara': - bind => $sahara_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'sahara': - listening_service => 'sahara', - ports => '8386', - ipaddresses => hiera('sahara_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'sahara': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('sahara_api_vip', $controller_virtual_ip), + service_port => $ports[sahara_api_port], + ip_addresses => hiera('sahara_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + public_ssl_port => $ports[sahara_api_ssl_port], } } if $trove { - haproxy::listen { 'trove': - bind => $trove_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'trove': - listening_service => 'trove', - ports => '8779', - ipaddresses => hiera('trove_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'trove': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('trove_api_vip', $controller_virtual_ip), + service_port => $ports[trove_api_port], + ip_addresses => hiera('trove_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + public_ssl_port => $ports[trove_api_ssl_port], } } if $glance_api { - haproxy::listen { 'glance_api': - bind => $glance_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'glance_api': - listening_service => 'glance_api', - ports => '9292', - ipaddresses => hiera('glance_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'glance_api': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('glance_api_vip', $controller_virtual_ip), + service_port => $ports[glance_api_port], + ip_addresses => hiera('glance_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + public_ssl_port => $ports[glance_api_ssl_port], } } if $glance_registry { - haproxy::listen { 'glance_registry': - bind => $glance_registry_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'glance_registry': - listening_service => 'glance_registry', - ports => '9191', - ipaddresses => hiera('glance_registry_node_ips', $controller_hosts_real), - server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + ::tripleo::loadbalancer::endpoint { 'glance_registry': + internal_ip => hiera('glance_registry_vip', $controller_virtual_ip), + service_port => $ports[glance_registry_port], + ip_addresses => hiera('glance_registry_node_ips', $controller_hosts_real), + server_names => $controller_hosts_names_real, } } + $nova_api_vip = hiera('nova_api_vip', $controller_virtual_ip) if $nova_ec2 { - haproxy::listen { 'nova_ec2': - bind => $nova_ec2_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'nova_ec2': - listening_service => 'nova_ec2', - ports => '8773', - ipaddresses => hiera('nova_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'nova_ec2': + public_virtual_ip => $public_virtual_ip, + internal_ip => $nova_api_vip, + service_port => $ports[nova_ec2_port], + ip_addresses => hiera('nova_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + public_ssl_port => $ports[nova_ec2_ssl_port], } } if $nova_osapi { - haproxy::listen { 'nova_osapi': - bind => $nova_osapi_bind_opts, - collect_exported => false, - mode => 'http', - options => { - 'http-request' => ['set-header X-Forwarded-Proto https if { ssl_fc }'], - }, - } - haproxy::balancermember { 'nova_osapi': - listening_service => 'nova_osapi', - ports => '8774', - ipaddresses => hiera('nova_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'nova_osapi': + public_virtual_ip => $public_virtual_ip, + internal_ip => $nova_api_vip, + service_port => $ports[nova_api_port], + ip_addresses => hiera('nova_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + mode => 'http', + listen_options => { + 'http-request' => [ + 'set-header X-Forwarded-Proto https if { ssl_fc }', + 'set-header X-Forwarded-Proto http if !{ ssl_fc }'], + }, + public_ssl_port => $ports[nova_api_ssl_port], } } if $nova_metadata { - haproxy::listen { 'nova_metadata': - bind => $nova_metadata_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'nova_metadata': - listening_service => 'nova_metadata', - ports => '8775', - ipaddresses => hiera('nova_metadata_node_ips', $controller_hosts_real), - server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + ::tripleo::loadbalancer::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 => $controller_hosts_names_real, } } if $nova_novncproxy { - haproxy::listen { 'nova_novncproxy': - bind => $nova_novnc_bind_opts, - options => { + ::tripleo::loadbalancer::endpoint { 'nova_novncproxy': + public_virtual_ip => $public_virtual_ip, + internal_ip => $nova_api_vip, + service_port => $ports[nova_novnc_port], + ip_addresses => hiera('nova_api_node_ips', $controller_hosts_real), + server_names => $controller_hosts_names_real, + listen_options => { 'balance' => 'source', 'timeout' => [ 'tunnel 1h' ], }, - collect_exported => false, - } - haproxy::balancermember { 'nova_novncproxy': - listening_service => 'nova_novncproxy', - ports => '6080', - ipaddresses => hiera('nova_api_node_ips', $controller_hosts_real), - server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + public_ssl_port => $ports[nova_novnc_ssl_port], } } if $ceilometer { - haproxy::listen { 'ceilometer': - bind => $ceilometer_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'ceilometer': - listening_service => 'ceilometer', - ports => '8777', - ipaddresses => hiera('ceilometer_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'ceilometer': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('ceilometer_api_vip', $controller_virtual_ip), + service_port => $ports[ceilometer_api_port], + ip_addresses => hiera('ceilometer_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + public_ssl_port => $ports[ceilometer_api_ssl_port], } } if $aodh { - haproxy::listen { 'aodh': - bind => $aodh_bind_opts, - collect_exported => false, + ::tripleo::loadbalancer::endpoint { 'aodh': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('aodh_api_vip', $controller_virtual_ip), + service_port => $ports[aodh_api_port], + ip_addresses => hiera('aodh_api_node_ips', $controller_hosts_real), + server_names => $controller_hosts_names_real, + public_ssl_port => $ports[aodh_api_ssl_port], } - haproxy::balancermember { 'aodh': - listening_service => 'aodh', - ports => '8042', - ipaddresses => hiera('aodh_api_node_ips', $controller_hosts_real), + } + + if $gnocchi { + ::tripleo::loadbalancer::endpoint { 'gnocchi': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('gnocchi_api_vip', $controller_virtual_ip), + service_port => $ports[gnocchi_api_port], + ip_addresses => hiera('gnocchi_api_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + public_ssl_port => $ports[gnocchi_api_ssl_port], } } if $swift_proxy_server { - haproxy::listen { 'swift_proxy_server': - bind => $swift_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'swift_proxy_server': - listening_service => 'swift_proxy_server', - ports => '8080', - ipaddresses => hiera('swift_proxy_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'swift_proxy_server': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('swift_proxy_vip', $controller_virtual_ip), + service_port => $ports[swift_proxy_port], + ip_addresses => hiera('swift_proxy_node_ips', $controller_hosts_real), server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + public_ssl_port => $ports[swift_proxy_ssl_port], } } - if $heat_api { - haproxy::listen { 'heat_api': - bind => $heat_bind_opts, - options => $heat_options, - collect_exported => false, - mode => 'http', + $heat_api_vip = hiera('heat_api_vip', $controller_virtual_ip) + $heat_ip_addresses = hiera('heat_api_node_ips', $controller_hosts_real) + $heat_base_options = { + 'http-request' => [ + 'set-header X-Forwarded-Proto https if { ssl_fc }', + 'set-header X-Forwarded-Proto http if !{ ssl_fc }']} + if $service_certificate { + $heat_ssl_options = { + 'rsprep' => "^Location:\\ http://${public_virtual_ip}(.*) Location:\\ https://${public_virtual_ip}\\1", } - haproxy::balancermember { 'heat_api': - listening_service => 'heat_api', - ports => '8004', - ipaddresses => hiera('heat_api_node_ips', $controller_hosts_real), + $heat_options = merge($heat_base_options, $heat_ssl_options) + } else { + $heat_options = $heat_base_options + } + + if $heat_api { + ::tripleo::loadbalancer::endpoint { 'heat_api': + public_virtual_ip => $public_virtual_ip, + internal_ip => $heat_api_vip, + service_port => $ports[heat_api_port], + ip_addresses => $heat_ip_addresses, server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + mode => 'http', + listen_options => $heat_options, + public_ssl_port => $ports[heat_api_ssl_port], } } if $heat_cloudwatch { - haproxy::listen { 'heat_cloudwatch': - bind => $heat_cw_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'heat_cloudwatch': - listening_service => 'heat_cloudwatch', - ports => '8003', - ipaddresses => hiera('heat_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'heat_cloudwatch': + public_virtual_ip => $public_virtual_ip, + internal_ip => $heat_api_vip, + service_port => $ports[heat_cw_port], + ip_addresses => $heat_ip_addresses, server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + mode => 'http', + listen_options => $heat_options, + public_ssl_port => $ports[heat_cw_ssl_port], } } if $heat_cfn { - haproxy::listen { 'heat_cfn': - bind => $heat_cfn_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'heat_cfn': - listening_service => 'heat_cfn', - ports => '8000', - ipaddresses => hiera('heat_api_node_ips', $controller_hosts_real), + ::tripleo::loadbalancer::endpoint { 'heat_cfn': + public_virtual_ip => $public_virtual_ip, + internal_ip => $heat_api_vip, + service_port => $ports[heat_cfn_port], + ip_addresses => $heat_ip_addresses, server_names => $controller_hosts_names_real, - options => $haproxy_member_options, + mode => 'http', + listen_options => $heat_options, + public_ssl_port => $ports[heat_cfn_ssl_port], } } if $horizon { haproxy::listen { 'horizon': bind => $horizon_bind_opts, - options => { - 'cookie' => 'SERVERID insert indirect nocache', - }, + options => $horizon_options, mode => 'http', collect_exported => false, } @@ -1097,6 +881,17 @@ class tripleo::loadbalancer ( } } + if $ironic { + ::tripleo::loadbalancer::endpoint { 'ironic': + public_virtual_ip => $public_virtual_ip, + internal_ip => hiera('ironic_api_vip', $controller_virtual_ip), + service_port => $ports[ironic_api_port], + ip_addresses => hiera('ironic_api_node_ips', $controller_hosts_real), + server_names => $controller_hosts_names_real, + public_ssl_port => $ports[ironic_api_ssl_port], + } + } + if $mysql_clustercheck { $mysql_listen_options = { 'option' => [ 'tcpka', 'httpchk' ], @@ -1114,20 +909,6 @@ class tripleo::loadbalancer ( $mysql_member_options = union($haproxy_member_options, ['backup']) } - if $ironic { - haproxy::listen { 'ironic': - bind => $ironic_bind_opts, - collect_exported => false, - } - haproxy::balancermember { 'ironic': - listening_service => 'ironic', - ports => '6385', - ipaddresses => hiera('ironic_api_node_ips', $controller_hosts_real), - server_names => $controller_hosts_names_real, - options => $haproxy_member_options, - } - } - if $mysql { haproxy::listen { 'mysql': bind => $mysql_bind_opts, @@ -1162,13 +943,17 @@ class tripleo::loadbalancer ( } if $redis { + if $redis_password { + $redis_tcp_check_options = ["send AUTH\\ ${redis_password}\\r\\n"] + } else { + $redis_tcp_check_options = [] + } haproxy::listen { 'redis': bind => $redis_bind_opts, options => { - 'timeout' => [ 'client 0', 'server 0' ], 'balance' => 'first', 'option' => ['tcp-check',], - 'tcp-check' => ['send info\ replication\r\n','expect string role:master'], + 'tcp-check' => union($redis_tcp_check_options, ['send PING\r\n','expect string +PONG','send info\ replication\r\n','expect string role:master','send QUIT\r\n','expect string +OK']), }, collect_exported => false, } diff --git a/manifests/loadbalancer/endpoint.pp b/manifests/loadbalancer/endpoint.pp new file mode 100644 index 0000000..e6bb185 --- /dev/null +++ b/manifests/loadbalancer/endpoint.pp @@ -0,0 +1,128 @@ +# 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::loadbalancer::endpoint +# +# Configure a HAProxy listen endpoint +# +# [*internal_ip*] +# The IP in which the proxy endpoint will be listening in the internal +# network. +# +# [*service_port*] +# The default port on which the endpoint will be listening. +# +# [*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 ommited. +# Defaults to undef. +# +# [*mode*] +# HAProxy mode in which the endpoint will be listening. This can be undef, +# tcp, http or health. +# Defaults to undef. +# +# [*haproxy_listen_bind_param*] +# A list of params to be added to the HAProxy listener bind directive. +# Defaults to undef. +# +# [*listen_options*] +# Options specified for the listening service's configuration block (in +# HAproxy terms, the frontend). +# 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 +# overriding with the internal proxy endpoint (which could happen if they were +# in the same network). +# Defaults to undef. +# +# [*public_certificate*] +# Certificate path used to enable TLS for the public proxy endpoint. +# Defaults to undef. +# +# [*internal_certificate*] +# Certificate path used to enable TLS for the internal proxy endpoint. +# Defaults to undef. +# +define tripleo::loadbalancer::endpoint ( + $internal_ip, + $service_port, + $ip_addresses, + $server_names, + $member_options, + $public_virtual_ip = undef, + $mode = undef, + $haproxy_listen_bind_param = undef, + $listen_options = { + 'option' => [], + }, + $public_ssl_port = undef, + $public_certificate = undef, + $internal_certificate = undef, +) { + if $public_virtual_ip { + # service exposed to the public network + + if $public_certificate { + $public_bind_opts = { + "${public_virtual_ip}:${public_ssl_port}" => union($haproxy_listen_bind_param, ['ssl', 'crt', $public_certificate]), + } + } else { + $public_bind_opts = { + "${public_virtual_ip}:${service_port}" => $haproxy_listen_bind_param, + } + } + } else { + # internal service only + $public_bind_opts = {} + } + + if $internal_certificate { + $internal_bind_opts = { + "${internal_ip}:${service_port}" => union($haproxy_listen_bind_param, ['ssl', 'crt', $public_certificate]), + } + } else { + $internal_bind_opts = { + "${internal_ip}:${service_port}" => $haproxy_listen_bind_param, + } + } + $bind_opts = merge($internal_bind_opts, $public_bind_opts) + + haproxy::listen { "${name}": + bind => $bind_opts, + collect_exported => false, + mode => $mode, + options => $listen_options, + } + haproxy::balancermember { "${name}": + listening_service => $name, + ports => $service_port, + ipaddresses => $ip_addresses, + server_names => $server_names, + options => $member_options, + } +} diff --git a/manifests/pacemaker/haproxy_with_vip.pp b/manifests/pacemaker/haproxy_with_vip.pp new file mode 100644 index 0000000..0539beb --- /dev/null +++ b/manifests/pacemaker/haproxy_with_vip.pp @@ -0,0 +1,64 @@ +# Copyright 2016 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. +# +# == Define: tripleo::pacemaker::haproxy_with_vip +# +# Configure the vip with the haproxy under pacemaker +# +# === Parameters: +# +# [*vip_name*] +# (String) Logical name of the vip (control, public, storage ...) +# Required +# +# [*ip_address*] +# (String) IP address on which HAProxy is colocated +# Required +# +# [*ensure*] +# (Boolean) Create the all the resources only if true. False won't +# destroy the resource, it will just not create them. +# Default to true +define tripleo::pacemaker::haproxy_with_vip($vip_name, $ip_address, $ensure = true) { + if($ensure) { + if is_ipv6_address($ip_address) { + $netmask = '64' + } else { + $netmask = '32' + } + + pacemaker::resource::ip { "${vip_name}_vip": + ip_address => $ip_address, + cidr_netmask => $netmask, + } + pacemaker::constraint::base { "${vip_name}_vip-then-haproxy": + constraint_type => 'order', + first_resource => "ip-${ip_address}", + second_resource => 'haproxy-clone', + first_action => 'start', + second_action => 'start', + constraint_params => 'kind=Optional', + require => [Pacemaker::Resource::Service['haproxy'], + Pacemaker::Resource::Ip["${vip_name}_vip"]], + } + pacemaker::constraint::colocation { "${vip_name}_vip-with-haproxy": + source => "ip-${ip_address}", + target => 'haproxy-clone', + score => 'INFINITY', + require => [Pacemaker::Resource::Service['haproxy'], + Pacemaker::Resource::Ip["${vip_name}_vip"]], + } + } +} diff --git a/manifests/packages.pp b/manifests/packages.pp index c0971e9..5e111fa 100644 --- a/manifests/packages.pp +++ b/manifests/packages.pp @@ -58,12 +58,19 @@ class tripleo::packages ( exec { 'package-upgrade': command => $pkg_upgrade_cmd, path => '/usr/bin', + timeout => 0, } # A resource chain to ensure the upgrade ordering we want: - # 1) upgrade puppet managed packages (will trigger puppet dependencies) - # 2) then upgrade all packages via exec - # 3) then restart services - Package <| |> -> Exec['package-upgrade'] -> Service <| |> + # 1) Upgrade all packages via exec. + # Note: The Package Puppet resources can be managed after or before package-upgrade, + # it does not matter. what we need to make sure is that they'll notify their + # respective services (if they have ~> in their manifests or here with the ->) + # for the other packages, they'll be upgraded before any Service notify. + # This approach prevents from Puppet dependencies cycle. + # 2) This upgrade will be run before any Service notified & managed by Puppet. + # Note: For example, during the Puppet catalog, configuration will change for most of + # the services so the Services will be likely restarted after the package upgrade. + Exec['package-upgrade'] -> Service <| |> } diff --git a/manifests/profile/base/database/schemas.pp b/manifests/profile/base/database/schemas.pp new file mode 100644 index 0000000..0821ae8 --- /dev/null +++ b/manifests/profile/base/database/schemas.pp @@ -0,0 +1,101 @@ +# Copyright 2016 Red Hat, Inc. +# +# 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::profile::base::database::schemas +# +# OpenStack Database Schema profile for tripleo +# +# === Parameters +# +# [*ceilometer_backend*] +# (Optional) Name of the backend for ceilometer storage +# Defaults to hiera('ceilometer_backend') +# +# [*enable_ceilometer*] +# (Optional) Whether to create schemas for Ceilometer +# Defaults to true +# +# [*enable_cinder*] +# (Optional) Whether to create schemas for Cinder +# Defaults to true +# +# [*enable_heat*] +# (Optional) Whether to create schemas for Heat +# Defaults to true +# +# [*enable_keystone*] +# (Optional) Whether to create schemas for Keystone +# Defaults to true +# +# [*enable_glance*] +# (Optional) Whether to create schemas for Glance +# Defaults to true +# +# [*enable_nova*] +# (Optional) Whether to create schemas for Nova +# Defaults to true +# +# [*enable_neutron*] +# (Optional) Whether to create schemas for Neutron +# Defaults to true +# +# [*enable_sahara*] +# (Optional) Whether to create schemas for Sahara +# Defaults to true +# +class tripleo::profile::base::database::schemas ( + $ceilometer_backend = hiera('ceilometer_backend'), + $enable_ceilometer = true, + $enable_cinder = true, + $enable_heat = true, + $enable_keystone = true, + $enable_glance = true, + $enable_nova = true, + $enable_neutron = true, + $enable_sahara = true +) { + if $enable_ceilometer and downcase($ceilometer_backend) == 'mysql' { + include ::ceilometer::db::mysql + } + + if $enable_cinder { + include ::cinder::db::mysql + } + + if $enable_keystone { + include ::keystone::db::mysql + } + + if $enable_glance { + include ::glance::db::mysql + } + + if $enable_nova { + include ::nova::db::mysql + include ::nova::db::mysql_api + } + + if $enable_neutron { + include ::neutron::db::mysql + } + + if $enable_heat { + include ::heat::db::mysql + } + + if $enable_sahara { + include ::sahara::db::mysql + } + +} diff --git a/manifests/profile/base/keystone.pp b/manifests/profile/base/keystone.pp new file mode 100644 index 0000000..f17bf30 --- /dev/null +++ b/manifests/profile/base/keystone.pp @@ -0,0 +1,118 @@ +# Copyright 2016 Red Hat, Inc. +# +# 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::profile::base::keystone +# +# Keystone profile for tripleo +# +# === Parameters +# +# [*sync_db*] +# (Optional) Whether to run db sync +# Defaults to undef +# +# [*manage_service*] +# (Optional) Whether to manage the keystone service +# Defaults to undef +# +# [*enabled*] +# (Optional) Whether to enable the keystone service +# Defaults to undef +# +# [*bootstrap_master*] +# (Optional) The hostname of the node responsible for bootstrapping +# Defaults to hiera('bootstrap_nodeid') +# +# [*manage_roles*] +# (Optional) whether to create keystone admin role +# Defaults to true +# +# [*manage_endpoint*] +# (Optional) Whether to create keystone endpoints +# Defaults to true +# +# [*manage_db_purge*] +# (Optional) Whether keystone token flushing should be enabled +# Defaults to hiera('keystone_enable_db_purge', true) +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# +class tripleo::profile::base::keystone ( + $sync_db = undef, + $manage_service = undef, + $enabled = undef, + $bootstrap_master = undef, + $manage_roles = true, + $manage_endpoint = true, + $manage_db_purge = hiera('keystone_enable_db_purge', true), + $step = hiera('step'), +) { + + if $step >= 4 { + class { '::keystone': + sync_db => $sync_db, + manage_service => $manage_service, + enabled => $enabled, + enable_bootstrap => $bootstrap_master, + } + + include ::keystone::config + include ::keystone::wsgi::apache + + if $manage_roles { + include ::keystone::roles::admin + } + + if $manage_endpoint { + include ::keystone::endpoint + } + + #TODO: need a cleanup-keystone-tokens.sh solution here + file { [ '/etc/keystone/ssl', '/etc/keystone/ssl/certs', '/etc/keystone/ssl/private' ]: + ensure => 'directory', + owner => 'keystone', + group => 'keystone', + require => Package['keystone'], + } + file { '/etc/keystone/ssl/certs/signing_cert.pem': + content => hiera('keystone_signing_certificate'), + owner => 'keystone', + group => 'keystone', + notify => Service['keystone'], + require => File['/etc/keystone/ssl/certs'], + } + file { '/etc/keystone/ssl/private/signing_key.pem': + content => hiera('keystone_signing_key'), + owner => 'keystone', + group => 'keystone', + notify => Service['keystone'], + require => File['/etc/keystone/ssl/private'], + } + file { '/etc/keystone/ssl/certs/ca.pem': + content => hiera('keystone_ca_certificate'), + owner => 'keystone', + group => 'keystone', + notify => Service['keystone'], + require => File['/etc/keystone/ssl/certs'], + } + } + + if $step >= 5 and $manage_db_purge { + include ::keystone::cron::token_flush + } +} + diff --git a/manifests/profile/pacemaker/database/schemas.pp b/manifests/profile/pacemaker/database/schemas.pp new file mode 100644 index 0000000..6aa5906 --- /dev/null +++ b/manifests/profile/pacemaker/database/schemas.pp @@ -0,0 +1,50 @@ +# Copyright 2016 Red Hat, Inc. +# +# 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::profile::base::pacemaker::schemas +# +# OpenStack Database Schema Pacemaker HA profile for tripleo +# +# === Parameters +# +# [*ceilometer_backend*] +# (Optional) The backend used by ceilometer, usually either 'mysql' +# or 'mongodb' +# Defaults to hiera('ceilometer_backend') +# +# [*pacemaker_master*] +# (Optional) The hostname of the pacemaker master in this cluster +# Defaults to hiera('bootstrap_nodeid') +# +class tripleo::profile::pacemaker::database::schemas ( + $ceilometer_backend = hiera('ceilometer_backend'), + $pacemaker_master = hiera('bootstrap_nodeid') +) { + if downcase($pacemaker_master) == $::hostname { + include ::tripleo::profile::base::database::schemas + + if downcase($ceilometer_backend) == 'mysql' { + Exec['galera-ready'] -> Class['::ceilometer::db::mysql'] + } + + Exec['galera-ready'] -> Class['::cinder::db::mysql'] + Exec['galera-ready'] -> Class['::glance::db::mysql'] + Exec['galera-ready'] -> Class['::keystone::db::mysql'] + Exec['galera-ready'] -> Class['::nova::db::mysql'] + Exec['galera-ready'] -> Class['::nova::db::mysql_api'] + Exec['galera-ready'] -> Class['::neutron::db::mysql'] + Exec['galera-ready'] -> Class['::heat::db::mysql'] + Exec['galera-ready'] -> Class['::sahara::db::mysql'] + } +} diff --git a/manifests/profile/pacemaker/keystone.pp b/manifests/profile/pacemaker/keystone.pp new file mode 100644 index 0000000..0f007a5 --- /dev/null +++ b/manifests/profile/pacemaker/keystone.pp @@ -0,0 +1,88 @@ +# Copyright 2016 Red Hat, Inc. +# +# 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::profile::pacemaker::keystone +# +# Keystone Pacemaker HA profile for tripleo +# +# === Parameters +# +# [*bootstrap_node*] +# (Optional) The hostname of the node responsible for bootstrapping tasks +# Defaults to hiera('bootstrap_nodeid') +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# +# [*enable_load_balancer*] +# (Optional) Whether load balancing is enabled for this cluster +# Defaults to hiera('enable_load_balancer', true) +# +class tripleo::profile::pacemaker::keystone ( + $bootstrap_node = hiera('bootstrap_nodeid'), + $step = hiera('step'), + $enable_load_balancer = hiera('enable_load_balancer', true) +) { + + if $::hostname == downcase($bootstrap_node) { + $pacemaker_master = true + } else { + $pacemaker_master = false + } + + if $step >= 6 and $pacemaker_master { + $manage_roles = true + Pacemaker::Resource::Service[$::apache::params::service_name] -> Class['::keystone::roles::admin'] + Pacemaker::Resource::Service[$::apache::params::service_name] -> Class['::keystone::endpoint'] + } else { + $manage_roles = false + } + + if $step >= 4 { + class { '::tripleo::profile::base::keystone': + sync_db => $pacemaker_master, + manage_service => false, + enabled => false, + bootstrap_master => $pacemaker_master, + manage_roles => $manage_roles, + manage_endpoint => $manage_roles + } + } + + if $step >= 5 and $pacemaker_master and $enable_load_balancer { + pacemaker::constraint::base { 'haproxy-then-keystone-constraint': + constraint_type => 'order', + first_resource => 'haproxy-clone', + second_resource => 'openstack-core-clone', + first_action => 'start', + second_action => 'start', + require => [Pacemaker::Resource::Service['haproxy'], + Pacemaker::Resource::Ocf['openstack-core']], + } + } + + if $step >= 5 and $pacemaker_master { + pacemaker::constraint::base { 'rabbitmq-then-keystone-constraint': + constraint_type => 'order', + first_resource => 'rabbitmq-clone', + second_resource => 'openstack-core-clone', + first_action => 'start', + second_action => 'start', + require => [Pacemaker::Resource::Ocf['rabbitmq'], + Pacemaker::Resource::Ocf['openstack-core']], + } + } +} diff --git a/manifests/ssl/cinder_config.pp b/manifests/ssl/cinder_config.pp new file mode 100644 index 0000000..e1ed113 --- /dev/null +++ b/manifests/ssl/cinder_config.pp @@ -0,0 +1,28 @@ +# Copyright 2016 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::ssl::cinder_config +# +# Enable SSL middleware for the cinder service's pipeline. +# + +class tripleo::ssl::cinder_config { + cinder_api_paste_ini { + 'filter:ssl_header_handler/paste.filter_factory': + value => 'oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory'; + 'pipeline:apiversions/pipeline': + value => 'ssl_header_handler faultwrap osvolumeversionapp'; + } +} diff --git a/spec/classes/tripleo_packages_spec.rb b/spec/classes/tripleo_packages_spec.rb index 55a135b..80e5d7e 100644 --- a/spec/classes/tripleo_packages_spec.rb +++ b/spec/classes/tripleo_packages_spec.rb @@ -20,10 +20,7 @@ describe 'tripleo::packages' do shared_examples_for 'Red Hat distributions' do let :pre_condition do - " - package{'nova-compute': ensure => present} - service{'nova-compute': ensure => 'running'} - " + "service{'nova-compute': ensure => 'running'}" end let :facts do @@ -40,7 +37,6 @@ describe 'tripleo::packages' do end it 'should contain correct upgrade ordering' do - is_expected.to contain_package('nova-compute').that_comes_before('Exec[package-upgrade]') is_expected.to contain_exec('package-upgrade').that_comes_before('Service[nova-compute]') is_expected.to contain_exec('package-upgrade').with(:command => 'yum -y update') end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5cf9642..15d5eab 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,5 @@ require 'puppetlabs_spec_helper/module_spec_helper' require 'shared_examples' -require 'webmock/rspec' fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures')) |