puppet-horizon/spec/classes/horizon_init_spec.rb
Tobias Urdin a0468fd8cb Add access_log_format for WSGI
Adds the access_log_format parameter that can be used to set
the log format that is used in the vhosts that puppetlabs-apache
manages.

Adds the same parameter to the init class to make sure that you
can set it when managing apache from there and not including the
wsgi::apache class manually.

The default value of the parameter is the same as enforced in other
modules that has the access_log_format, which is false. That is the
default that the puppetlabs-apache module has.

Change-Id: Ie8ac84c6231ad55c5974a95b50238f0d006b6336
2018-12-10 14:49:00 +01:00

761 lines
28 KiB
Ruby

require 'spec_helper'
describe 'horizon' do
let :params do
{ 'secret_key' => 'elj1IWiLoWHgcyYxFVLj7cM5rGOOxWl0' }
end
let :pre_condition do
'include apache'
end
let :fixtures_path do
File.expand_path(File.join(__FILE__, '..', '..', 'fixtures'))
end
shared_examples_for 'horizon' do
context 'with default parameters' do
it {
is_expected.to contain_package('horizon').with(
:ensure => 'present',
:tag => ['openstack', 'horizon-package'],
)
}
it { is_expected.to contain_exec('refresh_horizon_django_cache').with({
:command => '/usr/share/openstack-dashboard/manage.py collectstatic --noinput --clear',
:refreshonly => true,
})}
it { is_expected.to contain_exec('refresh_horizon_django_compress').with({
:command => '/usr/share/openstack-dashboard/manage.py compress --force',
:refreshonly => true,
})}
it {
if facts[:os_package_type] == 'rpm'
is_expected.to contain_concat(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_cache]')
is_expected.to contain_concat(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_compress]')
else
is_expected.to_not contain_concat(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_cache]')
is_expected.to contain_concat(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_compress]')
end
}
it 'configures apache' do
is_expected.to contain_class('horizon::wsgi::apache').with({
:servername => 'some.host.tld',
:listen_ssl => false,
:wsgi_processes => facts[:os_workers],
:wsgi_threads => '1',
:extra_params => {},
:redirect_type => 'permanent',
:access_log_format => false,
})
end
it 'generates local_settings.py' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
'DEBUG = False',
"LOGIN_URL = '#{platforms_params[:root_url]}/auth/login/'",
"LOGOUT_URL = '#{platforms_params[:root_url]}/auth/logout/'",
"LOGIN_REDIRECT_URL = '#{platforms_params[:root_url]}/'",
"ALLOWED_HOSTS = ['some.host.tld', ]",
" 'identity': 3,",
'HORIZON_CONFIG["password_autocomplete"] = "off"',
'HORIZON_CONFIG["images_panel"] = "legacy"',
"SECRET_KEY = 'elj1IWiLoWHgcyYxFVLj7cM5rGOOxWl0'",
'OPENSTACK_KEYSTONE_URL = "http://127.0.0.1:5000"',
'OPENSTACK_KEYSTONE_DEFAULT_ROLE = "member"',
" 'can_set_mount_point': True,",
" 'can_set_password': False,",
" 'enable_distributed_router': False,",
" 'enable_firewall': False,",
" 'enable_ha_router': False,",
" 'enable_lb': False,",
" 'enable_quotas': True,",
" 'enable_security_group': True,",
" 'enable_vpn': False,",
'API_RESULT_LIMIT = 1000',
'TIME_ZONE = "UTC"',
'COMPRESS_OFFLINE = True',
"FILE_UPLOAD_TEMP_DIR = '/tmp'",
"OPENSTACK_HEAT_STACK = {",
" 'enable_user_pass': True",
"}",
])
# From internals of verify_contents, get the contents to check for absence of a line
content = catalogue.resource('concat::fragment', 'local_settings.py').send(:parameters)[:content]
# With default options, should _not_ have a line to configure SESSION_ENGINE
expect(content).not_to match(/^SESSION_ENGINE/)
end
it { is_expected.not_to contain_file('/tmp') }
end
context 'with overridden parameters' do
before do
params.merge!({
:cache_backend => 'horizon.backends.memcached.HorizonMemcached',
:cache_options => {'SOCKET_TIMEOUT' => 1,'SERVER_RETRIES' => 1,'DEAD_RETRY' => 1},
:cache_server_ip => '10.0.0.1',
:django_session_engine => 'django.contrib.sessions.backends.cache',
:keystone_default_role => 'SwiftOperator',
:keystone_url => 'https://keystone.example.com:4682',
:ssl_no_verify => true,
:log_handler => 'syslog',
:log_level => 'DEBUG',
:openstack_endpoint_type => 'internalURL',
:secondary_endpoint_type => 'ANY-VALUE',
:django_debug => true,
:site_branding => 'mysite',
:api_result_limit => 4682,
:compress_offline => false,
:hypervisor_options => {'can_set_mount_point' => false, 'can_set_password' => true },
:cinder_options => {'enable_backup' => true },
:keystone_options => {'name' => 'native', 'can_edit_user' => true, 'can_edit_group' => true, 'can_edit_project' => true, 'can_edit_domain' => false, 'can_edit_role' => false},
:neutron_options => {'enable_lb' => true, 'enable_firewall' => true, 'enable_quotas' => false, 'enable_security_group' => false, 'enable_vpn' => true,
'enable_distributed_router' => false, 'enable_ha_router' => false, 'profile_support' => 'cisco',
'supported_provider_types' => ['flat', 'vxlan'], 'supported_vnic_types' => ['*'], 'default_ipv4_subnet_pool_label' => 'None', },
:instance_options => {'disable_image' => true, 'disable_instance_snapshot' => true, 'disable_volume' => true, 'disable_volume_snapshot' => true, 'create_volume' => false },
:file_upload_temp_dir => '/var/spool/horizon',
:wsgi_processes => '30',
:wsgi_threads => '5',
:secure_cookies => true,
:api_versions => {'identity' => 2.0},
:keystone_multidomain_support => true,
:keystone_default_domain => 'domain.tld',
:overview_days_range => 1,
:session_timeout => 1800,
:timezone => 'Asia/Shanghai',
:available_themes => [
{ 'name' => 'default', 'label' => 'Default', 'path' => 'themes/default' },
{ 'name' => 'material', 'label' => 'Material', 'path' => 'themes/material' },
],
:default_theme => 'default',
:password_autocomplete => 'on',
:images_panel => 'angular',
:create_image_defaults => {'image_visibility' => 'private'},
:password_retrieve => true,
:enable_secure_proxy_ssl_header => true,
})
end
it 'generates local_settings.py' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
'DEBUG = True',
"SITE_BRANDING = 'mysite'",
"ALLOWED_HOSTS = ['some.host.tld', ]",
"SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')",
'CSRF_COOKIE_SECURE = True',
'SESSION_COOKIE_SECURE = True',
" 'identity': 2.0,",
"OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True",
"OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = 'domain.tld'",
'HORIZON_CONFIG["password_autocomplete"] = "on"',
'HORIZON_CONFIG["images_panel"] = "angular"',
"SECRET_KEY = 'elj1IWiLoWHgcyYxFVLj7cM5rGOOxWl0'",
" 'DEAD_RETRY': 1,",
" 'SERVER_RETRIES': 1,",
" 'SOCKET_TIMEOUT': 1,",
" 'BACKEND': 'horizon.backends.memcached.HorizonMemcached',",
" 'LOCATION': '10.0.0.1:11211',",
'SESSION_ENGINE = "django.contrib.sessions.backends.cache"',
'OPENSTACK_KEYSTONE_URL = "https://keystone.example.com:4682"',
'OPENSTACK_KEYSTONE_DEFAULT_ROLE = "SwiftOperator"',
'OPENSTACK_SSL_NO_VERIFY = True',
"OPENSTACK_KEYSTONE_BACKEND = {",
" 'name': 'native',",
" 'can_edit_user': True,",
" 'can_edit_group': True,",
" 'can_edit_project': True,",
" 'can_edit_domain': False,",
" 'can_edit_role': False,",
"}",
" 'can_set_mount_point': False,",
" 'can_set_password': True,",
" 'enable_backup': True,",
" 'default_ipv4_subnet_pool_label': None,",
" 'enable_firewall': True,",
" 'enable_lb': True,",
" 'enable_quotas': False,",
" 'enable_security_group': False,",
" 'enable_vpn': True,",
" 'profile_support': 'cisco',",
" 'supported_provider_types': ['flat', 'vxlan'],",
" 'supported_vnic_types': ['*'],",
'OPENSTACK_ENABLE_PASSWORD_RETRIEVE = True',
'CREATE_IMAGE_DEFAULTS = {',
" 'image_visibility': 'private',",
" 'config_drive': False,",
" 'create_volume': False,",
" 'disable_image': True,",
" 'disable_instance_snapshot': True,",
" 'disable_volume': True,",
" 'disable_volume_snapshot': True,",
" 'enable_scheduler_hints': True,",
'OPENSTACK_ENDPOINT_TYPE = "internalURL"',
'SECONDARY_ENDPOINT_TYPE = "ANY-VALUE"',
'API_RESULT_LIMIT = 4682',
'TIME_ZONE = "Asia/Shanghai"',
"AVAILABLE_THEMES = [",
" ('default', 'Default', 'themes/default'),",
" ('material', 'Material', 'themes/material'),",
"]",
"DEFAULT_THEME = 'default'",
" 'level': 'DEBUG',",
" 'handlers': ['syslog'],",
"SESSION_TIMEOUT = 1800",
'COMPRESS_OFFLINE = False',
"FILE_UPLOAD_TEMP_DIR = '/var/spool/horizon'",
"OVERVIEW_DAYS_RANGE = 1",
])
end
it { is_expected.not_to contain_file(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_cache]') }
it { is_expected.not_to contain_file(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_compress]') }
it { is_expected.to contain_file(params[:file_upload_temp_dir]) }
end
context 'with enable_user_pass disabled' do
before do
params.merge!({ :enable_user_pass => false })
end
it {
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
"OPENSTACK_HEAT_STACK = {",
" 'enable_user_pass': False",
"}",
])
}
end
context 'with overridden parameters and cache_server_ip array' do
before do
params.merge!({
:cache_server_ip => ['10.0.0.1','10.0.0.2'],
})
end
it 'generates local_settings.py' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
" 'LOCATION': [ '10.0.0.1:11211','10.0.0.2:11211', ],",
])
end
it { is_expected.to contain_exec('refresh_horizon_django_cache') }
it { is_expected.to contain_exec('refresh_horizon_django_compress') }
end
context 'with overridden parameters and cache_server_url' do
before do
params.merge!({
:cache_server_url => 'redis://:password@10.0.0.1:6379/1',
})
end
it 'generates local_settings.py' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
" 'LOCATION': 'redis://:password@10.0.0.1:6379/1',",
])
end
it { is_expected.to contain_exec('refresh_horizon_django_cache') }
it { is_expected.to contain_exec('refresh_horizon_django_compress') }
end
context 'installs python memcache library when cache_backend is set to memcache' do
before do
params.merge!({
:cache_backend => 'django.core.cache.backends.memcached.MemcachedCache'
})
end
it {
is_expected.to contain_package('python-memcache').with(
:tag => ['openstack', 'horizon-package'],
:name => platforms_params[:memcache_package],
)
}
end
context 'does not install python memcache when manage_memcache_package set to false' do
before do
params.merge!( :cache_backend => 'django.core.cache.backends.memcached.MemcachedCache',
:manage_memcache_package => false )
end
it { is_expected.not_to contain_package('python-memcache') }
end
context 'with custom wsgi options' do
before do
params.merge!( :wsgi_processes => '30',
:wsgi_threads => '5',
:access_log_format => 'common' )
end
it { should contain_class('horizon::wsgi::apache').with(
:wsgi_processes => '30',
:wsgi_threads => '5',
:access_log_format => 'common',
)}
end
context 'with vhost_extra_params' do
before do
params.merge!({
:vhost_extra_params => { 'add_listen' => false },
:redirect_type => 'temp',
})
end
it 'configures apache' do
is_expected.to contain_class('horizon::wsgi::apache').with({
:extra_params => { 'add_listen' => false },
:redirect_type => 'temp',
})
end
end
context 'with ssl enabled' do
before do
params.merge!({
:listen_ssl => true,
:servername => 'some.host.tld',
:horizon_cert => '/etc/pki/tls/certs/httpd.crt',
:horizon_key => '/etc/pki/tls/private/httpd.key',
:horizon_ca => '/etc/pki/tls/certs/ca.crt',
})
end
it 'configures apache' do
is_expected.to contain_class('horizon::wsgi::apache').with({
:bind_address => nil,
:listen_ssl => true,
:horizon_cert => '/etc/pki/tls/certs/httpd.crt',
:horizon_key => '/etc/pki/tls/private/httpd.key',
:horizon_ca => '/etc/pki/tls/certs/ca.crt',
})
end
end
context 'with overridden http and https ports' do
before do
params.merge!({
:http_port => 1028,
:https_port => 1029,
})
end
it 'configures apache' do
is_expected.to contain_class('horizon::wsgi::apache').with({
:http_port => 1028,
:https_port => 1029,
})
end
end
context 'with default root_path' do
it 'configures apache' do
is_expected.to contain_class('horizon::wsgi::apache').with({
:root_path => "#{platforms_params[:root_path]}",
})
end
end
context 'with root_path set to /tmp/horizon' do
before do
params.merge!({
:root_path => '/tmp/horizon',
})
end
it 'configures apache' do
is_expected.to contain_class('horizon::wsgi::apache').with({
:root_path => '/tmp/horizon',
})
end
end
context 'without apache' do
before do
params.merge!({ :configure_apache => false })
end
it 'does not configure apache' do
is_expected.not_to contain_class('horizon::wsgi::apache')
end
end
context 'with available_regions parameter' do
before do
params.merge!({
:available_regions => [
['http://region-1.example.com:5000', 'Region-1'],
['http://region-2.example.com:5000', 'Region-2']
]
})
end
it 'AVAILABLE_REGIONS is configured' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
"AVAILABLE_REGIONS = [",
" ('http://region-1.example.com:5000', 'Region-1'),",
" ('http://region-2.example.com:5000', 'Region-2'),",
"]"
])
end
end
context 'with policy parameters' do
before do
params.merge!({
:policy_files_path => '/opt/openstack-dashboard',
:policy_files => {
'compute' => 'nova_policy.json',
'identity' => 'keystone_policy.json',
'network' => 'neutron_policy.json',
}
})
end
it 'POLICY_FILES_PATH and POLICY_FILES are configured' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
"POLICY_FILES_PATH = '/opt/openstack-dashboard'",
"POLICY_FILES = {",
" 'compute': 'nova_policy.json',",
" 'identity': 'keystone_policy.json',",
" 'network': 'neutron_policy.json',",
"} # POLICY_FILES"
])
end
end
context 'with overriding local_settings_template' do
before do
params.merge!({
:django_debug => 'True',
:help_url => 'https://docs.openstack.org',
:local_settings_template => fixtures_path + '/override_local_settings.py.erb'
})
end
it 'uses the custom local_settings.py template' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
'# Custom local_settings.py',
'DEBUG = True',
"HORIZON_CONFIG = {",
" 'dashboards': ('project', 'admin', 'settings',),",
" 'default_dashboard': 'project',",
" 'user_home': 'openstack_dashboard.views.get_user_home',",
" 'ajax_queue_limit': 10,",
" 'auto_fade_alerts': {",
" 'delay': 3000,",
" 'fade_duration': 1500,",
" 'types': ['alert-success', 'alert-info']",
" },",
" 'help_url': \"https://docs.openstack.org\",",
" 'exceptions': {'recoverable': exceptions.RECOVERABLE,",
" 'not_found': exceptions.NOT_FOUND,",
" 'unauthorized': exceptions.UNAUTHORIZED},",
"}",
])
end
end
context 'with /var/tmp as upload temp dir' do
before do
params.merge!({
:file_upload_temp_dir => '/var/tmp'
})
end
it { is_expected.not_to contain_file(params[:file_upload_temp_dir]) }
end
context 'with image_backend' do
before do
params.merge!({
:image_backend => {
'image_formats' => {
'' => 'Select image format',
'aki' => 'AKI - Amazon Kernel Image',
'ami' => 'AMI - Amazon Machine Image',
'ari' => 'ARI - Amazon Ramdisk Image',
'iso' => 'ISO - Optical Disk Image',
'qcow2' => 'QCOW2 - QEMU Emulator',
'raw' => 'Raw',
'vdi' => 'VDI',
'vhi' => 'VHI',
'vmdk' => 'VMDK',
},
'architectures' => {
'' => 'Select architecture',
'x86_64' => 'x86-64',
'aarch64' => 'ARMv8',
},
},
})
end
it 'configures OPENSTACK_IMAGE_BACKEND' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
"OPENSTACK_IMAGE_BACKEND = {",
" 'image_formats': [",
" ('', _('Select image format')),",
" ('aki', _('AKI - Amazon Kernel Image')),",
" ('ami', _('AMI - Amazon Machine Image')),",
" ('ari', _('ARI - Amazon Ramdisk Image')),",
" ('iso', _('ISO - Optical Disk Image')),",
" ('qcow2', _('QCOW2 - QEMU Emulator')),",
" ('raw', _('Raw')),",
" ('vdi', _('VDI')),",
" ('vhi', _('VHI')),",
" ('vmdk', _('VMDK')),",
" ], # image_formats",
" 'architectures': [",
" ('', _('Select architecture')),",
" ('x86_64', _('x86-64')),",
" ('aarch64', _('ARMv8')),",
" ], # architectures",
"} # OPENSTACK_IMAGE_BACKEND",
])
end
end
context 'with disable password reveal enabled' do
before do
params.merge!({
:disable_password_reveal => true
})
end
it 'disable_password_reveal is configured' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
'HORIZON_CONFIG["disable_password_reveal"] = True',
])
end
end
context 'with enforce password check enabled' do
before do
params.merge!({
:enforce_password_check => true
})
end
it 'enforce_password_check is configured' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
'HORIZON_CONFIG["enforce_password_check"] = True',
])
end
end
context 'with disallow iframe embed enabled' do
before do
params.merge!({
:disallow_iframe_embed => true
})
end
it 'disallow_iframe_embed is configured' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
'HORIZON_CONFIG["disallow_iframe_embed"] = True',
])
end
end
context 'with websso enabled' do
before do
params.merge!({
:websso_enabled => 'True',
:websso_initial_choice => 'acme',
:websso_choices => [
['oidc', 'OpenID Connect'],
['saml2', 'Security Assertion Markup Language'],
],
:websso_idp_mapping => {
'acme_oidc' => ['acme', 'oidc'],
'acme_saml2' => ['acme', 'saml2'],
}
})
end
it 'configures websso options' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
'WEBSSO_ENABLED = True',
'WEBSSO_INITIAL_CHOICE = "acme"',
'WEBSSO_CHOICES = (',
' ("credentials", _("Keystone Credentials")),',
' ("oidc", _("OpenID Connect")),',
' ("saml2", _("Security Assertion Markup Language")),',
')',
'WEBSSO_IDP_MAPPING = {',
' "acme_oidc": ("acme", "oidc"),',
' "acme_saml2": ("acme", "saml2"),',
'}',
])
end
end
context 'with customization_module provided' do
before do
params.merge!({
:help_url => 'https://docs.openstack.org',
:customization_module => 'my_project.overrides',
:local_settings_template => fixtures_path + '/override_local_settings.py.erb'
})
end
it 'uses the custom local_settings.py template' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
'# Custom local_settings.py',
"HORIZON_CONFIG = {",
" 'dashboards': ('project', 'admin', 'settings',),",
" 'default_dashboard': 'project',",
" 'user_home': 'openstack_dashboard.views.get_user_home',",
" 'ajax_queue_limit': 10,",
" 'auto_fade_alerts': {",
" 'delay': 3000,",
" 'fade_duration': 1500,",
" 'types': ['alert-success', 'alert-info']",
" },",
" 'help_url': \"https://docs.openstack.org\",",
" 'exceptions': {'recoverable': exceptions.RECOVERABLE,",
" 'not_found': exceptions.NOT_FOUND,",
" 'unauthorized': exceptions.UNAUTHORIZED},",
" 'customization_module': 'my_project.overrides',",
"}",
])
end
end
context 'with customization_module empty' do
before do
params.merge!({
:help_url => 'https://docs.openstack.org',
:customization_module => '',
:local_settings_template => fixtures_path + '/override_local_settings.py.erb'
})
end
it 'uses the custom local_settings.py template' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
'# Custom local_settings.py',
"HORIZON_CONFIG = {",
" 'dashboards': ('project', 'admin', 'settings',),",
" 'default_dashboard': 'project',",
" 'user_home': 'openstack_dashboard.views.get_user_home',",
" 'ajax_queue_limit': 10,",
" 'auto_fade_alerts': {",
" 'delay': 3000,",
" 'fade_duration': 1500,",
" 'types': ['alert-success', 'alert-info']",
" },",
" 'help_url': \"https://docs.openstack.org\",",
" 'exceptions': {'recoverable': exceptions.RECOVERABLE,",
" 'not_found': exceptions.NOT_FOUND,",
" 'unauthorized': exceptions.UNAUTHORIZED},",
"}",
])
end
end
context 'with upload mode' do
before do
params.merge!({
:horizon_upload_mode => 'direct',
})
end
it 'sets HORIZON_IMAGES_UPLOAD_MODE in local_settings.py' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
'HORIZON_IMAGES_UPLOAD_MODE = direct',
])
end
end
context 'with keystone_domain_choices' do
before do
params.merge!({
:keystone_domain_choices => [
{'name' => 'default', 'display' => 'The default domain'},
{'name' => 'LDAP', 'display' => 'The LDAP Catalog'},
],
})
end
it 'sets OPENSTACK_KEYSTONE_DOMAIN_DROPDOWN in local_settings.py' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
'OPENSTACK_KEYSTONE_DOMAIN_DROPDOWN = True',
'OPENSTACK_KEYSTONE_DOMAIN_CHOICES = (',
" ('default', 'The default domain'),",
" ('LDAP', 'The LDAP Catalog'),",
')',
])
end
end
end
shared_examples_for 'horizon on RedHat' do
it 'sets WEBROOT in local_settings.py' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
"WEBROOT = '/dashboard/'",
])
end
end
shared_examples_for 'horizon on Debian' do
it 'sets WEBROOT in local_settings.py' do
verify_concat_fragment_contents(catalogue, 'local_settings.py', [
"WEBROOT = '/horizon/'",
])
end
end
on_supported_os({
:supported_os => OSDefaults.get_supported_os
}).each do |os,facts|
context "on #{os}" do
let (:facts) do
facts.merge!(OSDefaults.get_facts({
:fqdn => 'some.host.tld',
:concat_basedir => '/var/lib/puppet/concat',
:os_workers => '6'
}))
end
let(:platforms_params) do
case facts[:osfamily]
when 'Debian'
if facts[:os_package_type] == 'debian'
{ :config_file => '/etc/openstack-dashboard/local_settings.py',
:package_name => 'openstack-dashboard-apache',
:root_url => '/horizon',
:root_path => '/var/lib/openstack-dashboard',
:memcache_package => 'python3-memcache',
}
else
{ :config_file => '/etc/openstack-dashboard/local_settings.py',
:package_name => 'openstack-dashboard',
:root_url => '/horizon',
:root_path => '/var/lib/openstack-dashboard',
:memcache_package => 'python-memcache',
}
end
when 'RedHat'
{ :config_file => '/etc/openstack-dashboard/local_settings',
:package_name => 'openstack-dashboard',
:root_url => '/dashboard',
:root_path => '/usr/share/openstack-dashboard',
:memcache_package => 'python-memcached',
}
end
end
it_behaves_like 'horizon'
it_behaves_like "horizon on #{facts[:osfamily]}"
end
end
end