class Chef::Knife::DataBagSync

DataBagSync class rubocop:disable Metrics/ClassLength

Public Instance Methods

compare(chef_data_bag, local_data_bag) click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 52
def compare(chef_data_bag, local_data_bag)
  chef_data_bag.each do |item, data|
    if local_data_bag.key?(item)
      compare_item(item, data, local_data_bag[item])
    else
      ui.error("Data bag item '#{item}' could not be locally found")
    end
  end
end
compare_item(item, chef_item, local_item) click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 62
def compare_item(item, chef_item, local_item)
  msg = "Item '#{item}':".ljust(50)
  opts = config[:abbrev] ? {} : { array_path: true }
  diff = ::HashDiff.diff(chef_item, local_item, opts)
  diff.empty? ? show_success(msg) : show_error(msg, diff)
end
data_bag_from_chef(data_bag) click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 69
def data_bag_from_chef(data_bag)
  items = find_chef_data_bag_items(data_bag)
  if items.empty?
    ui.error("No items founded in chef data bag '#{data_bag}'")
  end
  items
rescue Net::HTTPServerException
  ui.error("Data bag '#{data_bag}' could not be found on chef server")
  {}
end
data_bag_from_file(data_bag, list) click to toggle source

rubocop:disable Metrics/MethodLength

# File lib/chef/knife/data_bag_sync.rb, line 86
def data_bag_from_file(data_bag, list)
  items = nil
  data_bag_path.map do |data_bag_path|
    path = File.join(data_bag_path, data_bag)
    next unless File.directory?(path)

    items = find_local_data_bag_items(path, list)
    if items.empty?
      ui.error("No items founded in local data bag '#{data_bag}'")
    end
  end

  if items.nil?
    ui.error("Data bag '#{data_bag}' could not be locally found")
    items = {}
  end
  items
end
data_bag_item_from_chef(data_bag, item) click to toggle source

rubocop:enable Metrics/MethodLength

# File lib/chef/knife/data_bag_sync.rb, line 106
def data_bag_item_from_chef(data_bag, item)
  data_bag_item = Chef::DataBagItem.load(data_bag, item).raw_data
  if encrypted?(data_bag_item) && secret
    data_bag_item =
      Chef::EncryptedDataBagItem.load(data_bag, item, secret).to_h
  end
  data_bag_item
rescue Net::HTTPServerException
  ui.error("Item '#{item}' could not be found on chef server")
  nil
end
data_bag_item_from_file(data_bag_path, item) click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 118
def data_bag_item_from_file(data_bag_path, item)
  path = Pathname.new(data_bag_path)
  data = loader.load_from(path.parent, File.basename(path), item)
  encrypted?(data) ? decrypt(item, data) : data
rescue SystemExit
  ui.error("Data bag item #{item} could not be loaded")
  nil
end
data_bag_path() click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 80
def data_bag_path
  config_path = Chef::Config[:data_bag_path]
  config_path.is_a?(String) ? [config_path] : config_path
end
decrypt(name, data) click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 127
def decrypt(name, data)
  if secret
    Chef::EncryptedDataBagItem.new(data, secret).to_hash
  else
    ui.warn(
      "Data bag item '#{name}' is encrypted, but no secret provided " \
      'for decoding (will be ignored)'
    )
    nil
  end
end
find_chef_data_bag_items(data_bag) click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 139
def find_chef_data_bag_items(data_bag)
  Chef::DataBag.load(data_bag).to_hash.map do |item, _|
    [item, data_bag_item_from_chef(data_bag, item)]
  end.to_h
end
find_local_data_bag_items(data_bag_path, list) click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 145
def find_local_data_bag_items(data_bag_path, list)
  items = {}
  ::Find.find(data_bag_path) do |path|
    item = File.basename(path, File.extname(path))
    if File.file?(path) && list.include?(item)
      items[item] = data_bag_item_from_file(data_bag_path, path)
    end
  end
  items.compact
end
loader() click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 48
def loader
  @loader ||= Core::ObjectLoader.new(Chef::DataBagItem, ui)
end
run() click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 156
def run
  case @name_args.length
  when 0
    sync_data_bags(Chef::DataBag.list.keys)
  when 1
    sync_data_bags(@name_args)
  when 2
    sync_item(@name_args[0], @name_args[1])
  end
end
secret() click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 167
def secret
  encryption_secret_provided_ignore_encrypt_flag? ? read_secret : nil
end
show_error(msg, diff) click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 175
def show_error(msg, diff)
  ui.info(msg + ui.color('difference(s) found', :yellow))
  pp(diff) if config[:diff]
end
show_success(msg) click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 171
def show_success(msg)
  ui.info(msg + ui.color('properly synchronized.', :green))
end
sync_data_bags(data_bags) click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 180
def sync_data_bags(data_bags)
  data_bags.each do |data_bag|
    ui.info("--> Checking data bag '#{data_bag}'")
    chef_data_bag = data_bag_from_chef(data_bag)
    msg = "No items founded in chef data bag '#{data_bag}'"
    next ui.error(msg) if chef_data_bag.empty?

    local_data_bag = data_bag_from_file(data_bag, chef_data_bag.keys)
    next if local_data_bag.empty?

    compare(chef_data_bag, local_data_bag)
  end
end
sync_item(data_bag, item) click to toggle source
# File lib/chef/knife/data_bag_sync.rb, line 194
def sync_item(data_bag, item)
  ui.info("-> Checking item '#{item}' from data bag '#{data_bag}'")
  chef_item = data_bag_item_from_chef(data_bag, item)
  local_item = data_bag_from_file(data_bag, [item])
  if local_item.empty?
    ui.error("Data bag item '#{item}' could not be locally found")
  else
    compare_item(item, chef_item, local_item[item])
  end
end