Make SSL settings configurable for Glance

This commit allows enabling SSL for glance-api and registry
endpoints by adding few new node attributes. Glance API and registry
configuration files are also modified to use these node attributes.

With these changes, users can easily enable SSL - both in secure and
insecure mode. However, it is user's responsibility to generate and
provide location of SSL certificate and its key.

Closes-Bug #1445773

Change-Id: I1d0f776efb392e058bc3dbf0ee5223512b60f584
This commit is contained in:
Imtiaz Chowdhury 2015-04-18 06:32:23 -07:00
parent 524e5cc77c
commit 57f2b23d35
7 changed files with 198 additions and 15 deletions

View File

@ -153,6 +153,16 @@ Attributes for the Image service are in the ['openstack']['image'] namespace.
* `openstack['image']['cron']['redirection']` - Redirection of cron output
TODO: Add DB2 support on other platforms
SSL attributes
---------------
* `openstack['image']['ssl']['enabled']` - Enable SSL for Glance API and registry endpoints. NOTE: Once enabled, Glance service endpoint must be configured to use https on Keystone. Default is false.
* `openstack['image']['ssl']['basedir']` - Base directory for SSL certficate and key file.
* `openstack['image']['ssl']['cert_file']` - Path of the cert file for SSL.
* `openstack['image']['ssl']['key_file']` - Path of the keyfile for SSL.
* `openstack['image']['ssl']['cert_required']` - Client certificate required. Default is False.
* `openstack['image']['ssl']['ca_file']` - Path of the CA cert file
VMWare attributes
-----------------
@ -242,6 +252,7 @@ Author:: Chen Zhiwei (zhiwchen@cn.ibm.com)
Author:: Eric Zhou (zyouzhou@cn.ibm.com)
Author:: Jian Hua Geng (gengjh@cn.ibm.com)
Author:: Ionut Artarisi (iartarisi@suse.cz)
Author:: Imtiaz Chowdhury (<imtiaz.chowdhury@workday.com>)
Copyright 2012, Rackspace US, Inc.
Copyright 2012-2013, Opscode, Inc.

View File

@ -27,6 +27,21 @@ default['openstack']['image']['custom_template_banner'] = '
# Do not edit, changes will be overwritten
'
# SSL Options
# Enable SSL for glance-api endpoint. NOTE: Once enabled, Glance service endpoint
# must be set to https on Keystone
default['openstack']['image']['ssl']['enabled'] = false
# Base directory for SSL certficate and key
default['openstack']['image']['ssl']['basedir'] = '/etc/glance/ssl'
# Path of the cert file for SSL.
default['openstack']['image']['ssl']['cert_file'] = "#{node['openstack']['image']['ssl']['basedir']}/certs/sslcert.pem"
# Path of the keyfile for SSL.
default['openstack']['image']['ssl']['key_file'] = "#{node['openstack']['image']['ssl']['basedir']}/private/sslkey.pem"
# Specify server whether SSL certificate is required
default['openstack']['image']['ssl']['cert_required'] = false
# Path of the CA cert file for SSL. Only use if client certificate is required
default['openstack']['image']['ssl']['ca_file'] = "#{node['openstack']['image']['ssl']['basedir']}/certs/sslca.pem"
default['openstack']['image']['verbose'] = 'False'
default['openstack']['image']['debug'] = 'False'
# This is the name of the Chef role that will install the Keystone Service API

View File

@ -27,6 +27,7 @@ describe 'openstack-image::api' do
runner.converge(described_recipe)
end
include Helpers
include_context 'image-stubs'
include_examples 'common-logging-recipe'
include_examples 'common-packages'
@ -93,6 +94,87 @@ describe 'openstack-image::api' do
let(:file_name) { file.name }
end
context 'glance-api configuration with ssl enabled' do
default_opts = {
cert_file: '/etc/glance/ssl/certs/sslcert.pem',
key_file: '/etc/glance/ssl/private/sslkey.pem'
}
it 'configures SSL cert and key file' do
node.set['openstack']['image']['ssl']['enabled'] = true
default_opts.each do |key, val|
r = line_regexp("#{key} = #{val}")
expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', r)
end
end
end
context 'glance-api configuration with ssl disabled' do
default_opts = {
cert_file: '/etc/glance/ssl/certs/sslcert.pem',
key_file: '/etc/glance/ssl/private/sslkey.pem'
}
it 'does not set cert or key file' do
default_opts.each do |key, val|
r = line_regexp("#{key} = #{val}")
expect(chef_run).not_to render_config_file(file.name).with_section_content('DEFAULT', r)
end
end
end
context 'glance-registry configuration with ssl enabled' do
it 'sets registry client protocol to https' do
node.set['openstack']['image']['ssl']['enabled'] = true
expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', /^registry_client_protocol = https$/)
end
# if cert required then certfile
context 'glance-registry with cert required' do
it 'configures CA cert file' do
node.set['openstack']['image']['ssl']['enabled'] = true
node.set['openstack']['image']['ssl']['cert_required'] = true
node.set['openstack']['image']['registry']['auth']['cafile'] = '/etc/glance/ssl/certs/sslca.pem'
r = line_regexp('registry_client_ca_file = /etc/glance/ssl/certs/sslca.pem')
expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', r)
end
end
context 'glance-registry with cert not required' do
it 'does not configure CA cert file' do
node.set['openstack']['image']['ssl']['enabled'] = true
node.set['openstack']['image']['ssl']['cert_required'] = false
node.set['openstack']['image']['registry']['auth']['cafile'] = '/etc/glance/ssl/certs/sslca.pem'
r = line_regexp('registry_client_ca_file = /etc/glance/ssl/certs/sslca.pem')
expect(chef_run).not_to render_config_file(file.name).with_section_content('DEFAULT', r)
end
end
context 'glance-registry with certificate validation enabled' do
it 'enables SSL in insecure mode' do
node.set['openstack']['image']['ssl']['enabled'] = true
node.set['openstack']['image']['registry']['auth']['insecure'] = false
r = line_regexp('registry_client_insecure = false')
expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', r)
end
end
context 'glance-registry with certificate validation disabled' do
it 'enables SSL in secure mode' do
node.set['openstack']['image']['ssl']['enabled'] = true
node.set['openstack']['image']['registry']['auth']['insecure'] = true
r = line_regexp('registry_client_insecure = true')
expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', r)
end
end
end
context 'glance-registry configuration with ssl disabled' do
it 'sets registry client protocol to http' do
node.set['openstack']['image']['ssl']['enabled'] = false
expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', /^registry_client_protocol = http$/)
end
end
context 'commonly named attributes' do
%w(verbose debug filesystem_store_datadir).each do |attr|
it "sets the #{attr} attribute" do

View File

@ -15,6 +15,7 @@ describe 'openstack-image::registry' do
runner.converge(described_recipe)
end
include Helpers
include_context 'image-stubs'
include_examples 'common-logging-recipe'
include_examples 'common-packages'
@ -196,6 +197,53 @@ describe 'openstack-image::registry' do
expect(chef_run).to render_file(file.name).with_content(/^hash_algorithms = sha2$/)
end
end
context 'glance-registry configuration with ssl disabled' do
default_opts = {
cert_file: '/etc/glance/ssl/certs/sslcert.pem',
key_file: '/etc/glance/ssl/private/sslkey.pem'
}
it 'does not set cert or key file' do
default_opts.each do |key, val|
r = line_regexp("#{key} = #{val}")
expect(chef_run).not_to render_config_file(file.name).with_section_content('DEFAULT', r)
end
end
end
context 'glance-registry configuration with ssl enabled' do
default_opts = {
cert_file: '/etc/glance/ssl/certs/sslcert.pem',
key_file: '/etc/glance/ssl/private/sslkey.pem'
}
cert = { 'ca_file' => '/etc/glance/ssl/certs/sslca.pem' }
it 'configures SSL cert and key file' do
node.set['openstack']['image']['ssl']['enabled'] = true
default_opts.each do |key, val|
r = line_regexp("#{key} = #{val}")
expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', r)
end
end
context 'with cert required' do
it 'configures CA cert ' do
node.set['openstack']['image']['ssl']['enabled'] = true
node.set['openstack']['image']['ssl']['cert_required'] = true
r = line_regexp("ca_file = #{cert['ca_file']}")
expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', r)
end
end
context 'with cert not required' do
it 'configures CA cert ' do
node.set['openstack']['image']['ssl']['enabled'] = true
node.set['openstack']['image']['ssl']['cert_required'] = false
r = line_regexp("ca_file = #{cert['ca_file']}")
expect(chef_run).not_to render_config_file(file.name).with_section_content('DEFAULT', r)
end
end
end
end
it 'notifies glance-registry restart' do

View File

@ -23,6 +23,18 @@ SUSE_OPTS = {
log_lovel: LOG_LEVEL
}
# Helper methods
module Helpers
# Create an anchored regex to exactly match the entire line
# (name borrowed from grep --line-regexp)
#
# @param [String] str The whole line to match
# @return [Regexp] The anchored/escaped regular expression
def line_regexp(str)
/^#{Regexp.quote(str)}$/
end
end
shared_context 'image-stubs' do
before do
allow_any_instance_of(Chef::Recipe).to receive(:address_for)

View File

@ -130,14 +130,18 @@ log_file = /var/log/glance/api.log
# ================= SSL Options ===============================
# Certificate file to use when starting API server securely
#cert_file = /path/to/certfile
<% if node['openstack']['image']['ssl']['enabled'] -%>
cert_file = <%= node['openstack']['image']['ssl']['cert_file'] %>
# Private key file to use when starting API server securely
#key_file = /path/to/keyfile
key_file = <%= node['openstack']['image']['ssl']['key_file'] %>
<% if node['openstack']['image']['ssl']['cert_required'] -%>
# CA certificate file to use to verify connecting clients
#ca_file = /path/to/cafile
ca_file = <%=node['openstack']['image']['ssl']['ca_file'] %>
<% end -%>
<% end -%>
# ================= Security Options ==========================
# AES key for encrypting store 'location' metadata, including
@ -152,33 +156,40 @@ log_file = /var/log/glance/api.log
registry_host = <%= @registry_ip_address %>
# Port the registry server is listening on
#registry_port = 9191
registry_port = <%= @registry_port %>
# What protocol to use when connecting to the registry server?
<% if node['openstack']['image']['ssl']['enabled'] -%>
# Set to https for secure HTTP communication
registry_client_protocol = http
registry_client_protocol = https
# The path to the key file to use in SSL connections to the
# registry server, if any. Alternately, you may set the
# GLANCE_CLIENT_KEY_FILE environ variable to a filepath of the key file
#registry_client_key_file = /path/to/key/file
registry_client_key_file = <%= node['openstack']['image']['ssl']['key_file'] %>
# The path to the cert file to use in SSL connections to the
# registry server, if any. Alternately, you may set the
# GLANCE_CLIENT_CERT_FILE environ variable to a filepath of the cert file
#registry_client_cert_file = /path/to/cert/file
registry_client_cert_file = <%= node['openstack']['image']['ssl']['cert_file'] %>
<% if node['openstack']['image']['ssl']['cert_required'] %>
# The path to the certifying authority cert file to use in SSL connections
# to the registry server, if any. Alternately, you may set the
# GLANCE_CLIENT_CA_FILE environ variable to a filepath of the CA cert file
#registry_client_ca_file = /path/to/ca/file
registry_client_ca_file = <%= node['openstack']['image']['registry']['auth']['cafile'] %>
<% end %>
# When using SSL in connections to the registry server, do not require
# validation via a certifying authority. This is the registry's equivalent of
# specifying --insecure on the command line using glanceclient for the API
# Default: False
#registry_client_insecure = False
registry_client_insecure = <%= node['openstack']['image']['registry']['auth']['insecure'] %>
<% else -%>
registry_client_protocol = http
<% end -%>
# The period of time, in seconds, that the API server will wait for a registry
# request to complete. A value of '0' implies no timeout.

View File

@ -85,15 +85,18 @@ log_file = /var/log/glance/registry.log
# ================= SSL Options ===============================
<% if node['openstack']['image']['ssl']['enabled'] -%>
# Certificate file to use when starting registry server securely
#cert_file = /path/to/certfile
cert_file = <%= node['openstack']['image']['ssl']['cert_file'] %>
# Private key file to use when starting registry server securely
#key_file = /path/to/keyfile
key_file = <%= node['openstack']['image']['ssl']['key_file'] %>
<% if node['openstack']['image']['ssl']['cert_required'] -%>
# CA certificate file to use to verify connecting clients
#ca_file = /path/to/cafile
ca_file = <%= node['openstack']['image']['ssl']['ca_file'] %>
<% end -%>
<% end -%>
# ============ Notification System Options =====================
# Driver or drivers to handle sending notifications. Set to
@ -235,6 +238,7 @@ admin_tenant_name = <%= node["openstack"]["image"]["service_tenant_name"] %>
admin_user = <%= node["openstack"]["image"]["service_user"] %>
admin_password = <%= @service_pass %>
signing_dir = <%= node["openstack"]["image"]["registry"]["auth"]["cache_dir"] %>
insecure = <%= node['openstack']['image']['registry']['auth']['insecure'] %>
# A list of memcached server(s) to use for caching.
<% if node['openstack']['image']['registry']['auth']['memcached_servers'] %>