From 19a6e6d51a054cd16a48704d7df3f1b8d31e2145 Mon Sep 17 00:00:00 2001 From: "Luis A. Garcia" Date: Fri, 18 Apr 2014 07:51:28 -0700 Subject: [PATCH] Add crontab to flush tokens via keystone-manage When the keystone tokens backend is SQL, the tokens table grows unboundedly as new tokens are issued and not disposed of after expiration. Keystone provides a tool to delete the tokens, and this patch puts it in a cronjob in order to avoid growing the tokens database forever. Change-Id: I3e4831619efec273ac5aa378fff4b14ad877f326 Implements: blueprint token-flush --- CHANGELOG.md | 3 +++ README.md | 16 ++++++++++++++++ attributes/default.rb | 8 ++++++++ metadata.rb | 2 +- recipes/server.rb | 18 ++++++++++++++++++ spec/server_spec.rb | 13 +++++++++++++ 6 files changed, 59 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 653cdc0..dc24c33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # CHANGELOG for cookbook-openstack-identity This file is used to list changes made in each version of cookbook-openstack-identity. +## 9.1.0 +* Add token flushing cronjob + ## 9.0.0 * Upgrade to Icehouse diff --git a/README.md b/README.md index 8780225..55de4df 100644 --- a/README.md +++ b/README.md @@ -262,6 +262,22 @@ The following attributes are defined in attributes/default.rb of the common cook If the value of the 'bind_interface' attribute is non-nil, then the identity service will be bound to the first IP address on that interface. If the value of the 'bind_interface' attribute is nil, then the identity service will be bound to the IP address specified in the host attribute. +### Token flushing +When managing tokens with an SQL backend the token database may grow unboundedly as new tokens are issued and expired +tokens are not disposed of. Expired tokens may need to be kept around in order to allow for auditability. + +It is up to deployers to define when their tokens can be safely deleted. Keystone provides a tool to purge expired tokens, +and the server recipe can create a cronjob to run that tool. By default the cronjob will be configured to run hourly. + +The flush tokens cronjob configuration parameters are listed below: + +* `openstack['identity']['token_flush_cron']['enabled']` - Boolean indicating whether the flush tokens cronjob is enabled. It is by default enabled if the token backend is 'sql'. +* `openstack['identity']['token_flush_cron']['log_file']` - The log file for the flush tokens tool. +* `openstack['identity']['token_flush_cron']['hour']` - The hour at which the flush tokens cronjob should run (values 0 - 23). +* `openstack['identity']['token_flush_cron']['minute']` - The minute at which the flush tokens cronjob should run (values 0 - 59). +* `openstack']['identity']['token_flush_cron']['day']` - The day of the month when the flush tokens cronjob should run (values 1 - 31). +* `openstack['identity']['token_flush_cron']['weekday']` = The day of the week at which the flush tokens cronjob should run (values 0 - 6, where Sunday is 0). + Testing ===== diff --git a/attributes/default.rb b/attributes/default.rb index b39940b..448ff19 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -147,6 +147,14 @@ default['openstack']['identity']['ldap']['group_allow_create'] = true default['openstack']['identity']['ldap']['group_allow_update'] = true default['openstack']['identity']['ldap']['group_allow_delete'] = true +# Token flushing cronjob +default['openstack']['identity']['token_flush_cron']['enabled'] = node['openstack']['identity']['token']['backend'] == 'sql' +default['openstack']['identity']['token_flush_cron']['log_file'] = '/var/log/keystone/token-flush.log' +default['openstack']['identity']['token_flush_cron']['hour'] = '*' +default['openstack']['identity']['token_flush_cron']['minute'] = '0' +default['openstack']['identity']['token_flush_cron']['day'] = '*' +default['openstack']['identity']['token_flush_cron']['weekday'] = '*' + # platform defaults case platform_family when 'fedora', 'rhel' # :pragma-foodcritic: ~FC024 - won't fix this diff --git a/metadata.rb b/metadata.rb index c12009c..4774808 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ maintainer_email 'matt@opscode.com' license 'Apache 2.0' description 'The OpenStack Identity service Keystone.' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '9.0.0' +version '9.1.0' recipe 'openstack-identity::client', 'Install packages required for keystone client' recipe 'openstack-identity::server', 'Installs and Configures Keystone Service' diff --git a/recipes/server.rb b/recipes/server.rb index 17deb69..f6c6c2f 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -188,3 +188,21 @@ execute 'keystone-manage db_sync' do only_if { node['openstack']['db']['identity']['migrate'] } end + +# Configure the flush tokens cronjob +should_run_cron = node['openstack']['identity']['token_flush_cron']['enabled'] && node['openstack']['identity']['token']['backend'] == 'sql' +log_file = node['openstack']['identity']['token_flush_cron']['log_file'] + +cron 'keystone-manage-token-flush' do + minute node['openstack']['identity']['token_flush_cron']['minute'] + hour node['openstack']['identity']['token_flush_cron']['hour'] + day node['openstack']['identity']['token_flush_cron']['day'] + weekday node['openstack']['identity']['token_flush_cron']['weekday'] + action should_run_cron ? :create : :delete + user node['openstack']['identity']['user'] + command %Q{ + `which keystone-manage` token_flush > #{log_file} 2>&1 && + echo keystone-manage token_flush ran at $(/bin/date) with exit code $? >> #{log_file} + }.gsub!(/\n/, '') +end +# TODO(luisg): We can remove the \n substitution in the cron command when https://tickets.opscode.com/browse/CHEF-5238 is fixed diff --git a/spec/server_spec.rb b/spec/server_spec.rb index 882a1b1..d6d4f43 100644 --- a/spec/server_spec.rb +++ b/spec/server_spec.rb @@ -68,6 +68,19 @@ describe 'openstack-identity::server' do 'execute[Keystone: sleep]').to(:run) end + it 'has flush tokens cronjob running every day at 3:30am' do + expect(chef_run).to create_cron('keystone-manage-token-flush').with_command(/`which keystone-manage` token_flush/) + expect(chef_run).to create_cron('keystone-manage-token-flush').with_minute('0') + expect(chef_run).to create_cron('keystone-manage-token-flush').with_hour('*') + expect(chef_run).to create_cron('keystone-manage-token-flush').with_day('*') + expect(chef_run).to create_cron('keystone-manage-token-flush').with_weekday('*') + end + + it 'deletes flush tokens cronjob when tokens backend is not sql' do + node.set['openstack']['identity']['token']['backend'] = 'notsql' + expect(chef_run).to delete_cron('keystone-manage-token-flush') + end + describe '/etc/keystone' do let(:dir) { chef_run.directory('/etc/keystone') }