vault-kv 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +42 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +29 -0
  5. data/CHANGELOG.md +228 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +362 -0
  8. data/README.md +212 -0
  9. data/Rakefile +6 -0
  10. data/lib/vault.rb +49 -0
  11. data/lib/vault/api.rb +13 -0
  12. data/lib/vault/api/approle.rb +218 -0
  13. data/lib/vault/api/auth.rb +316 -0
  14. data/lib/vault/api/auth_tls.rb +92 -0
  15. data/lib/vault/api/auth_token.rb +242 -0
  16. data/lib/vault/api/help.rb +33 -0
  17. data/lib/vault/api/kv.rb +207 -0
  18. data/lib/vault/api/logical.rb +150 -0
  19. data/lib/vault/api/secret.rb +168 -0
  20. data/lib/vault/api/sys.rb +25 -0
  21. data/lib/vault/api/sys/audit.rb +91 -0
  22. data/lib/vault/api/sys/auth.rb +116 -0
  23. data/lib/vault/api/sys/health.rb +63 -0
  24. data/lib/vault/api/sys/init.rb +83 -0
  25. data/lib/vault/api/sys/leader.rb +48 -0
  26. data/lib/vault/api/sys/lease.rb +49 -0
  27. data/lib/vault/api/sys/mount.rb +103 -0
  28. data/lib/vault/api/sys/policy.rb +92 -0
  29. data/lib/vault/api/sys/seal.rb +81 -0
  30. data/lib/vault/client.rb +447 -0
  31. data/lib/vault/configurable.rb +48 -0
  32. data/lib/vault/defaults.rb +197 -0
  33. data/lib/vault/encode.rb +19 -0
  34. data/lib/vault/errors.rb +72 -0
  35. data/lib/vault/persistent.rb +1158 -0
  36. data/lib/vault/persistent/connection.rb +42 -0
  37. data/lib/vault/persistent/pool.rb +48 -0
  38. data/lib/vault/persistent/timed_stack_multi.rb +70 -0
  39. data/lib/vault/request.rb +43 -0
  40. data/lib/vault/response.rb +89 -0
  41. data/lib/vault/vendor/connection_pool.rb +150 -0
  42. data/lib/vault/vendor/connection_pool/timed_stack.rb +178 -0
  43. data/lib/vault/vendor/connection_pool/version.rb +5 -0
  44. data/lib/vault/version.rb +3 -0
  45. data/vault.gemspec +30 -0
  46. 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