diff --git a/spec/api_spec.rb b/spec/api_spec.rb
index fc12078..191c65f 100644
--- a/spec/api_spec.rb
+++ b/spec/api_spec.rb
@@ -104,38 +104,81 @@ describe 'openstack-block-storage::api' do
expect(sprintf('%o', file.mode)).to eq('644')
end
- it 'has signing_dir' do
- expect(chef_run).to render_file(file.name).with_content('signing_dir = /var/cache/cinder/api')
- end
-
it 'notifies cinder-api restart' do
expect(file).to notify('service[cinder-api]').to(:restart)
end
- it 'has auth_uri' do
- expect(chef_run).to render_file(file.name).with_content('auth_uri = http://127.0.0.1:5000/v2.0')
- end
+ context 'template contents' do
+ it 'has signing_dir' do
+ node.set['openstack']['block-storage']['api']['auth']['cache_dir'] = 'auth_cache_dir'
- it 'has auth_host' do
- expect(chef_run).to render_file(file.name).with_content('auth_host = 127.0.0.1')
- end
+ expect(chef_run).to render_file(file.name).with_content(/^signing_dir = auth_cache_dir$/)
+ end
- it 'has auth_port' do
- expect(chef_run).to render_file(file.name).with_content('auth_port = 35357')
- end
+ context 'endpoint related' do
+ before do
+ endpoint = double(port: 'port', host: 'host', scheme: 'scheme')
+ Chef::Recipe.any_instance.stub(:endpoint)
+ .with('image-api')
+ .and_return(endpoint)
+ Chef::Recipe.any_instance.stub(:endpoint)
+ .with('identity-admin')
+ .and_return(endpoint)
+ Chef::Recipe.any_instance.stub(:endpoint)
+ .with('identity-api')
+ .and_return(endpoint)
+ Chef::Recipe.any_instance.stub(:endpoint)
+ .with('block-storage-api')
+ .and_return(endpoint)
+ Chef::Recipe.any_instance.stub(:auth_uri_transform)
+ .and_return('auth_uri_transform')
+ end
- it 'has auth_protocol' do
- expect(chef_run).to render_file(file.name).with_content('auth_protocol = http')
- end
+ it 'has auth_uri' do
+ expect(chef_run).to render_file(file.name).with_content(/^auth_uri = auth_uri_transform$/)
+ end
- it 'has no auth_version when auth_version is v2.0' do
- expect(chef_run).not_to render_file(file.name).with_content('auth_version = v2.0')
- end
+ it 'has auth_host' do
+ expect(chef_run).to render_file(file.name).with_content(/^auth_host = host$/)
+ end
- it 'has auth_version when auth version is not v2.0' do
- node.set['openstack']['block-storage']['api']['auth']['version'] = 'v3.0'
+ it 'has auth_port' do
+ expect(chef_run).to render_file(file.name).with_content(/^auth_port = port$/)
+ end
- expect(chef_run).to render_file(file.name).with_content('auth_version = v3.0')
+ it 'has auth_protocol' do
+ expect(chef_run).to render_file(file.name).with_content(/^auth_protocol = scheme$/)
+ end
+ end
+
+ it 'has no auth_version when auth_version is v2.0' do
+ node.set['openstack']['block-storage']['api']['auth']['version'] = 'v2.0'
+
+ expect(chef_run).not_to render_file(file.name).with_content(/^auth_version = v2.0$/)
+ end
+
+ it 'has auth_version when auth version is not v2.0' do
+ node.set['openstack']['block-storage']['api']['auth']['version'] = 'v3.0'
+
+ expect(chef_run).to render_file(file.name).with_content(/^auth_version = v3.0$/)
+ end
+
+ it 'has an admin tenant name' do
+ node.set['openstack']['block-storage']['service_tenant_name'] = 'tenant_name'
+
+ expect(chef_run).to render_file(file.name).with_content(/^admin_tenant_name = tenant_name$/)
+ end
+
+ it 'has an admin user' do
+ node.set['openstack']['block-storage']['service_user'] = 'username'
+
+ expect(chef_run).to render_file(file.name).with_content(/^admin_user = username$/)
+ end
+
+ it 'has an admin password' do
+ # (fgimenez) the get_password mocking is set in spec/spec_helper.rb
+ expect(chef_run).to render_file(file.name).with_content(/^admin_password = cinder-pass$/)
+ end
end
end
end
diff --git a/spec/cinder_common_spec.rb b/spec/cinder_common_spec.rb
index 093cad5..99429f1 100644
--- a/spec/cinder_common_spec.rb
+++ b/spec/cinder_common_spec.rb
@@ -1,4 +1,4 @@
-# encoding: UTF-8
+# encoding: utf-8
#
# Cookbook Name:: openstack-block-storage
@@ -46,330 +46,452 @@ describe 'openstack-block-storage::cinder-common' do
expect(sprintf('%o', file.mode)).to eq '644'
end
- it 'has name templates' do
- expect(chef_run).to render_file(file.name).with_content('volume_name_template=volume-%s')
- expect(chef_run).to render_file(file.name).with_content('snapshot_name_template=snapshot-%s')
- end
-
- it 'has rpc_backend set' do
- expect(chef_run).to render_file(file.name).with_content('rpc_backend=cinder.openstack.common.rpc.impl_kombu')
- end
-
- it 'has has volumes_dir set' do
- expect(chef_run).to render_file(file.name).with_content('volumes_dir=/var/lib/cinder/volumes')
- end
-
- it 'has correct volume.driver set' do
- expect(chef_run).to render_file(file.name).with_content('volume_driver=cinder.volume.drivers.lvm.LVMISCSIDriver')
- end
-
- it 'has osapi_volume_listen set' do
- node.set['openstack']['endpoints']['block-storage-api']['host'] = '1.1.1.1'
- expect(chef_run).to render_file(file.name).with_content('osapi_volume_listen=1.1.1.1')
- end
-
- it 'has osapi_volume_listen_port set' do
- node.set['openstack']['endpoints']['block-storage-api']['port'] = '9999'
- expect(chef_run).to render_file(file.name).with_content('osapi_volume_listen_port=9999')
- end
-
- it 'has rpc_thread_pool_size' do
- expect(chef_run).to render_file(file.name).with_content('rpc_thread_pool_size=64')
- end
-
- it 'has rpc_conn_pool_size' do
- expect(chef_run).to render_file(file.name).with_content('rpc_conn_pool_size=30')
- end
-
- it 'has rpc_response_timeout' do
- expect(chef_run).to render_file(file.name).with_content('rpc_response_timeout=60')
- end
-
- it 'has rabbit_host' do
- expect(chef_run).to render_file(file.name).with_content('rabbit_host=127.0.0.1')
- end
-
- it 'does not have rabbit_hosts' do
- expect(chef_run).not_to render_file(file.name).with_content('rabbit_hosts=')
- end
-
- it 'does not have rabbit_ha_queues' do
- expect(chef_run).not_to render_file(file.name).with_content('rabbit_ha_queues=')
- end
-
- it 'has log_file' do
- expect(chef_run).to render_file(file.name).with_content('log_file = /var/log/cinder/cinder.log')
- end
-
- it 'has log_config when syslog is true' do
- node.set['openstack']['block-storage']['syslog']['use'] = true
-
- expect(chef_run).to render_file(file.name).with_content('log_config = /etc/openstack/logging.conf')
- end
-
- it 'has rabbit_port' do
- expect(chef_run).to render_file(file.name).with_content('rabbit_port=5672')
- end
-
- it 'has rabbit_use_ssl' do
- expect(chef_run).to render_file(file.name).with_content('rabbit_use_ssl=false')
- end
-
- it 'has rabbit_userid' do
- expect(chef_run).to render_file(file.name).with_content('rabbit_userid=guest')
- end
-
- it 'has rabbit_password' do
- expect(chef_run).to render_file(file.name).with_content('rabbit_password=mq-pass')
- end
-
- it 'has rabbit_virtual_host' do
- expect(chef_run).to render_file(file.name).with_content('rabbit_virtual_host=/')
- end
-
- it 'has rabbit notification_topics' do
- expect(chef_run).to render_file(file.name).with_content('notification_topics=rabbit_topic')
- end
-
- describe 'rabbit ha' do
+ context 'template contents' do
+ let(:test_pass) { 'test_pass' }
before do
- node.set['openstack']['mq']['block-storage']['rabbit']['ha'] = true
+ Chef::Recipe.any_instance.stub(:endpoint)
+ .with('image-api')
+ .and_return(double(host: 'glance_host_value', port: 'glance_port_value'))
+ Chef::Recipe.any_instance.stub(:endpoint)
+ .with('block-storage-api')
+ .and_return(double(host: 'cinder_host_value', port: 'cinder_port_value'))
+ Chef::Recipe.any_instance.stub(:get_password)
+ .with('user', anything)
+ .and_return(test_pass)
end
- it 'has rabbit_hosts' do
- expect(chef_run).to render_file(file.name).with_content('rabbit_hosts=1.1.1.1:5672,2.2.2.2:5672')
- end
+ context 'commonly named attributes' do
+ %w(debug verbose lock_path notification_driver
+ storage_availability_zone quota_volumes quota_gigabytes quota_driver
+ volume_name_template snapshot_name_template
+ control_exchange rpc_thread_pool_size rpc_conn_pool_size
+ rpc_response_timeout max_gigabytes).each do |attr_key|
+ it "has a #{attr_key} attribute" do
+ node.set['openstack']['block-storage'][attr_key] = "#{attr_key}_value"
- it 'has rabbit_ha_queues' do
- expect(chef_run).to render_file(file.name).with_content('rabbit_ha_queues=True')
- end
-
- it 'does not have rabbit_host' do
- expect(chef_run).not_to render_file(file.name).with_content('rabbit_host=127.0.0.1')
- end
-
- it 'does not have rabbit_port' do
- expect(chef_run).not_to render_file(file.name).with_content('rabbit_port=5672')
- end
- end
-
- describe 'qpid' do
- before do
- node.set['openstack']['mq']['block-storage']['service_type'] = 'qpid'
- node.set['openstack']['block-storage']['notification_driver'] = 'cinder.test_driver'
- node.set['openstack']['mq']['block-storage']['qpid']['notification_topic'] = 'qpid_topic'
- # we set username here since the attribute in common currently
- # defaults to ''
- node.set['openstack']['mq']['block-storage']['qpid']['username'] = 'guest'
- end
-
- it 'has qpid_hostname' do
- expect(chef_run).to render_file(file.name).with_content('qpid_hostname=127.0.0.1')
- end
-
- it 'has qpid_port' do
- expect(chef_run).to render_file(file.name).with_content('qpid_port=5672')
- end
-
- it 'has qpid_username' do
- expect(chef_run).to render_file(file.name).with_content('qpid_username=guest')
- end
-
- it 'has qpid_password' do
- expect(chef_run).to render_file(file.name).with_content('qpid_password=mq-pass')
- end
-
- it 'has qpid_sasl_mechanisms' do
- expect(chef_run).to render_file(file.name).with_content('qpid_sasl_mechanisms=')
- end
-
- it 'has qpid_reconnect_timeout' do
- expect(chef_run).to render_file(file.name).with_content('qpid_reconnect_timeout=0')
- end
-
- it 'has qpid_reconnect_limit' do
- expect(chef_run).to render_file(file.name).with_content('qpid_reconnect_limit=0')
- end
-
- it 'has qpid_reconnect_interval_min' do
- expect(chef_run).to render_file(file.name).with_content('qpid_reconnect_interval_min=0')
- end
-
- it 'has qpid_reconnect_interval_max' do
- expect(chef_run).to render_file(file.name).with_content('qpid_reconnect_interval_max=0')
- end
-
- it 'has qpid_reconnect_interval' do
- expect(chef_run).to render_file(file.name).with_content('qpid_reconnect_interval=0')
- end
-
- it 'has qpid_reconnect' do
- expect(chef_run).to render_file(file.name).with_content('qpid_reconnect=true')
- end
-
- it 'has qpid_heartbeat' do
- expect(chef_run).to render_file(file.name).with_content('qpid_heartbeat=60')
- end
-
- it 'has qpid_protocol' do
- expect(chef_run).to render_file(file.name).with_content('qpid_protocol=tcp')
- end
-
- it 'has qpid_tcp_nodelay' do
- expect(chef_run).to render_file(file.name).with_content('qpid_tcp_nodelay=true')
- end
-
- it 'has notification_driver' do
- expect(chef_run).to render_file(file.name).with_content('notification_driver=cinder.test_driver')
- end
-
- it 'has notification_topics' do
- expect(chef_run).to render_file(file.name).with_content('notification_topics=qpid_topic')
- end
- end
-
- describe 'lvm settings' do
- before do
- node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.lvm.LVMISCSIDriver'
- node.set['openstack']['block-storage']['volume']['volume_group'] = 'test-group'
- node.set['openstack']['block-storage']['volume']['volume_clear_size'] = 100
- node.set['openstack']['block-storage']['volume']['volume_clear'] = 'none'
- end
-
- it 'has volume_group' do
- expect(chef_run).to render_file(file.name).with_content('volume_group=test-group')
- end
-
- it 'has volume_clear_size' do
- expect(chef_run).to render_file(file.name).with_content('volume_clear_size=100')
- end
-
- it 'has volume_clear' do
- expect(chef_run).to render_file(file.name).with_content('volume_clear=none')
- end
- end
-
- describe 'solidfire settings' do
- before do
- node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.solidfire.SolidFire'
- node.set['openstack']['block-storage']['solidfire']['sf_emulate'] = 'test'
- node.set['openstack']['block-storage']['solidfire']['san_ip'] = '203.0.113.10'
- node.set['openstack']['block-storage']['solidfire']['san_login'] = 'solidfire_admin'
- end
-
- it 'has solidfire sf_emulate set' do
- expect(chef_run).to render_file(file.name).with_content('sf_emulate_512=test')
- end
-
- it 'has solidfire san_ip set' do
- expect(chef_run).to render_file(file.name).with_content('san_ip=203.0.113.10')
- end
-
- it 'has solidfire san_login' do
- expect(chef_run).to render_file(file.name).with_content('san_login=solidfire_admin')
- end
-
- it 'has solidfire password' do
- expect(chef_run).to render_file(file.name).with_content('san_password=solidfire_testpass')
- end
-
- it 'does not have iscsi_ip_prefix not specified' do
- expect(chef_run).to_not render_file(file.name).with_content('iscsi_ip_prefix')
- end
-
- it 'does have iscsi_ip_prefix when specified' do
- chef_run.node.set['openstack']['block-storage']['solidfire']['iscsi_ip_prefix'] = '203.0.113.*'
-
- expect(chef_run).to render_file(file.name).with_content('iscsi_ip_prefix=203.0.113.*')
- end
- end
-
- describe 'emc settings' do
- before do
- node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.emc.emc_smis_iscsi.EMCSMISISCSIDriver'
- node.set['openstack']['block-storage']['emc']['iscsi_target_prefix'] = 'test.prefix'
- node.set['openstack']['block-storage']['emc']['cinder_emc_config_file'] = '/etc/test/config.file'
- end
-
- it 'has emc iscsi_target_prefix' do
- expect(chef_run).to render_file(file.name).with_content('iscsi_target_prefix=test.prefix')
- end
-
- it 'has cinder_emc_config_file' do
- expect(chef_run).to render_file(file.name).with_content('cinder_emc_config_file=/etc/test/config.file')
- end
- end
-
- describe 'ibmnas settings' do
- before do
- chef_run.node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.ibm.ibmnas.IBMNAS_NFSDriver'
- chef_run.node.set['openstack']['block-storage']['ibmnas']['nas_ip'] = '127.0.0.1'
- chef_run.node.set['openstack']['block-storage']['ibmnas']['nas_login'] = 'ibmnas_admin'
- chef_run.node.set['openstack']['block-storage']['ibmnas']['nas_ssh_port'] = '22'
- chef_run.node.set['openstack']['block-storage']['ibmnas']['shares_config'] = '/etc/cinder/nfs_shares.conf'
- chef_run.node.set['openstack']['block-storage']['ibmnas']['mount_point_base'] = '/mnt/cinder-volumes'
- chef_run.node.set['openstack']['block-storage']['ibmnas']['nfs_sparsed_volumes'] = 'true'
- chef_run.converge 'openstack-block-storage::cinder-common'
- end
-
- it 'has ibmnas nas_ip' do
- expect(chef_run).to render_file(file.name).with_content('nas_ip=127.0.0.1')
- end
-
- it 'has ibmnas nas_login' do
- expect(chef_run).to render_file(file.name).with_content('nas_login=ibmnas_admin')
- end
-
- it 'has ibmnas nas_password' do
- expect(chef_run).to render_file(file.name).with_content('nas_password=test_pass')
- end
-
- it 'has ibmnas nas_ssh_port' do
- expect(chef_run).to render_file(file.name).with_content('nas_ssh_port=22')
- end
-
- it 'has ibmnas shares_config' do
- expect(chef_run).to render_file(file.name).with_content('shares_config=/etc/cinder/nfs_shares.conf')
- end
-
- it 'has ibmnas mount_point_base' do
- expect(chef_run).to render_file(file.name).with_content('mount_point_base=/mnt/cinder-volumes')
- end
-
- it 'has ibmnas nfs_sparsed_volumes' do
- expect(chef_run).to render_file(file.name).with_content('nfs_sparsed_volumes=true')
- end
- end
-
- describe 'vmware vmdk settings' do
- before do
- chef_run.node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.vmware.vmdk.VMwareVcVmdkDriver'
- chef_run.converge 'openstack-block-storage::cinder-common'
- end
-
- [
- /^vmware_host_ip = $/,
- /^vmware_host_username = $/,
- /^vmware_host_password = $/,
- /^vmware_api_retry_count = 10$/,
- /^vmware_task_poll_interval = 5$/,
- /^vmware_volume_folder = cinder-volumes/,
- /^vmware_image_transfer_timeout_secs = 7200$/,
- /^vmware_max_objects_retrieval = 100$/
- ].each do |content|
- it "has a #{content.source[1...-1]} line" do
- expect(chef_run).to render_file(file.name).with_content(content)
+ expect(chef_run).to render_file(file.name).with_content(/^#{attr_key}=#{attr_key}_value$/)
+ end
end
end
- it 'has no wsdl_location line' do
- expect(chef_run).not_to render_file(file.name).with_content('vmware_wsdl_location = ')
+ context 'syslog use' do
+ it 'sets the log_config value when syslog is in use' do
+ node.set['openstack']['block-storage']['syslog']['use'] = true
+
+ expect(chef_run).to render_file(file.name)
+ .with_content(%r{^log_config = /etc/openstack/logging.conf$})
+ end
+
+ it 'sets the log_file value when syslog is not in use' do
+ node.set['openstack']['block-storage']['syslog']['use'] = false
+
+ expect(chef_run).to render_file(file.name)
+ .with_content(%r{^log_file = /var/log/cinder/cinder.log$})
+ end
end
- it 'has wsdl_location line' do
- node.set['openstack']['block-storage']['vmware']['vmware_wsdl_location'] = 'http://127.0.0.1/wsdl'
+ it 'has a sql_connection attribute' do
+ Chef::Recipe.any_instance.stub(:db_uri)
+ .with('block-storage', anything, '').and_return('sql_connection_value')
- expect(chef_run).to render_file(file.name).with_content('vmware_wsdl_location = http://127.0.0.1/wsdl')
+ expect(chef_run).to render_file(file.name)
+ .with_content(/^sql_connection=sql_connection_value$/)
+ end
+
+ it 'has a volume_driver attribute' do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'volume_driver_value'
+ expect(chef_run).to render_file(file.name).with_content(/^volume_driver=volume_driver_value$/)
+ end
+
+ it 'has a state_path attribute' do
+ node.set['openstack']['block-storage']['volume']['state_path'] = 'state_path_value'
+ expect(chef_run).to render_file(file.name).with_content(/^state_path=state_path_value$/)
+ end
+
+ context 'glance endpoint' do
+ %w(host port).each do |glance_attr|
+ it "has a glace #{glance_attr} attribute" do
+ expect(chef_run).to render_file(file.name).with_content(/^glance_#{glance_attr}=glance_#{glance_attr}_value$/)
+ end
+ end
+ end
+
+ it 'has a api_rate_limit attribute' do
+ node.set['openstack']['block-storage']['api']['ratelimit'] = 'api_rate_limit_value'
+ expect(chef_run).to render_file(file.name).with_content(/^api_rate_limit=api_rate_limit_value$/)
+ end
+
+ context 'cinder endpoint' do
+ it 'has osapi_volume_listen set' do
+ expect(chef_run).to render_file(file.name).with_content(/^osapi_volume_listen=cinder_host_value$/)
+ end
+
+ it 'has osapi_volume_listen_port set' do
+ expect(chef_run).to render_file(file.name).with_content(/^osapi_volume_listen_port=cinder_port_value$/)
+ end
+ end
+
+ it 'has a rpc_backend attribute' do
+ node.set['openstack']['block_storage']['rpc_backend'] = 'rpc_backend_value'
+ expect(chef_run).to render_file(file.name).with_content(/^rpc_backend=rpc_backend_value$/)
+ end
+
+ context 'rabbitmq as mq service' do
+ before do
+ node.set['openstack']['mq']['block-storage']['service_type'] = 'rabbitmq'
+ end
+
+ context 'ha attributes' do
+ before do
+ node.set['openstack']['mq']['block-storage']['rabbit']['ha'] = true
+ end
+
+ it 'has a rabbit_hosts attribute' do
+ Chef::Recipe.any_instance.stub(:rabbit_servers)
+ .and_return('rabbit_servers_value')
+
+ expect(chef_run).to render_file(file.name).with_content(/^rabbit_hosts=rabbit_servers_value$/)
+ end
+
+ %w(host port).each do |attr|
+ it "does not have rabbit_#{attr} attribute" do
+ expect(chef_run).not_to render_file(file.name).with_content(/^rabbit_#{attr}=/)
+ end
+ end
+ end
+
+ context 'non ha attributes' do
+ before do
+ node.set['openstack']['mq']['block-storage']['rabbit']['ha'] = false
+ end
+
+ %w(host port).each do |attr|
+ it "has rabbit_#{attr} attribute" do
+ node.set['openstack']['mq']['block-storage']['rabbit'][attr] = "rabbit_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^rabbit_#{attr}=rabbit_#{attr}_value$/)
+ end
+ end
+
+ it 'does not have a rabbit_hosts attribute' do
+ expect(chef_run).not_to render_file(file.name).with_content(/^rabbit_hosts=/)
+ end
+ end
+
+ %w(use_ssl userid).each do |attr|
+ it "has rabbit_#{attr}" do
+ node.set['openstack']['mq']['block-storage']['rabbit'][attr] = "rabbit_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^rabbit_#{attr}=rabbit_#{attr}_value$/)
+ end
+ end
+
+ it 'has rabbit_password' do
+ expect(chef_run).to render_file(file.name).with_content(/^rabbit_password=#{test_pass}$/)
+ end
+
+ it 'has rabbit_virtual_host' do
+ node.set['openstack']['mq']['block-storage']['rabbit']['vhost'] = 'vhost_value'
+ expect(chef_run).to render_file(file.name).with_content(/^rabbit_virtual_host=vhost_value$/)
+ end
+ end
+
+ context 'qpid as mq service' do
+ before do
+ node.set['openstack']['mq']['block-storage']['service_type'] = 'qpid'
+ end
+
+ %w(port username sasl_mechanisms reconnect reconnect_timeout reconnect_limit
+ reconnect_interval_min reconnect_interval_max reconnect_interval heartbeat protocol
+ tcp_nodelay).each do |attr|
+ it "has qpid_#{attr} attribute" do
+ node.set['openstack']['mq']['block-storage']['qpid'][attr] = "qpid_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^qpid_#{attr}=qpid_#{attr}_value$/)
+ end
+ end
+
+ it 'has qpid_hostname' do
+ node.set['openstack']['mq']['block-storage']['qpid']['host'] = 'qpid_host_value'
+ expect(chef_run).to render_file(file.name).with_content(/^qpid_hostname=qpid_host_value$/)
+ end
+
+ it 'has qpid_password' do
+ expect(chef_run).to render_file(file.name).with_content(/^qpid_password=#{test_pass}$/)
+ end
+
+ it 'has qpid notification_topics' do
+ node.set['openstack']['mq']['block-storage']['qpid']['notification_topic'] = 'qpid_notification_topic_value'
+ expect(chef_run).to render_file(file.name).with_content(/^notification_topics=qpid_notification_topic_value$/)
+ end
+ end
+
+ context 'lvm settings' do
+ before do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.lvm.LVMISCSIDriver'
+ end
+
+ %w(group clear clear_size).each do |attr|
+ it "has lvm volume_#{attr} attribute" do
+ node.set['openstack']['block-storage']['volume']["volume_#{attr}"] = "volume_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^volume_#{attr}=volume_#{attr}_value$/)
+ end
+ end
+ end
+
+ context 'commonly named volume attributes' do
+ %w(iscsi_ip_address iscsi_port iscsi_helper volumes_dir).each do |attr|
+ it "has volume related #{attr} attribute" do
+ node.set['openstack']['block-storage']['volume'][attr] = "common_volume_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^#{attr}=common_volume_#{attr}_value$/)
+ end
+ end
+ end
+
+ context 'rbd attributes' do
+ before do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.rbd.RBDDriver'
+ end
+
+ %w(rbd_pool rbd_user rbd_secret_uuid).each do |attr|
+ it "has a #{attr} attribute" do
+ node.set['openstack']['block-storage'][attr] = "#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^#{attr}=#{attr}_value$/)
+ end
+ end
+ end
+
+ it 'has volume_driver attribute' do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'volume_driver_value'
+ expect(chef_run).to render_file(file.name).with_content(/^volume_driver=volume_driver_value$/)
+ end
+
+ context 'netapp ISCSI settings' do
+ before do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.netapp.NetAppISCSIDriver'
+ end
+
+ %w(login password).each do |attr|
+ it "has a netapp_#{attr} attribute" do
+ node.set['openstack']['block-storage']['netapp']["dfm_#{attr}"] = "dfm_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^netapp_#{attr}=dfm_#{attr}_value$/)
+ end
+ end
+
+ %w(hostname port).each do |attr|
+ it "has a netapp_server_#{attr} attribute" do
+ node.set['openstack']['block-storage']['netapp']["dfm_#{attr}"] = "dfm_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^netapp_server_#{attr}=dfm_#{attr}_value$/)
+ end
+ end
+
+ it 'has a netapp_storage_service attribute' do
+ node.set['openstack']['block-storage']['netapp']['storage_service'] = 'netapp_storage_service_value'
+ expect(chef_run).to render_file(file.name).with_content(/^netapp_storage_service=netapp_storage_service_value$/)
+ end
+ end
+
+ context 'netapp direct7 mode nfs settings' do
+ let(:hostnames) { %w(hostname1 hostname2 hostname3) }
+ before do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.netapp.nfs.NetAppDirect7modeNfsDriver'
+ node.set['openstack']['block-storage']['netapp']['netapp_server_hostname'] = hostnames
+ end
+
+ %w(mount_point_base shares_config).each do |attr_key|
+ it "has a nfs_#{attr_key} attribute" do
+ node.set['openstack']['block-storage']['nfs'][attr_key] = "netapp_nfs_#{attr_key}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^nfs_#{attr_key}=netapp_nfs_#{attr_key}_value$/)
+ end
+ end
+
+ it 'has netapp server_hostname attributes' do
+ hostnames.each do |hostname|
+ expect(chef_run).to render_file(file.name).with_content(/^netapp_server_hostname=#{hostname}$/)
+ end
+ end
+
+ it 'has a netapp_server_port attribute' do
+ node.set['openstack']['block-storage']['netapp']['netapp_server_port'] = 'netapp_server_port_value'
+ expect(chef_run).to render_file(file.name).with_content(/^netapp_server_port=netapp_server_port_value$/)
+ end
+
+ %w(login password).each do |attr|
+ it "has a netapp_#{attr} attribute" do
+ node.set['openstack']['block-storage']['netapp']["netapp_server_#{attr}"] = "netapp_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^netapp_#{attr}=netapp_#{attr}_value$/)
+ end
+ end
+
+ %w(disk_util sparsed_volumes).each do |attr|
+ it "has a nfs_#{attr} attribute" do
+ node.set['openstack']['block-storage']['nfs']["nfs_#{attr}"] = "netapp_nfs_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^nfs_#{attr}=netapp_nfs_#{attr}_value$/)
+ end
+ end
+ end
+
+ context 'ibmnas settings' do
+ before do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.ibm.ibmnas.IBMNAS_NFSDriver'
+ end
+
+ %w(mount_point_base shares_config).each do |attr|
+ it "has a ibmnas_#{attr} attribute" do
+ node.set['openstack']['block-storage']['ibmnas'][attr] = "ibmnas_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^nfs_#{attr}=ibmnas_#{attr}_value$/)
+ end
+ end
+
+ it 'has a nfs_sparsed_volumes attribute' do
+ node.set['openstack']['block-storage']['ibmnas']['nfs_sparsed_volumes'] = 'ibmnas_nfs_sparsed_volumes_value'
+ expect(chef_run).to render_file(file.name).with_content(/^nfs_sparsed_volumes=ibmnas_nfs_sparsed_volumes_value$/)
+ end
+
+ %w(nas_ip nas_login nas_ssh_port).each do |attr|
+ it "has a ibmnas #{attr} attribute" do
+ node.set['openstack']['block-storage']['ibmnas'][attr] = "ibmnas_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^#{attr}=ibmnas_#{attr}_value$/)
+ end
+ end
+
+ it 'has a nas_password attribute' do
+ expect(chef_run).to render_file(file.name).with_content(/^nas_password=#{test_pass}$/)
+ end
+ end
+
+ context 'storwize settings' do
+ before do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.ibm.storwize_svc.StorwizeSVCDriver'
+ end
+
+ %w(san_ip san_login san_private_key storwize_svc_volpool_name
+ storwize_svc_vol_rsize storwize_svc_vol_warning storwize_svc_vol_autoexpand
+ storwize_svc_vol_grainsize storwize_svc_vol_compression storwize_svc_vol_easytier
+ storwize_svc_vol_iogrp storwize_svc_flashcopy_timeout storwize_svc_connection_protocol
+ storwize_svc_multihostmap_enabled).each do |attr|
+ it "has a san_#{attr} attribute" do
+ node.set['openstack']['block-storage']['storwize'][attr] = "storwize_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^#{attr}=storwize_#{attr}_value$/)
+ end
+ end
+
+ context 'storwize with iSCSI connection protocol' do
+ before do
+ node.set['openstack']['block-storage']['storwize']['storwize_svc_connection_protocol'] = 'iSCSI'
+ end
+
+ it 'has a iscsi chap enabled attribute' do
+ node.set['openstack']['block-storage']['storwize']['storwize_svc_iscsi_chap_enabled'] = 'storwize_svc_iscsi_chap_enabled_value'
+ expect(chef_run).to render_file(file.name).with_content(/^storwize_svc_iscsi_chap_enabled=storwize_svc_iscsi_chap_enabled_value$/)
+ end
+
+ it 'does not have a multipath enabled attribute' do
+ expect(chef_run).not_to render_file(file.name).with_content(/^storwize_svc_multipath_enabled=/)
+ end
+ end
+
+ context 'storwize without iSCSI connection protocol' do
+ before do
+ node.set['openstack']['block-storage']['storwize']['storwize_svc_connection_protocol'] = 'non-iSCSI'
+ end
+
+ it 'does not have a iscsi chap enabled attribute' do
+ expect(chef_run).not_to render_file(file.name).with_content(/^storwize_svc_iscsi_enabled=/)
+ end
+
+ it 'has a multipath enabled attribute' do
+ node.set['openstack']['block-storage']['storwize']['storwize_svc_multipath_enabled'] = 'storwize_svc_multipath_enabled_value'
+ expect(chef_run).to render_file(file.name).with_content(/^storwize_svc_multipath_enabled=storwize_svc_multipath_enabled_value$/)
+ end
+ end
+ end
+
+ context 'solidfire settings' do
+ before do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.solidfire.SolidFire'
+ end
+
+ it 'has solidfire sf_emulate set' do
+ node.set['openstack']['block-storage']['solidfire']['sf_emulate'] = 'test'
+ expect(chef_run).to render_file(file.name).with_content(/^sf_emulate_512=test$/)
+ end
+
+ %w(san_login san_ip).each do |attr|
+ it "has solidfire #{attr} set" do
+ node.set['openstack']['block-storage']['solidfire'][attr] = "solidfire_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^#{attr}=solidfire_#{attr}_value$/)
+ end
+ end
+
+ it 'does not have iscsi_ip_prefix not specified' do
+ node.set['openstack']['block-storage']['solidfire']['iscsi_ip_prefix'] = nil
+ expect(chef_run).to_not render_file(file.name).with_content(/^iscsi_ip_prefix=/)
+ end
+
+ it 'does have iscsi_ip_prefix when specified' do
+ chef_run.node.set['openstack']['block-storage']['solidfire']['iscsi_ip_prefix'] = '203.0.113.*'
+ expect(chef_run).to render_file(file.name).with_content(/^iscsi_ip_prefix=203.0.113.*$/)
+ end
+ end
+
+ context 'emc settings' do
+ before do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.emc.emc_smis_iscsi.EMCSMISISCSIDriver'
+ end
+
+ %w(iscsi_target_prefix cinder_emc_config_file).each do |attr|
+ it "has emc #{attr} set" do
+ node.set['openstack']['block-storage']['emc'][attr] = "emc_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^#{attr}=emc_#{attr}_value$/)
+ end
+ end
+ end
+
+ context 'vmware vmdk settings' do
+ before do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.vmware.vmdk.VMwareVcVmdkDriver'
+ end
+
+ %w(vmware_host_ip vmware_host_username vmware_host_password
+ vmware_api_retry_count vmware_task_poll_interval vmware_volume_folder
+ vmware_image_transfer_timeout_secs vmware_max_objects_retrieval).each do |attr|
+ it "has vmware #{attr} set" do
+ node.set['openstack']['block-storage']['vmware'][attr] = "vmware_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^#{attr} = vmware_#{attr}_value$/)
+ end
+ end
+
+ it 'has no wsdl_location line without the attribute' do
+ node.set['openstack']['block-storage']['vmware']['vmware_wsdl_location'] = nil
+ expect(chef_run).not_to render_file(file.name).with_content(/^vmware_wsdl_location = /)
+ end
+
+ it 'has wsdl_location line with attribute present' do
+ node.set['openstack']['block-storage']['vmware']['vmware_wsdl_location'] = 'http://127.0.0.1/wsdl'
+ expect(chef_run).to render_file(file.name).with_content(%r(^vmware_wsdl_location = http://127.0.0.1/wsdl$))
+ end
+ end
+
+ context 'gpfs settings' do
+ before do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.gpfs.GPFSDriver'
+ end
+
+ %w(gpfs_mount_point_base gpfs_images_share_mode gpfs_max_clone_depth
+ gpfs_sparse_volumes gpfs_storage_pool).each do |attr|
+ it "has gpfs #{attr} set" do
+ node.set['openstack']['block-storage']['gpfs'][attr] = "gpfs_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^#{attr} = gpfs_#{attr}_value$/)
+ end
+ end
+
+ it 'has no gpfs_images_dir line without the attribute' do
+ node.set['openstack']['block-storage']['gpfs']['gpfs_images_dir'] = nil
+ expect(chef_run).not_to render_file(file.name).with_content(/^gpfs_images_dir = /)
+ end
+
+ it 'has gpfs_images_dir line with attribute present' do
+ node.set['openstack']['block-storage']['gpfs']['gpfs_images_dir'] = 'gpfs_images_dir_value'
+ expect(chef_run).to render_file(file.name).with_content(/^gpfs_images_dir = gpfs_images_dir_value$/)
+ end
end
end
end
diff --git a/spec/volume-redhat_spec.rb b/spec/volume-redhat_spec.rb
index 8c7b99f..9fe1cd1 100644
--- a/spec/volume-redhat_spec.rb
+++ b/spec/volume-redhat_spec.rb
@@ -50,8 +50,9 @@ describe 'openstack-block-storage::volume' do
end
it 'has redhat include' do
+ node.set['openstack']['block-storage']['volume']['volumes_dir'] = 'volumes_dir_value'
expect(chef_run).to render_file(file.name).with_content(
- 'include /var/lib/cinder/volumes/*')
+ 'include volumes_dir_value/*')
expect(chef_run).not_to render_file(file.name).with_content(
'include /etc/tgt/conf.d/*.conf')
end
@@ -159,5 +160,27 @@ describe 'openstack-block-storage::volume' do
)
end
end
+
+ describe 'create_vg' do
+ let(:file) { chef_run.template('/etc/init.d/cinder-group-active') }
+ before do
+ node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.lvm.LVMISCSIDriver'
+ node.set['openstack']['block-storage']['volume']['create_volume_group'] = true
+ stub_command('vgs cinder-volumes').and_return(false)
+ end
+
+ describe 'template contents' do
+ it 'sources /etc/rc.d/init.d/functions' do
+ expect(chef_run).to render_file(file.name).with_content(%r(^\s*. /etc/rc.d/init.d/functions$))
+ end
+
+ it 'calls success and echo' do
+ [/^\s*success$/, /^\s*echo$/].each do |cmd|
+ expect(chef_run).to render_file(file.name).with_content(cmd)
+ end
+ end
+ end
+ end
+
end
end
diff --git a/spec/volume_spec.rb b/spec/volume_spec.rb
index 53a7d06..aac0b11 100644
--- a/spec/volume_spec.rb
+++ b/spec/volume_spec.rb
@@ -56,17 +56,22 @@ describe 'openstack-block-storage::volume' do
let(:file) { chef_run.template('/etc/cinder/nfs_shares.conf') }
before do
node.set['openstack']['block-storage']['volume']['driver'] = 'cinder.volume.drivers.ibm.ibmnas.IBMNAS_NFSDriver'
- node.set['openstack']['block-storage']['ibmnas']['nas_access_ip'] = '127.0.0.1'
- node.set['openstack']['block-storage']['ibmnas']['export'] = '/ibm/fs/export'
end
- it 'creates IBMNAS shares_config file' do
- expect(chef_run).to create_template(file.name).with(
+ context 'IBMNAS shares_config file' do
+ it 'creates the file' do
+ expect(chef_run).to create_template(file.name).with(
owner: 'cinder',
group: 'cinder',
mode: '0600'
)
- expect(chef_run).to render_file(file.name).with_content('127.0.0.1:/ibm/fs/export')
+ end
+
+ it 'sets the ibmnas access_ip attribute' do
+ node.set['openstack']['block-storage']['ibmnas']['nas_access_ip'] = '127.0.0.1'
+ node.set['openstack']['block-storage']['ibmnas']['export'] = '/ibm/fs/export'
+ expect(chef_run).to render_file(file.name).with_content('127.0.0.1:/ibm/fs/export')
+ end
end
it 'installs nfs packages' do
@@ -95,6 +100,36 @@ describe 'openstack-block-storage::volume' do
it 'creates the nfs mount point' do
expect(chef_run).to create_directory '/mnt/cinder-volumes'
end
+
+ context 'shares config file' do
+ let(:shares_config_file) { 'nfs_shares_config_file' }
+ let(:file) { chef_run.template(shares_config_file) }
+
+ before do
+ node.set['openstack']['block-storage']['nfs']['shares_config'] = shares_config_file
+ end
+
+ it 'creates the file' do
+ node.set['openstack']['block-storage']['user'] = 'test_user'
+ node.set['openstack']['block-storage']['group'] = 'test_group'
+
+ expect(chef_run).to create_template(file.name).with(
+ owner: 'test_user',
+ group: 'test_group',
+ mode: '0600'
+ )
+ end
+
+ it 'sets netapp server hostname export settings' do
+ netapp_server_hostname = %w(hostname1 hostname2)
+ node.set['openstack']['block-storage']['netapp']['netapp_server_hostname'] = netapp_server_hostname
+ node.set['openstack']['block-storage']['netapp']['export'] = 'netapp_export_value'
+
+ netapp_server_hostname.each do |hostname|
+ expect(chef_run).to render_file(file.name).with_content(/^#{hostname}:netapp_export_value$/)
+ end
+ end
+ end
end
describe 'ISCSI' do
@@ -207,8 +242,10 @@ describe 'openstack-block-storage::volume' do
end
it 'has ubuntu include' do
+ node.set['openstack']['block-storage']['volume']['volumes_dir'] = 'volumes_dir_value'
+
expect(chef_run).to render_file(file.name).with_content('include /etc/tgt/conf.d/*.conf')
- expect(chef_run).not_to render_file(file.name).with_content('include /var/lib/cinder/volumes/*')
+ expect(chef_run).not_to render_file(file.name).with_content('include volumes_dir_value/*')
end
end
@@ -241,6 +278,29 @@ describe 'openstack-block-storage::volume' do
it 'creates cinder group active template file' do
expect(chef_run).to create_template(file.name)
end
+
+ describe 'template contents' do
+ let(:volume_group_value) { 'volume_group_value' }
+ before do
+ node.set['openstack']['block-storage']['volume']['volume_group'] = volume_group_value
+ stub_command("vgs #{volume_group_value}").and_return(true)
+ end
+
+ it 'calls vgs with the volume name attribute' do
+ expect(chef_run).to render_file(file.name).with_content(%r(vgs #{volume_group_value} > /dev/null 2>&1))
+ end
+
+ it 'calls vgcreate with the volume name and volume file attributes' do
+ node.set['openstack']['block-storage']['volume']['state_path'] = 'state_path_value'
+ volume_file = "state_path_value/#{volume_group_value}.img"
+ expect(chef_run).to render_file(file.name).with_content(/vgcreate #{volume_group_value} \$\(losetup --show -f #{volume_file}\)/)
+ end
+
+ it 'has ubuntu settings' do
+ expect(chef_run).to render_file(file.name).with_content(/^\s*echo "SUCCESS"/)
+ expect(chef_run).not_to render_file(file.name).with_content(/^\s*success$/)
+ end
+ end
end
describe 'cinder_emc_config.xml' do
@@ -257,34 +317,39 @@ describe 'openstack-block-storage::volume' do
expect(sprintf('%o', file.mode)).to eq('644')
end
- it 'has StorageType' do
- expect(chef_run).to render_file(file.name).with_content('0')
- end
+ describe 'template contents' do
+ before do
+ Chef::Recipe.any_instance.stub(:get_password)
+ .with('user', anything)
+ .and_return('emc_test_pass')
+ end
- it 'has EcomServerIp' do
- expect(chef_run).to render_file(file.name).with_content('127.0.0.1')
- end
+ %w(StorageType EcomServerPort EcomUserName).each do |attr|
+ it "has an emc #{attr} setting" do
+ node.set['openstack']['block-storage']['emc'][attr] = "emc_#{attr}_value"
+ expect(chef_run).to render_file(file.name).with_content(/^<#{attr}>emc_#{attr}_value<\/#{attr}>$/)
+ end
+ end
- it 'has EcomServerPort' do
- expect(chef_run).to render_file(file.name).with_content('5988')
- end
+ it 'has a EcomServerIP' do
+ node.set['openstack']['block-storage']['emc']['EcomServerIP'] = 'emc_EcomServerIP_value'
+ expect(chef_run).to render_file(file.name).with_content(/^emc_EcomServerIP_value<\/EcomServerIp>$/)
+ end
- it 'has EcomUserName' do
- expect(chef_run).to render_file(file.name).with_content('admin')
- end
+ it 'has EcomPassword' do
+ node.set['openstack']['block-storage']['emc']['EcomUserName'] = 'emc_username'
+ expect(chef_run).to render_file(file.name).with_content(/^emc_test_pass<\/EcomPassword>$/)
+ end
- it 'has EcomPassword' do
- expect(chef_run).to render_file(file.name).with_content('emc_test_pass')
- end
+ it 'does not have MaskingView when not specified' do
+ expect(chef_run).not_to render_file(file.name).with_content(/^/)
+ end
- it 'does not have MaskingView when not specified' do
- expect(chef_run).not_to render_file(file.name).with_content('')
- end
+ it 'has MaskingView when specified' do
+ node.set['openstack']['block-storage']['emc']['MaskingView'] = 'testMaskingView'
- it 'has MaskingView when specified' do
- node.set['openstack']['block-storage']['emc']['MaskingView'] = 'testMaskingView'
-
- expect(chef_run).to render_file(file.name).with_content('testMaskingView')
+ expect(chef_run).to render_file(file.name).with_content(/^testMaskingView<\/MaskingView>$/)
+ end
end
end
end
diff --git a/templates/default/cinder-group-active.erb b/templates/default/cinder-group-active.erb
index e2ea870..3a7eebb 100644
--- a/templates/default/cinder-group-active.erb
+++ b/templates/default/cinder-group-active.erb
@@ -1,4 +1,5 @@
#!/bin/sh
+<%= node["openstack"]["block-storage"]["custom_template_banner"] %>
#
# cinder volume group active script
#
diff --git a/templates/default/shares.conf.erb b/templates/default/shares.conf.erb
index e8b93f2..1c46112 100644
--- a/templates/default/shares.conf.erb
+++ b/templates/default/shares.conf.erb
@@ -1,4 +1,5 @@
-# Automatically generated by chef, changes will be overwritten
+<%= node["openstack"]["block-storage"]["custom_template_banner"] %>
+
<% node["openstack"]["block-storage"]["netapp"]["netapp_server_hostname"].each do |h| %>
<%= h %>:<%= @export %>
<% end %>