diff --git a/README.md b/README.md index 82476e1..c4eacdb 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,19 @@ The hiera lookup for `foo` will return a Hash: {"value"=>"bar","other"=>"baz"} +### Vault KV engine version - optional + +Since version 0.10.0 Vault supports kv secrets versioning so-called KV version 2. By default version 1 support is enabled. To configure module to work with version 2 secrets specify the :kv_version setting e.g. + + :vault: + :kv_version: 2 + +Make sure to enable versioning for all secrets in Vault: + + vault kv enable-versioning secret/foo + +**NOTE:** It is not possible to lookup through v1 and v2 secrets simultaneously. Use the only type. + ### Single Value - optional If you use just a single field to store data, eg. "value" - you can request that just this is returned as a string, instead of a hash. diff --git a/hiera-vault.gemspec b/hiera-vault.gemspec index cb94306..cab4e71 100644 --- a/hiera-vault.gemspec +++ b/hiera-vault.gemspec @@ -3,7 +3,7 @@ require 'rubygems/package_task' spec = Gem::Specification.new do |gem| gem.name = "hiera-vault" - gem.version = "0.2.2" + gem.version = "0.2.3" gem.license = "Apache-2.0" gem.summary = "Module for using vault as a hiera backend" gem.email = "jonathan.sokolowski@gmail.com" diff --git a/lib/hiera/backend/vault_backend.rb b/lib/hiera/backend/vault_backend.rb index 8cba891..2058e19 100644 --- a/lib/hiera/backend/vault_backend.rb +++ b/lib/hiera/backend/vault_backend.rb @@ -43,6 +43,20 @@ def initialize() @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 def lookup(key, scope, order_override, resolution_type) @@ -58,7 +72,7 @@ def lookup(key, scope, order_override, resolution_type) 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}/#{source}/#{key}", scope) + 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 @@ -92,22 +106,29 @@ def lookup_generic(key, scope) end return nil if secret.nil? - Hiera.debug("[hiera-vault] Read secret: #{key}") if @config[:default_field] and (@config[:default_field_behavior] == 'ignore' or (secret.data.has_key?(@config[:default_field].to_sym) and secret.data.length == 1)) return nil if not secret.data.has_key?(@config[:default_field].to_sym) # Return just our default_field - data = secret.data[@config[:default_field].to_sym] + if @config[:kv_version] == 2 + data = secret.data[:data][@config[:default_field].to_sym] + else + data = secret.data[@config[:default_field].to_sym] + end if @config[:default_field_parse] == 'json' begin - data = JSON.parse(data) + data = JSON.parse(data[: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 = secret.data.inject({}) { |h, (k, v)| h[k.to_s] = v; h } + if @config[:kv_version] == 2 + data = secret.data[:data].inject({}) { |h, (k, v)| h[k.to_s] = v; h } + else + data = secret.data.inject({}) { |h, (k, v)| h[k.to_s] = v; h } + end end #Hiera.debug("[hiera-vault] Data: #{data}:#{data.class}")