Files
puppet-glance/spec/classes/glance_api_spec.rb
Takashi Kajinami b9b2448b03 Refactor api service management
Drop validation of service name which is not implemented for
the other daemons, to simplify handling of the provided service name.

This allows us to more easily offload the service name definition to
hiera data in the near future.

Change-Id: I90a78929510ca3917d3ba32576fa123d512388b9
Signed-off-by: Takashi Kajinami <kajinamit@oss.nttdata.com>
2025-09-26 15:33:53 +00:00

554 lines
22 KiB
Ruby

require 'spec_helper'
describe 'glance::api' do
let :pre_condition do
"class { 'glance::api::authtoken':
password => 'ChangeMe',
}"
end
let :default_params do
{
:bind_host => '<SERVICE DEFAULT>',
:bind_port => '<SERVICE DEFAULT>',
:auth_strategy => 'keystone',
:enabled => true,
:manage_service => true,
:backlog => '<SERVICE DEFAULT>',
:workers => '7',
:show_image_direct_url => '<SERVICE DEFAULT>',
:show_multiple_locations => '<SERVICE DEFAULT>',
:filesystem_store_metadata_file => '<SERVICE DEFAULT>',
:filesystem_store_file_perm => '<SERVICE DEFAULT>',
:purge_config => false,
:delayed_delete => '<SERVICE DEFAULT>',
:enforce_secure_rbac => '<SERVICE DEFAULT>',
:use_keystone_limits => '<SERVICE DEFAULT>',
:image_cache_driver => '<SERVICE DEFAULT>',
:image_cache_dir => '/var/lib/glance/image-cache',
:image_cache_stall_time => '<SERVICE DEFAULT>',
:image_cache_max_size => '<SERVICE DEFAULT>',
:image_import_plugins => '<SERVICE DEFAULT>',
:image_conversion_output_format => '<SERVICE DEFAULT>',
:inject_metadata_properties => '<SERVICE DEFAULT>',
:ignore_user_roles => '<SERVICE DEFAULT>',
:enabled_import_methods => '<SERVICE DEFAULT>',
:node_staging_uri => '<SERVICE DEFAULT>',
:worker_self_reference_url => '<SERVICE DEFAULT>',
:image_member_quota => '<SERVICE DEFAULT>',
:image_property_quota => '<SERVICE DEFAULT>',
:image_tag_quota => '<SERVICE DEFAULT>',
:image_location_quota => '<SERVICE DEFAULT>',
:image_size_cap => '<SERVICE DEFAULT>',
:user_storage_quota => '<SERVICE DEFAULT>',
:paste_deploy_flavor => 'keystone',
:paste_deploy_config_file => '<SERVICE DEFAULT>',
:task_time_to_live => '<SERVICE DEFAULT>',
:task_executor => '<SERVICE DEFAULT>',
:task_work_dir => '<SERVICE DEFAULT>',
:taskflow_engine_mode => '<SERVICE DEFAULT>',
:taskflow_max_workers => '<SERVICE DEFAULT>',
:conversion_format => '<SERVICE DEFAULT>',
:sync_db => true,
:limit_param_default => '<SERVICE DEFAULT>',
:api_limit_max => '<SERVICE DEFAULT>',
:public_endpoint => '<SERVICE DEFAULT>',
:hashing_algorithm => '<SERVICE DEFAULT>',
}
end
shared_examples_for 'glance::api' do
[{
:bind_host => '127.0.0.1',
:bind_port => '9222',
:auth_strategy => 'not_keystone',
:enabled => false,
:backlog => '4095',
:workers => '5',
:show_image_direct_url => true,
:show_multiple_locations => true,
:filesystem_store_metadata_file => '/etc/glance/glance-metadata-file.conf',
:filesystem_store_file_perm => '0644',
:delayed_delete => 'true',
:enforce_secure_rbac => 'true',
:use_keystone_limits => 'true',
:image_cache_driver => 'centralized_db',
:image_cache_dir => '/tmp/glance',
:image_cache_stall_time => '10',
:image_cache_max_size => '10737418240',
:image_import_plugins => 'image_conversion',
:image_conversion_output_format => 'raw',
:inject_metadata_properties => 'key:val',
:ignore_user_roles => 'admin',
:enabled_import_methods => 'glance-direct,web-download',
:node_staging_uri => '/tmp/staging',
:worker_self_reference_url => 'http://worker1',
:image_member_quota => 128,
:image_property_quota => 129,
:image_tag_quota => 130,
:image_location_quota => 10,
:image_size_cap => 1099511627776,
:user_storage_quota => 0,
:paste_deploy_flavor => 'keystone+caching',
:paste_deploy_config_file => 'glance-api-paste.ini',
:sync_db => false,
:limit_param_default => '10',
:api_limit_max => '10',
:public_endpoint => 'https://cloud.acme.org/api/image',
:hashing_algorithm => 'sha512',
}
].each do |param_set|
describe "when #{param_set.empty? ? "using default" : "specifying"} class parameters" do
let :param_hash do
default_params.merge(param_set)
end
let :params do
param_set
end
it { is_expected.to contain_class 'glance' }
it { is_expected.to contain_class 'glance::policy' }
it { is_expected.to contain_class 'glance::api::db' }
it 'is_expected.to not sync the db if sync_db is set to false' do
if !param_hash[:sync_db]
is_expected.not_to contain_exec('glance-manage db_sync')
end
end
it { is_expected.to contain_service('glance-api').with(
'ensure' => (param_hash[:manage_service] && param_hash[:enabled]) ? 'running': 'stopped',
'enable' => param_hash[:enabled],
'hasstatus' => true,
'hasrestart' => true,
'tag' => 'glance-service',
) }
it { is_expected.to contain_glance_api_config('paste_deploy/flavor').with_value(param_hash[:paste_deploy_flavor]) }
it { is_expected.to contain_glance_api_config('paste_deploy/config_file').with_value(param_hash[:paste_deploy_config_file]) }
it 'is_expected.to lay down default api config' do
[
'bind_host',
'bind_port',
'show_image_direct_url',
'show_multiple_locations',
'delayed_delete',
'enforce_secure_rbac',
'use_keystone_limits',
'image_cache_driver',
'image_cache_dir',
'image_cache_stall_time',
'image_cache_max_size',
'node_staging_uri',
'worker_self_reference_url',
'image_member_quota',
'image_property_quota',
'image_tag_quota',
'image_location_quota',
'image_size_cap',
'user_storage_quota',
'limit_param_default',
'api_limit_max',
'public_endpoint',
'hashing_algorithm',
].each do |config|
is_expected.to contain_glance_api_config("DEFAULT/#{config}").with_value(param_hash[config.intern])
end
end
it 'is_expected.to lay down default enabled_import_methods config' do
# Verify brackets "[]" are added to satisfy the ListOpt syntax.
is_expected.to contain_glance_api_config("DEFAULT/enabled_import_methods").with_value(
"[%s]" % param_hash[:enabled_import_methods])
end
it 'is_expected.to lay down default image_import_plugins config' do
# Verify brackets "[]" are added to satisfy the ListOpt syntax.
is_expected.to contain_glance_image_import_config("image_import_opts/image_import_plugins").with_value(
"[%s]" % param_hash[:image_import_plugins])
end
it 'is_expected.to lay down default image_conversion & inject_metadata image_import config' do
is_expected.to contain_glance_image_import_config("image_conversion/output_format").with_value(param_hash[:image_conversion_output_format])
is_expected.to contain_glance_image_import_config("inject_metadata_properties/inject").with_value(param_hash[:inject_metadata_properties])
is_expected.to contain_glance_image_import_config("inject_metadata_properties/ignore_user_roles").with_value(param_hash[:ignore_user_roles])
end
it 'is_expected.to lay down default cache config' do
[
'image_cache_driver',
'image_cache_dir',
'image_cache_stall_time',
'image_cache_max_size',
].each do |config|
is_expected.to contain_glance_cache_config("DEFAULT/#{config}").with_value(param_hash[config.intern])
end
end
it 'is_expected.to lay down default glance_store api config' do
[
'filesystem_store_metadata_file',
'filesystem_store_file_perm',
].each do |config|
is_expected.to contain_glance_api_config("glance_store/#{config}").with_value(param_hash[config.intern])
is_expected.to contain_glance_cache_config("glance_store/#{config}").with_value(param_hash[config.intern])
end
end
it 'is_expected.to lay down default task & taskflow_executor config' do
is_expected.to contain_glance_api_config('task/task_time_to_live').with_value(param_hash[:task_time_to_live])
is_expected.to contain_glance_api_config('task/task_executor').with_value(param_hash[:task_executor])
is_expected.to contain_glance_api_config('task/work_dir').with_value(param_hash[:task_work_dir])
is_expected.to contain_glance_api_config('taskflow_executor/engine_mode').with_value(param_hash[:taskflow_engine_mode])
is_expected.to contain_glance_api_config('taskflow_executor/max_workers').with_value(param_hash[:taskflow_max_workers])
is_expected.to contain_glance_api_config('taskflow_executor/conversion_format').with_value(param_hash[:conversion_format])
end
it 'is_expected.to have no formats set' do
is_expected.to contain_glance_api_config('image_format/container_formats').with_value('<SERVICE DEFAULT>')
is_expected.to contain_glance_api_config('image_format/disk_formats').with_value('<SERVICE DEFAULT>')
is_expected.to contain_glance_api_config('image_format/require_image_format_match').with_value('<SERVICE DEFAULT>')
end
it 'passes purge to resource' do
is_expected.to contain_resources('glance_api_config').with({
:purge => false
})
end
end
end
describe 'with disabled service managing' do
let :params do
{
:manage_service => false,
:enabled => false,
}
end
it { is_expected.to_not contain_service('glance-api') }
end
describe 'with overridden flavor' do
let :params do
{
:paste_deploy_flavor => 'something',
}
end
it { is_expected.to contain_glance_api_config('paste_deploy/flavor').with_value('something') }
end
context 'when running glance-api in wsgi' do
let :params do
{
:service_name => 'httpd'
}
end
let :pre_condition do
"include apache
class { 'glance': }
class { 'glance::api::authtoken':
password => 'foo',
}"
end
it 'configures glance-api service with Apache' do
is_expected.to contain_class('apache::params')
is_expected.to contain_service('glance-api').with(
:ensure => 'stopped',
:enable => false,
:tag => ['glance-service'],
)
end
end
describe 'with platform default oslo concurrency lock_path' do
it { is_expected.to contain_oslo__concurrency('glance_api_config').with(
:lock_path => platform_params[:lock_path]
)}
it { is_expected.to contain_oslo__concurrency('glance_cache_config').with(
:lock_path => platform_params[:lock_path]
)}
end
describe 'with overridden oslo concurrency lock_path' do
let :params do
{:lock_path => '/glance/lock/path' }
end
it { is_expected.to contain_oslo__concurrency('glance_api_config').with(
:lock_path => '/glance/lock/path',
)}
it { is_expected.to contain_oslo__concurrency('glance_cache_config').with(
:lock_path => '/glance/lock/path',
)}
end
describe 'setting enable_proxy_headers_parsing' do
let :params do
{:enable_proxy_headers_parsing => true }
end
it { is_expected.to contain_oslo__middleware('glance_api_config').with(
:enable_proxy_headers_parsing => true,
)}
end
describe 'setting max_request_body_size' do
let :params do
{:max_request_body_size => '102400' }
end
it { is_expected.to contain_oslo__middleware('glance_api_config').with(
:max_request_body_size => '102400',
)}
end
describe 'with formats options with strings' do
let :params do
{
:container_formats => 'ami,ari',
:disk_formats => 'raw,iso',
}
end
context 'with disk_formats option' do
it { is_expected.to contain_glance_api_config('image_format/container_formats').with_value('ami,ari') }
it { is_expected.to contain_glance_api_config('image_format/disk_formats').with_value('raw,iso') }
end
end
describe 'with formats options with arrays' do
let :params do
{
:container_formats => ['ami', 'ari'],
:disk_formats => ['raw', 'iso'],
}
end
context 'with disk_formats option' do
it { is_expected.to contain_glance_api_config('image_format/container_formats').with_value('ami,ari') }
it { is_expected.to contain_glance_api_config('image_format/disk_formats').with_value('raw,iso') }
end
end
describe 'with require_image_format_match' do
let :params do
{
:require_image_format_match => true,
}
end
context 'with require_image_format_match option' do
it { is_expected.to contain_glance_api_config('image_format/require_image_format_match').with_value(true) }
end
end
describe 'with enabled_backends and stores by default' do
it { is_expected.to_not contain_glance_api_config('DEFAULT/enabled_backends').with_value('<SERVICE DEFAULT>') }
it { is_expected.to_not contain_glance_api_config('glance_store/stores').with_value('<SERVICE DEFAULT>') }
it { is_expected.to_not contain_glance_cache_config('DEFAULT/enabled_backends').with_value('<SERVICE DEFAULT>') }
it { is_expected.to_not contain_glance_cache_config('glance_store/stores').with_value('<SERVICE DEFAULT>') }
end
describe 'with enabled_backends' do
let :params do
{
:enabled_backends => ['file1:file','http1:http'],
:default_backend => 'file1',
:stores => ['file','http'],
:default_store => 'file',
}
end
it { is_expected.to contain_glance_api_config('DEFAULT/enabled_backends').with_value('file1:file,http1:http') }
it { is_expected.to contain_glance_api_config('glance_store/default_backend').with_value('file1') }
it { is_expected.to contain_glance_api_config('glance_store/stores').with_ensure('absent') }
it { is_expected.to contain_glance_api_config('glance_store/default_store').with_ensure('absent') }
it { is_expected.to contain_glance_cache_config('DEFAULT/enabled_backends').with_value('file1:file,http1:http') }
it { is_expected.to contain_glance_cache_config('glance_store/default_backend').with_value('file1') }
it { is_expected.to contain_glance_cache_config('glance_store/stores').with_ensure('absent') }
it { is_expected.to contain_glance_cache_config('glance_store/default_store').with_ensure('absent') }
end
describe 'with invalid backend type' do
let :params do
{
:enabled_backends => ['file1:file','bad1:mybad'],
:default_backend => 'file',
}
end
it_raises 'a Puppet::Error', / is not a valid backend type./
end
describe 'with enabled_backends but no default_backend' do
let :params do
{
:enabled_backends => ['file1:file','http1:http'],
}
end
it_raises 'a Puppet::Error', /A glance default_backend must be specified./
end
describe 'with duplicate backend identifiers' do
let :params do
{
:enabled_backends => ['file1:file','file1:http'],
:default_backend => 'file1',
}
end
it_raises 'a Puppet::Error', /All backend identifiers in enabled_backends must be unique./
end
describe 'with invalid default_backend' do
let :params do
{
:enabled_backends => ['file1:file','http1:http'],
:default_backend => 'file2',
}
end
it_raises 'a Puppet::Error', / is not a valid backend identifier./
end
describe 'with stores override' do
let :params do
{
:default_store => 'file',
:stores => ['file','http'],
:multi_store => true,
}
end
it { is_expected.to contain_glance_api_config('glance_store/default_store').with_value('file') }
it { is_expected.to contain_glance_api_config('glance_store/stores').with_value('file,http') }
it { is_expected.to contain_glance_cache_config('glance_store/default_store').with_value('file') }
it { is_expected.to contain_glance_cache_config('glance_store/stores').with_value('file,http') }
end
describe 'with single store override and no default store' do
let :params do
{
:stores => ['file'],
:multi_store => true,
}
end
it { is_expected.to contain_glance_api_config('glance_store/default_store').with_value('file') }
it { is_expected.to contain_glance_api_config('glance_store/stores').with_value('file') }
it { is_expected.to contain_glance_cache_config('glance_store/default_store').with_value('file') }
it { is_expected.to contain_glance_cache_config('glance_store/stores').with_value('file') }
end
describe 'with multiple stores override and no default store' do
let :params do
{
:stores => ['file', 'http'],
:multi_store => true,
}
end
it { is_expected.to contain_glance_api_config('glance_store/default_store').with_value('file') }
it { is_expected.to contain_glance_api_config('glance_store/stores').with_value('file,http') }
it { is_expected.to contain_glance_cache_config('glance_store/default_store').with_value('file') }
it { is_expected.to contain_glance_cache_config('glance_store/stores').with_value('file,http') }
end
describe 'with default_store' do
let :params do
{
:default_store => 'file',
:multi_store => true,
}
end
it { is_expected.to contain_glance_api_config('glance_store/default_store').with_value('file') }
it { is_expected.to contain_glance_api_config('glance_store/stores').with_value('file') }
it { is_expected.to contain_glance_cache_config('glance_store/default_store').with_value('file') }
it { is_expected.to contain_glance_cache_config('glance_store/stores').with_value('file') }
end
describe 'with task & taskflow configuration' do
let :params do
{
:task_time_to_live => 72,
:task_executor => 'taskflow-next-gen',
:task_work_dir => '/tmp/large',
:taskflow_engine_mode => 'serial',
:taskflow_max_workers => 1,
:conversion_format => 'raw',
}
end
it 'is_expected.to lay down default task & taskflow_executor config' do
is_expected.to contain_glance_api_config('task/task_time_to_live').with_value(72)
is_expected.to contain_glance_api_config('task/task_executor').with_value('taskflow-next-gen')
is_expected.to contain_glance_api_config('task/work_dir').with_value('/tmp/large')
is_expected.to contain_glance_api_config('taskflow_executor/engine_mode').with_value('serial')
is_expected.to contain_glance_api_config('taskflow_executor/max_workers').with_value(1)
is_expected.to contain_glance_api_config('taskflow_executor/conversion_format').with_value('raw')
end
end
end
shared_examples_for 'glance::api on Debian' do
# We only test this on Debian platforms, since on RedHat there isn't a
# separate package for glance API.
['present', 'latest'].each do |package_ensure|
context "with package_ensure '#{package_ensure}'" do
let(:params) do
{ :package_ensure => package_ensure }
end
it { is_expected.to contain_package('glance-api').with(
:ensure => package_ensure,
:name => 'glance-api',
:tag => ['openstack', 'glance-package']
)}
end
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())
end
let(:platform_params) do
case facts[:os]['family']
when 'Debian'
{ :lock_path => '/var/lock/glance' }
when 'RedHat'
{ :lock_path => '/var/lib/glance/tmp' }
end
end
it_configures 'glance::api'
if facts[:os]['family'] == 'Debian'
it_configures "glance::api on #{facts[:os]['family']}"
end
end
end
end