Skip to content

Instantly share code, notes, and snippets.

@berngp
Created May 21, 2013 17:55
Show Gist options
  • Save berngp/5621821 to your computer and use it in GitHub Desktop.
Save berngp/5621821 to your computer and use it in GitHub Desktop.
Littlechef - Chef Solo Ruby Scripts
#!/usr/bin/env ruby
require 'main'
require 'colored'
Main {
program 'databag'
description <<-hdoc
Longer description of the funcitonality.
hdoc
author '[email protected]'
version '0.0.1'
option('secret', 's'){
argument :optional
defaults "#{ENV['HOME']}/.chefsolo/your-env-deployment/encrypted_data_bag_secret"
description 'Path to the secret used to encrypt the databag.'
}
option('verbose', 'v'){
description "Enables verbose output."
cast :boolean
defaults false
}
option('create', 'c'){
description "Create the file if it doesn't exist."
cast :boolean
defaults false
}
argument('data_bag'){
description 'Databag name.'
argument :required
}
argument('item_name'){
description 'Databag item name.'
argument :required
}
environment('EDITOR'){
defaults 'vim'
synopsis 'export EDITOR=vim'
description 'Default editor used to open the unencrypted file.'
}
def run
require 'chef/encrypted_data_bag_item'
require 'json'
require 'tempfile'
dbag_key = params['secret'] .value
data_bag = params['data_bag'].value
item_name = params['item_name'].value
verbose = params['verbose'].value
create = params['create'].value
editor = params['EDITOR'].value
dbag_path = "data_bags/#{data_bag}"
unless File.exists? dbag_path
puts "Databag #{File.join(Dir.pwd, dbag_path)} is missing, please make sure the directory is there.".red
exit 1
end
encrypted_path = "#{dbag_path}/#{item_name}.json"
unless create or File.exists? encrypted_path
puts "Cannot find #{File.join(Dir.pwd, encrypted_path)}".red
exit 1
end
unless File.exists? dbag_key
puts "File #{dbag_key} is missing!".red
exit 1
end
begin
puts "Loading encrypted data bag item secret from #{dbag_key}" if verbose
secret = Chef::EncryptedDataBagItem.load_secret( dbag_key )
decrypted_file = Tempfile.new ["#{data_bag}_#{item_name}",".json"]
at_exit { decrypted_file.delete }
if File.exists? encrypted_path
puts "Reading encrypted file #{encrypted_path}" if verbose
encrypted_data = JSON.parse(File.read(encrypted_path))
plain_data = Chef::EncryptedDataBagItem.new(encrypted_data, secret).to_hash
else
json_template = <<-eos
{
"id" : "#{item_name}"
}
eos
plain_data = JSON.parse json_template
end
decrypted_file.puts JSON.pretty_generate(plain_data)
decrypted_file.close
system "#{editor} #{decrypted_file.path}"
plain_data = JSON.parse(File.read(decrypted_file.path))
encrypted_data = Chef::EncryptedDataBagItem.encrypt_data_bag_item(plain_data, secret)
puts "Encrypted data \n[#{encrypted_data}]" if verbose
puts "Writing encrypted file #{encrypted_path}" if verbose
File.write encrypted_path, JSON.pretty_generate(encrypted_data)
rescue => e
puts e.message.red
puts e.backtrace if verbose
exit(1)
end
end
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment