From cf5a131cd70c3c82f2d11c717198f754fdaba7c7 Mon Sep 17 00:00:00 2001 From: Adam Young Date: Thu, 15 Sep 2016 22:54:16 -0400 Subject: [PATCH] Allow the management of the Fernet Keys When keystone uses Fernet tokens in a multi node environment, each of the nodes needs to have a copy of the keys used by other nodes. While the upstream suggestion is to run the command on one node and then copy the keys to the others, deployments using a central configuration server do not usually follow workflows like this. Instead the keys are generated off server, and managed in a central data store. This change follows the pattern set for credentials key management. Change-Id: Ibd2a7692c247d0367c5fd331bb88790f882c2c91 --- manifests/init.pp | 45 ++++++++++++++----- ...eystone-fernet-setup-227ef6d380519cce.yaml | 12 +++++ spec/classes/keystone_spec.rb | 30 +++++++++++++ 3 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 releasenotes/notes/keystone-fernet-setup-227ef6d380519cce.yaml diff --git a/manifests/init.pp b/manifests/init.pp index 4e9a1fa24..75e42af2b 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -432,6 +432,20 @@ # (Optional) Number of maximum active Fernet keys. Integer > 0. # Defaults to $::os_service_default # +# [*fernet_keys*] +# (Optional) Hash of Keystone fernet keys +# If you enable this parameter, make sure enable_fernet_setup is set to True. +# Example of valid value: +# fernet_keys: +# /etc/keystone/fernet-keys/0: +# content: c_aJfy6At9y-toNS9SF1NQMTSkSzQ-OBYeYulTqKsWU= +# /etc/keystone/fernet-keys/1: +# content: zx0hNG7CStxFz5KXZRsf7sE4lju0dLYvXdGDIKGcd7k= +# Puppet will create a file per key in $fernet_key_repository. +# Note: defaults to false so keystone-manage fernet_setup will be executed. +# Otherwise Puppet will manage keys with File resource. +# Defaults to false +# # [*enable_credential_setup*] # (Optional) Setup keystone for credentials. # In a cluster environment where multiple Keystone nodes are running, you might @@ -713,6 +727,7 @@ class keystone( $enable_fernet_setup = false, $fernet_key_repository = '/etc/keystone/fernet-keys', $fernet_max_active_keys = $::os_service_default, + $fernet_keys = false, $enable_credential_setup = false, $credential_key_repository = '/etc/keystone/credential-keys', $credential_keys = false, @@ -1112,16 +1127,26 @@ class keystone( subscribe => Anchor['keystone::install::end'], }) - exec { 'keystone-manage fernet_setup': - command => "keystone-manage fernet_setup --keystone-user ${keystone_user} --keystone-group ${keystone_group}", - path => '/usr/bin', - user => $keystone_user, - refreshonly => true, - creates => "${fernet_key_repository}/0", - notify => Anchor['keystone::service::begin'], - subscribe => [Anchor['keystone::install::end'], Anchor['keystone::config::end']], - require => File[$fernet_key_repository], - tag => 'keystone-exec', + if $fernet_keys { + validate_hash($fernet_keys) + create_resources('file', $fernet_keys, { + 'owner' => $keystone_user, + 'group' => $keystone_group, + 'subscribe' => 'Anchor[keystone::install::end]', + } + ) + } else { + exec { 'keystone-manage fernet_setup': + command => "keystone-manage fernet_setup --keystone-user ${keystone_user} --keystone-group ${keystone_group}", + path => '/usr/bin', + user => $keystone_user, + refreshonly => true, + creates => "${fernet_key_repository}/0", + notify => Anchor['keystone::service::begin'], + subscribe => [Anchor['keystone::install::end'], Anchor['keystone::config::end']], + require => File[$fernet_key_repository], + tag => 'keystone-exec', + } } } diff --git a/releasenotes/notes/keystone-fernet-setup-227ef6d380519cce.yaml b/releasenotes/notes/keystone-fernet-setup-227ef6d380519cce.yaml new file mode 100644 index 000000000..dc6d5a925 --- /dev/null +++ b/releasenotes/notes/keystone-fernet-setup-227ef6d380519cce.yaml @@ -0,0 +1,12 @@ +--- +features: + - keystone-manage can be used to setup Keystone Fernet Keys. Disabled by default + as long as the proper version of keystone is not in UCA. + Upstream Keystone is moving to Fernet token support as the default provider. + With recent issues witj PKI, Fernet is the only viable token format for + multisite. + + Note, if fernet_keys parameter is set to a valid hash, keystone-manage won't + be used to generate credential keys but Puppet will manage file resources for each + key in the hash. It allows ensures that a the keys are synchronized in a + multinode environment. diff --git a/spec/classes/keystone_spec.rb b/spec/classes/keystone_spec.rb index 0f1f06631..6f10e9fd1 100644 --- a/spec/classes/keystone_spec.rb +++ b/spec/classes/keystone_spec.rb @@ -1051,6 +1051,36 @@ describe 'keystone' do end end + describe 'when setting fernet_keys parameter' do + let :params do + default_params.merge({ + 'enable_fernet_setup' => true, + 'fernet_keys' => { + '/etc/keystone/fernet-keys/0' => { + 'content' => 't-WdduhORSqoyAykuqWAQSYjg2rSRuJYySgI2xh48CI=', + }, + '/etc/keystone/fernet-keys/1' => { + 'content' => 'GLlnyygEVJP4-H2OMwClXn3sdSQUZsM5F194139Unv8=', + }, + } + }) + end + + it { is_expected.to_not contain_exec('keystone-manage fernet_setup') } + it { is_expected.to contain_file('/etc/keystone/fernet-keys/0').with( + 'content' => 't-WdduhORSqoyAykuqWAQSYjg2rSRuJYySgI2xh48CI=', + 'owner' => 'keystone', + 'owner' => 'keystone', + 'subscribe' => 'Anchor[keystone::install::end]', + )} + it { is_expected.to contain_file('/etc/keystone/fernet-keys/1').with( + 'content' => 'GLlnyygEVJP4-H2OMwClXn3sdSQUZsM5F194139Unv8=', + 'owner' => 'keystone', + 'owner' => 'keystone', + 'subscribe' => 'Anchor[keystone::install::end]', + )} + end + shared_examples_for "when configuring default domain" do describe 'with default domain and eventlet service is managed and enabled' do let :params do