allow unencrypted databags for storing secrets.

This will allow for easier storage of secrets for CI/dev type
environments as well as providing working unencrypted examples
of how the databags should be structured.

Documented that this should not be used for real
secrets.

Change-Id: I903086bea72fdcf76996fd5ebf98c552002de223
This commit is contained in:
Paul Czarkowski 2014-07-01 11:07:23 -05:00
parent 1a3c689d6d
commit 092ddc9571
4 changed files with 80 additions and 1 deletions

View File

@ -97,6 +97,15 @@ the entries to `/etc/sysctl.d/60-openstack.conf`.
]
```
Data Bags
=========
This cookbook containes Libraries to work with passwords and secrets in databags. Databags can be unencrypted ( for dev ) or encrypted ( for prod ).
Documentation for Attributes for selecting databag format can be found in the attributes section of this cookbook.
Documentation for format of these Databags can be found in the [Openstack Chef Repo](https://github.com/stackforge/openstack-chef-repo#databags) repository.
Libraries
=========

View File

@ -44,6 +44,13 @@ default['openstack']['developer_mode'] = false
# node['openstack']['secret'][key][type]
default['openstack']['use_databags'] = true
# Set databag type
# acceptable values 'encrypted', 'standard'
# Set this to 'standard' in order to use regular databags.
# this is not recommended for anything other than dev/CI
# type environments. Storing real secrets in plaintext = craycray.
default['openstack']['databag_type'] = 'encrypted'
# Default attributes when not using data bags (use_databags = false)
%w{block-storage object-storage compute database dashboard image identity
telemetry network object-storage orchestration}.each do |service|

View File

@ -56,12 +56,28 @@ module ::Openstack # rubocop:disable Documentation
return (node['openstack']['secret'][index] || index)
end
case node['openstack']['databag_type']
when 'encrypted'
encrypted_secret(bag_name, index)
when 'standard'
standard_secret(bag_name, index)
else
::Chef::Log.error("Unsupported value for node['openstack']['databag_type']")
end
end
def encrypted_secret(bag_name, index)
key_path = node['openstack']['secret']['key_path']
::Chef::Log.info "Loading encrypted databag #{bag_name}.#{index} using key at #{key_path}"
secret = ::Chef::EncryptedDataBagItem.load_secret key_path
::Chef::EncryptedDataBagItem.load(bag_name, index, secret)[index]
end
def standard_secret(bag_name, index)
::Chef::Log.info "Loading databag #{bag_name}.#{index}"
::Chef::DataBagItem.load(bag_name, index)[index]
end
# Ease-of-use/standarization routine that returns a secret from the
# attribute-specified openstack secrets databag.
def get_secret(key)

View File

@ -11,7 +11,7 @@ describe 'openstack-common::default' do
include_context 'library-stubs'
context 'stored in data bags by default' do
context 'stored in encrypted data bags by default' do
describe '#secret' do
it 'returns databag' do
value = { 'nova' => 'this' }
@ -63,6 +63,53 @@ describe 'openstack-common::default' do
end
end
context 'stored in standard data bags' do
before { node.set['openstack']['databag_type'] = 'standard' }
describe '#secret' do
it 'returns databag' do
value = { 'nova' => 'this' }
::Chef::DataBagItem.stub(:load).with('passwords', 'nova').and_return(value)
expect(subject.secret('passwords', 'nova')).to eq('this')
end
end
describe '#get_secret' do
it 'returns databag value' do
value = { 'nova' => 'this' }
::Chef::DataBagItem.stub(:load).with('secrets', 'nova').and_return(value)
expect(subject.get_secret('nova')).to eq('this')
end
it 'returns secret from an alternate databag when secrets_data_bag set' do
node.set['openstack']['secret']['secrets_data_bag'] = 'myothersecrets'
value = { 'nova' => 'this' }
::Chef::DataBagItem.stub(:load).with('myothersecrets', 'nova').and_return(value)
expect(subject.get_secret('nova')).to eq('this')
end
end
describe '#get_password' do
['service', 'db', 'user'].each do |type|
it "returns databag value for #{type}" do
value = { 'nova' => 'this' }
::Chef::DataBagItem.stub(:load).with("#{type}_passwords", 'nova').and_return(value)
expect(subject.get_password(type, 'nova')).to eq('this')
end
end
it 'returns nil for an invalid type' do
expect(subject.get_password('invalid_type', 'nova')).to be_nil
end
it 'returns tokens from the secrets_data_bag' do
bag_content = { 'nova' => 'mysecret' }
::Chef::DataBagItem.stub(:load).with(
'secrets', 'nova').and_return(bag_content)
expect(subject.get_password('token', 'nova')).to eq('mysecret')
end
end
end
context 'stored in attributes as an alternative' do
before { node.set['openstack']['use_databags'] = false }