Skip to content

Instantly share code, notes, and snippets.

@jtimberman
Created April 11, 2012 13:53
Show Gist options
  • Save jtimberman/2359433 to your computer and use it in GitHub Desktop.
Save jtimberman/2359433 to your computer and use it in GitHub Desktop.
Load data bag items from Ruby DSL files
# Put this in ~/chef-repo/data_bags/aws/main.rb
# Upload it to the Chef Server with:
#
# knife data bag item rb aws main.rb
#
# Export the two AWS values for your account.
{
'id' => "main",
'aws_access_key_id' => ENV['AWS_ACCESS_KEY_ID'],
'aws_secret_access_key' => ENV['AWS_SECRET_ACCESS_KEY']
}
# File:: ~/chef-repo/.chef/plugins/knife/data_bag_from_file_rb.rb
#
# Author:: Joshua Timberman <joshua@opscode.com>
# Copyright:: Copyright (c) 2011, Opscode, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/knife'
module KnifePlugins
class DataBagItemRb < Chef::Knife
deps do
require 'chef/data_bag_item'
end
banner "knife data bag item rb BAG FILE (options)"
category "data bag"
option :secret,
:short => "-s SECRET",
:long => "--secret ",
:description => "The secret key to use to encrypt data bag item values"
option :secret_file,
:long => "--secret-file SECRET_FILE",
:description => "A file containing the secret key to use to encrypt data bag item values"
def read_secret
if config[:secret]
config[:secret]
else
Chef::EncryptedDataBagItem.load_secret(config[:secret_file])
end
end
def use_encryption
if config[:secret] && config[:secret_file]
ui.fatal("please specify only one of --secret, --secret-file")
exit(1)
end
config[:secret] || config[:secret_file]
end
def run
bag_name, item_file = @name_args[0], @name_args[1]
item = eval(IO.read(File.join("data_bags", bag_name, item_file)))
item = if use_encryption
secret = read_secret
Chef::EncryptedDataBagItem.encrypt_data_bag_item(item, secret)
else
item
end
dbag = Chef::DataBagItem.new
dbag.data_bag(bag_name)
dbag.raw_data = item
dbag.save
ui.msg("Updated data_bag_item[#{dbag.data_bag}::#{dbag.id}]")
end
end
end
@glenbot
Copy link

glenbot commented May 10, 2012

Thank you for this! Although, there is a dependency missing require 'chef/encrypted_data_bag_item'. If you pass secret-file it errors out, the patch below fixes it. Thanks again!!!

    deps do
      require 'chef/data_bag_item'
      require 'chef/encrypted_data_bag_item'
    end

@kjwierenga
Copy link

To allow a databag with symbols

{
  :id => 'my_item',
  :staging => { :key => 'staging value' },
  :production => { :key => 'production value' }
}

I patched line 66 to create a Mash from item

  dbag.raw_data = Mash.from_hash(item)

I know Mash hash questionable semantics, but I prefer the symbol notation.

@ekrupnik
Copy link

Is there a specific reason you know of for why this would not have been added to core Chef data bag functionality? It seems like having the ability to have a data bag item in Ruby would be:

  1. Consistent with roles and environments, both of which allow either .json or .rb formats
  2. Beneficial because Ruby supports comments, if you wanted to document something in-line

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment