Class: Cerberus::VaultClient

Inherits:
Object
  • Object
show all
Defined in:
lib/cerberus/vault_client.rb

Overview

Client for interacting with the Vault API

Constant Summary collapse

SECRET_PATH_PREFIX =

relative path to the Vault secrets API

"/v1/secret/"
SECRET_MAP_DATA_KEY =
VAULT_LIST_DATA_KEY = "data"
VAULT_TOKEN_HEADER_KEY =
'X-Vault-Token'
VAULT_ERRORS_KEY =
"errors"
VAULT_PERMISSION_DENIED_ERR =
"permission denied"
VAULT_LIST_KEYS_KEY =
"keys"
VAULT_LIST_PARAM_KEY =
"list"
SLASH =
"/"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(urlResolver, credentialsProviderChain) ⇒ VaultClient

Init with the base URL for vault



32
33
34
35
36
37
38
39
# File 'lib/cerberus/vault_client.rb', line 32

def initialize(urlResolver, credentialsProviderChain)

  require 'net/https'

  @vaultBaseUrl = CerberusClient.getUrlFromResolver(urlResolver)
  @credentialsProvider = credentialsProviderChain.getCredentialsProvider

end

Instance Attribute Details

#credentialsProviderObject (readonly)

Returns the value of attribute credentialsProvider.



27
28
29
# File 'lib/cerberus/vault_client.rb', line 27

def credentialsProvider
  @credentialsProvider
end

#vaultBaseUrlObject (readonly)

Returns the value of attribute vaultBaseUrl.



26
27
28
# File 'lib/cerberus/vault_client.rb', line 26

def vaultBaseUrl
  @vaultBaseUrl
end

Instance Method Details

#describe!(path, resultHash = nil) ⇒ Object

This is potentially an expensive operation depending on the depth of the tree we’re trying to parse It recursively walks ‘path’ and returns a hash of all child [path] => [array of keys] found under ‘path’ if ‘path’ is a folder, it must have a trailing slash (‘/’). If ‘path’ is an “end node” or “vault file”, then it should not have a trailing slash (‘/’)



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/cerberus/vault_client.rb', line 108

def describe!(path, resultHash = nil)

  CerberusClient::Log.instance.debug("VaultClient::describe!(#{path})")

  if(resultHash == nil)
    resultHash = Hash.new()
  end

  curChildren = list(path)

  # if curChildren is nil, it's possible there are no children or that we don't have access
  # It's also possible it is the "end" of the path... what Vault calls "the file"
  # in that case, we should send back the keys in that path so give it a shot
  if(curChildren.nil?)
    resultHash[path] = Array.new
    readPathAndIterateOnDataWithProc(path, &(Proc.new { |key, value| resultHash[path] << key }) )
    return resultHash
  end

  curChildren.each { |childNode|
    curLocation = path + childNode
    # if childNode ends with '/' then we have a directory we need to call into
    if(childNode.end_with?(SLASH))
      describe!(curLocation, resultHash)
    else # it is a "directory" that contains keys
      resultHash[curLocation] = Array.new
      readPathAndIterateOnDataWithProc(curLocation, &(Proc.new { |key, value| resultHash[curLocation] << key }) )
    end
  }
  return resultHash
end

#list(path) ⇒ Object

Returns a list of key names at the specified location. Folders are suffixed with /. The input must be a folder; list on a file will return nil



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/cerberus/vault_client.rb', line 78

def list(path)
  begin
    response = doVaultHttpGet(SECRET_PATH_PREFIX + path + "?list=true")

    CerberusClient::Log.instance.debug("VaultClient::list(#{path}) HTTP response: #{response.code}, #{response.message}")

    jsonResonseBody = JSON.parse(response.body)
    pathList = jsonResonseBody[VAULT_LIST_DATA_KEY][VAULT_LIST_KEYS_KEY]
    CerberusClient::Log.instance.debug("VaultClient::list returning #{pathList.join(", ")} ")
    pathList

  rescue => ex

    # check to see if we threw the Http error with a response object
    response = (ex.instance_of?(Cerberus::Exception::HttpError)) ? ex.response : nil
    if(!response.nil? && response.code.to_i == 404)
      return nil
    end

    CerberusClient::Log.instance.error("VaultClient::list(#{path}) unhandled exception trying to read: #{ex.message}")
    raise ex
  end
end

#read(path) ⇒ Object

Read operation for a specified path.



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/cerberus/vault_client.rb', line 44

def read(path)
  begin
    response = doVaultHttpGet(SECRET_PATH_PREFIX + path)
    CerberusClient::Log.instance.debug("VaultClient::read(path) HTTP response: #{response.code}, #{response.message}")
    response.body

  rescue => ex
    CerberusClient::Log.instance.error("VaultClient::read(#{path}) unhandled exception trying to read: #{ex.message}")
    raise ex
  end
end

#readKey(path, key) ⇒ Object

Read operation for a specified path.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/cerberus/vault_client.rb', line 59

def readKey(path, key)
  begin
    CerberusClient::Log.instance.error("VaultClient::read(#{path}, #{key})")

    readPathAndIterateOnDataWithProc(path, &(Proc.new { |k, v| if(key == k); return v; end }) )

    # else, we didn't find it
    return nil

  rescue => ex
    CerberusClient::Log.instance.error("VaultClient::read(#{path}, #{key}) unhandled exception trying to read: #{ex.message}")
    raise ex
  end
end