vault 0.13.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 45b9f9e52cf35711735bdb4ff03db5c64712df2ad07b1ba50d5ba7172d0b5e15
4
- data.tar.gz: ee28f237fee824b1e9381ed35c06f587bdf022ab26455a04221ca385ac1a4448
3
+ metadata.gz: 46c570463a1aba190e789e5b2516b4140d48961611ff058235d3b9744e6a6b24
4
+ data.tar.gz: c84a96cf71d9f405281f56629e0fb68a6ce051740ea46da60e35cabf37d8b44e
5
5
  SHA512:
6
- metadata.gz: 8afef6bdd52369d7af804cbe8dc182166ee49698d9d2d71b923401f6546b9fc7f5ce7514236eaf9c92b867f030ed78e200a83cd71a88f765eae48af45aa41ec1
7
- data.tar.gz: 877dbfb3dba0fe37718a68bafe22218f4fb1bd9577d3263ed979d3a71c14bc78a603bacb32a231d4ae7c346171bd6e81b6b4f95ab7368be7dc5d1ac236860da7
6
+ metadata.gz: 98a20e963ec212e2269d1c28b581c24b356495789b4b37b20ebcb829c17904b518fc32f9cd2dadfcd59b957361410e7aa61f88e7ad419d72533d0ac1bd0ec68d
7
+ data.tar.gz: 35f0126a7e7ba6173662222a9006cd02bc2f78d6d674533546b68ad87420f99b1e26f1f160058b2a051c36a5faac219921ab24191f9165212ddc8f15c440e0a6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # Vault Ruby Changelog
2
2
 
3
+ ## v0.16.0 (??? ??, 2021)
4
+
5
+ IMPROVEMENTS
6
+
7
+ - The timeout used to get a connection from the connection pool that talks with vault is now configurable. Using `Vault.pool_timeout` or the env var `VAULT_POOL_TIMEOUT`.
8
+
9
+ ## v0.15.0 (July 29, 2020)
10
+
11
+ IMPROVEMENTS
12
+
13
+ - Added support for Resource Quotas
14
+
15
+ ## v0.14.0 (May 28, 2020)
16
+
17
+ IMPROVEMENTS
18
+
19
+ - Added support for the Transform Secrets Engine
20
+
21
+ ## v0.13.2 (May 7, 2020)
22
+
23
+ BUG FIXES
24
+
25
+ - Fixed the ability to use namespace as an option for each request. Previously, that option was ignored.
26
+ - aws-sigv4 gem was unlocked after a bug in 1.1.2 broke CI
27
+
28
+ ## v0.13.1 (April 28, 2020)
29
+
30
+ IMPROVEMENTS
31
+
32
+ - Added support for defining a namespace when initializing the client, as well as options for changing the namespace via method.
33
+ - Added support for sys/namespaces API. Ability to Get, Create, Delete, and List namespaces has been provided.
34
+
35
+ ## v0.13.0 (October 1, 2019)
36
+
37
+ IMPROVEMENTS
38
+
39
+ - Add support for versioned KV secrets in the client
40
+
3
41
  ## v0.12.0 (August 14, 2018)
4
42
 
5
43
  IMPROVEMENTS
data/README.md CHANGED
@@ -1,15 +1,17 @@
1
- Vault Ruby Client [![Build Status](https://secure.travis-ci.org/hashicorp/vault-ruby.svg)](http://travis-ci.org/hashicorp/vault-ruby)
1
+ Vault Ruby Client [![Build Status](https://circleci.com/gh/hashicorp/vault-ruby.svg?style=shield)](https://circleci.com/gh/hashicorp/vault-ruby)
2
2
  =================
3
3
 
4
4
  Vault is the official Ruby client for interacting with [Vault](https://vaultproject.io) by HashiCorp.
5
5
 
6
- **The documentation in this README corresponds to the master branch of the Vault Ruby client. It may contain unreleased features or different APIs than the most recently released version. Please see the Git tag that corresponds to your version of the Vault Ruby client for the proper documentation.**
6
+ **If you're viewing this README from GitHub on the `master` branch, know that it may contain unreleased features or
7
+ different APIs than the most recently released version. Please see the Git tag that corresponds to your version of the
8
+ Vault Ruby client for the proper documentation.**
7
9
 
8
10
  Quick Start
9
11
  -----------
10
12
  Install Ruby 2.0+: [Guide](https://www.ruby-lang.org/en/documentation/installation/).
11
13
 
12
- > Please note that Vault Ruby may work on older Ruby installations like Ruby 1.9, but you **should not** use these versions of Ruby when communicating with a Vault server. Ruby 1.9 has [reached EOL](https://www.ruby-lang.org/en/news/2014/01/10/ruby-1-9-3-will-end-on-2015/) and will no longer receive important security patches or maintenance updates. There _are known security vulnerabilities_ specifically around SSL ciphers, which this library uses to communicate with a Vault server. While many distros still ship with Ruby 1.9 as the default, you are **highly discouraged** from using this library on any version of Ruby lower than Ruby 2.0.
14
+ > Please note that as of Vault Ruby version 0.14.0 versions of Ruby prior to 2.0 are no longer supported.
13
15
 
14
16
  Install via Rubygems:
15
17
 
@@ -18,7 +20,7 @@ Install via Rubygems:
18
20
  or add it to your Gemfile if you're using Bundler:
19
21
 
20
22
  ```ruby
21
- gem "vault", "~> 0.1"
23
+ gem "vault"
22
24
  ```
23
25
 
24
26
  and then run the `bundle` command to install.
@@ -28,6 +30,8 @@ Start a Vault client:
28
30
  ```ruby
29
31
  Vault.address = "http://127.0.0.1:8200" # Also reads from ENV["VAULT_ADDR"]
30
32
  Vault.token = "abcd-1234" # Also reads from ENV["VAULT_TOKEN"]
33
+ # Optional - if using the Namespace enterprise feature
34
+ # Vault.namespace = "my-namespace" # Also reads from ENV["VAULT_NAMESPACE"]
31
35
 
32
36
  Vault.sys.mounts #=> { :secret => #<struct Vault::Mount type="generic", description="generic secret storage"> }
33
37
  ```
@@ -43,6 +47,8 @@ Vault.configure do |config|
43
47
 
44
48
  # The token to authenticate with Vault, also read as ENV["VAULT_TOKEN"]
45
49
  config.token = "abcd-1234"
50
+ # Optional - if using the Namespace enterprise feature
51
+ # config.namespace = "my-namespace" # Also reads from ENV["VAULT_NAMESPACE"]
46
52
 
47
53
  # Proxy connection information, also read as ENV["VAULT_PROXY_(thing)"]
48
54
  config.proxy_address = "..."
@@ -85,7 +91,8 @@ And if you want to authenticate with a `AWS EC2` :
85
91
  # Export VAULT_ADDR to ENV then
86
92
  # Get the pkcs7 value from AWS
87
93
  signature = `curl http://169.254.169.254/latest/dynamic/instance-identity/pkcs7`
88
- vault_token = Vault.auth.aws_ec2(ENV['EC2_ROLE'], signature, nil)
94
+ iam_role = `curl http://169.254.169.254/latest/meta-data/iam/security-credentials/`
95
+ vault_token = Vault.auth.aws_ec2(iam_role, signature, nil)
89
96
  vault_client = Vault::Client.new(address: ENV["VAULT_ADDR"], token: vault_token.auth.client_token)
90
97
  ```
91
98
 
@@ -208,7 +215,8 @@ Development
208
215
 
209
216
  Important Notes:
210
217
 
211
- - **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.
212
- - **The tests must be be idempotent.** The HTTP calls made during a test should be able to be run over and over.
218
+ - **All new features must include test coverage.** At a bare minimum, Unit tests are required. It is preferred if you include integration tests as well.
219
+ - **The tests must be idempotent.** The HTTP calls made during a test should be able to be run over and over.
213
220
  - **Tests are order independent.** The default RSpec configuration randomizes the test order, so this should not be a problem.
214
221
  - **Integration tests require Vault** Vault must be available in the path for the integration tests to pass.
222
+ - **In order to be considered an integration test:** The test MUST use the `vault_test_client` or `vault_redirect_test_client` as the client. This spawns a process, or uses an already existing process from another test, to run against.
data/lib/vault/api.rb CHANGED
@@ -9,5 +9,6 @@ module Vault
9
9
  require_relative "api/logical"
10
10
  require_relative "api/secret"
11
11
  require_relative "api/sys"
12
+ require_relative "api/transform"
12
13
  end
13
14
  end
data/lib/vault/api/kv.rb CHANGED
@@ -104,7 +104,7 @@ module Vault
104
104
  end
105
105
  end
106
106
 
107
- # Write the metadata of a secret at the given path. Note that teh data must
107
+ # Write the metadata of a secret at the given path. Note that the data must
108
108
  # be a {Hash}.
109
109
  #
110
110
  # @example
data/lib/vault/api/sys.rb CHANGED
@@ -21,5 +21,7 @@ require_relative "sys/init"
21
21
  require_relative "sys/leader"
22
22
  require_relative "sys/lease"
23
23
  require_relative "sys/mount"
24
+ require_relative "sys/namespace"
24
25
  require_relative "sys/policy"
26
+ require_relative "sys/quota"
25
27
  require_relative "sys/seal"
@@ -16,6 +16,11 @@ module Vault
16
16
  # Type of the mount.
17
17
  # @return [String]
18
18
  field :type
19
+
20
+ # @!attribute [r] type
21
+ # Options given to the mount.
22
+ # @return [Hash<Symbol, Object>]
23
+ field :options
19
24
  end
20
25
 
21
26
  class Sys < Request
@@ -0,0 +1,83 @@
1
+ module Vault
2
+ class Namespace < Response
3
+ # @!attribute [r] id
4
+ # ID of the namespace
5
+ # @return [String]
6
+ field :id
7
+
8
+ # @!attribute [r] path
9
+ # Path of the namespace, includes parent paths if nested.
10
+ # @return [String]
11
+ field :path
12
+ end
13
+
14
+ class Sys
15
+ # List all namespaces in a given scope. Ignores nested namespaces.
16
+ #
17
+ # @example
18
+ # Vault.sys.namespaces #=> { :foo => #<struct Vault::Namespace id="xxxx1", path="foo/" }
19
+ #
20
+ # @return [Hash<Symbol, Namespace>]
21
+ def namespaces(scoped=nil)
22
+ path = ["v1", scoped, "sys", "namespaces"].compact
23
+ json = client.list(path.join("/"))
24
+ json = json[:data] if json[:data]
25
+ if json[:key_info]
26
+ json = json[:key_info]
27
+ hash = {}
28
+ json.each do |k,v|
29
+ hash[k.to_s.chomp("/").to_sym] = Namespace.decode(v)
30
+ end
31
+ hash
32
+ else
33
+ json
34
+ end
35
+ end
36
+
37
+ # Create a namespace. Nests the namespace if a namespace header is provided.
38
+ #
39
+ # @example
40
+ # Vault.sys.create_namespace("foo")
41
+ #
42
+ # @param [String] namespace
43
+ # the potential path of the namespace, without any parent path provided
44
+ #
45
+ # @return [true]
46
+ def create_namespace(namespace)
47
+ client.put("/v1/sys/namespaces/#{namespace}", {})
48
+ return true
49
+ end
50
+
51
+ # Delete a namespace. Raises an error if the namespace provided is not empty.
52
+ #
53
+ # @example
54
+ # Vault.sys.delete_namespace("foo")
55
+ #
56
+ # @param [String] namespace
57
+ # the path of the namespace to be deleted
58
+ #
59
+ # @return [true]
60
+ def delete_namespace(namespace)
61
+ client.delete("/v1/sys/namespaces/#{namespace}")
62
+ return true
63
+ end
64
+
65
+ # Retrieve a namespace by path.
66
+ #
67
+ # @example
68
+ # Vault.sys.get_namespace("foo")
69
+ #
70
+ # @param [String] namespace
71
+ # the path of the namespace ot be retrieved
72
+ #
73
+ # @return [Namespace]
74
+ def get_namespace(namespace)
75
+ json = client.get("/v1/sys/namespaces/#{namespace}")
76
+ if data = json.dig(:data)
77
+ Namespace.decode(data)
78
+ else
79
+ json
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,107 @@
1
+ module Vault
2
+ class Quota < Response
3
+ # @!attribute [r] name
4
+ # Name of the quota rule.
5
+ # @return [String]
6
+ field :name
7
+
8
+ # @!attribute [r] path
9
+ # Namespace/Path combination the quota applies to.
10
+ # @return [String]
11
+ field :path
12
+
13
+ # @!attribute [r] type
14
+ # Type of the quota rule, must be one of "lease-count" or "rate-limit"
15
+ # @return [String]
16
+ field :type
17
+ end
18
+
19
+ class RateLimitQuota < Quota
20
+ # @!attribute [r] rate
21
+ # The rate at which allowed requests are refilled per second by the quota
22
+ # rule.
23
+ # @return [Float]
24
+ field :rate
25
+
26
+ # @!attribute [r] burst
27
+ # The maximum number of requests at any given second allowed by the quota
28
+ # rule.
29
+ # @return [Int]
30
+ field :burst
31
+ end
32
+
33
+ class LeaseCountQuota < Quota
34
+ # @!attribute [r] counter
35
+ # Number of currently active leases for the quota.
36
+ # @return [Int]
37
+ field :counter
38
+
39
+ # @!attribute [r] max_leases
40
+ # The maximum number of allowed leases for this quota.
41
+ # @return [Int]
42
+ field :max_leases
43
+ end
44
+
45
+ class Sys
46
+ def quotas(type)
47
+ path = generate_path(type)
48
+ json = client.list(path)
49
+ if data = json.dig(:data, :key_info)
50
+ data.map do |item|
51
+ type_class(type).decode(item)
52
+ end
53
+ else
54
+ json
55
+ end
56
+ end
57
+
58
+ def create_quota(type, name, opts={})
59
+ path = generate_path(type, name)
60
+ client.post(path, JSON.fast_generate(opts))
61
+ return true
62
+ end
63
+
64
+ def delete_quota(type, name)
65
+ path = generate_path(type, name)
66
+ client.delete(path)
67
+ return true
68
+ end
69
+
70
+ def get_quota(type, name)
71
+ path = generate_path(type, name)
72
+ response = client.get(path)
73
+ if data = response[:data]
74
+ type_class(type).decode(data)
75
+ end
76
+ end
77
+
78
+ def get_quota_config
79
+ client.get("v1/sys/quotas/config")
80
+ end
81
+
82
+ def update_quota_config(opts={})
83
+ client.post("v1/sys/quotas/config", JSON.fast_generate(opts))
84
+ return true
85
+ end
86
+
87
+ private
88
+
89
+ def generate_path(type, name=nil)
90
+ verify_type(type)
91
+ path = ["v1", "sys", "quotas", type, name].compact
92
+ path.join("/")
93
+ end
94
+
95
+ def verify_type(type)
96
+ return if ["rate-limit", "lease-count"].include?(type)
97
+ raise ArgumentError, "type must be one of \"rate-limit\" or \"lease-count\""
98
+ end
99
+
100
+ def type_class(type)
101
+ case type
102
+ when "lease-count" then LeaseCountQuota
103
+ when "rate-limit" then RateLimitQuota
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,29 @@
1
+ require_relative '../client'
2
+ require_relative '../request'
3
+
4
+ module Vault
5
+ class Client
6
+ # A proxy to the {Transform} methods.
7
+ # @return [Transform]
8
+ def transform
9
+ @transform ||= Transform.new(self)
10
+ end
11
+ end
12
+
13
+ class Transform < Request
14
+ def encode(role_name:, **opts)
15
+ opts ||= {}
16
+ client.post("/v1/transform/encode/#{encode_path(role_name)}", JSON.fast_generate(opts))
17
+ end
18
+
19
+ def decode(role_name:, **opts)
20
+ opts ||= {}
21
+ client.post("/v1/transform/decode/#{encode_path(role_name)}", JSON.fast_generate(opts))
22
+ end
23
+ end
24
+ end
25
+
26
+ require_relative 'transform/alphabet'
27
+ require_relative 'transform/role'
28
+ require_relative 'transform/template'
29
+ require_relative 'transform/transformation'
@@ -0,0 +1,43 @@
1
+ require_relative '../../request'
2
+ require_relative '../../response'
3
+
4
+ module Vault
5
+ class Transform < Request
6
+ class Alphabet < Response
7
+ # @!attribute [r] id
8
+ # String listing all possible characters of the alphabet
9
+ # @return [String]
10
+ field :alphabet
11
+ end
12
+
13
+ def create_alphabet(name, alphabet:, **opts)
14
+ opts ||= {}
15
+ opts[:alphabet] = alphabet
16
+ client.post("/v1/transform/alphabet/#{encode_path(name)}", JSON.fast_generate(opts))
17
+ return true
18
+ end
19
+
20
+ def get_alphabet(name)
21
+ json = client.get("/v1/transform/alphabet/#{encode_path(name)}")
22
+ if data = json.dig(:data)
23
+ Alphabet.decode(data)
24
+ else
25
+ json
26
+ end
27
+ end
28
+
29
+ def delete_alphabet(name)
30
+ client.delete("/v1/transform/alphabet/#{encode_path(name)}")
31
+ true
32
+ end
33
+
34
+ def alphabets
35
+ json = client.list("/v1/transform/alphabet")
36
+ if keys = json.dig(:data, :keys)
37
+ keys
38
+ else
39
+ json
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,42 @@
1
+ require_relative '../../request'
2
+ require_relative '../../response'
3
+
4
+ module Vault
5
+ class Transform < Request
6
+ class Role < Response
7
+ # @!attribute [r] transformations
8
+ # Array of all transformations the role has access to
9
+ # @return [Array<String>]
10
+ field :transformations
11
+ end
12
+
13
+ def create_role(name, **opts)
14
+ opts ||= {}
15
+ client.post("/v1/transform/role/#{encode_path(name)}", JSON.fast_generate(opts))
16
+ return true
17
+ end
18
+
19
+ def get_role(name)
20
+ json = client.get("/v1/transform/role/#{encode_path(name)}")
21
+ if data = json.dig(:data)
22
+ Role.decode(data)
23
+ else
24
+ json
25
+ end
26
+ end
27
+
28
+ def delete_role(name)
29
+ client.delete("/v1/transform/role/#{encode_path(name)}")
30
+ true
31
+ end
32
+
33
+ def roles
34
+ json = client.list("/v1/transform/role")
35
+ if keys = json.dig(:data, :keys)
36
+ keys
37
+ else
38
+ json
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,54 @@
1
+ require_relative '../../request'
2
+ require_relative '../../response'
3
+
4
+ module Vault
5
+ class Transform < Request
6
+ class Template < Response
7
+ # @!attribute [r] alphabet
8
+ # Name of the alphabet to be used in the template
9
+ # @return [String]
10
+ field :alphabet
11
+
12
+ # @!attribute [r] pattern
13
+ # Regex string to detect and match for the template
14
+ # @return [String]
15
+ field :pattern
16
+
17
+ # @!attribute [r] type
18
+ # Type of the template, currently, only "regex" is supported
19
+ # @return [String]
20
+ field :type
21
+ end
22
+
23
+ def create_template(name, type:, pattern:, **opts)
24
+ opts ||= {}
25
+ opts[:type] = type
26
+ opts[:pattern] = pattern
27
+ client.post("/v1/transform/template/#{encode_path(name)}", JSON.fast_generate(opts))
28
+ return true
29
+ end
30
+
31
+ def get_template(name)
32
+ json = client.get("/v1/transform/template/#{encode_path(name)}")
33
+ if data = json.dig(:data)
34
+ Template.decode(data)
35
+ else
36
+ json
37
+ end
38
+ end
39
+
40
+ def delete_template(name)
41
+ client.delete("/v1/transform/template/#{encode_path(name)}")
42
+ true
43
+ end
44
+
45
+ def templates
46
+ json = client.list("/v1/transform/template")
47
+ if keys = json.dig(:data, :keys)
48
+ keys
49
+ else
50
+ json
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,61 @@
1
+ require_relative '../../request'
2
+ require_relative '../../response'
3
+
4
+ module Vault
5
+ class Transform < Request
6
+ class Transformation < Response
7
+ # @!attribute [r] allowed_roles
8
+ # Array of role names that are allowed to use this transformation
9
+ # @return [Array<String>]
10
+ field :allowed_roles
11
+
12
+ # @!attribute [r] templates
13
+ # Array of template names accessible to this transformation
14
+ # @return [Array<String>]
15
+ field :templates
16
+
17
+ # @!attribute [r] tweak_source
18
+ # String representing how a tweak is provided for this transformation.
19
+ # Available tweaks are "supplied", "generated", and "internal"
20
+ # @return [String]
21
+ field :tweak_source
22
+
23
+ # @!attribute [r] type
24
+ # String representing the type of transformation this is.
25
+ # Available types are "fpe", and "masking"
26
+ # @return [String]
27
+ field :type
28
+ end
29
+
30
+ def create_transformation(name, type:, template:, **opts)
31
+ opts ||= {}
32
+ opts[:type] = type
33
+ opts[:template] = template
34
+ client.post("/v1/transform/transformation/#{encode_path(name)}", JSON.fast_generate(opts))
35
+ return true
36
+ end
37
+
38
+ def get_transformation(name)
39
+ json = client.get("/v1/transform/transformation/#{encode_path(name)}")
40
+ if data = json.dig(:data)
41
+ Transformation.decode(data)
42
+ else
43
+ json
44
+ end
45
+ end
46
+
47
+ def delete_transformation(name)
48
+ client.delete("/v1/transform/transformation/#{encode_path(name)}")
49
+ true
50
+ end
51
+
52
+ def transformations
53
+ json = client.list("/v1/transform/transformation")
54
+ if keys = json.dig(:data, :keys)
55
+ keys
56
+ else
57
+ json
58
+ end
59
+ end
60
+ end
61
+ end
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 Namespace.
20
+ NAMESPACE_HEADER = "X-Vault-Namespace".freeze
21
+
19
22
  # The name of the header used to hold the wrapped request ttl.
20
23
  WRAP_TTL_HEADER = "X-Vault-Wrap-TTL".freeze
21
24
 
@@ -83,7 +86,7 @@ module Vault
83
86
  @lock.synchronize do
84
87
  return @nhp if @nhp
85
88
 
86
- @nhp = PersistentHTTP.new("vault-ruby", nil, pool_size)
89
+ @nhp = PersistentHTTP.new("vault-ruby", nil, pool_size, pool_timeout)
87
90
 
88
91
  if proxy_address
89
92
  proxy_uri = URI.parse "http://#{proxy_address}"
@@ -255,6 +258,12 @@ module Vault
255
258
  headers[TOKEN_HEADER] ||= token
256
259
  end
257
260
 
261
+ # Add the Vault Namespace header - users could still override this on a
262
+ # per-request basis
263
+ if !namespace.nil?
264
+ headers[NAMESPACE_HEADER] ||= namespace
265
+ end
266
+
258
267
  # Add headers
259
268
  headers.each do |key, value|
260
269
  request.add_field(key, value)
@@ -7,12 +7,14 @@ module Vault
7
7
  :address,
8
8
  :token,
9
9
  :hostname,
10
+ :namespace,
10
11
  :open_timeout,
11
12
  :proxy_address,
12
13
  :proxy_password,
13
14
  :proxy_port,
14
15
  :proxy_username,
15
16
  :pool_size,
17
+ :pool_timeout,
16
18
  :read_timeout,
17
19
  :ssl_ciphers,
18
20
  :ssl_pem_contents,
@@ -30,6 +30,9 @@ module Vault
30
30
  # The default size of the connection pool
31
31
  DEFAULT_POOL_SIZE = 16
32
32
 
33
+ # The default timeout in seconds for retrieving a connection from the connection pool
34
+ DEFAULT_POOL_TIMEOUT = 0.5
35
+
33
36
  # The set of exceptions that are detect and retried by default
34
37
  # with `with_retries`
35
38
  RETRIED_EXCEPTIONS = [HTTPServerError]
@@ -61,6 +64,13 @@ module Vault
61
64
  nil
62
65
  end
63
66
 
67
+
68
+ # Vault Namespace, if any.
69
+ # @return [String, nil]
70
+ def namespace
71
+ ENV["VAULT_NAMESPACE"]
72
+ end
73
+
64
74
  # The SNI host to use when connecting to Vault via TLS.
65
75
  # @return [String, nil]
66
76
  def hostname
@@ -78,12 +88,22 @@ module Vault
78
88
  # @return Integer
79
89
  def pool_size
80
90
  if var = ENV["VAULT_POOL_SIZE"]
81
- return var.to_i
91
+ var.to_i
82
92
  else
83
93
  DEFAULT_POOL_SIZE
84
94
  end
85
95
  end
86
96
 
97
+ # The timeout for getting a connection from the connection pool that communicates with Vault
98
+ # @return Float
99
+ def pool_timeout
100
+ if var = ENV["VAULT_POOL_TIMEOUT"]
101
+ var.to_f
102
+ else
103
+ DEFAULT_POOL_TIMEOUT
104
+ end
105
+ end
106
+
87
107
  # The HTTP Proxy server address as a string
88
108
  # @return [String, nil]
89
109
  def proxy_address
@@ -202,11 +202,6 @@ class PersistentHTTP
202
202
 
203
203
  HAVE_OPENSSL = defined? OpenSSL::SSL # :nodoc:
204
204
 
205
- ##
206
- # The default connection pool size is 1/4 the allowed open files.
207
-
208
- DEFAULT_POOL_SIZE = 16
209
-
210
205
  ##
211
206
  # The version of PersistentHTTP you are using
212
207
 
@@ -505,7 +500,7 @@ class PersistentHTTP
505
500
  # Defaults to 1/4 the number of allowed file handles. You can have no more
506
501
  # than this many threads with active HTTP transactions.
507
502
 
508
- def initialize name=nil, proxy=nil, pool_size=DEFAULT_POOL_SIZE
503
+ def initialize name=nil, proxy=nil, pool_size=Vault::Defaults::DEFAULT_POOL_SIZE, pool_timeout=Vault::Defaults::DEFAULT_POOL_TIMEOUT
509
504
  @name = name
510
505
 
511
506
  @debug_output = nil
@@ -525,7 +520,7 @@ class PersistentHTTP
525
520
  @socket_options << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if
526
521
  Socket.const_defined? :TCP_NODELAY
527
522
 
528
- @pool = PersistentHTTP::Pool.new size: pool_size do |http_args|
523
+ @pool = PersistentHTTP::Pool.new size: pool_size, timeout: pool_timeout do |http_args|
529
524
  PersistentHTTP::Connection.new Net::HTTP, http_args, @ssl_generation
530
525
  end
531
526
 
@@ -31,7 +31,7 @@ class PersistentHTTP::Pool < Vault::ConnectionPool # :nodoc:
31
31
  stack = stacks[net_http_args]
32
32
 
33
33
  if stack.empty? then
34
- conn = @available.pop connection_args: net_http_args
34
+ conn = @available.pop @timeout, connection_args: net_http_args
35
35
  else
36
36
  conn = stack.last
37
37
  end
data/lib/vault/request.rb CHANGED
@@ -29,6 +29,7 @@ module Vault
29
29
  def extract_headers!(options = {})
30
30
  extract = {
31
31
  wrap_ttl: Vault::Client::WRAP_TTL_HEADER,
32
+ namespace: Vault::Client::NAMESPACE_HEADER,
32
33
  }
33
34
 
34
35
  {}.tap do |h|
data/lib/vault/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Vault
2
- VERSION = "0.13.0"
2
+ VERSION = "0.16.0"
3
3
  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.13.0
4
+ version: 0.16.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: 2019-10-01 00:00:00.000000000 Z
11
+ date: 2021-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sigv4
@@ -28,30 +28,30 @@ dependencies:
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '2'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: pry
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 0.13.1
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 0.13.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -84,30 +84,30 @@ dependencies:
84
84
  name: yard
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: 0.9.24
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: 0.9.24
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: webmock
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '2.3'
103
+ version: 3.8.3
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '2.3'
110
+ version: 3.8.3
111
111
  description: Vault is a Ruby API client for interacting with a Vault server.
112
112
  email:
113
113
  - sethvargo@gmail.com
@@ -115,14 +115,9 @@ executables: []
115
115
  extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
- - ".gitignore"
119
- - ".rspec"
120
- - ".travis.yml"
121
118
  - CHANGELOG.md
122
- - Gemfile
123
119
  - LICENSE
124
120
  - README.md
125
- - Rakefile
126
121
  - lib/vault.rb
127
122
  - lib/vault/api.rb
128
123
  - lib/vault/api/approle.rb
@@ -141,8 +136,15 @@ files:
141
136
  - lib/vault/api/sys/leader.rb
142
137
  - lib/vault/api/sys/lease.rb
143
138
  - lib/vault/api/sys/mount.rb
139
+ - lib/vault/api/sys/namespace.rb
144
140
  - lib/vault/api/sys/policy.rb
141
+ - lib/vault/api/sys/quota.rb
145
142
  - lib/vault/api/sys/seal.rb
143
+ - lib/vault/api/transform.rb
144
+ - lib/vault/api/transform/alphabet.rb
145
+ - lib/vault/api/transform/role.rb
146
+ - lib/vault/api/transform/template.rb
147
+ - lib/vault/api/transform/transformation.rb
146
148
  - lib/vault/client.rb
147
149
  - lib/vault/configurable.rb
148
150
  - lib/vault/defaults.rb
@@ -158,7 +160,6 @@ files:
158
160
  - lib/vault/vendor/connection_pool/timed_stack.rb
159
161
  - lib/vault/vendor/connection_pool/version.rb
160
162
  - lib/vault/version.rb
161
- - vault.gemspec
162
163
  homepage: https://github.com/hashicorp/vault-ruby
163
164
  licenses:
164
165
  - MPL-2.0
@@ -171,15 +172,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
171
172
  requirements:
172
173
  - - ">="
173
174
  - !ruby/object:Gem::Version
174
- version: '0'
175
+ version: '2.0'
175
176
  required_rubygems_version: !ruby/object:Gem::Requirement
176
177
  requirements:
177
178
  - - ">="
178
179
  - !ruby/object:Gem::Version
179
180
  version: '0'
180
181
  requirements: []
181
- rubyforge_project:
182
- rubygems_version: 2.7.6
182
+ rubygems_version: 3.2.3
183
183
  signing_key:
184
184
  specification_version: 4
185
185
  summary: Vault is a Ruby API client for interacting with a Vault server.
data/.gitignore DELETED
@@ -1,42 +0,0 @@
1
- ### Ruby ###
2
- *.gem
3
- *.rbc
4
- /.config
5
- /.vscode
6
- /coverage/
7
- /InstalledFiles
8
- /pkg/
9
- /spec/reports/
10
- /test/tmp/
11
- /test/version_tmp/
12
- /tmp/
13
- /vendor/bundle/
14
- /vendor/ruby/
15
-
16
- ## Specific to RubyMotion:
17
- .dat*
18
- .repl_history
19
- build/
20
-
21
- ## Documentation cache and generated files:
22
- /.yardoc/
23
- /_yardoc/
24
- /doc/
25
- /rdoc/
26
-
27
- ## Environment normalisation:
28
- /.bundle/
29
- /vendor/bundle
30
- /lib/bundler/man/
31
-
32
- # for a library or gem, you might want to ignore these files since the code is
33
- # intended to run in multiple environments; otherwise, check them in:
34
- Gemfile.lock
35
- .ruby-version
36
- .ruby-gemset
37
-
38
- # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
39
- .rvmrc
40
-
41
- # Project-specific
42
- spec/tmp
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --format documentation
2
- --color
data/.travis.yml DELETED
@@ -1,29 +0,0 @@
1
- dist: trusty
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
-
6
- env:
7
- - VAULT_VERSION=0.11.4
8
- - VAULT_VERSION=0.10.4
9
- - VAULT_VERSION=0.9.6
10
- - VAULT_VERSION=0.8.3
11
- - VAULT_VERSION=0.7.3
12
- - VAULT_VERSION=0.6.5
13
- - VAULT_VERSION=0.5.3
14
-
15
- before_install:
16
- - curl -sLo vault.zip https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip
17
- - unzip vault.zip
18
- - mkdir -p ~/bin
19
- - mv vault ~/bin
20
- - export PATH="~/bin:$PATH"
21
-
22
- branches:
23
- only:
24
- - master
25
-
26
- rvm:
27
- - 2.2
28
- - 2.3
29
- - 2.4
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task default: :spec
data/vault.gemspec DELETED
@@ -1,30 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "vault/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "vault"
8
- spec.version = Vault::VERSION
9
- spec.authors = ["Seth Vargo"]
10
- spec.email = ["sethvargo@gmail.com"]
11
- spec.licenses = ["MPL-2.0"]
12
-
13
- spec.summary = "Vault is a Ruby API client for interacting with a Vault server."
14
- spec.description = spec.summary
15
- spec.homepage = "https://github.com/hashicorp/vault-ruby"
16
-
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- spec.bindir = "exe"
19
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ["lib"]
21
-
22
- spec.add_runtime_dependency "aws-sigv4"
23
-
24
- spec.add_development_dependency "bundler"
25
- spec.add_development_dependency "pry"
26
- spec.add_development_dependency "rake", "~> 12.0"
27
- spec.add_development_dependency "rspec", "~> 3.5"
28
- spec.add_development_dependency "yard"
29
- spec.add_development_dependency "webmock", "~> 2.3"
30
- end