class BetweenMeals::Knife

Knife does not have a usable API for using it as a lib This could be possibly refactored to touch its internals instead of shelling out

Attributes

cookbook_dirs[RW]

Public Class Methods

new(opts = {}) click to toggle source
# File lib/between_meals/knife.rb, line 31
def initialize(opts = {})
  @logger = opts[:logger] || nil
  @user = opts[:user] || ENV['USER']
  @home = opts[:home] || ENV['HOME']
  # make sure people can pass in false :)
  @ssl = opts[:ssl].nil? ? true : opts[:ssl]
  @host = opts[:host] || 'localhost'
  @port = opts[:port] || 4000
  @config = opts[:config] ||
            "#{@home}/.chef/knife-#{@user}-taste-tester.rb"
  @knife = opts[:bin] || 'knife'
  @knife_verb_option = ''
  unless @logger.nil?
    if @logger.level == Logger::DEBUG
      @knife_verb_option = '-VV'
    elsif @logger.level == Logger::INFO
      @knife_verb_option = '-V'
    end
  end
  @berks = opts[:berks_bin] || 'berks'
  @berks_config = opts[:berks_config]
  @pem = opts[:pem] ||
         "#{@home}/.chef/#{@user}-taste-tester.pem"
  @role_dir = opts[:role_dir]
  @role_type = opts[:role_type] || 'rb'
  @cookbook_dirs = opts[:cookbook_dirs]
  @databag_dir = opts[:databag_dir]
  @checksum_dir = opts[:checksum_dir]
  @client_key =
    File.expand_path("#{@home}/.chef/#{@user}-taste-tester.pem")
end

Public Instance Methods

berks_cookbook_upload(cookbooks) click to toggle source
# File lib/between_meals/knife.rb, line 117
def berks_cookbook_upload(cookbooks)
  # cookbooks: array
  # cookbook_paths: array
  if @berks_config
    berks_config = '--config=' + @berks_config
  end
  if cookbooks.any?
    @cookbook_dirs.each do |path|
      cookbooks.each do |cb|
        next unless File.exist?("#{path}/#{cb}")

        @logger.warn("Running berkshelf on cookbook: #{cb}")
        exec!("cd #{path}/#{cb} && #{@berks} install #{berks_config} && " +
          "#{@berks} upload #{berks_config}", @logger)
      end
    end
  end
end
berks_cookbook_upload_all() click to toggle source
# File lib/between_meals/knife.rb, line 95
def berks_cookbook_upload_all
  if @berks_config
    berks_config = '--config=' + @berks_config
  end
  @cookbook_dirs.each do |path|
    cookbooks = Dir["#{path}/*"].select { |o| File.directory?(o) }
    cookbooks.each do |cb|
      @logger.warn("Running berkshelf on cookbook: #{cb}")
      exec!("cd #{cb} && #{@berks} install #{berks_config} && " +
        "#{@berks} upload #{berks_config}", @logger)
    end
  end
end
cookbook_delete(cookbooks) click to toggle source
# File lib/between_meals/knife.rb, line 136
def cookbook_delete(cookbooks)
  if cookbooks.any?
    cookbooks.each do |cookbook|
      exec!("#{@knife} cookbook delete #{cookbook.name}" +
              " --purge -a --yes #{@knife_verb_option} -c #{@config}",
            @logger)
    end
  end
end
cookbook_upload(cookbooks) click to toggle source
# File lib/between_meals/knife.rb, line 109
def cookbook_upload(cookbooks)
  if cookbooks.any?
    cookbooks = cookbooks.map(&:name).join(' ')
    exec!("#{@knife} cookbook upload #{cookbooks} #{@knife_verb_option} " +
      "-c #{@config}", @logger)
  end
end
cookbook_upload_all() click to toggle source
# File lib/between_meals/knife.rb, line 90
def cookbook_upload_all
  exec!("#{@knife} cookbook upload -a #{@knife_verb_option} " +
    "-c #{@config}", @logger)
end
databag_delete(databags) click to toggle source
# File lib/between_meals/knife.rb, line 172
def databag_delete(databags)
  if databags.any?
    databags.group_by(&:name).each do |dbname, dbs|
      dbs.each do |db|
        exec!("#{@knife} data bag delete #{dbname} #{db.item}" +
                " --yes #{@knife_verb_option} -c #{@config}", @logger)
      end
      delete_databag_if_empty(dbname)
    end
  end
end
databag_upload(databags) click to toggle source
# File lib/between_meals/knife.rb, line 156
def databag_upload(databags)
  if databags.any?
    databags.group_by(&:name).each do |dbname, dbs|
      create_databag_if_missing(dbname)
      dbitems = dbs.map do |x|
        File.join(@databag_dir, dbname, "#{x.item}.json")
      end.join(' ')
      exec!(
        "#{@knife} data bag from file #{dbname} #{dbitems} " +
        "#{@knife_verb_option} -c #{@config}",
        @logger,
      )
    end
  end
end
databag_upload_all() click to toggle source
# File lib/between_meals/knife.rb, line 146
def databag_upload_all
  glob = File.join(@databag_dir, '*', '*.json')
  items = Dir.glob(glob).map do |file|
    BetweenMeals::Changes::Databag.new(
      { :status => :modified, :path => file }, @databag_dir
    )
  end
  databag_upload(items)
end
role_delete(roles) click to toggle source
# File lib/between_meals/knife.rb, line 81
def role_delete(roles)
  if roles.any?
    roles.each do |role|
      exec!("#{@knife} role delete #{role.name} #{@knife_verb_option} " +
        "--yes -c #{@config}", @logger)
    end
  end
end
role_upload(roles) click to toggle source
# File lib/between_meals/knife.rb, line 71
def role_upload(roles)
  if roles.any?
    roles = roles.map do |x|
      File.join(@role_dir, "#{x.name}.#{@role_type}")
    end.join(' ')
    exec!("#{@knife} role from file #{roles} #{@knife_verb_option} " +
      "-c #{@config}", @logger)
  end
end
role_upload_all() click to toggle source
# File lib/between_meals/knife.rb, line 63
def role_upload_all
  if File.exist?(@role_dir)
    roles = File.join(@role_dir, "*.#{@role_type}")
    exec!("#{@knife} role from file #{roles} #{@knife_verb_option} " +
      "-c #{@config}", @logger)
  end
end
write_user_config() click to toggle source
# File lib/between_meals/knife.rb, line 184
    def write_user_config
      scheme = @ssl ? 'https' : 'http'
      cfg = <<-BLOCK
user = ENV['USER']
log_level :info
log_location STDOUT
node_name user
chef_server_url "#{scheme}://#{@host}:#{@port}"
ssl_verify_mode :verify_none
cache_type 'BasicFile'
client_key '#{@client_key}'
cache_options(:path => File.expand_path("#{@checksum_dir}"))
cookbook_path [
BLOCK
      @cookbook_dirs.each do |dir|
        cfg << "  \"#{dir}\",\n"
      end
      cfg << "]\n"
      begin
        Dir.mkdir(File.dirname(@config), 0o755)
      rescue Errno::EEXIST
        # not an error if it's already there.
        nil
      end
      if !File.exist?(@config) ||
         ::Digest::MD5.hexdigest(cfg) !=
         ::Digest::MD5.hexdigest(File.read(@config))
        @logger.info("Generating #{@config}")
        File.write(@config, cfg)
      end

      # Won't work with shorter keys
      pem = <<-BLOCK
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCs4Ih8+R/2hcYS
tccwJHd0cXHcUibC2wGYmRwf1fKxXLADvfuLRVBHOI5Hgd/ZXF70dowC5mDQ03gr
ouk8e7RL72MCKzPuG2V92sh/FnyKhkNsHCOEKaRRiP9lHVbZkS9LEotCKF7eOkL0
SVkGWx8pVZzrOFmhZgHaOFJ2/2t1irUTRFqTikrRsP2KvnhHdDlnnbUumZWxSuEN
oN6aSAQEOkKbEOLSn/EIMzEb2jtks7L7wkRErajH094jGoZbQvLiwRHDeM0C9uG7
2sdQ45BG9EQOCdBzy1We5keqtJbXBcpwuBa0d1nQZIsGxnDb88+Kmh9h6k9/WmYN
zEQEeSSdAgMBAAECggEATFWQru4p6ObEwTo2y9EuVeJJzmkP6HZfzAu/WWdVFG/C
4MQgsCxY+DnGyVhViVq6KuO1iwpCsbLOmyYCKszMncMESs7czUSXmezjHwrEzz3d
w3zhSdhBUCdX7kP4N3VeFp4Hk5zT1viO2+MPRjkyF0RQV6S4HwY1xy+baiP6RRnS
dGhUYsdz6fjxSkYEQy3/xHm9VLT6ZDV4pN2aA+LOFeveHKcnOjKFCBy4WzkO6fvj
6H3jghxsHXoL7loCHfi9WX3xKjeXG/NjGbUfTH8P7IldUPha+ru/e8W/P+jjE1os
VkScWt08Vu6iTl1EkYeFxOMtSDZxeXNnDkPI0iDQgQKBgQDUMFYncQcZ4uLIfoZq
B+Lx7WJGlIwulOdobnraTd5lsrBHj1sC1+/f4cBSpJwUij2l3GdmmnOpuFAof5eu
mrBGu++5jy+0eIeT5O2d30O8GOBryJ+oAKI2/BPVCmM8d986wl5Esauycb++O7UO
RhpZFOCKbFvlNjhg+CdlvHSl7QKBgQDQkkvpnE//yWmhCPg27n7w3bTg5QPNrzTO
pF2iwvLK4XjRceTeW3P4f42HONzJNnmt5TexM9NbdE9g/exA5uNt59ZB5FeFiKAu
NmVXbmswPX6R/dlyidqzz1guGrL04e0dZehHZBNDr5Sio8IBjMWrpDIxjDJqEwUa
4qCu4e6jcQKBgQDN0FTAzRFmOnxenNsj3aJzpx27+DpAtI4A7aicNwuQ+VGjF5nf
mDRDpGU3xBLgmXZSewaQrx+hb/XQUnJ+Ge0BrylHg2tyUbav7U3N49F/kWGdKmwy
OOsfCkLyUbEP5fXQuNdXKj6wR0UE8EUeI0FLRsTFf3VjTsRAynLsa295wQKBgAo3
QDSfDWQP73aNw+qc3+bYVSW20erfLAz7DAMO3WmGha5sj7M8c3+2b64x4M6SNn+H
/KRXT4DpP4IWrd238WfOtTXhA1BtErtwuqH/rIxeVra74kyz59xqyXzond9UuZJ5
DVmB01e7X+Jfdv8wb/YqQrMelNGRQOzCMPCf7FphAoGAbUh5HzNF2aciQJGA6Qk8
zvgEHqbS0/QkJGOZ+UifPRanTDuGYQkPdHHOER4UghbM+Kz5rZbBicJ3bCyNOsah
IAMAEpsWX2s2A6phgMCx7kH6wMmoZn3hb7Thh9+PfR8Jtp2/7k+ibCeF4gEWUCs5
6wX4GR84dwyhG80yd4TP8Qo=
-----END PRIVATE KEY-----
      BLOCK

      begin
        Dir.mkdir(File.dirname(@pem), 0o755)
      rescue Errno::EEXIST
        # not an error if it's already there.
        nil
      end

      unless File.exist?(@pem)
        @logger.info("Generating #{@pem}")
        File.write(@pem, pem)
      end
    end

Private Instance Methods

create_databag_if_missing(databag) click to toggle source
# File lib/between_meals/knife.rb, line 262
def create_databag_if_missing(databag)
  s = Mixlib::ShellOut.new("#{@knife} data bag list" +
                           " --format json #{@knife_verb_option} " +
                           "-c #{@config}").run_command
  s.error!
  db = JSON.parse(s.stdout)
  unless db.include?(databag)
    exec!("#{@knife} data bag create #{databag} #{@knife_verb_option} " +
      "-c #{@config}", @logger)
  end
end
delete_databag_if_empty(databag) click to toggle source
# File lib/between_meals/knife.rb, line 274
def delete_databag_if_empty(databag)
  s = Mixlib::ShellOut.new("#{@knife} data bag show #{databag}" +
                           " --format json #{@knife_verb_option} " +
                           "-c #{@config}").run_command
  s.error!
  db = JSON.parse(s.stdout)
  if db.empty?
    exec!("#{@knife} data bag delete #{databag} --yes " +
      "#{@knife_verb_option} -c #{@config}", @logger)
  end
end