aspera-cli 4.10.0 → 4.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) 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 +621 -378
  7. data/bin/ascli +4 -4
  8. data/bin/asession +11 -11
  9. data/docs/test_env.conf +28 -19
  10. data/examples/aoc.rb +4 -4
  11. data/examples/dascli +11 -9
  12. data/examples/faspex4.rb +8 -8
  13. data/examples/node.rb +11 -11
  14. data/examples/server.rb +9 -9
  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/listener/line_dump.rb +1 -1
  22. data/lib/aspera/cli/listener/logger.rb +1 -1
  23. data/lib/aspera/cli/listener/progress.rb +5 -6
  24. data/lib/aspera/cli/listener/progress_multi.rb +14 -19
  25. data/lib/aspera/cli/main.rb +66 -67
  26. data/lib/aspera/cli/manager.rb +110 -110
  27. data/lib/aspera/cli/plugin.rb +54 -37
  28. data/lib/aspera/cli/plugins/alee.rb +4 -4
  29. data/lib/aspera/cli/plugins/aoc.rb +308 -669
  30. data/lib/aspera/cli/plugins/ats.rb +44 -46
  31. data/lib/aspera/cli/plugins/bss.rb +10 -10
  32. data/lib/aspera/cli/plugins/config.rb +447 -344
  33. data/lib/aspera/cli/plugins/console.rb +12 -12
  34. data/lib/aspera/cli/plugins/cos.rb +18 -20
  35. data/lib/aspera/cli/plugins/faspex.rb +110 -112
  36. data/lib/aspera/cli/plugins/faspex5.rb +67 -46
  37. data/lib/aspera/cli/plugins/node.rb +364 -288
  38. data/lib/aspera/cli/plugins/orchestrator.rb +46 -46
  39. data/lib/aspera/cli/plugins/preview.rb +122 -114
  40. data/lib/aspera/cli/plugins/server.rb +137 -83
  41. data/lib/aspera/cli/plugins/shares.rb +30 -29
  42. data/lib/aspera/cli/plugins/sync.rb +13 -33
  43. data/lib/aspera/cli/transfer_agent.rb +57 -57
  44. data/lib/aspera/cli/version.rb +1 -1
  45. data/lib/aspera/colors.rb +3 -3
  46. data/lib/aspera/command_line_builder.rb +27 -27
  47. data/lib/aspera/cos_node.rb +22 -20
  48. data/lib/aspera/data_repository.rb +1 -1
  49. data/lib/aspera/environment.rb +30 -28
  50. data/lib/aspera/fasp/agent_base.rb +15 -15
  51. data/lib/aspera/fasp/agent_connect.rb +23 -21
  52. data/lib/aspera/fasp/agent_direct.rb +65 -67
  53. data/lib/aspera/fasp/agent_httpgw.rb +72 -68
  54. data/lib/aspera/fasp/agent_node.rb +23 -21
  55. data/lib/aspera/fasp/agent_trsdk.rb +20 -20
  56. data/lib/aspera/fasp/error.rb +3 -2
  57. data/lib/aspera/fasp/error_info.rb +11 -8
  58. data/lib/aspera/fasp/installation.rb +78 -78
  59. data/lib/aspera/fasp/listener.rb +1 -1
  60. data/lib/aspera/fasp/parameters.rb +75 -72
  61. data/lib/aspera/fasp/parameters.yaml +2 -2
  62. data/lib/aspera/fasp/resume_policy.rb +8 -8
  63. data/lib/aspera/fasp/transfer_spec.rb +35 -2
  64. data/lib/aspera/fasp/uri.rb +7 -7
  65. data/lib/aspera/faspex_gw.rb +7 -5
  66. data/lib/aspera/hash_ext.rb +3 -3
  67. data/lib/aspera/id_generator.rb +5 -5
  68. data/lib/aspera/keychain/encrypted_hash.rb +23 -28
  69. data/lib/aspera/keychain/macos_security.rb +21 -20
  70. data/lib/aspera/log.rb +7 -7
  71. data/lib/aspera/nagios.rb +19 -18
  72. data/lib/aspera/node.rb +209 -35
  73. data/lib/aspera/oauth.rb +37 -36
  74. data/lib/aspera/open_application.rb +19 -11
  75. data/lib/aspera/persistency_action_once.rb +4 -4
  76. data/lib/aspera/persistency_folder.rb +13 -13
  77. data/lib/aspera/preview/file_types.rb +8 -8
  78. data/lib/aspera/preview/generator.rb +67 -67
  79. data/lib/aspera/preview/utils.rb +27 -27
  80. data/lib/aspera/proxy_auto_config.js +41 -41
  81. data/lib/aspera/proxy_auto_config.rb +16 -16
  82. data/lib/aspera/rest.rb +56 -60
  83. data/lib/aspera/rest_call_error.rb +2 -1
  84. data/lib/aspera/rest_error_analyzer.rb +18 -17
  85. data/lib/aspera/rest_errors_aspera.rb +16 -16
  86. data/lib/aspera/secret_hider.rb +15 -13
  87. data/lib/aspera/ssh.rb +11 -10
  88. data/lib/aspera/sync.rb +158 -44
  89. data/lib/aspera/temp_file_manager.rb +2 -2
  90. data/lib/aspera/uri_reader.rb +4 -4
  91. data/lib/aspera/web_auth.rb +14 -13
  92. data.tar.gz.sig +0 -0
  93. metadata +8 -5
  94. 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,11 +210,11 @@ 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
@@ -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
- Environment.restrict_file_access(ascp_path, mode: 0755)
273
- Environment.restrict_file_access(ascp_path.gsub('ascp','ascp4'), mode: 0755)
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
- Environment.restrict_file_access(trd_path, mode: 0755) 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,29 +31,29 @@ 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
54
  when :opt_without_arg then i[:clswitch]
55
55
  when :opt_with_arg
56
- values=if i.has_key?(:enum)
56
+ values = if i.key?(:enum)
57
57
  ['enum']
58
58
  elsif i[:accepted_types].is_a?(Array)
59
59
  i[:accepted_types]
@@ -62,20 +62,21 @@ module Aspera
62
62
  else
63
63
  raise "error: #{param}"
64
64
  end.map{|n|"{#{n}}"}.join('|')
65
- conv=i.has_key?(:clconvert) ? '(conversion)' : ''
65
+ conv = i.key?(:clconvert) ? '(conversion)' : ''
66
66
  "#{i[:clswitch]} #{conv}#{values}"
67
67
  else ''
68
68
  end
69
- if i.has_key?(:enum)
69
+ if i.key?(:enum)
70
70
  param[:description] += "\nAllowed values: #{i[:enum].join(', ')}"
71
71
  end
72
+ param[:description] = param[:description].gsub('&sol;', '/') if to_text
72
73
  result.push(param)
73
74
  end
74
75
  return result
75
76
  end
76
77
 
77
78
  # special encoding methods used in YAML (key: :clconvert)
78
- def clconv_remove_hyphen(v); v.tr('-',''); end
79
+ def clconv_remove_hyphen(v); v.tr('-', ''); end
79
80
 
80
81
  # special encoding methods used in YAML (key: :clconvert)
81
82
  def clconv_json64(v); Base64.strict_encode64(JSON.generate(v)); end
@@ -85,13 +86,13 @@ module Aspera
85
86
 
86
87
  # file list is provided directly with ascp arguments
87
88
  def ts_has_ascp_file_list(ts)
88
- (ts['EX_ascp_args'].is_a?(Array) && ['--file-list','--file-pair-list'].any?{|i|ts['EX_ascp_args'].include?(i)}) ||
89
- ts.has_key?('EX_file_list') ||
90
- 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')
91
92
  end
92
93
 
93
- def ts_to_env_args(transfer_spec,options)
94
- 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
95
96
  end
96
97
 
97
98
  # temp file list files are created here
@@ -107,11 +108,56 @@ module Aspera
107
108
  end # self
108
109
 
109
110
  # @param options [Hash] key: :wss: bool
110
- def initialize(job_spec,options)
111
+ def initialize(job_spec, options)
111
112
  @job_spec = job_spec
112
113
  @options = options
113
- @builder = Aspera::CommandLineBuilder.new(@job_spec,self.class.description)
114
- 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?
115
161
  end
116
162
 
117
163
  # translate transfer spec to env vars and command line arguments for ascp
@@ -123,22 +169,22 @@ module Aspera
123
169
  ascp_version: :ascp
124
170
  }
125
171
  # some ssh credentials are required to avoid interactive password input
126
- if !@job_spec.has_key?('remote_password') &&
127
- !@job_spec.has_key?('ssh_private_key') &&
128
- !@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')
129
175
  raise Fasp::Error, 'required: password or ssh key (value or path)'
130
176
  end
131
177
 
132
178
  # special cases
133
- @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?
134
180
 
135
181
  # use web socket session initiation ?
136
- 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'))
137
183
  # by default use web socket session if available, unless removed by user
138
184
  @builder.add_command_line_options(['--ws-connect'])
139
185
  # TODO: option to give order ssh,ws (legacy http is implied bu ssh)
140
186
  # quel bordel:
141
- @job_spec['ssh_port'] = @builder.process_param('wss_port',:get_value)
187
+ @job_spec['ssh_port'] = @builder.process_param('wss_port', :get_value)
142
188
  @job_spec.delete('fasp_port')
143
189
  @job_spec.delete('EX_ssh_key_paths')
144
190
  @job_spec.delete('sshfp')
@@ -154,68 +200,25 @@ module Aspera
154
200
  @builder.process_params
155
201
 
156
202
  # symbol must be index of Installation.paths
157
- if @builder.process_param('use_ascp4',:get_value)
203
+ if @builder.process_param('use_ascp4', :get_value)
158
204
  env_args[:ascp_version] = :ascp4
159
205
  else
160
206
  env_args[:ascp_version] = :ascp
161
207
  # destination will be base64 encoded, put before path arguments
162
208
  @builder.add_command_line_options(['--dest64'])
163
209
  end
164
- # process file lists
165
- begin
166
- # is the file list provided through EX_ parameters?
167
- ascp_file_list_provided = self.class.ts_has_ascp_file_list(@job_spec)
168
- # set if paths is mandatory in ts
169
- @builder.params_definition['paths'][:mandatory] = !@job_spec.has_key?('keepalive') && !ascp_file_list_provided
170
- # get paths in transfer spec (after setting if it is mandatory)
171
- ts_paths_array = @builder.process_param('paths',:get_value)
172
- if ascp_file_list_provided && !ts_paths_array.nil?
173
- raise 'file list provided both in transfer spec and ascp file list. Remove one of them.'
174
- end
175
- # option 1: EX_file_list
176
- file_list_file = @builder.process_param('EX_file_list',:get_value)
177
- if !file_list_file.nil?
178
- option = '--file-list'
179
- else
180
- # option 2: EX_file_pair_list
181
- file_list_file = @builder.process_param('EX_file_pair_list',:get_value)
182
- if !file_list_file.nil?
183
- option = '--file-pair-list'
184
- elsif !ts_paths_array.nil?
185
- # option 3: in TS, it is an array
186
- if !self.class.file_list_folder.nil?
187
- # safer option: generate a file list file if there is storage defined for it
188
- # if there is destination in paths, then use filepairlist
189
- # TODO: well, we test only the first one, but anyway it shall be consistent
190
- if ts_paths_array.first.has_key?('destination')
191
- option = '--file-pair-list'
192
- lines = ts_paths_array.each_with_object([]){|e,m|m.push(e['source'],e['destination']);}
193
- else
194
- option = '--file-list'
195
- lines = ts_paths_array.map{|i|i['source']}
196
- end
197
- file_list_file = Aspera::TempFileManager.instance.new_file_path_in_folder(self.class.file_list_folder)
198
- File.write(file_list_file, lines.join("\n"))
199
- Log.log.debug{"#{option}=\n#{File.read(file_list_file)}".red}
200
- else
201
- # not safe for special characters ? (maybe not, depends on OS)
202
- Log.log.debug('placing source file list on command line (no file list file)')
203
- @builder.add_command_line_options(ts_paths_array.map{|i|i['source']})
204
- end
205
- end
206
- end
207
- @builder.add_command_line_options(["#{option}=#{file_list_file}"]) unless option.nil?
208
- end
210
+ # get list of files to transfer and build arg for ascp
211
+ process_file_list
209
212
  # optional args, at the end to override previous ones (to allow override)
210
- @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))
211
214
  # process destination folder
212
- destination_folder = @builder.process_param('destination_root',:get_value) || '/'
215
+ destination_folder = @builder.process_param('destination_root', :get_value) || '/'
213
216
  # ascp4 does not support base64 encoding of destination
214
217
  destination_folder = Base64.strict_encode64(destination_folder) unless env_args[:ascp_version].eql?(:ascp4)
215
218
  # destination MUST be last command line argument to ascp
216
219
  @builder.add_command_line_options([destination_folder])
217
220
 
218
- @builder.add_env_args(env_args[:env],env_args[:args])
221
+ @builder.add_env_args(env_args[:env], env_args[:args])
219
222
 
220
223
  return env_args
221
224
  end
@@ -313,8 +313,8 @@ ssh_port:
313
313
  ssh_private_key:
314
314
  :desc: |-
315
315
  Private key used for SSH authentication.
316
- Shall look like: -----BEGIN RSA PRIV4TE KEY-----\nMII...
317
- 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.
318
318
 
319
319
 
320
320
  :tragents:
@@ -20,13 +20,13 @@ module Aspera
20
20
  @parameters = DEFAULTS.dup
21
21
  if !params.nil?
22
22
  raise "expecting Hash (or nil), but have #{params.class}" unless params.is_a?(Hash)
23
- params.each do |k,v|
24
- raise "unknown resume parameter: #{k}, expect one of #{DEFAULTS.keys.map(&:to_s).join(',')}" unless DEFAULTS.has_key?(k)
23
+ params.each do |k, v|
24
+ raise "unknown resume parameter: #{k}, expect one of #{DEFAULTS.keys.map(&:to_s).join(',')}" unless DEFAULTS.key?(k)
25
25
  raise "#{k} must be Integer" unless v.is_a?(Integer)
26
26
  @parameters[k] = v
27
27
  end
28
28
  end
29
- Log.log.debug("resume params=#{@parameters}")
29
+ Log.log.debug{"resume params=#{@parameters}"}
30
30
  end
31
31
 
32
32
  # calls block a number of times (resumes) until success or limit reached
@@ -36,20 +36,20 @@ module Aspera
36
36
  # maximum of retry
37
37
  remaining_resumes = @parameters[:iter_max]
38
38
  sleep_seconds = @parameters[:sleep_initial]
39
- Log.log.debug("retries=#{remaining_resumes}")
39
+ Log.log.debug{"retries=#{remaining_resumes}"}
40
40
  # try to send the file until ascp is succesful
41
41
  loop do
42
- Log.log.debug('transfer starting');
42
+ Log.log.debug('transfer starting')
43
43
  begin
44
44
  # call provided block
45
45
  yield
46
46
  break
47
47
  rescue Fasp::Error => e
48
- Log.log.warn("An error occurred: #{e.message}");
48
+ Log.log.warn{"An error occurred: #{e.message}"}
49
49
  # failure in ascp
50
50
  if e.retryable?
51
51
  # exit if we exceed the max number of retry
52
- raise Fasp::Error,'Maximum number of retry reached' if remaining_resumes <= 0
52
+ raise Fasp::Error, 'Maximum number of retry reached' if remaining_resumes <= 0
53
53
  else
54
54
  # give one chance only to non retryable errors
55
55
  unless remaining_resumes.eql?(@parameters[:iter_max])
@@ -61,7 +61,7 @@ module Aspera
61
61
 
62
62
  # take this retry in account
63
63
  remaining_resumes -= 1
64
- Log.log.warn("resuming in #{sleep_seconds} seconds (retry left:#{remaining_resumes})");
64
+ Log.log.warn{"resuming in #{sleep_seconds} seconds (retry left:#{remaining_resumes})"}
65
65
 
66
66
  # wait a bit before retrying, maybe network condition will be better
67
67
  sleep(sleep_seconds)