aspera-cli 4.17.0 → 4.18.1

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 (85) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +3 -4
  3. data/CHANGELOG.md +33 -0
  4. data/CONTRIBUTING.md +15 -1
  5. data/README.md +711 -432
  6. data/bin/ascli +5 -0
  7. data/bin/asession +2 -2
  8. data/examples/build_package.sh +28 -0
  9. data/lib/aspera/agent/alpha.rb +10 -8
  10. data/lib/aspera/agent/base.rb +9 -6
  11. data/lib/aspera/agent/connect.rb +7 -8
  12. data/lib/aspera/agent/direct.rb +56 -37
  13. data/lib/aspera/agent/httpgw.rb +23 -324
  14. data/lib/aspera/agent/node.rb +19 -20
  15. data/lib/aspera/agent/trsdk.rb +19 -20
  16. data/lib/aspera/api/aoc.rb +17 -14
  17. data/lib/aspera/api/cos_node.rb +4 -4
  18. data/lib/aspera/api/httpgw.rb +342 -0
  19. data/lib/aspera/api/node.rb +135 -89
  20. data/lib/aspera/ascmd.rb +4 -3
  21. data/lib/aspera/ascp/installation.rb +15 -7
  22. data/lib/aspera/ascp/management.rb +2 -2
  23. data/lib/aspera/ascp/products.rb +1 -1
  24. data/lib/aspera/cli/basic_auth_plugin.rb +5 -9
  25. data/lib/aspera/cli/extended_value.rb +35 -16
  26. data/lib/aspera/cli/formatter.rb +161 -70
  27. data/lib/aspera/cli/hints.rb +18 -0
  28. data/lib/aspera/cli/main.rb +32 -39
  29. data/lib/aspera/cli/manager.rb +151 -119
  30. data/lib/aspera/cli/plugin.rb +27 -21
  31. data/lib/aspera/cli/plugin_factory.rb +31 -20
  32. data/lib/aspera/cli/plugins/alee.rb +14 -2
  33. data/lib/aspera/cli/plugins/aoc.rb +152 -141
  34. data/lib/aspera/cli/plugins/ats.rb +1 -1
  35. data/lib/aspera/cli/plugins/config.rb +72 -65
  36. data/lib/aspera/cli/plugins/console.rb +8 -5
  37. data/lib/aspera/cli/plugins/faspex.rb +32 -23
  38. data/lib/aspera/cli/plugins/faspex5.rb +232 -156
  39. data/lib/aspera/cli/plugins/faspio.rb +85 -0
  40. data/lib/aspera/cli/plugins/httpgw.rb +55 -0
  41. data/lib/aspera/cli/plugins/node.rb +129 -64
  42. data/lib/aspera/cli/plugins/orchestrator.rb +33 -30
  43. data/lib/aspera/cli/plugins/preview.rb +7 -3
  44. data/lib/aspera/cli/plugins/server.rb +6 -6
  45. data/lib/aspera/cli/plugins/shares.rb +16 -14
  46. data/lib/aspera/cli/special_values.rb +13 -0
  47. data/lib/aspera/cli/sync_actions.rb +10 -10
  48. data/lib/aspera/cli/transfer_agent.rb +7 -6
  49. data/lib/aspera/cli/version.rb +1 -1
  50. data/lib/aspera/environment.rb +70 -9
  51. data/lib/aspera/faspex_gw.rb +5 -4
  52. data/lib/aspera/faspex_postproc.rb +2 -2
  53. data/lib/aspera/log.rb +6 -3
  54. data/lib/aspera/node_simulator.rb +2 -2
  55. data/lib/aspera/oauth/base.rb +31 -19
  56. data/lib/aspera/oauth/factory.rb +12 -13
  57. data/lib/aspera/oauth/generic.rb +1 -0
  58. data/lib/aspera/oauth/jwt.rb +18 -15
  59. data/lib/aspera/oauth/url_json.rb +8 -6
  60. data/lib/aspera/oauth/web.rb +2 -2
  61. data/lib/aspera/persistency_folder.rb +2 -2
  62. data/lib/aspera/preview/generator.rb +3 -3
  63. data/lib/aspera/preview/options.rb +3 -3
  64. data/lib/aspera/preview/terminal.rb +4 -4
  65. data/lib/aspera/preview/utils.rb +3 -3
  66. data/lib/aspera/proxy_auto_config.rb +5 -1
  67. data/lib/aspera/rest.rb +105 -88
  68. data/lib/aspera/rest_call_error.rb +1 -1
  69. data/lib/aspera/rest_error_analyzer.rb +2 -2
  70. data/lib/aspera/rest_errors_aspera.rb +1 -1
  71. data/lib/aspera/resumer.rb +1 -1
  72. data/lib/aspera/secret_hider.rb +2 -4
  73. data/lib/aspera/ssh.rb +1 -1
  74. data/lib/aspera/transfer/parameters.rb +39 -36
  75. data/lib/aspera/transfer/spec.rb +2 -0
  76. data/lib/aspera/transfer/sync.rb +2 -1
  77. data/lib/aspera/transfer/uri.rb +1 -1
  78. data/lib/aspera/uri_reader.rb +5 -4
  79. data/lib/aspera/web_auth.rb +1 -1
  80. data/lib/aspera/web_server_simple.rb +4 -3
  81. data.tar.gz.sig +0 -0
  82. metadata +7 -4
  83. metadata.gz.sig +0 -0
  84. data/lib/aspera/cli/plugins/bss.rb +0 -71
  85. data/lib/aspera/open_application.rb +0 -71
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # cspell:ignore initdemo genkey pubkey asperasoft
3
+ # cspell:ignore initdemo genkey pubkey asperasoft filelists
4
4
  require 'aspera/cli/basic_auth_plugin'
5
5
  require 'aspera/cli/extended_value'
6
+ require 'aspera/cli/special_values'
6
7
  require 'aspera/cli/version'
7
8
  require 'aspera/cli/formatter'
8
9
  require 'aspera/cli/info'
@@ -15,7 +16,7 @@ require 'aspera/transfer/spec'
15
16
  require 'aspera/keychain/encrypted_hash'
16
17
  require 'aspera/keychain/macos_security'
17
18
  require 'aspera/proxy_auto_config'
18
- require 'aspera/open_application'
19
+ require 'aspera/environment'
19
20
  require 'aspera/persistency_action_once'
20
21
  require 'aspera/id_generator'
21
22
  require 'aspera/persistency_folder'
@@ -25,6 +26,7 @@ require 'aspera/rest'
25
26
  require 'aspera/log'
26
27
  require 'aspera/assert'
27
28
  require 'aspera/oauth'
29
+ require 'openssl'
28
30
  require 'open3'
29
31
  require 'date'
30
32
  require 'erb'
@@ -141,7 +143,7 @@ module Aspera
141
143
  Aspera.assert(!app_name.empty?)
142
144
  return File.join(module_family_folder, app_name)
143
145
  end
144
- end # self
146
+ end
145
147
 
146
148
  def initialize(gem:, name:, help:, version:, **env)
147
149
  # we need to defer parsing of options until we have the config file, so we can use @extend with @preset
@@ -163,7 +165,6 @@ module Aspera
163
165
  @option_http_options = {}
164
166
  @ssl_warned_urls = []
165
167
  @option_cache_tokens = true
166
- @proxy_credentials = nil
167
168
  @main_folder = nil
168
169
  @option_config_file = nil
169
170
  # store is used for ruby https
@@ -230,9 +231,10 @@ module Aspera
230
231
  options.declare(:silent_insecure, 'Issue a warning if certificate is ignored', values: :bool, handler: {o: self, m: :option_warn_insecure_cert}, default: :yes)
231
232
  options.declare(:cert_stores, 'List of folder with trusted certificates', types: [Array, String], handler: {o: self, m: :trusted_cert_locations})
232
233
  options.declare(:http_options, 'Options for HTTP/S socket', types: Hash, handler: {o: self, m: :option_http_options}, default: {})
234
+ options.declare(:http_proxy, 'URL for HTTP proxy with optional credentials', types: String, handler: {o: self, m: :option_http_proxy})
233
235
  options.declare(:cache_tokens, 'Save and reuse OAuth tokens', values: :bool, handler: {o: self, m: :option_cache_tokens})
234
236
  options.declare(:fpac, 'Proxy auto configuration script')
235
- options.declare(:proxy_credentials, 'HTTP proxy credentials (user and password)', types: Array)
237
+ options.declare(:proxy_credentials, 'HTTP proxy credentials for fpac. Array: user,password', types: Array)
236
238
  options.parse_options!
237
239
  @progress_bar = TransferProgress.new if options.get_option(:progress_bar)
238
240
  # Check SDK folder is set or not, for compatibility, we check in two places
@@ -255,20 +257,21 @@ module Aspera
255
257
  end
256
258
  pac_script = options.get_option(:fpac)
257
259
  # create PAC executor
258
- @pac_exec = ProxyAutoConfig.new(pac_script).register_uri_generic unless pac_script.nil?
259
- proxy_user_pass = options.get_option(:proxy_credentials)
260
- if !proxy_user_pass.nil?
261
- Aspera.assert(proxy_user_pass.length.eql?(2), exception_class: Cli::BadArgument){"proxy_credentials shall have two elements (#{proxy_user_pass.length})"}
262
- @proxy_credentials = {user: proxy_user_pass[0], pass: proxy_user_pass[1]}
263
- @pac_exec.proxy_user = @proxy_credentials[:user]
264
- @pac_exec.proxy_pass = @proxy_credentials[:pass]
260
+ if !pac_script.nil?
261
+ @pac_exec = ProxyAutoConfig.new(pac_script).register_uri_generic
262
+ proxy_user_pass = options.get_option(:proxy_credentials)
263
+ if !proxy_user_pass.nil?
264
+ Aspera.assert(proxy_user_pass.length.eql?(2), exception_class: Cli::BadArgument){"proxy_credentials shall have two elements (#{proxy_user_pass.length})"}
265
+ @pac_exec.proxy_user = proxy_user_pass[0]
266
+ @pac_exec.proxy_pass = proxy_user_pass[1]
267
+ end
265
268
  end
266
269
  Rest.set_parameters(
267
270
  user_agent: PROGRAM_NAME,
268
271
  session_cb: lambda{|http_session|update_http_session(http_session)},
269
272
  progress_bar: @progress_bar)
270
273
  OAuth::Factory.instance.persist_mgr = persistency if @option_cache_tokens
271
- Transfer::Parameters.file_list_folder = File.join(@main_folder, 'filelists') # cspell: disable-line
274
+ Transfer::Parameters.file_list_folder = File.join(@main_folder, 'filelists')
272
275
  RestErrorAnalyzer.instance.log_file = File.join(@main_folder, 'rest_exceptions.log')
273
276
  # register aspera REST call error handlers
274
277
  RestErrorsAspera.register_handlers
@@ -291,7 +294,7 @@ module Aspera
291
294
  Aspera.assert_type(path, String){'Expecting a String for certificate location'}
292
295
  paths_to_add = [path]
293
296
  Log.log.debug{"Adding cert location: #{path}"}
294
- if path.eql?(ExtendedValue::DEF)
297
+ if path.eql?(SpecialValues::DEF)
295
298
  @certificate_store.set_default_paths
296
299
  paths_to_add = [
297
300
  OpenSSL::X509::DEFAULT_CERT_DIR,
@@ -322,7 +325,7 @@ module Aspera
322
325
  locations = @certificate_paths
323
326
  if locations.nil?
324
327
  # compute default locations
325
- self.trusted_cert_locations = ExtendedValue::DEF
328
+ self.trusted_cert_locations = SpecialValues::DEF
326
329
  locations = @certificate_paths
327
330
  # restore defaults
328
331
  @certificate_paths = @certificate_store = nil
@@ -330,6 +333,15 @@ module Aspera
330
333
  return locations
331
334
  end
332
335
 
336
+ def option_http_proxy
337
+ return ENV['http_proxy']
338
+ end
339
+
340
+ def option_http_proxy=(value)
341
+ URI.parse(value)
342
+ ENV['http_proxy'] = value
343
+ end
344
+
333
345
  def option_ignore_cert_host_port=(url_list)
334
346
  url_list.each do |url|
335
347
  uri = URI.parse(url)
@@ -365,10 +377,6 @@ module Aspera
365
377
  http_session.verify_mode = SELF_SIGNED_CERT if http_session.use_ssl? && ignore_cert?(http_session.address, http_session.port)
366
378
  http_session.cert_store = @certificate_store if @certificate_store
367
379
  Log.log.debug{"using cert store #{http_session.cert_store} (#{@certificate_store})"} unless http_session.cert_store.nil?
368
- if @proxy_credentials
369
- http_session.proxy_user = @proxy_credentials[:user]
370
- http_session.proxy_pass = @proxy_credentials[:pass]
371
- end
372
380
  @option_http_options.each do |k, v|
373
381
  method = "#{k}=".to_sym
374
382
  # check if accessor is a method of Net::HTTP
@@ -453,7 +461,7 @@ module Aspera
453
461
  def add_plugin_default_preset(plugin_name_sym)
454
462
  default_config_name = get_plugin_default_config_name(plugin_name_sym)
455
463
  Log.log.debug{"add_plugin_default_preset:#{plugin_name_sym}:#{default_config_name}"}
456
- options.add_option_preset(preset_by_name(default_config_name), op: :unshift) unless default_config_name.nil?
464
+ options.add_option_preset(preset_by_name(default_config_name), 'default_plugin', override: false) unless default_config_name.nil?
457
465
  return nil
458
466
  end
459
467
 
@@ -539,12 +547,12 @@ module Aspera
539
547
 
540
548
  def option_preset=(value)
541
549
  case value
542
- when String
543
- options.add_option_preset(preset_by_name(value))
544
550
  when Hash
545
- options.add_option_preset(value)
551
+ options.add_option_preset(value, 'set')
552
+ when String
553
+ options.add_option_preset(preset_by_name(value), 'set_by_name')
546
554
  else
547
- raise 'Preset definition must be a String for name, or Hash for value'
555
+ raise 'Preset definition must be a String for preset name, or Hash for set of values'
548
556
  end
549
557
  end
550
558
 
@@ -613,18 +621,18 @@ module Aspera
613
621
  check_only = check_only.to_sym unless check_only.nil?
614
622
  found_apps = []
615
623
  my_self_plugin_sym = self.class.name.split('::').last.downcase.to_sym
616
- PluginFactory.instance.plugins.each do |plugin_name_sym, plugin_info|
624
+ PluginFactory.instance.plugin_list.each do |plugin_name_sym|
617
625
  # no detection for internal plugin
618
626
  next if plugin_name_sym.eql?(my_self_plugin_sym)
619
627
  next if check_only && !check_only.eql?(plugin_name_sym)
620
628
  # load plugin class
621
- require plugin_info[:require_stanza]
622
- detect_plugin_class = PluginFactory.plugin_class(plugin_name_sym)
629
+ detect_plugin_class = PluginFactory.instance.plugin_class(plugin_name_sym)
623
630
  # requires detection method
624
631
  next unless detect_plugin_class.respond_to?(:detect)
625
632
  detection_info = nil
626
633
  begin
627
634
  Log.log.debug{"detecting #{plugin_name_sym} at #{app_url}"}
635
+ formatter.long_operation_running("#{plugin_name_sym}\r")
628
636
  detection_info = detect_plugin_class.detect(app_url)
629
637
  rescue OpenSSL::SSL::SSLError => e
630
638
  Log.log.warn(e.message)
@@ -639,7 +647,7 @@ module Aspera
639
647
  app_name = detect_plugin_class.respond_to?(:application_name) ? detect_plugin_class.application_name : detect_plugin_class.name.split('::').last
640
648
  # if there is a redirect, then the detector can override the url.
641
649
  found_apps.push({product: plugin_name_sym, name: app_name, url: app_url, version: 'unknown'}.merge(detection_info))
642
- end # loop
650
+ end
643
651
  raise "No known application found at #{app_url}" if found_apps.empty?
644
652
  Aspera.assert(found_apps.all?{|a|a.keys.all?(Symbol)})
645
653
  return found_apps
@@ -678,7 +686,7 @@ module Aspera
678
686
  api_connect_cdn.call(operation: 'GET', subpath: file_url, save_to_file: File.join(folder_dest, filename))
679
687
  return Main.result_status("Downloaded: #{filename}")
680
688
  when :open
681
- OpenApplication.instance.uri(one_link['href'])
689
+ Environment.instance.open_uri(one_link['href'])
682
690
  return Main.result_status("Opened: #{one_link['href']}")
683
691
  end
684
692
  end
@@ -726,7 +734,7 @@ module Aspera
726
734
  when :spec
727
735
  return {
728
736
  type: :object_list,
729
- data: Transfer::Parameters.man_table,
737
+ data: Transfer::Parameters.man_table(formatter),
730
738
  fields: [%w[name type], Transfer::Parameters::SUPPORTED_AGENTS_SHORT.map(&:to_s), %w[description]].flatten.freeze
731
739
  }
732
740
  when :errors
@@ -779,11 +787,11 @@ module Aspera
779
787
  when :set
780
788
  param_name = options.get_next_argument('parameter name')
781
789
  param_name = Manager.option_line_to_name(param_name)
782
- param_value = options.get_next_argument('parameter value')
790
+ param_value = options.get_next_argument('parameter value', validation: nil)
783
791
  set_preset_key(name, param_name, param_value)
784
792
  return Main.result_nothing
785
793
  when :initialize
786
- config_value = options.get_next_argument('extended value', type: Hash)
794
+ config_value = options.get_next_argument('extended value', validation: Hash)
787
795
  if @config_presets.key?(name)
788
796
  Log.log.warn{"configuration already exists: #{name}, overwriting"}
789
797
  end
@@ -791,16 +799,16 @@ module Aspera
791
799
  return Main.result_status("Modified: #{@option_config_file}")
792
800
  when :update
793
801
  # get unprocessed options
794
- unprocessed_options = options.get_options_table
802
+ unprocessed_options = options.unprocessed_options_with_value
795
803
  Log.log.debug{"opts=#{unprocessed_options}"}
796
804
  @config_presets[name] ||= {}
797
805
  @config_presets[name].merge!(unprocessed_options)
798
806
  return Main.result_status("Updated: #{name}")
799
807
  when :ask
800
- options.ask_missing_mandatory = :yes
808
+ options.ask_missing_mandatory = true
801
809
  @config_presets[name] ||= {}
802
- options.get_next_argument('option names', expected: :multiple).each do |option_name|
803
- option_value = options.get_interactive(:option, option_name)
810
+ options.get_next_argument('option names', multiple: true).each do |option_name|
811
+ option_value = options.get_interactive(option_name, option: true)
804
812
  @config_presets[name][option_name] = option_value
805
813
  end
806
814
  return Main.result_status("Updated: #{name}")
@@ -853,6 +861,7 @@ module Aspera
853
861
  wizard
854
862
  detect
855
863
  coffee
864
+ image
856
865
  ascp
857
866
  email_test
858
867
  smtp_settings
@@ -871,16 +880,16 @@ module Aspera
871
880
  when :preset # newer syntax
872
881
  return execute_preset
873
882
  when :open
874
- OpenApplication.editor(@option_config_file.to_s)
883
+ Environment.open_editor(@option_config_file.to_s)
875
884
  return Main.result_nothing
876
885
  when :documentation
877
886
  section = options.get_next_argument('private key file path', mandatory: false)
878
887
  section = "##{section}" unless section.nil?
879
- OpenApplication.instance.uri("#{@help}#{section}")
888
+ Environment.instance.open_uri("#{@help}#{section}")
880
889
  return Main.result_nothing
881
890
  when :genkey # generate new rsa key
882
891
  private_key_path = options.get_next_argument('private key file path')
883
- private_key_length = options.get_next_argument('size in bits', mandatory: false, type: Integer, default: DEFAULT_PRIV_KEY_LENGTH)
892
+ private_key_length = options.get_next_argument('size in bits', mandatory: false, validation: Integer, default: DEFAULT_PRIV_KEY_LENGTH)
884
893
  self.class.generate_rsa_private_key(path: private_key_path, length: private_key_length)
885
894
  return Main.result_status("Generated #{private_key_length} bit RSA key: #{private_key_path}")
886
895
  when :pubkey # get pub key
@@ -900,7 +909,7 @@ module Aspera
900
909
  return Main.result_status(remote_chain.first.subject.to_a.find { |name, _, _| name == 'CN' }[1])
901
910
  end
902
911
  when :echo # display the content of a value given on command line
903
- return Formatter.auto_type(options.get_next_argument('value'))
912
+ return Formatter.auto_type(options.get_next_argument('value', validation: nil))
904
913
  when :flush_tokens
905
914
  deleted_files = OAuth::Factory.instance.flush_tokens
906
915
  return {type: :value_list, data: deleted_files, name: 'file'}
@@ -908,20 +917,19 @@ module Aspera
908
917
  case options.get_next_command(%i[list create])
909
918
  when :list
910
919
  result = []
911
- PluginFactory.instance.plugins.each do |name, info|
912
- require info[:require_stanza]
913
- plugin_klass = PluginFactory.plugin_class(name)
920
+ PluginFactory.instance.plugin_list.each do |name|
921
+ plugin_class = PluginFactory.instance.plugin_class(name)
914
922
  result.push({
915
923
  plugin: name,
916
- detect: Formatter.tick(plugin_klass.respond_to?(:detect)),
917
- wizard: Formatter.tick(plugin_klass.respond_to?(:wizard)),
918
- path: info[:source]
924
+ detect: Formatter.tick(plugin_class.respond_to?(:detect)),
925
+ wizard: Formatter.tick(plugin_class.respond_to?(:wizard)),
926
+ path: PluginFactory.instance.plugin_source(name)
919
927
  })
920
928
  end
921
929
  return {type: :object_list, data: result, fields: %w[plugin detect wizard path]}
922
930
  when :create
923
- plugin_name = options.get_next_argument('name', expected: :single).downcase
924
- destination_folder = options.get_next_argument('folder', expected: :single, mandatory: false) || File.join(@main_folder, ASPERA_PLUGINS_FOLDERNAME)
931
+ plugin_name = options.get_next_argument('name').downcase
932
+ destination_folder = options.get_next_argument('folder', mandatory: false) || File.join(@main_folder, ASPERA_PLUGINS_FOLDERNAME)
925
933
  plugin_file = File.join(destination_folder, "#{plugin_name}.rb")
926
934
  content = <<~END_OF_PLUGIN_CODE
927
935
  require 'aspera/cli/plugin'
@@ -950,11 +958,9 @@ module Aspera
950
958
  } if action.eql?(:detect)
951
959
  return wizard_find(apps)
952
960
  when :coffee
953
- if OpenApplication.instance.url_method.eql?(:text)
954
- return Main.result_picture_in_terminal(options, Rest.new(base_url: COFFEE_IMAGE).read('')[:http].body)
955
- end
956
- OpenApplication.instance.uri(COFFEE_IMAGE)
957
- return Main.result_nothing
961
+ return Main.result_image(COFFEE_IMAGE, formatter: formatter)
962
+ when :image
963
+ return Main.result_image(options.get_next_argument('image uri or blob'), formatter: formatter)
958
964
  when :ascp
959
965
  execute_action_ascp
960
966
  when :gem
@@ -1019,17 +1025,17 @@ module Aspera
1019
1025
  apps.first
1020
1026
  else
1021
1027
  formatter.display_status('Multiple applications detected, please select from:')
1022
- formatter.display_results({type: :object_list, data: apps, fields: %w[product url version]})
1028
+ formatter.display_results(type: :object_list, data: apps, fields: %w[product url version])
1023
1029
  answer = options.prompt_user_input_in_list('product', apps.map{|a|a[:product]})
1024
1030
  apps.find{|a|a[:product].eql?(answer)}
1025
1031
  end
1026
- wiz_url = identification[:url]
1027
1032
  Log.log.debug{Log.dump(:identification, identification)}
1033
+ wiz_url = identification[:url]
1028
1034
  formatter.display_status("Using: #{identification[:name]} at #{wiz_url}".bold)
1029
1035
  # set url for instantiation of plugin
1030
- options.add_option_preset({url: wiz_url})
1036
+ options.add_option_preset({url: wiz_url}, 'wizard')
1031
1037
  # instantiate plugin: command line options will be known and wizard can be called
1032
- wiz_plugin_class = PluginFactory.plugin_class(identification[:product])
1038
+ wiz_plugin_class = PluginFactory.instance.plugin_class(identification[:product])
1033
1039
  Aspera.assert(wiz_plugin_class.respond_to?(:wizard), exception_class: Cli::BadArgument) do
1034
1040
  "Detected: #{identification[:product]}, but this application has no wizard"
1035
1041
  end
@@ -1072,7 +1078,7 @@ module Aspera
1072
1078
  Log.log.debug{"wizard result: #{wizard_result}"}
1073
1079
  Aspera.assert(WIZARD_RESULT_KEYS.eql?(wizard_result.keys.sort)){"missing or extra keys in wizard result: #{wizard_result.keys}"}
1074
1080
  # get preset name from user or default
1075
- wiz_preset_name = options.get_option(:id)
1081
+ wiz_preset_name = nil
1076
1082
  if wiz_preset_name.nil?
1077
1083
  elements = [
1078
1084
  identification[:product],
@@ -1198,7 +1204,7 @@ module Aspera
1198
1204
  return default_config_name
1199
1205
  end
1200
1206
  return nil
1201
- end # get_plugin_default_config_name
1207
+ end
1202
1208
 
1203
1209
  # TODO: delete: ALLOWED_KEYS = %i[password username description].freeze
1204
1210
  # @return [Hash] result of execution of vault command
@@ -1208,19 +1214,20 @@ module Aspera
1208
1214
  when :info
1209
1215
  return {type: :single_object, data: vault_info}
1210
1216
  when :list
1211
- return {type: :object_list, data: vault.list}
1217
+ return {type: :object_list, data: vault.list, fields: %w(label url username password description)}
1212
1218
  when :show
1213
1219
  return {type: :single_object, data: vault.get(label: options.get_next_argument('label'))}
1214
1220
  when :create
1215
- label = options.get_next_argument('label', type: String)
1216
- info = options.get_next_argument('info', type: Hash)
1221
+ label = options.get_next_argument('label', validation: String)
1222
+ info = options.get_next_argument('info', validation: Hash)
1217
1223
  info = info.symbolize_keys
1218
1224
  info[:label] = label
1219
1225
  vault.set(info)
1220
1226
  return Main.result_status('Password added')
1221
1227
  when :delete
1222
- vault.delete(label: options.get_next_argument('label'))
1223
- return Main.result_status('Password deleted')
1228
+ label_to_delete = options.get_next_argument('label')
1229
+ vault.delete(label: label_to_delete)
1230
+ return Main.result_status("Entry deleted: #{label_to_delete}")
1224
1231
  when :password
1225
1232
  Aspera.assert(vault.respond_to?(:password=)){'Vault does not support password change'}
1226
1233
  new_password = options.get_next_argument('new_password')
@@ -1264,7 +1271,7 @@ module Aspera
1264
1271
  info[:password])
1265
1272
  when 'system'
1266
1273
  case Environment.os
1267
- when Environment::OS_X
1274
+ when Environment::OS_MACOS
1268
1275
  @vault = Keychain::MacosSystem.new(info[:name], info[:password])
1269
1276
  else
1270
1277
  raise 'not implemented for this OS'
@@ -18,7 +18,10 @@ module Aspera
18
18
  next unless base_url.start_with?('https://')
19
19
  api = Rest.new(base_url: base_url, redirect_max: 2)
20
20
  test_endpoint = 'login'
21
- test_page = api.call(operation: 'GET', subpath: test_endpoint, url_params: {local: true})
21
+ test_page = api.call(
22
+ operation: 'GET',
23
+ subpath: test_endpoint,
24
+ query: {local: true})
22
25
  next unless test_page[:http].body.include?('Aspera Console')
23
26
  version = 'unknown'
24
27
  if (m = test_page[:http].body.match(/\(v([1-9]\..*)\)/))
@@ -102,7 +105,7 @@ module Aspera
102
105
  end
103
106
  end
104
107
  end
105
- end # Console
106
- end # Plugins
107
- end # Cli
108
- end # Aspera
108
+ end
109
+ end
110
+ end
111
+ end
@@ -5,11 +5,12 @@ require 'aspera/cli/basic_auth_plugin'
5
5
  require 'aspera/cli/plugins/node'
6
6
  require 'aspera/cli/plugins/config'
7
7
  require 'aspera/cli/extended_value'
8
+ require 'aspera/cli/special_values'
8
9
  require 'aspera/cli/transfer_agent'
9
10
  require 'aspera/transfer/uri'
10
11
  require 'aspera/transfer/spec'
11
12
  require 'aspera/persistency_action_once'
12
- require 'aspera/open_application'
13
+ require 'aspera/environment'
13
14
  require 'aspera/nagios'
14
15
  require 'aspera/id_generator'
15
16
  require 'aspera/log'
@@ -179,7 +180,11 @@ module Aspera
179
180
  loop do
180
181
  # get a batch of package information
181
182
  # order: first batch is latest packages, and then in a batch ids are increasing
182
- atom_xml = api_v3.call(operation: 'GET', subpath: "#{mailbox}.atom", headers: {'Accept' => 'application/xml'}, url_params: mailbox_query)[:http].body
183
+ atom_xml = api_v3.call(
184
+ operation: 'GET',
185
+ subpath: "#{mailbox}.atom",
186
+ headers: {'Accept' => 'application/xml'},
187
+ query: mailbox_query)[:http].body
183
188
  box_data = XmlSimple.xml_in(atom_xml, {'ForceArray' => %w[entry field link to]})
184
189
  Log.log.debug{Log.dump(:box_data, box_data)}
185
190
  items = box_data.key?('entry') ? box_data['entry'] : []
@@ -246,8 +251,9 @@ module Aspera
246
251
  package_creation_data = api_public_link.call(
247
252
  operation: 'POST',
248
253
  subpath: create_path,
249
- json_params: package_create_params,
250
- headers: {'Accept' => 'text/javascript'})[:http].body
254
+ headers: {'Accept' => 'text/javascript'},
255
+ body: package_create_params,
256
+ body_type: :json)[:http].body
251
257
  # get arguments of function call
252
258
  package_creation_data.delete!("\n") # one line
253
259
  package_creation_data.gsub!(/^[^"]+\("\{/, '{') # delete header
@@ -308,8 +314,9 @@ module Aspera
308
314
  pkg_created = api_v3.call(
309
315
  operation: 'POST',
310
316
  subpath: 'send',
311
- json_params: package_create_params,
312
- headers: {'Accept' => 'application/json'}
317
+ headers: {'Accept' => 'application/json'},
318
+ body: package_create_params,
319
+ body_type: :json
313
320
  )[:data]
314
321
  if first_source.key?('id')
315
322
  # no transfer spec if remote source: handled by faspex
@@ -347,9 +354,9 @@ module Aspera
347
354
  delivery_id = instance_identifier
348
355
  raise 'empty id' if delivery_id.empty?
349
356
  recipient = options.get_option(:recipient)
350
- if delivery_id.eql?(ExtendedValue::ALL)
357
+ if delivery_id.eql?(SpecialValues::ALL)
351
358
  pkg_id_uri = mailbox_filtered_entries.map{|i|{id: i[PACKAGE_MATCH_FIELD], uri: self.class.get_fasp_uri_from_entry(i, raise_no_link: false)}}
352
- elsif delivery_id.eql?(ExtendedValue::INIT)
359
+ elsif delivery_id.eql?(SpecialValues::INIT)
353
360
  Aspera.assert(skip_ids_persistency){'Only with option once_only'}
354
361
  skip_ids_persistency.data.clear.concat(mailbox_filtered_entries.map{|i|{id: i[PACKAGE_MATCH_FIELD]}})
355
362
  skip_ids_persistency.save
@@ -380,18 +387,18 @@ module Aspera
380
387
  api_public_link = Rest.new(base_url: link_data[:base_url])
381
388
  package_creation_data = api_public_link.call(
382
389
  operation: 'GET',
383
- subpath: link_data[:subpath],
384
- url_params: {passcode: link_data[:query]['passcode']},
385
- headers: {'Accept' => 'application/xml'})
390
+ subpath: link_data[:subpath],
391
+ headers: {'Accept' => 'application/xml'},
392
+ query: {passcode: link_data[:query]['passcode']})
386
393
  if !package_creation_data[:http].body.start_with?('<?xml ')
387
- OpenApplication.instance.uri(link_url)
394
+ Environment.instance.open_uri(link_url)
388
395
  raise Cli::Error, 'Unexpected response: package not found ?'
389
396
  end
390
397
  package_entry = XmlSimple.xml_in(package_creation_data[:http].body, {'ForceArray' => false})
391
398
  Log.log.debug{Log.dump(:package_entry, package_entry)}
392
399
  transfer_uri = self.class.get_fasp_uri_from_entry(package_entry)
393
400
  pkg_id_uri = [{id: package_entry['id'], uri: transfer_uri}]
394
- end # public link
401
+ end
395
402
  # prune packages already downloaded
396
403
  # TODO : remove ids from skip not present in inbox to avoid growing too big
397
404
  # skip_ids_data.select!{|id|pkg_id_uri.select{|p|p[:id].eql?(id)}}
@@ -411,10 +418,12 @@ module Aspera
411
418
  xml_payload =
412
419
  %Q(<?xml version="1.0" encoding="UTF-8"?><url-list xmlns="http://schemas.asperasoft.com/xml/url-list"><url href="#{sanitized}"/></url-list>)
413
420
  transfer_spec['token'] = api_v3.call(
414
- operation: 'POST',
415
- subpath: 'issue-token?direction=down',
416
- headers: {'Accept' => 'text/plain', 'Content-Type' => 'application/vnd.aspera.url-list+xml'},
417
- text_body_params: xml_payload)[:http].body
421
+ operation: 'POST',
422
+ subpath: 'issue-token',
423
+ headers: {'Accept' => 'text/plain', 'Content-Type' => 'application/vnd.aspera.url-list+xml'},
424
+ query: {'direction' => 'down'},
425
+ body: xml_payload,
426
+ body_type: :text)[:http].body
418
427
  end
419
428
  transfer_spec['direction'] = Transfer::Spec::DIRECTION_RECEIVE
420
429
  statuses = transfer.start(transfer_spec)
@@ -502,9 +511,9 @@ module Aspera
502
511
  when :address_book
503
512
  result = api_v3.call(
504
513
  operation: 'GET',
505
- subpath: 'address-book',
506
- headers: {'Accept' => 'application/json'},
507
- url_params: {'format' => 'json', 'count' => 100_000}
514
+ subpath: 'address-book',
515
+ headers: {'Accept' => 'application/json'},
516
+ query: {'format' => 'json', 'count' => 100_000}
508
517
  )[:data]
509
518
  formatter.display_status("users: #{result['itemsPerPage']}/#{result['totalResults']}, start:#{result['startIndex']}")
510
519
  users = result['entry']
@@ -526,9 +535,9 @@ module Aspera
526
535
  login_meths = api_v3.call(operation: 'GET', subpath: 'login/new', headers: {'Accept' => 'application/xrds+xml'})[:http].body
527
536
  login_methods = XmlSimple.xml_in(login_meths, {'ForceArray' => false})
528
537
  return {type: :object_list, data: login_methods['XRD']['Service']}
529
- end # command
538
+ end
530
539
  end
531
540
  end
532
541
  end
533
- end # Cli
534
- end # Aspera
542
+ end
543
+ end