aspera-cli 4.24.1 → 4.24.2

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 (87) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +15 -2
  4. data/README.md +745 -436
  5. data/bin/ascli +20 -1
  6. data/bin/asession +23 -27
  7. data/lib/aspera/agent/base.rb +10 -21
  8. data/lib/aspera/agent/connect.rb +2 -3
  9. data/lib/aspera/agent/desktop.rb +2 -2
  10. data/lib/aspera/agent/direct.rb +49 -32
  11. data/lib/aspera/agent/factory.rb +31 -0
  12. data/lib/aspera/api/aoc.rb +79 -49
  13. data/lib/aspera/api/faspex.rb +212 -0
  14. data/lib/aspera/api/node.rb +99 -84
  15. data/lib/aspera/ascp/installation.rb +22 -21
  16. data/lib/aspera/ascp/management.rb +119 -23
  17. data/lib/aspera/assert.rb +14 -8
  18. data/lib/aspera/cli/extended_value.rb +15 -15
  19. data/lib/aspera/cli/formatter.rb +7 -5
  20. data/lib/aspera/cli/hints.rb +8 -0
  21. data/lib/aspera/cli/info.rb +4 -4
  22. data/lib/aspera/cli/main.rb +55 -70
  23. data/lib/aspera/cli/manager.rb +7 -4
  24. data/lib/aspera/cli/plugins/alee.rb +2 -1
  25. data/lib/aspera/cli/plugins/aoc.rb +110 -186
  26. data/lib/aspera/cli/plugins/ats.rb +4 -4
  27. data/lib/aspera/cli/plugins/base.rb +335 -0
  28. data/lib/aspera/cli/plugins/basic_auth.rb +45 -0
  29. data/lib/aspera/cli/plugins/config.rb +249 -220
  30. data/lib/aspera/cli/plugins/console.rb +15 -15
  31. data/lib/aspera/cli/plugins/cos.rb +2 -2
  32. data/lib/aspera/cli/plugins/factory.rb +78 -0
  33. data/lib/aspera/cli/plugins/faspex.rb +17 -20
  34. data/lib/aspera/cli/plugins/faspex5.rb +79 -193
  35. data/lib/aspera/cli/plugins/faspio.rb +14 -13
  36. data/lib/aspera/cli/plugins/httpgw.rb +13 -12
  37. data/lib/aspera/cli/plugins/node.rb +34 -32
  38. data/lib/aspera/cli/plugins/oauth.rb +48 -0
  39. data/lib/aspera/cli/plugins/orchestrator.rb +15 -13
  40. data/lib/aspera/cli/plugins/preview.rb +4 -4
  41. data/lib/aspera/cli/plugins/server.rb +15 -13
  42. data/lib/aspera/cli/plugins/shares.rb +18 -15
  43. data/lib/aspera/cli/sync_actions.rb +1 -1
  44. data/lib/aspera/cli/transfer_agent.rb +24 -20
  45. data/lib/aspera/cli/transfer_progress.rb +6 -6
  46. data/lib/aspera/cli/version.rb +3 -3
  47. data/lib/aspera/cli/wizard.rb +65 -53
  48. data/lib/aspera/colors.rb +6 -0
  49. data/lib/aspera/command_line_builder.rb +45 -50
  50. data/lib/aspera/command_line_converter.rb +2 -1
  51. data/lib/aspera/coverage.rb +1 -1
  52. data/lib/aspera/data_repository.rb +1 -1
  53. data/lib/aspera/environment.rb +10 -7
  54. data/lib/aspera/faspex_gw.rb +6 -4
  55. data/lib/aspera/faspex_postproc.rb +1 -1
  56. data/lib/aspera/keychain/macos_security.rb +1 -1
  57. data/lib/aspera/log.rb +37 -9
  58. data/lib/aspera/nagios.rb +1 -1
  59. data/lib/aspera/oauth/base.rb +17 -10
  60. data/lib/aspera/oauth/factory.rb +8 -8
  61. data/lib/aspera/oauth/web.rb +2 -2
  62. data/lib/aspera/products/connect.rb +4 -3
  63. data/lib/aspera/products/desktop.rb +1 -4
  64. data/lib/aspera/products/other.rb +9 -1
  65. data/lib/aspera/products/transferd.rb +0 -1
  66. data/lib/aspera/rest.rb +126 -83
  67. data/lib/aspera/ssh.rb +3 -3
  68. data/lib/aspera/sync/args.schema.yaml +46 -3
  69. data/lib/aspera/sync/conf.schema.yaml +130 -94
  70. data/lib/aspera/sync/operations.rb +16 -16
  71. data/lib/aspera/temp_file_manager.rb +17 -5
  72. data/lib/aspera/transfer/error.rb +16 -7
  73. data/lib/aspera/transfer/parameters.rb +34 -20
  74. data/lib/aspera/transfer/resumer.rb +74 -0
  75. data/lib/aspera/transfer/spec.rb +4 -3
  76. data/lib/aspera/transfer/spec.schema.yaml +132 -51
  77. data/lib/aspera/transfer/spec_doc.rb +41 -35
  78. data/lib/aspera/uri_reader.rb +1 -1
  79. data/lib/aspera/web_auth.rb +6 -6
  80. data.tar.gz.sig +0 -0
  81. metadata +9 -7
  82. metadata.gz.sig +0 -0
  83. data/lib/aspera/cli/basic_auth_plugin.rb +0 -43
  84. data/lib/aspera/cli/plugin.rb +0 -333
  85. data/lib/aspera/cli/plugin_factory.rb +0 -81
  86. data/lib/aspera/resumer.rb +0 -77
  87. data/lib/aspera/transfer/error_info.rb +0 -91
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # cspell:ignore snid fnid bidi ssync asyncs rund asnodeadmin mkfile mklink asperabrowser asperabrowserurl watchfolders watchfolderd entsrv
4
- require 'aspera/cli/basic_auth_plugin'
4
+ require 'aspera/cli/plugins/basic_auth'
5
5
  require 'aspera/cli/sync_actions'
6
6
  require 'aspera/cli/special_values'
7
7
  require 'aspera/transfer/spec'
@@ -9,7 +9,6 @@ require 'aspera/nagios'
9
9
  require 'aspera/hash_ext'
10
10
  require 'aspera/id_generator'
11
11
  require 'aspera/api/node'
12
- require 'aspera/api/aoc'
13
12
  require 'aspera/oauth'
14
13
  require 'aspera/node_simulator'
15
14
  require 'aspera/assert'
@@ -19,7 +18,7 @@ require 'zlib'
19
18
  module Aspera
20
19
  module Cli
21
20
  module Plugins
22
- class Node < Cli::BasicAuthPlugin
21
+ class Node < BasicAuth
23
22
  include SyncActions
24
23
 
25
24
  class << self
@@ -62,18 +61,6 @@ module Aspera
62
61
  return
63
62
  end
64
63
 
65
- def wizard(object:, _private_key_path: nil, _pub_key_pem: nil)
66
- options = object.options
67
- return {
68
- preset_value: {
69
- url: options.get_option(:url, mandatory: true),
70
- username: options.get_option(:username, mandatory: true),
71
- password: options.get_option(:password, mandatory: true)
72
- },
73
- test_args: 'info'
74
- }
75
- end
76
-
77
64
  def declare_options(options)
78
65
  return if @options_declared
79
66
  @options_declared = true
@@ -100,6 +87,20 @@ module Aspera
100
87
  end
101
88
  end
102
89
 
90
+ # @param wizard [Wizard] The wizard object
91
+ # @param app_url [Wizard] The wizard object
92
+ # @return [Hash] :preset_value, :test_args
93
+ def wizard(wizard, app_url)
94
+ return {
95
+ preset_value: {
96
+ url: app_url,
97
+ username: options.get_option(:username, mandatory: true),
98
+ password: options.get_option(:password, mandatory: true)
99
+ },
100
+ test_args: 'info'
101
+ }
102
+ end
103
+
103
104
  # spellchecker: disable
104
105
  # SOAP API call to test central API
105
106
  CENTRAL_SOAP_API_TEST = '<?xml version="1.0" encoding="UTF-8"?>' \
@@ -395,9 +396,9 @@ module Aspera
395
396
  when *COMMANDS_GEN3
396
397
  execute_command_gen3(command)
397
398
  when :access_keys
398
- ak_command = options.get_next_command(%i[do set_bearer_key].concat(Plugin::ALL_OPS))
399
+ ak_command = options.get_next_command(%i[do set_bearer_key].concat(ALL_OPS))
399
400
  case ak_command
400
- when *Plugin::ALL_OPS
401
+ when *ALL_OPS
401
402
  return entity_execute(
402
403
  api: @api_node,
403
404
  entity: 'access_keys',
@@ -437,7 +438,7 @@ module Aspera
437
438
  nagios.add_ok('node api', 'accessible')
438
439
  nagios.check_time_offset(info['current_time'], 'node api')
439
440
  nagios.check_product_version('node api', 'entsrv', info['version'])
440
- rescue StandardError => e
441
+ rescue RestCallError => e
441
442
  nagios.add_critical('node api', e.to_s)
442
443
  end
443
444
  begin
@@ -475,7 +476,7 @@ module Aspera
475
476
  # Allows to specify a file by its path or by its id on the node in command line
476
477
  # @return [Hash] api and main file id for given path or id in next argument
477
478
  def apifid_from_next_arg(top_file_id)
478
- file_path = instance_identifier(description: 'path or %id:<id>') do |attribute, value|
479
+ file_path = instance_identifier(description: 'path or %id:<id> or %id:') do |attribute, value|
479
480
  raise BadArgument, 'Only selection "id" is supported (file id)' unless attribute.eql?('id')
480
481
  # directly return result for method
481
482
  return {api: @api_node, file_id: value}
@@ -517,12 +518,12 @@ module Aspera
517
518
  return Main.result_text(result[:password])
518
519
  when :browse
519
520
  apifid = apifid_from_next_arg(top_file_id)
520
- file_info = apifid[:api].read_with_cache("files/#{apifid[:file_id]}")
521
+ file_info = apifid[:api].read("files/#{apifid[:file_id]}", **Api::Node.cache_control)
521
522
  unless file_info['type'].eql?('folder')
522
523
  # a single file
523
524
  return Main.result_object_list([file_info], fields: GEN4_LS_FIELDS)
524
525
  end
525
- return Main.result_object_list(apifid[:api].list_files(apifid[:file_id]), fields: GEN4_LS_FIELDS)
526
+ return Main.result_object_list(apifid[:api].list_files(apifid[:file_id], query: query_read_delete), fields: GEN4_LS_FIELDS)
526
527
  when :find
527
528
  apifid = apifid_from_next_arg(top_file_id)
528
529
  find_lambda = Api::Node.file_matcher_from_argument(options)
@@ -628,7 +629,7 @@ module Aspera
628
629
  command_perm = options.get_next_command(%i[list show create delete])
629
630
  case command_perm
630
631
  when :list
631
- list_query = query_read_delete(default: {'include' => Rest.array_params(%w[access_level permission_count])})
632
+ list_query = query_read_delete(default: Rest.php_style({'include' => %w[access_level permission_count]}))
632
633
  # specify file to get permissions for unless not specified
633
634
  list_query['file_id'] = apifid[:file_id] unless apifid[:file_id].to_s.empty?
634
635
  list_query['inherited'] = false if list_query.key?('file_id') && !list_query.key?('inherited')
@@ -820,9 +821,9 @@ module Aspera
820
821
  when :async then return execute_async # former API
821
822
  when :ssync
822
823
  # Node API: /asyncs (newer)
823
- sync_command = options.get_next_command(%i[start stop bandwidth counters files state summary] + Plugin::ALL_OPS - %i[modify])
824
+ sync_command = options.get_next_command(%i[start stop bandwidth counters files state summary] + ALL_OPS - %i[modify])
824
825
  case sync_command
825
- when *Plugin::ALL_OPS
826
+ when *ALL_OPS
826
827
  return entity_execute(
827
828
  api: @api_node,
828
829
  entity: :asyncs,
@@ -893,21 +894,22 @@ module Aspera
893
894
  return Main.result_object_list(transfers_data, fields: %w[id status start_spec.direction start_spec.remote_user start_spec.remote_host start_spec.destination_path])
894
895
  when :sessions
895
896
  transfers_data = @api_node.read('ops/transfers', query_read_delete)
896
- sessions = transfers_data.map{ |t| t['sessions']}.flatten
897
+ sessions = transfers_data.flat_map{ |t| t['sessions']}
897
898
  sessions.each do |session|
898
- session['start_time'] = Time.at(session['start_time_usec'] / 1_000_000.0).utc.iso8601(0)
899
- session['end_time'] = Time.at(session['end_time_usec'] / 1_000_000.0).utc.iso8601(0)
899
+ %i[start end].each do |what|
900
+ session["#{what}_time"] = session["#{what}_time_usec"] ? Time.at(session["#{what}_time_usec"] / 1_000_000.0).utc.iso8601(0) : nil
901
+ end
900
902
  end
901
903
  return Main.result_object_list(sessions, fields: %w[id status start_time end_time target_rate_kbps])
902
904
  when :cancel
903
- resp = @api_node.cancel("ops/transfers/#{instance_identifier}")
904
- return Main.result_single_object(resp)
905
+ @api_node.cancel("ops/transfers/#{instance_identifier}")
906
+ return Main.result_status('Cancelled')
905
907
  when :show
906
908
  resp = @api_node.read("ops/transfers/#{instance_identifier}")
907
909
  return Main.result_single_object(resp)
908
910
  when :modify
909
- resp = @api_node.update("ops/transfers/#{instance_identifier}", options.get_next_argument('update value', validation: Hash))
910
- return Main.result_single_object(resp)
911
+ @api_node.update("ops/transfers/#{instance_identifier}", options.get_next_argument('update value', validation: Hash))
912
+ return Main.result_status('Modified')
911
913
  when :bandwidth_average
912
914
  transfers_data = @api_node.read('ops/transfers', query_read_delete)
913
915
  # collect all key dates
@@ -1148,7 +1150,7 @@ module Aspera
1148
1150
  unless link_info.nil?
1149
1151
  m = link_info.match(/<([^>]+)>/)
1150
1152
  Aspera.assert(m){"Cannot parse iteration in Link: #{link_info}"}
1151
- next_iteration_token = CGI.parse(URI.parse(m[1]).query)['iteration_token']&.first
1153
+ next_iteration_token = Rest.query_to_h(URI.parse(m[1]).query)['iteration_token']
1152
1154
  end
1153
1155
  # same as last iteration: stop
1154
1156
  break if next_iteration_token&.eql?(query_token[:iteration_token])
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aspera/cli/plugins/basic_auth'
4
+
5
+ module Aspera
6
+ module Cli
7
+ module Plugins
8
+ # base class for applications supporting OAuth 2.0 authentication
9
+ class Oauth < BasicAuth
10
+ # OAuth methods supported
11
+ AUTH_TYPES = %i[web jwt boot].freeze
12
+ # Options used for authentication
13
+ AUTH_OPTIONS = %i[url auth client_id client_secret scope redirect_uri private_key passphrase username password].freeze
14
+ def initialize(**_)
15
+ super
16
+ options.declare(:auth, 'OAuth type of authentication', values: AUTH_TYPES, default: :jwt)
17
+ options.declare(:client_id, 'OAuth client identifier')
18
+ options.declare(:client_secret, 'OAuth client secret')
19
+ options.declare(:redirect_uri, 'OAuth (Web) redirect URI for web authentication')
20
+ options.declare(:private_key, 'OAuth (JWT) RSA private key PEM value (prefix file path with @file:)')
21
+ options.declare(:passphrase, 'OAuth (JWT) RSA private key passphrase')
22
+ options.declare(:scope, 'OAuth scope for API calls')
23
+ end
24
+
25
+ # Get all options specified by AUTH_OPTIONS and add.keys
26
+ # Adds those not nil to the `base`.
27
+ # Instantiate the provided `klass` with those kwargs.
28
+ # `add` can specify a default value (not `nil`)
29
+ # @param klass [Class] API object to create
30
+ # @param base [Hash] The base options for creation
31
+ # @param add [Hash] Additional options, key=symbol, value:default value or nil
32
+ def new_with_options(klass, base: {}, add: {})
33
+ klass.new(**
34
+ (AUTH_OPTIONS + add.keys).each_with_object(base) do |i, m|
35
+ v = options.get_option(i)
36
+ m[i] = v unless v.nil?
37
+ m[i] = add[i] unless !m[i].nil? || add[i].nil?
38
+ end)
39
+ rescue ::ArgumentError => e
40
+ if (m = e.message.match(/missing keyword: :(.*)$/))
41
+ raise Cli::Error, "Missing option: #{m[1]}"
42
+ end
43
+ raise
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'aspera/cli/basic_auth_plugin'
3
+ require 'aspera/cli/plugins/basic_auth'
4
4
  require 'aspera/cli/special_values'
5
5
  require 'aspera/nagios'
6
6
  require 'aspera/log'
@@ -10,7 +10,7 @@ require 'xmlsimple'
10
10
  module Aspera
11
11
  module Cli
12
12
  module Plugins
13
- class Orchestrator < Cli::BasicAuthPlugin
13
+ class Orchestrator < BasicAuth
14
14
  STANDARD_PATH = '/aspera/orchestrator'
15
15
  TEST_ENDPOINT = 'api/remote_node_ping'
16
16
  private_constant :STANDARD_PATH, :TEST_ENDPOINT
@@ -37,18 +37,20 @@ module Aspera
37
37
  raise error if error
38
38
  return
39
39
  end
40
+ end
40
41
 
41
- def wizard(object:)
42
- options = object.options
43
- return {
44
- preset_value: {
45
- url: options.get_option(:url, mandatory: true),
46
- username: options.get_option(:username, mandatory: true),
47
- password: options.get_option(:password, mandatory: true)
48
- },
49
- test_args: 'workflow list'
50
- }
51
- end
42
+ # @param wizard [Wizard] The wizard object
43
+ # @param app_url [Wizard] The wizard object
44
+ # @return [Hash] :preset_value, :test_args
45
+ def wizard(wizard, app_url)
46
+ return {
47
+ preset_value: {
48
+ url: app_url,
49
+ username: options.get_option(:username, mandatory: true),
50
+ password: options.get_option(:password, mandatory: true)
51
+ },
52
+ test_args: 'workflow list'
53
+ }
52
54
  end
53
55
 
54
56
  def initialize(**_)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # cspell:ignore trevents
4
- require 'aspera/cli/basic_auth_plugin'
4
+ require 'aspera/cli/plugins/basic_auth'
5
5
  require 'aspera/preview/generator'
6
6
  require 'aspera/preview/options'
7
7
  require 'aspera/preview/utils'
@@ -9,6 +9,7 @@ require 'aspera/preview/file_types'
9
9
  require 'aspera/preview/terminal'
10
10
  require 'aspera/transfer/spec'
11
11
  require 'aspera/persistency_action_once'
12
+ require 'aspera/temp_file_manager'
12
13
  require 'aspera/api/node'
13
14
  require 'aspera/hash_ext'
14
15
  require 'aspera/timer_limiter'
@@ -20,7 +21,7 @@ require 'securerandom'
20
21
  module Aspera
21
22
  module Cli
22
23
  module Plugins
23
- class Preview < Cli::BasicAuthPlugin
24
+ class Preview < BasicAuth
24
25
  # special tag to identify transfers related to generator
25
26
  PREV_GEN_TAG = 'preview_generator'
26
27
  # defined by node API: suffix for folder containing previews
@@ -74,7 +75,6 @@ module Aspera
74
75
  )
75
76
  options.declare(:skip_types, 'Skip types in comma separated list', handler: {o: self, m: :option_skip_types})
76
77
  options.declare(:previews_folder, 'Preview folder in storage root', handler: {o: self, m: :option_previews_folder}, default: DEFAULT_PREVIEWS_FOLDER)
77
- options.declare(:temp_folder, 'Path to temp folder', default: Dir.tmpdir)
78
78
  options.declare(:skip_folders, 'List of folder to skip', handler: {o: self, m: :option_skip_folders}, default: [])
79
79
  options.declare(:base, 'Basename of output for for test')
80
80
  options.declare(:scan_path, 'Subpath in folder id to start scan in (default=/)')
@@ -100,7 +100,7 @@ module Aspera
100
100
 
101
101
  options.parse_options!
102
102
  Aspera.assert_type(@option_skip_folders, Array){'skip_folder'}
103
- @tmp_folder = File.join(options.get_option(:temp_folder, mandatory: true), "#{TMP_DIR_PREFIX}.#{SecureRandom.uuid}")
103
+ @tmp_folder = File.join(TempFileManager.instance.global_temp, "#{TMP_DIR_PREFIX}.#{SecureRandom.uuid}")
104
104
  FileUtils.mkdir_p(@tmp_folder)
105
105
  Log.log.debug{"tmpdir: #{@tmp_folder}"}
106
106
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # cspell:ignore ascmd zmode zuid zgid fasping
4
- require 'aspera/cli/basic_auth_plugin'
4
+ require 'aspera/cli/plugins/basic_auth'
5
5
  require 'aspera/cli/sync_actions'
6
6
  require 'aspera/transfer/spec'
7
7
  require 'aspera/ascmd'
@@ -14,7 +14,7 @@ module Aspera
14
14
  module Cli
15
15
  module Plugins
16
16
  # Operations on HSTS with SSH/FASP (ascmd/ascp)
17
- class Server < Cli::BasicAuthPlugin
17
+ class Server < BasicAuth
18
18
  include SyncActions
19
19
 
20
20
  SSH_SCHEME = 'ssh'
@@ -67,18 +67,20 @@ module Aspera
67
67
  raise error if error
68
68
  return
69
69
  end
70
+ end
70
71
 
71
- def wizard(object:)
72
- options = object.options
73
- return {
74
- preset_value: {
75
- url: options.get_option(:url, mandatory: true),
76
- username: options.get_option(:username, mandatory: true),
77
- password: options.get_option(:password, mandatory: true)
78
- },
79
- test_args: 'files br /'
80
- }
81
- end
72
+ # @param wizard [Wizard] The wizard object
73
+ # @param app_url [Wizard] The wizard object
74
+ # @return [Hash] :preset_value, :test_args
75
+ def wizard(wizard, app_url)
76
+ return {
77
+ preset_value: {
78
+ url: app_url,
79
+ username: options.get_option(:username, mandatory: true),
80
+ password: options.get_option(:password, mandatory: true)
81
+ },
82
+ test_args: 'files browse /'
83
+ }
82
84
  end
83
85
 
84
86
  def initialize(**_)
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'aspera/cli/plugins/basic_auth'
3
4
  require 'aspera/cli/plugins/node'
4
5
  require 'aspera/assert'
5
6
  module Aspera
6
7
  module Cli
7
8
  module Plugins
8
9
  # Plugin for Aspera Shares v1
9
- class Shares < Cli::BasicAuthPlugin
10
+ class Shares < BasicAuth
10
11
  # path for node API after base url
11
12
  NODE_API_PATH = 'node_api'
12
13
  # path for node admin after base url
@@ -34,18 +35,20 @@ module Aspera
34
35
  url: address_or_url
35
36
  }
36
37
  end
38
+ end
37
39
 
38
- def wizard(object:)
39
- options = object.options
40
- return {
41
- preset_value: {
42
- url: options.get_option(:url, mandatory: true),
43
- username: options.get_option(:username, mandatory: true),
44
- password: options.get_option(:password, mandatory: true)
45
- },
46
- test_args: 'files br /'
47
- }
48
- end
40
+ # @param wizard [Wizard] The wizard object
41
+ # @param app_url [Wizard] The wizard object
42
+ # @return [Hash] :preset_value, :test_args
43
+ def wizard(wizard, app_url)
44
+ return {
45
+ preset_value: {
46
+ url: app_url,
47
+ username: options.get_option(:username, mandatory: true),
48
+ password: options.get_option(:password, mandatory: true)
49
+ },
50
+ test_args: 'files browse /'
51
+ }
49
52
  end
50
53
 
51
54
  def initialize(**_)
@@ -91,9 +94,9 @@ module Aspera
91
94
  when :node
92
95
  return entity_execute(api: api_shares_admin, entity: 'data/nodes')
93
96
  when :share
94
- share_command = options.get_next_command(%i[user_permissions group_permissions].concat(Plugin::ALL_OPS))
97
+ share_command = options.get_next_command(%i[user_permissions group_permissions].concat(ALL_OPS))
95
98
  case share_command
96
- when *Plugin::ALL_OPS
99
+ when *ALL_OPS
97
100
  return entity_execute(
98
101
  api: api_shares_admin,
99
102
  entity: 'data/shares',
@@ -135,7 +138,7 @@ module Aspera
135
138
  end
136
139
  entity_verb = options.get_next_command(entity_commands)
137
140
  case entity_verb
138
- when *Plugin::ALL_OPS # list, show, delete, create, modify
141
+ when *ALL_OPS # list, show, delete, create, modify
139
142
  display_fields = entity_type.eql?(:user) ? %w[id username first_name last_name email] : nil
140
143
  display_fields.push(:directory_user) if entity_type.eql?(:user) && entities_location.eql?(:all)
141
144
  return entity_execute(
@@ -9,7 +9,7 @@ module Aspera
9
9
  module Cli
10
10
  # Manage command line arguments to provide to Sync::Run, Sync::Database and Sync::Operations
11
11
  module SyncActions
12
- # translate state id (int) to string
12
+ # Translate state id (int) to string
13
13
  STATE_STR = (['Nil'] +
14
14
  (1..18).map{ |i| "P(#{i})"} +
15
15
  %w[Syncd Error Confl Pconf] +
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'aspera/agent/base'
3
+ require 'aspera/agent/factory'
4
4
  require 'aspera/transfer/spec'
5
5
  require 'aspera/cli/info'
6
6
  require 'aspera/log'
@@ -9,8 +9,8 @@ require 'aspera/assert'
9
9
  module Aspera
10
10
  module Cli
11
11
  # The Transfer agent is a common interface to start a transfer using
12
- # one of the supported transfer agents
13
- # provides CLI options to select one of the transfer agents (FASP/ascp client)
12
+ # one of the supported transfer agents.
13
+ # Provide CLI options to select one of the transfer agents (FASP/ascp client)
14
14
  class TransferAgent
15
15
  # @args special value for --sources : read file list from arguments
16
16
  FILE_LIST_FROM_ARGS = '@args'
@@ -27,12 +27,11 @@ module Aspera
27
27
  <%=ts.to_yaml%>
28
28
  END_OF_TEMPLATE
29
29
  CP4I_REMOTE_HOST_LB = 'N/A'
30
- # % (formatting bug in eclipse)
31
30
  private_constant :FILE_LIST_FROM_ARGS,
32
31
  :FILE_LIST_FROM_TRANSFER_SPEC,
33
32
  :FILE_LIST_OPTIONS,
34
33
  :DEFAULT_TRANSFER_NOTIFY_TEMPLATE
35
- TRANSFER_AGENTS = Agent::Base.agent_list.freeze
34
+ TRANSFER_AGENTS = Agent::Factory.instance.list.freeze
36
35
 
37
36
  class << self
38
37
  # @return :success if all sessions statuses returned by "start" are success
@@ -44,7 +43,8 @@ module Aspera
44
43
  end
45
44
  end
46
45
 
47
- # @param env external objects: option manager, config file manager
46
+ # @param opt_mgr [Manager] Option manager
47
+ # @param config_plugin [Config] Config plugin
48
48
  def initialize(opt_mgr, config_plugin)
49
49
  @opt_mgr = opt_mgr
50
50
  @config = config_plugin
@@ -82,18 +82,20 @@ module Aspera
82
82
 
83
83
  def option_transfer_spec; @transfer_spec_command_line; end
84
84
 
85
- # multiple option are merged
85
+ # Multiple option are merged
86
+ # @param value [Hash] Transfer spec
86
87
  def option_transfer_spec=(value)
87
88
  Aspera.assert_type(value, Hash){'ts'}
88
89
  @transfer_spec_command_line.deep_merge!(value)
89
90
  end
90
91
 
91
- # add other transfer spec parameters
92
+ # Add other transfer spec parameters
92
93
  def option_transfer_spec_deep_merge(value); @transfer_spec_command_line.deep_merge!(value); end
93
94
 
94
95
  attr_reader :transfer_info
95
96
 
96
- # multiple option are merged
97
+ # Multiple option are merged
98
+ # @param value [Hash]
97
99
  def transfer_info=(value)
98
100
  @transfer_info.deep_merge!(value)
99
101
  end
@@ -103,19 +105,20 @@ module Aspera
103
105
  end
104
106
 
105
107
  # analyze options and create new agent if not already created or set
106
- # TODO: make a Factory pattern
107
108
  def agent_instance
108
109
  return @agent unless @agent.nil?
109
110
  agent_type = @opt_mgr.get_option(:transfer, mandatory: true)
110
111
  # set keys as symbols
111
112
  agent_options = @opt_mgr.get_option(:transfer_info).symbolize_keys
113
+ agent_options[:progress] = @config.progress_bar
114
+ agent_options[:config_dir] = @config.main_folder
112
115
  # special cases
113
116
  case agent_type
114
117
  when :node
115
- if agent_options.empty?
118
+ if !agent_options.key?(:url)
116
119
  param_set_name = @config.get_plugin_default_config_name(:node)
117
120
  raise Cli::BadArgument, "No default node configured. Please specify #{Manager.option_name_to_line(:transfer_info)}" if param_set_name.nil?
118
- agent_options = @config.preset_by_name(param_set_name).symbolize_keys
121
+ agent_options.merge!(@config.preset_by_name(param_set_name).symbolize_keys)
119
122
  end
120
123
  when :direct
121
124
  # by default do not display ascp native progress bar
@@ -129,16 +132,15 @@ module Aspera
129
132
  agent_options[:url] = @httpgw_url_lambda.call
130
133
  end
131
134
  end
132
- agent_options[:progress] = @config.progress_bar
133
135
  # get agent instance
134
- self.agent_instance = Agent::Base.factory_create(agent_type, agent_options)
136
+ self.agent_instance = Agent::Factory.instance.create(agent_type, agent_options)
135
137
  Log.log.debug{"transfer agent is a #{@agent.class}"}
136
138
  return @agent
137
139
  end
138
140
 
139
- # return destination folder for transfers
140
- # sets default if needed
141
- # param: 'send' or 'receive'
141
+ # Get destination folder
142
+ # @param direction [String] `send`` or `receive``
143
+ # @return [String] Destination folder for transfers (with default based on direction)
142
144
  def destination_folder(direction)
143
145
  dest_folder = @opt_mgr.get_option(:to_folder)
144
146
  # do not expand path, if user wants to expand path: user @path:
@@ -161,12 +163,14 @@ module Aspera
161
163
  end
162
164
  end
163
165
 
166
+ # @param httpgw_url_proc [Proc]
164
167
  def httpgw_url_cb=(httpgw_url_proc)
165
168
  Aspera.assert_type(httpgw_url_proc, Proc){'httpgw_url_cb'}
166
169
  @httpgw_url_lambda = httpgw_url_proc
167
170
  end
168
171
 
169
- # transform the list of paths to a list of hash with source/dest
172
+ # Transform the list of paths to a list of hash with source/dest
173
+ # @param file_list [Array]
170
174
  def list_to_paths(file_list)
171
175
  source_type = @opt_mgr.get_option(:src_type, mandatory: true)
172
176
  case source_type
@@ -220,9 +224,9 @@ module Aspera
220
224
  return @transfer_paths
221
225
  end
222
226
 
223
- # start a transfer and wait for completion, plugins shall use this method
227
+ # Start a transfer and wait for completion, plugins shall use this method
224
228
  # @param transfer_spec [Hash]
225
- # @param rest_token [Rest] if oauth token regeneration supported
229
+ # @param rest_token [Rest] if oauth token regeneration supported
226
230
  def start(transfer_spec, rest_token: nil)
227
231
  # check parameters
228
232
  Aspera.assert_type(transfer_spec, Hash){'transfer_spec'}
@@ -13,7 +13,7 @@ module Aspera
13
13
  class TransferProgress
14
14
  def initialize
15
15
  @progress_bar = nil
16
- # key is session id
16
+ # Key is session id
17
17
  @sessions = {}
18
18
  @completed = false
19
19
  @title = nil
@@ -42,21 +42,21 @@ module Aspera
42
42
  progress_provided = false
43
43
  case type
44
44
  when :sessions_init
45
- # give opportunity to show progress of initialization with multiple status
45
+ # Give opportunity to show progress of initialization with multiple status
46
46
  Aspera.assert(session_id.nil?)
47
47
  Aspera.assert_type(info, String)
48
- # initialization of progress bar
48
+ # Initialization of progress bar
49
49
  @title = info
50
50
  when :session_start
51
51
  Aspera.assert_type(session_id, String)
52
52
  Aspera.assert(info.nil?)
53
53
  raise "Session #{session_id} already started" if @sessions[session_id]
54
54
  @sessions[session_id] = {
55
- job_size: 0, # total size of transfer (pre-calc)
55
+ job_size: 0, # Total size of transfer (pre-calc)
56
56
  current: 0,
57
57
  running: true
58
58
  }
59
- # remove last pre-start message if any
59
+ # Remove last pre-start message if any
60
60
  @title = nil
61
61
  when :session_size
62
62
  Aspera.assert_type(session_id, String)
@@ -77,7 +77,7 @@ module Aspera
77
77
  when :session_end
78
78
  Aspera.assert_type(session_id, String)
79
79
  Aspera.assert(info.nil?)
80
- # a session may be too short and finish before it has been started
80
+ # A session may be too short and finish before it has been started
81
81
  @sessions[session_id][:running] = false if @sessions[session_id].is_a?(Hash)
82
82
  when :end
83
83
  Aspera.assert(session_id.nil?)
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Aspera
4
4
  module Cli
5
- # for beta add extension : .beta1
6
- # for dev version add extension : .pre
7
- VERSION = '4.24.1'
5
+ # For beta add extension : .beta1
6
+ # For dev version add extension : .pre
7
+ VERSION = '4.24.2'
8
8
  end
9
9
  end