vault_ruby_client 0.18.2

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.
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,230 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: MPL-2.0
3
+
4
+ require_relative "secret"
5
+ require_relative "../client"
6
+ require_relative "../request"
7
+ require_relative "../response"
8
+
9
+ module Vault
10
+ class Client
11
+ # A proxy to the {KV} methods.
12
+ # @return [KV]
13
+ def kv(mount)
14
+ KV.new(self, mount)
15
+ end
16
+ end
17
+
18
+ class KV < Request
19
+ attr_reader :mount
20
+
21
+ def initialize(client, mount)
22
+ super client
23
+
24
+ @mount = mount
25
+ end
26
+
27
+ # List the names of secrets at the given path, if the path supports
28
+ # listing. If the the path does not exist, an empty array will be returned.
29
+ #
30
+ # @example
31
+ # Vault.kv("secret").list("foo") #=> ["bar", "baz"]
32
+ #
33
+ # @param [String] path
34
+ # the path to list
35
+ #
36
+ # @return [Array<String>]
37
+ def list(path = "", options = {})
38
+ headers = extract_headers!(options)
39
+ json = client.list("/v1/#{mount}/metadata/#{encode_path(path)}", {}, headers)
40
+ json[:data][:keys] || []
41
+ rescue HTTPError => e
42
+ return [] if e.code == 404
43
+ raise
44
+ end
45
+
46
+ # Read the secret at the given path. If the secret does not exist, +nil+
47
+ # will be returned. The latest version is returned by default, but you
48
+ # can request a specific version.
49
+ #
50
+ # @example
51
+ # Vault.kv("secret").read("password") #=> #<Vault::Secret lease_id="">
52
+ #
53
+ # @param [String] path
54
+ # the path to read
55
+ # @param [Integer] version
56
+ # the version of the secret
57
+ #
58
+ # @return [Secret, nil]
59
+ def read(path, version = nil, options = {})
60
+ headers = extract_headers!(options)
61
+ params = {}
62
+ params[:version] = version unless version.nil?
63
+
64
+ json = client.get("/v1/#{mount}/data/#{encode_path(path)}", params, headers)
65
+ return Secret.decode(json[:data])
66
+ rescue HTTPError => e
67
+ return nil if e.code == 404
68
+ raise
69
+ end
70
+
71
+ # Read the metadata of a secret at the given path. If the secret does not
72
+ # exist, nil will be returned.
73
+ #
74
+ # @example
75
+ # Vault.kv("secret").read_metadata("password") => {...}
76
+ #
77
+ # @param [String] path
78
+ # the path to read
79
+ #
80
+ # @return [Hash, nil]
81
+ def read_metadata(path)
82
+ client.get("/v1/#{mount}/metadata/#{encode_path(path)}")[:data]
83
+ rescue HTTPError => e
84
+ return nil if e.code == 404
85
+ raise
86
+ end
87
+
88
+ # Write the secret at the given path with the given data. Note that the
89
+ # data must be a {Hash}!
90
+ #
91
+ # @example
92
+ # Vault.logical.write("secret/password", value: "secret") #=> #<Vault::Secret lease_id="">
93
+ #
94
+ # @param [String] path
95
+ # the path to write
96
+ # @param [Hash] data
97
+ # the data to write
98
+ #
99
+ # @return [Secret]
100
+ def write(path, data = {}, options = {})
101
+ headers = extract_headers!(options)
102
+ json = client.post("/v1/#{mount}/data/#{encode_path(path)}", JSON.fast_generate(:data => data), headers)
103
+ if json.nil?
104
+ return true
105
+ else
106
+ return Secret.decode(json)
107
+ end
108
+ end
109
+
110
+ # Write the metadata of a secret at the given path. Note that the data must
111
+ # be a {Hash}.
112
+ #
113
+ # @example
114
+ # Vault.kv("secret").write_metadata("password", max_versions => 3)
115
+ #
116
+ # @param [String] path
117
+ # the path to write
118
+ # @param [Hash] metadata
119
+ # the metadata to write
120
+ #
121
+ # @return [true]
122
+ def write_metadata(path, metadata = {})
123
+ client.post("/v1/#{mount}/metadata/#{encode_path(path)}", JSON.fast_generate(metadata))
124
+
125
+ true
126
+ end
127
+
128
+ # Patch the metadata of a secret at the given path. Note that the data must
129
+ # be a {Hash}.
130
+ #
131
+ # @example
132
+ # Vault.kv("secret").patch_metadata("password", custom_metadata: { my_custom_key: "my_value" }, max_versions: 3)
133
+ #
134
+ # @param [String] path
135
+ # the path to patch
136
+ # @param [Hash] metadata
137
+ # the metadata to patch
138
+ #
139
+ # @return [true]
140
+ def patch_metadata(path, metadata = {}, options = {})
141
+ headers = extract_headers!(options)
142
+ headers["Content-Type"] = "application/merge-patch+json"
143
+ client.patch("/v1/#{mount}/metadata/#{encode_path(path)}", JSON.fast_generate(metadata), headers)
144
+
145
+ true
146
+ end
147
+
148
+ # Delete the secret at the given path. If the secret does not exist, vault
149
+ # will still return true.
150
+ #
151
+ # @example
152
+ # Vault.logical.delete("secret/password") #=> true
153
+ #
154
+ # @param [String] path
155
+ # the path to delete
156
+ #
157
+ # @return [true]
158
+ def delete(path)
159
+ client.delete("/v1/#{mount}/data/#{encode_path(path)}")
160
+
161
+ true
162
+ end
163
+
164
+ # Mark specific versions of a secret as deleted.
165
+ #
166
+ # @example
167
+ # Vault.kv("secret").delete_versions("password", [1, 2])
168
+ #
169
+ # @param [String] path
170
+ # the path to remove versions from
171
+ # @param [Array<Integer>] versions
172
+ # an array of versions to remove
173
+ #
174
+ # @return [true]
175
+ def delete_versions(path, versions)
176
+ client.post("/v1/#{mount}/delete/#{encode_path(path)}", JSON.fast_generate(versions: versions))
177
+
178
+ true
179
+ end
180
+
181
+ # Mark specific versions of a secret as active.
182
+ #
183
+ # @example
184
+ # Vault.kv("secret").undelete_versions("password", [1, 2])
185
+ #
186
+ # @param [String] path
187
+ # the path to enable versions for
188
+ # @param [Array<Integer>] versions
189
+ # an array of versions to mark as undeleted
190
+ #
191
+ # @return [true]
192
+ def undelete_versions(path, versions)
193
+ client.post("/v1/#{mount}/undelete/#{encode_path(path)}", JSON.fast_generate(versions: versions))
194
+
195
+ true
196
+ end
197
+
198
+ # Completely remove a secret and its metadata.
199
+ #
200
+ # @example
201
+ # Vault.kv("secret").destroy("password")
202
+ #
203
+ # @param [String] path
204
+ # the path to remove
205
+ #
206
+ # @return [true]
207
+ def destroy(path)
208
+ client.delete("/v1/#{mount}/metadata/#{encode_path(path)}")
209
+
210
+ true
211
+ end
212
+
213
+ # Completely remove specific versions of a secret.
214
+ #
215
+ # @example
216
+ # Vault.kv("secret").destroy_versions("password", [1, 2])
217
+ #
218
+ # @param [String] path
219
+ # the path to remove versions from
220
+ # @param [Array<Integer>] versions
221
+ # an array of versions to destroy
222
+ #
223
+ # @return [true]
224
+ def destroy_versions(path, versions)
225
+ client.post("/v1/#{mount}/destroy/#{encode_path(path)}", JSON.fast_generate(versions: versions))
226
+
227
+ true
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,153 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: MPL-2.0
3
+
4
+ require_relative "secret"
5
+ require_relative "../client"
6
+ require_relative "../request"
7
+ require_relative "../response"
8
+
9
+ module Vault
10
+ class Client
11
+ # A proxy to the {Logical} methods.
12
+ # @return [Logical]
13
+ def logical
14
+ @logical ||= Logical.new(self)
15
+ end
16
+ end
17
+
18
+ class Logical < Request
19
+ # List the secrets at the given path, if the path supports listing. If the
20
+ # the path does not exist, an exception will be raised.
21
+ #
22
+ # @example
23
+ # Vault.logical.list("secret") #=> [#<Vault::Secret>, #<Vault::Secret>, ...]
24
+ #
25
+ # @param [String] path
26
+ # the path to list
27
+ #
28
+ # @return [Array<String>]
29
+ def list(path, options = {})
30
+ headers = extract_headers!(options)
31
+ json = client.list("/v1/#{encode_path(path)}", {}, headers)
32
+ json[:data][:keys] || []
33
+ rescue HTTPError => e
34
+ return [] if e.code == 404
35
+ raise
36
+ end
37
+
38
+ # Read the secret at the given path. If the secret does not exist, +nil+
39
+ # will be returned.
40
+ #
41
+ # @example
42
+ # Vault.logical.read("secret/password") #=> #<Vault::Secret lease_id="">
43
+ #
44
+ # @param [String] path
45
+ # the path to read
46
+ #
47
+ # @return [Secret, nil]
48
+ def read(path, options = {})
49
+ headers = extract_headers!(options)
50
+ json = client.get("/v1/#{encode_path(path)}", {}, headers)
51
+ return Secret.decode(json)
52
+ rescue HTTPError => e
53
+ return nil if e.code == 404
54
+ raise
55
+ end
56
+
57
+ # Write the secret at the given path with the given data. Note that the
58
+ # data must be a {Hash}!
59
+ #
60
+ # @example
61
+ # Vault.logical.write("secret/password", value: "secret") #=> #<Vault::Secret lease_id="">
62
+ #
63
+ # @param [String] path
64
+ # the path to write
65
+ # @param [Hash] data
66
+ # the data to write
67
+ #
68
+ # @return [Secret]
69
+ def write(path, data = {}, options = {})
70
+ headers = extract_headers!(options)
71
+ json = client.put("/v1/#{encode_path(path)}", JSON.fast_generate(data), headers)
72
+ if json.nil?
73
+ return true
74
+ else
75
+ return Secret.decode(json)
76
+ end
77
+ end
78
+
79
+ # Delete the secret at the given path. If the secret does not exist, vault
80
+ # will still return true.
81
+ #
82
+ # @example
83
+ # Vault.logical.delete("secret/password") #=> true
84
+ #
85
+ # @param [String] path
86
+ # the path to delete
87
+ #
88
+ # @return [true]
89
+ def delete(path)
90
+ client.delete("/v1/#{encode_path(path)}")
91
+ return true
92
+ end
93
+
94
+ # Unwrap the data stored against the given token. If the secret does not
95
+ # exist, `nil` will be returned.
96
+ #
97
+ # @example
98
+ # Vault.logical.unwrap("f363dba8-25a7-08c5-430c-00b2367124e6") #=> #<Vault::Secret lease_id="">
99
+ #
100
+ # @param [String] wrapper
101
+ # the token to use when unwrapping the value
102
+ #
103
+ # @return [Secret, nil]
104
+ def unwrap(wrapper)
105
+ client.with_token(wrapper) do |client|
106
+ json = client.get("/v1/cubbyhole/response")
107
+ secret = Secret.decode(json)
108
+
109
+ # If there is nothing in the cubbyhole, return early.
110
+ if secret.nil? || secret.data.nil? || secret.data[:response].nil?
111
+ return nil
112
+ end
113
+
114
+ # Extract the response and parse it into a new secret.
115
+ json = JSON.parse(secret.data[:response], symbolize_names: true)
116
+ secret = Secret.decode(json)
117
+ return secret
118
+ end
119
+ rescue HTTPError => e
120
+ return nil if e.code == 404
121
+ raise
122
+ end
123
+
124
+ # Unwrap a token in a wrapped response given the temporary token.
125
+ #
126
+ # @example
127
+ # Vault.logical.unwrap("f363dba8-25a7-08c5-430c-00b2367124e6") #=> "0f0f40fd-06ce-4af1-61cb-cdc12796f42b"
128
+ #
129
+ # @param [String, Secret] wrapper
130
+ # the token to unwrap
131
+ #
132
+ # @return [String, nil]
133
+ def unwrap_token(wrapper)
134
+ # If provided a secret, grab the token. This is really just to make the
135
+ # API a bit nicer.
136
+ if wrapper.is_a?(Secret)
137
+ wrapper = wrapper.wrap_info.token
138
+ end
139
+
140
+ # Unwrap
141
+ response = unwrap(wrapper)
142
+
143
+ # If nothing was there, return nil
144
+ if response.nil? || response.auth.nil?
145
+ return nil
146
+ end
147
+
148
+ return response.auth.client_token
149
+ rescue HTTPError => e
150
+ raise
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,171 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: MPL-2.0
3
+
4
+ require "time"
5
+
6
+ require_relative "../response"
7
+
8
+ module Vault
9
+ # Secret is a representation of a secret from Vault. Almost all data returned
10
+ # from Vault is represented as a secret.
11
+ class Secret < Response
12
+ # @!attribute [r] auth
13
+ # Authentication information for this secret, if any. Most secrets will
14
+ # contain this field, but it may also be `nil`. When authenticating to
15
+ # Vault, the resulting Vault token will be included in this embedded
16
+ # field.
17
+ #
18
+ # @example Authenticating to Vault
19
+ # secret = Vault.auth.userpass("username", "password")
20
+ # secret.auth.client_token #=> "fdb29070-6379-70c9-ca3a-46152fb66de1"
21
+ #
22
+ # @return [SecretAuth, nil]
23
+ field :auth, load: ->(v) { SecretAuth.decode(v) }
24
+
25
+ # @!attribute [r] data
26
+ # Arbitrary data returned by the secret. The keys returned are dependent
27
+ # upon the request made. For more information on the names of the keys
28
+ # that may be returned, please see the Vault documentation.
29
+ #
30
+ # @example Reading data
31
+ # secret = Vault.auth.token("abcd1234")
32
+ # secret.data[:id] #=> "abcd1234"
33
+ # secret.data[:ttl] #=> 0
34
+ #
35
+ # @return [Hash<Symbol, Object>]
36
+ field :data, freeze: true
37
+
38
+ # @!attribute [r] metadata
39
+ # Read-only metadata information related to the secret.
40
+ #
41
+ # @example Reading metadata
42
+ # secret = Vault.logical(:versioned).read("secret", "foo")
43
+ # secret.metadata[:created_time] #=> "2018-12-08T04:22:54.168065Z"
44
+ # secret.metadata[:version] #=> 1
45
+ # secret.metadata[:destroyed] #=> false
46
+ #
47
+ # @return [Hash<Symbol, Object>]
48
+ field :metadata, freeze: true
49
+
50
+ # @!attribute [r] lease_duration
51
+ # The number of seconds this lease is valid. If this number is 0 or nil,
52
+ # the secret does not expire.
53
+ #
54
+ # @example Getting lease duration
55
+ # secret = Vault.logical.read("secret/foo")
56
+ # secret.lease_duration #=> 2592000 # 30 days
57
+ #
58
+ # @return [Fixnum]
59
+ field :lease_duration
60
+
61
+ # @!attribute [r] lease_id
62
+ # Unique ID for the lease associated with this secret. The `lease_id` is a
63
+ # path and UUID that uniquely represents the secret. This may be used for
64
+ # renewing and revoking the secret, if permitted.
65
+ #
66
+ # @example Getting lease ID
67
+ # secret = Vault.logical.read("postgresql/creds/readonly")
68
+ # secret.lease_id #=> "postgresql/readonly/fdb29070-6379-70c9-ca3a-46152fb66de1"
69
+ #
70
+ # @return [String]
71
+ field :lease_id
72
+
73
+ # @!method [r] renewable?
74
+ # Returns whether this lease is renewable.
75
+ #
76
+ # @example Checking if a lease is renewable
77
+ # secret = Vault.logical.read("secret/foo")
78
+ # secret.renewable? #=> false
79
+ #
80
+ # @return [Boolean]
81
+ field :renewable, as: :renewable?
82
+
83
+ # @!attribute [r] warnings
84
+ # List of warnings returned by the Vault server. These are returned by the
85
+ # Vault server and may include deprecation information, new APIs, or
86
+ # request using the API differently in the future.
87
+ #
88
+ # @example Display warnings
89
+ # result = Vault.logical.read("secret/foo")
90
+ # result.warnings #=> ["This path has been deprecated"]
91
+ #
92
+ # @return [Array<String>, nil]
93
+ field :warnings, freeze: true
94
+
95
+ # @!attribute [r] wrap_info
96
+ # Wrapped information sent with the request (only present in Vault 0.6+).
97
+ # @return [WrapInfo, nil]
98
+ field :wrap_info, load: ->(v) { WrapInfo.decode(v) }
99
+ end
100
+
101
+ # SecretAuth is a struct that contains the information about auth data, if
102
+ # present. This is never returned alone and is usually embededded in a
103
+ # {Secret}.
104
+ class SecretAuth < Response
105
+ # @!attribute [r] accessor
106
+ # Accessor for the token. This is like a `lease_id`, but for a token.
107
+ # @return [String]
108
+ field :accessor
109
+
110
+ # @!attribute [r] client_token
111
+ # The client token for this authentication.
112
+ # @return [String]
113
+ field :client_token
114
+
115
+ # @!attribute [r] lease_duration
116
+ # Number of seconds the token is valid.
117
+ # @return [Fixnum]
118
+ field :lease_duration
119
+
120
+ # @!attribute [r] metadata
121
+ # Arbitrary metadata from the authentication.
122
+ #
123
+ # @example Listing metadata attached to an authentication
124
+ # auth.metadata #=> { :username => "sethvargo" }
125
+ #
126
+ # @return [Hash<Symbol, Object>, nil]
127
+ field :metadata, freeze: true
128
+
129
+ # @!attribute [r] policies
130
+ # List of policies attached to this authentication.
131
+ #
132
+ # @example Listing policies attached to an authentication
133
+ # auth.policies #=> ["default"]
134
+ #
135
+ # @return [Array<String>, nil]
136
+ field :policies, freeze: true
137
+
138
+ # @!attribute [r] renewable
139
+ # Returns whether this authentication is renewable.
140
+ #
141
+ # @example Checking if an authentication is renewable
142
+ # auth.renewable? #=> false
143
+ #
144
+ # @return [Boolean]
145
+ field :renewable, as: :renewable?
146
+ end
147
+
148
+ # WrapInfo is the information returned by a wrapped response. This is almost
149
+ # always embedded as part of a {Secret}.
150
+ class WrapInfo < Response
151
+ # @!attribute [r] token
152
+ # Wrapped response token. This token may be used to unwrap the response.
153
+ # @return [String]
154
+ field :token
155
+
156
+ # @!attribute [r] wrapped_accessor
157
+ # Accessor for the wrapped token. This is like a `lease_id`, but for a token.
158
+ # @return [String]
159
+ field :wrapped_accessor
160
+
161
+ # @!attribute [r] creation_time
162
+ # Date & time when the wrapped token was created
163
+ # @return [Time]
164
+ field :creation_time, load: ->(v) { Time.parse(v) }
165
+
166
+ # @!attribute [r] ttl
167
+ # The TTL on the token returned in seconds.
168
+ # @return [Fixnum]
169
+ field :ttl
170
+ end
171
+ end
@@ -0,0 +1,94 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: MPL-2.0
3
+
4
+ require "json"
5
+
6
+ module Vault
7
+ class Audit < Response
8
+ # @!attribute [r] description
9
+ # Description of the audit backend.
10
+ # @return [String]
11
+ field :description
12
+
13
+ # @!attribute [r] options
14
+ # Map of options configured to the audit backend.
15
+ # @return [Hash<Symbol, Object>]
16
+ field :options
17
+
18
+ # @!attribute [r] type
19
+ # Name of the audit backend.
20
+ # @return [String]
21
+ field :type
22
+ end
23
+
24
+ class Sys
25
+ # List all audits for the vault.
26
+ #
27
+ # @example
28
+ # Vault.sys.audits #=> { :file => #<Audit> }
29
+ #
30
+ # @return [Hash<Symbol, Audit>]
31
+ def audits
32
+ json = client.get("/v1/sys/audit")
33
+ json = json[:data] if json[:data]
34
+ return Hash[*json.map do |k,v|
35
+ [k.to_s.chomp("/").to_sym, Audit.decode(v)]
36
+ end.flatten]
37
+ end
38
+
39
+ # Enable a particular audit. Note: the +options+ depend heavily on the
40
+ # type of audit being enabled. Please refer to audit-specific documentation
41
+ # for which need to be enabled.
42
+ #
43
+ # @example
44
+ # Vault.sys.enable_audit("/file-audit", "file", "File audit", path: "/path/on/disk") #=> true
45
+ #
46
+ # @param [String] path
47
+ # the path to mount the audit
48
+ # @param [String] type
49
+ # the type of audit to enable
50
+ # @param [String] description
51
+ # a human-friendly description of the audit backend
52
+ # @param [Hash] options
53
+ # audit-specific options
54
+ #
55
+ # @return [true]
56
+ def enable_audit(path, type, description, options = {})
57
+ client.put("/v1/sys/audit/#{encode_path(path)}", JSON.fast_generate(
58
+ type: type,
59
+ description: description,
60
+ options: options,
61
+ ))
62
+ return true
63
+ end
64
+
65
+ # Disable a particular audit. If an audit does not exist, and error will be
66
+ # raised.
67
+ #
68
+ # @param [String] path
69
+ # the path of the audit to disable
70
+ #
71
+ # @return [true]
72
+ def disable_audit(path)
73
+ client.delete("/v1/sys/audit/#{encode_path(path)}")
74
+ return true
75
+ end
76
+
77
+ # Generates a HMAC verifier for a given input.
78
+ #
79
+ # @example
80
+ # Vault.sys.audit_hash("file-audit", "my input") #=> "hmac-sha256:30aa7de18a5e90bbc1063db91e7c387b32b9fa895977eb8c177bbc91e7d7c542"
81
+ #
82
+ # @param [String] path
83
+ # the path of the audit backend
84
+ # @param [String] input
85
+ # the input to generate a HMAC for
86
+ #
87
+ # @return [String]
88
+ def audit_hash(path, input)
89
+ json = client.post("/v1/sys/audit-hash/#{encode_path(path)}", JSON.fast_generate(input: input))
90
+ json = json[:data] if json[:data]
91
+ json[:hash]
92
+ end
93
+ end
94
+ end