vault-kv 0.12.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 +7 -0
- data/.gitignore +42 -0
- data/.rspec +2 -0
- data/.travis.yml +29 -0
- data/CHANGELOG.md +228 -0
- data/Gemfile +3 -0
- data/LICENSE +362 -0
- data/README.md +212 -0
- data/Rakefile +6 -0
- data/lib/vault.rb +49 -0
- data/lib/vault/api.rb +13 -0
- data/lib/vault/api/approle.rb +218 -0
- data/lib/vault/api/auth.rb +316 -0
- data/lib/vault/api/auth_tls.rb +92 -0
- data/lib/vault/api/auth_token.rb +242 -0
- data/lib/vault/api/help.rb +33 -0
- data/lib/vault/api/kv.rb +207 -0
- data/lib/vault/api/logical.rb +150 -0
- data/lib/vault/api/secret.rb +168 -0
- data/lib/vault/api/sys.rb +25 -0
- data/lib/vault/api/sys/audit.rb +91 -0
- data/lib/vault/api/sys/auth.rb +116 -0
- data/lib/vault/api/sys/health.rb +63 -0
- data/lib/vault/api/sys/init.rb +83 -0
- data/lib/vault/api/sys/leader.rb +48 -0
- data/lib/vault/api/sys/lease.rb +49 -0
- data/lib/vault/api/sys/mount.rb +103 -0
- data/lib/vault/api/sys/policy.rb +92 -0
- data/lib/vault/api/sys/seal.rb +81 -0
- data/lib/vault/client.rb +447 -0
- data/lib/vault/configurable.rb +48 -0
- data/lib/vault/defaults.rb +197 -0
- data/lib/vault/encode.rb +19 -0
- data/lib/vault/errors.rb +72 -0
- data/lib/vault/persistent.rb +1158 -0
- data/lib/vault/persistent/connection.rb +42 -0
- data/lib/vault/persistent/pool.rb +48 -0
- data/lib/vault/persistent/timed_stack_multi.rb +70 -0
- data/lib/vault/request.rb +43 -0
- data/lib/vault/response.rb +89 -0
- data/lib/vault/vendor/connection_pool.rb +150 -0
- data/lib/vault/vendor/connection_pool/timed_stack.rb +178 -0
- data/lib/vault/vendor/connection_pool/version.rb +5 -0
- data/lib/vault/version.rb +3 -0
- data/vault.gemspec +30 -0
- metadata +186 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative "../client"
|
2
|
+
require_relative "../request"
|
3
|
+
require_relative "../response"
|
4
|
+
|
5
|
+
module Vault
|
6
|
+
class Client
|
7
|
+
# A proxy to the {Sys} methods.
|
8
|
+
# @return [Sys]
|
9
|
+
def sys
|
10
|
+
@sys ||= Sys.new(self)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Sys < Request; end
|
15
|
+
end
|
16
|
+
|
17
|
+
require_relative "sys/audit"
|
18
|
+
require_relative "sys/auth"
|
19
|
+
require_relative "sys/health"
|
20
|
+
require_relative "sys/init"
|
21
|
+
require_relative "sys/leader"
|
22
|
+
require_relative "sys/lease"
|
23
|
+
require_relative "sys/mount"
|
24
|
+
require_relative "sys/policy"
|
25
|
+
require_relative "sys/seal"
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Vault
|
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
|
20
|
+
|
21
|
+
class Sys
|
22
|
+
# List all audits for the vault.
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# Vault.sys.audits #=> { :file => #<Audit> }
|
26
|
+
#
|
27
|
+
# @return [Hash<Symbol, Audit>]
|
28
|
+
def audits
|
29
|
+
json = client.get("/v1/sys/audit")
|
30
|
+
json = json[:data] if json[:data]
|
31
|
+
return Hash[*json.map do |k,v|
|
32
|
+
[k.to_s.chomp("/").to_sym, Audit.decode(v)]
|
33
|
+
end.flatten]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Enable a particular audit. Note: the +options+ depend heavily on the
|
37
|
+
# type of audit being enabled. Please refer to audit-specific documentation
|
38
|
+
# for which need to be enabled.
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# Vault.sys.enable_audit("/file-audit", "file", "File audit", path: "/path/on/disk") #=> true
|
42
|
+
#
|
43
|
+
# @param [String] path
|
44
|
+
# the path to mount the audit
|
45
|
+
# @param [String] type
|
46
|
+
# the type of audit to enable
|
47
|
+
# @param [String] description
|
48
|
+
# a human-friendly description of the audit backend
|
49
|
+
# @param [Hash] options
|
50
|
+
# audit-specific options
|
51
|
+
#
|
52
|
+
# @return [true]
|
53
|
+
def enable_audit(path, type, description, options = {})
|
54
|
+
client.put("/v1/sys/audit/#{encode_path(path)}", JSON.fast_generate(
|
55
|
+
type: type,
|
56
|
+
description: description,
|
57
|
+
options: options,
|
58
|
+
))
|
59
|
+
return true
|
60
|
+
end
|
61
|
+
|
62
|
+
# Disable a particular audit. If an audit does not exist, and error will be
|
63
|
+
# raised.
|
64
|
+
#
|
65
|
+
# @param [String] path
|
66
|
+
# the path of the audit to disable
|
67
|
+
#
|
68
|
+
# @return [true]
|
69
|
+
def disable_audit(path)
|
70
|
+
client.delete("/v1/sys/audit/#{encode_path(path)}")
|
71
|
+
return true
|
72
|
+
end
|
73
|
+
|
74
|
+
# Generates a HMAC verifier for a given input.
|
75
|
+
#
|
76
|
+
# @example
|
77
|
+
# Vault.sys.audit_hash("file-audit", "my input") #=> "hmac-sha256:30aa7de18a5e90bbc1063db91e7c387b32b9fa895977eb8c177bbc91e7d7c542"
|
78
|
+
#
|
79
|
+
# @param [String] path
|
80
|
+
# the path of the audit backend
|
81
|
+
# @param [String] input
|
82
|
+
# the input to generate a HMAC for
|
83
|
+
#
|
84
|
+
# @return [String]
|
85
|
+
def audit_hash(path, input)
|
86
|
+
json = client.post("/v1/sys/audit-hash/#{encode_path(path)}", JSON.fast_generate(input: input))
|
87
|
+
json = json[:data] if json[:data]
|
88
|
+
json[:hash]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Vault
|
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
|
15
|
+
|
16
|
+
class AuthConfig < Response
|
17
|
+
# @!attribute [r] default_lease_ttl
|
18
|
+
# The default time-to-live.
|
19
|
+
# @return [String]
|
20
|
+
field :default_lease_ttl
|
21
|
+
|
22
|
+
# @!attribute [r] max_lease_ttl
|
23
|
+
# The maximum time-to-live.
|
24
|
+
# @return [String]
|
25
|
+
field :max_lease_ttl
|
26
|
+
end
|
27
|
+
|
28
|
+
class Sys
|
29
|
+
# List all auths in Vault.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# Vault.sys.auths #=> {:token => #<Vault::Auth type="token", description="token based credentials">}
|
33
|
+
#
|
34
|
+
# @return [Hash<Symbol, Auth>]
|
35
|
+
def auths
|
36
|
+
json = client.get("/v1/sys/auth")
|
37
|
+
json = json[:data] if json[:data]
|
38
|
+
return Hash[*json.map do |k,v|
|
39
|
+
[k.to_s.chomp("/").to_sym, Auth.decode(v)]
|
40
|
+
end.flatten]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Enable a particular authentication at the given path.
|
44
|
+
#
|
45
|
+
# @example
|
46
|
+
# Vault.sys.enable_auth("github", "github") #=> true
|
47
|
+
#
|
48
|
+
# @param [String] path
|
49
|
+
# the path to mount the auth
|
50
|
+
# @param [String] type
|
51
|
+
# the type of authentication
|
52
|
+
# @param [String] description
|
53
|
+
# a human-friendly description (optional)
|
54
|
+
#
|
55
|
+
# @return [true]
|
56
|
+
def enable_auth(path, type, description = nil)
|
57
|
+
payload = { type: type }
|
58
|
+
payload[:description] = description if !description.nil?
|
59
|
+
|
60
|
+
client.post("/v1/sys/auth/#{encode_path(path)}", JSON.fast_generate(payload))
|
61
|
+
return true
|
62
|
+
end
|
63
|
+
|
64
|
+
# Disable a particular authentication at the given path. If not auth
|
65
|
+
# exists at that path, an error will be raised.
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# Vault.sys.disable_auth("github") #=> true
|
69
|
+
#
|
70
|
+
# @param [String] path
|
71
|
+
# the path to disable
|
72
|
+
#
|
73
|
+
# @return [true]
|
74
|
+
def disable_auth(path)
|
75
|
+
client.delete("/v1/sys/auth/#{encode_path(path)}")
|
76
|
+
return true
|
77
|
+
end
|
78
|
+
|
79
|
+
# Read the given auth path's configuration.
|
80
|
+
#
|
81
|
+
# @example
|
82
|
+
# Vault.sys.auth_tune("github") #=> #<Vault::AuthConfig "default_lease_ttl"=3600, "max_lease_ttl"=7200>
|
83
|
+
#
|
84
|
+
# @param [String] path
|
85
|
+
# the path to retrieve configuration for
|
86
|
+
#
|
87
|
+
# @return [AuthConfig]
|
88
|
+
# configuration of the given auth path
|
89
|
+
def auth_tune(path)
|
90
|
+
json = client.get("/v1/sys/auth/#{encode_path(path)}/tune")
|
91
|
+
return AuthConfig.decode(json)
|
92
|
+
rescue HTTPError => e
|
93
|
+
return nil if e.code == 404
|
94
|
+
raise
|
95
|
+
end
|
96
|
+
|
97
|
+
# Write the given auth path's configuration.
|
98
|
+
#
|
99
|
+
# @example
|
100
|
+
# Vault.sys.auth_tune("github", "default_lease_ttl" => 600, "max_lease_ttl" => 1200 ) #=> true
|
101
|
+
#
|
102
|
+
# @param [String] path
|
103
|
+
# the path to retrieve configuration for
|
104
|
+
#
|
105
|
+
# @return [AuthConfig]
|
106
|
+
# configuration of the given auth path
|
107
|
+
def put_auth_tune(path, config = {})
|
108
|
+
json = client.put("/v1/sys/auth/#{encode_path(path)}/tune", JSON.fast_generate(config))
|
109
|
+
if json.nil?
|
110
|
+
return true
|
111
|
+
else
|
112
|
+
return Secret.decode(json)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Vault
|
4
|
+
class HealthStatus < Response
|
5
|
+
# @!attribute [r] initialized
|
6
|
+
# Whether the Vault server is Initialized.
|
7
|
+
# @return [Boolean]
|
8
|
+
field :initialized, as: :initialized?
|
9
|
+
|
10
|
+
# @!attribute [r] sealed
|
11
|
+
# Whether the Vault server is Sealed.
|
12
|
+
# @return [Boolean]
|
13
|
+
field :sealed, as: :sealed?
|
14
|
+
|
15
|
+
# @!attribute [r] standby
|
16
|
+
# Whether the Vault server is in Standby mode.
|
17
|
+
# @return [Boolean]
|
18
|
+
field :standby, as: :standby?
|
19
|
+
|
20
|
+
# @!attribute [r] replication_performance_mode
|
21
|
+
# Verbose description of DR mode (added in 0.9.2)
|
22
|
+
# @return [String]
|
23
|
+
field :replication_performance_mode
|
24
|
+
|
25
|
+
# @!attribute [r] replication_dr_mode
|
26
|
+
# Verbose description of DR mode (added in 0.9.2)
|
27
|
+
# @return [String]
|
28
|
+
field :replication_dr_mode
|
29
|
+
|
30
|
+
# @!attribute [r] server_time_utc
|
31
|
+
# Server time in Unix seconds, UTC
|
32
|
+
# @return [Fixnum]
|
33
|
+
field :server_time_utc
|
34
|
+
|
35
|
+
# @!attribute [r] version
|
36
|
+
# Server Vault version string (added in 0.6.1)
|
37
|
+
# @return [String]
|
38
|
+
field :version
|
39
|
+
|
40
|
+
# @!attribute [r] cluster_name
|
41
|
+
# Server cluster name
|
42
|
+
# @return [String]
|
43
|
+
field :cluster_name
|
44
|
+
|
45
|
+
# @!attribute [r] cluster_id
|
46
|
+
# Server cluster UUID
|
47
|
+
# @return [String]
|
48
|
+
field :cluster_id
|
49
|
+
end
|
50
|
+
|
51
|
+
class Sys
|
52
|
+
# Show the health status for this vault.
|
53
|
+
#
|
54
|
+
# @example
|
55
|
+
# Vault.sys.health_status #=> #Vault::HealthStatus @initialized=true, @sealed=false, @standby=false, @replication_performance_mode="disabled", @replication_dr_mode="disabled", @server_time_utc=1519776728, @version="0.9.3", @cluster_name="vault-cluster-997f514e", @cluster_id="c2dad70a-6d88-a06d-69f6-9ae7f5485998">
|
56
|
+
#
|
57
|
+
# @return [HealthStatus]
|
58
|
+
def health_status
|
59
|
+
json = client.get("/v1/sys/health", {:sealedcode => 200, :uninitcode => 200, :standbycode => 200})
|
60
|
+
return HealthStatus.decode(json)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Vault
|
4
|
+
class InitResponse < Response
|
5
|
+
# @!attribute [r] keys
|
6
|
+
# List of unseal keys.
|
7
|
+
# @return [Array<String>]
|
8
|
+
field :keys
|
9
|
+
|
10
|
+
# @!attribute [r] keys_base64
|
11
|
+
# List of unseal keys, base64-encoded
|
12
|
+
# @return [Array<String>]
|
13
|
+
field :keys_base64
|
14
|
+
|
15
|
+
# @!attribute [r] root_token
|
16
|
+
# Initial root token.
|
17
|
+
# @return [String]
|
18
|
+
field :root_token
|
19
|
+
end
|
20
|
+
|
21
|
+
class InitStatus < Response
|
22
|
+
# @!method initialized?
|
23
|
+
# Returns whether the Vault server is initialized.
|
24
|
+
# @return [Boolean]
|
25
|
+
field :initialized, as: :initialized?
|
26
|
+
end
|
27
|
+
|
28
|
+
class Sys
|
29
|
+
# Show the initialization status for this vault.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# Vault.sys.init_status #=> #<Vault::InitStatus initialized=true>
|
33
|
+
#
|
34
|
+
# @return [InitStatus]
|
35
|
+
def init_status
|
36
|
+
json = client.get("/v1/sys/init")
|
37
|
+
return InitStatus.decode(json)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Initialize a new vault.
|
41
|
+
#
|
42
|
+
# @example
|
43
|
+
# Vault.sys.init #=> #<Vault::InitResponse keys=["..."] root_token="...">
|
44
|
+
#
|
45
|
+
# @param [Hash] options
|
46
|
+
# the list of init options
|
47
|
+
#
|
48
|
+
# @option options [String] :root_token_pgp_key
|
49
|
+
# optional base64-encoded PGP public key used to encrypt the initial root
|
50
|
+
# token.
|
51
|
+
# @option options [Fixnum] :secret_shares
|
52
|
+
# the number of shares
|
53
|
+
# @option options [Fixnum] :secret_threshold
|
54
|
+
# the number of keys needed to unlock
|
55
|
+
# @option options [Array<String>] :pgp_keys
|
56
|
+
# an optional Array of base64-encoded PGP public keys to encrypt sharees
|
57
|
+
# @option options [Fixnum] :stored_shares
|
58
|
+
# the number of shares that should be encrypted by the HSM for
|
59
|
+
# auto-unsealing
|
60
|
+
# @option options [Fixnum] :recovery_shares
|
61
|
+
# the number of shares to split the recovery key into
|
62
|
+
# @option options [Fixnum] :recovery_threshold
|
63
|
+
# the number of shares required to reconstruct the recovery key
|
64
|
+
# @option options [Array<String>] :recovery_pgp_keys
|
65
|
+
# an array of PGP public keys used to encrypt the output for the recovery
|
66
|
+
# keys
|
67
|
+
#
|
68
|
+
# @return [InitResponse]
|
69
|
+
def init(options = {})
|
70
|
+
json = client.put("/v1/sys/init", JSON.fast_generate(
|
71
|
+
root_token_pgp_key: options.fetch(:root_token_pgp_key, nil),
|
72
|
+
secret_shares: options.fetch(:secret_shares, options.fetch(:shares, 5)),
|
73
|
+
secret_threshold: options.fetch(:secret_threshold, options.fetch(:threshold, 3)),
|
74
|
+
pgp_keys: options.fetch(:pgp_keys, nil),
|
75
|
+
stored_shares: options.fetch(:stored_shares, nil),
|
76
|
+
recovery_shares: options.fetch(:recovery_shares, nil),
|
77
|
+
recovery_threshold: options.fetch(:recovery_threshold, nil),
|
78
|
+
recovery_pgp_keys: options.fetch(:recovery_pgp_keys, nil),
|
79
|
+
))
|
80
|
+
return InitResponse.decode(json)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Vault
|
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
|
29
|
+
end
|
30
|
+
|
31
|
+
class Sys
|
32
|
+
# Determine the leader status for this vault.
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# Vault.sys.leader #=> #<Vault::LeaderStatus ha_enabled=false, is_self=false, leader_address="">
|
36
|
+
#
|
37
|
+
# @return [LeaderStatus]
|
38
|
+
def leader
|
39
|
+
json = client.get("/v1/sys/leader")
|
40
|
+
return LeaderStatus.decode(json)
|
41
|
+
end
|
42
|
+
|
43
|
+
def step_down
|
44
|
+
client.put("/v1/sys/step-down", nil)
|
45
|
+
return true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Vault
|
2
|
+
class Sys
|
3
|
+
# Renew a lease with the given ID.
|
4
|
+
#
|
5
|
+
# @example
|
6
|
+
# Vault.sys.renew("aws/username") #=> #<Vault::Secret ...>
|
7
|
+
#
|
8
|
+
# @param [String] id
|
9
|
+
# the lease ID
|
10
|
+
# @param [Fixnum] increment
|
11
|
+
#
|
12
|
+
# @return [Secret]
|
13
|
+
def renew(id, increment = 0)
|
14
|
+
json = client.put("/v1/sys/renew/#{id}", JSON.fast_generate(
|
15
|
+
increment: increment,
|
16
|
+
))
|
17
|
+
return Secret.decode(json)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Revoke the secret at the given id. If the secret does not exist, an error
|
21
|
+
# will be raised.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# Vault.sys.revoke("aws/username") #=> true
|
25
|
+
#
|
26
|
+
# @param [String] id
|
27
|
+
# the lease ID
|
28
|
+
#
|
29
|
+
# @return [true]
|
30
|
+
def revoke(id)
|
31
|
+
client.put("/v1/sys/revoke/#{id}", nil)
|
32
|
+
return true
|
33
|
+
end
|
34
|
+
|
35
|
+
# Revoke all secrets under the given prefix.
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# Vault.sys.revoke_prefix("aws") #=> true
|
39
|
+
#
|
40
|
+
# @param [String] id
|
41
|
+
# the lease ID
|
42
|
+
#
|
43
|
+
# @return [true]
|
44
|
+
def revoke_prefix(id)
|
45
|
+
client.put("/v1/sys/revoke-prefix/#{id}", nil)
|
46
|
+
return true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|