diff --git a/manifests/api.pp b/manifests/api.pp index 46183573..576f2fe2 100644 --- a/manifests/api.pp +++ b/manifests/api.pp @@ -89,6 +89,13 @@ # HTTPProxyToWSGI middleware. # Defaults to $::os_service_default. # +# [*service_name*] +# (Optional) Name of the service that will be providing the server +# functionality of the designate API. If the value is 'httpd', +# designate will be run as web service and configuration of the +# web server will be required (e.g designate::wsgi::apache) +# Defaults to $::designate::params::api_service_name +# class designate::api ( $package_ensure = present, $api_package_name = $::designate::params::api_package_name, @@ -111,6 +118,7 @@ class designate::api ( $enabled_extensions_v2 = $::os_service_default, $enabled_extensions_admin = $::os_service_default, $enable_proxy_headers_parsing = $::os_service_default, + $service_name = $::designate::params::api_service_name, ) inherits designate { include designate::deps @@ -143,11 +151,29 @@ class designate::api ( enable_proxy_headers_parsing => $enable_proxy_headers_parsing } + if $manage_service { + if $service_name == 'httpd' { + service { 'designate-api': + ensure => 'stopped', + name => $::barbican::params::api_service_name, + enable => false, + tag => ['designate-service'], + } + Service['designate-api'] -> Service[$service_name] + $service_name_real = false + Service <| title == 'httpd' |> { tag +> 'designate-service' } + } else { + $service_name_real = $service_name + } + } else { + $service_name_real = $service_name + } + designate::generic_service { 'api': enabled => $enabled, manage_service => $manage_service, package_ensure => $package_ensure, package_name => $api_package_name, - service_name => $::designate::params::api_service_name, + service_name => $service_name_real, } } diff --git a/manifests/params.pp b/manifests/params.pp index c26a7d70..f2a2585b 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -21,27 +21,31 @@ class designate::params { case $::osfamily { 'RedHat': { # package name - $common_package_name = 'openstack-designate-common' - $api_package_name = 'openstack-designate-api' - $central_package_name = 'openstack-designate-central' - $agent_package_name = 'openstack-designate-agent' - $sink_package_name = 'openstack-designate-sink' - $mdns_package_name = 'openstack-designate-mdns' - $zone_manager_package_name = 'openstack-designate-zone-manager' - $producer_package_name = 'openstack-designate-producer' - $worker_package_name = 'openstack-designate-worker' + $common_package_name = 'openstack-designate-common' + $api_package_name = 'openstack-designate-api' + $central_package_name = 'openstack-designate-central' + $agent_package_name = 'openstack-designate-agent' + $sink_package_name = 'openstack-designate-sink' + $mdns_package_name = 'openstack-designate-mdns' + $zone_manager_package_name = 'openstack-designate-zone-manager' + $producer_package_name = 'openstack-designate-producer' + $worker_package_name = 'openstack-designate-worker' + $designate_wsgi_script_path = '/var/www/cgi-bin/designate' + $designate_wsgi_script_source = '/usr/bin/designate-api-wsgi' } 'Debian': { # package name - $common_package_name = 'designate-common' - $api_package_name = 'designate-api' - $central_package_name = 'designate-central' - $agent_package_name = 'designate-agent' - $sink_package_name = 'designate-sink' - $mdns_package_name = 'designate-mdns' - $zone_manager_package_name = 'designate-zone-manager' - $producer_package_name = 'designate-producer' - $worker_package_name = 'designate-worker' + $common_package_name = 'designate-common' + $api_package_name = 'designate-api' + $central_package_name = 'designate-central' + $agent_package_name = 'designate-agent' + $sink_package_name = 'designate-sink' + $mdns_package_name = 'designate-mdns' + $zone_manager_package_name = 'designate-zone-manager' + $producer_package_name = 'designate-producer' + $worker_package_name = 'designate-worker' + $designate_wsgi_script_path = '/usr/lib/cgi-bin/designate' + $designate_wsgi_script_source = '/usr/bin/designate-api-wsgi' } default: { fail("Unsupported osfamily: ${::osfamily} operatingsystem") diff --git a/manifests/wsgi/apache.pp b/manifests/wsgi/apache.pp new file mode 100644 index 00000000..4ba3a07d --- /dev/null +++ b/manifests/wsgi/apache.pp @@ -0,0 +1,160 @@ +# +# Copyright (C) 2021 Red Hat Inc +# +# 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. +# +# == Class: designate::wsgi::apache +# +# Install Designate API under apache with mod_wsgi. +# +# == Parameters: +# +# [*servername*] +# (Optional) The servername for the virtualhost. +# Defaults to $::fqdn +# +# [*port*] +# (Optional) The port. +# Defaults to 9001 +# +# [*bind_host*] +# (Optional) The host/ip address Apache will listen on. +# Defaults to undef (listen on all ip addresses). +# +# [*path*] +# (Optional) The prefix for the endpoint. +# Defaults to '/' +# +# [*ssl*] +# (Optional) Use ssl. +# Defaults to false +# +# [*workers*] +# (Optional) Number of WSGI workers to spawn. +# Defaults to $::os_workers +# +# [*priority*] +# (Optional) The priority for the vhost. +# Defaults to '10' +# +# [*threads*] +# (Optional) The number of threads for the vhost. +# Defaults to 1 +# +# [*wsgi_process_display_name*] +# (Optional) Name of the WSGI process display-name. +# Defaults to undef +# +# [*ssl_cert*] +# [*ssl_key*] +# [*ssl_chain*] +# [*ssl_ca*] +# [*ssl_crl_path*] +# [*ssl_crl*] +# [*ssl_certs_dir*] +# (Optional) apache::vhost ssl parameters. +# Default to apache::vhost 'ssl_*' defaults +# +# [*access_log_file*] +# (Optional) The log file name for the virtualhost. +# Defaults to false +# +# [*access_log_format*] +# (Optional) The log format for the virtualhost. +# Defaults to false +# +# [*error_log_file*] +# (Optional) The error log file name for the virtualhost. +# Defaults to undef +# +# [*custom_wsgi_process_options*] +# (Optional) gives you the opportunity to add custom process options or to +# overwrite the default options for the WSGI main process. +# eg. to use a virtual python environment for the WSGI process +# you could set it to: +# { python-path => '/my/python/virtualenv' } +# Defaults to {} +# +# [*vhost_custom_fragment*] +# (optional) Passes a string of custom configuration +# directives to be placed at the end of the vhost configuration. +# Defaults to undef. +# +# == Example: +# +# include apache +# class { 'designate::wsgi::apache': } +# +class designate::wsgi::apache ( + $servername = $::fqdn, + $port = 9001, + $bind_host = undef, + $path = '/', + $ssl = false, + $workers = $::os_workers, + $ssl_cert = undef, + $ssl_key = undef, + $ssl_chain = undef, + $ssl_ca = undef, + $ssl_crl_path = undef, + $ssl_crl = undef, + $ssl_certs_dir = undef, + $wsgi_process_display_name = undef, + $threads = 1, + $priority = '10', + $access_log_file = false, + $access_log_format = false, + $error_log_file = undef, + $custom_wsgi_process_options = {}, + $vhost_custom_fragment = undef, +) { + + include designate::deps + include designate::params + include apache + include apache::mod::wsgi + if $ssl { + include apache::mod::ssl + } + ::openstacklib::wsgi::apache { 'designate_wsgi': + bind_host => $bind_host, + bind_port => $port, + group => 'designate', + 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 => 'designate', + vhost_custom_fragment => $vhost_custom_fragment, + workers => $workers, + wsgi_daemon_process => 'designate', + wsgi_process_display_name => $wsgi_process_display_name, + wsgi_process_group => 'designate', + wsgi_script_dir => $::designate::params::designate_wsgi_script_path, + wsgi_script_file => 'app', + wsgi_script_source => $::designate::params::designate_wsgi_script_source, + access_log_file => $access_log_file, + access_log_format => $access_log_format, + error_log_file => $error_log_file, + custom_wsgi_process_options => $custom_wsgi_process_options, + require => Anchor['designate::install::end'], + } +} diff --git a/releasenotes/notes/designate-api-wsgi-b7a408ecc00f3001.yaml b/releasenotes/notes/designate-api-wsgi-b7a408ecc00f3001.yaml new file mode 100644 index 00000000..b8d94607 --- /dev/null +++ b/releasenotes/notes/designate-api-wsgi-b7a408ecc00f3001.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Added the new ``designate::wsgi::apache`` class, you can now run + the ``designate-api`` service under Apache with mod_wsgi. diff --git a/spec/classes/designate_api_spec.rb b/spec/classes/designate_api_spec.rb index 6aaab9ca..4e6c77c5 100644 --- a/spec/classes/designate_api_spec.rb +++ b/spec/classes/designate_api_spec.rb @@ -130,6 +130,39 @@ describe 'designate::api' do end end + shared_examples 'designate-api wsgi' do + let :pre_condition do + "class { 'designate': } + include ::designate::db + class { '::designate::keystone::authtoken': + password => 'password', + } + include ::apache + " + end + + let :params do + { + :service_name => 'httpd', + } + end + + context 'with required params' do + it { should contain_package('designate-api').with( + :ensure => 'present', + :name => platform_params[:api_package_name], + :tag => ['openstack', 'designate-package'], + )} + + it { should contain_service('designate-api').with( + :ensure => 'stopped', + :name => platform_params[:api_service_name], + :enable => false, + :tag => ['designate-service'] + )} + end + end + on_supported_os({ :supported_os => OSDefaults.get_supported_os }).each do |os,facts| @@ -153,6 +186,7 @@ describe 'designate::api' do end end it_behaves_like 'designate-api' + it_behaves_like 'designate-api wsgi' end end end diff --git a/spec/classes/designate_wsgi_apache_spec.rb b/spec/classes/designate_wsgi_apache_spec.rb new file mode 100644 index 00000000..2ef58044 --- /dev/null +++ b/spec/classes/designate_wsgi_apache_spec.rb @@ -0,0 +1,115 @@ +require 'spec_helper' + +describe 'designate::wsgi::apache' do + + shared_examples_for 'apache serving designate with mod_wsgi' do + context 'with default parameters' do + it { is_expected.to contain_class('designate::params') } + it { is_expected.to contain_class('apache') } + it { is_expected.to contain_class('apache::mod::wsgi') } + it { is_expected.to_not contain_class('apache::mod::ssl') } + it { is_expected.to contain_openstacklib__wsgi__apache('designate_wsgi').with( + :bind_port => 9001, + :group => 'designate', + :path => '/', + :servername => facts[:fqdn], + :ssl => false, + :threads => 1, + :user => 'designate', + :workers => facts[:os_workers], + :wsgi_daemon_process => 'designate', + :wsgi_process_group => 'designate', + :wsgi_script_dir => platform_params[:wsgi_script_path], + :wsgi_script_file => 'app', + :wsgi_script_source => platform_params[:wsgi_script_source], + :custom_wsgi_process_options => {}, + :access_log_file => false, + :access_log_format => false, + )} + end + + context 'when overriding parameters using different ports' do + let :params do + { + :servername => 'dummy.host', + :bind_host => '10.42.51.1', + :port => 12345, + :ssl => true, + :wsgi_process_display_name => 'designate', + :workers => 37, + :custom_wsgi_process_options => { + 'python_path' => '/my/python/path', + }, + :access_log_file => '/var/log/httpd/access_log', + :access_log_format => 'some format', + :error_log_file => '/var/log/httpd/error_log', + :vhost_custom_fragment => 'Timeout 99' + } + end + it { is_expected.to contain_class('designate::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') } + it { is_expected.to contain_openstacklib__wsgi__apache('designate_wsgi').with( + :bind_host => '10.42.51.1', + :bind_port => 12345, + :group => 'designate', + :path => '/', + :servername => 'dummy.host', + :ssl => true, + :threads => 1, + :user => 'designate', + :workers => 37, + :vhost_custom_fragment => 'Timeout 99', + :wsgi_daemon_process => 'designate', + :wsgi_process_display_name => 'designate', + :wsgi_process_group => 'designate', + :wsgi_script_dir => platform_params[:wsgi_script_path], + :wsgi_script_file => 'app', + :wsgi_script_source => platform_params[:wsgi_script_source], + :custom_wsgi_process_options => { + 'python_path' => '/my/python/path', + }, + :access_log_file => '/var/log/httpd/access_log', + :access_log_format => 'some format', + :error_log_file => '/var/log/httpd/error_log' + )} + 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({ + :os_workers => 8, + :concat_basedir => '/var/lib/puppet/concat', + :fqdn => 'some.host.tld' + })) + end + + let(:platform_params) do + case facts[:osfamily] + when 'Debian' + { + :httpd_service_name => 'apache2', + :httpd_ports_file => '/etc/apache2/ports.conf', + :wsgi_script_path => '/usr/lib/cgi-bin/designate', + :wsgi_script_source => '/usr/bin/designate-api-wsgi' + } + when 'RedHat' + { + :httpd_service_name => 'httpd', + :httpd_ports_file => '/etc/httpd/conf/ports.conf', + :wsgi_script_path => '/var/www/cgi-bin/designate', + :wsgi_script_source => '/usr/bin/designate-api-wsgi' + } + + end + end + it_configures 'apache serving designate with mod_wsgi' + end + end + +end