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.
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
@@ -7,9 +7,9 @@ require 'aspera/preview/options'
7
7
  require 'aspera/preview/utils'
8
8
  require 'aspera/preview/file_types'
9
9
  require 'aspera/preview/terminal'
10
- require 'aspera/fasp/transfer_spec'
10
+ require 'aspera/transfer/spec'
11
11
  require 'aspera/persistency_action_once'
12
- require 'aspera/node'
12
+ require 'aspera/api/node'
13
13
  require 'aspera/hash_ext'
14
14
  require 'aspera/timer_limiter'
15
15
  require 'aspera/id_generator'
@@ -20,7 +20,7 @@ require 'securerandom'
20
20
  module Aspera
21
21
  module Cli
22
22
  module Plugins
23
- class Preview < Aspera::Cli::BasicAuthPlugin
23
+ class Preview < Cli::BasicAuthPlugin
24
24
  # special tag to identify transfers related to generator
25
25
  PREV_GEN_TAG = 'preview_generator'
26
26
  # defined by node API: suffix for folder containing previews
@@ -49,8 +49,8 @@ module Aspera
49
49
  attr_accessor :option_previews_folder
50
50
  attr_accessor :option_folder_reset_cache, :option_skip_folders, :option_overwrite, :option_file_access
51
51
 
52
- def initialize(env)
53
- super(env)
52
+ def initialize(**env)
53
+ super
54
54
  @skip_types = []
55
55
  @default_transfer_spec = nil
56
56
  # by default generate all supported formats (clone, as altered by options)
@@ -96,7 +96,7 @@ module Aspera
96
96
  end
97
97
 
98
98
  options.parse_options!
99
- assert_type(@option_skip_folders, Array){'skip_folder'}
99
+ Aspera.assert_type(@option_skip_folders, Array){'skip_folder'}
100
100
  @tmp_folder = File.join(options.get_option(:temp_folder, mandatory: true), "#{TMP_DIR_PREFIX}.#{SecureRandom.uuid}")
101
101
  FileUtils.mkdir_p(@tmp_folder)
102
102
  Log.log.debug{"tmpdir: #{@tmp_folder}"}
@@ -106,7 +106,7 @@ module Aspera
106
106
  @skip_types = []
107
107
  value.split(',').each do |v|
108
108
  s = v.to_sym
109
- assert_values(s, Aspera::Preview::FileTypes::CONVERSION_TYPES){'skip_types'}
109
+ Aspera.assert_values(s, Aspera::Preview::FileTypes::CONVERSION_TYPES){'skip_types'}
110
110
  @skip_types.push(s)
111
111
  end
112
112
  end
@@ -128,7 +128,7 @@ module Aspera
128
128
  def get_folder_entries(file_id, request_args=nil)
129
129
  headers = {'Accept' => 'application/json'}
130
130
  headers['X-Aspera-Cache-Control'] = 'no-cache' if @option_folder_reset_cache.eql?(:header)
131
- return @api_node.call({operation: 'GET', subpath: "files/#{file_id}/files", headers: headers, url_params: request_args})[:data]
131
+ return @api_node.call(operation: 'GET', subpath: "files/#{file_id}/files", headers: headers, url_params: request_args)[:data]
132
132
  # return @api_node.read("files/#{file_id}/files",request_args)[:data]
133
133
  end
134
134
 
@@ -153,11 +153,11 @@ module Aspera
153
153
  end
154
154
  return if events.empty?
155
155
  events.each do |event|
156
- if event['data']['direction'].eql?(Fasp::TransferSpec::DIRECTION_RECEIVE) &&
156
+ if event['data']['direction'].eql?(Transfer::Spec::DIRECTION_RECEIVE) &&
157
157
  event['data']['status'].eql?('completed') &&
158
158
  event['data']['error_code'].eql?(0) &&
159
- event['data'].dig('tags', Fasp::TransferSpec::TAG_RESERVED, PREV_GEN_TAG).nil?
160
- folder_id = event.dig('data', 'tags', Fasp::TransferSpec::TAG_RESERVED, 'node', 'file_id')
159
+ event['data'].dig('tags', Transfer::Spec::TAG_RESERVED, PREV_GEN_TAG).nil?
160
+ folder_id = event.dig('data', 'tags', Transfer::Spec::TAG_RESERVED, 'node', 'file_id')
161
161
  folder_id ||= event.dig('data', 'file_id')
162
162
  if !folder_id.nil?
163
163
  folder_entry = @api_node.read("files/#{folder_id}")[:data] rescue nil
@@ -191,7 +191,7 @@ module Aspera
191
191
  if event.dig('data', 'type').eql?('file')
192
192
  file_entry = @api_node.read("files/#{event['data']['id']}")[:data] rescue nil
193
193
  if !file_entry.nil? &&
194
- @option_skip_folders.select{|d|file_entry['path'].start_with?(d)}.empty?
194
+ @option_skip_folders.none?{|d|file_entry['path'].start_with?(d)}
195
195
  file_entry['parent_file_id'] = event['data']['parent_file_id']
196
196
  if event['types'].include?('file.deleted')
197
197
  Log.log.error('TODO'.red)
@@ -213,10 +213,10 @@ module Aspera
213
213
  end
214
214
 
215
215
  def do_transfer(direction, folder_id, source_filename, destination='/')
216
- assert(!(destination.nil? && direction.eql?(Fasp::TransferSpec::DIRECTION_RECEIVE)))
216
+ Aspera.assert(!(destination.nil? && direction.eql?(Transfer::Spec::DIRECTION_RECEIVE)))
217
217
  t_spec = @api_node.transfer_spec_gen4(folder_id, direction, {
218
218
  'paths' => [{'source' => source_filename}],
219
- 'tags' => {Fasp::TransferSpec::TAG_RESERVED => {PREV_GEN_TAG => true}}
219
+ 'tags' => {Transfer::Spec::TAG_RESERVED => {PREV_GEN_TAG => true}}
220
220
  })
221
221
  # force destination, need to set this in transfer agent else it gets overwritten, not do: t_spec['destination_root']=destination
222
222
  transfer.option_transfer_spec_deep_merge({'destination_root' => destination})
@@ -318,7 +318,7 @@ module Aspera
318
318
  if @access_remote
319
319
  raise 'missing parent_file_id in entry' if entry['parent_file_id'].nil?
320
320
  # download original file to temp folder
321
- do_transfer(Fasp::TransferSpec::DIRECTION_RECEIVE, entry['parent_file_id'], entry['name'], @tmp_folder)
321
+ do_transfer(Transfer::Spec::DIRECTION_RECEIVE, entry['parent_file_id'], entry['name'], @tmp_folder)
322
322
  end
323
323
  Log.log.info{"source: #{entry['id']}: #{entry['path']}"}
324
324
  gen_infos.each do |gen_info|
@@ -326,7 +326,7 @@ module Aspera
326
326
  end
327
327
  if @access_remote
328
328
  # upload
329
- do_transfer(Fasp::TransferSpec::DIRECTION_SEND, @previews_folder_entry['id'], local_entry_preview_dir)
329
+ do_transfer(Transfer::Spec::DIRECTION_SEND, @previews_folder_entry['id'], local_entry_preview_dir)
330
330
  # cleanup after upload
331
331
  FileUtils.rm_rf(local_entry_preview_dir)
332
332
  File.delete(File.join(@tmp_folder, entry['name']))
@@ -403,8 +403,8 @@ module Aspera
403
403
  command = options.get_next_command(ACTIONS)
404
404
  unless %i[check test show].include?(command)
405
405
  # this will use node api
406
- @api_node = Aspera::Node.new(params: basic_auth_params)
407
- @transfer_server_address = URI.parse(@api_node.params[:base_url]).host
406
+ @api_node = Api::Node.new(**basic_auth_params)
407
+ @transfer_server_address = URI.parse(@api_node.base_url).host
408
408
  # get current access key
409
409
  @access_key_self = @api_node.read('access_keys/self')[:data]
410
410
  # TODO: check events is activated here:
@@ -422,13 +422,13 @@ module Aspera
422
422
  raise Cli::Error, "Folder #{@option_previews_folder} does not exist on node. " \
423
423
  'Please create it in the storage root, or specify an alternate name.' if @previews_folder_entry.nil?
424
424
  else
425
- assert(@access_key_self['storage']['type'].eql?('local')){'only local storage allowed in this mode'}
425
+ Aspera.assert(@access_key_self['storage']['type'].eql?('local')){'only local storage allowed in this mode'}
426
426
  @local_storage_root = @access_key_self['storage']['path']
427
427
  # TODO: option to override @local_storage_root='xxx'
428
428
  @local_storage_root = @local_storage_root[PVCL_LOCAL_STORAGE.length..-1] if @local_storage_root.start_with?(PVCL_LOCAL_STORAGE)
429
429
  # TODO: windows could have "C:" ?
430
- assert(@local_storage_root.start_with?('/')){"not local storage: #{@local_storage_root}"}
431
- assert(File.directory?(@local_storage_root), exception_class: Cli::Error){"Local storage root folder #{@local_storage_root} does not exist."}
430
+ Aspera.assert(@local_storage_root.start_with?('/')){"not local storage: #{@local_storage_root}"}
431
+ Aspera.assert(File.directory?(@local_storage_root), exception_class: Cli::Error){"Local storage root folder #{@local_storage_root} does not exist."}
432
432
  @local_preview_folder = File.join(@local_storage_root, @option_previews_folder)
433
433
  raise Cli::Error, "Folder #{@local_preview_folder} does not exist locally. " \
434
434
  'Please create it, or specify an alternate name.' unless File.directory?(@local_preview_folder)
@@ -437,7 +437,7 @@ module Aspera
437
437
  Log.log.debug{"marker file: #{marker_file}"}
438
438
  if File.exist?(marker_file)
439
439
  ak = File.read(marker_file).chomp
440
- assert(@access_key_self['id'].eql?(ak)){"mismatch access key in #{marker_file}: contains #{ak}, using #{@access_key_self['id']}"}
440
+ Aspera.assert(@access_key_self['id'].eql?(ak)){"mismatch access key in #{marker_file}: contains #{ak}, using #{@access_key_self['id']}"}
441
441
  else
442
442
  File.write(marker_file, @access_key_self['id'])
443
443
  end
@@ -461,15 +461,15 @@ module Aspera
461
461
  else
462
462
  @api_node.read("files/#{scan_id}")[:data]
463
463
  end
464
- @filter_block = Aspera::Node.file_matcher_from_argument(options)
464
+ @filter_block = Api::Node.file_matcher_from_argument(options)
465
465
  scan_folder_files(folder_info, scan_path)
466
466
  return Main.result_status('scan finished')
467
467
  when :events, :trevents
468
- @filter_block = Aspera::Node.file_matcher_from_argument(options)
468
+ @filter_block = Api::Node.file_matcher_from_argument(options)
469
469
  iteration_persistency = nil
470
470
  if options.get_option(:once_only, mandatory: true)
471
471
  iteration_persistency = PersistencyActionOnce.new(
472
- manager: @agents[:persistency],
472
+ manager: persistency,
473
473
  data: [],
474
474
  id: IdGenerator.from_list([
475
475
  'preview_iteration',
@@ -479,7 +479,7 @@ module Aspera
479
479
  ]))
480
480
  end
481
481
  # call processing method specified by command line command
482
- send("process_#{command}", iteration_persistency)
482
+ send(:"process_#{command}", iteration_persistency)
483
483
  return Main.result_status("#{command} finished")
484
484
  when :check
485
485
  return Main.result_status('Tools validated')
@@ -501,8 +501,8 @@ module Aspera
501
501
  ensure
502
502
  Log.log.debug{"cleaning up temp folder #{@tmp_folder}"}
503
503
  FileUtils.rm_rf(@tmp_folder)
504
- end # execute_action
505
- end # Preview
506
- end # Plugins
507
- end # Cli
508
- end # Aspera
504
+ end
505
+ end
506
+ end
507
+ end
508
+ end
@@ -3,7 +3,7 @@
3
3
  # cspell:ignore ascmd zmode zuid zgid fasping
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/ascmd'
8
8
  require 'aspera/ssh'
9
9
  require 'aspera/nagios'
@@ -16,7 +16,7 @@ module Aspera
16
16
  module Cli
17
17
  module Plugins
18
18
  # implement basic remote access with FASP/SSH
19
- class Server < Aspera::Cli::BasicAuthPlugin
19
+ class Server < Cli::BasicAuthPlugin
20
20
  include SyncActions
21
21
  SSH_SCHEME = 'ssh'
22
22
  LOCAL_SCHEME = 'local'
@@ -53,27 +53,27 @@ module Aspera
53
53
  [address_or_url]
54
54
  else
55
55
  [
56
- "ssh://#{address_or_url}:33001",
57
- "ssh://#{address_or_url}:22"
56
+ "#{SSH_SCHEME}://#{address_or_url}:33001",
57
+ "#{SSH_SCHEME}://#{address_or_url}:22"
58
58
  ]
59
59
  # wss not practical as it requires a token
60
60
  end
61
-
61
+ error = nil
62
62
  urls.each do |base_url|
63
63
  server_uri = URI.parse(base_url)
64
64
  Log.log.debug{"URI=#{server_uri}, host=#{server_uri.hostname}, port=#{server_uri.port}, scheme=#{server_uri.scheme}"}
65
65
  next unless server_uri.scheme.eql?(SSH_SCHEME)
66
- begin
67
- socket = TCPSocket.new(server_uri.hostname, server_uri.port)
68
- socket.puts('SSH-2.0-Ascli_0.0')
69
- version = socket.gets.chomp
70
- if version.match?(/^SSH-2.0-/)
71
- return {version: version.gsub(/^SSH-2.0-/, ''), url: base_url}
72
- end
73
- rescue StandardError => e
74
- Log.log.debug{"detect error: #{e}"}
66
+ socket = TCPSocket.new(server_uri.hostname, server_uri.port)
67
+ socket.puts('SSH-2.0-Ascli_0.0')
68
+ version = socket.gets.chomp
69
+ if version.match?(/^SSH-2.0-/)
70
+ return {version: version.gsub(/^SSH-2.0-/, ''), url: base_url}
75
71
  end
72
+ rescue StandardError => e
73
+ error = e
74
+ Log.log.debug{"detect error: #{e}"}
76
75
  end
76
+ raise error if error
77
77
  return nil
78
78
  end
79
79
 
@@ -90,8 +90,8 @@ module Aspera
90
90
  end
91
91
  end
92
92
 
93
- def initialize(env)
94
- super(env)
93
+ def initialize(**env)
94
+ super
95
95
  options.declare(:ssh_keys, 'SSH key path list (Array or single)')
96
96
  options.declare(:passphrase, 'SSH private key passphrase')
97
97
  options.declare(:ssh_options, 'SSH options', types: Hash, default: {})
@@ -127,14 +127,14 @@ module Aspera
127
127
  if !server_uri.scheme.eql?(SSH_SCHEME)
128
128
  Log.log.warn('URL scheme is https but no token was provided in transfer spec.')
129
129
  Log.log.warn("If you want to access the server, not using WSS for session, then use a URL with scheme \"#{SSH_SCHEME}\" and proper SSH port")
130
- assumed_url = "#{SSH_SCHEME}://#{server_transfer_spec['remote_host']}:#{Aspera::Fasp::TransferSpec::SSH_PORT}"
130
+ assumed_url = "#{SSH_SCHEME}://#{server_transfer_spec['remote_host']}:#{Transfer::Spec::SSH_PORT}"
131
131
  Log.log.warn{"Assuming proper URL is: #{assumed_url}"}
132
132
  server_uri = URI.parse(assumed_url)
133
133
  end
134
134
  # Scheme is SSH
135
135
  if options.get_option(:username).nil?
136
- options.set_option(:username, Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER)
137
- Log.log.info{"No username provided: Assuming default transfer user: #{Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER}"}
136
+ options.set_option(:username, Transfer::Spec::ACCESS_KEY_TRANSFER_USER)
137
+ Log.log.info{"No username provided: Assuming default transfer user: #{Transfer::Spec::ACCESS_KEY_TRANSFER_USER}"}
138
138
  end
139
139
  server_transfer_spec['remote_user'] = options.get_option(:username, mandatory: true)
140
140
  if !server_uri.port.nil?
@@ -151,16 +151,14 @@ module Aspera
151
151
  ssh_key_list = options.get_option(:ssh_keys)
152
152
  if !ssh_key_list.nil?
153
153
  ssh_key_list = [ssh_key_list] if ssh_key_list.is_a?(String)
154
- assert_type(ssh_key_list, Array){'ssh_keys'}
155
- assert(ssh_key_list.all?(String))
154
+ Aspera.assert_type(ssh_key_list, Array){'ssh_keys'}
155
+ Aspera.assert(ssh_key_list.all?(String))
156
156
  ssh_key_list.map!{|p|File.expand_path(p)}
157
157
  Log.log.debug{"SSH keys=#{ssh_key_list}"}
158
158
  if !ssh_key_list.empty?
159
159
  @ssh_opts[:keys] = ssh_key_list
160
- server_transfer_spec['EX_ssh_key_paths'] = ssh_key_list
161
- ssh_key_list.each do |k|
162
- Log.log.warn{"No such key file: #{k}"} unless File.exist?(k)
163
- end
160
+ server_transfer_spec['ssh_private_key'] = File.read(ssh_key_list.first)
161
+ Log.log.warn{'Using only first SSH key for transfers'} unless ssh_key_list.length.eql?(1)
164
162
  cred_set = true
165
163
  end
166
164
  end
@@ -178,7 +176,7 @@ module Aspera
178
176
  def execute_transfer(command, transfer_spec)
179
177
  case command
180
178
  when :upload, :download
181
- Fasp::TransferSpec.action_to_direction(transfer_spec, command)
179
+ Transfer::Spec.action_to_direction(transfer_spec, command)
182
180
  return Main.result_transfer(transfer.start(transfer_spec))
183
181
  when :sync
184
182
  # lets ignore the arguments provided by execute_sync_action, we just give the transfer spec
@@ -189,7 +187,7 @@ module Aspera
189
187
  # actions without ascmd
190
188
  BASE_ACTIONS = %i[health].concat(TRANSFER_COMMANDS).freeze
191
189
  # all actions
192
- ACTIONS = [BASE_ACTIONS, Aspera::AsCmd::OPERATIONS, ASCMD_ALIASES.keys].flatten.freeze
190
+ ACTIONS = [BASE_ACTIONS, AsCmd::OPERATIONS, ASCMD_ALIASES.keys].flatten.freeze
193
191
 
194
192
  def execute_action
195
193
  server_transfer_spec = options_to_base_transfer_spec
@@ -228,16 +226,16 @@ module Aspera
228
226
  else
229
227
  nagios.add_critical('transfer', statuses.reject{|i|i.eql?(:success)}.first.to_s)
230
228
  end
231
- else error_unexpected_value(command_nagios)
229
+ else Aspera.error_unexpected_value(command_nagios)
232
230
  end
233
231
  return nagios.result
234
232
  when *TRANSFER_COMMANDS
235
233
  return execute_transfer(command, server_transfer_spec)
236
- when *Aspera::AsCmd::OPERATIONS
234
+ when *AsCmd::OPERATIONS
237
235
  command_arguments = options.get_next_argument('ascmd command arguments', expected: :multiple, mandatory: false)
238
- ascmd = Aspera::AsCmd.new(ascmd_executor)
236
+ ascmd = AsCmd.new(ascmd_executor)
239
237
  begin
240
- result = ascmd.send(:execute_single, command, command_arguments)
238
+ result = ascmd.execute_single(command, command_arguments)
241
239
  case command
242
240
  when :mkdir, :mv, :cp, :rm
243
241
  return Main.result_success
@@ -248,10 +246,10 @@ module Aspera
248
246
  when :du, :md5sum, :info
249
247
  return {type: :single_object, data: result.stringify_keys}
250
248
  end
251
- rescue Aspera::AsCmd::Error => e
249
+ rescue AsCmd::Error => e
252
250
  raise Cli::BadArgument, e.extended_message
253
251
  end
254
- else error_unreachable_line
252
+ else Aspera.error_unreachable_line
255
253
  end
256
254
  end # execute_action
257
255
  end # Server
@@ -6,7 +6,7 @@ module Aspera
6
6
  module Cli
7
7
  module Plugins
8
8
  # Plugin for Aspera Shares v1
9
- class Shares < Aspera::Cli::BasicAuthPlugin
9
+ class Shares < Cli::BasicAuthPlugin
10
10
  API_BASE = 'node_api'
11
11
  class << self
12
12
  def detect(address_or_url)
@@ -24,7 +24,7 @@ module Aspera
24
24
  end
25
25
  return nil unless found
26
26
  version = 'unknown'
27
- test_page = api.call({ operation: 'GET', subpath: 'login' })
27
+ test_page = api.call(operation: 'GET', subpath: 'login')
28
28
  if (m = test_page[:http].body.match(/\(v(1\..*)\)/))
29
29
  version = m[1]
30
30
  end
@@ -47,8 +47,8 @@ module Aspera
47
47
  end
48
48
  end
49
49
 
50
- def initialize(env)
51
- super(env)
50
+ def initialize(**env)
51
+ super
52
52
  end
53
53
 
54
54
  SAML_IMPORT_MANDATORY = %w[id name_id].freeze
@@ -79,7 +79,7 @@ module Aspera
79
79
  when :repository, :files
80
80
  api_shares_node = basic_auth_api(API_BASE)
81
81
  repo_command = options.get_next_command(Node::COMMANDS_SHARES)
82
- return Node.new(@agents, api: api_shares_node).execute_action(repo_command)
82
+ return Node.new(**init_params, api: api_shares_node).execute_action(repo_command)
83
83
  when :admin
84
84
  api_shares_admin = basic_auth_api('api/v1')
85
85
  admin_command = options.get_next_command(%i[node share transfer_settings user group].freeze)
@@ -102,17 +102,19 @@ module Aspera
102
102
  when :user, :group
103
103
  entity_type = admin_command
104
104
  entities_location = options.get_next_command(%i[all local ldap saml])
105
- entities_path = "data/#{entities_location}_#{entity_type}s"
105
+ entities_prefix = entities_location.eql?(:all) ? '' : "#{entities_location}_"
106
+ entities_path = "data/#{entities_prefix}#{entity_type}s"
106
107
  entity_action = nil
107
108
  case entities_location
108
109
  when :all
109
- entities_path = "data/#{entity_type}s"
110
110
  entity_action = %i[list show delete]
111
111
  entity_action.concat(USR_GRP_SETTINGS)
112
112
  entity_action.push(:users) if entity_type.eql?(:group)
113
113
  entity_action.freeze
114
114
  when :local
115
- entity_action = %i[list show delete create modify].freeze
115
+ entity_action = %i[list show delete create modify]
116
+ entity_action.push(:users) if entity_type.eql?(:group)
117
+ entity_action.freeze
116
118
  when :ldap
117
119
  entity_action = %i[add].freeze
118
120
  when :saml
@@ -131,7 +133,7 @@ module Aspera
131
133
  when :import # saml
132
134
  return do_bulk_operation(command: entity_verb, descr: 'user information') do |entity_parameters|
133
135
  entity_parameters = entity_parameters.transform_keys{|k|k.gsub(/\s+/, '_').downcase}
134
- assert_type(entity_parameters, Hash)
136
+ Aspera.assert_type(entity_parameters, Hash)
135
137
  SAML_IMPORT_MANDATORY.each{|p|raise "missing mandatory field: #{p}" if entity_parameters[p].nil?}
136
138
  entity_parameters.each_key do |p|
137
139
  raise "unsupported field: #{p}, use: #{SAML_IMPORT_ALLOWED.join(',')}" unless SAML_IMPORT_ALLOWED.include?(p)
@@ -143,8 +145,8 @@ module Aspera
143
145
  api_shares_admin.create(entities_path, {entity_type=>entity_name})[:data]
144
146
  end
145
147
  when :users # group
146
- raise "TODO, not implemented"
147
- else error_unexpected_value(entity_verb)
148
+ return entity_action(api_shares_admin, "#{entities_path}/#{instance_identifier}/#{entities_prefix}users")
149
+ else Aspera.error_unexpected_value(entity_verb)
148
150
  end
149
151
  end
150
152
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'aspera/fasp/sync'
3
+ require 'aspera/transfer/sync'
4
4
  require 'aspera/assert'
5
5
 
6
6
  module Aspera
@@ -8,7 +8,7 @@ module Aspera
8
8
  # Module for sync actions
9
9
  module SyncActions
10
10
  SIMPLE_ARGUMENTS_SYNC = {
11
- direction: Aspera::Fasp::Sync::DIRECTIONS,
11
+ direction: Transfer::Sync::DIRECTIONS,
12
12
  local_dir: String,
13
13
  remote_dir: String
14
14
  }.stringify_keys.freeze
@@ -20,7 +20,7 @@ module Aspera
20
20
  end
21
21
 
22
22
  def execute_sync_action(&block)
23
- assert(block){'No block given'}
23
+ Aspera.assert(block){'No block given'}
24
24
  command = options.get_next_command(%i[start admin])
25
25
  # try to get 3 arguments as simple arguments
26
26
  case command
@@ -45,13 +45,13 @@ module Aspera
45
45
  :sync_info,
46
46
  mandatory: false,
47
47
  default: {'sessions' => [{'name' => File.basename(simple_session_args['local_dir'])}]})
48
- assert_type(async_params, Hash){'sync_info'}
49
- assert_type(async_params['sessions'], Array){'sync_info[sessions]'}
50
- assert_type(async_params['sessions'].first, Hash){'sync_info[sessions][0]'}
48
+ Aspera.assert_type(async_params, Hash){'sync_info'}
49
+ Aspera.assert_type(async_params['sessions'], Array){'sync_info[sessions]'}
50
+ Aspera.assert_type(async_params['sessions'].first, Hash){'sync_info[sessions][0]'}
51
51
  async_params['sessions'].first.merge!(simple_session_args)
52
52
  end
53
53
  Log.log.debug{Log.dump('async_params', async_params)}
54
- Aspera::Fasp::Sync.start(async_params, &block)
54
+ Transfer::Sync.start(async_params, &block)
55
55
  return Main.result_success
56
56
  when :admin
57
57
  command2 = options.get_next_command([:status])
@@ -59,7 +59,7 @@ module Aspera
59
59
  when :status
60
60
  sync_session_name = options.get_next_argument('name of sync session', mandatory: false, type: String)
61
61
  async_params = options.get_option(:sync_info, mandatory: true)
62
- return {type: :single_object, data: Aspera::Fasp::Sync.admin_status(async_params, sync_session_name)}
62
+ return {type: :single_object, data: Transfer::Sync.admin_status(async_params, sync_session_name)}
63
63
  end # command2
64
64
  end # command
65
65
  end # execute_action
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'aspera/fasp/agent_base'
4
- require 'aspera/fasp/transfer_spec'
3
+ require 'aspera/agent/base'
4
+ require 'aspera/transfer/spec'
5
5
  require 'aspera/cli/info'
6
6
  require 'aspera/log'
7
7
  require 'aspera/assert'
@@ -31,7 +31,7 @@ module Aspera
31
31
  :FILE_LIST_FROM_TRANSFER_SPEC,
32
32
  :FILE_LIST_OPTIONS,
33
33
  :DEFAULT_TRANSFER_NOTIFY_TEMPLATE
34
- TRANSFER_AGENTS = Fasp::AgentBase.agent_list.freeze
34
+ TRANSFER_AGENTS = Agent::Base.agent_list.freeze
35
35
 
36
36
  class << self
37
37
  # @return :success if all sessions statuses returned by "start" are success
@@ -55,6 +55,8 @@ module Aspera
55
55
  @agent = nil
56
56
  # source/destination pair, like "paths" of transfer spec
57
57
  @transfer_paths = nil
58
+ # HTTPGW URL provided by webapp
59
+ @httpgw_url_lambda = nil
58
60
  @opt_mgr.declare(:ts, 'Override transfer spec values', types: Hash, handler: {o: self, m: :option_transfer_spec})
59
61
  @opt_mgr.declare(:to_folder, 'Destination folder for transferred files')
60
62
  @opt_mgr.declare(:sources, "How list of transferred files is provided (#{FILE_LIST_OPTIONS.join(',')})")
@@ -68,7 +70,7 @@ module Aspera
68
70
 
69
71
  # multiple option are merged
70
72
  def option_transfer_spec=(value)
71
- assert_type(value, Hash){'ts'}
73
+ Aspera.assert_type(value, Hash){'ts'}
72
74
  @transfer_spec_command_line.deep_merge!(value)
73
75
  end
74
76
 
@@ -95,11 +97,12 @@ module Aspera
95
97
  end
96
98
 
97
99
  # analyze options and create new agent if not already created or set
100
+ # TODO: make a Factory pattern
98
101
  def agent_instance
99
102
  return @agent unless @agent.nil?
100
103
  agent_type = @opt_mgr.get_option(:transfer, mandatory: true)
101
104
  # agent plugin is loaded on demand to avoid loading unnecessary dependencies
102
- require "aspera/fasp/agent_#{agent_type}"
105
+ require "aspera/agent/#{agent_type}"
103
106
  # set keys as symbols
104
107
  agent_options = @opt_mgr.get_option(:transfer_info).symbolize_keys
105
108
  # special cases
@@ -113,12 +116,17 @@ module Aspera
113
116
  when :direct
114
117
  # by default do not display ascp native progress bar
115
118
  agent_options[:quiet] = true unless agent_options.key?(:quiet)
116
- agent_options[:check_ignore] = ->(host, port){@config.ignore_cert?(host, port)}
117
- agent_options[:trusted_certs] = @config.trusted_cert_locations(files_only: true) unless agent_options.key?(:trusted_certs)
119
+ agent_options[:check_ignore_cb] = ->(host, port){@config.ignore_cert?(host, port)}
120
+ agent_options[:trusted_certs] = @config.trusted_cert_locations unless agent_options.key?(:trusted_certs)
121
+ when :httpgw
122
+ unless agent_options.key?(:url) || @httpgw_url_lambda.nil?
123
+ Log.log.debug('retrieving HTTPGW URL from webapp')
124
+ agent_options[:url] = @httpgw_url_lambda.call
125
+ end
118
126
  end
119
127
  agent_options[:progress] = @config.progress_bar
120
128
  # get agent instance
121
- new_agent = Kernel.const_get("Aspera::Fasp::Agent#{agent_type.capitalize}").new(agent_options)
129
+ new_agent = Kernel.const_get("Aspera::Agent::#{agent_type.capitalize}").new(agent_options)
122
130
  self.agent_instance = new_agent
123
131
  Log.log.debug{"transfer agent is a #{@agent.class}"}
124
132
  return @agent
@@ -135,9 +143,9 @@ module Aspera
135
143
  return dest_folder unless dest_folder.nil?
136
144
  # default: / on remote, . on local
137
145
  case direction.to_s
138
- when Fasp::TransferSpec::DIRECTION_SEND then dest_folder = '/'
139
- when Fasp::TransferSpec::DIRECTION_RECEIVE then dest_folder = '.'
140
- else error_unexpected_value(direction)
146
+ when Transfer::Spec::DIRECTION_SEND then dest_folder = '/'
147
+ when Transfer::Spec::DIRECTION_RECEIVE then dest_folder = '.'
148
+ else Aspera.error_unexpected_value(direction)
141
149
  end
142
150
  return dest_folder
143
151
  end
@@ -149,6 +157,11 @@ module Aspera
149
157
  end
150
158
  end
151
159
 
160
+ def httpgw_url_cb=(httpgw_url_proc)
161
+ Aspera.assert_type(httpgw_url_proc, Proc){'httpgw_url_cb'}
162
+ @httpgw_url_lambda = httpgw_url_proc
163
+ end
164
+
152
165
  # This is how the list of files to be transferred is specified
153
166
  # get paths suitable for transfer spec from command line
154
167
  # @return [Hash] {source: (mandatory), destination: (optional)}
@@ -171,7 +184,7 @@ module Aspera
171
184
  Log.log.debug('assume list provided in transfer spec')
172
185
  special_case_direct_with_list =
173
186
  @opt_mgr.get_option(:transfer, mandatory: true).eql?(:direct) &&
174
- Fasp::Parameters.ts_has_ascp_file_list(@transfer_spec_command_line, @opt_mgr.get_option(:transfer_info))
187
+ Transfer::Parameters.ascp_args_file_list?(@opt_mgr.get_option(:transfer_info)['ascp_args'])
175
188
  raise Cli::BadArgument, 'transfer spec on command line must have sources' if @transfer_paths.nil? && !special_case_direct_with_list
176
189
  # here we assume check of sources is made in transfer agent
177
190
  return @transfer_paths
@@ -185,15 +198,15 @@ module Aspera
185
198
  if !@transfer_paths.nil?
186
199
  Log.log.warn('--sources overrides paths from --ts')
187
200
  end
188
- source_type=@opt_mgr.get_option(:src_type, mandatory: true)
201
+ source_type = @opt_mgr.get_option(:src_type, mandatory: true)
189
202
  case source_type
190
203
  when :list
191
204
  # when providing a list, just specify source
192
205
  @transfer_paths = file_list.map{|i|{'source' => i}}
193
206
  when :pair
194
- assert(file_list.length.even?, exception_class: Cli::BadArgument){"When using pair, provide an even number of paths: #{file_list.length}"}
207
+ Aspera.assert(file_list.length.even?, exception_class: Cli::BadArgument){"When using pair, provide an even number of paths: #{file_list.length}"}
195
208
  @transfer_paths = file_list.each_slice(2).to_a.map{|s, d|{'source' => s, 'destination' => d}}
196
- else error_unexpected_value(source_type)
209
+ else Aspera.error_unexpected_value(source_type)
197
210
  end
198
211
  Log.log.debug{"paths=#{@transfer_paths}"}
199
212
  return @transfer_paths
@@ -204,14 +217,14 @@ module Aspera
204
217
  # @param rest_token [Rest] if oauth token regeneration supported
205
218
  def start(transfer_spec, rest_token: nil)
206
219
  # check parameters
207
- assert_type(transfer_spec, Hash){'transfer_spec'}
220
+ Aspera.assert_type(transfer_spec, Hash){'transfer_spec'}
208
221
  # process :src option
209
222
  case transfer_spec['direction']
210
- when Fasp::TransferSpec::DIRECTION_RECEIVE
223
+ when Transfer::Spec::DIRECTION_RECEIVE
211
224
  # init default if required in any case
212
225
  @transfer_spec_command_line['destination_root'] ||= destination_folder(transfer_spec['direction'])
213
- when Fasp::TransferSpec::DIRECTION_SEND
214
- if transfer_spec.dig('tags', Fasp::TransferSpec::TAG_RESERVED, 'node', 'access_key')
226
+ when Transfer::Spec::DIRECTION_SEND
227
+ if transfer_spec.dig('tags', Transfer::Spec::TAG_RESERVED, 'node', 'access_key')
215
228
  # gen4
216
229
  @transfer_spec_command_line.delete('destination_root') if @transfer_spec_command_line.key?('destination_root_id')
217
230
  elsif transfer_spec.key?('token')
@@ -26,7 +26,7 @@ module Aspera
26
26
 
27
27
  def event(session_id:, type:, info: nil)
28
28
  Log.log.debug{"progress: #{type} #{session_id} #{info}"}
29
- assert(!session_id.nil? || type.eql?(:pre_start)){'session_id is nil'}
29
+ Aspera.assert(!session_id.nil? || type.eql?(:pre_start)){'session_id is nil'}
30
30
  return if @completed
31
31
  if @progress_bar.nil?
32
32
  @progress_bar = ProgressBar.create(
@@ -4,6 +4,6 @@ module Aspera
4
4
  module Cli
5
5
  # for beta add extension : .beta1
6
6
  # for dev version add extension : .pre
7
- VERSION = '4.16.0'
7
+ VERSION = '4.17.0'
8
8
  end
9
9
  end
data/lib/aspera/colors.rb CHANGED
@@ -53,4 +53,9 @@ class String
53
53
  define_method(name){self}
54
54
  end
55
55
  end
56
+ def capital_to_snake
57
+ return gsub(/([a-z\d])([A-Z])/, '\1_\2')
58
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
59
+ .downcase
60
+ end
56
61
  end