vault 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|