Created
November 21, 2012 04:39
-
-
Save aaronjensen/4123044 to your computer and use it in GitHub Desktop.
Edit encrypted data bags for use with chef-solo and knife-solo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
Dir.chdir File.join(__FILE__, "../..") | |
unless ENV['EDITOR'] | |
puts "No EDITOR found. Try:" | |
puts "export EDITOR=vim" | |
exit 1 | |
end | |
unless ARGV.count == 2 | |
puts "usage: #{$0} <data bag> <item name>" | |
exit 1 | |
end | |
require 'chef/encrypted_data_bag_item' | |
require 'json' | |
require 'tempfile' | |
data_bag = ARGV[0] | |
item_name = ARGV[1] | |
encrypted_path = "data_bags/#{data_bag}/#{item_name}.json" | |
unless File.exists? encrypted_path | |
puts "Cannot find #{File.join(Dir.pwd, encrypted_path)}" | |
exit 1 | |
end | |
data_bag_key_path = File.join(Dir.pwd, "data_bag_key") | |
unless File.exists? data_bag_key_path | |
puts "Get the data_bag_key and put it in #{data_bag_key_path}." | |
exit 1 | |
end | |
secret = Chef::EncryptedDataBagItem.load_secret('data_bag_key') | |
decrypted_file = Tempfile.new ["#{data_bag}_#{item_name}",".json"] | |
at_exit { decrypted_file.delete } | |
encrypted_data = JSON.parse(File.read(encrypted_path)) | |
plain_data = Chef::EncryptedDataBagItem.new(encrypted_data, secret).to_hash | |
decrypted_file.puts JSON.pretty_generate(plain_data) | |
decrypted_file.close | |
system "#{ENV['EDITOR']} #{decrypted_file.path}" | |
plain_data = JSON.parse(File.read(decrypted_file.path)) | |
encrypted_data = Chef::EncryptedDataBagItem.encrypt_data_bag_item(plain_data, secret) | |
File.write encrypted_path, JSON.pretty_generate(encrypted_data) |
Yep, great script - thanks
Indeed, most handy. I've adapted the core of this into a Rake task for my company's ops project. Thank you!
+1 - simple solution, thanks :)
Thank you man, really appreciate it. As you know Chef doesn't provide a method to iterate over data bag items' attributes. Running something like this was the only way to save a data bag item to a (temporary) json file. As a reference for those non-ruby guys who want to use this in a Chef recipe:
# load my secret key from a path specified in a Chef attribute
secret_key = Chef::EncryptedDataBagItem.load_secret("#{node[:my_repo_name][:secret_key_file_path]}")
# use the ruby_block statement to run arbitrary Ruby code in the Chef DSL
ruby_block "decrypt passwords" do
block do
encrypted_path = "/home/me/data_bags/secrets/passwords.json"
encrypted_data = JSON.parse(File.read(encrypted_path))
plain_data = Chef::EncryptedDataBagItem.new(encrypted_data, secret_key).to_hash
File.open('/opt/me/passwords.json', 'w') { |f|
f.write(JSON.pretty_generate(plain_data))
}
end
end
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thats awesome! Works like a charm. THX.