diff --git a/manifests/api.pp b/manifests/api.pp index d94c1976..1123cd2a 100644 --- a/manifests/api.pp +++ b/manifests/api.pp @@ -42,6 +42,15 @@ # Required when $use_ssl is set to 'true'. # Defaults to $::os_service_default. # +# [*service_name*] +# (optional) Name of the service that will be providing the +# server functionality of heat-api. +# If the value is 'httpd', this means heat-api will be a web +# service, and you must use another class to configure that +# web service. For example, use class { 'heat::wsgi::apache_api'...} +# to make heat-api be a web app using apache mod_wsgi. +# Defaults to '$::heat::params::api_service_name' +# # === Deprecated Parameters # # No Deprecated Parameters. @@ -56,7 +65,8 @@ class heat::api ( $use_ssl = false, $cert_file = $::os_service_default, $key_file = $::os_service_default, -) { + $service_name = $::heat::params::api_service_name, +) inherits heat::params { include ::heat include ::heat::deps @@ -86,13 +96,29 @@ class heat::api ( } } - service { 'heat-api': - ensure => $service_ensure, - name => $::heat::params::api_service_name, - enable => $enabled, - hasstatus => true, - hasrestart => true, - tag => 'heat-service', + if $service_name == $::heat::params::api_service_name { + service { 'heat-api': + ensure => $service_ensure, + name => $::heat::params::api_service_name, + enable => $enabled, + hasstatus => true, + hasrestart => true, + tag => 'heat-service', + } + } elsif $service_name == 'httpd' { + include ::apache::params + service { 'heat-api': + ensure => 'stopped', + name => $::heat::params::api_service_name, + enable => false, + tag => ['heat-service'], + } + + # we need to make sure heat-api/eventlet is stopped before trying to start apache + Service['heat-api'] -> Service[$service_name] + } else { + fail("Invalid service_name. Either heat-api/openstack-heat-api for \ +running as a standalone service, or httpd for being run by a httpd server") } heat_config { diff --git a/manifests/api_cfn.pp b/manifests/api_cfn.pp index 3fb81ebc..20fc35c5 100644 --- a/manifests/api_cfn.pp +++ b/manifests/api_cfn.pp @@ -45,6 +45,15 @@ # Required when $use_ssl is set to 'true'. # Defaults to $::os_service_default. # +# [*service_name*] +# (optional) Name of the service that will be providing the +# server functionality of heat-api-cfn. +# If the value is 'httpd', this means heat-api-cfn will be a web +# service, and you must use another class to configure that +# web service. For example, use class { 'heat::wsgi::apache_api_cfn'...} +# to make heat-api-cfn be a web app using apache mod_wsgi. +# Defaults to '$::heat::params::api_cfn_service_name' +# # == Deprecated Parameters # # No Deprecated Parameters. @@ -59,7 +68,8 @@ class heat::api_cfn ( $use_ssl = false, $cert_file = $::os_service_default, $key_file = $::os_service_default, -) { + $service_name = $::heat::params::api_cfn_service_name, +) inherits heat::params { include ::heat include ::heat::deps @@ -89,13 +99,29 @@ class heat::api_cfn ( } } - service { 'heat-api-cfn': - ensure => $service_ensure, - name => $::heat::params::api_cfn_service_name, - enable => $enabled, - hasstatus => true, - hasrestart => true, - tag => 'heat-service', + if $service_name == $::heat::params::api_cfn_service_name { + service { 'heat-api-cfn': + ensure => $service_ensure, + name => $::heat::params::api_cfn_service_name, + enable => $enabled, + hasstatus => true, + hasrestart => true, + tag => 'heat-service', + } + } elsif $service_name == 'httpd' { + include ::apache::params + service { 'heat-api-cfn': + ensure => 'stopped', + name => $::heat::params::api_cfn_service_name, + enable => false, + tag => ['heat-service'], + } + + # we need to make sure heat-api-cfn/eventlet is stopped before trying to start apache + Service['heat-api-cfn'] -> Service[$service_name] + } else { + fail("Invalid service_name. Either heat-api-cfn/openstack-heat-api-cfn for \ +running as a standalone service, or httpd for being run by a httpd server") } heat_config { diff --git a/manifests/api_cloudwatch.pp b/manifests/api_cloudwatch.pp index 236ce785..b75ff89e 100644 --- a/manifests/api_cloudwatch.pp +++ b/manifests/api_cloudwatch.pp @@ -44,6 +44,16 @@ # Required when $use_ssl is set to 'true'. # Defaults to $::os_service_default. # +# [*service_name*] +# (optional) Name of the service that will be providing the +# server functionality of heat-api-cloudwatch. +# If the value is 'httpd', this means heat-api-cloudwatch will be a web +# service, and you must use another class to configure that +# web service. For example, use +# class{ 'heat::wsgi::apache_api_cloudwatch'...} to make heat-api-cloudwatch +# be a web app using apache mod_wsgi. +# Defaults to '$::heat::params::api_cloudwatch_service_name' +# # == Deprecated Parameters # # No Deprecated Parameters. @@ -58,7 +68,8 @@ class heat::api_cloudwatch ( $use_ssl = false, $cert_file = $::os_service_default, $key_file = $::os_service_default, -) { + $service_name = $::heat::params::api_cloudwatch_service_name, +) inherits heat::params { include ::heat include ::heat::deps @@ -88,13 +99,29 @@ class heat::api_cloudwatch ( } } - service { 'heat-api-cloudwatch': - ensure => $service_ensure, - name => $::heat::params::api_cloudwatch_service_name, - enable => $enabled, - hasstatus => true, - hasrestart => true, - tag => 'heat-service', + if $service_name == $::heat::params::api_cloudwatch_service_name { + service { 'heat-api-cloudwatch': + ensure => $service_ensure, + name => $::heat::params::api_cloudwatch_service_name, + enable => $enabled, + hasstatus => true, + hasrestart => true, + tag => 'heat-service', + } + } elsif $service_name == 'httpd' { + include ::apache::params + service { 'heat-api-cloudwatch': + ensure => 'stopped', + name => $::heat::params::api_cloudwatch_service_name, + enable => false, + tag => ['heat-service'], + } + + # we need to make sure heat-api-cloudwatch/eventlet is stopped before trying to start apache + Service['heat-api-cloudwatch'] -> Service[$service_name] + } else { + fail("Invalid service_name. Either heat-api-cloudwatch/openstack-heat-api-cloudwatch for \ +running as a standalone service, or httpd for being run by a httpd server") } heat_config { diff --git a/manifests/params.pp b/manifests/params.pp index 4dab153b..103706e3 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -20,6 +20,11 @@ class heat::params { $api_cloudwatch_service_name = 'openstack-heat-api-cloudwatch' $api_cfn_service_name = 'openstack-heat-api-cfn' $engine_service_name = 'openstack-heat-engine' + # WSGI scripts + $heat_wsgi_script_path = '/var/www/cgi-bin/heat' + $heat_api_wsgi_script_source = '/usr/bin/heat-wsgi-api' + $heat_api_cfn_wsgi_script_source = '/usr/bin/heat-wsgi-api-cfn' + $heat_api_cloudwatch_wsgi_script_source = '/usr/bin/heat-wsgi-api-cloudwatch' } 'Debian': { # package names @@ -33,6 +38,11 @@ class heat::params { $api_cloudwatch_service_name = 'heat-api-cloudwatch' $api_cfn_service_name = 'heat-api-cfn' $engine_service_name = 'heat-engine' + # WSGI scripts + $heat_wsgi_script_path = '/usr/lib/cgi-bin/heat' + $heat_api_wsgi_script_source = '/usr/bin/heat-wsgi-api' + $heat_api_cfn_wsgi_script_source = '/usr/bin/heat-wsgi-api-cfn' + $heat_api_cloudwatch_wsgi_script_source = '/usr/bin/heat-wsgi-api-cloudwatch' # Operating system specific case $::operatingsystem { 'Ubuntu': { diff --git a/manifests/wsgi/apache.pp b/manifests/wsgi/apache.pp new file mode 100644 index 00000000..267a74ce --- /dev/null +++ b/manifests/wsgi/apache.pp @@ -0,0 +1,133 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Resource to serve Heat API with apache mod_wsgi in place of heat-api service. +# +# This is useful for the main API as well as the CFN and Cloudwatch APIs. +# Serving Heat API from apache is the recommended way to go for production +# because of limited performance for concurrent accesses when running eventlet. +# +# When using this class you should disable your heat-api service. +# +# == Parameters +# +# [*title*] +# The heat API that will be running over this vhost. +# The valid options are "api", "api_cfn" and "api_cloudwatch" +# +# [*port*] +# The port for the specific API. +# +# [*servername*] +# The servername for the virtualhost. +# Optional. Defaults to $::fqdn +# +# [*bind_host*] +# The host/ip address Apache will listen on. +# Optional. Defaults to undef (listen on all ip addresses). +# +# [*path*] +# The prefix for the endpoint. +# Optional. Defaults to '/' +# +# [*ssl*] +# Use ssl ? (boolean) +# Optional. Defaults to true +# +# [*workers*] +# Number of WSGI workers to spawn. +# Optional. Defaults to 1 +# +# [*priority*] +# (optional) The priority for the vhost. +# Defaults to '10' +# +# [*threads*] +# (optional) The number of threads for the vhost. +# Defaults to $::os_workers +# +# [*ssl_cert*] +# [*ssl_key*] +# [*ssl_chain*] +# [*ssl_ca*] +# [*ssl_crl_path*] +# [*ssl_crl*] +# [*ssl_certs_dir*] +# apache::vhost ssl parameters. +# Optional. Default to apache::vhost 'ssl_*' defaults. +# +# == Dependencies +# +# requires Class['apache'] & Class['heat'] +# +# == Examples +# +# include apache +# +# class { 'heat::wsgi::apache': } +# +define heat::wsgi::apache ( + $port, + $servername = $::fqdn, + $bind_host = undef, + $path = '/', + $ssl = true, + $workers = 1, + $ssl_cert = undef, + $ssl_key = undef, + $ssl_chain = undef, + $ssl_ca = undef, + $ssl_crl_path = undef, + $ssl_crl = undef, + $ssl_certs_dir = undef, + $threads = $::os_workers, + $priority = '10', +) { + if $title !~ /^api(|_cfn|_cloudwatch)$/ { + fail('The valid options are api, api_cfn, api_cloudwatch') + } + include ::heat::deps + include ::heat::params + include ::apache + include ::apache::mod::wsgi + if $ssl { + include ::apache::mod::ssl + } + + ::openstacklib::wsgi::apache { "heat_${title}_wsgi": + bind_host => $bind_host, + bind_port => $port, + group => 'heat', + path => $path, + priority => $priority, + servername => $servername, + ssl => $ssl, + ssl_ca => $ssl_ca, + ssl_cert => $ssl_cert, + ssl_certs_dir => $ssl_certs_dir, + ssl_chain => $ssl_chain, + ssl_crl => $ssl_crl, + ssl_crl_path => $ssl_crl_path, + ssl_key => $ssl_key, + threads => $threads, + user => 'heat', + workers => $workers, + wsgi_daemon_process => "heat_${title}", + wsgi_process_group => "heat_${title}", + wsgi_script_dir => $::heat::params::heat_wsgi_script_path, + wsgi_script_file => "heat_${title}", + wsgi_script_source => getvar("::heat::params::heat_${title}_wsgi_script_source"), + allow_encoded_slashes => 'on', + require => Anchor['heat::install::end'], + } +} diff --git a/manifests/wsgi/apache_api.pp b/manifests/wsgi/apache_api.pp new file mode 100644 index 00000000..4a5867dd --- /dev/null +++ b/manifests/wsgi/apache_api.pp @@ -0,0 +1,108 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Resource to serve Heat API with apache mod_wsgi in place of heat-api service. +# +# Serving Heat API from apache is the recommended way to go for production +# because of limited performance for concurrent accesses when running eventlet. +# +# When using this class you should disable your heat-api service. +# +# == Parameters +# +# [*port*] +# The port for the specific API. +# +# [*servername*] +# The servername for the virtualhost. +# Optional. Defaults to $::fqdn +# +# [*bind_host*] +# The host/ip address Apache will listen on. +# Optional. Defaults to undef (listen on all ip addresses). +# +# [*path*] +# The prefix for the endpoint. +# Optional. Defaults to '/' +# +# [*ssl*] +# Use ssl ? (boolean) +# Optional. Defaults to true +# +# [*workers*] +# Number of WSGI workers to spawn. +# Optional. Defaults to 1 +# +# [*priority*] +# (optional) The priority for the vhost. +# Defaults to '10' +# +# [*threads*] +# (optional) The number of threads for the vhost. +# Defaults to $::os_workers +# +# [*ssl_cert*] +# [*ssl_key*] +# [*ssl_chain*] +# [*ssl_ca*] +# [*ssl_crl_path*] +# [*ssl_crl*] +# [*ssl_certs_dir*] +# apache::vhost ssl parameters. +# Optional. Default to apache::vhost 'ssl_*' defaults. +# +# == Dependencies +# +# requires Class['apache'] & Class['heat'] +# +# == Examples +# +# include apache +# +# class { 'heat::wsgi::apache': } +# +class heat::wsgi::apache_api ( + $port = 8004, + $servername = $::fqdn, + $bind_host = undef, + $path = '/', + $ssl = true, + $workers = 1, + $ssl_cert = undef, + $ssl_key = undef, + $ssl_chain = undef, + $ssl_ca = undef, + $ssl_crl_path = undef, + $ssl_crl = undef, + $ssl_certs_dir = undef, + $threads = $::os_workers, + $priority = '10', +) { + heat::wsgi::apache { 'api': + port => $port, + servername => $servername, + bind_host => $bind_host, + path => $path, + ssl => $ssl, + workers => $workers, + ssl_cert => $ssl_cert, + ssl_key => $ssl_key, + ssl_chain => $ssl_chain, + ssl_ca => $ssl_ca, + ssl_crl_path => $ssl_crl_path, + ssl_crl => $ssl_crl, + ssl_certs_dir => $ssl_certs_dir, + threads => $threads, + priority => $priority, + } +} diff --git a/manifests/wsgi/apache_api_cfn.pp b/manifests/wsgi/apache_api_cfn.pp new file mode 100644 index 00000000..1cba07fe --- /dev/null +++ b/manifests/wsgi/apache_api_cfn.pp @@ -0,0 +1,119 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Resource to serve Heat API with apache mod_wsgi in place of heat-api service. +# +# Serving Heat API from apache is the recommended way to go for production +# because of limited performance for concurrent accesses when running eventlet. +# +# When using this class you should disable your heat-api service. +# +# == Parameters +# +# [*port*] +# The port for the specific API. +# +# [*servername*] +# The servername for the virtualhost. +# Optional. Defaults to $::fqdn +# +# [*bind_host*] +# The host/ip address Apache will listen on. +# Optional. Defaults to undef (listen on all ip addresses). +# +# [*path*] +# The prefix for the endpoint. +# Optional. Defaults to '/' +# +# [*ssl*] +# Use ssl ? (boolean) +# Optional. Defaults to true +# +# [*workers*] +# Number of WSGI workers to spawn. +# Optional. Defaults to 1 +# +# [*priority*] +# (optional) The priority for the vhost. +# Defaults to '10' +# +# [*threads*] +# (optional) The number of threads for the vhost. +# Defaults to $::os_workers +# +# [*ssl_cert*] +# [*ssl_key*] +# [*ssl_chain*] +# [*ssl_ca*] +# [*ssl_crl_path*] +# [*ssl_crl*] +# [*ssl_certs_dir*] +# apache::vhost ssl parameters. +# Optional. Default to apache::vhost 'ssl_*' defaults. +# +# == Dependencies +# +# requires Class['apache'] & Class['heat'] +# +# == Examples +# +# include apache +# +# class { 'heat::wsgi::apache': } +# +class heat::wsgi::apache_api_cfn ( + $port = 8000, + $servername = $::fqdn, + $bind_host = undef, + $path = '/', + $ssl = true, + $workers = 1, + $ssl_cert = undef, + $ssl_key = undef, + $ssl_chain = undef, + $ssl_ca = undef, + $ssl_crl_path = undef, + $ssl_crl = undef, + $ssl_certs_dir = undef, + $threads = $::os_workers, + $priority = '10', +) { + + validate_integer($port) + + # Workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1396553 + if $::osfamily == 'RedHat' and $port == 8000 and $::selinux { + exec { "semanage port -m -t http_port_t -p tcp ${port}": + unless => "semanage port -l | grep -q \"http_port_t.*${port}\"", + path => ['/usr/bin', '/usr/sbin'], + notify => Heat::Wsgi::Apache['api_cfn'], + } + } + heat::wsgi::apache { 'api_cfn': + port => $port, + servername => $servername, + bind_host => $bind_host, + path => $path, + ssl => $ssl, + workers => $workers, + ssl_cert => $ssl_cert, + ssl_key => $ssl_key, + ssl_chain => $ssl_chain, + ssl_ca => $ssl_ca, + ssl_crl_path => $ssl_crl_path, + ssl_crl => $ssl_crl, + ssl_certs_dir => $ssl_certs_dir, + threads => $threads, + priority => $priority, + } +} diff --git a/manifests/wsgi/apache_api_cloudwatch.pp b/manifests/wsgi/apache_api_cloudwatch.pp new file mode 100644 index 00000000..71ca7a77 --- /dev/null +++ b/manifests/wsgi/apache_api_cloudwatch.pp @@ -0,0 +1,108 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Resource to serve Heat API with apache mod_wsgi in place of heat-api service. +# +# Serving Heat API from apache is the recommended way to go for production +# because of limited performance for concurrent accesses when running eventlet. +# +# When using this class you should disable your heat-api service. +# +# == Parameters +# +# [*port*] +# The port for the specific API. +# +# [*servername*] +# The servername for the virtualhost. +# Optional. Defaults to $::fqdn +# +# [*bind_host*] +# The host/ip address Apache will listen on. +# Optional. Defaults to undef (listen on all ip addresses). +# +# [*path*] +# The prefix for the endpoint. +# Optional. Defaults to '/' +# +# [*ssl*] +# Use ssl ? (boolean) +# Optional. Defaults to true +# +# [*workers*] +# Number of WSGI workers to spawn. +# Optional. Defaults to 1 +# +# [*priority*] +# (optional) The priority for the vhost. +# Defaults to '10' +# +# [*threads*] +# (optional) The number of threads for the vhost. +# Defaults to $::os_workers +# +# [*ssl_cert*] +# [*ssl_key*] +# [*ssl_chain*] +# [*ssl_ca*] +# [*ssl_crl_path*] +# [*ssl_crl*] +# [*ssl_certs_dir*] +# apache::vhost ssl parameters. +# Optional. Default to apache::vhost 'ssl_*' defaults. +# +# == Dependencies +# +# requires Class['apache'] & Class['heat'] +# +# == Examples +# +# include apache +# +# class { 'heat::wsgi::apache': } +# +class heat::wsgi::apache_api_cloudwatch ( + $port = 8003, + $servername = $::fqdn, + $bind_host = undef, + $path = '/', + $ssl = true, + $workers = 1, + $ssl_cert = undef, + $ssl_key = undef, + $ssl_chain = undef, + $ssl_ca = undef, + $ssl_crl_path = undef, + $ssl_crl = undef, + $ssl_certs_dir = undef, + $threads = $::os_workers, + $priority = '10', +) { + heat::wsgi::apache { 'api_cloudwatch': + port => $port, + servername => $servername, + bind_host => $bind_host, + path => $path, + ssl => $ssl, + workers => $workers, + ssl_cert => $ssl_cert, + ssl_key => $ssl_key, + ssl_chain => $ssl_chain, + ssl_ca => $ssl_ca, + ssl_crl_path => $ssl_crl_path, + ssl_crl => $ssl_crl, + ssl_certs_dir => $ssl_certs_dir, + threads => $threads, + priority => $priority, + } +} diff --git a/spec/acceptance/basic_heat_spec.rb b/spec/acceptance/basic_heat_spec.rb index bd1dc0f2..cb27ddfe 100644 --- a/spec/acceptance/basic_heat_spec.rb +++ b/spec/acceptance/basic_heat_spec.rb @@ -47,12 +47,21 @@ describe 'basic heat' do domain_password => 'oh_my_no_secret', } class { '::heat::client': } - class { '::heat::api': } + class { '::heat::api': + service_name => 'httpd', + } + include ::heat::wsgi::apache_api class { '::heat::engine': auth_encryption_key => '1234567890AZERTYUIOPMLKJHGFDSQ12', } - class { '::heat::api_cloudwatch': } - class { '::heat::api_cfn': } + class { '::heat::api_cloudwatch': + service_name => 'httpd', + } + include ::heat::wsgi::apache_api_cloudwatch + class { '::heat::api_cfn': + service_name => 'httpd', + } + include ::heat::wsgi::apache_api_cfn class { '::heat::cron::purge_deleted': } EOS @@ -63,15 +72,15 @@ describe 'basic heat' do end describe port(8000) do - it { is_expected.to be_listening.with('tcp') } + it { is_expected.to be_listening } end describe port(8003) do - it { is_expected.to be_listening.with('tcp') } + it { is_expected.to be_listening } end describe port(8004) do - it { is_expected.to be_listening.with('tcp') } + it { is_expected.to be_listening } end describe cron do diff --git a/spec/classes/heat_api_cfn_spec.rb b/spec/classes/heat_api_cfn_spec.rb index 8f7f4cc6..cde3cfb2 100644 --- a/spec/classes/heat_api_cfn_spec.rb +++ b/spec/classes/heat_api_cfn_spec.rb @@ -63,7 +63,7 @@ describe 'heat::api_cfn' do is_expected.to contain_service('heat-api-cfn').with( :ensure => (params[:manage_service] && params[:enabled]) ? 'running' : 'stopped', - :name => platform_params[:api_service_name], + :name => platform_params[:api_cfn_service_name], :enable => params[:enabled], :hasstatus => true, :hasrestart => true, @@ -85,7 +85,7 @@ describe 'heat::api_cfn' do is_expected.to contain_service('heat-api-cfn').with( :ensure => nil, - :name => platform_params[:api_service_name], + :name => platform_params[:api_cfn_service_name], :enable => false, :hasstatus => true, :hasrestart => true, @@ -123,9 +123,9 @@ describe 'heat::api_cfn' do let :platform_params do case facts[:osfamily] when 'Debian' - { :api_service_name => 'heat-api-cfn' } + { :api_cfn_service_name => 'heat-api-cfn' } when 'RedHat' - { :api_service_name => 'openstack-heat-api-cfn' } + { :api_cfn_service_name => 'openstack-heat-api-cfn' } end end diff --git a/spec/classes/heat_api_cloudwatch_spec.rb b/spec/classes/heat_api_cloudwatch_spec.rb index fbe0b001..9aaf45e6 100644 --- a/spec/classes/heat_api_cloudwatch_spec.rb +++ b/spec/classes/heat_api_cloudwatch_spec.rb @@ -64,7 +64,7 @@ describe 'heat::api_cloudwatch' do is_expected.to contain_service('heat-api-cloudwatch').with( :ensure => (params[:manage_service] && params[:enabled]) ? 'running' : 'stopped', - :name => platform_params[:api_service_name], + :name => platform_params[:api_cloudwatch_service_name], :enable => params[:enabled], :hasstatus => true, :hasrestart => true, @@ -86,7 +86,7 @@ describe 'heat::api_cloudwatch' do is_expected.to contain_service('heat-api-cloudwatch').with( :ensure => nil, - :name => platform_params[:api_service_name], + :name => platform_params[:api_cloudwatch_service_name], :enable => false, :hasstatus => true, :hasrestart => true, @@ -124,9 +124,9 @@ describe 'heat::api_cloudwatch' do let :platform_params do case facts[:osfamily] when 'Debian' - { :api_service_name => 'heat-api-cloudwatch' } + { :api_cloudwatch_service_name => 'heat-api-cloudwatch' } when 'RedHat' - { :api_service_name => 'openstack-heat-api-cloudwatch' } + { :api_cloudwatch_service_name => 'openstack-heat-api-cloudwatch' } end end diff --git a/spec/classes/heat_wsgi_apache_api_cfn_spec.rb b/spec/classes/heat_wsgi_apache_api_cfn_spec.rb new file mode 100644 index 00000000..ee44842c --- /dev/null +++ b/spec/classes/heat_wsgi_apache_api_cfn_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' + +describe 'heat::wsgi::apache_api_cfn' do + + shared_examples_for 'heat::wsgi::apache_api_cfn' do + context 'default parameters' do + it { is_expected.to contain_class('heat::wsgi::apache_api_cfn') } + it { is_expected.to contain_heat__wsgi__apache('api_cfn').with( + :port => 8000, + :servername => facts[:fqdn], + :bind_host => nil, + :path => '/', + :ssl => true, + :workers => 1, + :ssl_cert => nil, + :ssl_key => nil, + :ssl_chain => nil, + :ssl_ca => nil, + :ssl_crl_path => nil, + :ssl_certs_dir => nil, + :threads => facts[:os_workers], + :priority => 10, ) + } + 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 + + it_configures 'heat::wsgi::apache_api_cfn' + end + end + +end diff --git a/spec/classes/heat_wsgi_apache_api_cloudwatch_spec.rb b/spec/classes/heat_wsgi_apache_api_cloudwatch_spec.rb new file mode 100644 index 00000000..60601966 --- /dev/null +++ b/spec/classes/heat_wsgi_apache_api_cloudwatch_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' + +describe 'heat::wsgi::apache_api_cloudwatch' do + + shared_examples_for 'heat::wsgi::apache_api_cloudwatch' do + context 'default parameters' do + it { is_expected.to contain_class('heat::wsgi::apache_api_cloudwatch') } + it { is_expected.to contain_heat__wsgi__apache('api_cloudwatch').with( + :port => 8003, + :servername => facts[:fqdn], + :bind_host => nil, + :path => '/', + :ssl => true, + :workers => 1, + :ssl_cert => nil, + :ssl_key => nil, + :ssl_chain => nil, + :ssl_ca => nil, + :ssl_crl_path => nil, + :ssl_certs_dir => nil, + :threads => facts[:os_workers], + :priority => 10, ) + } + 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 + + it_configures 'heat::wsgi::apache_api_cloudwatch' + end + end + +end diff --git a/spec/classes/heat_wsgi_apache_api_spec.rb b/spec/classes/heat_wsgi_apache_api_spec.rb new file mode 100644 index 00000000..abc0ee60 --- /dev/null +++ b/spec/classes/heat_wsgi_apache_api_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' + +describe 'heat::wsgi::apache_api' do + + shared_examples_for 'heat::wsgi::apache_api' do + context 'default parameters' do + it { is_expected.to contain_class('heat::wsgi::apache_api') } + it { is_expected.to contain_heat__wsgi__apache('api').with( + :port => 8004, + :servername => facts[:fqdn], + :bind_host => nil, + :path => '/', + :ssl => true, + :workers => 1, + :ssl_cert => nil, + :ssl_key => nil, + :ssl_chain => nil, + :ssl_ca => nil, + :ssl_crl_path => nil, + :ssl_certs_dir => nil, + :threads => facts[:os_workers], + :priority => 10, ) + } + 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 + + it_configures 'heat::wsgi::apache_api' + end + end + +end diff --git a/spec/defines/heat_wsgi_apache_spec.rb b/spec/defines/heat_wsgi_apache_spec.rb new file mode 100644 index 00000000..fbbf4a79 --- /dev/null +++ b/spec/defines/heat_wsgi_apache_spec.rb @@ -0,0 +1,120 @@ +require 'spec_helper' + +describe 'heat::wsgi::apache' do + + + let :params do + { + :port => 8000, + } + end + + shared_examples_for 'apache serving a service with mod_wsgi' do + context 'valid title' do + let (:title) { 'api' } + it { is_expected.to contain_class('heat::deps') } + it { is_expected.to contain_class('heat::params') } + it { is_expected.to contain_class('apache') } + it { is_expected.to contain_class('apache::mod::wsgi') } + it { is_expected.to contain_class('apache::mod::ssl') } + + context 'with default parameters' do + it { is_expected.to contain_openstacklib__wsgi__apache("heat_#{title}_wsgi").with( + 'bind_host' => nil, + 'bind_port' => '8000', + 'group' => 'heat', + 'user' => 'heat', + 'ssl' => 'true', + 'wsgi_daemon_process' => "heat_#{title}", + 'wsgi_process_group' => "heat_#{title}", + 'wsgi_script_dir' => platform_params[:wsgi_script_dir], + 'wsgi_script_file' => "heat_#{title}", + 'allow_encoded_slashes' => 'on', + )} + it { is_expected.to contain_concat("#{platform_params[:httpd_ports_file]}") } + end + + context 'with bind host' do + let(:params) do + { :bind_host => '1.1.1.1', :port => 9000 } + end + it { is_expected.to contain_openstacklib__wsgi__apache("heat_#{title}_wsgi").with( + 'bind_host' => '1.1.1.1', + 'bind_port' => 9000, ) + } + end + + context 'with api options' do + let (:title) { 'api' } + it { is_expected.to contain_openstacklib__wsgi__apache("heat_#{title}_wsgi").with( + 'wsgi_daemon_process' => "heat_#{title}", + 'wsgi_process_group' => "heat_#{title}", + 'wsgi_script_dir' => platform_params[:wsgi_script_dir], + 'wsgi_script_file' => "heat_#{title}", + 'wsgi_script_source' => platform_params[:script_source_api], + )} + end + + context 'with cfn options' do + let (:title) { 'api_cfn' } + it { is_expected.to contain_openstacklib__wsgi__apache("heat_#{title}_wsgi").with( + 'wsgi_daemon_process' => "heat_#{title}", + 'wsgi_process_group' => "heat_#{title}", + 'wsgi_script_dir' => platform_params[:wsgi_script_dir], + 'wsgi_script_file' => "heat_#{title}", + 'wsgi_script_source' => platform_params[:script_source_cfn], + )} + end + + context 'with cloudwatch options' do + let (:title) { 'api_cloudwatch' } + it { is_expected.to contain_openstacklib__wsgi__apache("heat_#{title}_wsgi").with( + 'wsgi_daemon_process' => "heat_#{title}", + 'wsgi_process_group' => "heat_#{title}", + 'wsgi_script_dir' => platform_params[:wsgi_script_dir], + 'wsgi_script_file' => "heat_#{title}", + 'wsgi_script_source' => platform_params[:script_source_cloudwatch], + )} + end + + end + + context 'invalid title' do + let (:title) { 'someothertitle' } + it { expect { is_expected.to raise_error(Puppet::Error) } } + 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[:osfamily] + when 'Debian' + { :httpd_service_name => 'apache2', + :httpd_ports_file => '/etc/apache2/ports.conf', + :wsgi_script_dir => '/usr/lib/cgi-bin/heat', + :script_source_api => '/usr/bin/heat-wsgi-api', + :script_source_cfn => '/usr/bin/heat-wsgi-api-cfn', + :script_source_cloudwatch => '/usr/bin/heat-wsgi-api-cloudwatch', + } + when 'RedHat' + { :httpd_service_name => 'httpd', + :httpd_ports_file => '/etc/httpd/conf/ports.conf', + :wsgi_script_dir => '/var/www/cgi-bin/heat', + :script_source_api => '/usr/bin/heat-wsgi-api', + :script_source_cfn => '/usr/bin/heat-wsgi-api-cfn', + :script_source_cloudwatch => '/usr/bin/heat-wsgi-api-cloudwatch', + } + end + end + it_configures 'apache serving a service with mod_wsgi' + end + end + +end