diff --git a/deployment/puppet/openstack/manifests/horizon.pp b/deployment/puppet/openstack/manifests/horizon.pp deleted file mode 100644 index bb64e1f6fe..0000000000 --- a/deployment/puppet/openstack/manifests/horizon.pp +++ /dev/null @@ -1,159 +0,0 @@ -# -# == Class: openstack::horizon -# -# Class to install / configure horizon. -# Will eventually include apache and ssl. -# -# NOTE: Will the inclusion of memcache be an issue? -# Such as if the server already has memcache installed? -# -jtopjian -# -# === Parameters -# -# See params.pp -# -# === Examples -# -# class { 'openstack::horizon': -# secret_key => 'dummy_secret_key', -# } -# - -class openstack::horizon ( - $secret_key, - $bind_address = '127.0.0.1', - $cache_server_ip = '127.0.0.1', - $cache_server_port = '11211', - $neutron = false, - $neutron_options = {}, - $cinder_options = {}, - $horizon_app_links = undef, - $keystone_url = 'http://127.0.0.1:5000/v2.0/', - $keystone_default_role = '_member_', - $verbose = false, - $debug = false, - $api_result_limit = 1000, - $package_ensure = present, - $use_ssl = false, - $ssl_no_verify = false, - $use_syslog = false, - $log_level = 'WARNING', - $django_session_engine = 'django.contrib.sessions.backends.cache', - $servername = $::hostname, - $cache_backend = undef, - $cache_options = undef, - $log_handler = 'file', - $custom_theme_path = undef, - $apache_options = '-Indexes', - $headers = ['set X-XSS-Protection "1; mode=block"', - 'set X-Content-Type-Options nosniff', - 'always append X-Frame-Options SAMEORIGIN'], - $hypervisor_options = {}, - $overview_days_range = undef, - $file_upload_temp_dir = '/tmp', - $file_upload_max_size = '0', - $api_versions = {'identity' => 3}, -) { - - include ::horizon::params - - if $debug { #syslog and nondebug case - #We don't realy want django debug, it is too verbose. - $django_debug = false - $django_verbose = false - $log_level_real = 'DEBUG' - } elsif $verbose { - $django_verbose = true - $django_debug = false - $log_level_real = 'INFO' - } else { - $django_verbose = false - $django_debug = false - $log_level_real = $log_level - } - - # Listen directives with host required for ip_based vhosts - class { 'osnailyfacter::apache': - listen_ports => hiera_array('apache_ports', ['0.0.0.0:80', '0.0.0.0:8888']), - } - - class { '::horizon': - bind_address => $bind_address, - cache_server_ip => $cache_server_ip, - cache_server_port => $cache_server_port, - cache_backend => $cache_backend, - cache_options => $cache_options, - secret_key => $secret_key, - package_ensure => $package_ensure, - horizon_app_links => $horizon_app_links, - keystone_url => $keystone_url, - keystone_default_role => $keystone_default_role, - django_debug => $django_debug, - api_result_limit => $api_result_limit, - listen_ssl => $use_ssl, - ssl_no_verify => $ssl_no_verify, - log_level => $log_level_real, - configure_apache => false, - django_session_engine => $django_session_engine, - allowed_hosts => '*', - secure_cookies => false, - log_handler => $log_handler, - cinder_options => $cinder_options, - neutron_options => $neutron_options, - custom_theme_path => $custom_theme_path, - redirect_type => 'temp', # LP#1385133 - hypervisor_options => $hypervisor_options, - overview_days_range => $overview_days_range, - file_upload_temp_dir => $file_upload_temp_dir, - api_versions => $api_versions, - } - - # Always run collectstatic&compress for MOS/UCA packages - Concat[$::horizon::params::config_file] ~> Exec['refresh_horizon_django_cache'] - - # Performance optimization for wsgi - if ($::memorysize_mb < 1200 or $::processorcount <= 3) { - $wsgi_processes = 2 - $wsgi_threads = 9 - } else { - $wsgi_processes = $::processorcount - $wsgi_threads = 15 - } - - class { '::horizon::wsgi::apache': - priority => false, - bind_address => $bind_address, - wsgi_processes => $wsgi_processes, - wsgi_threads => $wsgi_threads, - listen_ssl => $use_ssl, - extra_params => { - add_listen => false, - ip_based => true, # Do not setup outdated 'NameVirtualHost' option - custom_fragment => template('openstack/horizon/wsgi_vhost_custom.erb'), - default_vhost => true, - headers => $headers, - options => $apache_options, - setenvif => 'X-Forwarded-Proto https HTTPS=1', - access_log_format => '%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"', - }, - } ~> - Service[$::apache::params::service_name] - - # Chown dashboard dir - $dashboard_directory = '/usr/share/openstack-dashboard/' - $wsgi_user = $::horizon::params::apache_user - $wsgi_group = $::horizon::params::apache_group - - exec { 'chown_dashboard' : - command => "chown -R ${wsgi_user}:${wsgi_group} ${dashboard_directory}", - path => [ '/usr/sbin', '/usr/bin', '/sbin', '/bin' ], - refreshonly => true, - provider => 'shell', - } - - # Refresh cache should be executed only for rpm packages. - # See I813b5f6067bb6ecce279cab7278d9227c4d31d28 for details. - if $::os_package_type == 'rpm' { - Exec['refresh_horizon_django_cache'] ~> Exec['chown_dashboard'] - } -} diff --git a/deployment/puppet/openstack/spec/classes/openstack_horizon_spec.rb b/deployment/puppet/openstack/spec/classes/openstack_horizon_spec.rb deleted file mode 100644 index a9c803ac94..0000000000 --- a/deployment/puppet/openstack/spec/classes/openstack_horizon_spec.rb +++ /dev/null @@ -1,100 +0,0 @@ -require 'spec_helper' - -describe 'openstack::horizon' do - - let(:upload_dir) { '/var/lib/horizon/tmp' } - - let(:default_params) { { - :debug => false, - :fqdn => 'some.host.tld' - } } - - let(:params) { { - :secret_key => 'very_secret_key', - :file_upload_max_size => '10737418235', - :file_upload_temp_dir => upload_dir, - :cinder_options => { 'enable_backup' => false }, - } } - - let :facts do - { :concat_basedir => '/var/lib/puppet/concat', - :fqdn => 'some.host.tld' - } - end - - shared_examples_for 'horizon configuration' do - let :p do - default_params.merge(params) - end - - - context 'with a default config' do - it 'contains openstack::horizon' do - should contain_class('openstack::horizon') - # .with( - # :file_upload_temp_dir => '/var/lib/horizon/tmp' - # ) - end - - it 'contains horizon' do - should contain_class('horizon').with( - :cinder_options => p[:cinder_options] - ) - end - - it 'contains horizon::wsgi::apache' do - if facts[:osfamily] == 'Debian' - custom_fragment = "\n \n Order allow,deny\n Allow from all\n \n\n LimitRequestBody 10737418235\n\n" - elsif facts[:osfamily] == 'RedHat' - custom_fragment = "\n \n \n SetOutputFilter DEFLATE\n \n # Make sure proxies don't deliver the wrong content\n Header append Vary User-Agent env=!dont-vary\n \n \n\n Order allow,deny\n Allow from all\n \n\n \n \n ExpiresActive On\n ExpiresDefault \"access 6 month\"\n \n \n SetOutputFilter DEFLATE\n \n\n Order allow,deny\n Allow from all\n \n\n LimitRequestBody 10737418235\n\n" - end - - should contain_class('horizon::wsgi::apache').with( - :extra_params => { - 'add_listen' => false, - 'ip_based' => true, - 'custom_fragment' => custom_fragment, - 'default_vhost' => true, - 'headers' => ["set X-XSS-Protection \"1; mode=block\"", "set X-Content-Type-Options nosniff", "always append X-Frame-Options SAMEORIGIN"], - 'options' => '-Indexes', - 'setenvif' => 'X-Forwarded-Proto https HTTPS=1', - 'access_log_format' => '%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"' - } - ) - end - end - end - - context 'on Debian platforms' do - before do - facts.merge!( - { :osfamily => 'Debian', - :operatingsystem => 'Debian', - :operatingsystemrelease => '8', - :hostname => 'hostname.example.com', - :physicalprocessorcount => 2, - :memorysize_mb => 1024, - :openstack_version => {'nova' => 'present' }, - }) - end - - it_configures 'horizon configuration' - end - - context 'on RedHat platforms' do - before do - facts.merge!( - { :osfamily => 'RedHat', - :operatingsystem => 'RedHat', - :operatingsystemrelease => '6.6', - :hostname => 'hostname.example.com', - :physicalprocessorcount => 2, - :memorysize_mb => 1024, - :openstack_version => {'nova' => 'present' }, - }) - end - - it_configures 'horizon configuration' - end - -end diff --git a/deployment/puppet/osnailyfacter/modular/horizon/horizon.pp b/deployment/puppet/osnailyfacter/modular/horizon/horizon.pp index 67359abdaf..67529a98ec 100644 --- a/deployment/puppet/osnailyfacter/modular/horizon/horizon.pp +++ b/deployment/puppet/osnailyfacter/modular/horizon/horizon.pp @@ -3,12 +3,14 @@ notice('MODULAR: horizon.pp') prepare_network_config(hiera_hash('network_scheme', {})) $horizon_hash = hiera_hash('horizon', {}) $service_endpoint = hiera('service_endpoint') -$memcached_server = hiera('memcached_addresses') +$cache_server_ip = hiera('memcached_addresses') $bind_address = get_network_role_property('horizon', 'ipaddr') $storage_hash = hiera_hash('storage', {}) $neutron_advanced_config = hiera_hash('neutron_advanced_configuration', {}) -$public_ssl_hash = hiera_hash('public_ssl') -$ssl_no_verify = $public_ssl_hash['horizon'] +$public_ssl = hiera('public_ssl') +$ssl_no_verify = $public_ssl['horizon'] +$use_ssl = hiera('horizon_use_ssl', false) + $overview_days_range = pick($horizon_hash['overview_days_range'], 1) $external_lb = hiera('external_lb', false) @@ -30,12 +32,12 @@ $custom_theme_path = undef # of the MOS package set. This should be contributed upstream and then we can # use this as the default. #if !$::os_package_type or $::os_package_type == 'debian' { -# $horizon_cache_backend = try_get_value($horizon_hash, 'cache_backend', 'horizon.backends.memcached.HorizonMemcached') +# $cache_backend = try_get_value($horizon_hash, 'cache_backend', 'horizon.backends.memcached.HorizonMemcached') #} else { -# $horizon_cache_backend = try_get_value($horizon_hash, 'cache_backend', 'django.core.cache.backends.memcached.MemcachedCache') +# $cache_backend = try_get_value($horizon_hash, 'cache_backend', 'django.core.cache.backends.memcached.MemcachedCache') #} # Don't use custom backend until its code lands to MOS 9.0. -$horizon_cache_backend = try_get_value($horizon_hash, 'cache_backend', 'django.core.cache.backends.memcached.MemcachedCache') +$cache_backend = try_get_value($horizon_hash, 'cache_backend', 'django.core.cache.backends.memcached.MemcachedCache') $neutron_dvr = pick($neutron_advanced_config['neutron_dvr'], false) @@ -63,37 +65,105 @@ else { $file_upload_temp_dir = pick($horizon_hash['upload_dir'], "${temp_root_prefix}/tmp") +class {'::osnailyfacter::wait_for_keystone_backends':} +Class['::horizon'] -> Class['::osnailyfacter::wait_for_keystone_backends'] + +include ::tweaks::apache_wrappers + +include ::horizon::params + +if pick($horizon_hash['debug'], hiera('debug')) { + $log_level = 'DEBUG' +} elsif pick($horizon_hash['verbose'], hiera('verbose', true)) { + $log_level = 'INFO' +} else { + $log_level = 'WARNING' +} + +# Listen directives with host required for ip_based vhosts +class { 'osnailyfacter::apache': + listen_ports => hiera_array('apache_ports', ['0.0.0.0:80', '0.0.0.0:8888']), +} + +class { '::horizon': + bind_address => $bind_address, + cache_server_ip => $cache_server_ip, + cache_server_port => hiera('memcache_server_port', '11211'), + cache_backend => $cache_backend, + cache_options => {'SOCKET_TIMEOUT' => 1,'SERVER_RETRIES' => 1,'DEAD_RETRY' => 1}, + secret_key => $secret_key, + keystone_url => $keystone_url, + listen_ssl => $use_ssl, + ssl_no_verify => $ssl_no_verify, + log_level => $log_level, + configure_apache => false, + django_session_engine => 'django.contrib.sessions.backends.cache', + allowed_hosts => '*', + secure_cookies => false, + cinder_options => $cinder_options, + neutron_options => $neutron_options, + custom_theme_path => $custom_theme_path, + redirect_type => 'temp', # LP#1385133 + hypervisor_options => $hypervisor_options, + overview_days_range => $overview_days_range, + file_upload_temp_dir => $file_upload_temp_dir, + api_versions => {'identity' => 3}, +} + +# Always run collectstatic&compress for MOS/UCA packages +Concat[$::horizon::params::config_file] ~> Exec['refresh_horizon_django_cache'] + +# Performance optimization for wsgi +if ($::memorysize_mb < 1200 or $::processorcount <= 3) { + $wsgi_processes = 2 + $wsgi_threads = 9 +} else { + $wsgi_processes = $::processorcount + $wsgi_threads = 15 +} + +$headers = ['set X-XSS-Protection "1; mode=block"', + 'set X-Content-Type-Options nosniff', + 'always append X-Frame-Options SAMEORIGIN'] +$options = '-Indexes' + # 10G by default $file_upload_max_size = pick($horizon_hash['upload_max_size'], 10737418235) -class { 'openstack::horizon': - secret_key => $secret_key, - cache_server_ip => $memcached_server, - package_ensure => hiera('horizon_package_ensure', 'installed'), - bind_address => $bind_address, - cache_server_port => hiera('memcache_server_port', '11211'), - cache_backend => $horizon_cache_backend, - cache_options => {'SOCKET_TIMEOUT' => 1,'SERVER_RETRIES' => 1,'DEAD_RETRY' => 1}, - neutron => hiera('use_neutron'), - keystone_url => $keystone_url, - use_ssl => hiera('horizon_use_ssl', false), - ssl_no_verify => $ssl_no_verify, - verbose => pick($horizon_hash['verbose'], hiera('verbose', true)), - debug => pick($horizon_hash['debug'], hiera('debug')), - use_syslog => hiera('use_syslog', true), - hypervisor_options => $hypervisor_options, - servername => hiera('public_vip'), - cinder_options => $cinder_options, - neutron_options => $neutron_options, - overview_days_range => $overview_days_range, - file_upload_temp_dir => $file_upload_temp_dir, - file_upload_max_size => $file_upload_max_size, - custom_theme_path => $custom_theme_path, - api_versions => {'identity' => 3}, +class { '::horizon::wsgi::apache': + priority => false, + bind_address => $bind_address, + wsgi_processes => $wsgi_processes, + wsgi_threads => $wsgi_threads, + listen_ssl => $use_ssl, + extra_params => { + add_listen => false, + ip_based => true, # Do not setup outdated 'NameVirtualHost' option + custom_fragment => template('osnailyfacter/horizon/wsgi_vhost_custom.erb'), + default_vhost => true, + headers => $headers, + options => $options, + setenvif => 'X-Forwarded-Proto https HTTPS=1', + access_log_format => '%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"', + }, +} ~> +Service[$::apache::params::service_name] + +# Chown dashboard dir +$dashboard_directory = '/usr/share/openstack-dashboard/' +$wsgi_user = $::horizon::params::apache_user +$wsgi_group = $::horizon::params::apache_group + +exec { 'chown_dashboard' : + command => "chown -R ${wsgi_user}:${wsgi_group} ${dashboard_directory}", + path => [ '/usr/sbin', '/usr/bin', '/sbin', '/bin' ], + refreshonly => true, + provider => 'shell', } +# Refresh cache should be executed only for rpm packages. +# See I813b5f6067bb6ecce279cab7278d9227c4d31d28 for details. +if $::os_package_type == 'rpm' { + Exec['refresh_horizon_django_cache'] ~> Exec['chown_dashboard'] +} -class {'::osnailyfacter::wait_for_keystone_backends':} -Class['openstack::horizon'] -> Class['::osnailyfacter::wait_for_keystone_backends'] - -include ::tweaks::apache_wrappers diff --git a/deployment/puppet/openstack/templates/horizon/wsgi_vhost_custom.erb b/deployment/puppet/osnailyfacter/templates/horizon/wsgi_vhost_custom.erb similarity index 100% rename from deployment/puppet/openstack/templates/horizon/wsgi_vhost_custom.erb rename to deployment/puppet/osnailyfacter/templates/horizon/wsgi_vhost_custom.erb diff --git a/tests/noop/spec/hosts/horizon/horizon_spec.rb b/tests/noop/spec/hosts/horizon/horizon_spec.rb index c70b50626f..74f3e85aca 100644 --- a/tests/noop/spec/hosts/horizon/horizon_spec.rb +++ b/tests/noop/spec/hosts/horizon/horizon_spec.rb @@ -67,6 +67,34 @@ describe manifest do end end + let(:horizon_hash) { Noop.hiera_hash 'horizon', {} } + let(:file_upload_max_size) do + Noop.puppet_function 'pick', horizon_hash['upload_max_size'], '10737418235' + end + + it 'contains ::horizon::wsgi::apache' do + if facts[:osfamily] == 'Debian' and file_upload_max_size + custom_fragment = "\n \n Order allow,deny\n Allow from all\n \n\n LimitRequestBody #{file_upload_max_size}\n\n" + elsif facts[:osfamily] == 'Debian' and not file_upload_max_size + custom_fragment = "\n \n Order allow,deny\n Allow from all\n \n\n" + elsif facts[:osfamily] == 'RedHat' + custom_fragment = "\n \n \n SetOutputFilter DEFLATE\n \n # Make sure proxies don't deliver the wrong content\n Header append Vary User-Agent env=!dont-vary\n \n \n\n Order allow,deny\n Allow from all\n \n\n \n \n ExpiresActive On\n ExpiresDefault \"access 6 month\"\n \n \n SetOutputFilter DEFLATE\n \n\n Order allow,deny\n Allow from all\n \n\n LimitRequestBody 10737418235\n\n" + end + + should contain_class('horizon::wsgi::apache').with( + 'extra_params' => { + 'add_listen' => false, + 'ip_based' => true, + 'custom_fragment' => custom_fragment, + 'default_vhost' => true, + 'headers' => ["set X-XSS-Protection \"1; mode=block\"", "set X-Content-Type-Options nosniff", "always append X-Frame-Options SAMEORIGIN"], + 'options' => '-Indexes', + 'setenvif' => 'X-Forwarded-Proto https HTTPS=1', + 'access_log_format' => '%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"' + } + ) + end + storage_hash = Noop.hiera_hash 'storage' let(:cinder_options) do { 'enable_backup' => storage_hash.fetch('volumes_ceph', false) } @@ -74,16 +102,16 @@ describe manifest do ########################################################################### - it 'should declare openstack::horizon class' do - should contain_class('openstack::horizon').with( + it 'should declare horizon class' do + should contain_class('horizon').with( 'cinder_options' => cinder_options, 'hypervisor_options' => {'enable_quotas' => nova_quota}, 'bind_address' => bind_address ) end - it 'should declare openstack::horizon class with keystone_url with v3 API version' do - should contain_class('openstack::horizon').with( + it 'should declare horizon class with keystone_url with v3 API version' do + should contain_class('horizon').with( 'keystone_url' => keystone_url, 'cache_server_ip' => memcache_servers, 'cache_server_port' => memcache_server_port, @@ -116,7 +144,7 @@ describe manifest do context 'with Neutron DVR', :if => Noop.hiera_structure('neutron_advanced_configuration/neutron_dvr') do it 'should configure horizon for neutron DVR' do - should contain_class('openstack::horizon').with( + should contain_class('horizon').with( 'neutron_options' => { 'enable_distributed_router' => Noop.hiera_structure('neutron_advanced_configuration/neutron_dvr') } @@ -126,8 +154,8 @@ describe manifest do it 'should have explicit ordering between LB classes and particular actions' do - expect(graph).to ensure_transitive_dependency("Class[openstack::horizon]", "Haproxy_backend_status[keystone-public]") - expect(graph).to ensure_transitive_dependency("Class[openstack::horizon]", "Haproxy_backend_status[keystone-admin]") + expect(graph).to ensure_transitive_dependency("Class[horizon]", "Haproxy_backend_status[keystone-public]") + expect(graph).to ensure_transitive_dependency("Class[horizon]", "Haproxy_backend_status[keystone-admin]") end