aspera-cli 4.16.0 → 4.17.0

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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +50 -19
  4. data/CONTRIBUTING.md +3 -1
  5. data/README.md +965 -793
  6. data/bin/asession +29 -21
  7. data/lib/aspera/{fasp/agent_alpha.rb → agent/alpha.rb} +26 -25
  8. data/lib/aspera/{fasp/agent_base.rb → agent/base.rb} +15 -12
  9. data/lib/aspera/{fasp/agent_connect.rb → agent/connect.rb} +13 -11
  10. data/lib/aspera/{fasp/agent_direct.rb → agent/direct.rb} +49 -53
  11. data/lib/aspera/{fasp/agent_httpgw.rb → agent/httpgw.rb} +20 -19
  12. data/lib/aspera/{fasp/agent_node.rb → agent/node.rb} +20 -33
  13. data/lib/aspera/{fasp/agent_trsdk.rb → agent/trsdk.rb} +11 -11
  14. data/lib/aspera/api/aoc.rb +586 -0
  15. data/lib/aspera/api/ats.rb +46 -0
  16. data/lib/aspera/api/cos_node.rb +95 -0
  17. data/lib/aspera/api/node.rb +344 -0
  18. data/lib/aspera/ascmd.rb +46 -10
  19. data/lib/aspera/{fasp → ascp}/installation.rb +5 -5
  20. data/lib/aspera/{fasp → ascp}/management.rb +3 -8
  21. data/lib/aspera/{fasp → ascp}/products.rb +1 -1
  22. data/lib/aspera/assert.rb +30 -30
  23. data/lib/aspera/cli/basic_auth_plugin.rb +11 -10
  24. data/lib/aspera/cli/extended_value.rb +1 -1
  25. data/lib/aspera/cli/formatter.rb +13 -13
  26. data/lib/aspera/cli/hints.rb +5 -5
  27. data/lib/aspera/cli/main.rb +35 -28
  28. data/lib/aspera/cli/manager.rb +25 -24
  29. data/lib/aspera/cli/plugin.rb +22 -15
  30. data/lib/aspera/cli/plugin_factory.rb +61 -0
  31. data/lib/aspera/cli/plugins/alee.rb +7 -7
  32. data/lib/aspera/cli/plugins/aoc.rb +83 -77
  33. data/lib/aspera/cli/plugins/ats.rb +32 -33
  34. data/lib/aspera/cli/plugins/bss.rb +3 -4
  35. data/lib/aspera/cli/plugins/config.rb +169 -186
  36. data/lib/aspera/cli/plugins/console.rb +8 -6
  37. data/lib/aspera/cli/plugins/cos.rb +19 -18
  38. data/lib/aspera/cli/plugins/faspex.rb +61 -54
  39. data/lib/aspera/cli/plugins/faspex5.rb +150 -103
  40. data/lib/aspera/cli/plugins/node.rb +68 -73
  41. data/lib/aspera/cli/plugins/orchestrator.rb +34 -44
  42. data/lib/aspera/cli/plugins/preview.rb +31 -31
  43. data/lib/aspera/cli/plugins/server.rb +31 -33
  44. data/lib/aspera/cli/plugins/shares.rb +13 -11
  45. data/lib/aspera/cli/sync_actions.rb +8 -8
  46. data/lib/aspera/cli/transfer_agent.rb +32 -19
  47. data/lib/aspera/cli/transfer_progress.rb +1 -1
  48. data/lib/aspera/cli/version.rb +1 -1
  49. data/lib/aspera/colors.rb +5 -0
  50. data/lib/aspera/command_line_builder.rb +14 -14
  51. data/lib/aspera/coverage.rb +1 -2
  52. data/lib/aspera/data_repository.rb +1 -1
  53. data/lib/aspera/environment.rb +2 -3
  54. data/lib/aspera/faspex_gw.rb +5 -6
  55. data/lib/aspera/faspex_postproc.rb +1 -1
  56. data/lib/aspera/id_generator.rb +2 -2
  57. data/lib/aspera/json_rpc.rb +5 -5
  58. data/lib/aspera/keychain/encrypted_hash.rb +6 -6
  59. data/lib/aspera/keychain/macos_security.rb +27 -22
  60. data/lib/aspera/log.rb +2 -2
  61. data/lib/aspera/nagios.rb +3 -3
  62. data/lib/aspera/node_simulator.rb +5 -6
  63. data/lib/aspera/oauth/base.rb +143 -0
  64. data/lib/aspera/oauth/factory.rb +124 -0
  65. data/lib/aspera/oauth/generic.rb +34 -0
  66. data/lib/aspera/oauth/jwt.rb +51 -0
  67. data/lib/aspera/oauth/url_json.rb +31 -0
  68. data/lib/aspera/oauth/web.rb +50 -0
  69. data/lib/aspera/oauth.rb +5 -331
  70. data/lib/aspera/open_application.rb +7 -7
  71. data/lib/aspera/persistency_action_once.rb +4 -4
  72. data/lib/aspera/persistency_folder.rb +2 -2
  73. data/lib/aspera/preview/generator.rb +5 -5
  74. data/lib/aspera/preview/terminal.rb +3 -2
  75. data/lib/aspera/preview/utils.rb +3 -3
  76. data/lib/aspera/proxy_auto_config.rb +4 -4
  77. data/lib/aspera/rest.rb +175 -144
  78. data/lib/aspera/rest_errors_aspera.rb +3 -3
  79. data/lib/aspera/resumer.rb +77 -0
  80. data/lib/aspera/ssh.rb +6 -1
  81. data/lib/aspera/{fasp → transfer}/error.rb +3 -3
  82. data/lib/aspera/{fasp → transfer}/error_info.rb +1 -1
  83. data/lib/aspera/{fasp → transfer}/faux_file.rb +1 -1
  84. data/lib/aspera/{fasp → transfer}/parameters.rb +58 -89
  85. data/lib/aspera/{fasp/transfer_spec.rb → transfer/spec.rb} +18 -16
  86. data/lib/aspera/{fasp/parameters.yaml → transfer/spec.yaml} +4 -99
  87. data/lib/aspera/{fasp → transfer}/sync.rb +32 -32
  88. data/lib/aspera/{fasp → transfer}/uri.rb +9 -8
  89. data/lib/aspera/web_server_simple.rb +11 -3
  90. data.tar.gz.sig +0 -0
  91. metadata +36 -63
  92. metadata.gz.sig +0 -0
  93. data/lib/aspera/aoc.rb +0 -601
  94. data/lib/aspera/ats_api.rb +0 -47
  95. data/lib/aspera/cos_node.rb +0 -94
  96. data/lib/aspera/fasp/resume_policy.rb +0 -79
  97. 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/fasp/transfer_spec'
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 < Aspera::Cli::BasicAuthPlugin
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, force: false)
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: Aspera::Node, m: :use_standard_ports})
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(env, api: nil)
121
- super(env)
122
- Node.declare_options(options, force: env[:all_manuals])
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? || env[:all_manuals]
125
- # this can be Aspera::Node or Aspera::Rest (shares)
124
+ if !api.nil?
125
+ # this can be Api::Node or Rest (shares)
126
126
  api
127
- elsif Oauth.bearer?(options.get_option(:password, mandatory: true))
127
+ elsif OAuth::Factory.bearer?(options.get_option(:password, mandatory: true))
128
128
  # info is provided like node_info of aoc
129
- Aspera::Node.new(params: {
129
+ Api::Node.new(
130
130
  base_url: options.get_option(:url, mandatory: true),
131
- headers: Aspera::Node.bearer_headers(options.get_option(:password, mandatory: true))
132
- })
131
+ headers: Api::Node.bearer_headers(options.get_option(:password, mandatory: true))
132
+ )
133
133
  else
134
134
  # this is normal case
135
- Aspera::Node.new(params: {
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 = 'ERROR: ' + p['error']['user_message']
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 : '/' + 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(Fasp::TransferSpec::DIRECTION_SEND) }]
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(Fasp::TransferSpec::DIRECTION_RECEIVE), file_name))
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.params[:auth][:username] = ak_info['id']
332
- @api_node.params[:auth][:password] = config.lookup_secret(url: @api_node.params[:base_url], username: ak_info['id'], mandatory: true)
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 { type: :single_object, data: node_license}
384
+ return {type: :single_object, data: node_license}
385
385
  when :api_details
386
- return { type: :single_object, data: @api_node.params }
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(@agents, api: apifid[:api]).execute_action(command_legacy)
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].params[:base_url],
413
+ url: apifid[:api].base_url,
414
414
  root_id: apifid[:file_id]
415
415
  }
416
- assert_values(apifid[:api].params[:auth][:type], %i[basic oauth2])
417
- case apifid[:api].params[:auth][:type]
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].params[:auth][:username]
420
- result[:password] = apifid[:api].params[:auth][:password]
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][Aspera::Node::HEADER_X_ASPERA_ACCESS_KEY]
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
- Oauth.bearer_extract(result[:password])
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 = Aspera::Node.file_matcher_from_argument(options)
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(Aspera::Node::PATH_SEPARATOR)
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(Aspera::Node::PATH_SEPARATOR))
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 Fasp::TransferSpec::DIRECTION_SEND
470
- when :pull then Fasp::TransferSpec::DIRECTION_RECEIVE
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(Fasp::TransferSpec::DIRECTION_SEND))
481
- return Main.result_transfer(transfer.start(apifid[:api].transfer_spec_gen4(apifid[:file_id], Fasp::TransferSpec::DIRECTION_SEND)))
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(Aspera::Node::PATH_SEPARATOR)
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(Aspera::Node::PATH_SEPARATOR)
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], Fasp::TransferSpec::DIRECTION_RECEIVE, {'paths'=>source_paths})))
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(Aspera::Node::PATH_SEPARATOR)
513
+ source_folder = source_folder.split(Api::Node::PATH_SEPARATOR)
514
514
  source_paths = [{'source' => source_folder.pop}]
515
- source_folder = source_folder.join(Aspera::Node::PATH_SEPARATOR)
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(Fasp::TransferSpec::DIRECTION_RECEIVE), file_name))
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'] = Aspera::Node::ACCESS_LEVELS unless create_param.key?('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: @agents[:persistency],
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 = Fasp::TransferSpec::DIRECTION_ENUM_VALUES.map(&:to_sym).each_with_object({}) do |direction, h|
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 Fasp::TransferSpec::DIRECTION_ENUM_VALUES.map(&:to_sym).all? do |dir|
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) + '?goto=' + encoded_params)
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(Aspera::Node.bearer_token(payload: token_info, access_key: access_key, private_key: private_key))
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 # execute_action
925
- end # Main
926
- end # Plugin
927
- end # Cli
928
- end # Aspera
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 < Aspera::Cli::BasicAuthPlugin
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(env)
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' => 'application/' + format}
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
- rest_params = {base_url: options.get_option(:url, mandatory: true)}
111
- case options.get_option(:auth_style, mandatory: true)
112
- when :arg_pass
113
- rest_params[:auth] = {
114
- type: :url,
115
- url_query: {
116
- 'login' => options.get_option(:username, mandatory: true),
117
- 'password' => options.get_option(:password, mandatory: true) }}
118
- when :head_basic
119
- rest_params[:auth] = {
120
- type: :basic,
121
- username: options.get_option(:username, mandatory: true),
122
- password: options.get_option(:password, mandatory: true) }
123
- when :apikey
124
- raise 'Not implemented'
125
- end
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(rest_params)
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: Jira ? API has only XML format
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: Jira ? only json format on url
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