aspera-cli 4.9.0 → 4.11.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 (95) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/BUGS.md +20 -0
  4. data/CHANGELOG.md +509 -0
  5. data/CONTRIBUTING.md +118 -0
  6. data/README.md +1241 -916
  7. data/bin/ascli +4 -4
  8. data/bin/asession +11 -11
  9. data/docs/test_env.conf +32 -21
  10. data/examples/aoc.rb +4 -4
  11. data/examples/dascli +16 -9
  12. data/examples/faspex4.rb +8 -8
  13. data/examples/node.rb +12 -12
  14. data/examples/server.rb +10 -10
  15. data/lib/aspera/aoc.rb +273 -266
  16. data/lib/aspera/ascmd.rb +56 -54
  17. data/lib/aspera/ats_api.rb +4 -4
  18. data/lib/aspera/cli/basic_auth_plugin.rb +15 -12
  19. data/lib/aspera/cli/extended_value.rb +5 -5
  20. data/lib/aspera/cli/formater.rb +64 -64
  21. data/lib/aspera/cli/info.rb +2 -2
  22. data/lib/aspera/cli/listener/line_dump.rb +1 -1
  23. data/lib/aspera/cli/listener/logger.rb +1 -1
  24. data/lib/aspera/cli/listener/progress.rb +5 -6
  25. data/lib/aspera/cli/listener/progress_multi.rb +14 -19
  26. data/lib/aspera/cli/main.rb +66 -67
  27. data/lib/aspera/cli/manager.rb +112 -110
  28. data/lib/aspera/cli/plugin.rb +57 -36
  29. data/lib/aspera/cli/plugins/alee.rb +4 -4
  30. data/lib/aspera/cli/plugins/aoc.rb +309 -670
  31. data/lib/aspera/cli/plugins/ats.rb +44 -46
  32. data/lib/aspera/cli/plugins/bss.rb +10 -10
  33. data/lib/aspera/cli/plugins/config.rb +497 -378
  34. data/lib/aspera/cli/plugins/console.rb +12 -12
  35. data/lib/aspera/cli/plugins/cos.rb +18 -20
  36. data/lib/aspera/cli/plugins/faspex.rb +112 -114
  37. data/lib/aspera/cli/plugins/faspex5.rb +71 -46
  38. data/lib/aspera/cli/plugins/node.rb +379 -283
  39. data/lib/aspera/cli/plugins/orchestrator.rb +46 -46
  40. data/lib/aspera/cli/plugins/preview.rb +122 -114
  41. data/lib/aspera/cli/plugins/server.rb +137 -83
  42. data/lib/aspera/cli/plugins/shares.rb +30 -29
  43. data/lib/aspera/cli/plugins/sync.rb +13 -33
  44. data/lib/aspera/cli/transfer_agent.rb +60 -59
  45. data/lib/aspera/cli/version.rb +1 -1
  46. data/lib/aspera/colors.rb +3 -3
  47. data/lib/aspera/command_line_builder.rb +27 -27
  48. data/lib/aspera/cos_node.rb +22 -20
  49. data/lib/aspera/data_repository.rb +1 -1
  50. data/lib/aspera/environment.rb +35 -15
  51. data/lib/aspera/fasp/agent_base.rb +15 -15
  52. data/lib/aspera/fasp/agent_connect.rb +23 -21
  53. data/lib/aspera/fasp/agent_direct.rb +66 -64
  54. data/lib/aspera/fasp/agent_httpgw.rb +141 -78
  55. data/lib/aspera/fasp/agent_node.rb +23 -21
  56. data/lib/aspera/fasp/agent_trsdk.rb +20 -20
  57. data/lib/aspera/fasp/error.rb +3 -2
  58. data/lib/aspera/fasp/error_info.rb +11 -8
  59. data/lib/aspera/fasp/installation.rb +79 -79
  60. data/lib/aspera/fasp/listener.rb +1 -1
  61. data/lib/aspera/fasp/parameters.rb +86 -71
  62. data/lib/aspera/fasp/parameters.yaml +7 -4
  63. data/lib/aspera/fasp/resume_policy.rb +8 -8
  64. data/lib/aspera/fasp/transfer_spec.rb +35 -2
  65. data/lib/aspera/fasp/uri.rb +7 -7
  66. data/lib/aspera/faspex_gw.rb +7 -5
  67. data/lib/aspera/hash_ext.rb +3 -3
  68. data/lib/aspera/id_generator.rb +5 -5
  69. data/lib/aspera/keychain/encrypted_hash.rb +38 -105
  70. data/lib/aspera/keychain/macos_security.rb +128 -57
  71. data/lib/aspera/log.rb +7 -7
  72. data/lib/aspera/nagios.rb +19 -18
  73. data/lib/aspera/node.rb +209 -35
  74. data/lib/aspera/oauth.rb +37 -36
  75. data/lib/aspera/open_application.rb +19 -11
  76. data/lib/aspera/persistency_action_once.rb +4 -4
  77. data/lib/aspera/persistency_folder.rb +16 -15
  78. data/lib/aspera/preview/file_types.rb +8 -8
  79. data/lib/aspera/preview/generator.rb +67 -67
  80. data/lib/aspera/preview/utils.rb +27 -27
  81. data/lib/aspera/proxy_auto_config.js +41 -41
  82. data/lib/aspera/proxy_auto_config.rb +21 -14
  83. data/lib/aspera/rest.rb +72 -67
  84. data/lib/aspera/rest_call_error.rb +2 -1
  85. data/lib/aspera/rest_error_analyzer.rb +18 -17
  86. data/lib/aspera/rest_errors_aspera.rb +16 -16
  87. data/lib/aspera/secret_hider.rb +15 -13
  88. data/lib/aspera/ssh.rb +11 -10
  89. data/lib/aspera/sync.rb +158 -44
  90. data/lib/aspera/temp_file_manager.rb +2 -2
  91. data/lib/aspera/uri_reader.rb +4 -4
  92. data/lib/aspera/web_auth.rb +14 -13
  93. data.tar.gz.sig +0 -0
  94. metadata +11 -36
  95. metadata.gz.sig +0 -0
@@ -42,9 +42,9 @@ module Aspera
42
42
  </default>
43
43
  </CONF>
44
44
  END_OF_CONFIG_FILE
45
- DUMMY_CERT_INFO='/C=US/ST=California/L=Emeryville/O=Aspera Inc./OU=Corporate/CN=Aspera Inc./emailAddress=info@asperasoft.com'
46
- private_constant :PRODUCT_CONNECT,:PRODUCT_CLI_V1,:PRODUCT_DRIVE,:PRODUCT_ENTSRV,:EXT_RUBY_PROTOBUF,:RB_SDK_FOLDER,
47
- :ONE_YEAR_SECONDS,:DEFAULT_ASPERA_CONF,:DUMMY_CERT_INFO
45
+ DUMMY_CERT_INFO = '/C=US/ST=California/L=Emeryville/O=Aspera Inc./OU=Corporate/CN=Aspera Inc./emailAddress=info@asperasoft.com'
46
+ private_constant :PRODUCT_CONNECT, :PRODUCT_CLI_V1, :PRODUCT_DRIVE, :PRODUCT_ENTSRV, :EXT_RUBY_PROTOBUF, :RB_SDK_FOLDER,
47
+ :ONE_YEAR_SECONDS, :DEFAULT_ASPERA_CONF, :DUMMY_CERT_INFO
48
48
  # set ascp executable path
49
49
  def ascp_path=(v)
50
50
  @path_to_ascp = v
@@ -55,7 +55,7 @@ module Aspera
55
55
  end
56
56
 
57
57
  def sdk_ruby_folder
58
- ruby_pb_folder = File.join(sdk_folder,RB_SDK_FOLDER)
58
+ ruby_pb_folder = File.join(sdk_folder, RB_SDK_FOLDER)
59
59
  FileUtils.mkdir_p(ruby_pb_folder) unless Dir.exist?(ruby_pb_folder)
60
60
  return ruby_pb_folder
61
61
  end
@@ -87,7 +87,7 @@ module Aspera
87
87
  raise "no such product installed: #{product_name}" if pl.nil?
88
88
  end
89
89
  self.ascp_path = pl[:ascp_path]
90
- Log.log.debug("ascp_path=#{@path_to_ascp}")
90
+ Log.log.debug{"ascp_path=#{@path_to_ascp}"}
91
91
  end
92
92
 
93
93
  # @return the list of installed products in format of product_locations
@@ -104,15 +104,15 @@ module Aspera
104
104
  @found_products = scan_locations.select! do |item|
105
105
  # skip if not main folder
106
106
  next false unless Dir.exist?(item[:app_root])
107
- Log.log.debug("Found #{item[:app_root]}")
107
+ Log.log.debug{"Found #{item[:app_root]}"}
108
108
  sub_bin = item[:sub_bin] || BIN_SUBFOLDER
109
- item[:ascp_path] = File.join(item[:app_root],sub_bin,ascp_filename)
109
+ item[:ascp_path] = File.join(item[:app_root], sub_bin, ascp_filename)
110
110
  # skip if no ascp
111
111
  next false unless File.exist?(item[:ascp_path])
112
112
  # read info from product info file if present
113
113
  product_info_file = "#{item[:app_root]}/#{PRODUCT_INFO}"
114
114
  if File.exist?(product_info_file)
115
- res_s = XmlSimple.xml_in(File.read(product_info_file),{'ForceArray' => false})
115
+ res_s = XmlSimple.xml_in(File.read(product_info_file), {'ForceArray' => false})
116
116
  item[:name] = res_s['name']
117
117
  item[:version] = res_s['version']
118
118
  else
@@ -131,20 +131,20 @@ module Aspera
131
131
  # keys and certs are generated locally... (they are well known values, arch. independant)
132
132
  def path(k)
133
133
  case k
134
- when :ascp,:ascp4
134
+ when :ascp, :ascp4
135
135
  use_ascp_from_product(FIRST_FOUND) if @path_to_ascp.nil?
136
136
  file = @path_to_ascp
137
- # note that there might be a .exe at the end
138
- file = file.gsub('ascp','ascp4') if k.eql?(:ascp4)
137
+ # NOTE: that there might be a .exe at the end
138
+ file = file.gsub('ascp', 'ascp4') if k.eql?(:ascp4)
139
139
  when :transferd
140
140
  file = transferd_filepath
141
141
  when :ssh_bypass_key_dsa
142
- file=Environment.write_file_restricted(File.join(sdk_folder,'aspera_bypass_dsa.pem')) {get_key('dsa',1)}
142
+ file = Environment.write_file_restricted(File.join(sdk_folder, 'aspera_bypass_dsa.pem')) {get_key('dsa', 1)}
143
143
  when :ssh_bypass_key_rsa
144
- file=Environment.write_file_restricted(File.join(sdk_folder,'aspera_bypass_rsa.pem')) {get_key('rsa',2)}
144
+ file = Environment.write_file_restricted(File.join(sdk_folder, 'aspera_bypass_rsa.pem')) {get_key('rsa', 2)}
145
145
  when :aspera_license
146
- file=Environment.write_file_restricted(File.join(sdk_folder,'aspera-license')) do
147
- clear=[
146
+ file = Environment.write_file_restricted(File.join(sdk_folder, 'aspera-license')) do
147
+ clear = [
148
148
  Zlib::Inflate.inflate(DataRepository.instance.data(6)),
149
149
  "==SIGNATURE==\n",
150
150
  Base64.strict_encode64(DataRepository.instance.data(7))
@@ -152,10 +152,10 @@ module Aspera
152
152
  Base64.strict_encode64(clear.join)
153
153
  end
154
154
  when :aspera_conf
155
- file=Environment.write_file_restricted(File.join(sdk_folder,'aspera.conf')) {DEFAULT_ASPERA_CONF}
156
- when :fallback_cert,:fallback_key
157
- file_key = File.join(sdk_folder,'aspera_fallback_key.pem')
158
- file_cert = File.join(sdk_folder,'aspera_fallback_cert.pem')
155
+ file = Environment.write_file_restricted(File.join(sdk_folder, 'aspera.conf')) {DEFAULT_ASPERA_CONF}
156
+ when :fallback_cert, :fallback_key
157
+ file_key = File.join(sdk_folder, 'aspera_fallback_key.pem')
158
+ file_cert = File.join(sdk_folder, 'aspera_fallback_cert.pem')
159
159
  if !File.exist?(file_key) || !File.exist?(file_cert)
160
160
  require 'openssl'
161
161
  # create new self signed certificate for http fallback
@@ -182,10 +182,10 @@ module Aspera
182
182
  # @return the file path of local connect where API's URI can be read
183
183
  def connect_uri
184
184
  connect = get_product_folders(PRODUCT_CONNECT)
185
- folder = File.join(connect[:run_root],VARRUN_SUBFOLDER)
186
- ['','s'].each do |ext|
187
- uri_file = File.join(folder,"http#{ext}.uri")
188
- Log.log.debug("checking connect port file: #{uri_file}")
185
+ folder = File.join(connect[:run_root], VARRUN_SUBFOLDER)
186
+ ['', 's'].each do |ext|
187
+ uri_file = File.join(folder, "http#{ext}.uri")
188
+ Log.log.debug{"checking connect port file: #{uri_file}"}
189
189
  if File.exist?(uri_file)
190
190
  return File.open(uri_file, &:gets).strip
191
191
  end
@@ -196,12 +196,12 @@ module Aspera
196
196
  # @ return path to configuration file of aspera CLI
197
197
  def cli_conf_file
198
198
  connect = get_product_folders(PRODUCT_CLI_V1)
199
- return File.join(connect[:app_root],BIN_SUBFOLDER,'.aspera_cli_conf')
199
+ return File.join(connect[:app_root], BIN_SUBFOLDER, '.aspera_cli_conf')
200
200
  end
201
201
 
202
202
  # default bypass key phrase
203
203
  def bypass_pass
204
- return format('%08x-%04x-%04x-%04x-%04x%08x',*DataRepository.instance.data(3).unpack('NnnnnN'))
204
+ return format('%08x-%04x-%04x-%04x-%04x%08x', *DataRepository.instance.data(3).unpack('NnnnnN'))
205
205
  end
206
206
 
207
207
  def bypass_keys
@@ -210,16 +210,16 @@ module Aspera
210
210
 
211
211
  # use in plugin `config`
212
212
  def get_ascp_version(exe_path)
213
- return get_exe_version(exe_path,'-A')
213
+ return get_exe_version(exe_path, '-A')
214
214
  end
215
215
 
216
216
  # Check that specified path is ascp and get version
217
- def get_exe_version(exe_path,vers_arg)
217
+ def get_exe_version(exe_path, vers_arg)
218
218
  raise 'ERROR: nil arg' if exe_path.nil?
219
219
  return nil unless File.exist?(exe_path)
220
220
  exe_version = nil
221
221
  cmd_out = %x("#{exe_path}" #{vers_arg})
222
- raise "An error occured when testing #{ascp_filename}: #{cmd_out}" unless $CHILD_STATUS == 0
222
+ raise "An error occurred when testing #{ascp_filename}: #{cmd_out}" unless $CHILD_STATUS == 0
223
223
  # get version from ascp, only after full extract, as windows requires DLLs (SSL/TLS/etc...)
224
224
  m = cmd_out.match(/ version ([0-9.]+)/)
225
225
  exe_version = m[1] unless m.nil?
@@ -233,18 +233,18 @@ module Aspera
233
233
  # SDK is organized by architecture, check this first, in case architecture is not supported
234
234
  arch_filter = "#{Environment.architecture}/"
235
235
  require 'zip'
236
- sdk_zip_path = File.join(Dir.tmpdir,'sdk.zip')
236
+ sdk_zip_path = File.join(Dir.tmpdir, 'sdk.zip')
237
237
  if sdk_url.start_with?('file:')
238
238
  # require specific file scheme: the path part is "relative", or absolute if there are 4 slash
239
239
  raise 'use format: file:///<path>' unless sdk_url.start_with?('file:///')
240
- sdk_zip_path = sdk_url.gsub(%r{^file:///},'')
240
+ sdk_zip_path = sdk_url.gsub(%r{^file:///}, '')
241
241
  else
242
- Aspera::Rest.new(base_url: sdk_url, redirect_max: 3).call(operation: 'GET',save_to_file: sdk_zip_path)
242
+ Aspera::Rest.new(base_url: sdk_url, redirect_max: 3).call(operation: 'GET', save_to_file: sdk_zip_path)
243
243
  end
244
244
  # rename old install
245
245
  if !Dir.empty?(sdk_folder)
246
246
  Log.log.warn('Previous install exists, renaming folder.')
247
- File.rename(sdk_folder,"#{sdk_folder}.#{Time.now.strftime('%Y%m%d%H%M%S')}")
247
+ File.rename(sdk_folder, "#{sdk_folder}.#{Time.now.strftime('%Y%m%d%H%M%S')}")
248
248
  # TODO: delete old archives ?
249
249
  end
250
250
  # extract files from archive
@@ -258,7 +258,7 @@ module Aspera
258
258
  # ruby adapters
259
259
  dest_folder = sdk_ruby_folder if entry.name.end_with?(EXT_RUBY_PROTOBUF)
260
260
  next if dest_folder.nil?
261
- File.open(File.join(dest_folder,File.basename(entry.name)), 'wb') do |output_stream|
261
+ File.open(File.join(dest_folder, File.basename(entry.name)), 'wb') do |output_stream|
262
262
  IO.copy_stream(entry.get_input_stream, output_stream)
263
263
  end
264
264
  end
@@ -267,17 +267,17 @@ module Aspera
267
267
  # ensure license file are generated so that ascp invokation for version works
268
268
  path(:aspera_license)
269
269
  path(:aspera_conf)
270
- ascp_path = File.join(sdk_folder,ascp_filename)
270
+ ascp_path = File.join(sdk_folder, ascp_filename)
271
271
  raise "No #{ascp_filename} found in SDK archive" unless File.exist?(ascp_path)
272
- FileUtils.chmod(0755,ascp_path)
273
- FileUtils.chmod(0755,ascp_path.gsub('ascp','ascp4'))
274
- ascp_version = get_ascp_version(File.join(sdk_folder,ascp_filename))
272
+ Environment.restrict_file_access(ascp_path, mode: 0o755)
273
+ Environment.restrict_file_access(ascp_path.gsub('ascp', 'ascp4'), mode: 0o755)
274
+ ascp_version = get_ascp_version(File.join(sdk_folder, ascp_filename))
275
275
  trd_path = transferd_filepath
276
- Log.log.warn("No #{trd_path} in SDK archive") unless File.exist?(trd_path)
277
- FileUtils.chmod(0755,trd_path) if File.exist?(trd_path)
278
- transferd_version = get_exe_version(trd_path,'version')
276
+ Log.log.warn{"No #{trd_path} in SDK archive"} unless File.exist?(trd_path)
277
+ Environment.restrict_file_access(trd_path, mode: 0o755) if File.exist?(trd_path)
278
+ transferd_version = get_exe_version(trd_path, 'version')
279
279
  sdk_version = transferd_version || ascp_version
280
- File.write(File.join(sdk_folder,PRODUCT_INFO),"<product><name>IBM Aspera SDK</name><version>#{sdk_version}</version></product>")
280
+ File.write(File.join(sdk_folder, PRODUCT_INFO), "<product><name>IBM Aspera SDK</name><version>#{sdk_version}</version></product>")
281
281
  return sdk_version
282
282
  end
283
283
 
@@ -285,13 +285,13 @@ module Aspera
285
285
 
286
286
  BIN_SUBFOLDER = 'bin'
287
287
  ETC_SUBFOLDER = 'etc'
288
- VARRUN_SUBFOLDER = File.join('var','run')
288
+ VARRUN_SUBFOLDER = File.join('var', 'run')
289
289
  # product information manifest: XML (part of aspera product)
290
290
  PRODUCT_INFO = 'product-info.mf'
291
291
  # policy for product selection
292
292
  FIRST_FOUND = 'FIRST'
293
293
 
294
- private_constant :BIN_SUBFOLDER,:ETC_SUBFOLDER,:VARRUN_SUBFOLDER,:PRODUCT_INFO
294
+ private_constant :BIN_SUBFOLDER, :ETC_SUBFOLDER, :VARRUN_SUBFOLDER, :PRODUCT_INFO
295
295
 
296
296
  def initialize
297
297
  @path_to_ascp = nil
@@ -313,7 +313,7 @@ module Aspera
313
313
  end
314
314
 
315
315
  def transferd_filepath
316
- return File.join(sdk_folder,'asperatransferd' + Environment.exe_extension)
316
+ return File.join(sdk_folder, 'asperatransferd' + Environment.exe_extension)
317
317
  end
318
318
 
319
319
  # @return product folders depending on OS fields
@@ -326,54 +326,54 @@ module Aspera
326
326
  case Aspera::Environment.os
327
327
  when Aspera::Environment::OS_WINDOWS; return [{
328
328
  expected: PRODUCT_CONNECT,
329
- app_root: File.join(ENV['LOCALAPPDATA'],'Programs','Aspera','Aspera Connect'),
330
- log_root: File.join(ENV['LOCALAPPDATA'],'Aspera','Aspera Connect','var','log'),
331
- run_root: File.join(ENV['LOCALAPPDATA'],'Aspera','Aspera Connect')
332
- },{
329
+ app_root: File.join(ENV['LOCALAPPDATA'], 'Programs', 'Aspera', 'Aspera Connect'),
330
+ log_root: File.join(ENV['LOCALAPPDATA'], 'Aspera', 'Aspera Connect', 'var', 'log'),
331
+ run_root: File.join(ENV['LOCALAPPDATA'], 'Aspera', 'Aspera Connect')
332
+ }, {
333
333
  expected: PRODUCT_CLI_V1,
334
- app_root: File.join('C:','Program Files','Aspera','cli'),
335
- log_root: File.join('C:','Program Files','Aspera','cli','var','log')
336
- },{
334
+ app_root: File.join('C:', 'Program Files', 'Aspera', 'cli'),
335
+ log_root: File.join('C:', 'Program Files', 'Aspera', 'cli', 'var', 'log')
336
+ }, {
337
337
  expected: PRODUCT_ENTSRV,
338
- app_root: File.join('C:','Program Files','Aspera','Enterprise Server'),
339
- log_root: File.join('C:','Program Files','Aspera','Enterprise Server','var','log')
338
+ app_root: File.join('C:', 'Program Files', 'Aspera', 'Enterprise Server'),
339
+ log_root: File.join('C:', 'Program Files', 'Aspera', 'Enterprise Server', 'var', 'log')
340
340
  }]
341
341
  when Aspera::Environment::OS_X; return [{
342
342
  expected: PRODUCT_CONNECT,
343
- app_root: File.join(Dir.home,'Applications','Aspera Connect.app'),
344
- log_root: File.join(Dir.home,'Library','Logs','Aspera_Connect'),
345
- run_root: File.join(Dir.home,'Library','Application Support','Aspera','Aspera Connect'),
346
- sub_bin: File.join('Contents','Resources')
347
- },{
343
+ app_root: File.join(Dir.home, 'Applications', 'Aspera Connect.app'),
344
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Connect'),
345
+ run_root: File.join(Dir.home, 'Library', 'Application Support', 'Aspera', 'Aspera Connect'),
346
+ sub_bin: File.join('Contents', 'Resources')
347
+ }, {
348
348
  expected: PRODUCT_CONNECT,
349
- app_root: File.join('','Applications','Aspera Connect.app'),
350
- log_root: File.join(Dir.home,'Library','Logs','Aspera_Connect'),
351
- run_root: File.join(Dir.home,'Library','Application Support','Aspera','Aspera Connect'),
352
- sub_bin: File.join('Contents','Resources')
353
- },{
349
+ app_root: File.join('', 'Applications', 'Aspera Connect.app'),
350
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Connect'),
351
+ run_root: File.join(Dir.home, 'Library', 'Application Support', 'Aspera', 'Aspera Connect'),
352
+ sub_bin: File.join('Contents', 'Resources')
353
+ }, {
354
354
  expected: PRODUCT_CLI_V1,
355
- app_root: File.join(Dir.home,'Applications','Aspera CLI'),
356
- log_root: File.join(Dir.home,'Library','Logs','Aspera')
357
- },{
355
+ app_root: File.join(Dir.home, 'Applications', 'Aspera CLI'),
356
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera')
357
+ }, {
358
358
  expected: PRODUCT_ENTSRV,
359
- app_root: File.join('','Library','Aspera'),
360
- log_root: File.join(Dir.home,'Library','Logs','Aspera')
361
- },{
359
+ app_root: File.join('', 'Library', 'Aspera'),
360
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera')
361
+ }, {
362
362
  expected: PRODUCT_DRIVE,
363
- app_root: File.join('','Applications','Aspera Drive.app'),
364
- log_root: File.join(Dir.home,'Library','Logs','Aspera_Drive'),
365
- sub_bin: File.join('Contents','Resources')
363
+ app_root: File.join('', 'Applications', 'Aspera Drive.app'),
364
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Drive'),
365
+ sub_bin: File.join('Contents', 'Resources')
366
366
  }]
367
367
  else; return [{ # other: Linux and Unix family
368
368
  expected: PRODUCT_CONNECT,
369
- app_root: File.join(Dir.home,'.aspera','connect'),
370
- run_root: File.join(Dir.home,'.aspera','connect')
371
- },{
369
+ app_root: File.join(Dir.home, '.aspera', 'connect'),
370
+ run_root: File.join(Dir.home, '.aspera', 'connect')
371
+ }, {
372
372
  expected: PRODUCT_CLI_V1,
373
- app_root: File.join(Dir.home,'.aspera','cli')
374
- },{
373
+ app_root: File.join(Dir.home, '.aspera', 'cli')
374
+ }, {
375
375
  expected: PRODUCT_ENTSRV,
376
- app_root: File.join('','opt','aspera')
376
+ app_root: File.join('', 'opt', 'aspera')
377
377
  }]
378
378
  end
379
379
  end
@@ -381,7 +381,7 @@ module Aspera
381
381
  # @return a standard bypass key
382
382
  # @param type rsa or dsa
383
383
  # @param id in repository 1 for dsa, 2 for rsa
384
- def get_key(type,id)
384
+ def get_key(type, id)
385
385
  # generate PEM from DER
386
386
  OpenSSL::PKey.const_get(type.upcase).new(DataRepository.instance.data(id)).to_pem
387
387
  end
@@ -3,7 +3,7 @@
3
3
  module Aspera
4
4
  module Fasp
5
5
  # imlement this class to get transfer events
6
- class Listener
6
+ class Listener # rubocop:disable Lint/EmptyClass
7
7
  # define one of the following methods:
8
8
  # event_text(text_data)
9
9
  # event_struct(legacy_names)
@@ -31,39 +31,52 @@ module Aspera
31
31
  def description
32
32
  if @param_description_cache.nil?
33
33
  # config file in same folder with same name as this source
34
- description_from_yaml=YAML.load_file("#{__FILE__[0..-3]}yaml")
34
+ description_from_yaml = YAML.load_file("#{__FILE__[0..-3]}yaml")
35
35
  @param_description_cache = Aspera::CommandLineBuilder.normalize_description(description_from_yaml)
36
36
  end
37
37
  return @param_description_cache
38
38
  end
39
39
 
40
40
  # @return a table suitable to display in manual
41
- def man_table
41
+ def man_table(to_text: true)
42
42
  result = []
43
- description.each do |k,i|
44
- param = {name: k, type: [i[:accepted_types]].flatten.join(','),description: i[:desc]}
43
+ description.each do |k, i|
44
+ param = {name: k, type: [i[:accepted_types]].flatten.join(','), description: i[:desc]}
45
45
  # add flags for supported agents in doc
46
46
  SUPPORTED_AGENTS.each do |a|
47
47
  param[a.to_s[0].to_sym] = i[:tragents].nil? || i[:tragents].include?(a) ? 'Y' : ''
48
48
  end
49
49
  # only keep lines that are usable in supported agents
50
- next if SUPPORTED_AGENTS_SHORT.inject(true){|m,j|m && param[j].empty?}
50
+ next if SUPPORTED_AGENTS_SHORT.inject(true){|m, j|m && param[j].empty?}
51
51
  param[:cli] =
52
52
  case i[:cltype]
53
53
  when :envvar then 'env:' + i[:clvarname]
54
- when :opt_without_arg,:opt_with_arg then i[:clswitch]
54
+ when :opt_without_arg then i[:clswitch]
55
+ when :opt_with_arg
56
+ values = if i.key?(:enum)
57
+ ['enum']
58
+ elsif i[:accepted_types].is_a?(Array)
59
+ i[:accepted_types]
60
+ elsif !i[:accepted_types].nil?
61
+ [i[:accepted_types]]
62
+ else
63
+ raise "error: #{param}"
64
+ end.map{|n|"{#{n}}"}.join('|')
65
+ conv = i.key?(:clconvert) ? '(conversion)' : ''
66
+ "#{i[:clswitch]} #{conv}#{values}"
55
67
  else ''
56
68
  end
57
- if i.has_key?(:enum)
69
+ if i.key?(:enum)
58
70
  param[:description] += "\nAllowed values: #{i[:enum].join(', ')}"
59
71
  end
72
+ param[:description] = param[:description].gsub('&sol;', '/') if to_text
60
73
  result.push(param)
61
74
  end
62
75
  return result
63
76
  end
64
77
 
65
78
  # special encoding methods used in YAML (key: :clconvert)
66
- def clconv_remove_hyphen(v); v.tr('-',''); end
79
+ def clconv_remove_hyphen(v); v.tr('-', ''); end
67
80
 
68
81
  # special encoding methods used in YAML (key: :clconvert)
69
82
  def clconv_json64(v); Base64.strict_encode64(JSON.generate(v)); end
@@ -73,13 +86,13 @@ module Aspera
73
86
 
74
87
  # file list is provided directly with ascp arguments
75
88
  def ts_has_ascp_file_list(ts)
76
- (ts['EX_ascp_args'].is_a?(Array) && ['--file-list','--file-pair-list'].any?{|i|ts['EX_ascp_args'].include?(i)}) ||
77
- ts.has_key?('EX_file_list') ||
78
- ts.has_key?('EX_file_pair_list')
89
+ (ts['EX_ascp_args'].is_a?(Array) && ['--file-list', '--file-pair-list'].any?{|i|ts['EX_ascp_args'].include?(i)}) ||
90
+ ts.key?('EX_file_list') ||
91
+ ts.key?('EX_file_pair_list')
79
92
  end
80
93
 
81
- def ts_to_env_args(transfer_spec,options)
82
- return Parameters.new(transfer_spec,options).ascp_args
94
+ def ts_to_env_args(transfer_spec, options)
95
+ return Parameters.new(transfer_spec, options).ascp_args
83
96
  end
84
97
 
85
98
  # temp file list files are created here
@@ -95,11 +108,56 @@ module Aspera
95
108
  end # self
96
109
 
97
110
  # @param options [Hash] key: :wss: bool
98
- def initialize(job_spec,options)
111
+ def initialize(job_spec, options)
99
112
  @job_spec = job_spec
100
113
  @options = options
101
- @builder = Aspera::CommandLineBuilder.new(@job_spec,self.class.description)
102
- Log.log.debug("agent options: #{@options}")
114
+ @builder = Aspera::CommandLineBuilder.new(@job_spec, self.class.description)
115
+ Log.log.debug{"agent options: #{@options}"}
116
+ end
117
+
118
+ def process_file_list
119
+ # is the file list provided through EX_ parameters?
120
+ ascp_file_list_provided = self.class.ts_has_ascp_file_list(@job_spec)
121
+ # set if paths is mandatory in ts
122
+ @builder.params_definition['paths'][:mandatory] = !@job_spec.key?('keepalive') && !ascp_file_list_provided
123
+ # get paths in transfer spec (after setting if it is mandatory)
124
+ ts_paths_array = @builder.process_param('paths', :get_value)
125
+ if ascp_file_list_provided && !ts_paths_array.nil?
126
+ raise 'file list provided both in transfer spec and ascp file list. Remove one of them.'
127
+ end
128
+ # option 1: EX_file_list
129
+ file_list_file = @builder.process_param('EX_file_list', :get_value)
130
+ if file_list_file.nil?
131
+ # option 2: EX_file_pair_list
132
+ file_list_file = @builder.process_param('EX_file_pair_list', :get_value)
133
+ if !file_list_file.nil?
134
+ option = '--file-pair-list'
135
+ elsif !ts_paths_array.nil?
136
+ # option 3: in TS, it is an array
137
+ if self.class.file_list_folder.nil?
138
+ # not safe for special characters ? (maybe not, depends on OS)
139
+ Log.log.debug('placing source file list on command line (no file list file)')
140
+ @builder.add_command_line_options(ts_paths_array.map{|i|i['source']})
141
+ else
142
+ # safer option: generate a file list file if there is storage defined for it
143
+ # if there is destination in paths, then use filepairlist
144
+ # TODO: well, we test only the first one, but anyway it shall be consistent
145
+ if ts_paths_array.first.key?('destination')
146
+ option = '--file-pair-list'
147
+ lines = ts_paths_array.each_with_object([]){|e, m|m.push(e['source'], e['destination']); }
148
+ else
149
+ option = '--file-list'
150
+ lines = ts_paths_array.map{|i|i['source']}
151
+ end
152
+ file_list_file = Aspera::TempFileManager.instance.new_file_path_in_folder(self.class.file_list_folder)
153
+ File.write(file_list_file, lines.join("\n"))
154
+ Log.log.debug{"#{option}=\n#{File.read(file_list_file)}".red}
155
+ end
156
+ end
157
+ else
158
+ option = '--file-list'
159
+ end
160
+ @builder.add_command_line_options(["#{option}=#{file_list_file}"]) unless option.nil?
103
161
  end
104
162
 
105
163
  # translate transfer spec to env vars and command line arguments for ascp
@@ -111,22 +169,22 @@ module Aspera
111
169
  ascp_version: :ascp
112
170
  }
113
171
  # some ssh credentials are required to avoid interactive password input
114
- if !@job_spec.has_key?('remote_password') &&
115
- !@job_spec.has_key?('ssh_private_key') &&
116
- !@job_spec.has_key?('EX_ssh_key_paths')
172
+ if !@job_spec.key?('remote_password') &&
173
+ !@job_spec.key?('ssh_private_key') &&
174
+ !@job_spec.key?('EX_ssh_key_paths')
117
175
  raise Fasp::Error, 'required: password or ssh key (value or path)'
118
176
  end
119
177
 
120
178
  # special cases
121
- @job_spec.delete('source_root') if @job_spec.has_key?('source_root') && @job_spec['source_root'].empty?
179
+ @job_spec.delete('source_root') if @job_spec.key?('source_root') && @job_spec['source_root'].empty?
122
180
 
123
181
  # use web socket session initiation ?
124
- if @builder.process_param('wss_enabled',:get_value) && (@options[:wss] || !@job_spec.has_key?('fasp_port'))
182
+ if @builder.process_param('wss_enabled', :get_value) && (@options[:wss] || !@job_spec.key?('fasp_port'))
125
183
  # by default use web socket session if available, unless removed by user
126
184
  @builder.add_command_line_options(['--ws-connect'])
127
185
  # TODO: option to give order ssh,ws (legacy http is implied bu ssh)
128
186
  # quel bordel:
129
- @job_spec['ssh_port'] = @builder.process_param('wss_port',:get_value)
187
+ @job_spec['ssh_port'] = @builder.process_param('wss_port', :get_value)
130
188
  @job_spec.delete('fasp_port')
131
189
  @job_spec.delete('EX_ssh_key_paths')
132
190
  @job_spec.delete('sshfp')
@@ -142,68 +200,25 @@ module Aspera
142
200
  @builder.process_params
143
201
 
144
202
  # symbol must be index of Installation.paths
145
- if @builder.process_param('use_ascp4',:get_value)
203
+ if @builder.process_param('use_ascp4', :get_value)
146
204
  env_args[:ascp_version] = :ascp4
147
205
  else
148
206
  env_args[:ascp_version] = :ascp
149
207
  # destination will be base64 encoded, put before path arguments
150
208
  @builder.add_command_line_options(['--dest64'])
151
209
  end
152
- # process file lists
153
- begin
154
- # is the file list provided through EX_ parameters?
155
- ascp_file_list_provided = self.class.ts_has_ascp_file_list(@job_spec)
156
- # set if paths is mandatory in ts
157
- @builder.params_definition['paths'][:mandatory] = !@job_spec.has_key?('keepalive') && !ascp_file_list_provided
158
- # get paths in transfer spec (after setting if it is mandatory)
159
- ts_paths_array = @builder.process_param('paths',:get_value)
160
- if ascp_file_list_provided && !ts_paths_array.nil?
161
- raise 'file list provided both in transfer spec and ascp file list. Remove one of them.'
162
- end
163
- # option 1: EX_file_list
164
- file_list_file = @builder.process_param('EX_file_list',:get_value)
165
- if !file_list_file.nil?
166
- option = '--file-list'
167
- else
168
- # option 2: EX_file_pair_list
169
- file_list_file = @builder.process_param('EX_file_pair_list',:get_value)
170
- if !file_list_file.nil?
171
- option = '--file-pair-list'
172
- elsif !ts_paths_array.nil?
173
- # option 3: in TS, it is an array
174
- if !self.class.file_list_folder.nil?
175
- # safer option: generate a file list file if there is storage defined for it
176
- # if there is destination in paths, then use filepairlist
177
- # TODO: well, we test only the first one, but anyway it shall be consistent
178
- if ts_paths_array.first.has_key?('destination')
179
- option = '--file-pair-list'
180
- lines = ts_paths_array.each_with_object([]){|e,m|m.push(e['source'],e['destination']);}
181
- else
182
- option = '--file-list'
183
- lines = ts_paths_array.map{|i|i['source']}
184
- end
185
- file_list_file = Aspera::TempFileManager.instance.new_file_path_in_folder(self.class.file_list_folder)
186
- File.write(file_list_file, lines.join("\n"))
187
- Log.log.debug{"#{option}=\n#{File.read(file_list_file)}".red}
188
- else
189
- # not safe for special characters ? (maybe not, depends on OS)
190
- Log.log.debug('placing source file list on command line (no file list file)')
191
- @builder.add_command_line_options(ts_paths_array.map{|i|i['source']})
192
- end
193
- end
194
- end
195
- @builder.add_command_line_options(["#{option}=#{file_list_file}"]) unless option.nil?
196
- end
210
+ # get list of files to transfer and build arg for ascp
211
+ process_file_list
197
212
  # optional args, at the end to override previous ones (to allow override)
198
- @builder.add_command_line_options(@builder.process_param('EX_ascp_args',:get_value))
213
+ @builder.add_command_line_options(@builder.process_param('EX_ascp_args', :get_value))
199
214
  # process destination folder
200
- destination_folder = @builder.process_param('destination_root',:get_value) || '/'
215
+ destination_folder = @builder.process_param('destination_root', :get_value) || '/'
201
216
  # ascp4 does not support base64 encoding of destination
202
217
  destination_folder = Base64.strict_encode64(destination_folder) unless env_args[:ascp_version].eql?(:ascp4)
203
218
  # destination MUST be last command line argument to ascp
204
219
  @builder.add_command_line_options([destination_folder])
205
220
 
206
- @builder.add_env_args(env_args[:env],env_args[:args])
221
+ @builder.add_env_args(env_args[:env], env_args[:args])
207
222
 
208
223
  return env_args
209
224
  end
@@ -4,7 +4,7 @@
4
4
  # enum : set with list of values for enum types accepted in transfer spec
5
5
  # tragents : supported agents (for doc only)
6
6
  # required : optional, default: false
7
- # cltype : ascp: type of parameter
7
+ # cltype : ascp: type of parameter: :opt_with_arg,:opt_without_arg,:envvar,:defer,:ignore,
8
8
  # clswitch : ascp: switch for ascp command line
9
9
  # clconvert : ascp: transform value: either a Hash with conversion values, or name of class
10
10
  # clvarname : ascp: name of env var
@@ -144,8 +144,11 @@ https_fallback_port:
144
144
  :cltype: :opt_with_arg
145
145
  :clswitch: "-t"
146
146
  move_after_transfer:
147
- :desc: The relative path to which the files will be moved after the transfer at the source side.
147
+ :desc: The relative path to which the files will be moved after the transfer at the source side. Available as of 3.8.0.
148
148
  :cltype: :opt_with_arg
149
+ :tragents:
150
+ - :direct
151
+ - :node
149
152
  multi_session:
150
153
  :desc: |
151
154
  Use multi-session transfer. max 128.
@@ -310,8 +313,8 @@ ssh_port:
310
313
  ssh_private_key:
311
314
  :desc: |-
312
315
  Private key used for SSH authentication.
313
- Shall look like: -----BEGIN RSA PRIV4TE KEY-----\nMII...
314
- Note the JSON encoding: \n for newlines.
316
+ Shall look like: -----BEGIN RSA PRIV4TE KEY-----&sol;nMII...
317
+ Note the JSON encoding: &sol;n for newlines.
315
318
 
316
319
 
317
320
  :tragents: