aspera-cli 4.16.0 → 4.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +50 -19
- data/CONTRIBUTING.md +3 -1
- data/README.md +965 -793
- data/bin/asession +29 -21
- data/lib/aspera/{fasp/agent_alpha.rb → agent/alpha.rb} +26 -25
- data/lib/aspera/{fasp/agent_base.rb → agent/base.rb} +15 -12
- data/lib/aspera/{fasp/agent_connect.rb → agent/connect.rb} +13 -11
- data/lib/aspera/{fasp/agent_direct.rb → agent/direct.rb} +49 -53
- data/lib/aspera/{fasp/agent_httpgw.rb → agent/httpgw.rb} +20 -19
- data/lib/aspera/{fasp/agent_node.rb → agent/node.rb} +20 -33
- data/lib/aspera/{fasp/agent_trsdk.rb → agent/trsdk.rb} +11 -11
- data/lib/aspera/api/aoc.rb +586 -0
- data/lib/aspera/api/ats.rb +46 -0
- data/lib/aspera/api/cos_node.rb +95 -0
- data/lib/aspera/api/node.rb +344 -0
- data/lib/aspera/ascmd.rb +46 -10
- data/lib/aspera/{fasp → ascp}/installation.rb +5 -5
- data/lib/aspera/{fasp → ascp}/management.rb +3 -8
- data/lib/aspera/{fasp → ascp}/products.rb +1 -1
- data/lib/aspera/assert.rb +30 -30
- data/lib/aspera/cli/basic_auth_plugin.rb +11 -10
- data/lib/aspera/cli/extended_value.rb +1 -1
- data/lib/aspera/cli/formatter.rb +13 -13
- data/lib/aspera/cli/hints.rb +5 -5
- data/lib/aspera/cli/main.rb +35 -28
- data/lib/aspera/cli/manager.rb +25 -24
- data/lib/aspera/cli/plugin.rb +22 -15
- data/lib/aspera/cli/plugin_factory.rb +61 -0
- data/lib/aspera/cli/plugins/alee.rb +7 -7
- data/lib/aspera/cli/plugins/aoc.rb +83 -77
- data/lib/aspera/cli/plugins/ats.rb +32 -33
- data/lib/aspera/cli/plugins/bss.rb +3 -4
- data/lib/aspera/cli/plugins/config.rb +169 -186
- data/lib/aspera/cli/plugins/console.rb +8 -6
- data/lib/aspera/cli/plugins/cos.rb +19 -18
- data/lib/aspera/cli/plugins/faspex.rb +61 -54
- data/lib/aspera/cli/plugins/faspex5.rb +150 -103
- data/lib/aspera/cli/plugins/node.rb +68 -73
- data/lib/aspera/cli/plugins/orchestrator.rb +34 -44
- data/lib/aspera/cli/plugins/preview.rb +31 -31
- data/lib/aspera/cli/plugins/server.rb +31 -33
- data/lib/aspera/cli/plugins/shares.rb +13 -11
- data/lib/aspera/cli/sync_actions.rb +8 -8
- data/lib/aspera/cli/transfer_agent.rb +32 -19
- data/lib/aspera/cli/transfer_progress.rb +1 -1
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/colors.rb +5 -0
- data/lib/aspera/command_line_builder.rb +14 -14
- data/lib/aspera/coverage.rb +1 -2
- data/lib/aspera/data_repository.rb +1 -1
- data/lib/aspera/environment.rb +2 -3
- data/lib/aspera/faspex_gw.rb +5 -6
- data/lib/aspera/faspex_postproc.rb +1 -1
- data/lib/aspera/id_generator.rb +2 -2
- data/lib/aspera/json_rpc.rb +5 -5
- data/lib/aspera/keychain/encrypted_hash.rb +6 -6
- data/lib/aspera/keychain/macos_security.rb +27 -22
- data/lib/aspera/log.rb +2 -2
- data/lib/aspera/nagios.rb +3 -3
- data/lib/aspera/node_simulator.rb +5 -6
- data/lib/aspera/oauth/base.rb +143 -0
- data/lib/aspera/oauth/factory.rb +124 -0
- data/lib/aspera/oauth/generic.rb +34 -0
- data/lib/aspera/oauth/jwt.rb +51 -0
- data/lib/aspera/oauth/url_json.rb +31 -0
- data/lib/aspera/oauth/web.rb +50 -0
- data/lib/aspera/oauth.rb +5 -331
- data/lib/aspera/open_application.rb +7 -7
- data/lib/aspera/persistency_action_once.rb +4 -4
- data/lib/aspera/persistency_folder.rb +2 -2
- data/lib/aspera/preview/generator.rb +5 -5
- data/lib/aspera/preview/terminal.rb +3 -2
- data/lib/aspera/preview/utils.rb +3 -3
- data/lib/aspera/proxy_auto_config.rb +4 -4
- data/lib/aspera/rest.rb +175 -144
- data/lib/aspera/rest_errors_aspera.rb +3 -3
- data/lib/aspera/resumer.rb +77 -0
- data/lib/aspera/ssh.rb +6 -1
- data/lib/aspera/{fasp → transfer}/error.rb +3 -3
- data/lib/aspera/{fasp → transfer}/error_info.rb +1 -1
- data/lib/aspera/{fasp → transfer}/faux_file.rb +1 -1
- data/lib/aspera/{fasp → transfer}/parameters.rb +58 -89
- data/lib/aspera/{fasp/transfer_spec.rb → transfer/spec.rb} +18 -16
- data/lib/aspera/{fasp/parameters.yaml → transfer/spec.yaml} +4 -99
- data/lib/aspera/{fasp → transfer}/sync.rb +32 -32
- data/lib/aspera/{fasp → transfer}/uri.rb +9 -8
- data/lib/aspera/web_server_simple.rb +11 -3
- data.tar.gz.sig +0 -0
- metadata +36 -63
- metadata.gz.sig +0 -0
- data/lib/aspera/aoc.rb +0 -601
- data/lib/aspera/ats_api.rb +0 -47
- data/lib/aspera/cos_node.rb +0 -94
- data/lib/aspera/fasp/resume_policy.rb +0 -79
- data/lib/aspera/node.rb +0 -339
@@ -3,12 +3,12 @@
|
|
3
3
|
# cspell:ignore snid fnid bidi ssync asyncs rund asnodeadmin mkfile mklink asperabrowser asperabrowserurl watchfolders watchfolderd entsrv
|
4
4
|
require 'aspera/cli/basic_auth_plugin'
|
5
5
|
require 'aspera/cli/sync_actions'
|
6
|
-
require 'aspera/
|
6
|
+
require 'aspera/transfer/spec'
|
7
7
|
require 'aspera/nagios'
|
8
8
|
require 'aspera/hash_ext'
|
9
9
|
require 'aspera/id_generator'
|
10
|
-
require 'aspera/node'
|
11
|
-
require 'aspera/aoc'
|
10
|
+
require 'aspera/api/node'
|
11
|
+
require 'aspera/api/aoc'
|
12
12
|
require 'aspera/oauth'
|
13
13
|
require 'aspera/node_simulator'
|
14
14
|
require 'aspera/assert'
|
@@ -18,10 +18,9 @@ require 'zlib'
|
|
18
18
|
module Aspera
|
19
19
|
module Cli
|
20
20
|
module Plugins
|
21
|
-
class Node <
|
21
|
+
class Node < Cli::BasicAuthPlugin
|
22
22
|
include SyncActions
|
23
23
|
class << self
|
24
|
-
@@node_options_declared = false # rubocop:disable Style/ClassVars
|
25
24
|
def application_name
|
26
25
|
'HSTS Node API'
|
27
26
|
end
|
@@ -36,7 +35,7 @@ module Aspera
|
|
36
35
|
"http://#{address_or_url}:9091"
|
37
36
|
]
|
38
37
|
end
|
39
|
-
|
38
|
+
error = nil
|
40
39
|
urls.each do |base_url|
|
41
40
|
next unless base_url.match?('https?://')
|
42
41
|
api = Rest.new(base_url: base_url)
|
@@ -48,8 +47,10 @@ module Aspera
|
|
48
47
|
url: result[:http].uri.to_s[0..url_length]
|
49
48
|
}
|
50
49
|
rescue StandardError => e
|
50
|
+
error = e
|
51
51
|
Log.log.debug{"detect error: #{e}"}
|
52
52
|
end
|
53
|
+
raise error if error
|
53
54
|
return nil
|
54
55
|
end
|
55
56
|
|
@@ -65,15 +66,13 @@ module Aspera
|
|
65
66
|
}
|
66
67
|
end
|
67
68
|
|
68
|
-
def declare_options(options
|
69
|
-
return if @@node_options_declared && !force
|
70
|
-
@@node_options_declared = true # rubocop:disable Style/ClassVars
|
69
|
+
def declare_options(options)
|
71
70
|
options.declare(:validator, 'Identifier of validator (optional for central)')
|
72
71
|
options.declare(:asperabrowserurl, 'URL for simple aspera web ui', default: 'https://asperabrowser.mybluemix.net')
|
73
72
|
options.declare(:sync_name, 'Sync name')
|
74
73
|
options.declare(
|
75
74
|
:default_ports, 'Use standard FASP ports or get from node api (gen4)', values: :bool, default: :yes,
|
76
|
-
handler: {o:
|
75
|
+
handler: {o: Api::Node, m: :use_standard_ports})
|
77
76
|
options.declare(:root_id, 'File id of top folder if using bearer tokens')
|
78
77
|
SyncActions.declare_options(options)
|
79
78
|
options.parse_options!
|
@@ -117,28 +116,29 @@ module Aspera
|
|
117
116
|
COMMANDS_SHARES = (BASE_ACTIONS - %i[search]).freeze
|
118
117
|
COMMANDS_FASPEX = COMMON_ACTIONS
|
119
118
|
|
120
|
-
def initialize(
|
121
|
-
super(env)
|
122
|
-
Node.declare_options(options
|
119
|
+
def initialize(api: nil, **env)
|
120
|
+
super(**env, basic_options: api.nil?)
|
121
|
+
Node.declare_options(options) if api.nil?
|
122
|
+
return if only_manual
|
123
123
|
@api_node =
|
124
|
-
if !api.nil?
|
125
|
-
# this can be
|
124
|
+
if !api.nil?
|
125
|
+
# this can be Api::Node or Rest (shares)
|
126
126
|
api
|
127
|
-
elsif
|
127
|
+
elsif OAuth::Factory.bearer?(options.get_option(:password, mandatory: true))
|
128
128
|
# info is provided like node_info of aoc
|
129
|
-
|
129
|
+
Api::Node.new(
|
130
130
|
base_url: options.get_option(:url, mandatory: true),
|
131
|
-
headers:
|
132
|
-
|
131
|
+
headers: Api::Node.bearer_headers(options.get_option(:password, mandatory: true))
|
132
|
+
)
|
133
133
|
else
|
134
134
|
# this is normal case
|
135
|
-
|
135
|
+
Api::Node.new(
|
136
136
|
base_url: options.get_option(:url, mandatory: true),
|
137
137
|
auth: {
|
138
138
|
type: :basic,
|
139
139
|
username: options.get_option(:username, mandatory: true),
|
140
140
|
password: options.get_option(:password, mandatory: true)
|
141
|
-
}
|
141
|
+
})
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
@@ -166,7 +166,7 @@ module Aspera
|
|
166
166
|
result = success_msg
|
167
167
|
if p.key?('error')
|
168
168
|
Log.log.error{"#{p['error']['user_message']} : #{p['path']}"}
|
169
|
-
result =
|
169
|
+
result = "ERROR: #{p['error']['user_message']}"
|
170
170
|
errors.push([p['path'], p['error']['user_message']])
|
171
171
|
end
|
172
172
|
final_result[:data].push({type => p['path'], 'result' => result})
|
@@ -192,7 +192,7 @@ module Aspera
|
|
192
192
|
case command
|
193
193
|
when :delete
|
194
194
|
paths_to_delete = get_next_arg_add_prefix(prefix_path, 'file list', :multiple)
|
195
|
-
resp = @api_node.create('files/delete', { paths: paths_to_delete.map{|i| {'path' => i.start_with?('/') ? i :
|
195
|
+
resp = @api_node.create('files/delete', { paths: paths_to_delete.map{|i| {'path' => i.start_with?('/') ? i : "/#{i}"} }})
|
196
196
|
return c_result_translate_rem_prefix(resp, 'file', 'deleted', prefix_path)
|
197
197
|
when :search
|
198
198
|
search_root = get_next_arg_add_prefix(prefix_path, 'search root')
|
@@ -284,7 +284,7 @@ module Aspera
|
|
284
284
|
request_transfer_spec[:paths] = if command.eql?(:download)
|
285
285
|
transfer.ts_source_paths
|
286
286
|
else
|
287
|
-
[{ destination: transfer.destination_folder(
|
287
|
+
[{ destination: transfer.destination_folder(Transfer::Spec::DIRECTION_SEND) }]
|
288
288
|
end
|
289
289
|
# add fixed parameters if any (for COS)
|
290
290
|
@api_node.add_tspec_info(request_transfer_spec) if @api_node.respond_to?(:add_tspec_info)
|
@@ -301,10 +301,10 @@ module Aspera
|
|
301
301
|
@api_node.call(
|
302
302
|
operation: 'GET',
|
303
303
|
subpath: "files/#{URI.encode_www_form_component(remote_path)}/contents",
|
304
|
-
save_to_file: File.join(transfer.destination_folder(
|
304
|
+
save_to_file: File.join(transfer.destination_folder(Transfer::Spec::DIRECTION_RECEIVE), file_name))
|
305
305
|
return Main.result_status("downloaded: #{file_name}")
|
306
306
|
end
|
307
|
-
error_unreachable_line
|
307
|
+
Aspera.error_unreachable_line
|
308
308
|
end
|
309
309
|
|
310
310
|
# common API to node and Shares
|
@@ -328,8 +328,8 @@ module Aspera
|
|
328
328
|
ak_info = @api_node.read("access_keys/#{access_key_id}")[:data]
|
329
329
|
# change API credentials if different access key
|
330
330
|
if !access_key_id.eql?('self')
|
331
|
-
@api_node.
|
332
|
-
@api_node.
|
331
|
+
@api_node.auth_params[:username] = ak_info['id']
|
332
|
+
@api_node.auth_params[:password] = config.lookup_secret(url: @api_node.base_url, username: ak_info['id'], mandatory: true)
|
333
333
|
end
|
334
334
|
root_file_id = ak_info['root_file_id']
|
335
335
|
end
|
@@ -381,9 +381,9 @@ module Aspera
|
|
381
381
|
if node_license['failure'].is_a?(String) && node_license['failure'].include?('ACL')
|
382
382
|
Log.log.error('server must have: asnodeadmin -mu <node user> --acl-add=internal --internal')
|
383
383
|
end
|
384
|
-
return {
|
384
|
+
return {type: :single_object, data: node_license}
|
385
385
|
when :api_details
|
386
|
-
return {
|
386
|
+
return {type: :single_object, data: {base_url: @api_node.base_url}.merge(@api_node.params)}
|
387
387
|
end
|
388
388
|
end
|
389
389
|
|
@@ -406,26 +406,26 @@ module Aspera
|
|
406
406
|
command_legacy = options.get_next_command(V3_IN_V4_ACTIONS)
|
407
407
|
# TODO: shall we support all methods here ? what if there is a link ?
|
408
408
|
apifid = @api_node.resolve_api_fid(top_file_id, '')
|
409
|
-
return Node.new(
|
409
|
+
return Node.new(**init_params, api: apifid[:api]).execute_action(command_legacy)
|
410
410
|
when :node_info, :bearer_token_node
|
411
411
|
apifid = @api_node.resolve_api_fid(top_file_id, options.get_next_argument('path'))
|
412
412
|
result = {
|
413
|
-
url: apifid[:api].
|
413
|
+
url: apifid[:api].base_url,
|
414
414
|
root_id: apifid[:file_id]
|
415
415
|
}
|
416
|
-
assert_values(apifid[:api].
|
417
|
-
case apifid[:api].
|
416
|
+
Aspera.assert_values(apifid[:api].auth_params[:type], %i[basic oauth2])
|
417
|
+
case apifid[:api].auth_params[:type]
|
418
418
|
when :basic
|
419
|
-
result[:username] = apifid[:api].
|
420
|
-
result[:password] = apifid[:api].
|
419
|
+
result[:username] = apifid[:api].auth_params[:username]
|
420
|
+
result[:password] = apifid[:api].auth_params[:password]
|
421
421
|
when :oauth2
|
422
|
-
result[:username] = apifid[:api].params[:headers][
|
422
|
+
result[:username] = apifid[:api].params[:headers][Api::Node::HEADER_X_ASPERA_ACCESS_KEY]
|
423
423
|
result[:password] = apifid[:api].oauth_token
|
424
|
-
else error_unreachable_line
|
424
|
+
else Aspera.error_unreachable_line
|
425
425
|
end
|
426
426
|
return {type: :single_object, data: result} if command_repo.eql?(:node_info)
|
427
427
|
# check format of bearer token
|
428
|
-
|
428
|
+
OAuth::Factory.bearer_extract(result[:password])
|
429
429
|
return Main.result_status(result[:password])
|
430
430
|
when :browse
|
431
431
|
apifid = @api_node.resolve_api_fid(top_file_id, options.get_next_argument('path'))
|
@@ -440,12 +440,12 @@ module Aspera
|
|
440
440
|
return {type: :object_list, data: items, fields: %w[name type recursive_size size modified_time access_level]}
|
441
441
|
when :find
|
442
442
|
apifid = @api_node.resolve_api_fid(top_file_id, options.get_next_argument('path'))
|
443
|
-
test_block =
|
443
|
+
test_block = Api::Node.file_matcher_from_argument(options)
|
444
444
|
return {type: :object_list, data: @api_node.find_files(apifid[:file_id], test_block), fields: ['path']}
|
445
445
|
when :mkdir
|
446
|
-
containing_folder_path = options.get_next_argument('path').split(
|
446
|
+
containing_folder_path = options.get_next_argument('path').split(Api::Node::PATH_SEPARATOR)
|
447
447
|
new_folder = containing_folder_path.pop
|
448
|
-
apifid = @api_node.resolve_api_fid(top_file_id, containing_folder_path.join(
|
448
|
+
apifid = @api_node.resolve_api_fid(top_file_id, containing_folder_path.join(Api::Node::PATH_SEPARATOR))
|
449
449
|
result = apifid[:api].create("files/#{apifid[:file_id]}/files", {name: new_folder, type: :folder})[:data]
|
450
450
|
return Main.result_status("created: #{result['name']} (id=#{result['id']})")
|
451
451
|
when :rename
|
@@ -464,11 +464,11 @@ module Aspera
|
|
464
464
|
return execute_sync_action do |sync_direction, _local_path, remote_path|
|
465
465
|
# Gen4 API
|
466
466
|
# direction is push pull, bidi
|
467
|
-
assert_values(sync_direction, %i[push pull bidi])
|
467
|
+
Aspera.assert_values(sync_direction, %i[push pull bidi])
|
468
468
|
ts_direction = case sync_direction
|
469
|
-
when :push, :bidi then
|
470
|
-
when :pull then
|
471
|
-
else error_unreachable_line
|
469
|
+
when :push, :bidi then Transfer::Spec::DIRECTION_SEND
|
470
|
+
when :pull then Transfer::Spec::DIRECTION_RECEIVE
|
471
|
+
else Aspera.error_unreachable_line
|
472
472
|
end
|
473
473
|
# remote is specified by option to_folder
|
474
474
|
apifid = @api_node.resolve_api_fid(top_file_id, remote_path)
|
@@ -477,8 +477,8 @@ module Aspera
|
|
477
477
|
transfer_spec
|
478
478
|
end
|
479
479
|
when :upload
|
480
|
-
apifid = @api_node.resolve_api_fid(top_file_id, transfer.destination_folder(
|
481
|
-
return Main.result_transfer(transfer.start(apifid[:api].transfer_spec_gen4(apifid[:file_id],
|
480
|
+
apifid = @api_node.resolve_api_fid(top_file_id, transfer.destination_folder(Transfer::Spec::DIRECTION_SEND))
|
481
|
+
return Main.result_transfer(transfer.start(apifid[:api].transfer_spec_gen4(apifid[:file_id], Transfer::Spec::DIRECTION_SEND)))
|
482
482
|
when :download
|
483
483
|
source_paths = transfer.ts_source_paths
|
484
484
|
# special case for AoC : all files must be in same folder
|
@@ -490,11 +490,11 @@ module Aspera
|
|
490
490
|
case file_info['type']
|
491
491
|
when 'file'
|
492
492
|
# if the single source is a file, we need to split into folder path and filename
|
493
|
-
src_dir_elements = source_folder.split(
|
493
|
+
src_dir_elements = source_folder.split(Api::Node::PATH_SEPARATOR)
|
494
494
|
# filename is the last one
|
495
495
|
source_paths = [{'source' => src_dir_elements.pop}]
|
496
496
|
# source folder is what remains
|
497
|
-
source_folder = src_dir_elements.join(
|
497
|
+
source_folder = src_dir_elements.join(Api::Node::PATH_SEPARATOR)
|
498
498
|
# TODO: instead of creating a new object, use the same, and change file id with parent folder id ? possible ?
|
499
499
|
apifid = @api_node.resolve_api_fid(top_file_id, source_folder)
|
500
500
|
when 'link', 'folder'
|
@@ -505,14 +505,14 @@ module Aspera
|
|
505
505
|
raise "Unknown source type: #{file_info['type']}"
|
506
506
|
end
|
507
507
|
end
|
508
|
-
return Main.result_transfer(transfer.start(apifid[:api].transfer_spec_gen4(apifid[:file_id],
|
508
|
+
return Main.result_transfer(transfer.start(apifid[:api].transfer_spec_gen4(apifid[:file_id], Transfer::Spec::DIRECTION_RECEIVE, {'paths'=>source_paths})))
|
509
509
|
when :http_node_download
|
510
510
|
source_paths = transfer.ts_source_paths
|
511
511
|
source_folder = source_paths.shift['source']
|
512
512
|
if source_paths.empty?
|
513
|
-
source_folder = source_folder.split(
|
513
|
+
source_folder = source_folder.split(Api::Node::PATH_SEPARATOR)
|
514
514
|
source_paths = [{'source' => source_folder.pop}]
|
515
|
-
source_folder = source_folder.join(
|
515
|
+
source_folder = source_folder.join(Api::Node::PATH_SEPARATOR)
|
516
516
|
end
|
517
517
|
raise Cli::BadArgument, 'one file at a time only in HTTP mode' if source_paths.length > 1
|
518
518
|
file_name = source_paths.first['source']
|
@@ -520,7 +520,7 @@ module Aspera
|
|
520
520
|
apifid[:api].call(
|
521
521
|
operation: 'GET',
|
522
522
|
subpath: "files/#{apifid[:file_id]}/content",
|
523
|
-
save_to_file: File.join(transfer.destination_folder(
|
523
|
+
save_to_file: File.join(transfer.destination_folder(Transfer::Spec::DIRECTION_RECEIVE), file_name))
|
524
524
|
return Main.result_status("downloaded: #{file_name}")
|
525
525
|
when :show
|
526
526
|
apifid = apifid_from_next_arg(top_file_id)
|
@@ -562,7 +562,7 @@ module Aspera
|
|
562
562
|
create_param = options.get_next_argument('creation data', type: Hash)
|
563
563
|
raise 'no file_id' if create_param.key?('file_id')
|
564
564
|
create_param['file_id'] = apifid[:file_id]
|
565
|
-
create_param['access_levels'] =
|
565
|
+
create_param['access_levels'] = Api::Node::ACCESS_LEVELS unless create_param.key?('access_levels')
|
566
566
|
# add application specific tags (AoC)
|
567
567
|
the_app = apifid[:api].app_info
|
568
568
|
the_app[:api].permissions_set_create_params(create_param: create_param, app_info: the_app) unless the_app.nil?
|
@@ -571,11 +571,11 @@ module Aspera
|
|
571
571
|
# notify application of creation
|
572
572
|
the_app[:api].permissions_send_event(created_data: created_data, app_info: the_app) unless the_app.nil?
|
573
573
|
return { type: :single_object, data: created_data}
|
574
|
-
else error_unreachable_line
|
574
|
+
else Aspera.error_unreachable_line
|
575
575
|
end
|
576
|
-
else error_unreachable_line
|
576
|
+
else Aspera.error_unreachable_line
|
577
577
|
end # command_repo
|
578
|
-
error_unreachable_line
|
578
|
+
Aspera.error_unreachable_line
|
579
579
|
end # execute_command_gen4
|
580
580
|
|
581
581
|
# This is older API
|
@@ -634,7 +634,7 @@ module Aspera
|
|
634
634
|
skip_ids_persistency = nil
|
635
635
|
if options.get_option(:once_only, mandatory: true)
|
636
636
|
skip_ids_persistency = PersistencyActionOnce.new(
|
637
|
-
manager:
|
637
|
+
manager: persistency,
|
638
638
|
data: iteration_data,
|
639
639
|
id: IdGenerator.from_list([
|
640
640
|
'sync_files',
|
@@ -781,7 +781,7 @@ module Aspera
|
|
781
781
|
# do not process last one
|
782
782
|
break if end_date.nil?
|
783
783
|
# init data for this period
|
784
|
-
period_bandwidth =
|
784
|
+
period_bandwidth = Transfer::Spec::DIRECTION_ENUM_VALUES.map(&:to_sym).each_with_object({}) do |direction, h|
|
785
785
|
h[direction] = dir_info.each_with_object({}) do |k2, h2|
|
786
786
|
h2[k2] = 0
|
787
787
|
end
|
@@ -799,7 +799,7 @@ module Aspera
|
|
799
799
|
info[:sessions] += 1
|
800
800
|
# end
|
801
801
|
end
|
802
|
-
next if
|
802
|
+
next if Transfer::Spec::DIRECTION_ENUM_VALUES.map(&:to_sym).all? do |dir|
|
803
803
|
period_bandwidth[dir][:sessions].zero?
|
804
804
|
end
|
805
805
|
result.push({start: Time.at(start_date / 1_000_000), end: Time.at(end_date / 1_000_000)}.merge(period_bandwidth))
|
@@ -895,7 +895,7 @@ module Aspera
|
|
895
895
|
}
|
896
896
|
# encode parameters so that it looks good in url
|
897
897
|
encoded_params = Base64.strict_encode64(Zlib::Deflate.deflate(JSON.generate(browse_params))).gsub(/=+$/, '').tr('+/', '-_').reverse
|
898
|
-
OpenApplication.instance.uri(options.get_option(:asperabrowserurl)
|
898
|
+
OpenApplication.instance.uri("#{options.get_option(:asperabrowserurl)}?goto=#{encoded_params}")
|
899
899
|
return Main.result_status('done')
|
900
900
|
when :basic_token
|
901
901
|
return Main.result_status(Rest.basic_token(options.get_option(:username, mandatory: true), options.get_option(:password, mandatory: true)))
|
@@ -903,7 +903,7 @@ module Aspera
|
|
903
903
|
private_key = OpenSSL::PKey::RSA.new(options.get_next_argument('private RSA key PEM value', type: String))
|
904
904
|
token_info = options.get_next_argument('user and group identification', type: Hash)
|
905
905
|
access_key = options.get_option(:username, mandatory: true)
|
906
|
-
return Main.result_status(
|
906
|
+
return Main.result_status(Api::Node.bearer_token(payload: token_info, access_key: access_key, private_key: private_key))
|
907
907
|
when :simulator
|
908
908
|
require 'aspera/node_simulator'
|
909
909
|
parameters = value_create_modify(command: command)
|
@@ -912,17 +912,12 @@ module Aspera
|
|
912
912
|
uri = URI.parse(parameters[:url])
|
913
913
|
server = WebServerSimple.new(uri, certificate: parameters[:certificate])
|
914
914
|
server.mount(uri.path, NodeSimulatorServlet, parameters[:credentials], transfer)
|
915
|
-
# on ctrl-c, tell server main loop to exit
|
916
|
-
trap('INT') { server.shutdown }
|
917
|
-
formatter.display_status("Node Simulator listening on #{uri.port}")
|
918
|
-
Log.log.info{"Listening on #{uri.port}"}
|
919
|
-
# this is blocking until server exits
|
920
915
|
server.start
|
921
916
|
return Main.result_status('Simulator terminated')
|
922
917
|
end # case command
|
923
918
|
raise 'ERROR: shall not reach this line'
|
924
|
-
end
|
925
|
-
end
|
926
|
-
end
|
927
|
-
end
|
928
|
-
end
|
919
|
+
end
|
920
|
+
end
|
921
|
+
end
|
922
|
+
end
|
923
|
+
end
|
@@ -9,13 +9,14 @@ require 'xmlsimple'
|
|
9
9
|
module Aspera
|
10
10
|
module Cli
|
11
11
|
module Plugins
|
12
|
-
class Orchestrator <
|
12
|
+
class Orchestrator < Cli::BasicAuthPlugin
|
13
13
|
class << self
|
14
14
|
STANDARD_PATH = '/aspera/orchestrator'
|
15
15
|
def detect(address_or_url)
|
16
16
|
address_or_url = "https://#{address_or_url}" unless address_or_url.match?(%r{^[a-z]{1,6}://})
|
17
17
|
urls = [address_or_url]
|
18
18
|
urls.push("#{address_or_url}#{STANDARD_PATH}") unless address_or_url.end_with?(STANDARD_PATH)
|
19
|
+
error = nil
|
19
20
|
urls.each do |base_url|
|
20
21
|
next unless base_url.match?('https?://')
|
21
22
|
api = Rest.new(base_url: base_url)
|
@@ -28,8 +29,10 @@ module Aspera
|
|
28
29
|
url: url[0..url.index(test_endpoint) - 2]
|
29
30
|
}
|
30
31
|
rescue StandardError => e
|
32
|
+
error = e
|
31
33
|
Log.log.debug{"detect error: #{e}"}
|
32
34
|
end
|
35
|
+
raise error if error
|
33
36
|
return nil
|
34
37
|
end
|
35
38
|
|
@@ -46,8 +49,8 @@ module Aspera
|
|
46
49
|
end
|
47
50
|
end
|
48
51
|
|
49
|
-
def initialize(env)
|
50
|
-
super
|
52
|
+
def initialize(**env)
|
53
|
+
super
|
51
54
|
options.declare(:result, "Specify result value as: 'work_step:parameter'")
|
52
55
|
options.declare(:synchronous, 'Wait for completion', values: :bool, default: :no)
|
53
56
|
options.declare(:ret_style, 'How return type is requested in api', values: %i[header arg ext], default: :arg)
|
@@ -57,24 +60,6 @@ module Aspera
|
|
57
60
|
|
58
61
|
ACTIONS = %i[health info workflow plugins processes].freeze
|
59
62
|
|
60
|
-
# for JSON format: add extension ".json" or add url parameter: format=json or Accept: application/json
|
61
|
-
# id can be: a parameter id=x, or at the end of url /id, for workflows: work_order[workflow_id]=wf_id
|
62
|
-
# def call_API_orig(endpoint,id=nil,url_params={format: :json},accept=nil)
|
63
|
-
# # calls are GET
|
64
|
-
# call_args={operation: 'GET',subpath: endpoint}
|
65
|
-
# # specify id if necessary
|
66
|
-
# call_args[:subpath]=call_args[:subpath]+'/'+id unless id.nil?
|
67
|
-
# unless url_params.nil?
|
68
|
-
# if url_params.has_key?(:format)
|
69
|
-
# call_args[:headers]={'Accept'=>'application/'+url_params[:format].to_s}
|
70
|
-
# end
|
71
|
-
# call_args[:headers]={'Accept'=>accept} unless accept.nil?
|
72
|
-
# # add params if necessary
|
73
|
-
# call_args[:url_params]=url_params
|
74
|
-
# end
|
75
|
-
# return @api_orch.call(call_args)
|
76
|
-
# end
|
77
|
-
|
78
63
|
def call_ao(endpoint, opt={})
|
79
64
|
opt[:prefix] = 'api' unless opt.key?(:prefix)
|
80
65
|
# calls are GET
|
@@ -91,40 +76,45 @@ module Aspera
|
|
91
76
|
unless format.nil?
|
92
77
|
case call_type
|
93
78
|
when :header
|
94
|
-
call_args[:headers] = {'Accept' =>
|
79
|
+
call_args[:headers] = {'Accept' => "application/#{format}" }
|
95
80
|
when :arg
|
96
81
|
call_args[:url_params] ||= {}
|
97
82
|
call_args[:url_params][:format] = format
|
98
83
|
when :ext
|
99
84
|
call_args[:subpath] = "#{call_args[:subpath]}.#{format}"
|
100
|
-
else error_unexpected_value(call_type)
|
85
|
+
else Aspera.error_unexpected_value(call_type)
|
101
86
|
end
|
102
87
|
end
|
103
|
-
result = @api_orch.call(call_args)
|
88
|
+
result = @api_orch.call(**call_args)
|
104
89
|
result[:data] = XmlSimple.xml_in(result[:http].body, opt[:xml_opt] || {'ForceArray' => true}) if format.eql?('xml')
|
105
90
|
Log.log.debug{Log.dump(:data, result[:data])}
|
106
91
|
return result
|
107
92
|
end
|
108
93
|
|
109
94
|
def execute_action
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
95
|
+
auth_params =
|
96
|
+
case options.get_option(:auth_style, mandatory: true)
|
97
|
+
when :arg_pass
|
98
|
+
{
|
99
|
+
type: :url,
|
100
|
+
url_query: {
|
101
|
+
'login' => options.get_option(:username, mandatory: true),
|
102
|
+
'password' => options.get_option(:password, mandatory: true) }
|
103
|
+
}
|
104
|
+
when :head_basic
|
105
|
+
{
|
106
|
+
type: :basic,
|
107
|
+
username: options.get_option(:username, mandatory: true),
|
108
|
+
password: options.get_option(:password, mandatory: true)
|
109
|
+
}
|
110
|
+
when :apikey
|
111
|
+
raise 'Not implemented'
|
112
|
+
end
|
126
113
|
|
127
|
-
@api_orch = Rest.new(
|
114
|
+
@api_orch = Rest.new(
|
115
|
+
base_url: options.get_option(:url, mandatory: true),
|
116
|
+
auth: auth_params
|
117
|
+
)
|
128
118
|
|
129
119
|
command1 = options.get_next_command(ACTIONS)
|
130
120
|
case command1
|
@@ -142,11 +132,11 @@ module Aspera
|
|
142
132
|
result = call_ao('remote_node_ping', format: 'xml', xml_opt: {'ForceArray' => false})[:data]
|
143
133
|
return {type: :single_object, data: result}
|
144
134
|
when :processes
|
145
|
-
# TODO:
|
135
|
+
# TODO: Bug ? API has only XML format
|
146
136
|
result = call_ao('processes_status', format: 'xml')[:data]
|
147
137
|
return {type: :object_list, data: result['process']}
|
148
138
|
when :plugins
|
149
|
-
# TODO:
|
139
|
+
# TODO: Bug ? only json format on url
|
150
140
|
result = call_ao('plugin_version')[:data]
|
151
141
|
return {type: :object_list, data: result['Plugin']}
|
152
142
|
when :workflow
|
@@ -207,7 +197,7 @@ module Aspera
|
|
207
197
|
result[:data] = call_ao('initiate', id: wf_id, args: call_params, accept: override_accept)[:data]
|
208
198
|
return result
|
209
199
|
end # wf command
|
210
|
-
else error_unexpected_value(command)
|
200
|
+
else Aspera.error_unexpected_value(command)
|
211
201
|
end # case command
|
212
202
|
end # execute_action
|
213
203
|
end # Orchestrator
|