Class: Legion::Crypt::TokenRenewer

Inherits:
Object
  • Object
show all
Includes:
Logging::Helper
Defined in:
lib/legion/crypt/token_renewer.rb

Constant Summary collapse

INITIAL_BACKOFF =
30
MAX_BACKOFF =
600
MIN_SLEEP =
30
RENEWAL_RATIO =
0.75

Constants included from Logging::Helper

Logging::Helper::CompatLogger

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging::Helper

#handle_exception, #log

Constructor Details

#initialize(cluster_name:, config:, vault_client:) ⇒ TokenRenewer

Returns a new instance of TokenRenewer.



18
19
20
21
22
23
24
25
# File 'lib/legion/crypt/token_renewer.rb', line 18

def initialize(cluster_name:, config:, vault_client:)
  @cluster_name = cluster_name
  @config       = config
  @vault_client = vault_client
  @thread       = nil
  @stop         = false
  @backoff      = INITIAL_BACKOFF
end

Instance Attribute Details

#cluster_nameObject (readonly)

Returns the value of attribute cluster_name.



16
17
18
# File 'lib/legion/crypt/token_renewer.rb', line 16

def cluster_name
  @cluster_name
end

Instance Method Details

#next_backoffObject



93
94
95
96
97
# File 'lib/legion/crypt/token_renewer.rb', line 93

def next_backoff
  current = @backoff
  @backoff = [@backoff * 2, MAX_BACKOFF].min
  current
end

#reauth_kerberosObject



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/legion/crypt/token_renewer.rb', line 62

def reauth_kerberos
  krb_config = @config[:kerberos] || {}
  result = Legion::Crypt::KerberosAuth.(
    vault_client:      @vault_client,
    service_principal: krb_config[:service_principal],
    auth_path:         krb_config[:auth_path] || KerberosAuth::DEFAULT_AUTH_PATH
  )

  @config[:token]          = result[:token]
  @config[:lease_duration] = result[:lease_duration]
  @config[:renewable]      = result[:renewable]
  @config[:connected]      = true
  @vault_client.token      = result[:token]
  log.info("TokenRenewer[#{@cluster_name}]: re-authenticated via Kerberos, ttl=#{result[:lease_duration]}s")

  reissue_all_leases
  true
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'crypt.token_renewer.reauth_kerberos', cluster_name: @cluster_name)
  log.warn("TokenRenewer[#{@cluster_name}]: Kerberos re-auth failed: #{e.message}")
  false
end

#renew_tokenObject



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/legion/crypt/token_renewer.rb', line 50

def renew_token
  result = @vault_client.auth_token.renew_self
  @config[:lease_duration] = result.auth.lease_duration
  @config[:renewable] = result.auth.renewable? if result.auth.respond_to?(:renewable?)
  log.info("TokenRenewer[#{@cluster_name}]: token renewed, ttl=#{result.auth.lease_duration}s")
  true
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'crypt.token_renewer.renew_token', cluster_name: @cluster_name)
  log.warn("TokenRenewer[#{@cluster_name}]: token renewal failed: #{e.message}")
  false
end

#reset_backoffObject



99
100
101
# File 'lib/legion/crypt/token_renewer.rb', line 99

def reset_backoff
  @backoff = INITIAL_BACKOFF
end

#running?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/legion/crypt/token_renewer.rb', line 46

def running?
  @thread&.alive? == true
end

#sleep_durationObject



85
86
87
88
89
90
91
# File 'lib/legion/crypt/token_renewer.rb', line 85

def sleep_duration
  lease_duration = @config[:lease_duration].to_i
  duration = [(lease_duration * RENEWAL_RATIO).to_i, 1].max
  return [duration, lease_duration - 1].min if lease_duration.positive? && lease_duration < MIN_SLEEP

  [duration, MIN_SLEEP].max
end

#startObject



27
28
29
30
31
32
33
34
# File 'lib/legion/crypt/token_renewer.rb', line 27

def start
  return if running?

  @stop = false
  @thread = Thread.new { renewal_loop }
  @thread.name = "vault-renewer-#{@cluster_name}"
  log.info("TokenRenewer[#{@cluster_name}]: token renewal thread started")
end

#stopObject



36
37
38
39
40
41
42
43
44
# File 'lib/legion/crypt/token_renewer.rb', line 36

def stop
  @stop = true
  @thread&.wakeup
rescue ThreadError => e
  handle_exception(e, level: :debug, operation: 'crypt.token_renewer.stop', cluster_name: @cluster_name)
  nil
ensure
  stop_thread_and_revoke
end