etna 0.1.36 → 0.1.40
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/lib/etna.rb +1 -0
- data/lib/etna/application.rb +90 -8
- data/lib/etna/clients/metis/client.rb +54 -1
- data/lib/etna/clients/metis/workflows.rb +4 -3
- data/lib/etna/clients/metis/workflows/ingest_metis_data_workflow.rb +31 -0
- data/lib/etna/clients/metis/workflows/metis_upload_workflow.rb +1 -1
- data/lib/etna/controller.rb +18 -13
- data/lib/etna/directed_graph.rb +6 -1
- data/lib/etna/filesystem.rb +63 -0
- data/lib/etna/logger.rb +4 -0
- data/lib/etna/metrics.rb +26 -0
- data/lib/etna/route.rb +64 -1
- data/lib/etna/server.rb +5 -0
- metadata +18 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e83d3c30c23693011d59b103f8b5a9372950eba1b3123376a288826204d47c62
|
|
4
|
+
data.tar.gz: c3b50952e71d91f4361a87e872ba5532849644abe42fbc9e480549726a6bbf93
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c3c561cdd7db4631c267f2edba8421b94baba5de790ca1ff9edd06cd21d039d7224d868eaa43ba7090b4114b595830ac777c1c4688ec15c9320cde90530be4e5
|
|
7
|
+
data.tar.gz: 7148582a82f7e90357ed6658c7337bce7b34dd532b4a899ac27a2d74f40f34224cb6c225b2aa4db4164c467aa8a5c189d7acf28a1c462097e619e9875fbdc4d1
|
data/lib/etna.rb
CHANGED
data/lib/etna/application.rb
CHANGED
|
@@ -8,6 +8,7 @@ require_relative './command'
|
|
|
8
8
|
require_relative './generate_autocompletion_script'
|
|
9
9
|
require 'singleton'
|
|
10
10
|
require 'rollbar'
|
|
11
|
+
require 'fileutils'
|
|
11
12
|
|
|
12
13
|
module Etna::Application
|
|
13
14
|
def self.included(other)
|
|
@@ -59,6 +60,72 @@ module Etna::Application
|
|
|
59
60
|
end
|
|
60
61
|
end
|
|
61
62
|
|
|
63
|
+
# This will cause metrics to persist to a file.
|
|
64
|
+
# NOTE -- /tmp/metrics.bin should be a persistent mount when using this.
|
|
65
|
+
# You will still need to export metrics in the text format for the node_exporter on the host machine to
|
|
66
|
+
# export them to prometheus. Ensure that the /tmp/metrics.bin is on a named volume or a bind mount, either is fine.
|
|
67
|
+
def enable_job_metrics!
|
|
68
|
+
require 'prometheus'
|
|
69
|
+
Prometheus::Client.config.data_store = Prometheus::Client::DataStores::DirectFileStore.new({
|
|
70
|
+
dir: "/tmp/metrics.bin"
|
|
71
|
+
})
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def setup_yabeda
|
|
75
|
+
application = self.id
|
|
76
|
+
Yabeda.configure do
|
|
77
|
+
default_tag :application, application
|
|
78
|
+
|
|
79
|
+
group :etna do
|
|
80
|
+
histogram :response_time do
|
|
81
|
+
comment "Time spent by a controller returning a response"
|
|
82
|
+
unit :seconds
|
|
83
|
+
tags [:controller, :action, :user_hash, :project_name]
|
|
84
|
+
buckets [0.01, 0.1, 0.3, 0.5, 1, 5]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
counter :visits do
|
|
88
|
+
comment "Counts visits to the controller"
|
|
89
|
+
tags [:controller, :action, :user_hash, :project_name]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
counter :rollbar_errors do
|
|
93
|
+
comment "Counts errors detected by and sent to rollbar"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
gauge :last_command_completion do
|
|
97
|
+
comment "Unix time of last time command was completed"
|
|
98
|
+
tags [:command, :status, :application]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
histogram :command_runtime do
|
|
102
|
+
comment "Time spent processing a given command"
|
|
103
|
+
tags [:command, :status, :application]
|
|
104
|
+
unit :seconds
|
|
105
|
+
buckets [0.1, 1, 5, 60, 300, 1500]
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
Yabeda.configure!
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Writes all metrics currently gathered to a text format prometheus file. If /tmp/metrics.prom is bind mounted
|
|
114
|
+
# to the host directed bound to the node_exporter's file exporter directory, these will be exported to
|
|
115
|
+
# prometheus. Combine this enable_job_metrics! for maximum effect.
|
|
116
|
+
def write_job_metrics(name)
|
|
117
|
+
node_metrics_dir = "/tmp/metrics.prom"
|
|
118
|
+
::FileUtils.mkdir_p(node_metrics_dir)
|
|
119
|
+
|
|
120
|
+
tmp_file = ::File.join(node_metrics_dir, "#{name}.prom.$$")
|
|
121
|
+
::File.open(tmp_file, "w") do |f|
|
|
122
|
+
f.write(Prometheus::Client::Formats::Text.marshal(Prometheus::Client.registry))
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
require 'fileutils'
|
|
126
|
+
::FileUtils.mv(tmp_file, ::File.join(node_metrics_dir, "#{name}.prom"))
|
|
127
|
+
end
|
|
128
|
+
|
|
62
129
|
def setup_logger
|
|
63
130
|
@logger = Etna::Logger.new(
|
|
64
131
|
# The name of the log_file, required.
|
|
@@ -108,17 +175,32 @@ module Etna::Application
|
|
|
108
175
|
end
|
|
109
176
|
|
|
110
177
|
def run_command(config, *args, &block)
|
|
178
|
+
application = self.id
|
|
179
|
+
status = 'success'
|
|
180
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
111
181
|
cmd, cmd_args, cmd_kwds = find_command(*args)
|
|
112
|
-
cmd.setup(config)
|
|
113
182
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
183
|
+
begin
|
|
184
|
+
cmd.setup(config)
|
|
185
|
+
if block_given?
|
|
186
|
+
return unless yield [cmd, cmd_args]
|
|
187
|
+
end
|
|
117
188
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
189
|
+
cmd.execute(*cmd.fill_in_missing_params(cmd_args), **cmd_kwds)
|
|
190
|
+
rescue => e
|
|
191
|
+
Rollbar.error(e)
|
|
192
|
+
status = 'failed'
|
|
193
|
+
raise
|
|
194
|
+
ensure
|
|
195
|
+
if defined?(Yabeda) && Yabeda.configured?
|
|
196
|
+
tags = { command: cmd.class.name, status: status, application: application }
|
|
197
|
+
dur = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
|
198
|
+
|
|
199
|
+
Yabeda.etna.last_command_completion.set(tags, Time.now.to_i)
|
|
200
|
+
Yabeda.etna.command_runtime.measure(tags, dur)
|
|
201
|
+
write_job_metrics("run_command")
|
|
202
|
+
end
|
|
203
|
+
end
|
|
122
204
|
end
|
|
123
205
|
end
|
|
124
206
|
|
|
@@ -210,6 +210,52 @@ module Etna
|
|
|
210
210
|
}
|
|
211
211
|
end
|
|
212
212
|
|
|
213
|
+
def resolve_conflicts_and_verify_rename(project_name:, source_bucket:, dest_bucket:, folder:, file:)
|
|
214
|
+
parent_folder = ::File.dirname(file.file_path)
|
|
215
|
+
|
|
216
|
+
should_rename_original = true
|
|
217
|
+
|
|
218
|
+
# If the destination folder already exists, check to see if
|
|
219
|
+
# the file also exists, otherwise we risk a
|
|
220
|
+
# rename conflict.
|
|
221
|
+
create_folder_request = CreateFolderRequest.new(
|
|
222
|
+
project_name: project_name,
|
|
223
|
+
bucket_name: dest_bucket,
|
|
224
|
+
folder_path: parent_folder
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
if folder_exists?(create_folder_request)
|
|
228
|
+
# If file exists in destination, delete the older file.
|
|
229
|
+
list_dest_folder_request = Etna::Clients::Metis::ListFolderRequest.new(
|
|
230
|
+
bucket_name: dest_bucket,
|
|
231
|
+
project_name: project_name,
|
|
232
|
+
folder_path: parent_folder
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
dest_file = list_folder(list_dest_folder_request).files.all.find { |f| f.file_name == file.file_name }
|
|
236
|
+
|
|
237
|
+
if (dest_file && file.updated_at <= dest_file.updated_at)
|
|
238
|
+
# Delete source file if it's out of date
|
|
239
|
+
delete_file(Etna::Clients::Metis::DeleteFileRequest.new(
|
|
240
|
+
bucket_name: source_bucket,
|
|
241
|
+
project_name: project_name,
|
|
242
|
+
file_path: file.file_path,
|
|
243
|
+
))
|
|
244
|
+
|
|
245
|
+
should_rename_original = false
|
|
246
|
+
elsif (dest_file && file.updated_at > dest_file.updated_at)
|
|
247
|
+
# Delete dest file if it's out of date
|
|
248
|
+
delete_file(Etna::Clients::Metis::DeleteFileRequest.new(
|
|
249
|
+
bucket_name: dest_bucket,
|
|
250
|
+
project_name: project_name,
|
|
251
|
+
file_path: dest_file.file_path,
|
|
252
|
+
))
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
should_rename_original
|
|
257
|
+
end
|
|
258
|
+
|
|
213
259
|
def recursively_rename_folder(project_name:, source_bucket:, dest_bucket:, folder:)
|
|
214
260
|
folder_contents = list_folder(
|
|
215
261
|
Etna::Clients::Metis::ListFolderRequest.new(
|
|
@@ -228,6 +274,13 @@ module Etna
|
|
|
228
274
|
end
|
|
229
275
|
|
|
230
276
|
folder_contents.files.all.each do |file|
|
|
277
|
+
should_rename = resolve_conflicts_and_verify_rename(
|
|
278
|
+
project_name: project_name,
|
|
279
|
+
source_bucket: source_bucket,
|
|
280
|
+
dest_bucket: dest_bucket,
|
|
281
|
+
folder: folder,
|
|
282
|
+
file: file)
|
|
283
|
+
|
|
231
284
|
rename_file(Etna::Clients::Metis::RenameFileRequest.new(
|
|
232
285
|
bucket_name: source_bucket,
|
|
233
286
|
project_name: project_name,
|
|
@@ -235,7 +288,7 @@ module Etna
|
|
|
235
288
|
new_bucket_name: dest_bucket,
|
|
236
289
|
new_file_path: file.file_path,
|
|
237
290
|
create_parent: true)
|
|
238
|
-
)
|
|
291
|
+
) if should_rename
|
|
239
292
|
end
|
|
240
293
|
|
|
241
294
|
# Now delete the source folder
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
require_relative
|
|
2
|
-
require_relative
|
|
3
|
-
require_relative
|
|
1
|
+
require_relative "./workflows/metis_download_workflow"
|
|
2
|
+
require_relative "./workflows/metis_upload_workflow"
|
|
3
|
+
require_relative "./workflows/sync_metis_data_workflow"
|
|
4
|
+
require_relative "./workflows/ingest_metis_data_workflow"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require "ostruct"
|
|
2
|
+
require "fileutils"
|
|
3
|
+
require "tempfile"
|
|
4
|
+
|
|
5
|
+
module Etna
|
|
6
|
+
module Clients
|
|
7
|
+
class Metis
|
|
8
|
+
class IngestMetisDataWorkflow < Struct.new(:metis_filesystem, :ingest_filesystem, :logger, keyword_init: true)
|
|
9
|
+
# Since we are doing manual triage of files,
|
|
10
|
+
# do not automatically copy directory trees.
|
|
11
|
+
# srcs must be a list of full paths to files.
|
|
12
|
+
def copy_files(srcs)
|
|
13
|
+
srcs.each do |src|
|
|
14
|
+
next unless ingest_filesystem.exist?(src)
|
|
15
|
+
|
|
16
|
+
logger&.info("Copying file #{src} (#{Etna::Formatting.as_size(ingest_filesystem.stat(src).size)})")
|
|
17
|
+
|
|
18
|
+
# For ingestion triage, just copy over the exact path + filename.
|
|
19
|
+
copy_file(dest: src, src: src)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def copy_file(dest:, src:)
|
|
24
|
+
ingest_filesystem.with_readable(src, "r") do |file|
|
|
25
|
+
metis_filesystem.do_streaming_upload(file, dest, file.size)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/etna/controller.rb
CHANGED
|
@@ -19,25 +19,30 @@ module Etna
|
|
|
19
19
|
@logger.warn(request_msg(line))
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def handle_error(e)
|
|
23
|
+
case e
|
|
24
|
+
when Etna::Error
|
|
25
|
+
Rollbar.error(e)
|
|
26
|
+
@logger.error(request_msg("Exiting with #{e.status}, #{e.message}"))
|
|
27
|
+
return failure(e.status, error: e.message)
|
|
28
|
+
else
|
|
29
|
+
Rollbar.error(e)
|
|
30
|
+
@logger.error(request_msg('Caught unspecified error'))
|
|
31
|
+
@logger.error(request_msg(e.message))
|
|
32
|
+
e.backtrace.each do |trace|
|
|
33
|
+
@logger.error(request_msg(trace))
|
|
34
|
+
end
|
|
35
|
+
return failure(500, error: 'Server error.')
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
22
39
|
def response(&block)
|
|
23
40
|
return instance_eval(&block) if block_given?
|
|
24
|
-
|
|
25
41
|
return send(@action) if @action
|
|
26
42
|
|
|
27
|
-
|
|
28
43
|
[501, {}, ['This controller is not implemented.']]
|
|
29
|
-
rescue Etna::Error => e
|
|
30
|
-
Rollbar.error(e)
|
|
31
|
-
@logger.error(request_msg("Exiting with #{e.status}, #{e.message}"))
|
|
32
|
-
return failure(e.status, error: e.message)
|
|
33
44
|
rescue Exception => e
|
|
34
|
-
|
|
35
|
-
@logger.error(request_msg('Caught unspecified error'))
|
|
36
|
-
@logger.error(request_msg(e.message))
|
|
37
|
-
e.backtrace.each do |trace|
|
|
38
|
-
@logger.error(request_msg(trace))
|
|
39
|
-
end
|
|
40
|
-
return failure(500, error: 'Server error.')
|
|
45
|
+
handle_error(e)
|
|
41
46
|
end
|
|
42
47
|
|
|
43
48
|
def require_params(*params)
|
data/lib/etna/directed_graph.rb
CHANGED
|
@@ -52,7 +52,12 @@ class DirectedGraph
|
|
|
52
52
|
result[grandparent] << child_node if result.include?(grandparent)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
# Depending on the graph shape, diamonds could lead to
|
|
56
|
+
# resetting of previously calculated dependencies.
|
|
57
|
+
# Here we avoid resetting existing entries in `result`
|
|
58
|
+
# and instead concatenate them if they already exist.
|
|
59
|
+
result[child_node] = [] unless result.include?(child_node)
|
|
60
|
+
result[n].concat(result[child_node]) if result.include?(child_node) && result.include?(n)
|
|
56
61
|
end
|
|
57
62
|
end
|
|
58
63
|
|
data/lib/etna/filesystem.rb
CHANGED
|
@@ -3,6 +3,8 @@ require 'fileutils'
|
|
|
3
3
|
require 'open3'
|
|
4
4
|
require 'securerandom'
|
|
5
5
|
require 'concurrent-ruby'
|
|
6
|
+
require 'net/sftp'
|
|
7
|
+
require 'net/ssh'
|
|
6
8
|
|
|
7
9
|
module Etna
|
|
8
10
|
# A class that encapsulates opening / reading file system entries that abstracts normal file access in order
|
|
@@ -50,6 +52,11 @@ module Etna
|
|
|
50
52
|
::FileUtils.mv(src, dest)
|
|
51
53
|
end
|
|
52
54
|
|
|
55
|
+
def stat(src)
|
|
56
|
+
raise "stat not supported by #{self.class.name}" unless self.class == Filesystem
|
|
57
|
+
::File.stat(src)
|
|
58
|
+
end
|
|
59
|
+
|
|
53
60
|
class EmptyIO < StringIO
|
|
54
61
|
def write(*args)
|
|
55
62
|
# Do nothing -- always leave empty
|
|
@@ -369,7 +376,59 @@ module Etna
|
|
|
369
376
|
end
|
|
370
377
|
end
|
|
371
378
|
|
|
379
|
+
class SftpFilesystem < Filesystem
|
|
380
|
+
def initialize(host:, username:, password: nil, port: 22, **args)
|
|
381
|
+
@username = username
|
|
382
|
+
@password = password
|
|
383
|
+
@host = host
|
|
384
|
+
@port = port
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def ssh
|
|
388
|
+
@ssh ||= Net::SSH.start(@host, @username, password: @password)
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
def sftp
|
|
392
|
+
@sftp ||= begin
|
|
393
|
+
conn = Net::SFTP::Session.new(ssh)
|
|
394
|
+
conn.loop { conn.opening? }
|
|
395
|
+
|
|
396
|
+
conn
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def with_readable(src, opts = 'r', &block)
|
|
401
|
+
sftp.file.open(src, opts, &block)
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def ls(dir)
|
|
405
|
+
sftp.dir.entries(dir)
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def exist?(src)
|
|
409
|
+
begin
|
|
410
|
+
sftp.file.open(src)
|
|
411
|
+
rescue Net::SFTP::StatusException
|
|
412
|
+
return false
|
|
413
|
+
end
|
|
414
|
+
return true
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def stat(src)
|
|
418
|
+
sftp.file.open(src).stat
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
372
422
|
class Mock < Filesystem
|
|
423
|
+
class MockStat
|
|
424
|
+
def initialize
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def size
|
|
428
|
+
0
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
373
432
|
def initialize(&new_io)
|
|
374
433
|
@files = {}
|
|
375
434
|
@dirs = {}
|
|
@@ -438,6 +497,10 @@ module Etna
|
|
|
438
497
|
def exist?(src)
|
|
439
498
|
@files.include?(src) || @dirs.include?(src)
|
|
440
499
|
end
|
|
500
|
+
|
|
501
|
+
def stat(src)
|
|
502
|
+
@files[src].respond_to?(:stat) ? @files[src].stat : MockStat.new
|
|
503
|
+
end
|
|
441
504
|
end
|
|
442
505
|
end
|
|
443
506
|
end
|
data/lib/etna/logger.rb
CHANGED
data/lib/etna/metrics.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
module Etna
|
|
3
|
+
class MetricsExporter
|
|
4
|
+
def initialize(app, path: '/metrics')
|
|
5
|
+
@app = app
|
|
6
|
+
@path = path
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def exporter
|
|
10
|
+
@exporter ||= begin
|
|
11
|
+
exporter = Yabeda::Prometheus::Exporter.new(@app, path: @path)
|
|
12
|
+
Rack::Auth::Basic.new(exporter) do |user, pw|
|
|
13
|
+
user == 'prometheus' && pw == ENV['METRICS_PW']
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def call(env)
|
|
19
|
+
if env['PATH_INFO'] == @path
|
|
20
|
+
exporter.call(env)
|
|
21
|
+
else
|
|
22
|
+
@app.call(env)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/etna/route.rb
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
require 'digest'
|
|
2
|
+
require 'date'
|
|
3
|
+
|
|
1
4
|
module Etna
|
|
2
5
|
class Route
|
|
3
6
|
attr_reader :name
|
|
@@ -58,6 +61,63 @@ module Etna
|
|
|
58
61
|
end
|
|
59
62
|
|
|
60
63
|
def call(app, request)
|
|
64
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
65
|
+
|
|
66
|
+
try_yabeda(request) do |tags|
|
|
67
|
+
Yabeda.etna.visits.increment(tags)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
begin
|
|
71
|
+
process_call(app, request)
|
|
72
|
+
ensure
|
|
73
|
+
try_yabeda(request) do |tags|
|
|
74
|
+
dur = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
|
75
|
+
Yabeda.etna.response_time.measure(tags, dur)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def hash_user_email(email)
|
|
81
|
+
secret = Etna::Application.instance.config(:user_hash_secret) || 'notsosecret'
|
|
82
|
+
digest = email + secret + Date.today.to_s
|
|
83
|
+
|
|
84
|
+
if @name
|
|
85
|
+
digest += @name.to_s
|
|
86
|
+
else
|
|
87
|
+
digest += @route.to_s
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
Digest::MD5.hexdigest(digest)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def try_yabeda(request, &block)
|
|
94
|
+
if @action
|
|
95
|
+
controller, action = @action.split('#')
|
|
96
|
+
elsif @name
|
|
97
|
+
controller = "none"
|
|
98
|
+
action = @name
|
|
99
|
+
else
|
|
100
|
+
controller = "none"
|
|
101
|
+
action = @route
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
params = request.env['rack.request.params']
|
|
105
|
+
user = request.env['etna.user']
|
|
106
|
+
user_hash = user ? hash_user_email(user.email) : 'unknown'
|
|
107
|
+
project_name = "unknown"
|
|
108
|
+
|
|
109
|
+
if params && (params.include?(:project_name) || params.include?('project_name'))
|
|
110
|
+
project_name = params[:project_name] || params['project_name']
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
begin
|
|
114
|
+
block.call({ controller: controller, action: action, user_hash: user_hash, project_name: project_name })
|
|
115
|
+
rescue => e
|
|
116
|
+
raise e unless Etna::Application.instance.environment == :production
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def process_call(app, request)
|
|
61
121
|
update_params(request)
|
|
62
122
|
|
|
63
123
|
unless authorized?(request)
|
|
@@ -148,7 +208,10 @@ module Etna
|
|
|
148
208
|
params = request.env['rack.request.params']
|
|
149
209
|
|
|
150
210
|
@auth[:user].all? do |constraint, param_name|
|
|
151
|
-
user.respond_to?(constraint) &&
|
|
211
|
+
user.respond_to?(constraint) && (
|
|
212
|
+
param_name.is_a?(Symbol) ?
|
|
213
|
+
user.send(constraint, params[param_name]) :
|
|
214
|
+
user.send(constraint, param_name))
|
|
152
215
|
end
|
|
153
216
|
end
|
|
154
217
|
|
data/lib/etna/server.rb
CHANGED
|
@@ -74,6 +74,11 @@ module Etna
|
|
|
74
74
|
def initialize
|
|
75
75
|
# Setup logging.
|
|
76
76
|
application.setup_logger
|
|
77
|
+
|
|
78
|
+
# This needs to be required before yabeda invocation, but cannot belong at the top of any module since clients
|
|
79
|
+
# do not install yabeda.
|
|
80
|
+
require 'yabeda'
|
|
81
|
+
application.setup_yabeda
|
|
77
82
|
end
|
|
78
83
|
|
|
79
84
|
private
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: etna
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.40
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Saurabh Asthana
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-07-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|
|
@@ -94,6 +94,20 @@ dependencies:
|
|
|
94
94
|
- - ">="
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: net-sftp
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: 3.0.0
|
|
104
|
+
type: :runtime
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 3.0.0
|
|
97
111
|
description: See summary
|
|
98
112
|
email: Saurabh.Asthana@ucsf.edu
|
|
99
113
|
executables:
|
|
@@ -144,6 +158,7 @@ files:
|
|
|
144
158
|
- lib/etna/clients/metis/client.rb
|
|
145
159
|
- lib/etna/clients/metis/models.rb
|
|
146
160
|
- lib/etna/clients/metis/workflows.rb
|
|
161
|
+
- lib/etna/clients/metis/workflows/ingest_metis_data_workflow.rb
|
|
147
162
|
- lib/etna/clients/metis/workflows/metis_download_workflow.rb
|
|
148
163
|
- lib/etna/clients/metis/workflows/metis_upload_workflow.rb
|
|
149
164
|
- lib/etna/clients/metis/workflows/sync_metis_data_workflow.rb
|
|
@@ -168,6 +183,7 @@ files:
|
|
|
168
183
|
- lib/etna/hmac.rb
|
|
169
184
|
- lib/etna/json_serializable_struct.rb
|
|
170
185
|
- lib/etna/logger.rb
|
|
186
|
+
- lib/etna/metrics.rb
|
|
171
187
|
- lib/etna/multipart_serializable_nested_hash.rb
|
|
172
188
|
- lib/etna/parse_body.rb
|
|
173
189
|
- lib/etna/route.rb
|