vault 0.1.5 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +11 -1
- data/README.md +58 -1
- data/lib/vault/client.rb +53 -4
- data/lib/vault/defaults.rb +12 -1
- data/lib/vault/errors.rb +11 -3
- data/lib/vault/version.rb +1 -1
- data/vault.gemspec +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85725acc286dd2dc1e346442a4e528d7e11ae42e
|
4
|
+
data.tar.gz: 6344245bd60e54203151708b45134c9ae2201a51
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d573f396ec086b8103a3d29750c92aa79c0dd0567c5eb511c60a2d9912ad9fb47ef7d4a7a43b910e480ba3742e61e24cd2df9b3fe30e215dfa8d5d22993da88
|
7
|
+
data.tar.gz: 558a0c41ef94a57da06b5bb40bdd34fb07d0367a0ccdf7b51edae9d53fbb28940a81abccd5b9eccd78474493424d7f259459fcc8c522da515f3af37a0e8d5b2d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Vault Ruby Changelog
|
2
2
|
|
3
|
+
## v0.2.0 (December 2, 2015)
|
4
|
+
|
5
|
+
IMPROVEMENTS
|
6
|
+
|
7
|
+
- Add support for retries (clients must opt-in) [GH-47]
|
8
|
+
|
9
|
+
BUG FIXES
|
10
|
+
|
11
|
+
- Fix redirection on POST/PUT [GH-40]
|
12
|
+
- Use `$HOME` instead of `~` for shell expansion
|
13
|
+
|
3
14
|
## v0.1.5 (September 1, 2015)
|
4
15
|
|
5
16
|
IMPROVEMENTS
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
vault (0.
|
4
|
+
vault (0.2.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
addressable (2.3.8)
|
9
10
|
coderay (1.1.0)
|
11
|
+
crack (0.4.2)
|
12
|
+
safe_yaml (~> 1.0.0)
|
10
13
|
diff-lcs (1.2.5)
|
14
|
+
hashdiff (0.2.3)
|
11
15
|
method_source (0.8.2)
|
12
16
|
pry (0.10.1)
|
13
17
|
coderay (~> 1.1.0)
|
@@ -27,7 +31,12 @@ GEM
|
|
27
31
|
diff-lcs (>= 1.2.0, < 2.0)
|
28
32
|
rspec-support (~> 3.2.0)
|
29
33
|
rspec-support (3.2.2)
|
34
|
+
safe_yaml (1.0.4)
|
30
35
|
slop (3.6.0)
|
36
|
+
webmock (1.22.3)
|
37
|
+
addressable (>= 2.3.6)
|
38
|
+
crack (>= 0.3.2)
|
39
|
+
hashdiff
|
31
40
|
|
32
41
|
PLATFORMS
|
33
42
|
ruby
|
@@ -38,6 +47,7 @@ DEPENDENCIES
|
|
38
47
|
rake (~> 10.0)
|
39
48
|
rspec (~> 3.2)
|
40
49
|
vault!
|
50
|
+
webmock (~> 1.22)
|
41
51
|
|
42
52
|
BUNDLED WITH
|
43
53
|
1.10.6
|
data/README.md
CHANGED
@@ -3,6 +3,8 @@ Vault Ruby Client [![Build Status](https://secure.travis-ci.org/hashicorp/vault-
|
|
3
3
|
|
4
4
|
Vault is the official Ruby client for interacting with [Vault](https://vaultproject.io) by HashiCorp.
|
5
5
|
|
6
|
+
**The documentation in this README corresponds to the master branch of the Vault Ruby client. It may contain unreleased features or different APIs than the most recently released version. Please see the Git tag that corresponds to your version of the Vault Ruby client for the proper documentation.**
|
7
|
+
|
6
8
|
Quick Start
|
7
9
|
-----------
|
8
10
|
Install Ruby 2.0+: [Guide](https://www.ruby-lang.org/en/documentation/installation/).
|
@@ -35,7 +37,7 @@ Usage
|
|
35
37
|
The following configuration options are available:
|
36
38
|
|
37
39
|
```ruby
|
38
|
-
Vault
|
40
|
+
Vault.configure do |config|
|
39
41
|
# The address of the Vault server, also read as ENV["VAULT_ADDR"]
|
40
42
|
config.address = "https://127.0.0.1:8200"
|
41
43
|
|
@@ -76,6 +78,61 @@ client_2 = Vault::Client.new(address: "https://other-vault.mycompany.com")
|
|
76
78
|
### Making requests
|
77
79
|
All of the methods and API calls are heavily documented with examples inline using YARD. In order to keep the examples versioned with the code, the README only lists a few examples for using the Vault gem. Please see the inline documentation for the full API documentation. The tests in the 'spec' directory are an additional source of examples.
|
78
80
|
|
81
|
+
Idempotent requests can be wrapped with a `with_retries` clause to automatically retry on certain connection errors. For example, to retry on socket/network-level issues, you can do the following:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
Vault.with_retries(Vault::HTTPConnectionError) do
|
85
|
+
Vault.logical.read("secret/on_bad_network")
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
To rescue particular HTTP exceptions:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
# Rescue 4xx errors
|
93
|
+
Vault.with_retries(Vault::HTTPClientError) {}
|
94
|
+
|
95
|
+
# Rescue 5xx errors
|
96
|
+
Vault.with_retries(Vault::HTTPServerError) {}
|
97
|
+
|
98
|
+
# Rescue all HTTP errors
|
99
|
+
Vault.with_retries(Vault::HTTPError) {}
|
100
|
+
```
|
101
|
+
|
102
|
+
For advanced users, the first argument of the block is the attempt number and the second argument is the exception itself:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
Vault.with_retries(Vault::HTTPConnectionError, Vault::HTTPError) do |attempt, e|
|
106
|
+
log "Received exception #{e} from Vault - attempt #{attempt}"
|
107
|
+
Vault.logical.read("secret/bacon")
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
The following options are available:
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
# :attempts - The number of retries when communicating with the Vault server.
|
115
|
+
# The default value is 2.
|
116
|
+
#
|
117
|
+
# :base - The base interval for retry exponential backoff. The default value is
|
118
|
+
# 0.05s.
|
119
|
+
#
|
120
|
+
# :max_wait - The maximum amount of time for a single exponential backoff to
|
121
|
+
# sleep. The default value is 2.0s.
|
122
|
+
|
123
|
+
Vault.with_retries(Vault::HTTPError, attempts: 5) do
|
124
|
+
# ...
|
125
|
+
end
|
126
|
+
```
|
127
|
+
|
128
|
+
After the number of retries have been exhausted, the original exception is raised.
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
Vault.with_retries(Exception) do
|
132
|
+
raise Exception
|
133
|
+
end #=> #<Exception>
|
134
|
+
```
|
135
|
+
|
79
136
|
#### Seal Status
|
80
137
|
```ruby
|
81
138
|
Vault.sys.seal_status
|
data/lib/vault/client.rb
CHANGED
@@ -16,6 +16,9 @@ module Vault
|
|
16
16
|
# The name of the header used to hold the Vault token.
|
17
17
|
TOKEN_HEADER = "X-Vault-Token".freeze
|
18
18
|
|
19
|
+
# The name of the header used for redirection.
|
20
|
+
LOCATION_HEADER = "location".freeze
|
21
|
+
|
19
22
|
# The default headers that are sent with every request.
|
20
23
|
DEFAULT_HEADERS = {
|
21
24
|
"Content-Type" => "application/json",
|
@@ -214,8 +217,7 @@ module Vault
|
|
214
217
|
|
215
218
|
case response
|
216
219
|
when Net::HTTPRedirection
|
217
|
-
|
218
|
-
request(verb, redirect, data, headers)
|
220
|
+
request(verb, response[LOCATION_HEADER], data, headers)
|
219
221
|
when Net::HTTPSuccess
|
220
222
|
success(response)
|
221
223
|
else
|
@@ -313,18 +315,65 @@ module Vault
|
|
313
315
|
raise MissingTokenError
|
314
316
|
end
|
315
317
|
|
318
|
+
# Use the correct exception class
|
319
|
+
case response
|
320
|
+
when Net::HTTPClientError
|
321
|
+
klass = HTTPClientError
|
322
|
+
when Net::HTTPServerError
|
323
|
+
klass = HTTPServerError
|
324
|
+
else
|
325
|
+
klass = HTTPError
|
326
|
+
end
|
327
|
+
|
316
328
|
if (response.content_type || '').include?("json")
|
317
329
|
# Attempt to parse the error as JSON
|
318
330
|
begin
|
319
331
|
json = JSON.parse(response.body, JSON_PARSE_OPTIONS)
|
320
332
|
|
321
333
|
if json[:errors]
|
322
|
-
raise
|
334
|
+
raise klass.new(address, response, json[:errors])
|
323
335
|
end
|
324
336
|
rescue JSON::ParserError; end
|
325
337
|
end
|
326
338
|
|
327
|
-
raise
|
339
|
+
raise klass.new(address, response, [response.body])
|
340
|
+
end
|
341
|
+
|
342
|
+
# Execute the given block with retries and exponential backoff.
|
343
|
+
#
|
344
|
+
# @param [Array<Exception>] rescued
|
345
|
+
# the list of exceptions to rescue
|
346
|
+
def with_retries(*rescued, &block)
|
347
|
+
options = rescued.last.is_a?(Hash) ? rescued.pop : {}
|
348
|
+
exception = nil
|
349
|
+
retries = 0
|
350
|
+
|
351
|
+
max_attempts = options[:attempts] || Defaults::RETRY_ATTEMPTS
|
352
|
+
backoff_base = options[:base] || Defaults::RETRY_BASE
|
353
|
+
backoff_max = options[:max_wait] || Defaults::RETRY_MAX_WAIT
|
354
|
+
|
355
|
+
begin
|
356
|
+
return yield retries
|
357
|
+
rescue *rescued => e
|
358
|
+
exception = e
|
359
|
+
|
360
|
+
retries += 1
|
361
|
+
raise if retries > max_attempts
|
362
|
+
|
363
|
+
# Calculate the exponential backoff combined with an element of
|
364
|
+
# randomness.
|
365
|
+
backoff = [backoff_base * (2 ** (retries - 1)), backoff_max].min
|
366
|
+
backoff = backoff * (0.5 * (1 + Kernel.rand))
|
367
|
+
|
368
|
+
# Ensure we are sleeping at least the minimum interval.
|
369
|
+
backoff = [backoff_base, backoff].max
|
370
|
+
|
371
|
+
# Exponential backoff.
|
372
|
+
Kernel.sleep(backoff)
|
373
|
+
|
374
|
+
# Now retry
|
375
|
+
retry
|
376
|
+
end
|
328
377
|
end
|
329
378
|
end
|
330
379
|
end
|
data/lib/vault/defaults.rb
CHANGED
@@ -8,13 +8,24 @@ module Vault
|
|
8
8
|
|
9
9
|
# The path to the vault token on disk.
|
10
10
|
# @return [String]
|
11
|
-
VAULT_DISK_TOKEN = Pathname.new("
|
11
|
+
VAULT_DISK_TOKEN = Pathname.new("#{ENV["HOME"]}/.vault-token").expand_path.freeze
|
12
12
|
|
13
13
|
# The list of SSL ciphers to allow. You should not change this value unless
|
14
14
|
# you absolutely know what you are doing!
|
15
15
|
# @return [String]
|
16
16
|
SSL_CIPHERS = "TLSv1.2:!aNULL:!eNULL".freeze
|
17
17
|
|
18
|
+
# The default number of attempts.
|
19
|
+
# @return [Fixnum]
|
20
|
+
RETRY_ATTEMPTS = 2
|
21
|
+
|
22
|
+
# The default backoff interval.
|
23
|
+
# @return [Fixnum]
|
24
|
+
RETRY_BASE = 0.05
|
25
|
+
|
26
|
+
# The maximum amount of time for a single exponential backoff to sleep.
|
27
|
+
RETRY_MAX_WAIT = 2.0
|
28
|
+
|
18
29
|
class << self
|
19
30
|
# The list of calculated options for this configurable.
|
20
31
|
# @return [Hash]
|
data/lib/vault/errors.rb
CHANGED
@@ -42,13 +42,18 @@ shown below:
|
|
42
42
|
Please refer to the documentation for more help.
|
43
43
|
EOH
|
44
44
|
end
|
45
|
+
|
46
|
+
def original_exception
|
47
|
+
@exception
|
48
|
+
end
|
45
49
|
end
|
46
50
|
|
47
51
|
class HTTPError < VaultError
|
48
|
-
attr_reader :address, :code, :errors
|
52
|
+
attr_reader :address, :response, :code, :errors
|
49
53
|
|
50
|
-
def initialize(address,
|
51
|
-
@address, @
|
54
|
+
def initialize(address, response, errors = [])
|
55
|
+
@address, @response, @errors = address, response, errors
|
56
|
+
@code = response.code.to_i
|
52
57
|
errors = errors.map { |error| " * #{error}" }
|
53
58
|
|
54
59
|
super <<-EOH
|
@@ -61,4 +66,7 @@ Please refer to the documentation for help.
|
|
61
66
|
EOH
|
62
67
|
end
|
63
68
|
end
|
69
|
+
|
70
|
+
class HTTPClientError < HTTPError; end
|
71
|
+
class HTTPServerError < HTTPError; end
|
64
72
|
end
|
data/lib/vault/version.rb
CHANGED
data/vault.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vault
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Seth Vargo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: webmock
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.22'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.22'
|
69
83
|
description: Vault is a Ruby API client for interacting with a Vault server.
|
70
84
|
email:
|
71
85
|
- sethvargo@gmail.com
|