nova_api_spec.rb 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. require 'spec_helper'
  2. describe 'nova::api' do
  3. let :pre_condition do
  4. "include nova
  5. class { '::nova::keystone::authtoken':
  6. password => 'passw0rd',
  7. }"
  8. end
  9. let :params do
  10. {}
  11. end
  12. shared_examples 'nova-api' do
  13. context 'with default parameters' do
  14. it { is_expected.to contain_class('nova::keystone::authtoken') }
  15. it { is_expected.to contain_class('cinder::client').that_notifies('Nova::Generic_service[api]') }
  16. it 'installs nova-api package and service' do
  17. is_expected.to contain_service('nova-api').with(
  18. :name => platform_params[:nova_api_service],
  19. :ensure => 'running',
  20. :hasstatus => true,
  21. :enable => true,
  22. :tag => 'nova-service',
  23. )
  24. is_expected.to contain_package('nova-api').with(
  25. :name => platform_params[:nova_api_package],
  26. :ensure => 'present',
  27. :tag => ['openstack', 'nova-package'],
  28. )
  29. is_expected.to contain_package('nova-api').that_requires('Anchor[nova::install::begin]')
  30. is_expected.to contain_package('nova-api').that_notifies('Anchor[nova::install::end]')
  31. is_expected.to_not contain_exec('validate_nova_api')
  32. end
  33. it 'enable metadata in evenlet configuration' do
  34. is_expected.to contain_nova_config('DEFAULT/enabled_apis').with_value('osapi_compute,metadata')
  35. end
  36. it { is_expected.to contain_nova_config('DEFAULT/instance_name_template').with_ensure('absent')}
  37. it 'configures various stuff' do
  38. is_expected.to contain_nova_config('wsgi/api_paste_config').with('value' => 'api-paste.ini')
  39. is_expected.to contain_nova_config('DEFAULT/osapi_compute_listen').with('value' => '0.0.0.0')
  40. is_expected.to contain_nova_config('DEFAULT/osapi_compute_listen_port').with('value' => '8774')
  41. is_expected.to contain_nova_config('DEFAULT/metadata_listen').with('value' => '0.0.0.0')
  42. is_expected.to contain_nova_config('DEFAULT/metadata_listen_port').with('value' => '8775')
  43. is_expected.to contain_nova_config('DEFAULT/osapi_volume_listen').with('value' => '0.0.0.0')
  44. is_expected.to contain_nova_config('DEFAULT/osapi_compute_workers').with('value' => '5')
  45. is_expected.to contain_nova_config('DEFAULT/metadata_workers').with('value' => '5')
  46. is_expected.to contain_nova_config('DEFAULT/default_floating_pool').with('value' => 'nova')
  47. is_expected.to contain_nova_config('api/fping_path').with('value' => '/usr/sbin/fping')
  48. is_expected.to contain_nova_config('oslo_middleware/enable_proxy_headers_parsing').with('value' => '<SERVICE DEFAULT>')
  49. is_expected.to contain_nova_config('api/metadata_cache_expiration').with('value' => '<SERVICE DEFAULT>')
  50. is_expected.to contain_nova_config('api/vendordata_jsonfile_path').with('value' => '<SERVICE DEFAULT>')
  51. is_expected.to contain_nova_config('api/vendordata_providers').with('value' => '<SERVICE DEFAULT>')
  52. is_expected.to contain_nova_config('api/vendordata_dynamic_targets').with('value' => '<SERVICE DEFAULT>')
  53. is_expected.to contain_nova_config('api/vendordata_dynamic_connect_timeout').with('value' => '<SERVICE DEFAULT>')
  54. is_expected.to contain_nova_config('api/vendordata_dynamic_read_timeout').with('value' => '<SERVICE DEFAULT>')
  55. is_expected.to contain_nova_config('api/max_limit').with('value' => '<SERVICE DEFAULT>')
  56. is_expected.to contain_nova_config('api/compute_link_prefix').with('value' => '<SERVICE DEFAULT>')
  57. is_expected.to contain_nova_config('api/glance_link_prefix').with('value' => '<SERVICE DEFAULT>')
  58. is_expected.to contain_nova_config('api/hide_server_address_states').with('value' => '<SERVICE DEFAULT>')
  59. is_expected.to contain_nova_config('api/allow_instance_snapshots').with('value' => '<SERVICE DEFAULT>')
  60. is_expected.to contain_nova_config('DEFAULT/enable_network_quota').with('value' => '<SERVICE DEFAULT>')
  61. is_expected.to contain_nova_config('api/enable_instance_password').with('value' => '<SERVICE DEFAULT>')
  62. is_expected.to contain_nova_config('DEFAULT/password_length').with('value' => '<SERVICE DEFAULT>')
  63. is_expected.to contain_nova_config('DEFAULT/allow_resize_to_same_host').with('value' => false)
  64. end
  65. it 'unconfigures neutron_metadata proxy' do
  66. is_expected.to contain_nova_config('neutron/service_metadata_proxy').with(:value => false)
  67. is_expected.to contain_nova_config('neutron/metadata_proxy_shared_secret').with(:ensure => 'absent')
  68. end
  69. end
  70. context 'with overridden parameters' do
  71. before do
  72. params.merge!({
  73. :enabled => false,
  74. :ensure_package => '2012.1-2',
  75. :api_bind_address => '192.168.56.210',
  76. :metadata_listen => '127.0.0.1',
  77. :metadata_listen_port => 8875,
  78. :osapi_compute_listen_port => 8874,
  79. :use_forwarded_for => false,
  80. :ratelimits => '(GET, "*", .*, 100, MINUTE);(POST, "*", .*, 200, MINUTE)',
  81. :neutron_metadata_proxy_shared_secret => 'secrete',
  82. :osapi_compute_workers => 1,
  83. :metadata_workers => 2,
  84. :default_floating_pool => 'public',
  85. :enable_proxy_headers_parsing => true,
  86. :metadata_cache_expiration => 15,
  87. :vendordata_jsonfile_path => '/tmp',
  88. :vendordata_providers => ['StaticJSON', 'DynamicJSON'],
  89. :vendordata_dynamic_targets => ['join@http://127.0.0.1:9999/v1/'],
  90. :vendordata_dynamic_connect_timeout => 30,
  91. :vendordata_dynamic_read_timeout => 30,
  92. :osapi_max_limit => 1000,
  93. :osapi_compute_link_prefix => 'https://10.0.0.1:7777/',
  94. :osapi_glance_link_prefix => 'https://10.0.0.1:6666/',
  95. :osapi_hide_server_address_states => 'building',
  96. :allow_instance_snapshots => true,
  97. :enable_network_quota => false,
  98. :enable_instance_password => true,
  99. :password_length => 12,
  100. :pci_alias => "[{\"vendor_id\":\"8086\",\"product_id\":\"0126\",\"name\":\"graphic_card\"},{\"vendor_id\":\"9096\",\"product_id\":\"1520\",\"name\":\"network_card\"}]",
  101. :allow_resize_to_same_host => true,
  102. })
  103. end
  104. it 'installs nova-api package and service' do
  105. is_expected.to contain_package('nova-api').with(
  106. :name => platform_params[:nova_api_package],
  107. :ensure => '2012.1-2',
  108. :tag => ['openstack', 'nova-package'],
  109. )
  110. is_expected.to contain_service('nova-api').with(
  111. :name => platform_params[:nova_api_service],
  112. :ensure => 'stopped',
  113. :hasstatus => true,
  114. :enable => false,
  115. :tag => 'nova-service',
  116. )
  117. end
  118. it 'configures various stuff' do
  119. is_expected.to contain_nova_config('DEFAULT/osapi_compute_listen').with('value' => '192.168.56.210')
  120. is_expected.to contain_nova_config('DEFAULT/osapi_compute_listen_port').with('value' => '8874')
  121. is_expected.to contain_nova_config('DEFAULT/metadata_listen').with('value' => '127.0.0.1')
  122. is_expected.to contain_nova_config('DEFAULT/metadata_listen_port').with('value' => '8875')
  123. is_expected.to contain_nova_config('DEFAULT/osapi_volume_listen').with('value' => '192.168.56.210')
  124. is_expected.to contain_nova_config('api/use_forwarded_for').with('value' => false)
  125. is_expected.to contain_nova_config('DEFAULT/osapi_compute_workers').with('value' => '1')
  126. is_expected.to contain_nova_config('DEFAULT/metadata_workers').with('value' => '2')
  127. is_expected.to contain_nova_config('DEFAULT/default_floating_pool').with('value' => 'public')
  128. is_expected.to contain_nova_config('api/metadata_cache_expiration').with('value' => '15')
  129. is_expected.to contain_nova_config('api/vendordata_jsonfile_path').with('value' => '/tmp')
  130. is_expected.to contain_nova_config('api/vendordata_providers').with('value' => 'StaticJSON,DynamicJSON')
  131. is_expected.to contain_nova_config('api/vendordata_dynamic_targets').with('value' => 'join@http://127.0.0.1:9999/v1/')
  132. is_expected.to contain_nova_config('api/vendordata_dynamic_connect_timeout').with('value' => '30')
  133. is_expected.to contain_nova_config('api/vendordata_dynamic_read_timeout').with('value' => '30')
  134. is_expected.to contain_nova_config('api/max_limit').with('value' => '1000')
  135. is_expected.to contain_nova_config('api/compute_link_prefix').with('value' => 'https://10.0.0.1:7777/')
  136. is_expected.to contain_nova_config('api/glance_link_prefix').with('value' => 'https://10.0.0.1:6666/')
  137. is_expected.to contain_nova_config('neutron/service_metadata_proxy').with('value' => true)
  138. is_expected.to contain_nova_config('neutron/metadata_proxy_shared_secret').with('value' => 'secrete')
  139. is_expected.to contain_nova_config('oslo_middleware/enable_proxy_headers_parsing').with('value' => true)
  140. is_expected.to contain_nova_config('api/hide_server_address_states').with('value' => 'building')
  141. is_expected.to contain_nova_config('api/allow_instance_snapshots').with('value' => true)
  142. is_expected.to contain_nova_config('DEFAULT/enable_network_quota').with('value' => false)
  143. is_expected.to contain_nova_config('api/enable_instance_password').with('value' => true)
  144. is_expected.to contain_nova_config('DEFAULT/password_length').with('value' => '12')
  145. is_expected.to contain_nova_config('DEFAULT/allow_resize_to_same_host').with('value' => true)
  146. end
  147. it 'configures nova pci_alias entries' do
  148. is_expected.to contain_nova_config('DEFAULT/pci_alias').with(
  149. 'value' => "[{\"vendor_id\":\"8086\",\"product_id\":\"0126\",\"name\":\"graphic_card\"},{\"vendor_id\":\"9096\",\"product_id\":\"1520\",\"name\":\"network_card\"}]"
  150. )
  151. end
  152. end
  153. context 'while validating the service with default command' do
  154. before do
  155. params.merge!({
  156. :validate => true,
  157. })
  158. end
  159. it { is_expected.to contain_exec('execute nova-api validation').with(
  160. :path => '/usr/bin:/bin:/usr/sbin:/sbin',
  161. :provider => 'shell',
  162. :tries => '10',
  163. :try_sleep => '2',
  164. :command => 'nova --os-auth-url http://127.0.0.1:5000/ --os-project-name services --os-username nova --os-password passw0rd flavor-list',
  165. )}
  166. it { is_expected.to contain_anchor('create nova-api anchor').with(
  167. :require => 'Exec[execute nova-api validation]',
  168. )}
  169. end
  170. context 'while validating the service with custom command' do
  171. before do
  172. params.merge!({
  173. :validate => true,
  174. :validation_options => { 'nova-api' => { 'command' => 'my-script' } }
  175. })
  176. end
  177. it { is_expected.to contain_exec('execute nova-api validation').with(
  178. :path => '/usr/bin:/bin:/usr/sbin:/sbin',
  179. :provider => 'shell',
  180. :tries => '10',
  181. :try_sleep => '2',
  182. :command => 'my-script',
  183. )}
  184. it { is_expected.to contain_anchor('create nova-api anchor').with(
  185. :require => 'Exec[execute nova-api validation]',
  186. )}
  187. end
  188. context 'while not managing service state' do
  189. before do
  190. params.merge!({
  191. :enabled => false,
  192. :manage_service => false,
  193. })
  194. end
  195. it { is_expected.to contain_service('nova-api').without_ensure }
  196. end
  197. context 'with default database parameters' do
  198. let :pre_condition do
  199. "include nova
  200. class { '::nova::keystone::authtoken':
  201. password => 'a_big_secret',
  202. }"
  203. end
  204. it { is_expected.to_not contain_nova_config('database/connection') }
  205. it { is_expected.to_not contain_nova_config('database/slave_connection') }
  206. it { is_expected.to_not contain_nova_config('api_database/connection') }
  207. it { is_expected.to_not contain_nova_config('api_database/slave_connection') }
  208. it { is_expected.to_not contain_nova_config('database/idle_timeout').with_value('<SERVICE DEFAULT>') }
  209. end
  210. context 'with overridden database parameters' do
  211. let :pre_condition do
  212. "class { 'nova':
  213. database_connection => 'mysql://user:pass@db/db1',
  214. slave_connection => 'mysql://user:pass@slave/db1',
  215. api_database_connection => 'mysql://user:pass@db/db2',
  216. api_slave_connection => 'mysql://user:pass@slave/db2',
  217. database_idle_timeout => '30',
  218. }
  219. class { '::nova::keystone::authtoken':
  220. password => 'passw0rd',
  221. }
  222. "
  223. end
  224. it { is_expected.to contain_nova_config('database/connection').with_value('mysql://user:pass@db/db1').with_secret(true) }
  225. it { is_expected.to contain_nova_config('database/slave_connection').with_value('mysql://user:pass@slave/db1').with_secret(true) }
  226. it { is_expected.to contain_nova_config('api_database/connection').with_value('mysql://user:pass@db/db2').with_secret(true) }
  227. it { is_expected.to contain_nova_config('api_database/slave_connection').with_value('mysql://user:pass@slave/db2').with_secret(true) }
  228. it { is_expected.to contain_nova_config('database/idle_timeout').with_value('30') }
  229. end
  230. context 'with custom instance_name_template' do
  231. before do
  232. params.merge!({
  233. :instance_name_template => 'instance-%08x',
  234. })
  235. end
  236. it 'configures instance_name_template' do
  237. is_expected.to contain_nova_config('DEFAULT/instance_name_template').with_value('instance-%08x');
  238. end
  239. end
  240. context 'when running nova API in wsgi compute, and enabling metadata' do
  241. before do
  242. params.merge!({ :service_name => 'httpd' })
  243. end
  244. let :pre_condition do
  245. "include ::apache
  246. include ::nova
  247. class { '::nova::keystone::authtoken':
  248. password => 'a_big_secret',
  249. }"
  250. end
  251. it 'enable nova API service' do
  252. is_expected.to contain_service('nova-api').with(
  253. :ensure => 'running',
  254. :name => platform_params[:nova_api_service],
  255. :enable => true,
  256. :tag => 'nova-service',
  257. )
  258. end
  259. it 'enable metadata in evenlet configuration' do
  260. is_expected.to contain_nova_config('DEFAULT/enabled_apis').with_value('metadata')
  261. end
  262. end
  263. context 'when running nova API in wsgi for compute, and disabling metadata' do
  264. before do
  265. params.merge!({
  266. :service_name => 'httpd',
  267. :enabled_apis => ['osapi_compute'] })
  268. end
  269. let :pre_condition do
  270. "include ::apache
  271. include ::nova
  272. class { '::nova::keystone::authtoken':
  273. password => 'a_big_secret',
  274. }"
  275. end
  276. it 'disable nova API service' do
  277. is_expected.to contain_service('nova-api').with(
  278. :ensure => 'stopped',
  279. :name => platform_params[:nova_api_service],
  280. :enable => false,
  281. :tag => 'nova-service',
  282. )
  283. end
  284. end
  285. context 'when disabling cinder client installation' do
  286. before do
  287. params.merge!({ :install_cinder_client => false })
  288. end
  289. it { is_expected.to_not contain_class('cinder::client') }
  290. end
  291. context 'when service_name is not valid' do
  292. before do
  293. params.merge!({ :service_name => 'foobar' })
  294. end
  295. let :pre_condition do
  296. "include ::apache
  297. include ::nova
  298. class { '::nova::keystone::authtoken':
  299. password => 'a_big_secret',
  300. }"
  301. end
  302. it_raises 'a Puppet::Error', /Invalid service_name/
  303. end
  304. end
  305. on_supported_os({
  306. :supported_os => OSDefaults.get_supported_os
  307. }).each do |os,facts|
  308. context "on #{os}" do
  309. let (:facts) do
  310. facts.merge!(OSDefaults.get_facts({ :processorcount => 5 }))
  311. end
  312. let (:platform_params) do
  313. case facts[:osfamily]
  314. when 'Debian'
  315. { :nova_api_package => 'nova-api',
  316. :nova_api_service => 'nova-api' }
  317. when 'RedHat'
  318. { :nova_api_package => 'openstack-nova-api',
  319. :nova_api_service => 'openstack-nova-api' }
  320. end
  321. end
  322. it_behaves_like 'nova-api'
  323. end
  324. end
  325. end