class Hiera::Backend::Vault_backend
Public Class Methods
new()
click to toggle source
# File lib/hiera/backend/vault_backend.rb, line 6 def initialize() require 'json' require 'vault' @config = Config[:vault] @config[:mounts] ||= {} @config[:mounts][:generic] ||= @config[:mounts]['generic'] || ['secret'] @config[:default_field_parse] ||= 'string' # valid values: 'string', 'json' if not ['string','json'].include?(@config[:default_field_parse]) raise Exception, "[hiera-vault] invalid value for :default_field_parse: '#{@config[:default_field_behavior]}', should be one of 'string','json'" end # :default_field_behavior: # 'ignore' => ignore additional fields, if the field is not present return nil # 'only' => only return value of default_field when it is present and the only field, otherwise return hash as normal @config[:default_field_behavior] ||= 'ignore' if not ['ignore','only'].include?(@config[:default_field_behavior]) raise Exception, "[hiera-vault] invalid value for :default_field_behavior: '#{@config[:default_field_behavior]}', should be one of 'ignore','only'" end begin @vault = Vault::Client.new @vault.configure do |config| config.address = @config[:addr] unless @config[:addr].nil? config.token = @config[:token] unless @config[:token].nil? config.ssl_pem_file = @config[:ssl_pem_file] unless @config[:ssl_pem_file].nil? config.ssl_verify = @config[:ssl_verify] unless @config[:ssl_verify].nil? config.ssl_ca_cert = @config[:ssl_ca_cert] if config.respond_to? :ssl_ca_cert config.ssl_ca_path = @config[:ssl_ca_path] if config.respond_to? :ssl_ca_path config.ssl_ciphers = @config[:ssl_ciphers] if config.respond_to? :ssl_ciphers end fail if @vault.sys.seal_status.sealed? Hiera.debug("[hiera-vault] Client configured to connect to #{@vault.address}") rescue Exception => e @vault = nil Hiera.warn("[hiera-vault] Skipping backend. Configuration error: #{e}") end # Check vault kv version if (@config[:kv_version]).nil? @api_path = "" Hiera.debug("[hiera-vault] kv engine version not set using default: 1") elsif @config[:kv_version] == 1 @api_path = "" Hiera.debug("[hiera-vault] Using kv engine version: #{@config[:kv_version]}") elsif @config[:kv_version] == 2 @api_path = "data/" Hiera.debug("[hiera-vault] Using kv engine version: #{@config[:kv_version]}") else Hiera.warn("[hiera-vault] Not supported kv engine version: #{@config[:kv_version]}") end end
Public Instance Methods
lookup(key, scope, order_override, resolution_type)
click to toggle source
# File lib/hiera/backend/vault_backend.rb, line 62 def lookup(key, scope, order_override, resolution_type) return nil if @vault.nil? Hiera.debug("[hiera-vault] Looking up #{key} in vault backend") answer = nil found = false # Only generic mounts supported so far @config[:mounts][:generic].each do |mount| path = Backend.parse_string(mount, scope, { 'key' => key }) Backend.datasources(scope, order_override) do |source| Hiera.debug("Looking in path #{path}/#{source}/") new_answer = lookup_generic("#{path}/#{@api_path}#{source}/#{key}", scope) #Hiera.debug("[hiera-vault] Answer: #{new_answer}:#{new_answer.class}") next if new_answer.nil? case resolution_type when :array raise Exception, "Hiera type mismatch: expected Array and got #{new_answer.class}" unless new_answer.kind_of? Array or new_answer.kind_of? String answer ||= [] answer << new_answer when :hash raise Exception, "Hiera type mismatch: expected Hash and got #{new_answer.class}" unless new_answer.kind_of? Hash answer ||= {} answer = Backend.merge_answer(new_answer,answer) else answer = new_answer found = true break end end break if found end return answer end
lookup_generic(key, scope)
click to toggle source
# File lib/hiera/backend/vault_backend.rb, line 99 def lookup_generic(key, scope) begin secret = @vault.logical.read(key) rescue Vault::HTTPConnectionError Hiera.debug("[hiera-vault] Could not connect to read secret: #{key}") rescue Vault::HTTPError => e Hiera.warn("[hiera-vault] Could not read secret #{key}: #{e.errors.join("\n").rstrip}") end return nil if secret.nil? sd = @config[:kv_version] == 2 ? secret.data[:data] : secret.data Hiera.debug("[hiera-vault] Read secret: #{key}") if @config[:default_field] and (@config[:default_field_behavior] == 'ignore' or (sd.has_key?(@config[:default_field].to_sym) and sd.length == 1)) return nil if not sd.has_key?(@config[:default_field].to_sym) # Return just our default_field data = sd[@config[:default_field].to_sym] if @config[:default_field_parse] == 'json' begin data = JSON.parse(data) rescue JSON::ParserError => e Hiera.debug("[hiera-vault] Could not parse string as json: #{e}") end end else # Turn secret's hash keys into strings data = sd.inject({}) { |h, (k, v)| h[k.to_s] = v; h } end #Hiera.debug("[hiera-vault] Data: #{data}:#{data.class}") return Backend.parse_answer(data, scope) end