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:
parent
1a3c689d6d
commit
092ddc9571
|
@ -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
|
Libraries
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,13 @@ default['openstack']['developer_mode'] = false
|
||||||
# node['openstack']['secret'][key][type]
|
# node['openstack']['secret'][key][type]
|
||||||
default['openstack']['use_databags'] = true
|
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)
|
# Default attributes when not using data bags (use_databags = false)
|
||||||
%w{block-storage object-storage compute database dashboard image identity
|
%w{block-storage object-storage compute database dashboard image identity
|
||||||
telemetry network object-storage orchestration}.each do |service|
|
telemetry network object-storage orchestration}.each do |service|
|
||||||
|
|
|
@ -56,12 +56,28 @@ module ::Openstack # rubocop:disable Documentation
|
||||||
|
|
||||||
return (node['openstack']['secret'][index] || index)
|
return (node['openstack']['secret'][index] || index)
|
||||||
end
|
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']
|
key_path = node['openstack']['secret']['key_path']
|
||||||
::Chef::Log.info "Loading encrypted databag #{bag_name}.#{index} using key at #{key_path}"
|
::Chef::Log.info "Loading encrypted databag #{bag_name}.#{index} using key at #{key_path}"
|
||||||
secret = ::Chef::EncryptedDataBagItem.load_secret key_path
|
secret = ::Chef::EncryptedDataBagItem.load_secret key_path
|
||||||
::Chef::EncryptedDataBagItem.load(bag_name, index, secret)[index]
|
::Chef::EncryptedDataBagItem.load(bag_name, index, secret)[index]
|
||||||
end
|
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
|
# Ease-of-use/standarization routine that returns a secret from the
|
||||||
# attribute-specified openstack secrets databag.
|
# attribute-specified openstack secrets databag.
|
||||||
def get_secret(key)
|
def get_secret(key)
|
||||||
|
|
|
@ -11,7 +11,7 @@ describe 'openstack-common::default' do
|
||||||
|
|
||||||
include_context 'library-stubs'
|
include_context 'library-stubs'
|
||||||
|
|
||||||
context 'stored in data bags by default' do
|
context 'stored in encrypted data bags by default' do
|
||||||
describe '#secret' do
|
describe '#secret' do
|
||||||
it 'returns databag' do
|
it 'returns databag' do
|
||||||
value = { 'nova' => 'this' }
|
value = { 'nova' => 'this' }
|
||||||
|
@ -63,6 +63,53 @@ describe 'openstack-common::default' do
|
||||||
end
|
end
|
||||||
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
|
context 'stored in attributes as an alternative' do
|
||||||
before { node.set['openstack']['use_databags'] = false }
|
before { node.set['openstack']['use_databags'] = false }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue