Added chef-vault as option to store secrets
*Added gem chef-vault to gemfile *Added method to decrypt chef-vault items *Added case for ['openstack']['databag_type'] = 'vault' *Added version for ['openstack']['vault_gem_version'] = '~> 2.3' *Moved ::Chef.log.warn for developer_mode from method 'secret' to private method 'dev_secret' to refactore and shrink the method 'secret' *Added link to opscode chef-vault documentation Change-Id: Icda0e288bbb920498aba856fefaf04c0f1852787
This commit is contained in:
parent
0655583c91
commit
794cc3d461
1
Gemfile
1
Gemfile
@ -10,3 +10,4 @@ gem 'foodcritic', '~> 4.0'
|
|||||||
gem 'strainer'
|
gem 'strainer'
|
||||||
gem 'rubocop', '~> 0.18.1'
|
gem 'rubocop', '~> 0.18.1'
|
||||||
gem 'rake', '~> 10.0'
|
gem 'rake', '~> 10.0'
|
||||||
|
gem 'chef-vault', '~> 2.3'
|
||||||
|
@ -102,7 +102,7 @@ the entries to `/etc/sysctl.d/60-openstack.conf`.
|
|||||||
Data Bags
|
Data Bags
|
||||||
=========
|
=========
|
||||||
|
|
||||||
This cookbook containes Libraries to work with passwords and secrets in databags. Databags can be unencrypted ( for dev ) or encrypted ( for prod ).
|
This cookbook containes Libraries to work with passwords and secrets in databags. Databags can be unencrypted ( for dev ) or encrypted ( for prod ). In addition to traditionally encrypted data bags they can also be created as chef-vault items. To read more about chef-vault and how to use it, go to https://docs.getchef.com/chef_vault.html.
|
||||||
|
|
||||||
Documentation for Attributes for selecting databag format can be found in the attributes section of this cookbook.
|
Documentation for Attributes for selecting databag format can be found in the attributes section of this cookbook.
|
||||||
|
|
||||||
|
@ -45,11 +45,15 @@ default['openstack']['developer_mode'] = false
|
|||||||
default['openstack']['use_databags'] = true
|
default['openstack']['use_databags'] = true
|
||||||
|
|
||||||
# Set databag type
|
# Set databag type
|
||||||
# acceptable values 'encrypted', 'standard'
|
# acceptable values 'encrypted', 'standard', 'vault'
|
||||||
# Set this to 'standard' in order to use regular databags.
|
# Set this to 'standard' in order to use regular databags.
|
||||||
# this is not recommended for anything other than dev/CI
|
# this is not recommended for anything other than dev/CI
|
||||||
# type environments. Storing real secrets in plaintext = craycray.
|
# type environments. Storing real secrets in plaintext = craycray.
|
||||||
|
# In addition to the encrypted data_bags which are an included
|
||||||
|
# feature of the official chef project, you can use 'vault' to
|
||||||
|
# encrypt your secrets with the method provided in the chef-vault gem.
|
||||||
default['openstack']['databag_type'] = 'encrypted'
|
default['openstack']['databag_type'] = 'encrypted'
|
||||||
|
default['openstack']['vault_gem_version'] = '~> 2.3'
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -47,24 +47,23 @@ module ::Openstack # rubocop:disable Documentation
|
|||||||
# nova_password = secret 'passwords', 'nova'
|
# nova_password = secret 'passwords', 'nova'
|
||||||
#
|
#
|
||||||
# The nova_password will == 'nova_password'
|
# The nova_password will == 'nova_password'
|
||||||
|
|
||||||
def secret(bag_name, index)
|
def secret(bag_name, index)
|
||||||
if node['openstack']['developer_mode']
|
if node['openstack']['developer_mode']
|
||||||
::Chef::Log.warn(
|
dev_secret(index)
|
||||||
"Developer mode for reading passwords is DEPRECATED and will "\
|
else
|
||||||
"be removed. Please use attributes (and the get_password method) "\
|
|
||||||
"instead.")
|
|
||||||
|
|
||||||
return (node['openstack']['secret'][index] || index)
|
|
||||||
end
|
|
||||||
case node['openstack']['databag_type']
|
case node['openstack']['databag_type']
|
||||||
when 'encrypted'
|
when 'encrypted'
|
||||||
encrypted_secret(bag_name, index)
|
encrypted_secret(bag_name, index)
|
||||||
when 'standard'
|
when 'standard'
|
||||||
standard_secret(bag_name, index)
|
standard_secret(bag_name, index)
|
||||||
|
when 'vault' # chef-vault, by convention use "vault_<bag_name>" as bag_name
|
||||||
|
vault_secret('vault_' + bag_name, index)
|
||||||
else
|
else
|
||||||
::Chef::Log.error("Unsupported value for node['openstack']['databag_type']")
|
::Chef::Log.error("Unsupported value for node['openstack']['databag_type']")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def encrypted_secret(bag_name, index)
|
def encrypted_secret(bag_name, index)
|
||||||
key_path = node['openstack']['secret']['key_path']
|
key_path = node['openstack']['secret']['key_path']
|
||||||
@ -78,6 +77,16 @@ module ::Openstack # rubocop:disable Documentation
|
|||||||
::Chef::DataBagItem.load(bag_name, index)[index]
|
::Chef::DataBagItem.load(bag_name, index)[index]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def vault_secret(bag_name, index)
|
||||||
|
begin
|
||||||
|
require 'chef-vault'
|
||||||
|
rescue LoadError
|
||||||
|
Chef::Log.warn("Missing gem 'chef-vault'")
|
||||||
|
end
|
||||||
|
::Chef::Log.info "Loading vault secret #{index} from #{bag_name}"
|
||||||
|
::ChefVault::Item.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)
|
||||||
@ -115,4 +124,14 @@ module ::Openstack # rubocop:disable Documentation
|
|||||||
node['openstack']['secret'][key][type]
|
node['openstack']['secret'][key][type]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def dev_secret(index)
|
||||||
|
::Chef::Log.warn(
|
||||||
|
'Developer mode for reading passwords is DEPRECATED and will '\
|
||||||
|
'be removed. Please use attributes (and the get_password method) '\
|
||||||
|
'instead.')
|
||||||
|
(node['openstack']['secret'][index] || index)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -103,3 +103,9 @@ when 'suse'
|
|||||||
not_if { Mixlib::ShellOut.new('zypper repos --export -').run_command.stdout.include? repo_uri }
|
not_if { Mixlib::ShellOut.new('zypper repos --export -').run_command.stdout.include? repo_uri }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if node['openstack']['databag_type'] == 'vault'
|
||||||
|
chef_gem 'chef-vault' do
|
||||||
|
version node['openstack']['vault_gem_version']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@ -30,5 +30,16 @@ describe 'openstack-common::default' do
|
|||||||
uri: 'http://ubuntu-cloud.archive.canonical.com/ubuntu',
|
uri: 'http://ubuntu-cloud.archive.canonical.com/ubuntu',
|
||||||
components: ['precise-updates/juno', 'main'])
|
components: ['precise-updates/juno', 'main'])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'does not install the gem chef-vault by default' do
|
||||||
|
expect(chef_run).to_not install_chef_gem('chef-vault')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'installs the gem chef-vault if databag_type is vault' do
|
||||||
|
node.set['openstack']['databag_type'] = 'vault'
|
||||||
|
expect(chef_run).to install_chef_gem('chef-vault')
|
||||||
|
.with(version: '~> 2.3')
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
require_relative 'spec_helper'
|
require_relative 'spec_helper'
|
||||||
require ::File.join ::File.dirname(__FILE__), '..', 'libraries', 'passwords'
|
require ::File.join ::File.dirname(__FILE__), '..', 'libraries', 'passwords'
|
||||||
|
require 'chef-vault'
|
||||||
|
|
||||||
describe 'openstack-common::default' do
|
describe 'openstack-common::default' do
|
||||||
describe 'Passwords' do
|
describe 'Passwords' do
|
||||||
@ -21,6 +22,17 @@ describe 'openstack-common::default' do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'using chef-vault' do
|
||||||
|
before do
|
||||||
|
node.set['openstack']['databag_type'] = 'vault'
|
||||||
|
end
|
||||||
|
it 'returns the data from a chef vault item' do
|
||||||
|
allow(ChefVault::Item).to receive(:load).with('vault_passwords', 'nova')
|
||||||
|
.and_return('nova' => 'novapassword')
|
||||||
|
expect(subject.secret('passwords', 'nova')).to eq('novapassword')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#get_secret' do
|
describe '#get_secret' do
|
||||||
it 'returns databag value' do
|
it 'returns databag value' do
|
||||||
value = { 'nova' => 'this' }
|
value = { 'nova' => 'this' }
|
||||||
|
Loading…
Reference in New Issue
Block a user