cookbook-openstack-identity/spec/server-apache_spec.rb
Jens Harbott 87d4d2ed40 Use python3 packages on Ubuntu
Python2.7 is going EOL soon, let us deploy python3 for Rocky from the
start, so we avoid having to switch later.

Also update Berksfile to allow dependency testing and require chef >= 14 now.

Change-Id: Id4c06c8fc136ae3cde97e751373049db989de21e
2019-11-26 10:46:40 +00:00

414 lines
15 KiB
Ruby

# encoding: UTF-8
#
require_relative 'spec_helper'
describe 'openstack-identity::server-apache' do
describe 'ubuntu' do
let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) }
let(:node) { runner.node }
let(:chef_run) do
runner.converge(described_recipe)
end
include Helpers
include_context 'identity_stubs'
service_name = 'keystone'
service_user = 'admin'
region = 'RegionOne'
project_name = 'admin'
role_name = 'admin'
password = 'admin'
public_url = 'http://127.0.0.1:5000/v3'
it 'runs logging recipe if node attributes say to' do
node.override['openstack']['identity']['syslog']['use'] = true
expect(chef_run).to include_recipe('openstack-common::logging')
end
it 'does not run logging recipe' do
expect(chef_run).not_to include_recipe('openstack-common::logging')
end
it 'upgrades mysql python packages' do
expect(chef_run).to upgrade_package('identity cookbook package python3-mysqldb')
end
it 'upgrades memcache python packages' do
expect(chef_run).to upgrade_package('identity cookbook package python3-memcache')
end
it 'upgrades keystone packages' do
expect(chef_run).to upgrade_package('identity cookbook package python3-keystone')
expect(chef_run).to upgrade_package('identity cookbook package keystone')
end
it 'bootstrap with keystone-manage' do
expect(chef_run).to run_execute('bootstrap_keystone').with(command: "keystone-manage bootstrap \\
--bootstrap-password #{password} \\
--bootstrap-username #{service_user} \\
--bootstrap-project-name #{project_name} \\
--bootstrap-role-name #{role_name} \\
--bootstrap-service-name #{service_name} \\
--bootstrap-region-id #{region} \\
--bootstrap-admin-url #{public_url} \\
--bootstrap-public-url #{public_url} \\
--bootstrap-internal-url #{public_url}")
end
describe '/etc/keystone' do
let(:dir) { chef_run.directory('/etc/keystone') }
it 'creates directory /etc/keystone' do
expect(chef_run).to create_directory(dir.name).with(
user: 'keystone',
group: 'keystone',
mode: 0o0700
)
end
end
describe '/etc/keystone/domains' do
let(:dir) { '/etc/keystone/domains' }
it 'does not create /etc/keystone/domains by default' do
expect(chef_run).not_to create_directory(dir)
end
it 'creates /etc/keystone/domains when domain_specific_drivers_enabled enabled' do
node.override['openstack']['identity']['domain_specific_drivers_enabled'] = true
expect(chef_run).to create_directory(dir).with(
user: 'keystone',
group: 'keystone',
mode: 0o0700
)
end
end
it 'deletes keystone.db' do
expect(chef_run).to delete_file('/var/lib/keystone/keystone.db')
end
it 'does not delete keystone.db when configured to use sqlite' do
node.override['openstack']['db']['identity']['service_type'] = 'sqlite'
expect(chef_run).not_to delete_file('/var/lib/keystone/keystone.db')
end
describe 'keystone.conf' do
let(:path) { '/etc/keystone/keystone.conf' }
let(:resource) { chef_run.template(path) }
describe 'file properties' do
it 'creates /etc/keystone/keystone.conf' do
expect(chef_run).to create_template(resource.name).with(
user: 'keystone',
group: 'keystone',
mode: 0o0640
)
end
end
it 'has no list_limits by default' do
expect(chef_run).not_to render_config_file(path).with_section_content('DEFAULT', /^list_limit = /)
end
it 'has default transport_url/AMQP options set' do
[%r{^transport_url = rabbit://openstack:mypass@127.0.0.1:5672$}].each do |line|
expect(chef_run).to render_file(path).with_content(line)
end
end
describe '[DEFAULT] section' do
describe 'syslog configuration' do
log_file = %r{^log_dir = /var/log/keystone$}
log_conf = %r{^log_config_append = /\w+}
it 'renders log_file correctly' do
expect(chef_run).to render_config_file(path).with_section_content('DEFAULT', log_file)
expect(chef_run).not_to render_config_file(path).with_section_content('DEFAULT', log_conf)
end
it 'renders log_config correctly' do
node.override['openstack']['identity']['syslog']['use'] = true
expect(chef_run).to render_config_file(path).with_section_content('DEFAULT', log_conf)
expect(chef_run).not_to render_config_file(path).with_section_content('DEFAULT', log_file)
end
end
it 'has correct endpoints' do
# values correspond to node attrs set in chef_run above
pub = line_regexp('public_endpoint = http://127.0.0.1:5000/')
expect(chef_run).to render_config_file(path).with_section_content('DEFAULT', pub)
end
end
describe '[memcache] section' do
it 'has no servers by default' do
# `Openstack#memcached_servers' is stubbed in spec_helper.rb to
# return an empty array, so we expect an empty `servers' list.
r = line_regexp('servers = ')
expect(chef_run).to render_config_file(path).with_section_content('memcache', r)
end
it 'has servers when hostnames are configured' do
# Re-stub `Openstack#memcached_servers' here
hosts = ['host1:111', 'host2:222']
r = line_regexp("servers = #{hosts.join(',')}")
allow_any_instance_of(Chef::Recipe).to receive(:memcached_servers)
.and_return(hosts)
expect(chef_run).to render_config_file(path).with_section_content('memcache', r)
end
end
describe '[sql] section' do
it 'has a connection' do
r = /^connection = \w+/
expect(chef_run).to render_config_file(path).with_section_content('database', r)
end
end
describe '[ldap] section' do
describe 'optional nil attributes' do
optional_attrs = %w(group_tree_dn group_filter user_filter
user_tree_dn user_enabled_emulation_dn
group_attribute_ignore role_attribute_ignore
role_tree_dn role_filter project_tree_dn
project_enabled_emulation_dn project_filter
project_attribute_ignore)
it 'does not configure attributes' do
optional_attrs.each do |a|
r = /^#{Regexp.quote(a)} = $/
expect(chef_run).not_to render_config_file(path).with_section_content('ldap', r)
end
end
context 'ssl settings' do
context 'when use_tls disabled' do
it 'does not set tls_ options if use_tls is disabled' do
[/^tls_cacertfile = /, /^tls_cacertdir = /, /^tls_req_cert = /].each do |setting|
expect(chef_run).not_to render_config_file(path).with_section_content('ldap', setting)
end
end
end
context 'when use_tls enabled' do
before do
node.override['openstack']['identity']['ldap']['use_tls'] = true
end
end
end
end
end
describe '[assignment] section' do
it 'configures driver' do
r = line_regexp('driver = sql')
expect(chef_run).to render_config_file(path).with_section_content('assignment', r)
end
end
describe '[policy] section' do
it 'configures driver' do
r = line_regexp('driver = sql')
expect(chef_run).to render_config_file(path).with_section_content('policy', r)
end
end
end
describe 'db_sync' do
let(:cmd) { 'keystone-manage db_sync' }
it 'runs migrations' do
expect(chef_run).to run_execute(cmd).with(
user: 'root'
)
end
it 'does not run migrations' do
node.override['openstack']['db']['identity']['migrate'] = false
expect(chef_run).not_to run_execute(cmd).with(
user: 'root'
)
end
end
describe 'keystone-paste.ini as template' do
let(:path) { '/etc/keystone/keystone-paste.ini' }
it 'has default api pipeline values' do
expect(chef_run).to render_config_file(path).with_section_content(
'pipeline:api_v3',
/^pipeline = healthcheck cors sizelimit http_proxy_to_wsgi osprofiler url_normalize request_id build_auth_context token_auth json_body ec2_extension_v3 s3_extension service_v3$/
)
end
it 'template api pipeline set correct' do
node.override['openstack']['identity']['pipeline']['api_v3'] = 'service_v3'
expect(chef_run).to render_config_file(path).with_section_content(
'pipeline:api_v3',
/^pipeline = service_v3$/
)
end
it 'template misc_paste array correctly' do
node.override['openstack']['identity']['misc_paste'] = ['MISC1 = OPTION1', 'MISC2 = OPTION2']
expect(chef_run).to render_file(path).with_content(
/^MISC1 = OPTION1$/
)
expect(chef_run).to render_file(path).with_content(
/^MISC2 = OPTION2$/
)
end
end
describe 'keystone-paste.ini as remote file' do
before { node.override['openstack']['identity']['pastefile_url'] = 'http://server/mykeystone-paste.ini' }
let(:remote_paste) { chef_run.remote_file('/etc/keystone/keystone-paste.ini') }
it 'uses a remote file if pastefile_url is specified' do
expect(chef_run).to create_remote_file_if_missing('/etc/keystone/keystone-paste.ini').with(
source: 'http://server/mykeystone-paste.ini',
user: 'keystone',
group: 'keystone',
mode: 0o0644
)
end
end
describe 'apache setup' do
it 'set apache addresses and ports' do
expect(chef_run.node['apache']['listen']).to eq(%w(127.0.0.1:5000))
end
describe 'apache recipes' do
it 'include apache recipes' do
expect(chef_run).to include_recipe('apache2')
expect(chef_run).not_to include_recipe('apache2::mod_wsgi')
expect(chef_run).not_to include_recipe('apache2::mod_ssl')
end
it 'include apache recipes' do
node.override['openstack']['identity']['ssl']['enabled'] = true
expect(chef_run).to include_recipe('apache2::mod_ssl')
end
end
describe 'apache wsgi' do
let(:file) { '/etc/apache2/sites-available/identity.conf' }
it 'creates identity.conf' do
expect(chef_run).to create_template(file).with(
user: 'root',
group: 'root',
mode: '0644'
)
end
it 'does not configure keystone-admin.conf' do
expect(chef_run).not_to render_file('/etc/apache2/sites-available/keystone-admin.conf')
end
it 'configures identity.conf lines' do
node.override['openstack']['identity']['custom_template_banner'] = 'custom_template_banner_value'
[/^custom_template_banner_value$/,
/user=keystone/,
/group=keystone/,
%r{^ ErrorLog /var/log/apache2/identity.log$},
%r{^ CustomLog /var/log/apache2/identity_access.log combined$}].each do |line|
expect(chef_run).to render_file(file).with_content(line)
end
end
it 'does not configure identity.conf triggered common lines' do
[/^ LogLevel/,
/^ SSL/].each do |line|
expect(chef_run).not_to render_file(file).with_content(line)
end
end
context 'Enable SSL' do
let(:file) { '/etc/apache2/sites-available/identity.conf' }
before do
node.override['openstack']['identity']['ssl']['enabled'] = true
end
it 'configures identity.conf common ssl lines' do
[/^ SSLEngine On$/,
%r{^ SSLCertificateFile /etc/keystone/ssl/certs/sslcert.pem$},
%r{^ SSLCertificateKeyFile /etc/keystone/ssl/private/sslkey.pem$},
%r{^ SSLCACertificatePath /etc/keystone/ssl/certs/$},
/^ SSLProtocol All -SSLv2 -SSLv3$/].each do |line|
expect(chef_run).to render_file(file).with_content(line)
end
end
it 'does not configure identity.conf common ssl lines' do
[/^ SSLCertificateChainFile/,
/^ SSLCipherSuite/,
/^ SSLVerifyClient require/].each do |line|
expect(chef_run).not_to render_file(file).with_content(line)
end
end
it 'configures identity.conf chainfile when set' do
node.override['openstack']['identity']['ssl']['chainfile'] = '/etc/keystone/ssl/certs/chainfile.pem'
expect(chef_run).to render_file(file)
.with_content(%r{^ SSLCertificateChainFile /etc/keystone/ssl/certs/chainfile.pem$})
end
it 'configures identity.conf ciphers when set' do
node.override['openstack']['identity']['ssl']['ciphers'] = 'ciphers_value'
expect(chef_run).to render_file(file)
.with_content(/^ SSLCipherSuite ciphers_value$/)
end
it 'configures identity.conf cert_required set' do
node.override['openstack']['identity']['ssl']['cert_required'] = true
expect(chef_run).to render_file(file)
.with_content(/^ SSLVerifyClient require$/)
end
end
end
describe 'identity.conf' do
let(:file) { '/etc/apache2/sites-available/identity.conf' }
it 'configures required lines' do
[/^<VirtualHost 127.0.0.1:5000>$/,
/^ WSGIDaemonProcess identity/,
/^ WSGIProcessGroup identity$/,
%r{^ WSGIScriptAlias / /usr/bin/keystone-wsgi-public$}].each do |line|
expect(chef_run).to render_file(file).with_content(line)
end
end
end
describe 'restart apache' do
it do
expect(chef_run).to nothing_execute('Clear Keystone apache restart')
.with(
command: 'rm -f /var/chef/cache/keystone-apache-restarted'
)
end
%w(
/etc/keystone/keystone.conf
/etc/apache2/sites-available/identity.conf
).each do |f|
it "#{f} notifies execute[Clear Keystone apache restart]" do
expect(chef_run.template(f)).to notify('execute[Clear Keystone apache restart]').to(:run).immediately
end
end
it do
expect(chef_run).to run_execute('Keystone apache restart')
.with(
command: 'touch /var/chef/cache/keystone-apache-restarted',
creates: '/var/chef/cache/keystone-apache-restarted'
)
end
it do
expect(chef_run.execute('Keystone apache restart')).to notify('execute[restore-selinux-context]').to(:run).immediately
end
it do
expect(chef_run.execute('Keystone apache restart')).to notify('service[apache2]').to(:restart).immediately
end
end
end
end
end