# # Class to serve keystone with apache mod_wsgi in place of keystone service # # Serving keystone from apache is the recommended way to go for production # systems as the current keystone implementation is not multi-processor aware, # thus limiting the performance for concurrent accesses. # # See the following URIs for reference: # https://etherpad.openstack.org/havana-keystone-performance # http://adam.younglogic.com/2012/03/keystone-should-move-to-apache-httpd/ # # When using this class you should disable your keystone service. # # == Parameters # # [*servername*] # The servername for the virtualhost. # Optional. Defaults to $::fqdn # # [*servername_admin*] # The servername for the admin virtualhost. # Optional. Defaults to $servername # # [*public_port*] # The public port. # Optional. Defaults to 5000 # # [*admin_port*] # The admin port. # Optional. Defaults to 35357 # # [*bind_host*] # The host/ip address Apache will listen on. # Optional. Defaults to undef (listen on all ip addresses). # # [*admin_bind_host*] # The host/ip address Apache will listen on for admin API connections. # Optional. Defaults to undef or bind_host if only that setting is used. # # [*public_path*] # The prefix for the public endpoint. # Optional. Defaults to '/' # # [*admin_path*] # The prefix for the admin endpoint. # Optional. Defaults to '/' # # [*ssl*] # Use ssl ? (boolean) # Optional. Defaults to true # # [*workers*] # Number of WSGI workers to spawn. # Optional. Defaults to 1 # # [*ssl_cert*] # (optional) Path to SSL certificate # Default to apache::vhost 'ssl_*' defaults. # # [*ssl_key*] # (optional) Path to SSL key # Default to apache::vhost 'ssl_*' defaults. # # [*ssl_cert_admin*] # (optional) Path to SSL certificate for the admin endpoint. # Default to apache::vhost 'ssl_*' defaults. # # [*ssl_key_admin*] # (optional) Path to SSL key for the admin endpoint. # Default to apache::vhost 'ssl_*' defaults. # # [*ssl_chain*] # (optional) SSL chain # Default to apache::vhost 'ssl_*' defaults. # # [*ssl_ca*] # (optional) Path to SSL certificate authority # Default to apache::vhost 'ssl_*' defaults. # # [*ssl_crl_path*] # (optional) Path to SSL certificate revocation list # Default to apache::vhost 'ssl_*' defaults. # # [*ssl_crl*] # (optional) SSL certificate revocation list name # Default to apache::vhost 'ssl_*' defaults. # # [*ssl_certs_dir*] # apache::vhost ssl parameters. # Optional. Default to apache::vhost 'ssl_*' defaults. # # [*priority*] # (optional) The priority for the vhost. # Defaults to '10' # # [*threads*] # (optional) The number of threads for the vhost. # Defaults to $::processorcount # # [*wsgi_application_group*] # (optional) The application group of the WSGI script. # Defaults to '%{GLOBAL}' # # [*wsgi_pass_authorization*] # (optional) Whether HTTP authorisation headers are passed through to a WSGI # script when the equivalent HTTP request headers are present. # Defaults to 'On' # # [*wsgi_script_ensure*] # (optional) File ensure parameter for wsgi scripts. # Defaults to undef. # # [*wsgi_admin_script_source*] # (optional) Wsgi script source for the admin endpoint. If set to undef # $::keystone::params::keystone_wsgi_admin_script_path is used. This source # is copied to the apache cgi-bin path as keystone-admin. # Defaults to undef. # # [*wsgi_public_script_source*] # (optional) Wsgi script source for the public endpoint. If set to undef # $::keystone::params::keystone_wsgi_public_script_path is used. This source # is copied to the apache cgi-bin path as keystone-admin. # Defaults to undef. # # [*access_log_format*] # The log format for the virtualhost. # Optional. Defaults to false. # # [*headers*] # (optional) Headers for the vhost. # Defaults to undef. # # [*vhost_custom_fragment*] # (optional) Passes a string of custom configuration # directives to be placed at the end of the vhost configuration. # Defaults to undef. # # [*wsgi_chunked_request*] # (optional) apache::vhost wsgi_chunked_request parameter. # Defaults to undef # # DEPRECATED OPTIONS # # [*wsgi_script_source*] # (optional) Wsgi script source. # Defaults to undef. # # == Dependencies # # requires Class['apache'] & Class['keystone'] # # == Examples # # include apache # # class { 'keystone::wsgi::apache': } # # == Note about ports & paths # # When using same port for both endpoints (443 anyone ?), you *MUST* use two # different public_path & admin_path ! # # == Authors # # Francois Charlier # # == Copyright # # Copyright 2013 eNovance # class keystone::wsgi::apache ( $servername = $::fqdn, $servername_admin = undef, $public_port = 5000, $admin_port = 35357, $bind_host = undef, $admin_bind_host = undef, $public_path = '/', $admin_path = '/', $ssl = true, $workers = 1, $ssl_cert = undef, $ssl_key = undef, $ssl_cert_admin = undef, $ssl_key_admin = undef, $ssl_chain = undef, $ssl_ca = undef, $ssl_crl_path = undef, $ssl_crl = undef, $ssl_certs_dir = undef, $threads = $::processorcount, $priority = '10', $wsgi_application_group = '%{GLOBAL}', $wsgi_pass_authorization = 'On', $wsgi_chunked_request = undef, $wsgi_admin_script_source = $::keystone::params::keystone_wsgi_admin_script_path, $wsgi_public_script_source = $::keystone::params::keystone_wsgi_public_script_path, $wsgi_script_ensure = undef, $access_log_format = false, $headers = undef, $vhost_custom_fragment = undef, #DEPRECATED $wsgi_script_source = undef, ) inherits ::keystone::params { include ::keystone::deps include ::apache include ::apache::mod::wsgi $servername_admin_real = pick_default($servername_admin, $servername) if $ssl { include ::apache::mod::ssl # This is probably a bug in Class[apache::mod::ssl] or in the mod_ssl EL # package but for now I want this to pass p-o-i CI. The issue is that the # mod_ssl package is placing a ssl.conf file after the confd_dir is purged # on Puppet 4. Class['::apache::mod::ssl'] -> File[$::apache::confd_dir] # Attempt to use the admin cert/key, else default to the public one. # Since it's possible that no cert/key were given, we allow this to be # empty with pick_default $ssl_cert_admin_real = pick_default($ssl_cert_admin, $ssl_cert) $ssl_key_admin_real = pick_default($ssl_key_admin, $ssl_key) } else { $ssl_cert_admin_real = undef $ssl_key_admin_real = undef } # The httpd package is untagged, but needs to have ordering enforced, # so handle it here rather than in the deps class. Anchor['keystone::install::begin'] -> Package['httpd'] -> Anchor['keystone::install::end'] # Configure apache during the config phase Anchor['keystone::config::begin'] -> Apache::Vhost<||> ~> Anchor['keystone::config::end'] # Start the service during the service phase Anchor['keystone::service::begin'] -> Service['httpd'] -> Anchor['keystone::service::end'] # Notify the service when config changes Anchor['keystone::config::end'] ~> Service['httpd'] ## Sanitize parameters # Ensure there's no trailing '/' except if this is also the only character $public_path_real = regsubst($public_path, '(^/.*)/$', '\1') # Ensure there's no trailing '/' except if this is also the only character $admin_path_real = regsubst($admin_path, '(^/.*)/$', '\1') if $public_port == $admin_port and $public_path_real == $admin_path_real { fail('When using the same port for public & private endpoints, public_path and admin_path should be different.') } file { $::keystone::params::keystone_wsgi_script_path: ensure => directory, owner => 'keystone', group => 'keystone', require => Anchor['keystone::install::end'], } $wsgi_file_target = $wsgi_script_ensure ? { 'link' => 'target', default => 'source' } $wsgi_file_defaults = { 'ensure' => $wsgi_script_ensure, 'owner' => 'keystone', 'group' => 'keystone', 'mode' => '0644', 'require' => File[$::keystone::params::keystone_wsgi_script_path], } if $wsgi_script_source { warning('The single wsgi script source has been deprecated as part of the Mitaka cycle, please switch to \ $wsgi_admin_script_source and $wsgi_public_script_source') $wsgi_admin_source = $wsgi_script_source $wsgi_public_source = $wsgi_script_source } else { $wsgi_admin_source = $wsgi_admin_script_source $wsgi_public_source = $wsgi_public_script_source } $wsgi_files = { 'keystone_wsgi_admin' => { 'path' => "${::keystone::params::keystone_wsgi_script_path}/keystone-admin", "${wsgi_file_target}" => $wsgi_admin_source, }, 'keystone_wsgi_main' => { 'path' => "${::keystone::params::keystone_wsgi_script_path}/keystone-public", "${wsgi_file_target}" => $wsgi_public_source, }, } create_resources('file', $wsgi_files, $wsgi_file_defaults) $wsgi_daemon_process_options_main = { user => 'keystone', group => 'keystone', processes => $workers, threads => $threads, display-name => 'keystone-main', } $wsgi_daemon_process_options_admin = { user => 'keystone', group => 'keystone', processes => $workers, threads => $threads, display-name => 'keystone-admin', } $wsgi_script_aliases_main = hash([$public_path_real,"${::keystone::params::keystone_wsgi_script_path}/keystone-public"]) $wsgi_script_aliases_admin = hash([$admin_path_real, "${::keystone::params::keystone_wsgi_script_path}/keystone-admin"]) if $public_port == $admin_port { $wsgi_script_aliases_main_real = merge($wsgi_script_aliases_main, $wsgi_script_aliases_admin) } else { $wsgi_script_aliases_main_real = $wsgi_script_aliases_main } if $admin_bind_host { $real_admin_bind_host = $admin_bind_host } else { # backwards compat before we had admin_bind_host $real_admin_bind_host = $bind_host } ::apache::vhost { 'keystone_wsgi_main': ensure => 'present', servername => $servername, ip => $bind_host, port => $public_port, docroot => $::keystone::params::keystone_wsgi_script_path, docroot_owner => 'keystone', docroot_group => 'keystone', priority => $priority, ssl => $ssl, ssl_cert => $ssl_cert, ssl_key => $ssl_key, ssl_chain => $ssl_chain, ssl_ca => $ssl_ca, ssl_crl_path => $ssl_crl_path, ssl_crl => $ssl_crl, ssl_certs_dir => $ssl_certs_dir, wsgi_daemon_process => 'keystone_main', wsgi_daemon_process_options => $wsgi_daemon_process_options_main, wsgi_process_group => 'keystone_main', wsgi_script_aliases => $wsgi_script_aliases_main_real, wsgi_application_group => $wsgi_application_group, wsgi_pass_authorization => $wsgi_pass_authorization, headers => $headers, custom_fragment => $vhost_custom_fragment, wsgi_chunked_request => $wsgi_chunked_request, require => File['keystone_wsgi_main'], access_log_format => $access_log_format, } if $public_port != $admin_port { ::apache::vhost { 'keystone_wsgi_admin': ensure => 'present', servername => $servername_admin_real, ip => $real_admin_bind_host, port => $admin_port, docroot => $::keystone::params::keystone_wsgi_script_path, docroot_owner => 'keystone', docroot_group => 'keystone', priority => $priority, ssl => $ssl, ssl_cert => $ssl_cert_admin_real, ssl_key => $ssl_key_admin_real, ssl_chain => $ssl_chain, ssl_ca => $ssl_ca, ssl_crl_path => $ssl_crl_path, ssl_crl => $ssl_crl, ssl_certs_dir => $ssl_certs_dir, wsgi_daemon_process => 'keystone_admin', wsgi_daemon_process_options => $wsgi_daemon_process_options_admin, wsgi_process_group => 'keystone_admin', wsgi_script_aliases => $wsgi_script_aliases_admin, wsgi_application_group => $wsgi_application_group, wsgi_pass_authorization => $wsgi_pass_authorization, headers => $headers, custom_fragment => $vhost_custom_fragment, wsgi_chunked_request => $wsgi_chunked_request, require => File['keystone_wsgi_admin'], access_log_format => $access_log_format, } } }