cookbook-openstack-dashboard/spec/apache2-server_spec.rb
Mark Vanderwiel 7c2869bab2 Trusty juno updates
* update spec platform versions
* remove old 12.04 logic

Change-Id: Iecc8a1b126924b27d54e4224fe8f2562c32b1e5d
Implements: blueprint trusty-juno
2015-02-02 16:53:12 -06:00

416 lines
16 KiB
Ruby

# encoding: UTF-8
require_relative 'spec_helper'
shared_examples 'virtualhost port configurator' do |port_attribute_name, port_attribute_value|
let(:virtualhost_directive) { "<VirtualHost \\*:#{port_attribute_value}>" }
before do
node.set['openstack']['dashboard'][port_attribute_name] = port_attribute_value
end
it "sets Listen and NameVirtualHost directives when apache's listen_ports does not include #{port_attribute_value}" do
node.set['apache']['listen_ports'] = [port_attribute_value.to_i + 1]
%w(Listen NameVirtualHost).each do |directive|
expect(chef_run).to render_file(file.name).with_content(/^#{directive} \*:#{port_attribute_value}$/)
end
end
it "does not set Listen and NameVirtualHost directives when apache's listen_ports include #{port_attribute_value}" do
node.set['apache']['listen_ports'] = [port_attribute_value]
chef_run.converge(described_recipe)
%w(Listen NameVirtualHost).each do |directive|
expect(chef_run).not_to render_file(file.name).with_content(/^#{directive} \*:#{port_attribute_value}$/)
end
end
it 'sets the VirtualHost directive' do
expect(chef_run).to render_file(file.name).with_content(/^#{virtualhost_directive}$/)
end
context 'server_hostname' do
it 'sets the value if the server_hostname is present' do
node.set['openstack']['dashboard']['server_hostname'] = 'server_hostname_value'
expect(chef_run).to render_file(file.name).with_content(/^#{virtualhost_directive}\s*ServerName server_hostname_value$/)
end
it 'does not set the value if the server_hostname is not present' do
node.set['openstack']['dashboard']['server_hostname'] = nil
expect(chef_run).not_to render_file(file.name).with_content(/^#{virtualhost_directive}\s*ServerName$/)
end
end
end
describe 'openstack-dashboard::apache2-server' do
describe 'ubuntu' do
let(:runner) { ChefSpec::Runner.new(UBUNTU_OPTS) }
let(:node) { runner.node }
let(:chef_run) do
runner.converge(described_recipe)
end
let(:chef_run_session_sql) do
node.set['openstack']['dashboard']['session_backend'] = 'sql'
runner.converge(described_recipe)
end
include_context 'non_redhat_stubs'
include_context 'dashboard_stubs'
it 'does not execute set-selinux-permissive' do
cmd = '/sbin/setenforce Permissive'
expect(chef_run).not_to run_execute(cmd)
end
it 'installs apache packages' do
expect(chef_run).to include_recipe('apache2')
expect(chef_run).to include_recipe('apache2::mod_wsgi')
expect(chef_run).to include_recipe('apache2::mod_rewrite')
expect(chef_run).to include_recipe('apache2::mod_ssl')
end
it 'does not execute set-selinux-enforcing' do
cmd = '/sbin/setenforce Enforcing ; restorecon -R /etc/httpd'
expect(chef_run).not_to run_execute(cmd)
end
describe 'certs' do
let(:crt) { chef_run.cookbook_file('/etc/ssl/certs/horizon.pem') }
let(:key) { chef_run.cookbook_file('/etc/ssl/private/horizon.key') }
let(:remote_key) { chef_run.remote_file('/etc/ssl/private/horizon.key') }
it 'has proper owner and group' do
expect(crt.owner).to eq('root')
expect(crt.group).to eq('root')
expect(key.owner).to eq('root')
expect(key.group).to eq('ssl-cert')
end
it 'has proper modes' do
expect(sprintf('%o', crt.mode)).to eq('644')
expect(sprintf('%o', key.mode)).to eq('640')
end
it 'has proper sensitvity' do
expect(crt.sensitive).to eq(true)
expect(key.sensitive).to eq(true)
end
it 'notifies restore-selinux-context' do
expect(crt).to notify('execute[restore-selinux-context]').to(:run)
expect(key).to notify('execute[restore-selinux-context]').to(:run)
end
it 'does not download certs if not needed' do
expect(chef_run).not_to create_remote_file('/etc/ssl/certs/horizon.pem')
expect(chef_run).not_to create_remote_file('/etc/ssl/private/horizon.key')
end
it 'downloads certs if needed and restarts apache' do
node.set['openstack']['dashboard']['ssl']['cert_url'] = 'http://server/mycert.pem'
node.set['openstack']['dashboard']['ssl']['key_url'] = 'http://server/mykey.key'
expect(chef_run).to create_remote_file('/etc/ssl/certs/horizon.pem').with(
sensitive: true,
user: 'root',
group: 'root',
mode: 0644
)
expect(chef_run).to create_remote_file('/etc/ssl/private/horizon.key').with(
sensitive: true,
user: 'root',
group: 'ssl-cert',
mode: 0640
)
expect(remote_key).to notify('service[apache2]').to(:restart)
end
end
it 'creates .blackhole dir with proper owner' do
dir = '/usr/share/openstack-dashboard/openstack_dashboard/.blackhole'
expect(chef_run.directory(dir).owner).to eq('root')
end
describe 'openstack-dashboard virtual host' do
let(:file) { chef_run.template('/etc/apache2/sites-available/openstack-dashboard.conf') }
it 'has proper owner' do
expect(file.owner).to eq('root')
expect(file.group).to eq('root')
end
it 'has proper modes' do
expect(sprintf('%o', file.mode)).to eq('644')
end
context 'template content' do
let(:rewrite_ssl_directive) { /^\s*RewriteEngine On\s*RewriteCond \%\{HTTPS\} off$/ }
let(:default_rewrite_rule) { %r(^\s*RewriteRule \^\(\.\*\)\$ https\://%\{HTTP_HOST\}%\{REQUEST_URI\} \[L,R\]$) }
it 'has the default banner' do
node.set['openstack']['dashboard']['custom_template_banner'] = 'custom_template_banner_value'
expect(chef_run).to render_file(file.name).with_content(/^custom_template_banner_value$/)
end
it_should_behave_like 'virtualhost port configurator', 'http_port', 8080
context 'with use_ssl enabled' do
before do
node.set['openstack']['dashboard']['use_ssl'] = true
end
it_should_behave_like 'virtualhost port configurator', 'https_port', 4433
it 'shows rewrite ssl directive' do
expect(chef_run).to render_file(file.name).with_content(rewrite_ssl_directive)
end
context 'rewrite rule' do
it 'shows the default rewrite rule when http_port is 80 and https_port is 443' do
node.set['openstack']['dashboard']['http_port'] = 80
node.set['openstack']['dashboard']['https_port'] = 443
expect(chef_run).to render_file(file.name).with_content(default_rewrite_rule)
end
it 'shows the parameterized rewrite rule when http_port is different from 80' do
https_port_value = 443
node.set['openstack']['dashboard']['http_port'] = 81
node.set['openstack']['dashboard']['https_port'] = https_port_value
expect(chef_run).to render_file(file.name)
.with_content(%r(^\s*RewriteRule \^\(\.\*\)\$ https://%\{SERVER_NAME\}:#{https_port_value}%\{REQUEST_URI\} \[L,R\]$))
end
it 'shows the parameterized rewrite rule when https_port is different from 443' do
https_port_value = 444
node.set['openstack']['dashboard']['http_port'] = 80
node.set['openstack']['dashboard']['https_port'] = https_port_value
expect(chef_run).to render_file(file.name)
.with_content(%r(^\s*RewriteRule \^\(\.\*\)\$ https://%\{SERVER_NAME\}:#{https_port_value}%\{REQUEST_URI\} \[L,R\]$))
end
end
it 'shows ssl certificate related directives defaults' do
[/^\s*SSLEngine on$/,
%r(^\s*SSLCertificateFile /etc/ssl/certs/horizon.pem$),
%r(^\s*SSLCertificateKeyFile /etc/ssl/private/horizon.key$),
/^\s*SSLProtocol All -SSLv2 -SSLv3$/].each do |ssl_certificate_directive|
expect(chef_run).to render_file(file.name).with_content(ssl_certificate_directive)
end
end
it 'shows ssl certificate related directives overrides' do
node.set['openstack']['dashboard']['ssl']['dir'] = 'ssl_dir_value'
node.set['openstack']['dashboard']['ssl']['cert'] = 'ssl_cert_value'
node.set['openstack']['dashboard']['ssl']['key'] = 'ssl_key_value'
node.set['openstack']['dashboard']['ssl']['protocol'] = 'ssl_protocol_value'
[/^\s*SSLEngine on$/,
%r(^\s*SSLCertificateFile ssl_dir_value/certs/ssl_cert_value$),
%r(^\s*SSLCertificateKeyFile ssl_dir_value/private/ssl_key_value$),
/^\s*SSLProtocol ssl_protocol_value$/].each do |ssl_certificate_directive|
expect(chef_run).to render_file(file.name).with_content(ssl_certificate_directive)
end
end
end
context 'with use_ssl disabled' do
before do
node.set['openstack']['dashboard']['use_ssl'] = false
end
it 'does not show rewrite ssl directive' do
expect(chef_run).not_to render_file(file.name).with_content(rewrite_ssl_directive)
end
it 'does not show the default rewrite rule' do
node.set['openstack']['dashboard']['http_port'] = 80
node.set['openstack']['dashboard']['https_port'] = 443
expect(chef_run).not_to render_file(file.name).with_content(default_rewrite_rule)
end
it 'does not show ssl certificate related directives' do
[/^\s*SSLEngine on$/,
/^\s*SSLCertificateFile/,
/^\s*SSLCertificateKeyFile/].each do |ssl_certificate_directive|
expect(chef_run).not_to render_file(file.name).with_content(ssl_certificate_directive)
end
end
end
it 'shows the ServerAdmin' do
node.set['apache']['contact'] = 'apache_contact_value'
expect(chef_run).to render_file(file.name).with_content(/\s*ServerAdmin apache_contact_value$/)
end
it 'sets the WSGI script alias defaults' do
expect(chef_run).to render_file(file.name).with_content(%r(^\s*WSGIScriptAlias / /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi$))
end
it 'sets the WSGI script alias' do
node.set['openstack']['dashboard']['wsgi_path'] = 'wsgi_path_value'
node.set['openstack']['dashboard']['webroot'] = 'root'
expect(chef_run).to render_file(file.name).with_content(/^\s*WSGIScriptAlias root wsgi_path_value$/)
end
it 'sets the WSGI daemon process' do
node.set['openstack']['dashboard']['horizon_user'] = 'horizon_user_value'
node.set['openstack']['dashboard']['horizon_group'] = 'horizon_group_value'
node.set['openstack']['dashboard']['dash_path'] = 'dash_path_value'
expect(chef_run).to render_file(file.name).with_content(
/^\s*WSGIDaemonProcess dashboard user=horizon_user_value group=horizon_group_value processes=3 threads=10 python-path=dash_path_value$/)
end
it 'has the default DocRoot' do
node.set['openstack']['dashboard']['dash_path'] = 'dash_path_value'
expect(chef_run).to render_file(file.name)
.with_content(%r(\s*DocumentRoot dash_path_value/.blackhole/$))
end
it 'has TraceEnable set' do
node.set['openstack']['dashboard']['traceenable'] = 'value'
expect(chef_run).to render_file(file.name)
.with_content(/^ TraceEnable value$/)
end
it 'sets the right Alias path for /static' do
node.set['openstack']['dashboard']['static_path'] = 'static_path_value'
expect(chef_run).to render_file(file.name).with_content(/^\s+Alias \/static static_path_value$/)
end
%w(dash_path static_path).each do |dir_attribute|
it "sets the #{dir_attribute} directory directive" do
node.set['openstack']['dashboard'][dir_attribute] = "#{dir_attribute}_value"
expect(chef_run).to render_file(file.name).with_content(/^\s*<Directory #{dir_attribute}_value>$/)
end
end
context 'directory options' do
it 'sets default options for apache 2.2' do
node.set['apache']['version'] = '2.2'
expect(chef_run).to render_file(file.name).with_content(/^\s*Order allow,deny\n\s*allow from all$/)
end
it 'sets default options for apache 2.4' do
expect(chef_run).to render_file(file.name).with_content(/^\s*Require all granted$/)
end
end
context 'log directives' do
before do
node.set['apache']['log_dir'] = 'log_dir_value'
end
it 'sets de ErrorLog directive' do
node.set['openstack']['dashboard']['error_log'] = 'error_log_value'
expect(chef_run).to render_file(file.name).with_content(/^\s*ErrorLog log_dir_value\/error_log_value$/)
end
it 'sets de CustomLog directive' do
node.set['openstack']['dashboard']['access_log'] = 'access_log_value'
expect(chef_run).to render_file(file.name).with_content(/^\s*CustomLog log_dir_value\/access_log_value combined$/)
end
end
it 'sets wsgi socket prefix if wsgi_socket_prefix attribute is preset' do
node.set['openstack']['dashboard']['wsgi_socket_prefix'] = '/var/run/wsgi'
expect(chef_run).to render_file(file.name).with_content(%r(^WSGISocketPrefix /var/run/wsgi$))
end
it 'omits wsgi socket prefix if wsgi_socket_prefix attribute is not preset' do
node.set['openstack']['dashboard']['wsgi_socket_prefix'] = nil
expect(chef_run).not_to render_file(file.name).with_content(/^WSGISocketPrefix $/)
end
end
it 'notifies restore-selinux-context' do
expect(file).to notify('execute[restore-selinux-context]').to(:run)
end
end
describe 'secret_key_path file' do
secret_key_path = '/var/lib/openstack-dashboard/secret_key'
let(:file) { chef_run.file(secret_key_path) }
it 'has correct ownership' do
expect(file.owner).to eq('horizon')
expect(file.group).to eq('horizon')
end
it 'has correct mode' do
expect(file.mode).to eq(00600)
end
it 'does not notify apache2 restart' do
expect(file).not_to notify('service[apache2]').to(:restart)
end
it 'has configurable path and ownership settings' do
node.set['openstack']['dashboard']['secret_key_path'] = 'somerandompath'
node.set['openstack']['dashboard']['horizon_user'] = 'somerandomuser'
node.set['openstack']['dashboard']['horizon_group'] = 'somerandomgroup'
file = chef_run.file('somerandompath')
expect(file.owner).to eq('somerandomuser')
expect(file.group).to eq('somerandomgroup')
end
describe 'secret_key_content set' do
before do
node.set['openstack']['dashboard']['secret_key_content'] = 'somerandomcontent'
end
it 'has configurable secret_key_content setting' do
expect(chef_run).to render_file(file.name).with_content('somerandomcontent')
end
it 'notifies apache2 restart when secret_key_content set' do
expect(file).to notify('service[apache2]').to(:restart)
end
end
end
it 'does not delete openstack-dashboard.conf' do
file = '/etc/httpd/conf.d/openstack-dashboard.conf'
expect(chef_run).not_to delete_file(file)
end
it 'calls apache_site to disable 000-default virtualhost' do
resource = chef_run.find_resource('execute',
'a2dissite 000-default.conf').to_hash
expect(resource).to include(
action: 'run',
params: {
enable: false,
name: '000-default'
}
)
end
it 'calls apache_site to enable openstack-dashboard virtualhost' do
resource = chef_run.find_resource('execute',
'a2ensite openstack-dashboard.conf').to_hash
expect(resource).to include(
action: 'run',
params: {
enable: true,
notifies: [:reload, 'service[apache2]', :immediately],
name: 'openstack-dashboard'
}
)
end
it 'notifies apache2 restart' do
skip 'TODO: how to test when tied to an LWRP'
end
it 'does not execute restore-selinux-context' do
cmd = 'restorecon -Rv /etc/httpd /etc/pki; chcon -R -t httpd_sys_content_t /usr/share/openstack-dashboard || :'
expect(chef_run).not_to run_execute(cmd)
end
end
end