::server: serve neutron-api by Apache, with SSL support

Unlike Glance, according to
https://docs.openstack.org/neutron/wallaby/admin/config-wsgi.html
it is very much okay to run neutron-api that way - and it makes
configuring TLS simpler than in standalone UWSGI mode.

Ported from our internal, Rocky-based implementation. First iteration,
no tests yet.

Signed-off-by: Marek Szuba <m.szuba@gsi.de>
Change-Id: I40b5152c944bc00c3e1821de04cb5fb611965b8a
This commit is contained in:
Marek Szuba 2021-08-31 17:51:46 +01:00
parent 222df62ab3
commit 08d945969f
No known key found for this signature in database
GPG Key ID: 28C43B28551E3201
5 changed files with 113 additions and 12 deletions

View File

@ -33,6 +33,16 @@ end
default['openstack']['bind_service']['all']['network']['host'] = '127.0.0.1'
default['openstack']['bind_service']['all']['network']['port'] = 9696
# Neutron API WSGI app SSL settings
default['openstack']['block-storage']['ssl']['enabled'] = false
default['openstack']['block-storage']['ssl']['certfile'] = ''
default['openstack']['block-storage']['ssl']['chainfile'] = ''
default['openstack']['block-storage']['ssl']['keyfile'] = ''
default['openstack']['block-storage']['ssl']['ca_certs_path'] = ''
default['openstack']['block-storage']['ssl']['cert_required'] = false
default['openstack']['block-storage']['ssl']['protocol'] = ''
default['openstack']['block-storage']['ssl']['ciphers'] = ''
# trigger the usage of syslog (will include the proper recipe to create a log
# config)
default['openstack']['network']['syslog']['use'] = false
@ -165,7 +175,7 @@ default['openstack']['network']['platform'].tap do |platform|
platform['neutron_linuxbridge_agent_service'] = 'neutron-linuxbridge-agent'
platform['neutron_metadata_agent_packages'] = []
platform['neutron_metering_agent_packages'] = %w(openstack-neutron-metering-agent)
platform['neutron_server_packages'] = []
platform['neutron_server_packages'] = %w(mod_wsgi)
platform['neutron_openvswitch_service'] = 'openvswitch'
platform['neutron_openvswitch_agent_service'] = 'neutron-openvswitch-agent'
platform['package_overrides'] = ''
@ -199,7 +209,7 @@ default['openstack']['network']['platform'].tap do |platform|
platform['neutron_linuxbridge_agent_service'] = 'neutron-linuxbridge-agent'
platform['neutron_metadata_agent_packages'] = %w(neutron-metadata-agent)
platform['neutron_metering_agent_packages'] = %w(neutron-metering-agent)
platform['neutron_server_packages'] = %w(neutron-server)
platform['neutron_server_packages'] = %w(libapache2-mod-wsgi-py3 neutron-server)
platform['neutron_openvswitch_service'] = 'openvswitch-switch'
platform['neutron_openvswitch_agent_service'] = 'neutron-openvswitch-agent'
platform['package_overrides'] = ''

View File

@ -9,6 +9,7 @@ version '20.0.0'
supports os
end
depends 'apache2', '~> 8.1'
depends 'openstackclient'
depends 'openstack-common', '>= 20.0.0'
depends 'openstack-identity', '>= 20.0.0'

View File

@ -96,6 +96,22 @@ end
# merge all config options and secrets to be used in the neutron.conf.erb
neutron_conf_options = merge_config_options 'network'
plugin_templates = []
node['openstack']['network']['plugins'].each_value.to_s do |plugin|
plugin_templates << "template[#{File.join(plugin['path'], plugin['filename'])}]"
end
# service['apache2'] is defined in the apache2_default_install resource
# but other resources are currently unable to reference it. To work
# around this issue, define the following helper in your cookbook:
service 'apache2' do
extend Apache2::Cookbook::Helpers
service_name lazy { apache_platform_service_name }
supports restart: true, status: true, reload: true
action :nothing
subscribes :restart, plugin_templates
end
template '/etc/neutron/neutron.conf' do
source 'openstack-service.conf.erb'
cookbook 'openstack-common'
@ -106,6 +122,7 @@ template '/etc/neutron/neutron.conf' do
variables(
service_config: neutron_conf_options
)
notifies :restart, 'service[apache2]'
end
# delete all secrets saved in the attribute

View File

@ -56,25 +56,62 @@ if node['openstack']['network']['policyfile_url']
owner node['openstack']['network']['platform']['user']
group node['openstack']['network']['platform']['group']
mode '644'
notifies :restart, 'service[apache2]'
end
end
# Migrate network database to latest version
include_recipe 'openstack-network::db_migration'
plugin_templates = []
node['openstack']['network']['plugins'].each_value.to_s do |plugin|
plugin_templates << "template[#{File.join(plugin['path'], plugin['filename'])}]"
end
# This must not run if neutron-api is to be provided via Apache - the point
# of having both active aside, they bind to the same port.
service 'neutron-server' do
service_name platform_options['neutron_server_service']
supports status: true, restart: true
action [:disable, :stop]
end
# When Neutron API is served by a Web server it is difficult for it to start
# an RPC listener thread, therefore start the RPC server as a separate service.
service 'neutron-rpc-server' do
service_name platform_options['neutron_rpc_server_service']
action [:enable, :start]
subscribes :restart, [
plugin_templates,
'template[/etc/neutron/neutron.conf]',
'remote_file[/etc/neutron/policy.json]',
].flatten
subscribes :restart, 'template[/etc/neutron/neutron.conf]'
end
# Finds and appends the listen port to the apache2_install[openstack]
# resource which is defined in openstack-identity::server-apache.
apache_resource = find_resource(:apache2_install, 'openstack')
bind_service = node['openstack']['bind_service']['all']['network']
if apache_resource
apache_resource.listen = [apache_resource.listen, "#{bind_service['host']}:#{bind_service['port']}"].flatten
else
apache2_install 'openstack' do
listen "#{bind_service['host']}:#{bind_service['port']}"
end
end
apache2_module 'wsgi'
apache2_module 'ssl' if node['openstack']['network']['ssl']['enabled']
template "#{apache_dir}/sites-available/neutron-api.conf" do
extend Apache2::Cookbook::Helpers
source 'wsgi-template.conf.erb'
variables(
daemon_process: 'neutron-api',
server_host: bind_service['host'],
server_port: bind_service['port'],
server_entry: '/usr/bin/neutron-api',
log_dir: default_log_dir,
run_dir: lock_dir,
user: node['openstack']['network']['platform']['user'],
group: node['openstack']['network']['platform']['group']
)
notifies :restart, 'service[apache2]'
end
apache2_site 'neutron-api' do
notifies :restart, 'service[apache2]', :immediately
end
include_recipe 'openstack-network::identity_registration'

View File

@ -0,0 +1,36 @@
<%= node["openstack"]["network"]["custom_template_banner"] %>
<VirtualHost <%= @server_host %>:<%= @server_port %>>
WSGIDaemonProcess <%= @daemon_process %> processes=2 threads=10 user=<%= @user %> group=<%= @group %> display-name=%{GROUP}
WSGIProcessGroup <%= @daemon_process %>
WSGIScriptAlias / <%= @server_entry %>
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
<Directory /usr/bin>
Require all granted
</Directory>
ErrorLogFormat "%{cu}t %M"
ErrorLog <%= @log_dir %>/<%= @daemon_process %>_error.log
CustomLog <%= @log_dir %>/<%= @daemon_process %>_access.log combined
<% if node['openstack']['network']['ssl']['enabled'] -%>
SSLEngine On
SSLCertificateFile <%= node['openstack']['network']['ssl']['certfile'] %>
SSLCertificateKeyFile <%= node['openstack']['network']['ssl']['keyfile'] %>
SSLCACertificatePath <%= node['openstack']['network']['ssl']['ca_certs_path'] %>
<% unless node['openstack']['network']['ssl']['chainfile'].empty? %>
SSLCertificateChainFile <%= node['openstack']['network']['ssl']['chainfile'] %>
<% end -%>
SSLProtocol <%= node['openstack']['network']['ssl']['protocol'] %>
<% unless node['openstack']['network']['ssl']['ciphers'].empty? -%>
SSLCipherSuite <%= node['openstack']['network']['ssl']['ciphers'] %>
<% end -%>
<% if node['openstack']['network']['ssl']['cert_required'] -%>
SSLVerifyClient require
<% end -%>
<% end -%>
</VirtualHost>
WSGISocketPrefix <%= @run_dir -%>