aspera-cli 4.11.0 → 4.12.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 (67) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/BUGS.md +0 -1
  4. data/CHANGELOG.md +71 -52
  5. data/CONTRIBUTING.md +31 -6
  6. data/README.md +404 -259
  7. data/bin/asession +2 -2
  8. data/docs/test_env.conf +1 -0
  9. data/examples/aoc.rb +2 -2
  10. data/examples/dascli +11 -11
  11. data/examples/faspex4.rb +7 -7
  12. data/examples/node.rb +1 -1
  13. data/examples/proxy.pac +2 -2
  14. data/examples/server.rb +3 -3
  15. data/lib/aspera/aoc.rb +105 -40
  16. data/lib/aspera/cli/extended_value.rb +4 -4
  17. data/lib/aspera/cli/{formater.rb → formatter.rb} +7 -7
  18. data/lib/aspera/cli/listener/progress.rb +1 -1
  19. data/lib/aspera/cli/listener/progress_multi.rb +2 -2
  20. data/lib/aspera/cli/main.rb +18 -18
  21. data/lib/aspera/cli/manager.rb +5 -5
  22. data/lib/aspera/cli/plugin.rb +23 -20
  23. data/lib/aspera/cli/plugins/aoc.rb +75 -112
  24. data/lib/aspera/cli/plugins/ats.rb +6 -6
  25. data/lib/aspera/cli/plugins/config.rb +84 -83
  26. data/lib/aspera/cli/plugins/cos.rb +1 -1
  27. data/lib/aspera/cli/plugins/faspex.rb +38 -38
  28. data/lib/aspera/cli/plugins/faspex5.rb +187 -43
  29. data/lib/aspera/cli/plugins/node.rb +30 -37
  30. data/lib/aspera/cli/plugins/orchestrator.rb +7 -4
  31. data/lib/aspera/cli/plugins/preview.rb +10 -9
  32. data/lib/aspera/cli/plugins/server.rb +1 -1
  33. data/lib/aspera/cli/plugins/shares.rb +67 -43
  34. data/lib/aspera/cli/transfer_agent.rb +16 -16
  35. data/lib/aspera/cli/version.rb +2 -1
  36. data/lib/aspera/command_line_builder.rb +70 -66
  37. data/lib/aspera/cos_node.rb +9 -9
  38. data/lib/aspera/fasp/agent_base.rb +3 -1
  39. data/lib/aspera/fasp/agent_connect.rb +23 -23
  40. data/lib/aspera/fasp/agent_direct.rb +13 -14
  41. data/lib/aspera/fasp/agent_httpgw.rb +20 -19
  42. data/lib/aspera/fasp/agent_node.rb +13 -15
  43. data/lib/aspera/fasp/agent_trsdk.rb +1 -1
  44. data/lib/aspera/fasp/installation.rb +5 -5
  45. data/lib/aspera/fasp/listener.rb +1 -1
  46. data/lib/aspera/fasp/parameters.rb +49 -41
  47. data/lib/aspera/fasp/parameters.yaml +311 -212
  48. data/lib/aspera/fasp/resume_policy.rb +2 -2
  49. data/lib/aspera/fasp/transfer_spec.rb +0 -13
  50. data/lib/aspera/faspex_gw.rb +80 -161
  51. data/lib/aspera/faspex_postproc.rb +77 -0
  52. data/lib/aspera/log.rb +7 -7
  53. data/lib/aspera/nagios.rb +6 -6
  54. data/lib/aspera/node.rb +24 -19
  55. data/lib/aspera/oauth.rb +50 -47
  56. data/lib/aspera/proxy_auto_config.js +22 -22
  57. data/lib/aspera/proxy_auto_config.rb +3 -3
  58. data/lib/aspera/rest.rb +12 -10
  59. data/lib/aspera/rest_error_analyzer.rb +5 -5
  60. data/lib/aspera/secret_hider.rb +4 -3
  61. data/lib/aspera/ssh.rb +4 -4
  62. data/lib/aspera/sync.rb +37 -36
  63. data/lib/aspera/web_auth.rb +7 -59
  64. data/lib/aspera/web_server_simple.rb +76 -0
  65. data.tar.gz.sig +0 -0
  66. metadata +6 -4
  67. metadata.gz.sig +0 -0
@@ -3,7 +3,7 @@
3
3
  require 'aspera/cli/basic_auth_plugin'
4
4
  require 'aspera/cli/extended_value'
5
5
  require 'aspera/cli/version'
6
- require 'aspera/cli/formater'
6
+ require 'aspera/cli/formatter'
7
7
  require 'aspera/cli/info'
8
8
  require 'aspera/fasp/installation'
9
9
  require 'aspera/fasp/parameters'
@@ -129,7 +129,7 @@ module Aspera
129
129
  ExtendedValue.instance.set_handler(EXTV_PRESET, :reader, lambda{|v|preset_by_name(v)})
130
130
  ExtendedValue.instance.set_handler(EXTV_INCLUDE_PRESETS, :decoder, lambda{|v|expanded_with_preset_includes(v)})
131
131
  ExtendedValue.instance.set_handler(EXTV_VAULT, :decoder, lambda{|v|vault_value(v)})
132
- # load defaults before it can be overriden
132
+ # load defaults before it can be overridden
133
133
  add_plugin_default_preset(CONF_GLOBAL_SYM)
134
134
  options.parse_options!
135
135
  options.set_obj_attr(:ascp_path, Fasp::Installation.instance, :ascp_path)
@@ -261,16 +261,16 @@ module Aspera
261
261
  Log.log.debug{"javascript=[\n#{connect_versions_javascript}\n]"}
262
262
  # get javascript object only
263
263
  found = connect_versions_javascript.match(/^.*? = (.*);/)
264
- raise CliError, 'Problen when getting connect versions from internet' if found.nil?
265
- alldata = JSON.parse(found[1])
266
- @connect_versions = alldata['entries']
264
+ raise CliError, 'Problem when getting connect versions from internet' if found.nil?
265
+ all_data = JSON.parse(found[1])
266
+ @connect_versions = all_data['entries']
267
267
  end
268
268
  return @connect_versions
269
269
  end
270
270
 
271
271
  # loads default parameters of plugin if no -P parameter
272
272
  # and if there is a section defined for the plugin in the "default" section
273
- # try to find: conffile[conffile["default"][plugin_str]]
273
+ # try to find: conf[conf["default"][plugin_str]]
274
274
  # @param plugin_name_sym : symbol for plugin name
275
275
  def add_plugin_default_preset(plugin_name_sym)
276
276
  default_config_name = get_plugin_default_config_name(plugin_name_sym)
@@ -297,7 +297,7 @@ module Aspera
297
297
  File.dirname(File.expand_path(__FILE__))
298
298
  end
299
299
 
300
- # name of englobin module
300
+ # name of englobing module
301
301
  # @return "Aspera::Cli::Plugins"
302
302
  def module_full_name
303
303
  return Module.nesting[2].to_s
@@ -309,7 +309,7 @@ module Aspera
309
309
  File.expand_path(module_full_name.gsub('::', '/').gsub(%r{[^/]+}, '..'), gem_plugins_folder)
310
310
  end
311
311
 
312
- # instanciate a plugin
312
+ # instantiate a plugin
313
313
  # plugins must be Capitalized
314
314
  def plugin_class(plugin_name_sym)
315
315
  # Module.nesting[2] is Aspera::Cli::Plugins
@@ -330,7 +330,7 @@ module Aspera
330
330
  end
331
331
  @config_presets[global_default_preset_name] ||= {}
332
332
  @config_presets[global_default_preset_name][key.to_s] = value
333
- self.format.display_status("Updated: #{global_default_preset_name}: #{key} <- #{value}")
333
+ formatter.display_status("Updated: #{global_default_preset_name}: #{key} <- #{value}")
334
334
  save_presets_to_config_file
335
335
  return global_default_preset_name
336
336
  end
@@ -362,7 +362,7 @@ module Aspera
362
362
  end
363
363
  end
364
364
 
365
- # @return the hash value with 'incps' keys expanced to include other presets
365
+ # @return the hash value with 'incps' keys expanded to include other presets
366
366
  # @param hash_val
367
367
  # @param include_path to avoid inclusion loop
368
368
  def expanded_with_preset_includes(hash_val, include_path=[])
@@ -582,7 +582,8 @@ module Aspera
582
582
  Log.log.debug{"Cannot detect #{plugin_name_sym} : #{e.message}"}
583
583
  end
584
584
  end
585
- return detection_info.merge(product: plugin_name_sym, url: current_url) unless detection_info.nil?
585
+ # if there is a redirect, then the detector can override the url.
586
+ return {product: plugin_name_sym, url: current_url}.merge(detection_info) unless detection_info.nil?
586
587
  end # loop
587
588
  raise "No known application found at #{url}"
588
589
  end
@@ -615,9 +616,9 @@ module Aspera
615
616
  folder_dest = transfer.destination_folder(Fasp::TransferSpec::DIRECTION_RECEIVE)
616
617
  # folder_dest=self.options.get_next_argument('destination folder')
617
618
  api_connect_cdn = Rest.new({base_url: CONNECT_WEB_URL})
618
- fileurl = one_link['href']
619
- filename = fileurl.gsub(%r{.*/}, '')
620
- api_connect_cdn.call({operation: 'GET', subpath: fileurl, save_to_file: File.join(folder_dest, filename)})
619
+ file_url = one_link['href']
620
+ filename = file_url.gsub(%r{.*/}, '')
621
+ api_connect_cdn.call({operation: 'GET', subpath: file_url, save_to_file: File.join(folder_dest, filename)})
621
622
  return Main.result_status("Downloaded: #{filename}")
622
623
  when :open
623
624
  OpenApplication.instance.uri(one_link['href'])
@@ -634,7 +635,7 @@ module Aspera
634
635
  when :use
635
636
  ascp_path = options.get_next_argument('path to ascp')
636
637
  ascp_version = Fasp::Installation.instance.get_ascp_version(ascp_path)
637
- self.format.display_status("ascp version: #{ascp_version}")
638
+ formatter.display_status("ascp version: #{ascp_version}")
638
639
  preset_name = set_global_default(:ascp_path, ascp_path)
639
640
  return Main.result_status("Saved to default global preset #{preset_name}")
640
641
  when :show # shows files used
@@ -692,7 +693,7 @@ module Aspera
692
693
  return {
693
694
  type: :object_list,
694
695
  data: Fasp::Parameters.man_table,
695
- fields: %w[name type].concat(Fasp::Parameters::SUPPORTED_AGENTS_SHORT.map(&:to_s), %w[description])
696
+ fields: [%w[name type], Fasp::Parameters::SUPPORTED_AGENTS_SHORT.map(&:to_s), %w[description]].flatten.freeze
696
697
  }
697
698
  when :errors
698
699
  error_data = []
@@ -706,23 +707,23 @@ module Aspera
706
707
 
707
708
  # legacy actions available globally
708
709
  PRESET_GBL_ACTIONS = %i[list overview lookup secure].freeze
709
- # require existing preset
710
- PRESET_EXST_ACTIONS = %i[show delete get unset].freeze
710
+ # operations requiring that preset exists
711
+ PRESET_EXIST_ACTIONS = %i[show delete get unset].freeze
711
712
  # require id
712
- PRESET_INSTANCE_ACTIONS = %i[initialize update ask set].concat(PRESET_EXST_ACTIONS).freeze
713
- PRESET_ALL_ACTIONS = [].concat(PRESET_GBL_ACTIONS, PRESET_INSTANCE_ACTIONS).freeze
713
+ PRESET_INSTANCE_ACTIONS = %i[initialize update ask set].concat(PRESET_EXIST_ACTIONS).freeze
714
+ PRESET_ALL_ACTIONS = [PRESET_GBL_ACTIONS, PRESET_INSTANCE_ACTIONS].flatten.freeze
714
715
 
715
716
  def execute_preset(action: nil, name: nil)
716
717
  action = options.get_next_command(PRESET_ALL_ACTIONS) if action.nil?
717
718
  name = instance_identifier if name.nil? && PRESET_INSTANCE_ACTIONS.include?(action)
718
719
  # those operations require existing option
719
- raise "no such preset: #{name}" if PRESET_EXST_ACTIONS.include?(action) && !@config_presets.key?(name)
720
+ raise "no such preset: #{name}" if PRESET_EXIST_ACTIONS.include?(action) && !@config_presets.key?(name)
720
721
  selected_preset = @config_presets[name]
721
722
  case action
722
723
  when :list
723
724
  return {type: :value_list, data: @config_presets.keys, name: 'name'}
724
725
  when :overview
725
- return {type: :object_list, data: Formater.flatten_config_overview(@config_presets)}
726
+ return {type: :object_list, data: Formatter.flatten_config_overview(@config_presets)}
726
727
  when :show
727
728
  raise "no such config: #{name}" if selected_preset.nil?
728
729
  return {type: :single_object, data: selected_preset}
@@ -766,10 +767,10 @@ module Aspera
766
767
  return Main.result_status("Modified: #{@option_config_file}")
767
768
  when :update
768
769
  # get unprocessed options
769
- theopts = options.get_options_table
770
- Log.log.debug{"opts=#{theopts}"}
770
+ unprocessed_options = options.get_options_table
771
+ Log.log.debug{"opts=#{unprocessed_options}"}
771
772
  @config_presets[name] ||= {}
772
- @config_presets[name].merge!(theopts)
773
+ @config_presets[name].merge!(unprocessed_options)
773
774
  # fix bug in 4.4 (creating key "true" in "default" preset)
774
775
  @config_presets[CONF_PRESET_DEFAULT].delete(true) if @config_presets[CONF_PRESET_DEFAULT].is_a?(Hash)
775
776
  save_presets_to_config_file
@@ -777,9 +778,9 @@ module Aspera
777
778
  when :ask
778
779
  options.ask_missing_mandatory = :yes
779
780
  @config_presets[name] ||= {}
780
- options.get_next_argument('option names', expected: :multiple).each do |optionname|
781
- option_value = options.get_interactive(:option, optionname)
782
- @config_presets[name][optionname] = option_value
781
+ options.get_next_argument('option names', expected: :multiple).each do |option_name|
782
+ option_value = options.get_interactive(:option, option_name)
783
+ @config_presets[name][option_name] = option_value
783
784
  end
784
785
  save_presets_to_config_file
785
786
  return Main.result_status("Updated: #{name}")
@@ -794,20 +795,20 @@ module Aspera
794
795
  identifier = options.get_next_argument('config name', mandatory: false)
795
796
  preset_names = identifier.nil? ? @config_presets.keys : [identifier]
796
797
  secret_keywords = %w[password secret].freeze
797
- preset_names.each do |pset_name|
798
- preset = @config_presets[pset_name]
798
+ preset_names.each do |preset_name|
799
+ preset = @config_presets[preset_name]
799
800
  next unless preset.is_a?(Hash)
800
801
  preset.each_key do |option_name|
801
802
  secret_keywords.each do |keyword|
802
803
  next unless option_name.end_with?(keyword)
803
- vault_label = pset_name
804
+ vault_label = preset_name
804
805
  incr = 0
805
806
  until vault.get(label: vault_label, exception: false).nil?
806
- vault_label = "#{pset_name}#{incr}"
807
+ vault_label = "#{preset_name}#{incr}"
807
808
  incr += 1
808
809
  end
809
810
  to_set = {label: vault_label, password: preset[option_name]}
810
- puts "need to encode #{pset_name}.#{option_name} -> #{vault_label} -> #{to_set}"
811
+ puts "need to encode #{preset_name}.#{option_name} -> #{vault_label} -> #{to_set}"
811
812
  # to_copy=%i[]
812
813
  vault.set(to_set)
813
814
  preset[option_name] = "@vault:#{vault_label}.password"
@@ -925,20 +926,20 @@ module Aspera
925
926
  raise CliBadArgument, "Supports only: aoc. Detected: #{params[:application]}"
926
927
  end # product
927
928
  if params[:option_default]
928
- self.format.display_status("Setting config preset as default for #{params[:plugin_name]}")
929
+ formatter.display_status("Setting config preset as default for #{params[:plugin_name]}")
929
930
  @config_presets[CONF_PRESET_DEFAULT][params[:plugin_name]] = params[:preset_name]
930
931
  else
931
932
  params[:test_args] = "-P#{params[:preset_name]} #{params[:test_args]}"
932
933
  end
933
- self.format.display_status('Saving config file.')
934
+ formatter.display_status('Saving config file.')
934
935
  save_presets_to_config_file
935
936
  return Main.result_status("Done.\nYou can test with:\n#{@info[:name]} #{params[:test_args]}")
936
937
  when :export_to_cli # this method shall be deprecated in the future: it was used to export configuration to "aspera.exe" CLI
937
- self.format.display_status('Exporting: Aspera on Cloud')
938
+ formatter.display_status('Exporting: Aspera on Cloud')
938
939
  require 'aspera/cli/plugins/aoc'
939
940
  # need url / username
940
941
  add_plugin_default_preset(AOC_COMMAND_V3.to_sym)
941
- # instanciate AoC plugin
942
+ # instantiate AoC plugin
942
943
  self.class.plugin_class(AOC_COMMAND_CURRENT).new(@agents) # TODO: is this line needed ? get options ?
943
944
  url = options.get_option(:url, is_type: :mandatory)
944
945
  cli_conf_file = Fasp::Installation.instance.cli_conf_file
@@ -961,9 +962,9 @@ module Aspera
961
962
  entry = data['AoCAccounts'].find{|i|i['organization'].eql?(organization)}
962
963
  if entry.nil?
963
964
  data['AoCAccounts'].push(new_conf)
964
- self.format.display_status("Creating new aoc entry: #{organization}")
965
+ formatter.display_status("Creating new aoc entry: #{organization}")
965
966
  else
966
- self.format.display_status("Updating existing aoc entry: #{organization}")
967
+ formatter.display_status("Updating existing aoc entry: #{organization}")
967
968
  entry.merge!(new_conf)
968
969
  end
969
970
  File.write(cli_conf_file, JSON.pretty_generate(data))
@@ -1208,12 +1209,12 @@ module Aspera
1208
1209
  end
1209
1210
 
1210
1211
  def wizard_aoc(params)
1211
- self.format.display_status('Detected: Aspera on Cloud'.bold)
1212
+ formatter.display_status('Detected: Aspera on Cloud'.bold)
1212
1213
  params[:plugin_name] = AOC_COMMAND_CURRENT
1213
1214
  organization = AoC.parse_url(params[:instance_url]).first
1214
1215
  # if not defined by user, generate name
1215
1216
  params[:preset_name] = [params[:application], organization].join('_') if params[:preset_name].nil?
1216
- self.format.display_status("Preparing preset: #{params[:preset_name]}")
1217
+ formatter.display_status("Preparing preset: #{params[:preset_name]}")
1217
1218
  # init defaults if necessary
1218
1219
  @config_presets[CONF_PRESET_DEFAULT] ||= {}
1219
1220
  option_override = options.get_option(:override, is_type: :mandatory)
@@ -1227,7 +1228,7 @@ module Aspera
1227
1228
  private_key_path = options.get_option(:pkeypath)
1228
1229
  # give a chance to provide
1229
1230
  if private_key_path.nil?
1230
- self.format.display_status('Please provide path to your private RSA key, or empty to generate one:')
1231
+ formatter.display_status('Please provide path to your private RSA key, or empty to generate one:')
1231
1232
  private_key_path = options.get_option(:pkeypath, is_type: :mandatory).to_s
1232
1233
  end
1233
1234
  # else generate path
@@ -1235,45 +1236,45 @@ module Aspera
1235
1236
  private_key_path = File.join(@main_folder, DEFAULT_PRIV_KEY_FILENAME)
1236
1237
  end
1237
1238
  if File.exist?(private_key_path)
1238
- self.format.display_status('Using existing key:')
1239
+ formatter.display_status('Using existing key:')
1239
1240
  else
1240
- self.format.display_status("Generating #{DEFAULT_PRIVKEY_LENGTH} bit RSA key...")
1241
+ formatter.display_status("Generating #{DEFAULT_PRIVKEY_LENGTH} bit RSA key...")
1241
1242
  generate_rsa_private_key(private_key_path, DEFAULT_PRIVKEY_LENGTH)
1242
- self.format.display_status('Created:')
1243
+ formatter.display_status('Created:')
1243
1244
  end
1244
- self.format.display_status(private_key_path)
1245
+ formatter.display_status(private_key_path)
1245
1246
  pub_key_pem = OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
1246
1247
  # declare command line options for AoC
1247
1248
  require 'aspera/cli/plugins/aoc'
1248
1249
  # make username mandatory for jwt, this triggers interactive input
1249
1250
  options.get_option(:username, is_type: :mandatory)
1250
- # instanciate AoC plugin, so that command line options are known
1251
+ # instantiate AoC plugin, so that command line options are known
1251
1252
  aoc_api = self.class.plugin_class(params[:plugin_name]).new(@agents.merge({skip_basic_auth_options: true, private_key_path: private_key_path})).aoc_api
1252
1253
  auto_set_pub_key = false
1253
1254
  auto_set_jwt = false
1254
1255
  use_browser_authentication = false
1255
1256
  if options.get_option(:use_generic_client)
1256
- self.format.display_status('Using global client_id.')
1257
- self.format.display_status('Please Login to your Aspera on Cloud instance.'.red)
1258
- self.format.display_status('Navigate to your "Account Settings"'.red)
1259
- self.format.display_status('Check or update the value of "Public Key" to be:'.red.blink)
1260
- self.format.display_status(pub_key_pem.to_s)
1257
+ formatter.display_status('Using global client_id.')
1258
+ formatter.display_status('Please Login to your Aspera on Cloud instance.'.red)
1259
+ formatter.display_status('Navigate to your "Account Settings"'.red)
1260
+ formatter.display_status('Check or update the value of "Public Key" to be:'.red.blink)
1261
+ formatter.display_status(pub_key_pem.to_s)
1261
1262
  if !options.get_option(:test_mode)
1262
- self.format.display_status('Once updated or validated, press enter.')
1263
+ formatter.display_status('Once updated or validated, press enter.')
1263
1264
  OpenApplication.instance.uri(params[:instance_url])
1264
1265
  $stdin.gets
1265
1266
  end
1266
1267
  else
1267
- self.format.display_status('Using organization specific client_id.')
1268
+ formatter.display_status('Using organization specific client_id.')
1268
1269
  if options.get_option(:client_id).nil? || options.get_option(:client_secret, is_type: :optional).nil?
1269
- self.format.display_status('Please login to your Aspera on Cloud instance.'.red)
1270
- self.format.display_status('Go to: Apps->Admin->Organization->Integrations')
1271
- self.format.display_status('Create or check if there is an existing integration named:')
1272
- self.format.display_status("- name: #{@info[:name]}")
1273
- self.format.display_status("- redirect uri: #{DEFAULT_REDIRECT}")
1274
- self.format.display_status('- origin: localhost')
1275
- self.format.display_status('Once created or identified,')
1276
- self.format.display_status('Please enter:'.red)
1270
+ formatter.display_status('Please login to your Aspera on Cloud instance.'.red)
1271
+ formatter.display_status('Go to: Apps->Admin->Organization->Integrations')
1272
+ formatter.display_status('Create or check if there is an existing integration named:')
1273
+ formatter.display_status("- name: #{@info[:name]}")
1274
+ formatter.display_status("- redirect uri: #{DEFAULT_REDIRECT}")
1275
+ formatter.display_status('- origin: localhost')
1276
+ formatter.display_status('Once created or identified,')
1277
+ formatter.display_status('Please enter:'.red)
1277
1278
  end
1278
1279
  OpenApplication.instance.uri("#{params[:instance_url]}/#{AOC_PATH_API_CLIENTS}")
1279
1280
  options.get_option(:client_id, is_type: :mandatory)
@@ -1281,24 +1282,24 @@ module Aspera
1281
1282
  use_browser_authentication = true
1282
1283
  end
1283
1284
  if use_browser_authentication
1284
- self.format.display_status('We will use web authentication to bootstrap.')
1285
+ formatter.display_status('We will use web authentication to bootstrap.')
1285
1286
  auto_set_pub_key = true
1286
1287
  auto_set_jwt = true
1287
- aoc_api.oauth.gparams[:crtype] = :web
1288
- aoc_api.oauth.gparams[:scope] = AoC::SCOPE_FILES_ADMIN
1289
- aoc_api.oauth.sparams[:redirect_uri] = DEFAULT_REDIRECT
1288
+ aoc_api.oauth.generic_parameters[:grant_method] = :web
1289
+ aoc_api.oauth.generic_parameters[:scope] = AoC::SCOPE_FILES_ADMIN
1290
+ aoc_api.oauth.specific_parameters[:redirect_uri] = DEFAULT_REDIRECT
1290
1291
  end
1291
1292
  myself = aoc_api.read('self')[:data]
1292
1293
  if auto_set_pub_key
1293
1294
  raise CliError, 'Public key is already set in profile (use --override=yes)' unless myself['public_key'].empty? || option_override
1294
- self.format.display_status('Updating profile with new key')
1295
+ formatter.display_status('Updating profile with new key')
1295
1296
  aoc_api.update("users/#{myself['id']}", {'public_key' => pub_key_pem})
1296
1297
  end
1297
1298
  if auto_set_jwt
1298
- self.format.display_status('Enabling JWT for client')
1299
+ formatter.display_status('Enabling JWT for client')
1299
1300
  aoc_api.update("clients/#{options.get_option(:client_id)}", {'jwt_grant_enabled' => true, 'explicit_authorization_required' => false})
1300
1301
  end
1301
- self.format.display_status("Creating new config preset: #{params[:preset_name]}")
1302
+ formatter.display_status("Creating new config preset: #{params[:preset_name]}")
1302
1303
  @config_presets[params[:preset_name]] = {
1303
1304
  :url.to_s => options.get_option(:url),
1304
1305
  :username.to_s => myself['email'],
@@ -1314,11 +1315,11 @@ module Aspera
1314
1315
  end
1315
1316
 
1316
1317
  def wizard_faspex5(params)
1317
- self.format.display_status('Detected: Faspex v5'.bold)
1318
+ formatter.display_status('Detected: Faspex v5'.bold)
1318
1319
  # if not defined by user, generate unique name
1319
1320
  params[:preset_name] = [params[:application]].concat(URI.parse(params[:instance_url]).host.gsub(/[^a-z0-9.]/, '').split('.')).join('_') \
1320
1321
  if params[:preset_name].nil?
1321
- self.format.display_status("Preparing preset: #{params[:preset_name]}")
1322
+ formatter.display_status("Preparing preset: #{params[:preset_name]}")
1322
1323
  # init defaults if necessary
1323
1324
  @config_presets[CONF_PRESET_DEFAULT] ||= {}
1324
1325
  option_override = options.get_option(:override, is_type: :mandatory)
@@ -1332,7 +1333,7 @@ module Aspera
1332
1333
  private_key_path = options.get_option(:pkeypath)
1333
1334
  # give a chance to provide
1334
1335
  if private_key_path.nil?
1335
- self.format.display_status('Please provide path to your private RSA key, or empty to generate one:')
1336
+ formatter.display_status('Please provide path to your private RSA key, or empty to generate one:')
1336
1337
  private_key_path = options.get_option(:pkeypath, is_type: :mandatory).to_s
1337
1338
  end
1338
1339
  # else generate path
@@ -1340,25 +1341,25 @@ module Aspera
1340
1341
  private_key_path = File.join(@main_folder, DEFAULT_PRIV_KEY_FILENAME)
1341
1342
  end
1342
1343
  if File.exist?(private_key_path)
1343
- self.format.display_status('Using existing key:')
1344
+ formatter.display_status('Using existing key:')
1344
1345
  else
1345
- self.format.display_status("Generating #{DEFAULT_PRIVKEY_LENGTH} bit RSA key...")
1346
+ formatter.display_status("Generating #{DEFAULT_PRIVKEY_LENGTH} bit RSA key...")
1346
1347
  generate_rsa_private_key(private_key_path, DEFAULT_PRIVKEY_LENGTH)
1347
- self.format.display_status('Created:')
1348
+ formatter.display_status('Created:')
1348
1349
  end
1349
- self.format.display_status(private_key_path)
1350
+ formatter.display_status(private_key_path)
1350
1351
  pub_key_pem = OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
1351
1352
  # declare command line options for AoC
1352
1353
  require 'aspera/cli/plugins/faspex5'
1353
1354
  self.class.plugin_class(params[:plugin_name]).new(@agents.merge({skip_basic_auth_options: true}))
1354
- self.format.display_status('Please login to Faspex 5.'.red)
1355
+ formatter.display_status('Please login to Faspex 5.'.red)
1355
1356
  OpenApplication.instance.uri(params[:instance_url])
1356
- self.format.display_status('Navigate to: 𓃑 → Admin → Configurations → API clients')
1357
- self.format.display_status('Create a client with:')
1358
- self.format.display_status('- JWT enabled')
1359
- self.format.display_status('- The following public key:')
1360
- self.format.display_status(pub_key_pem.to_s)
1361
- self.format.display_status('Once created, copy the following parameters:')
1357
+ formatter.display_status('Navigate to: 𓃑 → Admin → Configurations → API clients')
1358
+ formatter.display_status('Create a client with:')
1359
+ formatter.display_status('- JWT enabled')
1360
+ formatter.display_status('- The following public key:')
1361
+ formatter.display_status(pub_key_pem.to_s)
1362
+ formatter.display_status('Once created, copy the following parameters:')
1362
1363
  @config_presets[params[:preset_name]] = {
1363
1364
  :url.to_s => options.get_option(:url),
1364
1365
  :username.to_s => options.get_option(:username),
@@ -14,7 +14,7 @@ module Aspera
14
14
  options.add_opt_simple(:bucket, 'Bucket name')
15
15
  options.add_opt_simple(:endpoint, 'Storage endpoint url')
16
16
  options.add_opt_simple(:apikey, 'Storage API key')
17
- options.add_opt_simple(:crn, 'Ressource instance id')
17
+ options.add_opt_simple(:crn, 'Resource instance id')
18
18
  options.add_opt_simple(:service_credentials, 'IBM Cloud service credentials (Hash)')
19
19
  options.add_opt_simple(:region, 'Storage region')
20
20
  options.add_opt_simple(:identity, "Authentication url (#{CosNode::IBM_CLOUD_TOKEN_URL})")
@@ -46,24 +46,24 @@ module Aspera
46
46
  if result[:http].body.start_with?('<?xml')
47
47
  res_s = XmlSimple.xml_in(result[:http].body, {'ForceArray' => false})
48
48
  version = res_s['XRD']['application']['version']
49
- return {version: version}
49
+ return {version: version, url: result[:http].uri}
50
50
  end
51
51
  return nil
52
52
  end
53
53
 
54
54
  # extract elements from anonymous faspex link
55
- def get_link_data(publink)
56
- publink_uri = URI.parse(publink)
57
- raise CliBadArgument, 'Public link does not match Faspex format' unless (m = publink_uri.path.match(%r{^(.*)/(external.*)$}))
55
+ def get_link_data(public_url)
56
+ public_uri = URI.parse(public_url)
57
+ raise CliBadArgument, 'Public link does not match Faspex format' unless (m = public_uri.path.match(%r{^(.*)/(external.*)$}))
58
58
  base = m[1]
59
59
  subpath = m[2]
60
- port_add = publink_uri.port.eql?(publink_uri.default_port) ? '' : ":#{publink_uri.port}"
60
+ port_add = public_uri.port.eql?(public_uri.default_port) ? '' : ":#{public_uri.port}"
61
61
  result = {
62
- base_url: "#{publink_uri.scheme}://#{publink_uri.host}#{port_add}#{base}",
62
+ base_url: "#{public_uri.scheme}://#{public_uri.host}#{port_add}#{base}",
63
63
  subpath: subpath,
64
- query: URI.decode_www_form(publink_uri.query).each_with_object({}){|v, h|h[v.first] = v.last; }
64
+ query: URI.decode_www_form(public_uri.query).each_with_object({}){|v, h|h[v.first] = v.last; }
65
65
  }
66
- Log.dump('publink', result)
66
+ Log.dump('link data', result)
67
67
  return result
68
68
  end
69
69
 
@@ -125,12 +125,12 @@ module Aspera
125
125
  @api_v4 = Rest.new({
126
126
  base_url: faspex_api_base + '/api',
127
127
  auth: {
128
- type: :oauth2,
129
- base_url: faspex_api_base + '/auth/oauth2',
130
- auth: {type: :basic, username: options.get_option(:username, is_type: :mandatory), password: options.get_option(:password, is_type: :mandatory)},
131
- crtype: :generic,
132
- generic: {grant_type: 'password'},
133
- scope: 'admin'
128
+ type: :oauth2,
129
+ base_url: faspex_api_base + '/auth/oauth2',
130
+ auth: {type: :basic, username: options.get_option(:username, is_type: :mandatory), password: options.get_option(:password, is_type: :mandatory)},
131
+ grant_method: :generic,
132
+ generic: {grant_type: 'password'},
133
+ scope: 'admin'
134
134
  }})
135
135
  end
136
136
  return @api_v4
@@ -205,7 +205,7 @@ module Aspera
205
205
  end
206
206
 
207
207
  # retrieve transfer spec from pub link for send package
208
- def send_publink_to_ts(public_link_url, package_create_params)
208
+ def send_public_link_to_ts(public_link_url, package_create_params)
209
209
  delivery_info = package_create_params['delivery']
210
210
  # pub link user
211
211
  link_data = self.class.get_link_data(public_link_url)
@@ -215,28 +215,28 @@ module Aspera
215
215
  create_path = link_data[:subpath].split('/')[0..-2].join('/')
216
216
  package_create_params[:passcode] = link_data[:query]['passcode']
217
217
  delivery_info[:transfer_type] = 'connect'
218
- delivery_info[:source_paths_list] = transfer.ts_source_paths.map{|i|i['source']}.join("\r\n")
218
+ delivery_info[:source_paths_list] = transfer.source_list.join("\r\n")
219
219
  api_public_link = Rest.new({base_url: link_data[:base_url]})
220
220
  # Hum, as this does not always work (only user, but not dropbox), we get the javascript and need hack
221
221
  # pkg_created=api_public_link.create(create_path,package_create_params)[:data]
222
222
  # so extract data from javascript
223
- pkgdatares = api_public_link.call({
223
+ package_creation_data = api_public_link.call({
224
224
  operation: 'POST',
225
225
  subpath: create_path,
226
226
  json_params: package_create_params,
227
227
  headers: {'Accept' => 'text/javascript'}})[:http].body
228
228
  # get args of function call
229
- pkgdatares.delete!("\n") # one line
230
- pkgdatares.gsub!(/^[^"]+\("\{/, '{') # delete header
231
- pkgdatares.gsub!(/"\);[^"]+$/, '"') # delete trailer
232
- pkgdatares.gsub!(/\}", *"/, '},"') # between two args
233
- pkgdatares.gsub!('\\"', '"') # remove protecting quote
229
+ package_creation_data.delete!("\n") # one line
230
+ package_creation_data.gsub!(/^[^"]+\("\{/, '{') # delete header
231
+ package_creation_data.gsub!(/"\);[^"]+$/, '"') # delete trailer
232
+ package_creation_data.gsub!(/\}", *"/, '},"') # between two args
233
+ package_creation_data.gsub!('\\"', '"') # remove protecting quote
234
234
  begin
235
- pkgdatares = JSON.parse("[#{pkgdatares}]")
235
+ package_creation_data = JSON.parse("[#{package_creation_data}]")
236
236
  rescue JSON::ParserError # => e
237
237
  raise 'Unexpected response: missing metadata ?'
238
238
  end
239
- return pkgdatares.first
239
+ return package_creation_data.first
240
240
  end
241
241
 
242
242
  ACTIONS = %i[health package source me dropbox v4 address_book login_methods].freeze
@@ -273,7 +273,7 @@ module Aspera
273
273
  # authenticated user
274
274
  delivery_info['sources'] ||= [{'paths' => []}]
275
275
  first_source = delivery_info['sources'].first
276
- first_source['paths'].push(*transfer.ts_source_paths.map{|i|i['source']})
276
+ first_source['paths'].push(*transfer.source_list)
277
277
  source_name = options.get_option(:source_name)
278
278
  if !source_name.nil?
279
279
  source_list = api_v3.call({operation: 'GET', subpath: 'source_shares', headers: {'Accept' => 'application/json'}})[:data]['items']
@@ -294,8 +294,8 @@ module Aspera
294
294
  transfer_spec = pkg_created['xfer_sessions'].first
295
295
  # use source from cmd line, this one only contains destination (already in dest root)
296
296
  transfer_spec.delete('paths')
297
- else # publink
298
- transfer_spec = send_publink_to_ts(public_link_url, package_create_params)
297
+ else # public link
298
+ transfer_spec = send_public_link_to_ts(public_link_url, package_create_params)
299
299
  end
300
300
  # Log.dump('transfer_spec',transfer_spec)
301
301
  return Main.result_transfer(transfer.start(transfer_spec))
@@ -319,15 +319,15 @@ module Aspera
319
319
  ]))
320
320
  end
321
321
  # get command line parameters
322
- delivid = instance_identifier
323
- raise 'empty id' if delivid.empty?
322
+ delivery_id = instance_identifier
323
+ raise 'empty id' if delivery_id.empty?
324
324
  recipient = options.get_option(:recipient)
325
- if VAL_ALL.eql?(delivid)
325
+ if VAL_ALL.eql?(delivery_id)
326
326
  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)}}
327
327
  elsif !recipient.nil? && recipient.start_with?('*')
328
- found_package_link = mailbox_filtered_entries(stop_at_id: delivid).find{|p|p[PACKAGE_MATCH_FIELD].eql?(delivid)}['link'].first['href']
328
+ found_package_link = mailbox_filtered_entries(stop_at_id: delivery_id).find{|p|p[PACKAGE_MATCH_FIELD].eql?(delivery_id)}['link'].first['href']
329
329
  raise 'Not Found. Dropbox and Workgroup packages can use the link option with faspe:' if found_package_link.nil?
330
- pkg_id_uri = [{id: delivid, uri: found_package_link}]
330
+ pkg_id_uri = [{id: delivery_id, uri: found_package_link}]
331
331
  else
332
332
  # TODO: delivery id is the right one if package was receive by workgroup
333
333
  endpoint =
@@ -335,9 +335,9 @@ module Aspera
335
335
  when :inbox, :archive then'received'
336
336
  when :sent then 'sent'
337
337
  end
338
- entry_xml = api_v3.call({operation: 'GET', subpath: "#{endpoint}/#{delivid}", headers: {'Accept' => 'application/xml'}})[:http].body
338
+ entry_xml = api_v3.call({operation: 'GET', subpath: "#{endpoint}/#{delivery_id}", headers: {'Accept' => 'application/xml'}})[:http].body
339
339
  package_entry = XmlSimple.xml_in(entry_xml, {'ForceArray' => true})
340
- pkg_id_uri = [{id: delivid, uri: self.class.get_fasp_uri_from_entry(package_entry)}]
340
+ pkg_id_uri = [{id: delivery_id, uri: self.class.get_fasp_uri_from_entry(package_entry)}]
341
341
  end
342
342
  when /^faspe:/
343
343
  pkg_id_uri = [{id: 'package', uri: link_url}]
@@ -348,16 +348,16 @@ module Aspera
348
348
  end
349
349
  # NOTE: unauthenticated API (authorization is in url params)
350
350
  api_public_link = Rest.new({base_url: link_data[:base_url]})
351
- pkgdatares = api_public_link.call(
351
+ package_creation_data = api_public_link.call(
352
352
  operation: 'GET',
353
353
  subpath: link_data[:subpath],
354
354
  url_params: {passcode: link_data[:query]['passcode']},
355
355
  headers: {'Accept' => 'application/xml'})
356
- if !pkgdatares[:http].body.start_with?('<?xml ')
356
+ if !package_creation_data[:http].body.start_with?('<?xml ')
357
357
  OpenApplication.instance.uri(link_url)
358
358
  raise CliError, 'Unexpected response: package not found ?'
359
359
  end
360
- package_entry = XmlSimple.xml_in(pkgdatares[:http].body, {'ForceArray' => false})
360
+ package_entry = XmlSimple.xml_in(package_creation_data[:http].body, {'ForceArray' => false})
361
361
  Log.dump(:package_entry, package_entry)
362
362
  transfer_uri = self.class.get_fasp_uri_from_entry(package_entry)
363
363
  pkg_id_uri = [{id: package_entry['id'], uri: transfer_uri}]
@@ -480,7 +480,7 @@ module Aspera
480
480
  headers: {'Accept' => 'application/json'},
481
481
  url_params: {'format' => 'json', 'count' => 100_000}
482
482
  )[:data]
483
- self.format.display_status("users: #{result['itemsPerPage']}/#{result['totalResults']}, start:#{result['startIndex']}")
483
+ formatter.display_status("users: #{result['itemsPerPage']}/#{result['totalResults']}, start:#{result['startIndex']}")
484
484
  users = result['entry']
485
485
  # add missing entries
486
486
  users.each do |u|