legion-crypt 1.5.12 → 1.5.37
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/.rubocop.yml +3 -0
- data/CHANGELOG.md +146 -1
- data/README.md +68 -14
- data/legion-crypt.gemspec +2 -1
- data/lib/legion/crypt/cert_rotation.rb +83 -65
- data/lib/legion/crypt/cipher.rb +5 -15
- data/lib/legion/crypt/cluster_secret.rb +71 -19
- data/lib/legion/crypt/erasure.rb +3 -10
- data/lib/legion/crypt/jwks_client.rb +43 -31
- data/lib/legion/crypt/jwt.rb +8 -7
- data/lib/legion/crypt/kerberos_auth.rb +18 -8
- data/lib/legion/crypt/ldap_auth.rb +14 -13
- data/lib/legion/crypt/lease_manager.rb +485 -335
- data/lib/legion/crypt/mtls.rb +3 -6
- data/lib/legion/crypt/partition_keys.rb +2 -0
- data/lib/legion/crypt/settings.rb +2 -1
- data/lib/legion/crypt/spiffe/workload_api_client.rb +83 -71
- data/lib/legion/crypt/token_renewer.rb +212 -82
- data/lib/legion/crypt/vault.rb +113 -83
- data/lib/legion/crypt/vault_client.rb +355 -0
- data/lib/legion/crypt/vault_cluster.rb +161 -39
- data/lib/legion/crypt/vault_entity.rb +21 -34
- data/lib/legion/crypt/vault_jwt_auth.rb +9 -20
- data/lib/legion/crypt/vault_kerberos_auth.rb +11 -14
- data/lib/legion/crypt/vault_operation.rb +27 -0
- data/lib/legion/crypt/version.rb +1 -1
- data/lib/legion/crypt.rb +116 -63
- metadata +23 -9
- data/lib/legion/logging/helper.rb +0 -101
- data/lib/legion/logging.rb +0 -58
data/lib/legion/crypt.rb
CHANGED
|
@@ -9,7 +9,9 @@ require 'legion/crypt/cipher'
|
|
|
9
9
|
require 'legion/crypt/jwt'
|
|
10
10
|
require 'legion/crypt/vault_jwt_auth'
|
|
11
11
|
require 'legion/crypt/lease_manager'
|
|
12
|
+
require 'legion/crypt/vault_operation'
|
|
12
13
|
require 'legion/crypt/vault_cluster'
|
|
14
|
+
require 'legion/crypt/vault'
|
|
13
15
|
require 'legion/crypt/ldap_auth'
|
|
14
16
|
require 'legion/crypt/token_renewer'
|
|
15
17
|
require 'legion/crypt/helper'
|
|
@@ -32,15 +34,12 @@ module Legion
|
|
|
32
34
|
}.freeze
|
|
33
35
|
|
|
34
36
|
class << self
|
|
35
|
-
attr_reader :sessions
|
|
37
|
+
attr_reader :sessions, :stopping
|
|
36
38
|
|
|
37
39
|
include Legion::Logging::Helper
|
|
38
40
|
include Legion::Crypt::Cipher
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
require 'legion/crypt/vault'
|
|
42
|
-
include Legion::Crypt::Vault
|
|
43
|
-
end
|
|
42
|
+
include Legion::Crypt::Vault
|
|
44
43
|
|
|
45
44
|
def vault_settings
|
|
46
45
|
Legion::Settings[:crypt][:vault]
|
|
@@ -66,24 +65,32 @@ module Legion
|
|
|
66
65
|
|
|
67
66
|
def start
|
|
68
67
|
lifecycle_mutex.synchronize do
|
|
69
|
-
if @started
|
|
70
|
-
log.info 'Legion::Crypt start ignored because the lifecycle is
|
|
68
|
+
if @started || @stopping
|
|
69
|
+
log.info 'Legion::Crypt start ignored because the lifecycle is running or stopping'
|
|
71
70
|
return
|
|
72
71
|
end
|
|
73
72
|
|
|
74
73
|
log.info 'Legion::Crypt startup initiated'
|
|
75
74
|
log.debug 'Legion::Crypt start requested'
|
|
76
|
-
|
|
75
|
+
if settings[:save_private_key]
|
|
76
|
+
key = private_key
|
|
77
|
+
::File.open('./legionio.key', ::File::WRONLY | ::File::CREAT, 0o600) do |file|
|
|
78
|
+
file.chmod(0o600)
|
|
79
|
+
file.truncate(0)
|
|
80
|
+
file.write(key.to_pem)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
77
83
|
@token_renewers ||= []
|
|
84
|
+
start_session_tracking
|
|
78
85
|
|
|
79
86
|
if vault_settings[:clusters]&.any?
|
|
80
87
|
log.info "Legion::Crypt connecting #{vault_settings[:clusters].size} Vault cluster(s)"
|
|
81
88
|
connect_all_clusters
|
|
82
|
-
start_token_renewers
|
|
83
89
|
else
|
|
84
90
|
log.info 'Legion::Crypt connecting primary Vault client' unless settings[:vault][:token].nil?
|
|
85
91
|
connect_vault unless settings[:vault][:token].nil?
|
|
86
92
|
end
|
|
93
|
+
start_token_renewers
|
|
87
94
|
start_lease_manager
|
|
88
95
|
start_svid_rotation
|
|
89
96
|
@started = true
|
|
@@ -91,6 +98,29 @@ module Legion
|
|
|
91
98
|
end
|
|
92
99
|
end
|
|
93
100
|
|
|
101
|
+
def vault_auth_generation
|
|
102
|
+
lifecycle_mutex.synchronize do
|
|
103
|
+
raise 'Crypt is shutting down; login must be retried' if @stopping
|
|
104
|
+
|
|
105
|
+
@token_generation || 0
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def install_vault_grant(client:, config:, grant:, auth_method:, generation:, **)
|
|
110
|
+
issued_at = Time.now
|
|
111
|
+
lifecycle_mutex.synchronize do
|
|
112
|
+
raise 'Crypt stopped during login; login must be retried' if @stopping || generation != (@token_generation || 0)
|
|
113
|
+
|
|
114
|
+
cluster_name = clusters.find { |_name, candidate| candidate.equal?(config) }&.first
|
|
115
|
+
previous = (@token_renewers || []).find { |worker| worker.cluster_name == cluster_name }
|
|
116
|
+
previous&.stop
|
|
117
|
+
raise 'Previous token worker has not stopped; login must be retried' if previous&.running?
|
|
118
|
+
|
|
119
|
+
publish_vault_grant(client: client, config: config, grant: grant, auth_method: auth_method, issued_at: issued_at)
|
|
120
|
+
start_token_renewer(cluster_name: cluster_name, config: config, vault_client: client)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
94
124
|
def settings
|
|
95
125
|
if Legion.const_defined?('Settings')
|
|
96
126
|
Legion::Settings[:crypt]
|
|
@@ -112,7 +142,7 @@ module Legion
|
|
|
112
142
|
|
|
113
143
|
Legion::Settings.merge_settings('transport', Legion::Transport::Settings.default) if defined?(Legion::Transport::Settings)
|
|
114
144
|
|
|
115
|
-
response = LeaseManager.instance.vault_logical.read('rabbitmq/creds/legionio-bootstrap')
|
|
145
|
+
response = LeaseManager.instance.vault_logical.read(path: 'rabbitmq/creds/legionio-bootstrap')
|
|
116
146
|
return unless response&.data
|
|
117
147
|
|
|
118
148
|
bootstrap_lease_ttl = Legion::Settings.dig(:crypt, :vault, :bootstrap_lease_ttl).to_i
|
|
@@ -147,10 +177,18 @@ module Legion
|
|
|
147
177
|
return if mode == :lite
|
|
148
178
|
|
|
149
179
|
role = RMQ_ROLE_MAP.fetch(mode, "legionio-#{mode}")
|
|
150
|
-
|
|
151
|
-
|
|
180
|
+
manager = LeaseManager.instance
|
|
181
|
+
response = Legion::Crypt::VaultOperation.with_timeout { manager.vault_logical.read(path: "rabbitmq/creds/#{role}") }
|
|
182
|
+
raise "Failed to fetch identity-scoped RMQ creds for role #{role}" unless response
|
|
152
183
|
|
|
153
|
-
|
|
184
|
+
settings = Legion::Settings.loader.settings
|
|
185
|
+
settings[:transport] ||= {}
|
|
186
|
+
settings[:transport][:connection] ||= {}
|
|
187
|
+
conn = settings[:transport][:connection]
|
|
188
|
+
conn[:user] = nil unless conn.key?(:user)
|
|
189
|
+
conn[:password] = nil unless conn.key?(:password)
|
|
190
|
+
|
|
191
|
+
installed = manager.register_dynamic_lease(
|
|
154
192
|
name: :rabbitmq,
|
|
155
193
|
path: "rabbitmq/creds/#{role}",
|
|
156
194
|
response: response,
|
|
@@ -159,32 +197,15 @@ module Legion
|
|
|
159
197
|
{ path: %i[transport connection password], key: :password }
|
|
160
198
|
]
|
|
161
199
|
)
|
|
200
|
+
raise 'Identity credential handoff failed — bootstrap lease NOT revoked' unless installed
|
|
162
201
|
|
|
163
|
-
|
|
164
|
-
settings[:transport] ||= {}
|
|
165
|
-
settings[:transport][:connection] ||= {}
|
|
166
|
-
conn = settings[:transport][:connection]
|
|
167
|
-
username = response.data[:username] || response.data['username']
|
|
168
|
-
password = response.data[:password] || response.data['password']
|
|
169
|
-
raise "Identity-scoped RMQ creds for role #{role} missing username or password" unless username && password
|
|
170
|
-
|
|
171
|
-
conn[:user] = username
|
|
172
|
-
conn[:password] = password
|
|
173
|
-
|
|
174
|
-
if defined?(Legion::Transport::Connection)
|
|
175
|
-
Legion::Transport::Connection.force_reconnect
|
|
176
|
-
raise 'Transport reconnect failed after credential swap — bootstrap lease NOT revoked' unless Legion::Transport::Connection.session_open?
|
|
177
|
-
|
|
178
|
-
log.info "Transport reconnected with identity-scoped creds (role: #{role})"
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
revoke_bootstrap_lease
|
|
202
|
+
Legion::Crypt::VaultOperation.with_timeout { revoke_bootstrap_lease }
|
|
182
203
|
end
|
|
183
204
|
|
|
184
205
|
def revoke_bootstrap_lease
|
|
185
206
|
return unless @bootstrap_lease_id
|
|
186
207
|
|
|
187
|
-
LeaseManager.instance.vault_sys.revoke(@bootstrap_lease_id)
|
|
208
|
+
LeaseManager.instance.vault_sys.revoke(lease_id: @bootstrap_lease_id)
|
|
188
209
|
log.info "Bootstrap RMQ lease revoked (#{@bootstrap_lease_id[0..7]}...)"
|
|
189
210
|
@bootstrap_lease_id = nil
|
|
190
211
|
@bootstrap_lease_expires = nil
|
|
@@ -196,6 +217,8 @@ module Legion
|
|
|
196
217
|
end
|
|
197
218
|
|
|
198
219
|
def vault_connected?
|
|
220
|
+
return connected_clusters.any? if settings.dig(:vault, :clusters)&.any?
|
|
221
|
+
|
|
199
222
|
return true if settings.dig(:vault, :connected) == true
|
|
200
223
|
return true if respond_to?(:connected_clusters) && connected_clusters.any?
|
|
201
224
|
|
|
@@ -233,20 +256,43 @@ module Legion
|
|
|
233
256
|
end
|
|
234
257
|
|
|
235
258
|
def shutdown
|
|
236
|
-
lifecycle_mutex.synchronize do
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
return
|
|
240
|
-
end
|
|
259
|
+
shutdown_started = lifecycle_mutex.synchronize do
|
|
260
|
+
return if @stopping
|
|
261
|
+
return unless @started || @vault_clients || @retired_vault_clients&.size&.positive?
|
|
241
262
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
stop_token_renewers
|
|
245
|
-
shutdown_renewer
|
|
246
|
-
close_sessions
|
|
247
|
-
stop_svid_rotation
|
|
263
|
+
@stopping = true
|
|
264
|
+
@token_generation = (@token_generation || 0) + 1
|
|
248
265
|
@started = false
|
|
249
|
-
|
|
266
|
+
true
|
|
267
|
+
end
|
|
268
|
+
deadline = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) + Legion::Crypt::VaultOperation::SHUTDOWN_TIMEOUT
|
|
269
|
+
manager = Legion::Crypt::LeaseManager.instance
|
|
270
|
+
[manager, *(@token_renewers || [])].each do |worker|
|
|
271
|
+
worker.request_stop
|
|
272
|
+
rescue StandardError => e
|
|
273
|
+
handle_exception(e, level: :warn, operation: 'crypt.shutdown.request_stop')
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
components = [
|
|
277
|
+
[self, :stop_svid_rotation, { deadline: deadline }],
|
|
278
|
+
[self, :shutdown_renewer, {}],
|
|
279
|
+
[manager, :shutdown, { deadline: deadline }],
|
|
280
|
+
[self, :stop_token_renewers, { deadline: deadline }],
|
|
281
|
+
[self, :close_sessions, { deadline: deadline }],
|
|
282
|
+
[self, :clear_vault_clients, { deadline: deadline }]
|
|
283
|
+
]
|
|
284
|
+
components.each do |owner, operation, options|
|
|
285
|
+
owner.send(operation, **options)
|
|
286
|
+
rescue StandardError => e
|
|
287
|
+
handle_exception(e, level: :warn, operation: "crypt.shutdown.#{operation}")
|
|
288
|
+
end
|
|
289
|
+
log.info 'Legion::Crypt shutdown completed'
|
|
290
|
+
ensure
|
|
291
|
+
if shutdown_started
|
|
292
|
+
lifecycle_mutex.synchronize do
|
|
293
|
+
@started = false
|
|
294
|
+
@stopping = false
|
|
295
|
+
end
|
|
250
296
|
end
|
|
251
297
|
end
|
|
252
298
|
|
|
@@ -287,27 +333,34 @@ module Legion
|
|
|
287
333
|
|
|
288
334
|
def start_token_renewers
|
|
289
335
|
started = 0
|
|
290
|
-
clusters.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
config: config,
|
|
296
|
-
vault_client: vault_client(name)
|
|
297
|
-
)
|
|
298
|
-
renewer.start
|
|
299
|
-
@token_renewers << renewer
|
|
336
|
+
configurations = clusters.empty? ? { nil => vault_settings } : clusters
|
|
337
|
+
configurations.each do |name, config|
|
|
338
|
+
next unless %w[kerberos ldap jwt].include?(config[:auth_method].to_s) && config[:connected]
|
|
339
|
+
|
|
340
|
+
start_token_renewer(cluster_name: name, config: config, vault_client: vault_client(name))
|
|
300
341
|
started += 1
|
|
301
342
|
end
|
|
302
343
|
log.info "Legion::Crypt started #{started} token renewer(s)" if started.positive?
|
|
303
344
|
end
|
|
304
345
|
|
|
305
|
-
def
|
|
306
|
-
|
|
346
|
+
def start_token_renewer(cluster_name:, config:, vault_client:, **)
|
|
347
|
+
@token_renewers ||= []
|
|
348
|
+
return if @token_renewers.any? { |worker| worker.cluster_name == cluster_name && worker.running? }
|
|
307
349
|
|
|
308
|
-
@token_renewers.
|
|
309
|
-
|
|
310
|
-
@token_renewers
|
|
350
|
+
@token_renewers.reject! { |worker| worker.cluster_name == cluster_name }
|
|
351
|
+
renewer = Legion::Crypt::TokenRenewer.new(cluster_name: cluster_name, config: config, vault_client: vault_client)
|
|
352
|
+
@token_renewers << renewer
|
|
353
|
+
renewer.start
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
def stop_token_renewers(deadline: nil)
|
|
357
|
+
renewers = @token_renewers || []
|
|
358
|
+
@token_renewers = []
|
|
359
|
+
renewers.each do |renewer|
|
|
360
|
+
renewer.stop(deadline: deadline)
|
|
361
|
+
rescue StandardError => e
|
|
362
|
+
handle_exception(e, level: :warn, operation: 'crypt.stop_token_renewers')
|
|
363
|
+
end
|
|
311
364
|
end
|
|
312
365
|
|
|
313
366
|
def start_svid_rotation
|
|
@@ -320,11 +373,11 @@ module Legion
|
|
|
320
373
|
handle_exception(e, level: :warn, operation: 'crypt.start_svid_rotation')
|
|
321
374
|
end
|
|
322
375
|
|
|
323
|
-
def stop_svid_rotation
|
|
376
|
+
def stop_svid_rotation(deadline: nil)
|
|
324
377
|
return unless @svid_rotation
|
|
325
378
|
|
|
326
|
-
|
|
327
|
-
|
|
379
|
+
Legion::Crypt::VaultOperation.with_timeout(deadline: deadline) { @svid_rotation.stop }
|
|
380
|
+
ensure
|
|
328
381
|
@svid_rotation = nil
|
|
329
382
|
end
|
|
330
383
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: legion-crypt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.5.
|
|
4
|
+
version: 1.5.37
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -37,6 +37,20 @@ dependencies:
|
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '1.3'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: faraday
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '2.0'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '2.0'
|
|
40
54
|
- !ruby/object:Gem::Dependency
|
|
41
55
|
name: jwt
|
|
42
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -52,33 +66,33 @@ dependencies:
|
|
|
52
66
|
- !ruby/object:Gem::Version
|
|
53
67
|
version: '2.7'
|
|
54
68
|
- !ruby/object:Gem::Dependency
|
|
55
|
-
name: legion-
|
|
69
|
+
name: legion-json
|
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|
|
57
71
|
requirements:
|
|
58
72
|
- - ">="
|
|
59
73
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: 1.
|
|
74
|
+
version: 1.2.0
|
|
61
75
|
type: :runtime
|
|
62
76
|
prerelease: false
|
|
63
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
78
|
requirements:
|
|
65
79
|
- - ">="
|
|
66
80
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: 1.
|
|
81
|
+
version: 1.2.0
|
|
68
82
|
- !ruby/object:Gem::Dependency
|
|
69
|
-
name:
|
|
83
|
+
name: legion-logging
|
|
70
84
|
requirement: !ruby/object:Gem::Requirement
|
|
71
85
|
requirements:
|
|
72
86
|
- - ">="
|
|
73
87
|
- !ruby/object:Gem::Version
|
|
74
|
-
version:
|
|
88
|
+
version: 1.5.0
|
|
75
89
|
type: :runtime
|
|
76
90
|
prerelease: false
|
|
77
91
|
version_requirements: !ruby/object:Gem::Requirement
|
|
78
92
|
requirements:
|
|
79
93
|
- - ">="
|
|
80
94
|
- !ruby/object:Gem::Version
|
|
81
|
-
version:
|
|
95
|
+
version: 1.5.0
|
|
82
96
|
description: A gem used by the LegionIO framework for encryption
|
|
83
97
|
email:
|
|
84
98
|
- matthewdiverson@gmail.com
|
|
@@ -127,14 +141,14 @@ files:
|
|
|
127
141
|
- lib/legion/crypt/tls.rb
|
|
128
142
|
- lib/legion/crypt/token_renewer.rb
|
|
129
143
|
- lib/legion/crypt/vault.rb
|
|
144
|
+
- lib/legion/crypt/vault_client.rb
|
|
130
145
|
- lib/legion/crypt/vault_cluster.rb
|
|
131
146
|
- lib/legion/crypt/vault_entity.rb
|
|
132
147
|
- lib/legion/crypt/vault_jwt_auth.rb
|
|
133
148
|
- lib/legion/crypt/vault_kerberos_auth.rb
|
|
149
|
+
- lib/legion/crypt/vault_operation.rb
|
|
134
150
|
- lib/legion/crypt/vault_renewer.rb
|
|
135
151
|
- lib/legion/crypt/version.rb
|
|
136
|
-
- lib/legion/logging.rb
|
|
137
|
-
- lib/legion/logging/helper.rb
|
|
138
152
|
- scripts/pre-commit-rubocop.sh
|
|
139
153
|
- sonar-project.properties
|
|
140
154
|
homepage: https://github.com/LegionIO/legion-crypt
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
begin
|
|
4
|
-
helper_path = File.join(
|
|
5
|
-
Gem::Specification.find_by_name('legion-logging').full_gem_path,
|
|
6
|
-
'lib/legion/logging/helper.rb'
|
|
7
|
-
)
|
|
8
|
-
require helper_path if File.exist?(helper_path)
|
|
9
|
-
rescue Gem::LoadError => e
|
|
10
|
-
require 'legion/logging'
|
|
11
|
-
Legion::Logging.warn("legion-crypt logging helper fallback active: #{e.message}")
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
require 'legion/logging'
|
|
15
|
-
|
|
16
|
-
module Legion
|
|
17
|
-
module Logging
|
|
18
|
-
module Helper
|
|
19
|
-
unless const_defined?(:CompatLogger, false)
|
|
20
|
-
CompatLogger = Class.new do
|
|
21
|
-
%i[debug info warn error fatal unknown].each do |level|
|
|
22
|
-
define_method(level) do |message = nil, &block|
|
|
23
|
-
payload = block ? block.call : message
|
|
24
|
-
return if payload.nil?
|
|
25
|
-
|
|
26
|
-
if logging_supports?(level)
|
|
27
|
-
Legion::Logging.public_send(level, payload)
|
|
28
|
-
elsif %i[error fatal warn].include?(level)
|
|
29
|
-
::Kernel.warn(payload)
|
|
30
|
-
else
|
|
31
|
-
$stdout.puts(payload)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
def logging_supports?(level)
|
|
39
|
-
return false unless Legion.const_defined?('Logging')
|
|
40
|
-
|
|
41
|
-
Legion::Logging.respond_to?(level)
|
|
42
|
-
rescue StandardError => e
|
|
43
|
-
Legion::Logging.warn("legion-crypt logging support check failed: #{e.message}")
|
|
44
|
-
false
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def log
|
|
50
|
-
@log ||= CompatLogger.new
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def handle_exception(exception, task_id: nil, level: :error, handled: true, **opts) # rubocop:disable Lint/UnusedMethodArgument,Style/ArgumentsForwarding
|
|
54
|
-
message = exception_log_message(exception, level: level, **opts) # rubocop:disable Style/ArgumentsForwarding
|
|
55
|
-
|
|
56
|
-
if logging_supports?(:log_exception)
|
|
57
|
-
Legion::Logging.log_exception(exception, level: level, lex: 'crypt', component_type: :helper)
|
|
58
|
-
return
|
|
59
|
-
end
|
|
60
|
-
if logging_supports?(level)
|
|
61
|
-
Legion::Logging.public_send(level, message)
|
|
62
|
-
return
|
|
63
|
-
end
|
|
64
|
-
if logging_supports?(:error)
|
|
65
|
-
Legion::Logging.error(message)
|
|
66
|
-
return
|
|
67
|
-
end
|
|
68
|
-
if logging_supports?(:warn)
|
|
69
|
-
Legion::Logging.warn(message)
|
|
70
|
-
return
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
::Kernel.warn(message)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
private
|
|
77
|
-
|
|
78
|
-
def logging_supports?(level)
|
|
79
|
-
return false unless Legion.const_defined?('Logging')
|
|
80
|
-
|
|
81
|
-
Legion::Logging.respond_to?(level)
|
|
82
|
-
rescue StandardError => e
|
|
83
|
-
Legion::Logging.warn("legion-crypt logging support check failed: #{e.message}")
|
|
84
|
-
false
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def exception_log_message(exception, level:, **opts)
|
|
88
|
-
operation = opts[:operation] || opts['operation']
|
|
89
|
-
prefix = operation ? "#{operation} failed: " : ''
|
|
90
|
-
details = opts.reject { |key, _value| key.to_s == 'operation' }.map { |key, value| "#{key}=#{value}" }
|
|
91
|
-
detail_suffix = details.empty? ? '' : " (#{details.join(' ')})"
|
|
92
|
-
backtrace = Array(exception.backtrace).join("\n")
|
|
93
|
-
base = "#{prefix}#{exception.class}: #{exception.message}#{detail_suffix}"
|
|
94
|
-
return base if backtrace.empty? || level == :debug
|
|
95
|
-
return base if backtrace.empty?
|
|
96
|
-
|
|
97
|
-
"#{base}\n#{backtrace}"
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
end
|
data/lib/legion/logging.rb
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'logger'
|
|
4
|
-
|
|
5
|
-
begin
|
|
6
|
-
gem_root = Gem::Specification.find_by_name('legion-logging').full_gem_path
|
|
7
|
-
upstream_logging = File.join(gem_root, 'lib/legion/logging.rb')
|
|
8
|
-
require upstream_logging if File.exist?(upstream_logging)
|
|
9
|
-
rescue Gem::LoadError
|
|
10
|
-
nil
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
module Legion
|
|
14
|
-
module Logging
|
|
15
|
-
class << self
|
|
16
|
-
unless method_defined?(:setup)
|
|
17
|
-
def setup(level: 'info', **_opts)
|
|
18
|
-
logger.level = normalize_level(level)
|
|
19
|
-
self
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def logger
|
|
23
|
-
@logger ||= Logger.new($stdout).tap do |instance|
|
|
24
|
-
instance.progname = 'legion-crypt'
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def log_exception(exception, lex: nil, component_type: nil, **_opts)
|
|
29
|
-
prefix = [lex, component_type].compact.join('.')
|
|
30
|
-
payload = prefix.empty? ? exception.message : "#{prefix}: #{exception.message}"
|
|
31
|
-
error(payload)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
%i[debug info warn error fatal unknown].each do |level_name|
|
|
35
|
-
define_method(level_name) do |message = nil, &block|
|
|
36
|
-
payload = block ? block.call : message
|
|
37
|
-
return if payload.nil?
|
|
38
|
-
|
|
39
|
-
logger.public_send(level_name, payload)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
private
|
|
44
|
-
|
|
45
|
-
def normalize_level(level)
|
|
46
|
-
case level.to_s.downcase
|
|
47
|
-
when 'debug' then Logger::DEBUG
|
|
48
|
-
when 'info' then Logger::INFO
|
|
49
|
-
when 'warn' then Logger::WARN
|
|
50
|
-
when 'error' then Logger::ERROR
|
|
51
|
-
when 'fatal' then Logger::FATAL
|
|
52
|
-
else Logger::UNKNOWN
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|