module YamlRecrypt

Sourced from github.com/sihil/hiera-eyaml-gpg file: /lib/hiera/backend/eyaml/encryptors/gpg.rb

Constants

BACKUP_EXT
GPG_MAGIC
REAL_PUPPET_DIR

match /etc/puppet and /etc/puppetlabs to protect all customers

VERSION

Public Class Methods

descend(gpg_home, eyaml_pub_key, value) click to toggle source
# File lib/yaml_recrypt.rb, line 46
def self.descend(gpg_home, eyaml_pub_key, value)
  replaced = 0
  if value.class == Array
    i = 0
    value.each { |v|
      begin
        r, subtree  = descend(gpg_home, eyaml_pub_key, v)
        value[i]    = subtree
        replaced    += r
      rescue GPGME::Error::NoData => e
        warn("Invalid GPG data detected in element #{i} or damaged cypher ")
        raise e
      end
      i += 1
    }
  elsif value.class == Hash
    value.each { |k,v|
      begin
        r, subtree  = descend(gpg_home, eyaml_pub_key, v)
        value[k]    = subtree
        replaced    += r
      rescue GPGME::Error::NoData => e
        warn("Invalid GPG data detected in element #{k} or damaged cypher ")
        raise e
      end
    }
  else
    r, value = process_value(value, gpg_home, eyaml_pub_key)
    replaced += r
  end

  return replaced, value
end
process_value(value, gpg_home, eyaml_pub_key) click to toggle source
# File lib/yaml_recrypt.rb, line 80
def self.process_value(value, gpg_home, eyaml_pub_key)
  changed = 0

  # fix ascii text blocks that have been corrupted by extra newlines

  #end
  if value.class == String and ! value.empty?
    split = value.split("\n")

    # scan the entire block looking for the magic marker to fix variable
    # leading whitespace breaking detection
    gpg_value = false
    i = 0
    while ! gpg_value and i < split.size
      if split[i].strip == GPG_MAGIC
        gpg_value = true
      elsif split[i] =~ /[^\s]+/
        # we found non-whitespace before our magic marker, this isn't GPG data
        # so break out of the loop
        i = split.size
      end
      i += 1
    end
    if gpg_value
      value = recrypt(value, gpg_home, eyaml_pub_key)
      changed = 1
    end
  end

  return changed, value
end
recrypt(gpg_ct, gpg_home, eyaml_pub_key) click to toggle source
# File lib/yaml_recrypt.rb, line 121
def self.recrypt(gpg_ct, gpg_home, eyaml_pub_key)
  pt = YamlRecrypt::Gpg::decrypt(gpg_ct, gpg_home)

  YamlRecrypt::Eyaml::encrypt_and_encode(pt, eyaml_pub_key).strip
end
recrypt_file(filename, gpg_home, eyaml_pub_key) click to toggle source
# File lib/yaml_recrypt.rb, line 18
def self.recrypt_file(filename, gpg_home, eyaml_pub_key)
  if filename.start_with? REAL_PUPPET_DIR
    abort("Detected being run from the #{REAL_PUPPET_DIR}*! Refusing to run to avoid trashing live puppet master")
  end
  Escort::Logger.output.puts "Processing #{filename}"

  # load the yaml into a hash
  raw_data = File.open(filename, 'r') { |f| f.read }
  hash_wip  = YAML.load(raw_data)

  # descend every key until a string (or terminal) is reached
  replaced, converted = descend(gpg_home, eyaml_pub_key, hash_wip)

  if replaced > 0
    Escort::Logger.output.puts "*** updated #{replaced} values in #{filename} ****"
    # save old file with .orig -- some fool might run this on a non-version
    # controlled directory...
    FileUtils.cp(filename, "#{filename}.#{BACKUP_EXT}")

    # save the new data
    File.open(filename, 'w') {|f| f.write hash_wip.to_yaml }

    # Post-process the data to convert yaml multi-line blocks into yaml folded
    # blocks
    YamlRecrypt::PostProcess::postprocess(filename)
  end
end
recrypt_r(dir, gpg_home, eyaml_pub_key) click to toggle source
# File lib/yaml_recrypt.rb, line 112
def self.recrypt_r(dir, gpg_home, eyaml_pub_key)
  Find.find(dir) do |path|
    if path =~ /.*\.yaml$/
      recrypt_file(path, gpg_home, eyaml_pub_key)
    end
  end

end