vault 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +12 -0
- data/README.md +31 -2
- data/lib/vault/api/auth_token.rb +52 -7
- data/lib/vault/api/help.rb +12 -2
- data/lib/vault/api/logical.rb +68 -6
- data/lib/vault/api/secret.rb +147 -16
- data/lib/vault/api/sys/audit.rb +16 -3
- data/lib/vault/api/sys/auth.rb +11 -3
- data/lib/vault/api/sys/init.rb +19 -5
- data/lib/vault/api/sys/leader.rb +27 -9
- data/lib/vault/api/sys/lease.rb +0 -2
- data/lib/vault/api/sys/mount.rb +30 -3
- data/lib/vault/api/sys/policy.rb +19 -3
- data/lib/vault/api/sys/seal.rb +36 -4
- data/lib/vault/client.rb +23 -1
- data/lib/vault/defaults.rb +2 -2
- data/lib/vault/request.rb +22 -0
- data/lib/vault/response.rb +57 -11
- data/lib/vault/version.rb +1 -1
- data/vault.gemspec +1 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: efbf977407c93919ed45ceff129bc3df6088d462
|
4
|
+
data.tar.gz: 7b3a458357a1a3a9eef3606eb5d1a8160d1d04c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef87eb90b77096ce92ab3f2c765f9b897bac05ec82da49ac600b62b05847ab02cfa9f29f2d09244527be308be61e1f24b3bfa99cac7df5aef45d458c993d76d2
|
7
|
+
data.tar.gz: 01b3384ce315cfc0e30ee11fdc020327172cde312de1f89bff1b63bf6eacd8f18425234d742b76d5551428212315424612420969c2d16edaa09bb500dea75e21
|
data/.travis.yml
CHANGED
@@ -3,7 +3,7 @@ cache: bundler
|
|
3
3
|
sudo: false
|
4
4
|
|
5
5
|
before_install: |-
|
6
|
-
|
6
|
+
curl -so vault.zip https://releases.hashicorp.com/vault/0.6.0/vault_0.6.0_linux_amd64.zip
|
7
7
|
unzip vault.zip
|
8
8
|
mkdir ~/bin
|
9
9
|
mv vault ~/bin
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Vault Ruby Changelog
|
2
2
|
|
3
|
+
## v0.4.0.dev (Unreleased)
|
4
|
+
|
5
|
+
NEW FEATURES
|
6
|
+
|
7
|
+
- Add TTL wrapping to logical and auth backends
|
8
|
+
- Support passing PGP keys to init
|
9
|
+
|
10
|
+
BUG FIXES
|
11
|
+
|
12
|
+
- New API documentation
|
13
|
+
- Remove recursive requires
|
14
|
+
|
3
15
|
## v0.4.0 (March 31, 2016)
|
4
16
|
|
5
17
|
NEW FEATURES
|
data/README.md
CHANGED
@@ -151,11 +151,39 @@ Vault.logical.read("secret/bacon")
|
|
151
151
|
#=> #<Vault::Secret lease_id="">
|
152
152
|
```
|
153
153
|
|
154
|
-
####
|
154
|
+
#### Retrieve the Contents of a Secret
|
155
155
|
```ruby
|
156
|
-
Vault.
|
156
|
+
secret = Vault.logical.read("secret/bacon")
|
157
|
+
secret.data #=> { :cooktime = >"11", :delicious => true }
|
157
158
|
```
|
158
159
|
|
160
|
+
### Response wrapping
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
# Request new access token as wrapped response where the TTL of the temporary
|
164
|
+
# token is "5s".
|
165
|
+
wrapped = Vault.auth_token.create(wrap_ttl: "5s")
|
166
|
+
|
167
|
+
# Unwrap the wrapped response to get the final token using the initial temporary
|
168
|
+
# token from the first request.
|
169
|
+
unwrapped = Vault.logical.unwrap(wrapped.wrap_info.token)
|
170
|
+
|
171
|
+
# Extract the final token from the response.
|
172
|
+
token = unwrapped.data.auth.client_token
|
173
|
+
```
|
174
|
+
|
175
|
+
A helper function is also provided when unwrapping a token directly:
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
# Request new access token as wrapped response where the TTL of the temporary
|
179
|
+
# token is "5s".
|
180
|
+
wrapped = Vault.auth_token.create(wrap_ttl: "5s")
|
181
|
+
|
182
|
+
# Unwrap wrapped response for final token using the initial temporary token.
|
183
|
+
token = Vault.logical.unwrap_token(wrapped)
|
184
|
+
```
|
185
|
+
|
186
|
+
|
159
187
|
Development
|
160
188
|
-----------
|
161
189
|
1. Clone the project on GitHub
|
@@ -167,3 +195,4 @@ Important Notes:
|
|
167
195
|
- **All new features must include test coverage.** At a bare minimum, Unit tests are required. It is preferred if you include acceptance tests as well.
|
168
196
|
- **The tests must be be idempotent.** The HTTP calls made during a test should be able to be run over and over.
|
169
197
|
- **Tests are order independent.** The default RSpec configuration randomizes the test order, so this should not be a problem.
|
198
|
+
- **Integration tests require Vault** Vault must be available in the path for the integration tests to pass.
|
data/lib/vault/api/auth_token.rb
CHANGED
@@ -15,16 +15,45 @@ module Vault
|
|
15
15
|
end
|
16
16
|
|
17
17
|
class AuthToken < Request
|
18
|
-
# Create an authentication token.
|
18
|
+
# Create an authentication token. Note that the parameters specified below
|
19
|
+
# are not validated and passed directly to the Vault server. Depending on
|
20
|
+
# the version of Vault in operation, some of these options may not work, and
|
21
|
+
# newer options may be available that are not listed here.
|
19
22
|
#
|
20
|
-
# @example
|
23
|
+
# @example Creating a token
|
21
24
|
# Vault.auth_token.create #=> #<Vault::Secret lease_id="">
|
22
25
|
#
|
26
|
+
# @example Creating a token assigned to policies with a wrap TTL
|
27
|
+
# Vault.auth_token.create(
|
28
|
+
# policies: ["myapp"],
|
29
|
+
# wrap_ttl: 500,
|
30
|
+
# )
|
31
|
+
#
|
23
32
|
# @param [Hash] options
|
33
|
+
# @option options [String] :id
|
34
|
+
# The ID of the client token - this can only be specified for root tokens
|
35
|
+
# @option options [Array<String>] :policies
|
36
|
+
# List of policies to apply to the token
|
37
|
+
# @option options [Fixnum, String] :wrap_ttl
|
38
|
+
# The number of seconds or a golang-formatted timestamp like "5s" or "10m"
|
39
|
+
# for the TTL on the wrapped response
|
40
|
+
# @option options [Hash<String, String>] :meta
|
41
|
+
# A map of metadata that is passed to audit backends
|
42
|
+
# @option options [Boolean] :no_parent
|
43
|
+
# Create a token without a parent - see also {#create_orphan}
|
44
|
+
# @option options [Boolean] :no_default_policy
|
45
|
+
# Create a token without the default policy attached
|
46
|
+
# @option options [Boolean] :renewable
|
47
|
+
# Set whether this token is renewable or not
|
48
|
+
# @option options [String] :display_name
|
49
|
+
# Name of the token
|
50
|
+
# @option options [Fixnum] :num_uses
|
51
|
+
# Maximum number of uses for the token
|
24
52
|
#
|
25
53
|
# @return [Secret]
|
26
54
|
def create(options = {})
|
27
|
-
|
55
|
+
headers = extract_headers!(options)
|
56
|
+
json = client.post("/v1/auth/token/create", JSON.fast_generate(options), headers)
|
28
57
|
return Secret.decode(json)
|
29
58
|
end
|
30
59
|
|
@@ -33,11 +62,27 @@ module Vault
|
|
33
62
|
# @example
|
34
63
|
# Vault.auth_token.create_orphan #=> #<Vault::Secret lease_id="">
|
35
64
|
#
|
36
|
-
# @param
|
65
|
+
# @param (see #create)
|
66
|
+
# @option (see #create)
|
37
67
|
#
|
38
68
|
# @return [Secret]
|
39
69
|
def create_orphan(options = {})
|
40
|
-
|
70
|
+
headers = extract_headers!(options)
|
71
|
+
json = client.post("/v1/auth/token/create-orphan", JSON.fast_generate(options), headers)
|
72
|
+
return Secret.decode(json)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Create an orphaned authentication token.
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
# Vault.auth_token.create_with_role("developer") #=> #<Vault::Secret lease_id="">
|
79
|
+
#
|
80
|
+
# @param [Hash] options
|
81
|
+
#
|
82
|
+
# @return [Secret]
|
83
|
+
def create_with_role(name, options = {})
|
84
|
+
headers = extract_headers!(options)
|
85
|
+
json = client.post("/v1/auth/token/create/#{CGI.escape(name)}", JSON.fast_generate(options), headers)
|
41
86
|
return Secret.decode(json)
|
42
87
|
end
|
43
88
|
|
@@ -126,8 +171,8 @@ module Vault
|
|
126
171
|
# @example
|
127
172
|
# Vault.auth_token.revoke_prefix("abcd-1234") #=> true
|
128
173
|
#
|
129
|
-
# @param [String]
|
130
|
-
# the
|
174
|
+
# @param [String] prefix
|
175
|
+
# the prefix to revoke
|
131
176
|
#
|
132
177
|
# @return [true]
|
133
178
|
def revoke_prefix(prefix)
|
data/lib/vault/api/help.rb
CHANGED
@@ -3,13 +3,23 @@ require_relative "../response"
|
|
3
3
|
|
4
4
|
module Vault
|
5
5
|
# Help is the response from a help query.
|
6
|
-
class Help < Response
|
6
|
+
class Help < Response
|
7
|
+
# @!attribute [r] help
|
8
|
+
# The help information.
|
9
|
+
# @return [String]
|
10
|
+
field :help
|
11
|
+
|
12
|
+
# @!attribute [r] see_also
|
13
|
+
# Additional help documentation to see.
|
14
|
+
# @return [String]
|
15
|
+
field :see_also
|
16
|
+
end
|
7
17
|
|
8
18
|
class Client
|
9
19
|
# Gets help for the given path.
|
10
20
|
#
|
11
21
|
# @example
|
12
|
-
# Vault.help #=> #<Vault::Help help="..." see_also="...">
|
22
|
+
# Vault.help("secret") #=> #<Vault::Help help="..." see_also="...">
|
13
23
|
#
|
14
24
|
# @param [String] path
|
15
25
|
# the path to get help for
|
data/lib/vault/api/logical.rb
CHANGED
@@ -23,8 +23,9 @@ module Vault
|
|
23
23
|
# the path to list
|
24
24
|
#
|
25
25
|
# @return [Array<String>]
|
26
|
-
def list(path)
|
27
|
-
|
26
|
+
def list(path, options = {})
|
27
|
+
headers = extract_headers!(options)
|
28
|
+
json = client.list("/v1/#{CGI.escape(path)}", {}, headers)
|
28
29
|
json[:data][:keys] || []
|
29
30
|
rescue HTTPError => e
|
30
31
|
return [] if e.code == 404
|
@@ -41,8 +42,9 @@ module Vault
|
|
41
42
|
# the path to read
|
42
43
|
#
|
43
44
|
# @return [Secret, nil]
|
44
|
-
def read(path)
|
45
|
-
|
45
|
+
def read(path, options = {})
|
46
|
+
headers = extract_headers!(options)
|
47
|
+
json = client.get("/v1/#{CGI.escape(path)}", {}, headers)
|
46
48
|
return Secret.decode(json)
|
47
49
|
rescue HTTPError => e
|
48
50
|
return nil if e.code == 404
|
@@ -61,8 +63,9 @@ module Vault
|
|
61
63
|
# the data to write
|
62
64
|
#
|
63
65
|
# @return [Secret]
|
64
|
-
def write(path, data = {})
|
65
|
-
|
66
|
+
def write(path, data = {}, options = {})
|
67
|
+
headers = extract_headers!(options)
|
68
|
+
json = client.put("/v1/#{CGI.escape(path)}", JSON.fast_generate(data), headers)
|
66
69
|
if json.nil?
|
67
70
|
return true
|
68
71
|
else
|
@@ -84,5 +87,64 @@ module Vault
|
|
84
87
|
client.delete("/v1/#{CGI.escape(path)}")
|
85
88
|
return true
|
86
89
|
end
|
90
|
+
|
91
|
+
# Unwrap the data stored against the given token. If the secret does not
|
92
|
+
# exist, `nil` will be returned.
|
93
|
+
#
|
94
|
+
# @example
|
95
|
+
# Vault.logical.unwrap("f363dba8-25a7-08c5-430c-00b2367124e6") #=> #<Vault::Secret lease_id="">
|
96
|
+
#
|
97
|
+
# @param [String] wrapper
|
98
|
+
# the token to use when unwrapping the value
|
99
|
+
#
|
100
|
+
# @return [Secret, nil]
|
101
|
+
def unwrap(wrapper)
|
102
|
+
client.with_token(wrapper) do |client|
|
103
|
+
json = client.get("/v1/cubbyhole/response")
|
104
|
+
secret = Secret.decode(json)
|
105
|
+
|
106
|
+
# If there is nothing in the cubbyhole, return early.
|
107
|
+
if secret.nil? || secret.data.nil? || secret.data[:response].nil?
|
108
|
+
return nil
|
109
|
+
end
|
110
|
+
|
111
|
+
# Extract the response and parse it into a new secret.
|
112
|
+
json = JSON.parse(secret.data[:response], symbolize_names: true)
|
113
|
+
secret = Secret.decode(json)
|
114
|
+
return secret
|
115
|
+
end
|
116
|
+
rescue HTTPError => e
|
117
|
+
return nil if e.code == 404
|
118
|
+
raise
|
119
|
+
end
|
120
|
+
|
121
|
+
# Unwrap a token in a wrapped response given the temporary token.
|
122
|
+
#
|
123
|
+
# @example
|
124
|
+
# Vault.logical.unwrap("f363dba8-25a7-08c5-430c-00b2367124e6") #=> "0f0f40fd-06ce-4af1-61cb-cdc12796f42b"
|
125
|
+
#
|
126
|
+
# @param [String, Secret] wrapper
|
127
|
+
# the token to unwrap
|
128
|
+
#
|
129
|
+
# @return [String, nil]
|
130
|
+
def unwrap_token(wrapper)
|
131
|
+
# If provided a secret, grab the token. This is really just to make the
|
132
|
+
# API a bit nicer.
|
133
|
+
if wrapper.is_a?(Secret)
|
134
|
+
wrapper = wrapper.wrap_info.token
|
135
|
+
end
|
136
|
+
|
137
|
+
# Unwrap
|
138
|
+
response = unwrap(wrapper)
|
139
|
+
|
140
|
+
# If nothing was there, return nil
|
141
|
+
if response.nil? || response.auth.nil?
|
142
|
+
return nil
|
143
|
+
end
|
144
|
+
|
145
|
+
return response.auth.client_token
|
146
|
+
rescue HTTPError => e
|
147
|
+
raise
|
148
|
+
end
|
87
149
|
end
|
88
150
|
end
|
data/lib/vault/api/secret.rb
CHANGED
@@ -1,23 +1,154 @@
|
|
1
1
|
require_relative "../response"
|
2
2
|
|
3
3
|
module Vault
|
4
|
-
# Secret is a representation of a secret.
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
4
|
+
# Secret is a representation of a secret from Vault. Almost all data returned
|
5
|
+
# from Vault is represented as a secret.
|
6
|
+
class Secret < Response
|
7
|
+
# @!attribute [r] auth
|
8
|
+
# Authentication information for this secret, if any. Most secrets will
|
9
|
+
# contain this field, but it may also be `nil`. When authenticating to
|
10
|
+
# Vault, the resulting Vault token will be included in this embedded
|
11
|
+
# field.
|
12
|
+
#
|
13
|
+
# @example Authenticating to Vault
|
14
|
+
# secret = Vault.auth.userpass("username", "password")
|
15
|
+
# secret.auth.client_token #=> "fdb29070-6379-70c9-ca3a-46152fb66de1"
|
16
|
+
#
|
17
|
+
# @return [SecretAuth, nil]
|
18
|
+
field :auth, load: ->(v) { SecretAuth.decode(v) }
|
19
|
+
|
20
|
+
# @!attribute [r] data
|
21
|
+
# Arbitrary data returned by the secret. The keys returned are dependent
|
22
|
+
# upon the request made. For more information on the names of the keys
|
23
|
+
# that may be returned, please see the Vault documentation.
|
24
|
+
#
|
25
|
+
# @example Reading data
|
26
|
+
# secret = Vault.auth.token("abcd1234")
|
27
|
+
# secret.data[:id] #=> "abcd1234"
|
28
|
+
# secret.data[:ttl] #=> 0
|
29
|
+
#
|
30
|
+
# @return [Hash<Symbol, Object>]
|
31
|
+
field :data, freeze: true
|
32
|
+
|
33
|
+
# @!attribute [r] lease_duration
|
34
|
+
# The number of seconds this lease is valid. If this number is 0 or nil,
|
35
|
+
# the secret does not expire.
|
36
|
+
#
|
37
|
+
# @example Getting lease duration
|
38
|
+
# secret = Vault.logical.read("secret/foo")
|
39
|
+
# secret.lease_duration #=> 2592000 # 30 days
|
40
|
+
#
|
41
|
+
# @return [Fixnum]
|
42
|
+
field :lease_duration
|
43
|
+
|
44
|
+
# @!attribute [r] lease_id
|
45
|
+
# Unique ID for the lease associated with this secret. The `lease_id` is a
|
46
|
+
# path and UUID that uniquely represents the secret. This may be used for
|
47
|
+
# renewing and revoking the secret, if permitted.
|
48
|
+
#
|
49
|
+
# @example Getting lease ID
|
50
|
+
# secret = Vault.logical.read("postgresql/creds/readonly")
|
51
|
+
# secret.lease_id #=> "postgresql/readonly/fdb29070-6379-70c9-ca3a-46152fb66de1"
|
52
|
+
#
|
53
|
+
# @return [String]
|
54
|
+
field :lease_id
|
55
|
+
|
56
|
+
# @!method [r] renewable?
|
57
|
+
# Returns whether this lease is renewable.
|
58
|
+
#
|
59
|
+
# @example Checking if a lease is renewable
|
60
|
+
# secret = Vault.logical.read("secret/foo")
|
61
|
+
# secret.renewable? #=> false
|
62
|
+
#
|
63
|
+
# @return [Boolean]
|
64
|
+
field :renewable, as: :renewable?
|
65
|
+
|
66
|
+
# @!attribute [r] warnings
|
67
|
+
# List of warnings returned by the Vault server. These are returned by the
|
68
|
+
# Vault server and may include deprecation information, new APIs, or
|
69
|
+
# request using the API differently in the future.
|
70
|
+
#
|
71
|
+
# @example Display warnings
|
72
|
+
# result = Vault.logical.read("secret/foo")
|
73
|
+
# result.warnings #=> ["This path has been deprecated"]
|
74
|
+
#
|
75
|
+
# @return [Array<String>, nil]
|
76
|
+
field :warnings, freeze: true
|
77
|
+
|
78
|
+
# @!attribute [r] wrap_info
|
79
|
+
# Wrapped information sent with the request (only present in Vault 0.6+).
|
80
|
+
# @return [WrapInfo, nil]
|
81
|
+
field :wrap_info, load: ->(v) { WrapInfo.decode(v) }
|
82
|
+
end
|
83
|
+
|
84
|
+
# SecretAuth is a struct that contains the information about auth data, if
|
85
|
+
# present. This is never returned alone and is usually embededded in a
|
86
|
+
# {Secret}.
|
87
|
+
class SecretAuth < Response
|
88
|
+
# @!attribute [r] accessor
|
89
|
+
# Accessor for the token. This is like a `lease_id`, but for a token.
|
90
|
+
# @return [String]
|
91
|
+
field :accessor
|
92
|
+
|
93
|
+
# @!attribute [r] client_token
|
94
|
+
# The client token for this authentication.
|
95
|
+
# @return [String]
|
96
|
+
field :client_token
|
97
|
+
|
98
|
+
# @!attribute [r] lease_duration
|
99
|
+
# Number of seconds the token is valid.
|
100
|
+
# @return [Fixnum]
|
101
|
+
field :lease_duration
|
102
|
+
|
103
|
+
# @!attribute [r] metadata
|
104
|
+
# Arbitrary metadata from the authentication.
|
105
|
+
#
|
106
|
+
# @example Listing metadata attached to an authentication
|
107
|
+
# auth.metadata #=> { :username => "sethvargo" }
|
108
|
+
#
|
109
|
+
# @return [Hash<Symbol, Object>, nil]
|
110
|
+
field :metadata, freeze: true
|
111
|
+
|
112
|
+
# @!attribute [r] policies
|
113
|
+
# List of policies attached to this authentication.
|
114
|
+
#
|
115
|
+
# @example Listing policies attached to an authentication
|
116
|
+
# auth.policies #=> ["default"]
|
117
|
+
#
|
118
|
+
# @return [Array<String>, nil]
|
119
|
+
field :policies, freeze: true
|
120
|
+
|
121
|
+
# @!attribute [r] renewable
|
122
|
+
# Returns whether this authentication is renewable.
|
123
|
+
#
|
124
|
+
# @example Checking if an authentication is renewable
|
125
|
+
# auth.renewable? #=> false
|
126
|
+
#
|
127
|
+
# @return [Boolean]
|
128
|
+
field :renewable, as: :renewable?
|
17
129
|
end
|
18
130
|
|
19
|
-
#
|
20
|
-
|
21
|
-
|
131
|
+
# WrapInfo is the information returned by a wrapped response. This is almost
|
132
|
+
# always embedded as part of a {Secret}.
|
133
|
+
class WrapInfo < Response
|
134
|
+
# @!attribute [r] token
|
135
|
+
# Wrapped response token. This token may be used to unwrap the response.
|
136
|
+
# @return [String]
|
137
|
+
field :token
|
138
|
+
|
139
|
+
# @!attribute [r] wrapped_accessor
|
140
|
+
# Accessor for the wrapped token. This is like a `lease_id`, but for a token.
|
141
|
+
# @return [String]
|
142
|
+
field :wrapped_accessor
|
143
|
+
|
144
|
+
# @!attribute [r] creation_time
|
145
|
+
# Date & time when the wrapped token was created
|
146
|
+
# @return [Time]
|
147
|
+
field :creation_time, load: ->(v) { Time.parse(v) }
|
148
|
+
|
149
|
+
# @!attribute [r] ttl
|
150
|
+
# The TTL on the token returned in seconds.
|
151
|
+
# @return [Fixnum]
|
152
|
+
field :ttl
|
22
153
|
end
|
23
154
|
end
|
data/lib/vault/api/sys/audit.rb
CHANGED
@@ -1,9 +1,22 @@
|
|
1
1
|
require "json"
|
2
2
|
|
3
|
-
require_relative "../sys"
|
4
|
-
|
5
3
|
module Vault
|
6
|
-
class Audit < Response
|
4
|
+
class Audit < Response
|
5
|
+
# @!attribute [r] description
|
6
|
+
# Description of the audit backend.
|
7
|
+
# @return [String]
|
8
|
+
field :description
|
9
|
+
|
10
|
+
# @!attribute [r] options
|
11
|
+
# Map of options configured to the audit backend.
|
12
|
+
# @return [Hash<Symbol, Object>]
|
13
|
+
field :options
|
14
|
+
|
15
|
+
# @!attribute [r] type
|
16
|
+
# Name of the audit backend.
|
17
|
+
# @return [String]
|
18
|
+
field :type
|
19
|
+
end
|
7
20
|
|
8
21
|
class Sys
|
9
22
|
# List all audis for the vault.
|
data/lib/vault/api/sys/auth.rb
CHANGED
@@ -1,9 +1,17 @@
|
|
1
1
|
require "json"
|
2
2
|
|
3
|
-
require_relative "../sys"
|
4
|
-
|
5
3
|
module Vault
|
6
|
-
class Auth < Response
|
4
|
+
class Auth < Response
|
5
|
+
# @!attribute [r] description
|
6
|
+
# Description of the auth backend.
|
7
|
+
# @return [String]
|
8
|
+
field :description
|
9
|
+
|
10
|
+
# @!attribute [r] type
|
11
|
+
# Name of the auth backend.
|
12
|
+
# @return [String]
|
13
|
+
field :type
|
14
|
+
end
|
7
15
|
|
8
16
|
class Sys
|
9
17
|
# List all auths in Vault.
|
data/lib/vault/api/sys/init.rb
CHANGED
@@ -1,12 +1,23 @@
|
|
1
1
|
require "json"
|
2
2
|
|
3
|
-
require_relative "../sys"
|
4
|
-
|
5
3
|
module Vault
|
6
|
-
class InitResponse < Response
|
4
|
+
class InitResponse < Response
|
5
|
+
# @!attribute [r] keys
|
6
|
+
# List of unseal keys.
|
7
|
+
# @return [Array<String>]
|
8
|
+
field :keys
|
9
|
+
|
10
|
+
# @!attribute [r] root_token
|
11
|
+
# Initial root token.
|
12
|
+
# @return [String]
|
13
|
+
field :root_token
|
14
|
+
end
|
7
15
|
|
8
|
-
class InitStatus < Response
|
9
|
-
|
16
|
+
class InitStatus < Response
|
17
|
+
# @!method initialized?
|
18
|
+
# Returns whether the Vault server is initialized.
|
19
|
+
# @return [Boolean]
|
20
|
+
field :initialized, as: :initialized?
|
10
21
|
end
|
11
22
|
|
12
23
|
class Sys
|
@@ -33,12 +44,15 @@ module Vault
|
|
33
44
|
# the number of shares
|
34
45
|
# @option options [Fixnum] :threshold
|
35
46
|
# the number of keys needed to unlock
|
47
|
+
# @option options [Array] :pgp_keys
|
48
|
+
# an optional Array of base64-encoded PGP public keys to encrypt shares with
|
36
49
|
#
|
37
50
|
# @return [InitResponse]
|
38
51
|
def init(options = {})
|
39
52
|
json = client.put("/v1/sys/init", JSON.fast_generate(
|
40
53
|
secret_shares: options.fetch(:shares, 5),
|
41
54
|
secret_threshold: options.fetch(:threshold, 3),
|
55
|
+
pgp_keys: options.fetch(:pgp_keys, nil)
|
42
56
|
))
|
43
57
|
return InitResponse.decode(json)
|
44
58
|
end
|
data/lib/vault/api/sys/leader.rb
CHANGED
@@ -1,13 +1,31 @@
|
|
1
|
-
require_relative "../sys"
|
2
|
-
|
3
1
|
module Vault
|
4
|
-
class LeaderStatus < Response
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
class LeaderStatus < Response
|
3
|
+
# @!method ha_enabled?
|
4
|
+
# Returns whether the high-availability mode is enabled.
|
5
|
+
# @return [Boolean]
|
6
|
+
field :ha_enabled, as: :ha_enabled?
|
7
|
+
|
8
|
+
# @!method leader?
|
9
|
+
# Returns whether the Vault server queried is the leader.
|
10
|
+
# @return [Boolean]
|
11
|
+
field :is_self, as: :leader?
|
12
|
+
|
13
|
+
# @!attribute [r] address
|
14
|
+
# URL where the server is running.
|
15
|
+
# @return [String]
|
16
|
+
field :leader_address, as: :address
|
17
|
+
|
18
|
+
# @deprecated Use {#ha_enabled?} instead
|
19
|
+
def ha?; ha_enabled?; end
|
20
|
+
|
21
|
+
# @deprecated Use {#leader?} instead
|
22
|
+
def is_leader?; leader?; end
|
23
|
+
|
24
|
+
# @deprecated Use {#leader?} instead
|
25
|
+
def is_self?; leader?; end
|
26
|
+
|
27
|
+
# @deprecated Use {#leader?} instead
|
28
|
+
def self?; leader?; end
|
11
29
|
end
|
12
30
|
|
13
31
|
class Sys
|
data/lib/vault/api/sys/lease.rb
CHANGED
data/lib/vault/api/sys/mount.rb
CHANGED
@@ -1,9 +1,22 @@
|
|
1
1
|
require "json"
|
2
2
|
|
3
|
-
require_relative "../sys"
|
4
|
-
|
5
3
|
module Vault
|
6
|
-
class Mount < Response
|
4
|
+
class Mount < Response
|
5
|
+
# @!attribute [r] config
|
6
|
+
# Arbitrary configuration for the backend.
|
7
|
+
# @return [Hash<Symbol, Object>]
|
8
|
+
field :config
|
9
|
+
|
10
|
+
# @!attribute [r] description
|
11
|
+
# Description of the mount.
|
12
|
+
# @return [String]
|
13
|
+
field :description
|
14
|
+
|
15
|
+
# @!attribute [r] type
|
16
|
+
# Type of the mount.
|
17
|
+
# @return [String]
|
18
|
+
field :type
|
19
|
+
end
|
7
20
|
|
8
21
|
class Sys < Request
|
9
22
|
# List all mounts in the vault.
|
@@ -38,6 +51,20 @@ module Vault
|
|
38
51
|
return true
|
39
52
|
end
|
40
53
|
|
54
|
+
# Tune a mount at the given path.
|
55
|
+
#
|
56
|
+
# @example
|
57
|
+
# Vault.sys.mount_tune("pki", max_lease_ttl: '87600h') #=> true
|
58
|
+
#
|
59
|
+
# @param [String] path
|
60
|
+
# the path to write
|
61
|
+
# @param [Hash] data
|
62
|
+
# the data to write
|
63
|
+
def mount_tune(path, data = {})
|
64
|
+
json = client.post("/v1/sys/mounts/#{CGI.escape(path)}/tune", JSON.fast_generate(data))
|
65
|
+
return true
|
66
|
+
end
|
67
|
+
|
41
68
|
# Unmount the thing at the given path. If the mount does not exist, an error
|
42
69
|
# will be raised.
|
43
70
|
#
|
data/lib/vault/api/sys/policy.rb
CHANGED
@@ -1,9 +1,25 @@
|
|
1
1
|
require "json"
|
2
2
|
|
3
|
-
require_relative "../sys"
|
4
|
-
|
5
3
|
module Vault
|
6
|
-
class Policy < Response
|
4
|
+
class Policy < Response
|
5
|
+
# @!attribute [r] name
|
6
|
+
# Name of the policy.
|
7
|
+
#
|
8
|
+
# @example Get the name of the policy
|
9
|
+
# policy.name #=> "default"
|
10
|
+
#
|
11
|
+
# @return [String]
|
12
|
+
field :name
|
13
|
+
|
14
|
+
# @!attribute [r] rules
|
15
|
+
# Raw HCL policy.
|
16
|
+
#
|
17
|
+
# @example Display the list of rules
|
18
|
+
# policy.rules #=> "path \"secret/foo\" {}"
|
19
|
+
#
|
20
|
+
# @return [String]
|
21
|
+
field :rules
|
22
|
+
end
|
7
23
|
|
8
24
|
class Sys
|
9
25
|
# The list of policies in vault.
|
data/lib/vault/api/sys/seal.rb
CHANGED
@@ -1,10 +1,42 @@
|
|
1
1
|
require "json"
|
2
2
|
|
3
|
-
require_relative "../sys"
|
4
|
-
|
5
3
|
module Vault
|
6
|
-
class SealStatus < Response
|
7
|
-
|
4
|
+
class SealStatus < Response
|
5
|
+
# @!method sealed?
|
6
|
+
# Returns if the Vault is sealed.
|
7
|
+
#
|
8
|
+
# @example Check if the Vault is sealed
|
9
|
+
# status.sealed? #=> true
|
10
|
+
#
|
11
|
+
# @return [Boolean]
|
12
|
+
field :sealed, as: :sealed?
|
13
|
+
|
14
|
+
# @!attribute t
|
15
|
+
# Threshold of keys required to unseal the Vault.
|
16
|
+
#
|
17
|
+
# @example Get the threshold of keys
|
18
|
+
# status.t #=> 3
|
19
|
+
#
|
20
|
+
# @return [Fixnum]
|
21
|
+
field :t
|
22
|
+
|
23
|
+
# @!attribute n
|
24
|
+
# Total number of unseal keys.
|
25
|
+
#
|
26
|
+
# @example Get the total number of keys
|
27
|
+
# status.n #=> 5
|
28
|
+
#
|
29
|
+
# @return [Fixnum]
|
30
|
+
field :n
|
31
|
+
|
32
|
+
# @!attribute progress
|
33
|
+
# Number of keys that have been entered.
|
34
|
+
#
|
35
|
+
# @example Get the current unseal progress
|
36
|
+
# status.progress #=> 2
|
37
|
+
#
|
38
|
+
# @return [Fixnum]
|
39
|
+
field :progress
|
8
40
|
end
|
9
41
|
|
10
42
|
class Sys
|
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 to hold the wrapped request ttl.
|
20
|
+
WRAP_TTL_HEADER = "X-Vault-Wrap-TTL".freeze
|
21
|
+
|
19
22
|
# The name of the header used for redirection.
|
20
23
|
LOCATION_HEADER = "location".freeze
|
21
24
|
|
@@ -66,6 +69,18 @@ module Vault
|
|
66
69
|
end
|
67
70
|
end
|
68
71
|
|
72
|
+
# Creates and yields a new client object with the given token. This may be
|
73
|
+
# used safely in a threadsafe manner because the original client remains
|
74
|
+
# unchanged. The value of the block is returned.
|
75
|
+
#
|
76
|
+
# @yield [Vault::Client]
|
77
|
+
def with_token(token)
|
78
|
+
client = self.dup
|
79
|
+
client.token = token
|
80
|
+
return yield client if block_given?
|
81
|
+
return nil
|
82
|
+
end
|
83
|
+
|
69
84
|
# Determine if the given options are the same as ours.
|
70
85
|
# @return [true, false]
|
71
86
|
def same_options?(opts)
|
@@ -78,6 +93,13 @@ module Vault
|
|
78
93
|
request(:get, path, params, headers)
|
79
94
|
end
|
80
95
|
|
96
|
+
# Perform a LIST request.
|
97
|
+
# @see Client#request
|
98
|
+
def list(path, params = {}, headers = {})
|
99
|
+
params = params.merge(list: true)
|
100
|
+
request(:get, path, params, headers)
|
101
|
+
end
|
102
|
+
|
81
103
|
# Perform a POST request.
|
82
104
|
# @see Client#request
|
83
105
|
def post(path, data = {}, headers = {})
|
@@ -132,7 +154,7 @@ module Vault
|
|
132
154
|
# Add the Vault token header - users could still override this on a
|
133
155
|
# per-request basis
|
134
156
|
if !token.nil?
|
135
|
-
|
157
|
+
headers[TOKEN_HEADER] ||= token
|
136
158
|
end
|
137
159
|
|
138
160
|
# Add headers
|
data/lib/vault/defaults.rb
CHANGED
@@ -47,7 +47,7 @@ module Vault
|
|
47
47
|
end
|
48
48
|
|
49
49
|
if VAULT_DISK_TOKEN.exist? && VAULT_DISK_TOKEN.readable?
|
50
|
-
return VAULT_DISK_TOKEN.read
|
50
|
+
return VAULT_DISK_TOKEN.read.chomp
|
51
51
|
end
|
52
52
|
|
53
53
|
nil
|
@@ -128,7 +128,7 @@ module Vault
|
|
128
128
|
def ssl_verify
|
129
129
|
# Vault CLI uses this envvar, so accept it by precedence
|
130
130
|
if !ENV["VAULT_SKIP_VERIFY"].nil?
|
131
|
-
return
|
131
|
+
return false
|
132
132
|
end
|
133
133
|
|
134
134
|
if ENV["VAULT_SSL_VERIFY"].nil?
|
data/lib/vault/request.rb
CHANGED
@@ -15,5 +15,27 @@ module Vault
|
|
15
15
|
def inspect
|
16
16
|
"#<#{self.class.name}:0x#{"%x" % (self.object_id << 1)}>"
|
17
17
|
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Removes the given header fields from options and returns the result. This
|
22
|
+
# modifies the given options in place.
|
23
|
+
#
|
24
|
+
# @param [Hash] options
|
25
|
+
#
|
26
|
+
# @return [Hash]
|
27
|
+
def extract_headers!(options = {})
|
28
|
+
extract = {
|
29
|
+
wrap_ttl: Vault::Client::WRAP_TTL_HEADER,
|
30
|
+
}
|
31
|
+
|
32
|
+
{}.tap do |h|
|
33
|
+
extract.each do |k,v|
|
34
|
+
if options[k]
|
35
|
+
h[v] = options.delete(k)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
18
40
|
end
|
19
41
|
end
|
data/lib/vault/response.rb
CHANGED
@@ -1,18 +1,64 @@
|
|
1
1
|
module Vault
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
class Response
|
3
|
+
# Defines a new field. This is designed to be used by the subclass as a
|
4
|
+
# mini-DSL.
|
5
|
+
#
|
6
|
+
# @example Default
|
7
|
+
# field :data
|
8
|
+
#
|
9
|
+
# @example With a mutator
|
10
|
+
# field :present, as: :present?
|
11
|
+
#
|
12
|
+
# @param n [Symbol] the name of the field
|
13
|
+
# @option opts [Symbol] :as alias for method name
|
14
|
+
#
|
15
|
+
# @!visibility private
|
16
|
+
def self.field(n, opts = {})
|
17
|
+
self.fields[n] = opts
|
8
18
|
|
9
|
-
|
10
|
-
|
19
|
+
if opts[:as].nil?
|
20
|
+
attr_reader n
|
21
|
+
else
|
22
|
+
define_method(opts[:as]) do
|
23
|
+
instance_variable_get(:"@#{n}")
|
11
24
|
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the list of fields defined on this subclass.
|
29
|
+
# @!visibility private
|
30
|
+
def self.fields
|
31
|
+
@fields ||= {}
|
32
|
+
end
|
33
|
+
|
34
|
+
# Decodes the given object (usually a Hash) into an instance of this class.
|
35
|
+
#
|
36
|
+
# @param object [Hash<Symbol, Object>]
|
37
|
+
def self.decode(object)
|
38
|
+
self.new(object)
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(opts = {})
|
42
|
+
# Initialize all fields as nil to start
|
43
|
+
self.class.fields.each do |k, _|
|
44
|
+
instance_variable_set(:"@#{k}", nil)
|
45
|
+
end
|
46
|
+
|
47
|
+
# For each supplied option, set the instance variable if it was defined
|
48
|
+
# as a field.
|
49
|
+
opts.each do |k, v|
|
50
|
+
if self.class.fields.key?(k)
|
51
|
+
opts = self.class.fields[k]
|
52
|
+
|
53
|
+
if (m = opts[:load]) && !v.nil?
|
54
|
+
v = m.call(v)
|
55
|
+
end
|
56
|
+
|
57
|
+
if opts[:freeze]
|
58
|
+
v = v.freeze
|
59
|
+
end
|
12
60
|
|
13
|
-
|
14
|
-
data = self.members.map { |m| "@#{m}=#{self.public_send(m).inspect}" }.join(", ")
|
15
|
-
"#<#{self.class.name} #{data}>"
|
61
|
+
instance_variable_set(:"@#{k}", v)
|
16
62
|
end
|
17
63
|
end
|
18
64
|
end
|
data/lib/vault/version.rb
CHANGED
data/vault.gemspec
CHANGED
@@ -23,5 +23,6 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "pry"
|
24
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
25
|
spec.add_development_dependency "rspec", "~> 3.2"
|
26
|
+
spec.add_development_dependency "yard"
|
26
27
|
spec.add_development_dependency "webmock", "~> 1.22"
|
27
28
|
end
|
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.5.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: 2016-
|
11
|
+
date: 2016-08-16 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: yard
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: webmock
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -139,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
153
|
version: '0'
|
140
154
|
requirements: []
|
141
155
|
rubyforge_project:
|
142
|
-
rubygems_version: 2.
|
156
|
+
rubygems_version: 2.4.5.1
|
143
157
|
signing_key:
|
144
158
|
specification_version: 4
|
145
159
|
summary: Vault is a Ruby API client for interacting with a Vault server.
|