Adds encrypted databag secret support
* Adds ::Openstack::secret library routine to return decrypted databag values or supplied parameter values when in developer_mode * Adds documentation on library routine to README * Adds unit tests for secret to specs/
This commit is contained in:
parent
17bea73749
commit
4241aa3b5c
57
README.md
57
README.md
|
@ -17,6 +17,63 @@ of all the settable attributes for this cookbook.
|
|||
|
||||
Note that all attributes are in the `default["openstack"]` "namespace"
|
||||
|
||||
Libraries
|
||||
=========
|
||||
|
||||
This cookbook exposes a set of default library routines:
|
||||
|
||||
* `endpoint` -- Used to return a `::URI` object representing the named OpenStack endpoint
|
||||
* `endpoints` -- Useful for operating on all OpenStack endpoints
|
||||
* `db` -- Returns a Hash of information about a named OpenStack database
|
||||
* `db_uri` -- Returns the SQLAlchemy RFC-1738 DB URI (see: http://rfc.net/rfc1738.html) for a named OpenStack database
|
||||
* `db_create_with_user` -- Creates a database and database user for a named OpenStack database
|
||||
* `secret` -- Returns the value of an encrypted data bag for a named OpenStack secret key and key-section
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
The following are code examples showing the above library routines in action.
|
||||
Remember when using the library routines exposed by this library to include
|
||||
the Openstack routines in your recipe's `::Chef::Recipe` namespace, like so:
|
||||
|
||||
```ruby
|
||||
class ::Chef::Recipe
|
||||
include ::Openstack
|
||||
end
|
||||
```
|
||||
|
||||
Example of using the `endpoint` routine:
|
||||
|
||||
```ruby
|
||||
nova_api_ep = endpoint "compute-api"
|
||||
::Chef::Log.info("Using Openstack Compute API endpoint at #{nova_api_ep.to_s}")
|
||||
|
||||
# Note that endpoint URIs may contain variable interpolation markers such
|
||||
# as `%(tenant_id)s`, so you may need to decode them. Do so like this:
|
||||
|
||||
require "uri"
|
||||
|
||||
puts ::URI.decode nova_api_ap.to_s
|
||||
```
|
||||
|
||||
Example of using the `secret` and `db\_uri` routine:
|
||||
|
||||
```ruby
|
||||
db_pass = secret "passwords", "cinder"
|
||||
db_user = node["cinder"]["db"]["user"]
|
||||
sql_connection = db_uri "volume", db_user, db_pass
|
||||
|
||||
template "/etc/cinder/cinder.conf" do
|
||||
source "cinder.conf.erb"
|
||||
owner node["cinder"]["user"]
|
||||
group node["cinder"]["group"]
|
||||
mode 00644
|
||||
variables(
|
||||
"sql_connection" => sql_connection
|
||||
)
|
||||
end
|
||||
```
|
||||
|
||||
Testing
|
||||
=====
|
||||
|
||||
|
|
|
@ -17,6 +17,24 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
# Setting this to True means that database passwords and service user
|
||||
# passwords for Keystone will be easy-to-remember values -- they will be
|
||||
# the same value as the key. For instance, if a cookbook calls the
|
||||
# ::Openstack::secret routine like so:
|
||||
#
|
||||
# pass = secret "passwords", "nova"
|
||||
#
|
||||
# The value of pass will be "nova"
|
||||
default["openstack"]["developer_mode"] = false
|
||||
|
||||
# ========================= Encrypted Databag Setup ===========================
|
||||
#
|
||||
# The openstack-common cookbook's default library contains a `secret`
|
||||
# routine that looks up the value of encrypted databag values. This routine
|
||||
# uses the secret key file located at the following location to decrypt the
|
||||
# values in the data bag.
|
||||
default["openstack"]["secret"]["key_path"] = "/etc/chef/openstack_data_bag_secret"
|
||||
|
||||
# ========================= Package and Repository Setup ======================
|
||||
#
|
||||
# Various Linux distributions provide OpenStack packages and repositories.
|
||||
|
@ -188,12 +206,11 @@ default['openstack']['endpoints']['volume-api']['path'] = "/v1/%(tenant_id)s"
|
|||
# attributes:
|
||||
#
|
||||
# node['db']['user'] = 'keystone'
|
||||
# node['db']['password'] = 'password'
|
||||
#
|
||||
# In a "keystone" recipe, you might find the following code:
|
||||
#
|
||||
# user = node['db']['user']
|
||||
# pass = node['db']['password']
|
||||
# pass = secret 'passwords', 'keystone'
|
||||
#
|
||||
# sql_connection = ::Openstack::db_uri('identity', user, pass)
|
||||
#
|
||||
|
|
|
@ -146,6 +146,34 @@ module ::Openstack
|
|||
info
|
||||
end
|
||||
|
||||
# Library routine that returns an encrypted data bag value
|
||||
# for a supplied string. The key used in decrypting the
|
||||
# encrypted value should be located at
|
||||
# node["openstack"]["secret"]["key_path"].
|
||||
#
|
||||
# Note that if node["openstack"]["developer_mode"] is true,
|
||||
# then the value of the index parameter is just returned as-is. This
|
||||
# means that in developer mode, if a cookbook does this:
|
||||
#
|
||||
# class Chef
|
||||
# class Recipe
|
||||
# include ::Openstack
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# nova_password = secret "passwords", "nova"
|
||||
#
|
||||
# That means nova_password will == "nova".
|
||||
def secret section, index
|
||||
if node["openstack"]["developer_mode"]
|
||||
return index
|
||||
end
|
||||
bag_name = node["openstack"]["secret"]["bag_name"]
|
||||
key_path = node["openstack"]["secret"]["key_path"]
|
||||
::Chef::Log.info("Loading encrypted databag #{section}.#{index} using key at #{key_path}")
|
||||
::Chef::EncryptedDataBagItem.load(section, index, key_path)
|
||||
end
|
||||
|
||||
private
|
||||
# Instead of specifying the verbose node["openstack"]["endpoints"][name],
|
||||
# this shortcut allows the simpler and shorter endpoint(name)
|
||||
|
|
|
@ -173,4 +173,23 @@ describe ::Openstack do
|
|||
result['port'].should eq "3306"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#secret" do
|
||||
it "returns index param when developer_mode is true" do
|
||||
@chef_run = ::ChefSpec::ChefRunner.new(:log_level => :info) do |n|
|
||||
n.set["openstack"]["developer_mode"] = true
|
||||
end
|
||||
@chef_run.converge "openstack-common::default"
|
||||
@subject.stub(:node).and_return @chef_run.node
|
||||
result = @subject.secret("passwords", "nova")
|
||||
result.should eq "nova"
|
||||
end
|
||||
it "returns databag when developer_mode is false" do
|
||||
value = "this"
|
||||
::Chef::EncryptedDataBagItem.stub(:load).with("passwords", "nova", "/etc/chef/openstack_data_bag_secret").and_return value
|
||||
@subject.stub(:node).and_return @chef_run.node
|
||||
result = @subject.secret("passwords", "nova")
|
||||
result.should eq value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue