diff options
Diffstat (limited to 'puppet/modules/couchdb/lib')
4 files changed, 194 insertions, 0 deletions
| diff --git a/puppet/modules/couchdb/lib/facter/couchdb_pwhash_alg.rb b/puppet/modules/couchdb/lib/facter/couchdb_pwhash_alg.rb new file mode 100644 index 00000000..60ae701a --- /dev/null +++ b/puppet/modules/couchdb/lib/facter/couchdb_pwhash_alg.rb @@ -0,0 +1,43 @@ +require 'facter' + +def version_parts ( version ) +  # gives back a hash containing major, minor and patch numbers +  # of a give version string + +  parts = Hash.new +  first, *rest = version.split(".") +  parts["major"] = first +  parts["minor"] = rest[0] +  parts["patch"] = rest[1] +  return parts +end + +def couchdb_pwhash_alg +  # couchdb uses sha1 as pw hash algorithm until v. 1.2, +  # but pbkdf2 from v.1.3 on. +  # see http://docs.couchdb.org/en/1.4.x/configuring.html for +  # details + +  couchdb_version = Facter.value(:couchdb_version) +  version = version_parts(couchdb_version) +  major = version["major"].to_i +  alg = case major +    when 0 then alg = 'n/a' +    when 1 then +      minor = version['minor'].to_i +      if minor < 3 +        alg = 'sha1' +      else +        alg = 'pbkdf2' +      end +  else +    alg = 'pbkdf2' +  end +  return alg +end + +Facter.add(:couchdb_pwhash_alg) do +  setcode do +    couchdb_pwhash_alg +  end +end diff --git a/puppet/modules/couchdb/lib/facter/couchdb_version.rb b/puppet/modules/couchdb/lib/facter/couchdb_version.rb new file mode 100644 index 00000000..3a721169 --- /dev/null +++ b/puppet/modules/couchdb/lib/facter/couchdb_version.rb @@ -0,0 +1,34 @@ +require 'facter' + +def deb_installed_version ( name ) +  # returns an empty string if package is not installed, +  # otherwise the version + +  version = `apt-cache policy #{name} | grep Installed 2>&1` +  version.slice! "  Installed: " +  version.slice! "(none)" +  return version.strip.chomp +end + +def couchdb_version +  bigcouch = deb_installed_version("bigcouch") +  if bigcouch.empty? +    couchdb = deb_installed_version("couchdb") +    if couchdb.empty? +      version = 'n/a' +    else +      version =  couchdb +    end +  else +    # bigcouch is currently only available in one version (0.4.2), +    # which includes couchdb 1.1.1 +    version = '1.1.1' +  end +  return version +end + +Facter.add(:couchdb_version) do +  setcode do +    couchdb_version +  end +end diff --git a/puppet/modules/couchdb/lib/puppet/parser/functions/couchdblookup.rb b/puppet/modules/couchdb/lib/puppet/parser/functions/couchdblookup.rb new file mode 100644 index 00000000..b9067d2a --- /dev/null +++ b/puppet/modules/couchdb/lib/puppet/parser/functions/couchdblookup.rb @@ -0,0 +1,55 @@ +# +# A basic function to retrieve data in couchdb +# + + +module Puppet::Parser::Functions +  newfunction(:couchdblookup, :type => :rvalue) do |args| +    require 'json' +    require 'open-uri' + +    raise Puppet::ParseError, ("couchdblookup(): wrong number of arguments (#{args.length}; must be 2 or 3)") unless args.length.between?(2, 3) + +    url = args[0] +    key = args[1] +    default = args[2] if args.length >= 3 + +    begin +      json = JSON.parse(open(URI.parse(url)).read) +    rescue OpenURI::HTTPError => error +      raise Puppet::ParseError, "couchdblookup(): fetching URL #{url} failed with status '#{error.message}'" +    rescue Timeout::Error => error +      raise Puppet::ParseError, "couchdblookup(): connection to couchdb server timed out: '#{error.message}'" +    rescue Errno::ECONNREFUSED => error +      raise Puppet::ParseError, "couchdblookup(): connection to couchdb server failed: '#{error.message}'" +    rescue JSON::ParserError => error +      raise Puppet::ParseError, "couchdblookup(): failed to parse JSON received from couchdb: '#{error.message}'" +    rescue StandardError => error +      raise Puppet::ParseError, "couchdblookup(): something unexpected happened: '#{error.inspect}'" +    end + +    result = nil + +    if json.has_key?("rows") + +      if json['rows'].length > 1 +        arr = json['rows'].collect do |x| +          x[key] if x.is_a?(Hash) and x.has_key?(key) +        end +        arr.compact! +        result = arr unless arr.empty? + +      elsif json['rows'].length == 1 +        hash = json['rows'].pop +        result = hash[key] if hash.is_a?(Hash) +      end + +    elsif json.has_key?(key) +      result = json[key] +    end + +    result or default or raise Puppet::ParseError, "couchdblookup(): key '#{key}' not found in JSON object !" + +  end +end + diff --git a/puppet/modules/couchdb/lib/puppet/parser/functions/pbkdf2.rb b/puppet/modules/couchdb/lib/puppet/parser/functions/pbkdf2.rb new file mode 100644 index 00000000..46400c9c --- /dev/null +++ b/puppet/modules/couchdb/lib/puppet/parser/functions/pbkdf2.rb @@ -0,0 +1,62 @@ +# +# pbkdf2.rb +# + +module Puppet::Parser::Functions +  newfunction(:pbkdf2, :type => :rvalue, :doc => <<-EOS +This converts a password and a salt (and optional iterations and keylength +parameters) to a hash containing the salted SHA1 password hash, salt, +iterations and keylength. +pbkdf2 is used i.e. for couchdb passwords since v1.3. + +Example usage: +  $pbkdf2 = pbkdf2($::couchdb::admin_pw, $::couchdb::admin_salt) +  $sha1   = $pbkdf2['sha1'] +EOS +  ) do |arguments| +    require 'openssl' +    require 'base64' + +    raise(Puppet::ParseError, "pbkdf2(): Wrong number of arguments " + +      "passed (#{arguments.size} but we require at least 2)") if arguments.size < 2 + +    unless arguments.is_a?(Array) +      raise(Puppet::ParseError, 'pbkdf2(): Requires a ' + +        "Array argument, you passed: #{password.class}") +    end + +    password   = arguments[0] +    salt       = arguments[1] + +    if arguments.size > 2 +      iterations = arguments[2].to_i +    else +      iterations = 1000 +    end + +    if arguments.size > 3 +      keylength  = arguments[3].to_i +    else +      keylength  = 20 +    end + +    pbkdf2 = OpenSSL::PKCS5::pbkdf2_hmac_sha1( +      password, +      salt, +      iterations, +      keylength +    ) + +    return_hash = Hash.new() +    # return hex encoded string +    return_hash['sha1']       = pbkdf2.unpack('H*')[0] +    return_hash['password']   = password +    return_hash['salt']       = salt +    return_hash['iterations'] = iterations +    return_hash['keylength']  = keylength + +    return return_hash +  end +end + +# vim: set ts=2 sw=2 et : | 
