From 28d5e53fd73daf8951d7bc4600de15ad415baf5d Mon Sep 17 00:00:00 2001 From: Samuel Cassiba Date: Tue, 4 Sep 2018 09:26:41 -0700 Subject: [PATCH] Refactor ironic cookbook * added endpoint attributes * moved version to 18.0.0 for Rocky release * refactored attributes to fit the template logic * moved attributes for ironic.conf to attributes/ironic_conf.rb * adapted identity registration for the client library cookbook Depends-On: https://review.openstack.org/599860 Change-Id: Idd4b3ecbc9f0a91f12450aad8ff679665dd18cce --- .delivery/project.toml | 1 + .gitignore | 9 ++ .zuul.yaml | 3 + Berksfile | 14 ++ LICENSE | 176 +++++++++++++++++++++++ attributes/conductor_conf.rb | 2 + attributes/default.rb | 146 +++++++++++++++++++ attributes/ironic_conf.rb | 20 +++ metadata.rb | 25 ++++ recipes/api.rb | 81 +++++++++++ recipes/conductor.rb | 45 ++++++ recipes/default.rb | 1 + recipes/identity_registration.rb | 86 +++++++++++ recipes/ironic-common.rb | 99 +++++++++++++ spec/api_spec.rb | 55 +++++++ spec/conductor_spec.rb | 65 +++++++++ spec/identity_registration_spec.rb | 48 +++++++ spec/ironic-common_spec.rb | 110 ++++++++++++++ spec/spec_helper.rb | 169 ++++++++++++++++++++++ templates/default/ironic.conf.erb | 12 ++ templates/default/rootwrap.conf.erb | 29 ++++ templates/default/wsgi-template.conf.erb | 42 ++++++ 22 files changed, 1238 insertions(+) create mode 100644 .delivery/project.toml create mode 100644 .gitignore create mode 100644 .zuul.yaml create mode 100644 Berksfile create mode 100644 LICENSE create mode 100644 attributes/conductor_conf.rb create mode 100644 attributes/default.rb create mode 100644 attributes/ironic_conf.rb create mode 100644 metadata.rb create mode 100644 recipes/api.rb create mode 100644 recipes/conductor.rb create mode 100644 recipes/default.rb create mode 100644 recipes/identity_registration.rb create mode 100644 recipes/ironic-common.rb create mode 100644 spec/api_spec.rb create mode 100644 spec/conductor_spec.rb create mode 100644 spec/identity_registration_spec.rb create mode 100644 spec/ironic-common_spec.rb create mode 100644 spec/spec_helper.rb create mode 100644 templates/default/ironic.conf.erb create mode 100644 templates/default/rootwrap.conf.erb create mode 100644 templates/default/wsgi-template.conf.erb diff --git a/.delivery/project.toml b/.delivery/project.toml new file mode 100644 index 0000000..6d5e361 --- /dev/null +++ b/.delivery/project.toml @@ -0,0 +1 @@ +remote_file = "https://raw.githubusercontent.com/chef-cookbooks/community_cookbook_tools/master/delivery/project.toml" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1ac6115 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.bundle/ +berks-cookbooks/ +.kitchen/ +.vagrant/ +.coverage/ +*.swp +Berksfile.lock +Vagrantfile +Gemfile.lock diff --git a/.zuul.yaml b/.zuul.yaml new file mode 100644 index 0000000..f578684 --- /dev/null +++ b/.zuul.yaml @@ -0,0 +1,3 @@ +- project: + templates: + - openstack-chef-jobs diff --git a/Berksfile b/Berksfile new file mode 100644 index 0000000..6cca20b --- /dev/null +++ b/Berksfile @@ -0,0 +1,14 @@ +source 'https://supermarket.chef.io' + +%w(common identity image network).each do |cookbook| + if Dir.exist?("../cookbook-openstack-#{cookbook}") + cookbook "openstack-#{cookbook}", path: "../cookbook-openstack-#{cookbook}" + else + cookbook "openstack-#{cookbook}", git: "https://git.openstack.org/openstack/cookbook-openstack-#{cookbook}" + end +end + +cookbook 'openstackclient', + git: 'https://git.openstack.org/openstack/cookbook-openstackclient' + +metadata diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..68c771a --- /dev/null +++ b/LICENSE @@ -0,0 +1,176 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + diff --git a/attributes/conductor_conf.rb b/attributes/conductor_conf.rb new file mode 100644 index 0000000..276fee4 --- /dev/null +++ b/attributes/conductor_conf.rb @@ -0,0 +1,2 @@ +default['openstack']['baremetal']['conductor']['periodic_max_workers'] = 8 +default['openstack']['baremetal']['conductor']['workers_pool_size'] = 100 diff --git a/attributes/default.rb b/attributes/default.rb new file mode 100644 index 0000000..2001710 --- /dev/null +++ b/attributes/default.rb @@ -0,0 +1,146 @@ +# encoding: UTF-8 +# +# Cookbook Name:: openstack-bare-metal +# Attributes:: default +# +# Copyright 2015, IBM, Corp +# +# 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. +# + +# Set to some text value if you want templated config files +# to contain a custom banner at the top of the written file +default['openstack']['baremetal']['custom_template_banner'] = " +# This file is managed by Chef +# Do not edit, changes will be overwritten +" + +%w(admin internal public).each do |ep_type| + # host for openstack admin/internal/public bare metal endpoint + default['openstack']['endpoints'][ep_type]['baremetal']['host'] = '127.0.0.1' + # scheme for openstack admin/internal/public bare metal endpoint + default['openstack']['endpoints'][ep_type]['baremetal']['scheme'] = 'http' + # port for openstack admin/internal/public bare metal endpoint + default['openstack']['endpoints'][ep_type]['baremetal']['port'] = 6385 + # path for openstack admin/internal/public bare metal endpoint + default['openstack']['endpoints'][ep_type]['baremetal']['path'] = '' +end + +default['openstack']['baremetal']['verbose'] = 'false' +default['openstack']['baremetal']['debug'] = 'false' + +# Maximum number of worker threads that can be started +# simultaneously by a periodic task. Should be less than RPC +# thread pool size. (integer value) +default['openstack']['baremetal']['conductor']['periodic_max_workers'] = 8 + +# The size of the workers greenthread pool. (integer value) +default['openstack']['baremetal']['conductor']['workers_pool_size'] = 100 + +# Common rpc definitions +default['openstack']['baremetal']['rpc_thread_pool_size'] = 64 +default['openstack']['baremetal']['rpc_conn_pool_size'] = 30 +default['openstack']['baremetal']['rpc_response_timeout'] = 60 + +# The name of the Chef role that knows about the message queue server +# that Ironic uses +default['openstack']['baremetal']['rabbit_server_chef_role'] = 'os-ops-messaging' + +default['openstack']['baremetal']['rpc_backend'] = 'rabbit' + +# Logging stuff +default['openstack']['baremetal']['log_dir'] = '/var/log/ironic' + +default['openstack']['baremetal']['syslog']['use'] = false +default['openstack']['baremetal']['syslog']['facility'] = 'LOG_LOCAL1' +default['openstack']['baremetal']['syslog']['config_facility'] = 'local1' + +default['openstack']['baremetal']['region'] = node['openstack']['region'] + +# Keystone settings +default['openstack']['baremetal']['api']['auth_strategy'] = 'keystone' + +default['openstack']['baremetal']['api']['auth']['version'] = node['openstack']['api']['auth']['version'] + +# Whether to allow the client to perform insecure SSL (https) requests +default['openstack']['baremetal']['api']['auth']['insecure'] = false + +default['openstack']['baremetal']['service_user'] = 'ironic' +default['openstack']['baremetal']['project'] = 'service' +default['openstack']['baremetal']['service_role'] = 'service' +default['openstack']['baremetal']['service_name'] = 'ironic' +default['openstack']['baremetal']['service_type'] = 'baremetal' + +default['openstack']['baremetal']['user'] = 'ironic' +default['openstack']['baremetal']['group'] = 'ironic' + +# Setup the tftp variables +default['openstack']['baremetal']['tftp']['enabled'] = false +# IP address of Ironic compute node's tftp server +default['openstack']['baremetal']['tftp']['server'] = '127.0.0.1' +# Ironic compute node's tftp root path +default['openstack']['baremetal']['tftp']['root_path'] = '/var/lib/tftpboot' +# Directory where master tftp images are stored on disk +default['openstack']['baremetal']['tftp']['master_path'] = "#{node['openstack']['baremetal']['tftp']['root_path']}/master_images" + +# Ironic WSGI app SSL settings +default['openstack']['baremetal']['ssl']['enabled'] = false +default['openstack']['baremetal']['ssl']['certfile'] = '' +default['openstack']['baremetal']['ssl']['chainfile'] = '' +default['openstack']['baremetal']['ssl']['keyfile'] = '' +default['openstack']['baremetal']['ssl']['ca_certs_path'] = '' +default['openstack']['baremetal']['ssl']['cert_required'] = false +default['openstack']['baremetal']['ssl']['protocol'] = '' +default['openstack']['baremetal']['ssl']['ciphers'] = '' + +case node['platform_family'] +when 'fedora', 'rhel' + default['openstack']['baremetal']['platform'] = { + 'ironic_api_packages' => ['openstack-ironic-api'], + 'ironic_api_service' => 'openstack-ironic-api', + 'ironic_conductor_packages' => ['openstack-ironic-conductor', 'ipmitool'], + 'ironic_conductor_service' => 'openstack-ironic-conductor', + 'ironic_common_packages' => ['openstack-ironic-common', 'python-ironicclient'], + } +when 'debian' + default['openstack']['baremetal']['platform'] = { + 'ironic_api_packages' => ['ironic-api'], + 'ironic_api_service' => 'ironic-api', + 'ironic_conductor_packages' => ['ironic-conductor', 'ipmitool'], + 'ironic_conductor_service' => 'ironic-conductor', + 'ironic_common_packages' => ['python-ironicclient', 'ironic-common'], + } +end + +# ******************** OpenStack Bare Metal Endpoints ***************************** + +# The OpenStack Bare Metal (Ironic) API endpoint +%w(public internal admin).each do |ep_type| + default['openstack']['endpoints'][ep_type]['baremetal']['scheme'] = 'http' + default['openstack']['endpoints'][ep_type]['baremetal']['path'] = '' + default['openstack']['endpoints'][ep_type]['baremetal']['host'] = '127.0.0.1' + default['openstack']['endpoints'][ep_type]['baremetal']['port'] = '6385' +end +default['openstack']['bind_service']['all']['baremetal']['host'] = '127.0.0.1' +default['openstack']['bind_service']['all']['baremetal']['port'] = '6385' +# ============================= rootwrap Configuration =================== +# use ironic root wrap +default['openstack']['baremetal']['use_rootwrap'] = true +# rootwrap.conf +default['openstack']['baremetal']['rootwrap']['conf'].tap do |conf| + conf['DEFAULT']['filters_path'] = '/etc/ironic/rootwrap.d,/usr/share/ironic/rootwrap' + conf['DEFAULT']['exec_dirs'] = '/sbin,/usr/sbin,/bin,/usr/bin' + conf['DEFAULT']['use_syslog'] = false + conf['DEFAULT']['syslog_log_facility'] = 'syslog' + conf['DEFAULT']['syslog_log_level'] = 'ERROR' +end diff --git a/attributes/ironic_conf.rb b/attributes/ironic_conf.rb new file mode 100644 index 0000000..b26e719 --- /dev/null +++ b/attributes/ironic_conf.rb @@ -0,0 +1,20 @@ +default['openstack']['baremetal']['conf_secrets'] = {} + +default['openstack']['baremetal']['conf'].tap do |conf| + if node['openstack']['baremetal']['syslog']['use'] + conf['DEFAULT']['log_config'] = '/etc/openstack/logging.conf' + end + conf['DEFAULT']['auth_strategy'] = 'keystone' + conf['DEFAULT']['control_exchange'] = 'ironic' + conf['DEFAULT']['glance_api_version'] = '2' + conf['DEFAULT']['state_path'] = '/var/lib/ironic' + + conf['keystone_authtoken']['auth_type'] = 'password' + conf['keystone_authtoken']['region_name'] = node['openstack']['region'] + conf['keystone_authtoken']['username'] = 'ironic' + conf['keystone_authtoken']['project_name'] = 'service' + conf['keystone_authtoken']['user_domain_name'] = 'Default' + conf['keystone_authtoken']['project_domain_name'] = 'Default' + + conf['oslo_concurrency']['lock_path'] = '/var/lib/cinder/tmp' +end diff --git a/metadata.rb b/metadata.rb new file mode 100644 index 0000000..92bf9a0 --- /dev/null +++ b/metadata.rb @@ -0,0 +1,25 @@ +name 'openstack-bare-metal' +maintainer 'openstack-chef' +maintainer_email 'openstack-dev@lists.openstack.org' +license 'Apache-2.0' +description 'Installs/Configures OpenStack Bare Metal service Ironic' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '18.0.0' +issues_url 'https://launchpad.net/openstack-chef' if respond_to?(:issues_url) +source_url 'https://github.com/openstack/cookbook-openstack-bare-metal' if respond_to?(:source_url) +chef_version '>= 12.5' if respond_to?(:chef_version) + +recipe 'openstack-bare-metal::api', 'Installs the ironic-api, sets up the ironic database' +recipe 'openstack-bare-metal::conductor', 'Installs the ironic-conductor service' +recipe 'openstack-bare-metal::default', 'Temp workaround to create ironic db with user' +recipe 'openstack-bare-metal::identity_registration', 'Registers ironic service/user/endpoints in keystone' +recipe 'openstack-bare-metal::ironic-common', 'Defines the common pieces of repeated code from the other recipes' + +%w(ubuntu redhat centos).each do |os| + supports os +end + +depends 'openstack-common', '>= 18.0.0' +depends 'openstack-identity', '>= 18.0.0' +depends 'openstack-image', '>= 18.0.0' +depends 'openstack-network', '>= 18.0.0' diff --git a/recipes/api.rb b/recipes/api.rb new file mode 100644 index 0000000..90b30a9 --- /dev/null +++ b/recipes/api.rb @@ -0,0 +1,81 @@ +# Encoding: utf-8 +# +# Cookbook Name:: openstack-bare-metal +# Recipe:: api +# +# Copyright 2015, IBM Corp. +# +# 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 ::Chef::Recipe + include ::Openstack +end + +include_recipe 'openstack-bare-metal::ironic-common' + +platform_options = node['openstack']['baremetal']['platform'] + +platform_options['ironic_api_packages'].each do |pkg| + package pkg do + action :upgrade + + notifies :restart, 'service[ironic-api]', :delayed + end +end + +directory '/var/cache/ironic' do + owner node['openstack']['baremetal']['user'] + group node['openstack']['baremetal']['group'] + mode 00700 + action :create +end + +service 'ironic-api' do + service_name platform_options['ironic_api_service'] + action [:disable, :stop] +end + +execute 'ironic db sync' do + command 'ironic-dbsync --config-file /etc/ironic/ironic.conf upgrade' + user 'root' + group 'root' + action :run +end + +# remove the ironic-wsgi.conf automatically generated from package +apache_config 'ironic-wsgi' do + enable false +end + +bind_service = node['openstack']['bind_service']['all']['baremetal'] + +web_app 'ironic-api' do + template 'wsgi-template.conf.erb' + daemon_process 'ironic-wsgi' + server_host bind_service['host'] + server_port bind_service['port'] + server_entry '/usr/bin/ironic-api-wsgi' + log_dir node['apache']['log_dir'] + run_dir node['apache']['run_dir'] + user node['openstack']['baremetal']['user'] + group node['openstack']['baremetal']['group'] + use_ssl node['openstack']['baremetal']['ssl']['enabled'] + cert_file node['openstack']['baremetal']['ssl']['certfile'] + chain_file node['openstack']['baremetal']['ssl']['chainfile'] + key_file node['openstack']['baremetal']['ssl']['keyfile'] + ca_certs_path node['openstack']['baremetal']['ssl']['ca_certs_path'] + cert_required node['openstack']['baremetal']['ssl']['cert_required'] + protocol node['openstack']['baremetal']['ssl']['protocol'] + ciphers node['openstack']['baremetal']['ssl']['ciphers'] +end diff --git a/recipes/conductor.rb b/recipes/conductor.rb new file mode 100644 index 0000000..901fc43 --- /dev/null +++ b/recipes/conductor.rb @@ -0,0 +1,45 @@ +# Encoding: utf-8 +# +# Cookbook Name:: openstack-bare-metal +# Recipe:: conductor +# +# Copyright 2015, IBM Corp. +# +# 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 ::Chef::Recipe + include ::Openstack +end + +include_recipe 'openstack-bare-metal::ironic-common' + +platform_options = node['openstack']['baremetal']['platform'] + +platform_options['ironic_conductor_packages'].each do |pkg| + package pkg do + action :upgrade + + notifies :restart, 'service[ironic-conductor]', :delayed + end +end + +service 'ironic-conductor' do + service_name platform_options['ironic_conductor_service'] + supports status: true, restart: true + action [:enable, :start] + subscribes :restart, 'template[/etc/ironic/ironic.conf]' + platform_options['ironic_common_packages'].each do |pkg| + subscribes :restart, "package[#{pkg}]", :delayed + end +end diff --git a/recipes/default.rb b/recipes/default.rb new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/recipes/default.rb @@ -0,0 +1 @@ + diff --git a/recipes/identity_registration.rb b/recipes/identity_registration.rb new file mode 100644 index 0000000..51c3db1 --- /dev/null +++ b/recipes/identity_registration.rb @@ -0,0 +1,86 @@ +# encoding: UTF-8 +# +# Cookbook Name:: openstack-bare-metal +# Recipe:: identity_registration +# +# Copyright 2015, IBM, 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. +# + +require 'uri' + +class ::Chef::Recipe + include ::Openstack +end + +identity_endpoint = internal_endpoint 'identity' +auth_url = ::URI.decode identity_endpoint.to_s + +interfaces = { + public: { url: public_endpoint('baremetal') }, + internal: { url: internal_endpoint('baremetal') }, + admin: { url: admin_endpoint('baremetal') }, +} +service_pass = get_password 'service', 'openstack-bare-metal' +region = node['openstack']['baremetal']['region'] +service_project_name = node['openstack']['baremetal']['conf']['keystone_authtoken']['project_name'] +service_user = node['openstack']['baremetal']['service_user'] +admin_user = node['openstack']['identity']['admin_user'] +admin_pass = get_password 'user', node['openstack']['identity']['admin_user'] +admin_project = node['openstack']['identity']['admin_project'] +admin_domain = node['openstack']['identity']['admin_domain_name'] +service_domain_name = node['openstack']['baremetal']['conf']['keystone_authtoken']['user_domain_name'] +service_role = node['openstack']['baremetal']['service_role'] +service_name = node['openstack']['baremetal']['service_name'] +service_type = node['openstack']['baremetal']['service_type'] + +connection_params = { + openstack_auth_url: "#{auth_url}/auth/tokens", + openstack_username: admin_user, + openstack_api_key: admin_pass, + openstack_project_name: admin_project, + openstack_domain_name: admin_domain, +} + +# Register Bare Metal Service +openstack_service service_name do + type service_type + connection_params connection_params +end + +interfaces.each do |interface, res| + # Register Bare Metal Endpoints + openstack_endpoint service_type do + service_name service_name + interface interface.to_s + url res[:url].to_s + region region + connection_params connection_params + end +end + +# Register Service Project +openstack_project service_project_name do + connection_params connection_params +end + +# Register Service User +openstack_user service_user do + project_name service_project_name + domain_name service_domain_name + role_name service_role + password service_pass + connection_params connection_params + action [:create, :grant_role] +end diff --git a/recipes/ironic-common.rb b/recipes/ironic-common.rb new file mode 100644 index 0000000..02dc9ab --- /dev/null +++ b/recipes/ironic-common.rb @@ -0,0 +1,99 @@ +# Encoding: utf-8 +# +# Cookbook Name:: openstack-bare-metal +# Recipe:: ironic-common +# +# Copyright 2015, IBM Corp. +# +# 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 ::Chef::Recipe + include ::Openstack +end + +if node['openstack']['baremetal']['syslog']['use'] + include_recipe 'openstack-common::logging' +end + +platform_options = node['openstack']['baremetal']['platform'] + +platform_options['ironic_common_packages'].each do |pkg| + package pkg do + action :upgrade + end +end + +db_type = node['openstack']['db']['baremetal']['service_type'] +node['openstack']['db']['python_packages'][db_type].each do |pkg| + package pkg do + action :upgrade + end +end + +db_user = node['openstack']['db']['baremetal']['username'] +db_pass = get_password 'db', 'ironic' + +node.default['openstack']['baremetal']['conf_secrets'] + .[]('database')['connection'] = + db_uri('baremetal', db_user, db_pass) +if node['openstack']['endpoints']['db']['enabled_slave'] + node.default['openstack']['baremetal']['conf_secrets'] + .[]('database')['slave_connection'] = + db_uri('baremetal', db_user, db_pass, true) +end + +if node['openstack']['mq']['service_type'] == 'rabbit' + node.default['openstack']['baremetal']['conf_secrets']['DEFAULT']['transport_url'] = rabbit_transport_url 'baremetal' +end + +# merge all config options and secrets to be used in ironic.conf +ironic_conf_options = merge_config_options 'baremetal' + +directory '/etc/ironic' do + owner node['openstack']['baremetal']['user'] + group node['openstack']['baremetal']['group'] + mode 00750 + action :create +end + +template '/etc/ironic/ironic.conf' do + source 'ironic.conf.erb' + owner node['openstack']['baremetal']['user'] + group node['openstack']['baremetal']['group'] + mode 00640 + variables( + service_config: ironic_conf_options + ) +end + +# delete all secrets saved in the attribute +# node['openstack']['baremetal']['conf_secrets'] after creating the config file +ruby_block "delete all attributes in node['openstack']['baremetal']['conf_secrets']" do + block do + node.rm(:openstack, :baremetal, :conf_secrets) + end +end + +if node['openstack']['baremetal']['use_rootwrap'] + template '/etc/ironic/rootwrap.conf' do + source 'openstack-service.conf.erb' + cookbook 'openstack-common' + owner 'root' + group 'root' + mode 0o0644 + variables( + service_config: node['openstack']['baremetal']['rootwrap']['conf'] + ) + end +end diff --git a/spec/api_spec.rb b/spec/api_spec.rb new file mode 100644 index 0000000..bb0d713 --- /dev/null +++ b/spec/api_spec.rb @@ -0,0 +1,55 @@ +# Encoding: utf-8 +# +# Cookbook Name:: openstack-bare-metal +# Spec:: api_spec +# +# Copyright 2015, IBM Corp. +# +# 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. +# + +require_relative 'spec_helper' + +describe 'openstack-bare-metal::api' do + describe 'ubuntu' do + let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } + let(:node) { runner.node } + let(:chef_run) { runner.converge(described_recipe) } + + include_context 'bare-metal-stubs' + + it 'includes ironic common recipe' do + expect(chef_run).to include_recipe('openstack-bare-metal::ironic-common') + end + + it 'upgrades ironic api packages' do + expect(chef_run).to upgrade_package('ironic-api') + end + + it 'should create the directory /var/cache/ironic' do + expect(chef_run).to create_directory('/var/cache/ironic').with( + user: 'ironic', + group: 'ironic', + mode: 00700 + ) + end + + it 'disables ironic api on boot' do + expect(chef_run).to disable_service('ironic-api') + end + + it 'runs db migrations' do + expect(chef_run).to run_execute('ironic db sync').with(user: 'root', group: 'root') + end + end +end diff --git a/spec/conductor_spec.rb b/spec/conductor_spec.rb new file mode 100644 index 0000000..f04f739 --- /dev/null +++ b/spec/conductor_spec.rb @@ -0,0 +1,65 @@ +# Encoding: utf-8 +# +# Cookbook Name:: openstack-bare-metal +# Spec:: conductor_spec +# +# Copyright 2015, IBM Corp. +# +# 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. +# + +require_relative 'spec_helper' + +describe 'openstack-bare-metal::conductor' do + describe 'ubuntu' do + let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } + let(:node) { runner.node } + let(:chef_run) { runner.converge(described_recipe) } + + include_context 'bare-metal-stubs' + + it 'includes ironic common recipe' do + expect(chef_run).to include_recipe('openstack-bare-metal::ironic-common') + end + + it 'upgrades ironic conductor packages' do + %w(ironic-conductor ipmitool).each do |pkg| + expect(chef_run).to upgrade_package(pkg) + end + end + + describe 'ironic-conductor packages' do + let(:package) { chef_run.package('ironic-conductor') } + + it 'sends a notification to the service' do + expect(package).to notify('service[ironic-conductor]').to(:restart).delayed + end + end + + it 'enables ironic conductor on boot' do + expect(chef_run).to enable_service('ironic-conductor') + end + + describe 'ironic-conductor' do + let(:service) { chef_run.service('ironic-conductor') } + + it 'subscribes to the template creation' do + expect(service).to subscribe_to('template[/etc/ironic/ironic.conf]') + end + + it 'subscribes to the common packages' do + expect(service).to subscribe_to('package[python-ironicclient]').delayed + end + end + end +end diff --git a/spec/identity_registration_spec.rb b/spec/identity_registration_spec.rb new file mode 100644 index 0000000..78d4aac --- /dev/null +++ b/spec/identity_registration_spec.rb @@ -0,0 +1,48 @@ +# encoding: UTF-8 + +require_relative 'spec_helper' + +describe 'openstack-bare-metal::identity_registration' do + describe 'ubuntu' do + let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } + let(:node) { runner.node } + let(:chef_run) { runner.converge(described_recipe) } + + include_context 'bare-metal-stubs' + + connection_params = { + openstack_auth_url: 'http://127.0.0.1:5000/v3/auth/tokens', + openstack_username: 'admin', + openstack_api_key: 'admin_test_pass', + openstack_project_name: 'admin', + openstack_domain_name: 'default', + } + service_name = 'baremetal' + service_project = 'ironic' + service_user = 'ironic' + + it "registers #{service_name} service" do + expect(chef_run).to create_openstack_service( + service_project + ).with( + connection_params: connection_params + ) + end + + it "registers #{service_name} endpoint" do + expect(chef_run).to create_openstack_endpoint( + service_name + ).with( + connection_params: connection_params + ) + end + + it "registers #{service_name} user" do + expect(chef_run).to create_openstack_user( + service_user + ).with( + connection_params: connection_params + ) + end + end +end diff --git a/spec/ironic-common_spec.rb b/spec/ironic-common_spec.rb new file mode 100644 index 0000000..c04e196 --- /dev/null +++ b/spec/ironic-common_spec.rb @@ -0,0 +1,110 @@ +# Encoding: utf-8 +# +# Cookbook Name:: openstack-bare-metal +# Spec:: ironic_common_spec +# +# Copyright 2015, IBM Corp. +# +# 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. +# + +require_relative 'spec_helper' + +describe 'openstack-bare-metal::ironic-common' do + describe 'ubuntu' do + let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } + let(:node) { runner.node } + let(:chef_run) { runner.converge(described_recipe) } + + include_context 'bare-metal-stubs' + + it 'upgrades ironic common packages' do + expect(chef_run).to upgrade_package('ironic-common') + end + + describe '/etc/ironic' do + let(:dir) { chef_run.directory('/etc/ironic') } + + it 'should create the /etc/ironic directory' do + expect(chef_run).to create_directory(dir.name).with( + user: 'ironic', + group: 'ironic', + mode: 0o0750 + ) + end + end + + describe 'ironic.conf' do + let(:file) { chef_run.template('/etc/ironic/ironic.conf') } + let(:test_pass) { 'test_pass' } + before do + allow_any_instance_of(Chef::Recipe).to receive(:get_password) + .with('user', anything) + .and_return(test_pass) + end + + it 'should create the ironic.conf template' do + expect(chef_run).to create_template(file.name).with( + user: 'ironic', + group: 'ironic', + mode: 0o0640 + ) + end + + context 'template contents' do + context 'syslog use' do + it 'sets the log_config value when syslog is in use' do + node.override['openstack']['baremetal']['syslog']['use'] = true + + expect(chef_run).to render_file(file.name) + .with_content(%r{^log_config = /etc/openstack/logging.conf$}) + end + end + + it 'has a db connection attribute' do + allow_any_instance_of(Chef::Recipe).to receive(:db_uri) + .and_return('sql_connection_value') + + expect(chef_run).to render_config_file(file.name) + .with_section_content('database', /^connection = sql_connection_value$/) + end + end + end + + describe 'rootwrap.conf' do + let(:file) { chef_run.template('/etc/ironic/rootwrap.conf') } + + it 'should create the /etc/ironic/rootwrap.conf file' do + expect(chef_run).to create_template(file.name).with( + user: 'root', + group: 'root', + mode: 0o644 + ) + end + + context 'template contents' do + it 'sets the default attributes' do + [ + %r{^filters_path = /etc/ironic/rootwrap.d,/usr/share/ironic/rootwrap$}, + %r{^exec_dirs = /sbin,/usr/sbin,/bin,/usr/bin$}, + /^use_syslog = false$/, + /^syslog_log_facility = syslog$/, + /^syslog_log_level = ERROR$/, + ].each do |line| + expect(chef_run).to render_config_file(file.name).with_content(line) + end + end + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..b1f94ea --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,169 @@ +# encoding: UTF-8 + +require 'chefspec' +require 'chefspec/berkshelf' +require 'chef/application' + +RSpec.configure do |config| + config.color = true + config.formatter = :documentation + config.log_level = :fatal +end + +SUSE_OPTS = { + platform: 'suse', + version: '11.3', +}.freeze +REDHAT_OPTS = { + platform: 'redhat', + version: '7.4', +}.freeze +UBUNTU_OPTS = { + platform: 'ubuntu', + version: '16.04', +}.freeze + +shared_context 'bare-metal-stubs' do + before do + allow_any_instance_of(Chef::Recipe).to receive(:rabbit_servers) + .and_return('1.1.1.1:5672,2.2.2.2:5672') + allow_any_instance_of(Chef::Recipe).to receive(:get_password) + .with('service', anything) + .and_return('') + allow_any_instance_of(Chef::Recipe).to receive(:get_password) + .with('db', anything) + .and_return('') + allow_any_instance_of(Chef::Recipe).to receive(:get_password) + .with('user', 'guest') + .and_return('mq-pass') + allow_any_instance_of(Chef::Recipe).to receive(:get_password) + .with('user', 'admin') + .and_return('admin_test_pass') + allow_any_instance_of(Chef::Recipe).to receive(:get_password) + .with('service', 'openstack-bare-metal') + .and_return('ironic_pass') + allow_any_instance_of(Chef::Recipe).to receive(:rabbit_transport_url) + .with('baremetal') + .and_return('rabbit://guest:mypass@127.0.0.1:5672') + stub_command('/usr/sbin/httpd -t').and_return(true) + stub_command('/usr/sbin/apache2 -t').and_return(true) + allow_any_instance_of(Chef::Recipe).to receive(:memcached_servers).and_return [] + allow(Chef::Application).to receive(:fatal!) + end +end + +shared_examples 'expect runs openstack common logging recipe' do + it 'runs logging recipe if node attributes say to' do + expect(chef_run).to include_recipe 'openstack-common::logging' + end +end + +shared_examples 'expect installs common ironic package' do + it 'installs the openstack-ironic common package' do + expect(chef_run).to upgrade_package 'openstack-ironic-common' + end +end + +shared_examples 'expect installs mysql package' do + it 'installs mysql python packages by default' do + expect(chef_run).to upgrade_package 'MySQL-python' + end +end + +shared_examples 'expect runs db migrations' do + it 'runs db migrations' do + expect(chef_run).to run_execute('ironic-dbsync').with(user: 'ironic', group: 'ironic') + end +end + +shared_examples 'expects to create ironic directories' do + it 'creates /etc/ironic' do + expect(chef_run).to create_directory('/etc/ironic').with( + owner: 'ironic', + group: 'ironic', + mode: 0o750 + ) + end +end + +shared_examples 'expects to create ironic conf' do + describe 'ironic.conf' do + let(:file) { chef_run.template('/etc/ironic/ironic.conf') } + + it 'creates the ironic.conf file' do + expect(chef_run).to create_template(file.name).with( + owner: 'ironic', + group: 'ironic', + mode: 0o640 + ) + end + + it 'sets auth_encryption_key' do + expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', /^auth_encryption_key = auth_encryption_key_secret$/) + end + + describe 'default values' + it 'has default conf values' do + [ + %r{^log_dir = /var/log/ironic$}, + /^region_name_for_services = RegionOne$/, + ].each do |line| + expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', line) + end + end + + it 'sets database connection value' do + expect(chef_run).to render_config_file(file.name).with_section_content( + 'database', %r{^connection = mysql\+pymysql://ironic:ironic@127.0.0.1:3306/ironic\?charset=utf8$} + ) + end + end + + describe 'has oslo_messaging_rabbit values' do + it 'has default rabbit values' do + [ + %r{^transport_url = rabbit://guest:mypass@127.0.0.1:5672$}, + ].each do |line| + expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', line) + end + end + end + + describe 'has keystone_authtoken values' do + it 'has default keystone_authtoken values' do + [ + %r{^auth_url = http://127.0.0.1:5000/v3$}, + /^auth_type = password$/, + /^username = ironic$/, + /^project_name = service$/, + /^user_domain_name = Default/, + /^project_domain_name = Default/, + /^password = ironic_pass$/, + ].each do |line| + expect(chef_run).to render_config_file(file.name).with_section_content('keystone_authtoken', line) + end + end + end +end + +shared_examples 'logging' do + context 'with logging enabled' do + before do + node.override['openstack']['baremetal']['syslog']['use'] = true + end + + it 'runs logging recipe if node attributes say to' do + expect(chef_run).to include_recipe 'openstack-common::logging' + end + end + + context 'with logging disabled' do + before do + node.override['openstack']['baremetal']['syslog']['use'] = false + end + + it 'does not run logging recipe' do + expect(chef_run).not_to include_recipe 'openstack-common::logging' + end + end +end diff --git a/templates/default/ironic.conf.erb b/templates/default/ironic.conf.erb new file mode 100644 index 0000000..dcff638 --- /dev/null +++ b/templates/default/ironic.conf.erb @@ -0,0 +1,12 @@ +<%= node['openstack']['baremetal']['custom_template_banner'] %> +<% @service_config.each do |section, values| -%> +[<%= section %>] + <% values.each do |key, value| -%> + <% if value.class == Hash -%> +<%= "# #{value['comment']}" -%> +<%= key %> = <%= value['set_to'] %> + <% else -%> +<%= key %> = <%= value %> + <% end -%> + <% end -%> +<% end -%> diff --git a/templates/default/rootwrap.conf.erb b/templates/default/rootwrap.conf.erb new file mode 100644 index 0000000..059f893 --- /dev/null +++ b/templates/default/rootwrap.conf.erb @@ -0,0 +1,29 @@ +<%= node['openstack']['baremetal']['custom_template_banner'] %> + +# Configuration for ironic-rootwrap +# This file should be owned by (and only-writeable by) the root user + +[DEFAULT] +# List of directories to load filter definitions from (separated by ','). +# These directories MUST all be only writeable by root ! +filters_path=<%= node['openstack']['baremetal']['rootwrap']['filters_path'] %> + +# List of directories to search executables in, in case filters do not +# explicitely specify a full path (separated by ',') +# If not specified, defaults to system PATH environment variable. +# These directories MUST all be only writeable by root ! +exec_dirs=<%= node['openstack']['baremetal']['rootwrap']['exec_dirs'] %> + +# Enable logging to syslog +# Default value is False +use_syslog=<%= node['openstack']['baremetal']['rootwrap']['use_syslog'] %> + +# Which syslog facility to use. +# Valid values include auth, authpriv, syslog, local0, local1... +# Default value is 'syslog' +syslog_log_facility=<%= node['openstack']['baremetal']['rootwrap']['syslog_log_facility'] %> + +# Which messages to log. +# INFO means log all usage +# ERROR means only log unsuccessful attempts +syslog_log_level=<%= node['openstack']['baremetal']['rootwrap']['syslog_log_level'] %> diff --git a/templates/default/wsgi-template.conf.erb b/templates/default/wsgi-template.conf.erb new file mode 100644 index 0000000..458847e --- /dev/null +++ b/templates/default/wsgi-template.conf.erb @@ -0,0 +1,42 @@ +<%= node['openstack']['baremetal']['custom_template_banner'] %> + +Listen <%= @params[:server_host] %>:<%= @params[:server_port] %> + +:<%= @params[:server_port] %>> + WSGIDaemonProcess <%= @params[:daemon_process] %> processes=2 threads=10 user=<%= @params[:user] %> group=<%= @params[:group] %> display-name=%{GROUP} + WSGIProcessGroup <%= @params[:daemon_process] %> + WSGIScriptAlias / <%= @params[:server_entry] %> + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + + + Require all granted + + + ErrorLogFormat "%{cu}t %M" + ErrorLog <%= @params[:log_dir] %>/<%= @params[:daemon_process] %>_error.log + CustomLog <%= @params[:log_dir] %>/<%= @params[:daemon_process] %>_access.log combined +<% if [true, 'true', 'True'].include?(@params[:log_debug]) -%> + LogLevel debug +<% end -%> + +<% if @params[:use_ssl] -%> + SSLEngine On + SSLCertificateFile <%= @params[:cert_file] %> + SSLCertificateKeyFile <%= @params[:key_file] %> + SSLCACertificatePath <%= @params[:ca_certs_path] %> +<% if @params[:chain_file] %> + SSLCertificateChainFile <%= @params[:chain_file] %> +<% end -%> + SSLProtocol <%= @params[:protocol] %> +<% if @params[:ciphers] -%> + SSLCipherSuite <%= @params[:ciphers] %> +<% end -%> +<% if @params[:cert_required] -%> + SSLVerifyClient require +<% end -%> +<% end -%> + + +WSGISocketPrefix <%= @params[:run_dir] -%> +