legion-crypt 1.5.8 → 1.5.9
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 +4 -4
- data/CHANGELOG.md +13 -0
- data/lib/legion/crypt/lease_manager.rb +26 -6
- data/lib/legion/crypt/token_renewer.rb +24 -5
- data/lib/legion/crypt/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 42200f56d577b407725621c56af4f7d191c1ad0219c33c99f5e4adc02568aac6
|
|
4
|
+
data.tar.gz: c231674d541726ab2fa3cf381e655a67be065e2481ce4f50c39d42b52875f6fa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2ee34bea6a9a73af47707259d8b857dfc1c1eb8f9e3519ccbefd811bb43e182c734795d15732de82058acb1101f3ba14bc16c39feeae87873c290e2aad58c049
|
|
7
|
+
data.tar.gz: b4d4c72a242b0cfb229dcb27f654f41e6dfd6c3035c73901345588639ea102969e83edb31e5b9572705f674eeba8bd3a6fe89915b9db4ca2eedd33749c12fcf3
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.5.9] - 2026-04-10
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- Vault lease cascade revocation: all three service credentials (RabbitMQ, PostgreSQL, Redis) died at exactly 2 hours when the Vault Kerberos auth token expired — Vault cascade-revokes all child leases when the parent token dies, regardless of individual lease TTLs (closes #29)
|
|
9
|
+
- `TokenRenewer` now detects non-renewable tokens (`renewable=false`) and skips `renew_self` (which always fails for non-renewable tokens), going straight to `reauth_kerberos` before the token expires
|
|
10
|
+
- `TokenRenewer#reauth_kerberos` now triggers `LeaseManager.reissue_all` after obtaining a new token, re-issuing all active leases under the new token so they are not orphaned when the old token expires
|
|
11
|
+
- `LeaseManager#push_to_settings` symbol/string key mismatch: `resolve_secrets!` registers refs with string keys (`"rabbitmq"`) via `lease://` URI parsing, but `cache_lease` stores leases with symbol keys (`:rabbitmq` from `Legion::JSON.load`) — now tries both key types
|
|
12
|
+
- `LeaseManager#trigger_reconnect` for `:postgresql` — uses surgical Sequel pool `disconnect` + `test_connection` instead of `Data.shutdown + Data.setup` which tore down unrelated connections (Apollo SQLite, Local cache)
|
|
13
|
+
- `LeaseManager#trigger_reconnect` for `:redis` — uses `Cache.restart` (the actual method) instead of `Cache.reconnect` (which does not exist)
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- `LeaseManager#reissue_all` — re-issues all active leases under the current vault client token; called by `TokenRenewer` after successful Kerberos re-authentication to prevent cascade revocation of orphaned leases
|
|
17
|
+
|
|
5
18
|
## [1.5.8] - 2026-04-09
|
|
6
19
|
|
|
7
20
|
### Added
|
|
@@ -86,7 +86,9 @@ module Legion
|
|
|
86
86
|
|
|
87
87
|
def push_to_settings(name)
|
|
88
88
|
refs, data = @state_mutex.synchronize do
|
|
89
|
-
[@refs[name]
|
|
89
|
+
r = @refs[name] || @refs[name.to_s] || @refs[name.to_sym]
|
|
90
|
+
d = @lease_cache[name] || @lease_cache[name.to_s] || @lease_cache[name.to_sym]
|
|
91
|
+
[r&.dup, d&.dup]
|
|
90
92
|
end
|
|
91
93
|
return if refs.nil? || refs.empty?
|
|
92
94
|
return unless data
|
|
@@ -109,6 +111,19 @@ module Legion
|
|
|
109
111
|
sys
|
|
110
112
|
end
|
|
111
113
|
|
|
114
|
+
def reissue_all
|
|
115
|
+
log.info('LeaseManager: reissue_all — re-issuing all active leases under new token')
|
|
116
|
+
lease_names = @state_mutex.synchronize { @active_leases.keys.dup }
|
|
117
|
+
|
|
118
|
+
lease_names.each do |name|
|
|
119
|
+
lease = @state_mutex.synchronize { @active_leases[name]&.dup }
|
|
120
|
+
next unless lease && lease[:path]
|
|
121
|
+
|
|
122
|
+
reissue_lease(name)
|
|
123
|
+
end
|
|
124
|
+
log.info('LeaseManager: reissue_all complete')
|
|
125
|
+
end
|
|
126
|
+
|
|
112
127
|
def register_dynamic_lease(name:, path:, response:, settings_refs:)
|
|
113
128
|
register_at_exit_hook
|
|
114
129
|
|
|
@@ -451,14 +466,19 @@ module Legion
|
|
|
451
466
|
Legion::Transport::Connection.force_reconnect
|
|
452
467
|
log.info("LeaseManager: triggered transport reconnect after '#{name}' reissue")
|
|
453
468
|
when :postgresql
|
|
454
|
-
return unless defined?(Legion::Data) && Legion::Data.
|
|
469
|
+
return unless defined?(Legion::Data::Connection) && Legion::Data::Connection.sequel
|
|
455
470
|
|
|
456
|
-
Legion::Data.
|
|
457
|
-
|
|
471
|
+
Legion::Data::Connection.sequel.disconnect
|
|
472
|
+
Legion::Data::Connection.sequel.test_connection
|
|
473
|
+
log.info("LeaseManager: triggered data pool reconnect after '#{name}' reissue")
|
|
458
474
|
when :redis
|
|
459
|
-
return unless defined?(Legion::Cache)
|
|
475
|
+
return unless defined?(Legion::Cache)
|
|
460
476
|
|
|
461
|
-
Legion::Cache.
|
|
477
|
+
if Legion::Cache.respond_to?(:restart)
|
|
478
|
+
Legion::Cache.restart
|
|
479
|
+
elsif Legion::Cache.respond_to?(:reconnect)
|
|
480
|
+
Legion::Cache.reconnect
|
|
481
|
+
end
|
|
462
482
|
log.info("LeaseManager: triggered cache reconnect after '#{name}' reissue")
|
|
463
483
|
end
|
|
464
484
|
rescue StandardError => e
|
|
@@ -72,7 +72,9 @@ module Legion
|
|
|
72
72
|
@config[:renewable] = result[:renewable]
|
|
73
73
|
@config[:connected] = true
|
|
74
74
|
@vault_client.token = result[:token]
|
|
75
|
-
log.info("TokenRenewer[#{@cluster_name}]: re-authenticated via Kerberos")
|
|
75
|
+
log.info("TokenRenewer[#{@cluster_name}]: re-authenticated via Kerberos, ttl=#{result[:lease_duration]}s")
|
|
76
|
+
|
|
77
|
+
reissue_all_leases
|
|
76
78
|
true
|
|
77
79
|
rescue StandardError => e
|
|
78
80
|
handle_exception(e, level: :warn, operation: 'crypt.token_renewer.reauth_kerberos', cluster_name: @cluster_name)
|
|
@@ -104,10 +106,18 @@ module Legion
|
|
|
104
106
|
interruptible_sleep(sleep_duration)
|
|
105
107
|
|
|
106
108
|
until @stop
|
|
107
|
-
if
|
|
108
|
-
|
|
109
|
+
if @config[:renewable]
|
|
110
|
+
if renew_token || reauth_kerberos
|
|
111
|
+
on_renewal_success
|
|
112
|
+
else
|
|
113
|
+
on_renewal_failure
|
|
114
|
+
end
|
|
109
115
|
else
|
|
110
|
-
|
|
116
|
+
if reauth_kerberos # rubocop:disable Style/IfInsideElse
|
|
117
|
+
on_renewal_success
|
|
118
|
+
else
|
|
119
|
+
on_renewal_failure
|
|
120
|
+
end
|
|
111
121
|
end
|
|
112
122
|
end
|
|
113
123
|
rescue StandardError => e
|
|
@@ -128,6 +138,15 @@ module Legion
|
|
|
128
138
|
interruptible_sleep(delay)
|
|
129
139
|
end
|
|
130
140
|
|
|
141
|
+
def reissue_all_leases
|
|
142
|
+
return unless defined?(Legion::Crypt::LeaseManager)
|
|
143
|
+
|
|
144
|
+
Legion::Crypt::LeaseManager.instance.reissue_all
|
|
145
|
+
rescue StandardError => e
|
|
146
|
+
handle_exception(e, level: :warn, operation: 'crypt.token_renewer.reissue_all_leases', cluster_name: @cluster_name)
|
|
147
|
+
log.warn("TokenRenewer[#{@cluster_name}]: failed to reissue leases after reauth: #{e.message}")
|
|
148
|
+
end
|
|
149
|
+
|
|
131
150
|
def interruptible_sleep(seconds)
|
|
132
151
|
deadline = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) + seconds
|
|
133
152
|
loop do
|
|
@@ -150,7 +169,7 @@ module Legion
|
|
|
150
169
|
else
|
|
151
170
|
@thread = nil
|
|
152
171
|
revoke_token
|
|
153
|
-
log.
|
|
172
|
+
log.info("TokenRenewer[#{@cluster_name}]: token renewal thread stopped")
|
|
154
173
|
end
|
|
155
174
|
end
|
|
156
175
|
|
data/lib/legion/crypt/version.rb
CHANGED