Fixup Identity service deployment for Ocata

- Remove recipe for PKI tokens as they have been dropped from keystone
- Use Fernet tokens unconditionally
- Cleanup paste deployment according to keystone changes in Ocata

Change-Id: I28c27caacc09a3e46eca135a6c4f5a841f4715f9
This commit is contained in:
Jens Rosenboom 2017-03-08 12:47:32 +00:00
parent ae02664362
commit f8b8302aae
9 changed files with 60 additions and 269 deletions

View File

@ -6,6 +6,7 @@
# Copyright 2012-2013, AT&T Services, Inc.
# Copyright 2013, Opscode, Inc.
# Copyright 2013, IBM Corp.
# Copyright 2017, x-ion GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -22,7 +23,7 @@
# 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']['identity']['custom_template_banner'] =
'# This file autogenerated by Chef, changes will be overwritten'
'# This file is autogenerated by Chef, changes will be overwritten'
%w(admin internal public).each do |ep_type|
# host for openstack admin/internal/public identity endpoint
@ -67,19 +68,19 @@ default['openstack']['identity']['pastefile_url'] = nil
# this value will be used in the templated version of keystone-paste.ini
# The last item in this pipeline must be public_service or an equivalent
# application. It cannot be a filter.
default['openstack']['identity']['pipeline']['public_api'] = 'sizelimit url_normalize request_id build_auth_context token_auth admin_token_auth json_body ec2_extension user_crud_extension public_service'
default['openstack']['identity']['pipeline']['public_api'] = 'healthcheck cors sizelimit http_proxy_to_wsgi url_normalize request_id build_auth_context token_auth json_body ec2_extension public_service'
# This specify the pipeline of the keystone admin API,
# all Identity admin API requests will be processed by the order of the pipeline.
# this value will be used in the templated version of keystone-paste.ini
# The last item in this pipeline must be admin_service or an equivalent
# application. It cannot be a filter.
default['openstack']['identity']['pipeline']['admin_api'] = 'sizelimit url_normalize request_id build_auth_context token_auth admin_token_auth json_body ec2_extension s3_extension crud_extension admin_service'
default['openstack']['identity']['pipeline']['admin_api'] = 'healthcheck cors sizelimit http_proxy_to_wsgi url_normalize request_id build_auth_context token_auth json_body ec2_extension s3_extension admin_service'
# This specify the pipeline of the keystone V3 API,
# all Identity V3 API requests will be processed by the order of the pipeline.
# this value will be used in the templated version of keystone-paste.ini
# The last item in this pipeline must be service_v3 or an equivalent
# application. It cannot be a filter.
default['openstack']['identity']['pipeline']['api_v3'] = 'sizelimit url_normalize request_id build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension simple_cert_extension revoke_extension federation_extension oauth1_extension endpoint_filter_extension service_v3'
default['openstack']['identity']['pipeline']['api_v3'] = 'healthcheck cors sizelimit http_proxy_to_wsgi url_normalize request_id build_auth_context token_auth json_body ec2_extension_v3 s3_extension service_v3'
# region to be used for endpoint registration
default['openstack']['identity']['region'] = node['openstack']['region']
@ -123,8 +124,6 @@ default['openstack']['identity']['ssl']['ca_certs'] = "#{node['openstack']['iden
# path of the CA cert files for SSL (Apache)
default['openstack']['identity']['ssl']['ca_certs_path'] = "#{node['openstack']['identity']['ssl']['basedir']}/certs/"
# Fernet keys. Note this section is only written if
# node['openstack']['auth']['strategy'] == 'fernet'
# Fernet keys to read from databags/vaults. This should be changed in the
# environment when rotating keys (with the defaults below, the items
# 'fernet_key0' and 'fernet_key1' will be read from the databag/vault
@ -132,6 +131,8 @@ default['openstack']['identity']['ssl']['ca_certs_path'] = "#{node['openstack'][
# For more information please read:
# http://docs.openstack.org/admin-guide-cloud/keystone_fernet_token_faq.html
default['openstack']['identity']['fernet']['keys'] = [0, 1]
default['openstack']['identity']['conf']['fernet_tokens']['key_repository'] =
'/etc/keystone/fernet-tokens'
# The external (REMOTE_USER) auth plugin module. (String value)
default['openstack']['identity']['auth']['external'] = 'keystone.auth.plugins.external.DefaultDomain'
@ -156,16 +157,6 @@ default['openstack']['identity']['token_flush_cron']['weekday'] = '*'
# configuration directory for keystone domain specific options
default['openstack']['identity']['identity']['domain_config_dir'] = '/etc/keystone/domains'
# PKI signing. Corresponds to the [signing] section of keystone.conf
# Note this section is only written if node['openstack']['auth']['strategy'] == 'pki'
default['openstack']['identity']['signing']['basedir'] = '/etc/keystone/ssl'
# certfile used for keystone pki token signing
default['openstack']['identity']['signing']['certfile'] = "#{node['openstack']['identity']['signing']['basedir']}/certs/signing_cert.pem"
# keyfile used for keystone pki token signing
default['openstack']['identity']['signing']['keyfile'] = "#{node['openstack']['identity']['signing']['basedir']}/private/signing_key.pem"
# certificate authority used for keystone pki token signing
default['openstack']['identity']['signing']['ca_certs'] = "#{node['openstack']['identity']['signing']['basedir']}/certs/ca.pem"
# keystone service user name
default['openstack']['identity']['user'] = 'keystone'
# keystone service user group
@ -180,7 +171,6 @@ when 'fedora', 'rhel' # :pragma-foodcritic: ~FC024 - won't fix this
'keystone_packages' => ['openstack-keystone'],
'keystone_service' => 'openstack-keystone',
'keystone_process_name' => 'keystone-all',
'keystone_wsgi_file' => '/usr/share/keystone/keystone.wsgi',
'package_options' => ''
}
when 'debian'
@ -190,7 +180,6 @@ when 'debian'
'keystone_packages' => ['keystone'],
'keystone_service' => 'keystone',
'keystone_process_name' => 'keystone-all',
'keystone_wsgi_file' => '/usr/share/keystone/wsgi.py',
'package_options' => "-o Dpkg::Options::='--force-confold' -o Dpkg::Options::='--force-confdef'"
}
end

View File

@ -15,19 +15,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# This recipe is automatically included in openstack-identiy::service-apache
# when node['openstack']['auth']['strategy'] is set to 'fernet'. It will add the
# needed configuration options to the keystone.conf and create the needed fernet
# tokens from predefined secrets (e.g. encrypted data bags or vaults).
# This recipe is automatically included in openstack-identity::service-apache.
# It will add the needed configuration options to the keystone.conf and create
# the needed fernet keys from predefined secrets (e.g. encrypted data bags or vaults).
class ::Chef::Recipe
include ::Openstack
end
node.default['openstack']['identity']['conf']['fernet_tokens']['key_repository'] =
'/etc/keystone/fernet-tokens'
node.default['openstack']['identity']['conf']['token']['provider'] = 'fernet'
key_repository =
node['openstack']['identity']['conf']['fernet_tokens']['key_repository']
@ -43,6 +38,6 @@ node['openstack']['identity']['fernet']['keys'].each do |key_index|
content key
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00600
mode 00400
end
end

View File

@ -1,76 +0,0 @@
# encoding: UTF-8
#
# Cookbook Name:: openstack-identity
# Recipe:: _pki_tokens
#
# 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.
# This recipe is automatically included in openstack-identiy::service-apache
# when node['openstack']['auth']['strategy'] is set to 'pki'. It will either
# create the needed pki secrets or load them as remote files. The usage of
# keystone pki tokens is deprecated in favor of fernet tokens and this recipe
# might be removed in future releases when the support for pki is removed from
# keystone.
certfile_url = node['openstack']['identity']['signing']['certfile_url']
keyfile_url = node['openstack']['identity']['signing']['keyfile_url']
ca_certs_url = node['openstack']['identity']['signing']['ca_certs_url']
signing_basedir = node['openstack']['identity']['signing']['basedir']
directory signing_basedir do
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00700
end
directory "#{signing_basedir}/certs" do
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00755
end
directory "#{signing_basedir}/private" do
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00750
end
if certfile_url.nil? || keyfile_url.nil? || ca_certs_url.nil?
execute 'keystone-manage pki_setup' do
user node['openstack']['identity']['user']
group node['openstack']['identity']['group']
not_if { ::FileTest.exists? "#{node['openstack']['identity']['signing']['basedir']}/private/signing_key.pem" }
end
else
remote_file node['openstack']['identity']['signing']['certfile'] do
source certfile_url
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00640
end
remote_file node['openstack']['identity']['signing']['keyfile'] do
source keyfile_url
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00640
end
remote_file node['openstack']['identity']['signing']['ca_certs'] do
source ca_certs_url
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00640
end
end

View File

@ -94,14 +94,8 @@ file '/var/lib/keystone/keystone.db' do
not_if { node['openstack']['db']['identity']['service_type'] == 'sqlite' }
end
# include the recipe to setup the selected keystone auth strategy (pki or
# fernet)
case node['openstack']['auth']['strategy']
when 'pki'
include_recipe 'openstack-identity::_pki_tokens'
when 'fernet'
include_recipe 'openstack-identity::_fernet_tokens'
end
# include the recipe to setup fernet tokens
include_recipe 'openstack-identity::_fernet_tokens'
# define the address to bind the keystone apache main service to
main_bind_service = node['openstack']['bind_service']['main']['identity']

View File

@ -5,21 +5,14 @@ require_relative 'spec_helper'
describe 'openstack-identity::_fernet_tokens' do
describe 'ubuntu' do
include_context 'identity_stubs'
let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) }
let(:node) { runner.node }
let(:chef_run) do
runner.converge(described_recipe)
end
before do
allow_any_instance_of(Chef::Recipe).to receive(:secret)
.with('keystone', 'fernet_key0')
.and_return('thisisfernetkey0')
allow_any_instance_of(Chef::Recipe).to receive(:secret)
.with('keystone', 'fernet_key1')
.and_return('thisisfernetkey1')
end
it do
expect(chef_run).to create_directory('/etc/keystone/fernet-tokens')
.with(owner: 'keystone', user: 'keystone', mode: 00700)
@ -32,7 +25,7 @@ describe 'openstack-identity::_fernet_tokens' do
content: "thisisfernetkey#{key_index}",
owner: 'keystone',
group: 'keystone',
mode: 00600
mode: 00400
)
end
end

View File

@ -1,90 +0,0 @@
# encoding: UTF-8
#
require_relative 'spec_helper'
describe 'openstack-identity::_pki_tokens' do
describe 'ubuntu' do
let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) }
let(:node) { runner.node }
let(:chef_run) do
runner.converge(described_recipe)
end
include Helpers
include_context 'identity_stubs'
describe 'ssl directories' do
let(:ssl_dir) { '/etc/keystone/ssl' }
let(:certs_dir) { "#{ssl_dir}/certs" }
let(:private_dir) { "#{ssl_dir}/private" }
describe '/etc/keystone/ssl' do
let(:dir_resource) { chef_run.directory(ssl_dir) }
it 'creates /etc/keystone/ssl' do
expect(chef_run).to create_directory(ssl_dir).with(
owner: 'keystone',
group: 'keystone',
mode: 0700
)
end
end
describe '/etc/keystone/ssl/certs' do
let(:dir_resource) { chef_run.directory(certs_dir) }
it 'creates /etc/keystone/ssl/certs' do
expect(chef_run).to create_directory(certs_dir).with(
user: 'keystone',
group: 'keystone',
mode: 0755
)
end
end
describe '/etc/keystone/ssl/private' do
let(:dir_resource) { chef_run.directory(private_dir) }
it 'creates /etc/keystone/ssl/private' do
expect(chef_run).to create_directory(private_dir)
.with(
user: 'keystone',
group: 'keystone',
mode: 0750
)
end
end
end
describe 'pki setup' do
let(:cmd) { 'keystone-manage pki_setup' }
describe 'without {certfile,keyfile,ca_certs}_url attributes set' do
it 'executes' do
expect(FileTest).to receive(:exists?)
.with('/etc/keystone/ssl/private/signing_key.pem')
.and_return(false)
expect(chef_run).to run_execute(cmd)
.with(
user: 'keystone',
group: 'keystone'
)
end
end
it 'does not execute when dir exists' do
expect(FileTest).to receive(:exists?)
.with('/etc/keystone/ssl/private/signing_key.pem')
.and_return(true)
expect(chef_run).not_to run_execute(cmd)
.with(
user: 'keystone',
group: 'keystone'
)
end
end
end
end

View File

@ -82,28 +82,6 @@ describe 'openstack-identity::server-apache' do
end
end
describe 'ssl directories' do
let(:ssl_dir) { '/etc/keystone/ssl' }
let(:certs_dir) { "#{ssl_dir}/certs" }
let(:private_dir) { "#{ssl_dir}/private" }
describe 'without pki' do
before { node.set['openstack']['auth']['strategy'] = 'uuid' }
it 'does not create /etc/keystone/ssl' do
expect(chef_run).not_to create_directory(ssl_dir)
end
it 'does not create /etc/keystone/ssl/certs' do
expect(chef_run).not_to create_directory(certs_dir)
end
it 'does not create /etc/keystone/ssl/private' do
expect(chef_run).not_to create_directory(private_dir)
end
end
end
it 'deletes keystone.db' do
expect(chef_run).to delete_file('/var/lib/keystone/keystone.db')
end
@ -296,18 +274,36 @@ describe 'openstack-identity::server-apache' do
)
end
it 'has default api pipeline value' do
expect(chef_run).to render_file(path).with_content(/^pipeline = sizelimit url_normalize request_id build_auth_context token_auth admin_token_auth json_body ec2_extension user_crud_extension public_service$/)
expect(chef_run).to render_file(path).with_content(/^pipeline = sizelimit url_normalize request_id build_auth_context token_auth admin_token_auth json_body ec2_extension s3_extension crud_extension admin_service$/)
expect(chef_run).to render_file(path).with_content(/^pipeline = sizelimit url_normalize request_id build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension simple_cert_extension revoke_extension federation_extension oauth1_extension endpoint_filter_extension service_v3$/)
it 'has default api pipeline values' do
expect(chef_run).to render_config_file(path).with_section_content(
'pipeline:public_api',
/^pipeline = healthcheck cors sizelimit http_proxy_to_wsgi url_normalize request_id build_auth_context token_auth json_body ec2_extension public_service$/
)
expect(chef_run).to render_config_file(path).with_section_content(
'pipeline:admin_api',
/^pipeline = healthcheck cors sizelimit http_proxy_to_wsgi url_normalize request_id build_auth_context token_auth json_body ec2_extension s3_extension admin_service$/
)
expect(chef_run).to render_config_file(path).with_section_content(
'pipeline:api_v3',
/^pipeline = healthcheck cors sizelimit http_proxy_to_wsgi url_normalize request_id build_auth_context token_auth json_body ec2_extension_v3 s3_extension service_v3$/
)
end
it 'template api pipeline set correct' do
node.set['openstack']['identity']['pipeline']['public_api'] = 'public_service'
node.set['openstack']['identity']['pipeline']['admin_api'] = 'admin_service'
node.set['openstack']['identity']['pipeline']['api_v3'] = 'service_v3'
expect(chef_run).to render_file(path).with_content(/^pipeline = public_service$/)
expect(chef_run).to render_file(path).with_content(/^pipeline = admin_service$/)
expect(chef_run).to render_file(path).with_content(/^pipeline = service_v3$/)
expect(chef_run).to render_config_file(path).with_section_content(
'pipeline:public_api',
/^pipeline = public_service$/
)
expect(chef_run).to render_config_file(path).with_section_content(
'pipeline:admin_api',
/^pipeline = admin_service$/
)
expect(chef_run).to render_config_file(path).with_section_content(
'pipeline:api_v3',
/^pipeline = service_v3$/
)
end
it 'template misc_paste array correctly' do
node.set['openstack']['identity']['misc_paste'] = ['MISC1 = OPTION1', 'MISC2 = OPTION2']
@ -333,11 +329,6 @@ describe 'openstack-identity::server-apache' do
end
describe 'apache setup' do
it 'stop and disable keystone service' do
expect(chef_run).to stop_service('keystone')
expect(chef_run).to disable_service('keystone')
end
it 'set apache addresses and ports' do
expect(chef_run.node['apache']['listen']).to eq(
%w(127.0.0.1:5000 127.0.0.1:35357)

View File

@ -64,6 +64,12 @@ shared_context 'identity_stubs' do
allow_any_instance_of(Chef::Recipe).to receive(:get_password)
.with('user', 'admin')
.and_return('admin')
allow_any_instance_of(Chef::Recipe).to receive(:secret)
.with('keystone', 'fernet_key0')
.and_return('thisisfernetkey0')
allow_any_instance_of(Chef::Recipe).to receive(:secret)
.with('keystone', 'fernet_key1')
.and_return('thisisfernetkey1')
allow_any_instance_of(Chef::Recipe).to receive(:rabbit_transport_url)
.with('identity')
.and_return('rabbit://guest:mypass@127.0.0.1:5672')

View File

@ -14,17 +14,18 @@ use = egg:keystone#build_auth_context
[filter:token_auth]
use = egg:keystone#token_auth
[filter:admin_token_auth]
use = egg:keystone#admin_token_auth
[filter:json_body]
use = egg:keystone#json_body
[filter:user_crud_extension]
use = egg:keystone#user_crud_extension
[filter:cors]
use = egg:oslo.middleware#cors
oslo_config_project = keystone
[filter:crud_extension]
use = egg:keystone#crud_extension
[filter:http_proxy_to_wsgi]
use = egg:oslo.middleware#http_proxy_to_wsgi
[filter:healthcheck]
use = egg:oslo.middleware#healthcheck
[filter:ec2_extension]
use = egg:keystone#ec2_extension
@ -32,30 +33,18 @@ use = egg:keystone#ec2_extension
[filter:ec2_extension_v3]
use = egg:keystone#ec2_extension_v3
[filter:federation_extension]
use = egg:keystone#federation_extension
[filter:oauth1_extension]
use = egg:keystone#oauth1_extension
[filter:s3_extension]
use = egg:keystone#s3_extension
[filter:endpoint_filter_extension]
use = egg:keystone#endpoint_filter_extension
[filter:simple_cert_extension]
use = egg:keystone#simple_cert_extension
[filter:revoke_extension]
use = egg:keystone#revoke_extension
[filter:url_normalize]
use = egg:keystone#url_normalize
[filter:sizelimit]
use = egg:keystone#sizelimit
[filter:osprofiler]
use = egg:osprofiler#osprofiler
[app:public_service]
use = egg:keystone#public_service
@ -81,10 +70,10 @@ use = egg:keystone#public_version_service
use = egg:keystone#admin_version_service
[pipeline:public_version_api]
pipeline = sizelimit url_normalize public_version_service
pipeline = healthcheck cors sizelimit osprofiler url_normalize public_version_service
[pipeline:admin_version_api]
pipeline = sizelimit url_normalize admin_version_service
pipeline = healthcheck cors sizelimit osprofiler url_normalize admin_version_service
[composite:main]
use = egg:Paste#urlmap