vault_ruby_client 0.18.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +287 -0
  3. data/LICENSE +364 -0
  4. data/README.md +223 -0
  5. data/lib/vault/api/approle.rb +221 -0
  6. data/lib/vault/api/auth.rb +324 -0
  7. data/lib/vault/api/auth_tls.rb +95 -0
  8. data/lib/vault/api/auth_token.rb +245 -0
  9. data/lib/vault/api/help.rb +36 -0
  10. data/lib/vault/api/kv.rb +230 -0
  11. data/lib/vault/api/logical.rb +153 -0
  12. data/lib/vault/api/secret.rb +171 -0
  13. data/lib/vault/api/sys/audit.rb +94 -0
  14. data/lib/vault/api/sys/auth.rb +119 -0
  15. data/lib/vault/api/sys/health.rb +66 -0
  16. data/lib/vault/api/sys/init.rb +86 -0
  17. data/lib/vault/api/sys/leader.rb +51 -0
  18. data/lib/vault/api/sys/lease.rb +52 -0
  19. data/lib/vault/api/sys/mount.rb +165 -0
  20. data/lib/vault/api/sys/namespace.rb +86 -0
  21. data/lib/vault/api/sys/policy.rb +95 -0
  22. data/lib/vault/api/sys/quota.rb +110 -0
  23. data/lib/vault/api/sys/seal.rb +84 -0
  24. data/lib/vault/api/sys.rb +30 -0
  25. data/lib/vault/api/transform/alphabet.rb +46 -0
  26. data/lib/vault/api/transform/role.rb +45 -0
  27. data/lib/vault/api/transform/template.rb +57 -0
  28. data/lib/vault/api/transform/transformation.rb +64 -0
  29. data/lib/vault/api/transform.rb +32 -0
  30. data/lib/vault/api.rb +17 -0
  31. data/lib/vault/client.rb +460 -0
  32. data/lib/vault/configurable.rb +53 -0
  33. data/lib/vault/defaults.rb +218 -0
  34. data/lib/vault/encode.rb +22 -0
  35. data/lib/vault/errors.rb +87 -0
  36. data/lib/vault/persistent/connection.rb +45 -0
  37. data/lib/vault/persistent/pool.rb +51 -0
  38. data/lib/vault/persistent/timed_stack_multi.rb +73 -0
  39. data/lib/vault/persistent.rb +1161 -0
  40. data/lib/vault/request.rb +47 -0
  41. data/lib/vault/response.rb +92 -0
  42. data/lib/vault/vendor/connection_pool/timed_stack.rb +181 -0
  43. data/lib/vault/vendor/connection_pool/version.rb +8 -0
  44. data/lib/vault/vendor/connection_pool.rb +153 -0
  45. data/lib/vault/version.rb +6 -0
  46. data/lib/vault_ruby_client.rb +53 -0
  47. metadata +158 -0
@@ -0,0 +1,119 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: MPL-2.0
3
+
4
+ require "json"
5
+
6
+ module Vault
7
+ class Auth < Response
8
+ # @!attribute [r] description
9
+ # Description of the auth backend.
10
+ # @return [String]
11
+ field :description
12
+
13
+ # @!attribute [r] type
14
+ # Name of the auth backend.
15
+ # @return [String]
16
+ field :type
17
+ end
18
+
19
+ class AuthConfig < Response
20
+ # @!attribute [r] default_lease_ttl
21
+ # The default time-to-live.
22
+ # @return [String]
23
+ field :default_lease_ttl
24
+
25
+ # @!attribute [r] max_lease_ttl
26
+ # The maximum time-to-live.
27
+ # @return [String]
28
+ field :max_lease_ttl
29
+ end
30
+
31
+ class Sys
32
+ # List all auths in Vault.
33
+ #
34
+ # @example
35
+ # Vault.sys.auths #=> {:token => #<Vault::Auth type="token", description="token based credentials">}
36
+ #
37
+ # @return [Hash<Symbol, Auth>]
38
+ def auths
39
+ json = client.get("/v1/sys/auth")
40
+ json = json[:data] if json[:data]
41
+ return Hash[*json.map do |k,v|
42
+ [k.to_s.chomp("/").to_sym, Auth.decode(v)]
43
+ end.flatten]
44
+ end
45
+
46
+ # Enable a particular authentication at the given path.
47
+ #
48
+ # @example
49
+ # Vault.sys.enable_auth("github", "github") #=> true
50
+ #
51
+ # @param [String] path
52
+ # the path to mount the auth
53
+ # @param [String] type
54
+ # the type of authentication
55
+ # @param [String] description
56
+ # a human-friendly description (optional)
57
+ #
58
+ # @return [true]
59
+ def enable_auth(path, type, description = nil)
60
+ payload = { type: type }
61
+ payload[:description] = description if !description.nil?
62
+
63
+ client.post("/v1/sys/auth/#{encode_path(path)}", JSON.fast_generate(payload))
64
+ return true
65
+ end
66
+
67
+ # Disable a particular authentication at the given path. If not auth
68
+ # exists at that path, an error will be raised.
69
+ #
70
+ # @example
71
+ # Vault.sys.disable_auth("github") #=> true
72
+ #
73
+ # @param [String] path
74
+ # the path to disable
75
+ #
76
+ # @return [true]
77
+ def disable_auth(path)
78
+ client.delete("/v1/sys/auth/#{encode_path(path)}")
79
+ return true
80
+ end
81
+
82
+ # Read the given auth path's configuration.
83
+ #
84
+ # @example
85
+ # Vault.sys.auth_tune("github") #=> #<Vault::AuthConfig "default_lease_ttl"=3600, "max_lease_ttl"=7200>
86
+ #
87
+ # @param [String] path
88
+ # the path to retrieve configuration for
89
+ #
90
+ # @return [AuthConfig]
91
+ # configuration of the given auth path
92
+ def auth_tune(path)
93
+ json = client.get("/v1/sys/auth/#{encode_path(path)}/tune")
94
+ return AuthConfig.decode(json)
95
+ rescue HTTPError => e
96
+ return nil if e.code == 404
97
+ raise
98
+ end
99
+
100
+ # Write the given auth path's configuration.
101
+ #
102
+ # @example
103
+ # Vault.sys.auth_tune("github", "default_lease_ttl" => 600, "max_lease_ttl" => 1200 ) #=> true
104
+ #
105
+ # @param [String] path
106
+ # the path to retrieve configuration for
107
+ #
108
+ # @return [AuthConfig]
109
+ # configuration of the given auth path
110
+ def put_auth_tune(path, config = {})
111
+ json = client.put("/v1/sys/auth/#{encode_path(path)}/tune", JSON.fast_generate(config))
112
+ if json.nil?
113
+ return true
114
+ else
115
+ return Secret.decode(json)
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,66 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: MPL-2.0
3
+
4
+ require "json"
5
+
6
+ module Vault
7
+ class HealthStatus < Response
8
+ # @!attribute [r] initialized
9
+ # Whether the Vault server is Initialized.
10
+ # @return [Boolean]
11
+ field :initialized, as: :initialized?
12
+
13
+ # @!attribute [r] sealed
14
+ # Whether the Vault server is Sealed.
15
+ # @return [Boolean]
16
+ field :sealed, as: :sealed?
17
+
18
+ # @!attribute [r] standby
19
+ # Whether the Vault server is in Standby mode.
20
+ # @return [Boolean]
21
+ field :standby, as: :standby?
22
+
23
+ # @!attribute [r] replication_performance_mode
24
+ # Verbose description of DR mode (added in 0.9.2)
25
+ # @return [String]
26
+ field :replication_performance_mode
27
+
28
+ # @!attribute [r] replication_dr_mode
29
+ # Verbose description of DR mode (added in 0.9.2)
30
+ # @return [String]
31
+ field :replication_dr_mode
32
+
33
+ # @!attribute [r] server_time_utc
34
+ # Server time in Unix seconds, UTC
35
+ # @return [Fixnum]
36
+ field :server_time_utc
37
+
38
+ # @!attribute [r] version
39
+ # Server Vault version string (added in 0.6.1)
40
+ # @return [String]
41
+ field :version
42
+
43
+ # @!attribute [r] cluster_name
44
+ # Server cluster name
45
+ # @return [String]
46
+ field :cluster_name
47
+
48
+ # @!attribute [r] cluster_id
49
+ # Server cluster UUID
50
+ # @return [String]
51
+ field :cluster_id
52
+ end
53
+
54
+ class Sys
55
+ # Show the health status for this vault.
56
+ #
57
+ # @example
58
+ # 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">
59
+ #
60
+ # @return [HealthStatus]
61
+ def health_status
62
+ json = client.get("/v1/sys/health", {:sealedcode => 200, :uninitcode => 200, :standbycode => 200})
63
+ return HealthStatus.decode(json)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,86 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: MPL-2.0
3
+
4
+ require "json"
5
+
6
+ module Vault
7
+ class InitResponse < Response
8
+ # @!attribute [r] keys
9
+ # List of unseal keys.
10
+ # @return [Array<String>]
11
+ field :keys
12
+
13
+ # @!attribute [r] keys_base64
14
+ # List of unseal keys, base64-encoded
15
+ # @return [Array<String>]
16
+ field :keys_base64
17
+
18
+ # @!attribute [r] root_token
19
+ # Initial root token.
20
+ # @return [String]
21
+ field :root_token
22
+ end
23
+
24
+ class InitStatus < Response
25
+ # @!method initialized?
26
+ # Returns whether the Vault server is initialized.
27
+ # @return [Boolean]
28
+ field :initialized, as: :initialized?
29
+ end
30
+
31
+ class Sys
32
+ # Show the initialization status for this vault.
33
+ #
34
+ # @example
35
+ # Vault.sys.init_status #=> #<Vault::InitStatus initialized=true>
36
+ #
37
+ # @return [InitStatus]
38
+ def init_status
39
+ json = client.get("/v1/sys/init")
40
+ return InitStatus.decode(json)
41
+ end
42
+
43
+ # Initialize a new vault.
44
+ #
45
+ # @example
46
+ # Vault.sys.init #=> #<Vault::InitResponse keys=["..."] root_token="...">
47
+ #
48
+ # @param [Hash] options
49
+ # the list of init options
50
+ #
51
+ # @option options [String] :root_token_pgp_key
52
+ # optional base64-encoded PGP public key used to encrypt the initial root
53
+ # token.
54
+ # @option options [Fixnum] :secret_shares
55
+ # the number of shares
56
+ # @option options [Fixnum] :secret_threshold
57
+ # the number of keys needed to unlock
58
+ # @option options [Array<String>] :pgp_keys
59
+ # an optional Array of base64-encoded PGP public keys to encrypt sharees
60
+ # @option options [Fixnum] :stored_shares
61
+ # the number of shares that should be encrypted by the HSM for
62
+ # auto-unsealing
63
+ # @option options [Fixnum] :recovery_shares
64
+ # the number of shares to split the recovery key into
65
+ # @option options [Fixnum] :recovery_threshold
66
+ # the number of shares required to reconstruct the recovery key
67
+ # @option options [Array<String>] :recovery_pgp_keys
68
+ # an array of PGP public keys used to encrypt the output for the recovery
69
+ # keys
70
+ #
71
+ # @return [InitResponse]
72
+ def init(options = {})
73
+ json = client.put("/v1/sys/init", JSON.fast_generate(
74
+ root_token_pgp_key: options.fetch(:root_token_pgp_key, nil),
75
+ secret_shares: options.fetch(:secret_shares, options.fetch(:shares, 5)),
76
+ secret_threshold: options.fetch(:secret_threshold, options.fetch(:threshold, 3)),
77
+ pgp_keys: options.fetch(:pgp_keys, nil),
78
+ stored_shares: options.fetch(:stored_shares, nil),
79
+ recovery_shares: options.fetch(:recovery_shares, nil),
80
+ recovery_threshold: options.fetch(:recovery_threshold, nil),
81
+ recovery_pgp_keys: options.fetch(:recovery_pgp_keys, nil),
82
+ ))
83
+ return InitResponse.decode(json)
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,51 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: MPL-2.0
3
+
4
+ module Vault
5
+ class LeaderStatus < Response
6
+ # @!method ha_enabled?
7
+ # Returns whether the high-availability mode is enabled.
8
+ # @return [Boolean]
9
+ field :ha_enabled, as: :ha_enabled?
10
+
11
+ # @!method leader?
12
+ # Returns whether the Vault server queried is the leader.
13
+ # @return [Boolean]
14
+ field :is_self, as: :leader?
15
+
16
+ # @!attribute [r] address
17
+ # URL where the server is running.
18
+ # @return [String]
19
+ field :leader_address, as: :address
20
+
21
+ # @deprecated Use {#ha_enabled?} instead
22
+ def ha?; ha_enabled?; end
23
+
24
+ # @deprecated Use {#leader?} instead
25
+ def is_leader?; leader?; end
26
+
27
+ # @deprecated Use {#leader?} instead
28
+ def is_self?; leader?; end
29
+
30
+ # @deprecated Use {#leader?} instead
31
+ def self?; leader?; end
32
+ end
33
+
34
+ class Sys
35
+ # Determine the leader status for this vault.
36
+ #
37
+ # @example
38
+ # Vault.sys.leader #=> #<Vault::LeaderStatus ha_enabled=false, is_self=false, leader_address="">
39
+ #
40
+ # @return [LeaderStatus]
41
+ def leader
42
+ json = client.get("/v1/sys/leader")
43
+ return LeaderStatus.decode(json)
44
+ end
45
+
46
+ def step_down
47
+ client.put("/v1/sys/step-down", nil)
48
+ return true
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,52 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: MPL-2.0
3
+
4
+ module Vault
5
+ class Sys
6
+ # Renew a lease with the given ID.
7
+ #
8
+ # @example
9
+ # Vault.sys.renew("aws/username") #=> #<Vault::Secret ...>
10
+ #
11
+ # @param [String] id
12
+ # the lease ID
13
+ # @param [Fixnum] increment
14
+ #
15
+ # @return [Secret]
16
+ def renew(id, increment = 0)
17
+ json = client.put("/v1/sys/renew/#{id}", JSON.fast_generate(
18
+ increment: increment,
19
+ ))
20
+ return Secret.decode(json)
21
+ end
22
+
23
+ # Revoke the secret at the given id. If the secret does not exist, an error
24
+ # will be raised.
25
+ #
26
+ # @example
27
+ # Vault.sys.revoke("aws/username") #=> true
28
+ #
29
+ # @param [String] id
30
+ # the lease ID
31
+ #
32
+ # @return [true]
33
+ def revoke(id)
34
+ client.put("/v1/sys/revoke/#{id}", nil)
35
+ return true
36
+ end
37
+
38
+ # Revoke all secrets under the given prefix.
39
+ #
40
+ # @example
41
+ # Vault.sys.revoke_prefix("aws") #=> true
42
+ #
43
+ # @param [String] id
44
+ # the lease ID
45
+ #
46
+ # @return [true]
47
+ def revoke_prefix(id)
48
+ client.put("/v1/sys/revoke-prefix/#{id}", nil)
49
+ return true
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,165 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: MPL-2.0
3
+
4
+ require "json"
5
+
6
+ module Vault
7
+ class Mount < Response
8
+ # @!attribute [r] config
9
+ # Arbitrary configuration for the backend.
10
+ # @return [Hash<Symbol, Object>]
11
+ field :config
12
+
13
+ # @!attribute [r] description
14
+ # Description of the mount.
15
+ # @return [String]
16
+ field :description
17
+
18
+ # @!attribute [r] type
19
+ # Type of the mount.
20
+ # @return [String]
21
+ field :type
22
+
23
+ # @!attribute [r] type
24
+ # Options given to the mount.
25
+ # @return [Hash<Symbol, Object>]
26
+ field :options
27
+ end
28
+
29
+ class MountTune < Response
30
+ # @!attribute [r] description
31
+ # Specifies the description of the mount.
32
+ # @return [String]
33
+ field :description
34
+
35
+ # @!attribute [r] default_lease_ttl
36
+ # Specifies the default time-to-live.
37
+ # @return [Fixnum]
38
+ field :default_lease_ttl
39
+
40
+ # @!attribute [r] max_lease_ttl
41
+ # Specifies the maximum time-to-live.
42
+ # @return [Fixnum]
43
+ field :max_lease_ttl
44
+
45
+ # @!attribute [r] audit_non_hmac_request_keys
46
+ # Specifies the comma-separated list of keys that will not be HMAC'd by audit devices in the request data object.
47
+ # @return [Array<String>]
48
+ field :audit_non_hmac_request_keys
49
+
50
+ # @!attribute [r] audit_non_hmac_response_keys
51
+ # Specifies the comma-separated list of keys that will not be HMAC'd by audit devices in the response data object.
52
+ # @return [Array<String>]
53
+ field :audit_non_hmac_response_keys
54
+
55
+ # @!attribute [r] listing_visibility
56
+ # Specifies whether to show this mount in the UI-specific listing endpoint.
57
+ # @return [String]
58
+ field :listing_visibility
59
+
60
+ # @!attribute [r] passthrough_request_headers
61
+ # Comma-separated list of headers to whitelist and pass from the request to the plugin.
62
+ # @return [Array<String>]
63
+ field :passthrough_request_headers
64
+
65
+ # @!attribute [r] allowed_response_headers
66
+ # Comma-separated list of headers to whitelist, allowing a plugin to include them in the response.
67
+ # @return [Array<String>]
68
+ field :allowed_response_headers
69
+ end
70
+
71
+ class Sys < Request
72
+ # List all mounts in the vault.
73
+ #
74
+ # @example
75
+ # Vault.sys.mounts #=> { :secret => #<struct Vault::Mount type="generic", description="generic secret storage"> }
76
+ #
77
+ # @return [Hash<Symbol, Mount>]
78
+ def mounts
79
+ json = client.get("/v1/sys/mounts")
80
+ json = json[:data] if json[:data]
81
+ return Hash[*json.map do |k,v|
82
+ [k.to_s.chomp("/").to_sym, Mount.decode(v)]
83
+ end.flatten]
84
+ end
85
+
86
+ # Create a mount at the given path.
87
+ #
88
+ # @example
89
+ # Vault.sys.mount("pg", "postgresql", "Postgres user management") #=> true
90
+ #
91
+ # @param [String] path
92
+ # the path to mount at
93
+ # @param [String] type
94
+ # the type of mount
95
+ # @param [String] description
96
+ # a human-friendly description (optional)
97
+ def mount(path, type, description = nil, options = {})
98
+ payload = options.merge type: type
99
+ payload[:description] = description if !description.nil?
100
+
101
+ client.post("/v1/sys/mounts/#{encode_path(path)}", JSON.fast_generate(payload))
102
+ return true
103
+ end
104
+
105
+ # Get the mount tunings at a given path.
106
+ #
107
+ # @example
108
+ # Vault.sys.get_mount_tune("pki") #=> { :pki => #<struct Vault::MountTune default_lease_ttl=2764800> }
109
+ #
110
+ # @return [MountTune]
111
+ def get_mount_tune(path)
112
+ json = client.get("/v1/sys/mounts/#{encode_path(path)}/tune")
113
+ json = json[:data] if json[:data]
114
+ return MountTune.decode(json)
115
+ end
116
+
117
+ # Tune a mount at the given path.
118
+ #
119
+ # @example
120
+ # Vault.sys.mount_tune("pki", max_lease_ttl: '87600h') #=> true
121
+ #
122
+ # @param [String] path
123
+ # the path to write
124
+ # @param [Hash] data
125
+ # the data to write
126
+ def mount_tune(path, data = {})
127
+ json = client.post("/v1/sys/mounts/#{encode_path(path)}/tune", JSON.fast_generate(data))
128
+ return true
129
+ end
130
+
131
+ # Unmount the thing at the given path. If the mount does not exist, an error
132
+ # will be raised.
133
+ #
134
+ # @example
135
+ # Vault.sys.unmount("pg") #=> true
136
+ #
137
+ # @param [String] path
138
+ # the path to unmount
139
+ #
140
+ # @return [true]
141
+ def unmount(path)
142
+ client.delete("/v1/sys/mounts/#{encode_path(path)}")
143
+ return true
144
+ end
145
+
146
+ # Change the name of the mount
147
+ #
148
+ # @example
149
+ # Vault.sys.remount("pg", "postgres") #=> true
150
+ #
151
+ # @param [String] from
152
+ # the origin mount path
153
+ # @param [String] to
154
+ # the new mount path
155
+ #
156
+ # @return [true]
157
+ def remount(from, to)
158
+ client.post("/v1/sys/remount", JSON.fast_generate(
159
+ from: from,
160
+ to: to,
161
+ ))
162
+ return true
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,86 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: MPL-2.0
3
+
4
+ module Vault
5
+ class Namespace < Response
6
+ # @!attribute [r] id
7
+ # ID of the namespace
8
+ # @return [String]
9
+ field :id
10
+
11
+ # @!attribute [r] path
12
+ # Path of the namespace, includes parent paths if nested.
13
+ # @return [String]
14
+ field :path
15
+ end
16
+
17
+ class Sys
18
+ # List all namespaces in a given scope. Ignores nested namespaces.
19
+ #
20
+ # @example
21
+ # Vault.sys.namespaces #=> { :foo => #<struct Vault::Namespace id="xxxx1", path="foo/" }
22
+ #
23
+ # @return [Hash<Symbol, Namespace>]
24
+ def namespaces(scoped=nil)
25
+ path = ["v1", scoped, "sys", "namespaces"].compact
26
+ json = client.list(path.join("/"))
27
+ json = json[:data] if json[:data]
28
+ if json[:key_info]
29
+ json = json[:key_info]
30
+ hash = {}
31
+ json.each do |k,v|
32
+ hash[k.to_s.chomp("/").to_sym] = Namespace.decode(v)
33
+ end
34
+ hash
35
+ else
36
+ json
37
+ end
38
+ end
39
+
40
+ # Create a namespace. Nests the namespace if a namespace header is provided.
41
+ #
42
+ # @example
43
+ # Vault.sys.create_namespace("foo")
44
+ #
45
+ # @param [String] namespace
46
+ # the potential path of the namespace, without any parent path provided
47
+ #
48
+ # @return [true]
49
+ def create_namespace(namespace)
50
+ client.put("/v1/sys/namespaces/#{namespace}", {})
51
+ return true
52
+ end
53
+
54
+ # Delete a namespace. Raises an error if the namespace provided is not empty.
55
+ #
56
+ # @example
57
+ # Vault.sys.delete_namespace("foo")
58
+ #
59
+ # @param [String] namespace
60
+ # the path of the namespace to be deleted
61
+ #
62
+ # @return [true]
63
+ def delete_namespace(namespace)
64
+ client.delete("/v1/sys/namespaces/#{namespace}")
65
+ return true
66
+ end
67
+
68
+ # Retrieve a namespace by path.
69
+ #
70
+ # @example
71
+ # Vault.sys.get_namespace("foo")
72
+ #
73
+ # @param [String] namespace
74
+ # the path of the namespace ot be retrieved
75
+ #
76
+ # @return [Namespace]
77
+ def get_namespace(namespace)
78
+ json = client.get("/v1/sys/namespaces/#{namespace}")
79
+ if data = json.dig(:data)
80
+ Namespace.decode(data)
81
+ else
82
+ json
83
+ end
84
+ end
85
+ end
86
+ end