settings_reader-vault_resolver 0.2.4 → 0.4.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce73ad9e3b10d933922778fa85c1f2fecc4f33dd0041a83c4b6b034229c7574f
4
- data.tar.gz: eef4339b9136147de04ba2e85648fbf2328c3771fed427e600edf544683c1c98
3
+ metadata.gz: 4e24591d4c66561cb24e3e12d124d2c4f4ca90236112f6324f709883297e692f
4
+ data.tar.gz: df5df6353fb0169385697bdb2c6b6e6b1ca082a7cc99e99e166cf29ad38354bc
5
5
  SHA512:
6
- metadata.gz: ddab1303046474d0da7916d9e64803d9c599f1ee80e2d50e2c96e4cc73ff17f5d4e0b45dd0db37447d3553596135883ca088868800c588f9ceffb7113457bfe4
7
- data.tar.gz: 6f31f31fccc0281890df52503a9b8c353229fe7cc6f4233eb251e69ed245ea63acdc8bd4cd9e9e5cd1e0f6ef00c448ba30e0afb732105d2322a0ae338180438d
6
+ metadata.gz: 3b08d59ab15c02f04f0204e071da10b72aefdd1fe5ef0a70e3902c94487993aadf30afb852a68de9af984f76624dc032d2d4a79e71bce27163782725de15ebff
7
+ data.tar.gz: a56e1ef3320ba333755c27aa31aea29a51c82c8f6cbdb32cc0f5a287e93636286ee2b4a51ef950318a7029e6ff46bc52199e42832aecfe9661803398f4f9fc74
data/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0]
4
+ ### Breaking changes
5
+ - Reworked authentication helpers interface
6
+
7
+ ### New features
8
+ - Retry secret retrieval and renewal
9
+ - Capture more vault exceptions including connectivity errors
10
+ - Introduce vault engine adapter concept
11
+ - Separate kv, database, and auth engine logic
12
+
13
+ ## [0.3.0]
14
+ ### Breaking changes
15
+ - Require configuration before use
16
+
17
+ ### New features
18
+ - Gem configurations
19
+ - Require configuration before use
20
+ - Report renew errors via configuration listeners
21
+
22
+ ### Fixes
23
+ - Cleanup logging
24
+
25
+ ## [0.2.4]
26
+ ### Fixes
27
+ - Fix refresher task logging
28
+
29
+ ## [0.2.3]
30
+ ### Fixes
31
+ - Fix logging setup when gem loaded before rails
32
+
33
+ ## [0.2.2]
34
+ ### New features
35
+ - Add logging to gem
36
+
3
37
  ## [0.2.1]
4
38
  ### Fixes
5
39
  - Use default k8s auth route without namespace
@@ -21,7 +55,12 @@
21
55
  - Secrets caching
22
56
  - Automatic secrets lease renewal
23
57
 
24
- [Unreleased]: https://github.com/matic-insurance/settings_reader-vault_resolver/compare/0.2.1...HEAD
58
+ [Unreleased]: https://github.com/matic-insurance/settings_reader-vault_resolver/compare/0.4.0...HEAD
59
+ [0.4.0]: https://github.com/matic-insurance/settings_reader-vault_resolver/commits/0.4.0
60
+ [0.3.0]: https://github.com/matic-insurance/settings_reader-vault_resolver/commits/0.3.0
61
+ [0.2.4]: https://github.com/matic-insurance/settings_reader-vault_resolver/commits/0.2.4
62
+ [0.2.3]: https://github.com/matic-insurance/settings_reader-vault_resolver/commits/0.2.3
63
+ [0.2.2]: https://github.com/matic-insurance/settings_reader-vault_resolver/commits/0.2.2
25
64
  [0.2.1]: https://github.com/matic-insurance/settings_reader-vault_resolver/commits/0.2.1
26
65
  [0.2.0]: https://github.com/matic-insurance/settings_reader-vault_resolver/commits/0.2.0
27
66
  [0.1.1]: https://github.com/matic-insurance/settings_reader-vault_resolver/commits/0.1.1
data/README.md CHANGED
@@ -28,7 +28,13 @@ Vault.token = 'MY_SUPER_SECRET_TOKEN'
28
28
 
29
29
  #Load Settings Reader and configure resolver
30
30
  AppSettings = SettingsReader.load do |config|
31
- # ... Other configurations
31
+ # ... SettingReader configurations
32
+
33
+ # Configure vault resolver
34
+ SettingsReader::VaultResolver.configure do |vault_resolver_config|
35
+ vault_resolver_config.logger = Rails.logger
36
+ # ... VaultResolver configurations
37
+ end
32
38
 
33
39
  # Add vault resolver as one of resolvers
34
40
  config.resolvers << SettingsReader::VaultResolver.resolver
data/codecov.yml ADDED
@@ -0,0 +1,12 @@
1
+ codecov:
2
+ require_ci_to_pass: yes
3
+
4
+ coverage:
5
+ precision: 2
6
+ round: up
7
+ range: "90...100"
8
+
9
+ ignore:
10
+ - "spec"
11
+ - "bin"
12
+ - "local"
@@ -36,6 +36,10 @@ module SettingsReader
36
36
  @secrets.each_value(&block)
37
37
  end
38
38
 
39
+ def clear_all
40
+ @secrets = {}
41
+ end
42
+
39
43
  private
40
44
 
41
45
  def cache_key(address)
@@ -0,0 +1,71 @@
1
+ module SettingsReader
2
+ module VaultResolver
3
+ # Configurations for vault resolver
4
+ class Configuration
5
+ # Logger for gem
6
+ # Default: Logger.new(STDOUT, level: Logger::ERROR)
7
+ attr_accessor :logger
8
+
9
+ # How many times to retry retrieval of the secret
10
+ # Default: 2
11
+ attr_accessor :retrieval_retries
12
+
13
+ # How often do we check if secret lease is about to expire
14
+ # Default: 60seconds
15
+ attr_accessor :lease_refresh_interval
16
+
17
+ # Time before expiration when we try to renew the lease
18
+ # Default: 300seconds
19
+ attr_accessor :lease_renew_delay
20
+
21
+ # How many times to retry renew of the secret
22
+ # Default: 4
23
+ attr_accessor :lease_renew_retries
24
+
25
+ # Block to be executed when lease is refreshed
26
+ # Default: empty proc
27
+ attr_accessor :lease_renew_success_listener
28
+
29
+ # Block to be executed when lease is not refreshed
30
+ # Default: empty proc
31
+ attr_accessor :lease_renew_error_listener
32
+
33
+ def initialize
34
+ @logger = Logger.new($stdout, level: Logger::ERROR)
35
+ @retrieval_retries = 2
36
+ @lease_refresh_interval = 60
37
+ @lease_renew_delay = 300
38
+ @lease_renew_retries = 4
39
+ @lease_renew_error_listener = proc {}
40
+ @lease_renew_success_listener = proc {}
41
+ end
42
+
43
+ def setup_lease_refresher(cache, previous_task = nil)
44
+ previous_task&.shutdown
45
+
46
+ timer_task = Concurrent::TimerTask.new(execution_interval: lease_refresh_interval) do
47
+ SettingsReader::VaultResolver::Refresher.new(cache, self).refresh
48
+ end
49
+ timer_task.add_observer(SettingsReader::VaultResolver::RefresherObserver.new(self))
50
+ timer_task.execute
51
+ timer_task
52
+ end
53
+
54
+ def vault_engines
55
+ @vault_engines ||= [
56
+ SettingsReader::VaultResolver::Engines::KV2.new(self),
57
+ SettingsReader::VaultResolver::Engines::Database.new(self),
58
+ SettingsReader::VaultResolver::Engines::Auth.new(self)
59
+ ]
60
+ end
61
+
62
+ def vault_engine_for(address)
63
+ unless (engine = vault_engines.detect { |e| e.retrieves?(address) })
64
+ raise SettingsReader::VaultResolver::Error, "Unknown engine for #{address}"
65
+ end
66
+
67
+ engine
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,64 @@
1
+ module SettingsReader
2
+ module VaultResolver
3
+ module Engines
4
+ # Abstract interface for Vault Backends
5
+ class Abstract
6
+ include Logging
7
+
8
+ attr_reader :config
9
+
10
+ def initialize(config)
11
+ @config = config
12
+ end
13
+
14
+ def retrieves?(_address)
15
+ raise NotImplementedError
16
+ end
17
+
18
+ def get(address)
19
+ return unless (vault_secret = get_secret_with_retries(address))
20
+
21
+ wrap_secret(address, vault_secret)
22
+ rescue Vault::VaultError => e
23
+ raise SettingsReader::VaultResolver::Error, e.message
24
+ end
25
+
26
+ def renew(entry)
27
+ return unless entry.leased?
28
+
29
+ new_secret = renew_lease_with_retries(entry)
30
+ entry.update_renewed(new_secret)
31
+ true
32
+ rescue Vault::VaultError => e
33
+ raise SettingsReader::VaultResolver::Error, e.message
34
+ end
35
+
36
+ protected
37
+
38
+ def get_secret_with_retries(address)
39
+ Vault.with_retries(Vault::HTTPConnectionError, attempts: config.retrieval_retries) do
40
+ get_secret(address)
41
+ end
42
+ end
43
+
44
+ def renew_lease_with_retries(address)
45
+ Vault.with_retries(Vault::HTTPConnectionError, attempts: config.lease_renew_retries) do
46
+ renew_lease(address)
47
+ end
48
+ end
49
+
50
+ def get_secret(address)
51
+ raise NotImplementedError
52
+ end
53
+
54
+ def renew_lease(entry)
55
+ raise NotImplementedError
56
+ end
57
+
58
+ def wrap_secret(address, secret)
59
+ SettingsReader::VaultResolver::Entry.new(address, secret)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,36 @@
1
+ module SettingsReader
2
+ module VaultResolver
3
+ module Engines
4
+ # Adapter to retrieve / renew auth tokens
5
+ class Auth < Abstract
6
+ MOUNT = 'auth'.freeze
7
+ K8S_AUTH = 'kubernetes/login'.freeze
8
+
9
+ def retrieves?(address)
10
+ address.mount == MOUNT
11
+ end
12
+
13
+ protected
14
+
15
+ def get_secret(address)
16
+ return k8s_auth(address) if address.path == K8S_AUTH
17
+
18
+ raise SettingsReader::VaultResolver::Error, "Unsupported auth backed for #{address}"
19
+ end
20
+
21
+ def renew_lease(_entry)
22
+ secret = Vault.client.auth_token.renew_self
23
+ secret&.auth
24
+ end
25
+
26
+ private
27
+
28
+ def k8s_auth(address)
29
+ options = { route: address.options['route'], service_token_path: address.options['service_token_path'] }
30
+ secret = Vault.auth.kubernetes(address.options['role'], **options)
31
+ secret&.auth
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,29 @@
1
+ module SettingsReader
2
+ module VaultResolver
3
+ module Engines
4
+ # Adapter to retrieve / renew secret from database engine
5
+ class Database < Abstract
6
+ MOUNT = 'database'.freeze
7
+
8
+ def retrieves?(address)
9
+ address.mount == MOUNT
10
+ end
11
+
12
+ private
13
+
14
+ def get_secret(address)
15
+ debug { "Fetching new database secret at: #{address}" }
16
+ Vault.logical.read(address.full_path)
17
+ rescue Vault::HTTPClientError => e
18
+ return nil if e.message.include?('* unknown role')
19
+
20
+ raise e
21
+ end
22
+
23
+ def renew_lease(entry)
24
+ Vault.sys.renew(entry.lease_id)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ module SettingsReader
2
+ module VaultResolver
3
+ module Engines
4
+ # Adapter to retrieve / renew secret from kv2 engine
5
+ class KV2 < Abstract
6
+ MOUNT = 'secret'.freeze
7
+
8
+ def retrieves?(address)
9
+ address.mount == MOUNT
10
+ end
11
+
12
+ def renew(_entry)
13
+ # KV secrets are static. Nothing to do
14
+ end
15
+
16
+ private
17
+
18
+ def get_secret(address)
19
+ debug { "Fetching new kv secret at: #{address}" }
20
+ Vault.kv(address.mount).read(address.path)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -13,7 +13,7 @@ module SettingsReader
13
13
  end
14
14
 
15
15
  def leased?
16
- @secret.lease_id && lease_duration.positive?
16
+ @secret.renewable?
17
17
  end
18
18
 
19
19
  def expired?
@@ -28,26 +28,26 @@ module SettingsReader
28
28
  @lease_started + lease_duration - Time.now
29
29
  end
30
30
 
31
- def renew
32
- return unless leased?
31
+ def lease_id
32
+ @secret.lease_id
33
+ end
33
34
 
34
- @secret = Vault.sys.renew(@secret.lease_id)
35
+ def update_renewed(new_secret)
36
+ @secret = new_secret
35
37
  @lease_started = Time.now
36
- true
37
- rescue Vault::HTTPClientError => e
38
- raise SettingsReader::VaultResolver::Error, e.message
39
38
  end
40
39
 
41
40
  def value_for(attribute)
42
- secret.data[attribute.to_sym]
41
+ return secret.data[attribute.to_sym] if secret.respond_to?(:data) && secret.data.key?(attribute.to_sym)
42
+ return secret.public_send(attribute) if secret.respond_to?(attribute)
43
+
44
+ nil
43
45
  end
44
46
 
45
47
  def to_s
46
48
  address.to_s
47
49
  end
48
50
 
49
- private
50
-
51
51
  def lease_duration
52
52
  @secret.lease_duration.to_i
53
53
  end
@@ -0,0 +1,23 @@
1
+ require_relative '../patches/authenticate'
2
+
3
+ module SettingsReader
4
+ module VaultResolver
5
+ module Helpers
6
+ # Helps with authentication using different schemes
7
+ class VaultAuthentication
8
+ FAKE_RESOLVER_PATH = 'vault/authentication'.freeze
9
+
10
+ def authenticate_via_k8s(role, route: nil, service_token_path: nil)
11
+ params = URI.encode_www_form({ role: role, route: route, service_token_path: service_token_path }.compact)
12
+ resolver.resolve("vault://auth/kubernetes/login?#{params}#client_token", FAKE_RESOLVER_PATH)
13
+ end
14
+
15
+ private
16
+
17
+ def resolver
18
+ @resolver = SettingsReader::VaultResolver.resolver
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -9,6 +9,13 @@ module SettingsReader
9
9
  IDENTIFIER = 'vault://'.freeze
10
10
  DATABASE_MOUNT = 'database'.freeze
11
11
 
12
+ attr_reader :config
13
+
14
+ def initialize(config)
15
+ @config = config
16
+ @engines = config.vault_engines
17
+ end
18
+
12
19
  def resolvable?(value, _path)
13
20
  return unless value.respond_to?(:start_with?)
14
21
 
@@ -23,37 +30,16 @@ module SettingsReader
23
30
  entry&.value_for(address.attribute)
24
31
  end
25
32
 
26
- # Resolve KV secret
27
- def kv_secret(address)
28
- debug { "Fetching new kv secret at: #{address}" }
29
- Vault.kv(address.mount).read(address.path)
30
- rescue Vault::HTTPClientError => e
31
- error { "Error retrieving secret at: #{address}: #{e.message}" }
32
- raise SettingsReader::VaultResolver::Error, e.message
33
- end
34
-
35
- def database_secret(address)
36
- debug { "Fetching new database secret at: #{address}" }
37
- Vault.logical.read(address.full_path)
38
- rescue Vault::HTTPClientError => e
39
- error { "Error retrieving database secret: #{address}: #{e.message}" }
40
- return nil if e.message.include?('* unknown role')
41
-
42
- raise SettingsReader::VaultResolver::Error, e.message
43
- end
44
-
45
33
  private
46
34
 
47
35
  def fetch_entry(address)
48
36
  cache.fetch(address) do
49
37
  info { "Retrieving new secret at: #{address}" }
50
- if (secret = address.mount == DATABASE_MOUNT ? database_secret(address) : kv_secret(address))
51
- debug { "Retrieved secret at: #{address}" }
52
- SettingsReader::VaultResolver::Entry.new(address, secret)
53
- else
54
- debug { "Secret not retrieved: #{address}" }
55
- end
38
+ config.vault_engine_for(address).get(address)
56
39
  end
40
+ rescue StandardError => e
41
+ error { "Error retrieving secret: #{address}: #{e.message}" }
42
+ raise e
57
43
  end
58
44
 
59
45
  def cache
@@ -3,37 +3,34 @@ module SettingsReader
3
3
  # Methods for centralized logging
4
4
  module Logging
5
5
  def debug(&block)
6
- logger.debug do
7
- "[VaultResolver] #{block.call}"
8
- end
9
- nil
6
+ log_message(Logger::DEBUG, &block)
10
7
  end
11
8
 
12
9
  def info(&block)
13
- logger.info do
14
- "[VaultResolver] #{block.call}"
15
- end
16
- nil
10
+ log_message(Logger::INFO, &block)
17
11
  end
18
12
 
19
13
  def warn(&block)
20
- logger.warn do
21
- "[VaultResolver] #{block.call}"
22
- end
23
- nil
14
+ log_message(Logger::WARN, &block)
24
15
  end
25
16
 
26
17
  def error(&block)
27
- logger.error do
18
+ log_message(Logger::ERROR, &block)
19
+ end
20
+
21
+ private
22
+
23
+ def log_message(severity, &block)
24
+ logger&.log(severity) do
28
25
  "[VaultResolver] #{block.call}"
26
+ rescue StandardError => _e
27
+ # Ignoring errors in log message
29
28
  end
30
29
  nil
31
30
  end
32
31
 
33
- private
34
-
35
32
  def logger
36
- SettingsReader::VaultResolver.logger
33
+ config.logger
37
34
  end
38
35
  end
39
36
  end
@@ -1,7 +1,7 @@
1
1
  module Vault
2
2
  # Monkey patch to support k8s authenticaiton. Taken from https://github.com/hashicorp/vault-ruby/pull/202
3
3
  class Authenticate < Request
4
- def kubernetes(role, route = nil, service_token_path = nil)
4
+ def kubernetes(role, route: nil, service_token_path: nil)
5
5
  route ||= '/v1/auth/kubernetes/login'
6
6
  service_token_path ||= '/var/run/secrets/kubernetes.io/serviceaccount/token'
7
7
 
@@ -1,3 +1,5 @@
1
+ require 'concurrent/promise'
2
+
1
3
  module SettingsReader
2
4
  module VaultResolver
3
5
  # Vault Lease refresher task
@@ -7,35 +9,34 @@ module SettingsReader
7
9
  DEFAULT_RENEW_DELAY = 200
8
10
  REFRESH_INTERVAL = 60
9
11
 
10
- def initialize(cache)
12
+ attr_reader :cache, :config
13
+
14
+ def initialize(cache, config)
11
15
  @cache = cache
16
+ @config = config
12
17
  end
13
18
 
14
19
  def refresh
15
- info { 'Starting Vault lease refreshing' }
16
- @cache.entries.each do |entry|
20
+ info { 'Performing Vault leases refresh' }
21
+ promises = cache.entries.map do |entry|
22
+ debug { "Checking lease for #{entry}. Leased?: #{entry.leased?}. Expires in: #{entry.expires_in}s" }
17
23
  refresh_entry(entry)
18
- end
19
- info { 'Finished Vault lease refreshing' }
24
+ end.compact
25
+ promises.each(&:wait)
26
+ promises
20
27
  end
21
28
 
22
29
  def refresh_entry(entry)
23
- debug { "Checking lease for #{entry}. Leased?: #{entry.leased?}. Expires in: #{entry.expires_in}s" }
24
- return unless entry.leased?
25
- return unless entry.expires_in < DEFAULT_RENEW_DELAY
26
-
27
- info { "Refreshing lease for #{entry}. Expires in: #{entry.expires_in}" }
28
- entry.renew
29
- info { "Lease renewed for #{entry}. Expires in: #{entry.expires_in}" }
30
- rescue SettingsReader::VaultResolver::Error => e
31
- error { "Error refreshing lease for #{entry}: #{e.message}" }
32
- # Continue renewal.
33
- end
30
+ return unless entry.expires_in < config.lease_renew_delay
34
31
 
35
- def self.refresh_task(cache)
36
- refresher = self
37
- Concurrent::TimerTask.new(execution_interval: refresher::REFRESH_INTERVAL) do
38
- refresher.new(cache).refresh
32
+ Concurrent::Promise.execute do
33
+ debug { "Refreshing lease for #{entry}. Expires in: #{entry.expires_in}" }
34
+ config.vault_engine_for(entry.address).renew(entry)
35
+ info { "Lease renewed for #{entry}. Expires in: #{entry.expires_in}" }
36
+ entry
37
+ rescue StandardError => e
38
+ error { "Error refreshing lease for #{entry}: #{e.message}" }
39
+ raise SettingsReader::VaultResolver::Error, e.message
39
40
  end
40
41
  end
41
42
  end
@@ -0,0 +1,30 @@
1
+ module SettingsReader
2
+ module VaultResolver
3
+ # Check lease refresh result and report problems if needed
4
+ class RefresherObserver
5
+ attr_reader :config
6
+
7
+ def initialize(config)
8
+ @config = config
9
+ end
10
+
11
+ def update(_time, result, error)
12
+ if result
13
+ result.map do |promise|
14
+ promise.on_success(&method(:notify_success)).on_error(&method(:notify_error))
15
+ end.each(&:wait)
16
+ else
17
+ notify_error(error)
18
+ end
19
+ end
20
+
21
+ def notify_success(result)
22
+ config.lease_renew_success_listener.call(result)
23
+ end
24
+
25
+ def notify_error(result)
26
+ config.lease_renew_error_listener.call(result)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,5 @@
1
1
  module SettingsReader
2
2
  module VaultResolver
3
- VERSION = '0.2.4'.freeze
3
+ VERSION = '0.4.1'.freeze
4
4
  end
5
5
  end
@@ -2,13 +2,19 @@ require 'logger'
2
2
  require 'concurrent/timer_task'
3
3
 
4
4
  require 'settings_reader'
5
- require 'settings_reader/vault_resolver/version'
6
- require 'settings_reader/vault_resolver/logging'
7
- require 'settings_reader/vault_resolver/address'
8
- require 'settings_reader/vault_resolver/entry'
9
- require 'settings_reader/vault_resolver/cache'
10
- require 'settings_reader/vault_resolver/refresher'
11
- require 'settings_reader/vault_resolver/instance'
5
+ require_relative 'vault_resolver/version'
6
+ require_relative 'vault_resolver/logging'
7
+ require_relative 'vault_resolver/configuration'
8
+ require_relative 'vault_resolver/address'
9
+ require_relative 'vault_resolver/entry'
10
+ require_relative 'vault_resolver/engines/abstract'
11
+ require_relative 'vault_resolver/engines/auth'
12
+ require_relative 'vault_resolver/engines/kv2'
13
+ require_relative 'vault_resolver/engines/database'
14
+ require_relative 'vault_resolver/cache'
15
+ require_relative 'vault_resolver/refresher'
16
+ require_relative 'vault_resolver/refresher_observer'
17
+ require_relative 'vault_resolver/instance'
12
18
 
13
19
  module SettingsReader
14
20
  # Singleton for lease renewals and secrets cache
@@ -16,36 +22,23 @@ module SettingsReader
16
22
  class Error < StandardError; end
17
23
 
18
24
  class << self
19
- attr_accessor :cache, :refresher_timer_task
25
+ attr_reader :configuration, :refresher_timer_task
20
26
  end
21
27
 
22
- def self.logger
23
- return @logger if @logger
24
- return @logger = Rails.logger if (defined? Rails) && Rails.logger
25
-
26
- @logger = Logger.new($stdout, level: Logger::INFO)
27
- end
28
-
29
- def self.logger=(logger)
30
- @logger = logger
28
+ def self.configure(&block)
29
+ @configuration = SettingsReader::VaultResolver::Configuration.new
30
+ block&.call(@configuration)
31
+ @refresher_timer_task = @configuration.setup_lease_refresher(cache, refresher_timer_task)
31
32
  end
32
33
 
33
- def self.setup_cache
34
- logger.debug { '[VaultResolver] Setting up secrets cache' }
35
- self.cache ||= SettingsReader::VaultResolver::Cache.new
36
- end
37
-
38
- def self.setup_lease_refresher
39
- logger.debug { '[VaultResolver] Setting up lease resolver task' }
40
- self.refresher_timer_task ||= SettingsReader::VaultResolver::Refresher.refresh_task(self.cache)
41
- self.refresher_timer_task.execute
34
+ def self.cache
35
+ @cache ||= SettingsReader::VaultResolver::Cache.new
42
36
  end
43
37
 
44
38
  def self.resolver
45
- SettingsReader::VaultResolver::Instance.new
46
- end
39
+ raise Error, 'Gem not configured. Call configure before getting resolver' unless configuration
47
40
 
48
- setup_cache
49
- setup_lease_refresher
41
+ SettingsReader::VaultResolver::Instance.new(configuration)
42
+ end
50
43
  end
51
44
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: settings_reader-vault_resolver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Volodymyr Mykhailyk
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-28 00:00:00.000000000 Z
11
+ date: 2022-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -77,16 +77,23 @@ files:
77
77
  - Rakefile
78
78
  - bin/console
79
79
  - bin/setup
80
+ - codecov.yml
80
81
  - docker-compose.yml
81
82
  - lib/settings_reader/vault_resolver.rb
82
83
  - lib/settings_reader/vault_resolver/address.rb
83
84
  - lib/settings_reader/vault_resolver/cache.rb
85
+ - lib/settings_reader/vault_resolver/configuration.rb
86
+ - lib/settings_reader/vault_resolver/engines/abstract.rb
87
+ - lib/settings_reader/vault_resolver/engines/auth.rb
88
+ - lib/settings_reader/vault_resolver/engines/database.rb
89
+ - lib/settings_reader/vault_resolver/engines/kv2.rb
84
90
  - lib/settings_reader/vault_resolver/entry.rb
85
- - lib/settings_reader/vault_resolver/helpers/k8s_auth.rb
91
+ - lib/settings_reader/vault_resolver/helpers/vault_authentication.rb
86
92
  - lib/settings_reader/vault_resolver/instance.rb
87
93
  - lib/settings_reader/vault_resolver/logging.rb
88
94
  - lib/settings_reader/vault_resolver/patches/authenticate.rb
89
95
  - lib/settings_reader/vault_resolver/refresher.rb
96
+ - lib/settings_reader/vault_resolver/refresher_observer.rb
90
97
  - lib/settings_reader/vault_resolver/version.rb
91
98
  - settings_reader-vault_resolver.gemspec
92
99
  homepage: https://github.com/matic-insurance/settings_reader-vault_resolver
@@ -1,43 +0,0 @@
1
- require_relative '../patches/authenticate'
2
-
3
- module SettingsReader
4
- module VaultResolver
5
- module Helpers
6
- # Helps with Vault authentication using kubernetes login
7
- class K8sAuth
8
- def call(role)
9
- secret = Vault.auth.kubernetes(role)
10
-
11
- cache_token_for_renewal(secret)
12
- secret
13
- end
14
-
15
- private
16
-
17
- def cache_token_for_renewal(secret)
18
- address = SettingsReader::VaultResolver::Address.new('vault://v1/auth/token/lookup-self')
19
- entry = SettingsReader::VaultResolver::AuthEntry.new(address, secret)
20
- SettingsReader::VaultResolver.cache.save(entry)
21
- entry
22
- end
23
- end
24
- end
25
-
26
- # Helps with auth token lease renewal
27
- class AuthEntry < SettingsReader::VaultResolver::Entry
28
- def leased?
29
- true
30
- end
31
-
32
- def lease_duration
33
- @secret.auth.lease_duration
34
- end
35
-
36
- def renew
37
- Vault.client.auth_token.renew_self
38
- @lease_started = Time.now
39
- true
40
- end
41
- end
42
- end
43
- end