aspera-cli 4.16.0 → 4.17.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 (97) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +50 -19
  4. data/CONTRIBUTING.md +3 -1
  5. data/README.md +965 -793
  6. data/bin/asession +29 -21
  7. data/lib/aspera/{fasp/agent_alpha.rb → agent/alpha.rb} +26 -25
  8. data/lib/aspera/{fasp/agent_base.rb → agent/base.rb} +15 -12
  9. data/lib/aspera/{fasp/agent_connect.rb → agent/connect.rb} +13 -11
  10. data/lib/aspera/{fasp/agent_direct.rb → agent/direct.rb} +49 -53
  11. data/lib/aspera/{fasp/agent_httpgw.rb → agent/httpgw.rb} +20 -19
  12. data/lib/aspera/{fasp/agent_node.rb → agent/node.rb} +20 -33
  13. data/lib/aspera/{fasp/agent_trsdk.rb → agent/trsdk.rb} +11 -11
  14. data/lib/aspera/api/aoc.rb +586 -0
  15. data/lib/aspera/api/ats.rb +46 -0
  16. data/lib/aspera/api/cos_node.rb +95 -0
  17. data/lib/aspera/api/node.rb +344 -0
  18. data/lib/aspera/ascmd.rb +46 -10
  19. data/lib/aspera/{fasp → ascp}/installation.rb +5 -5
  20. data/lib/aspera/{fasp → ascp}/management.rb +3 -8
  21. data/lib/aspera/{fasp → ascp}/products.rb +1 -1
  22. data/lib/aspera/assert.rb +30 -30
  23. data/lib/aspera/cli/basic_auth_plugin.rb +11 -10
  24. data/lib/aspera/cli/extended_value.rb +1 -1
  25. data/lib/aspera/cli/formatter.rb +13 -13
  26. data/lib/aspera/cli/hints.rb +5 -5
  27. data/lib/aspera/cli/main.rb +35 -28
  28. data/lib/aspera/cli/manager.rb +25 -24
  29. data/lib/aspera/cli/plugin.rb +22 -15
  30. data/lib/aspera/cli/plugin_factory.rb +61 -0
  31. data/lib/aspera/cli/plugins/alee.rb +7 -7
  32. data/lib/aspera/cli/plugins/aoc.rb +83 -77
  33. data/lib/aspera/cli/plugins/ats.rb +32 -33
  34. data/lib/aspera/cli/plugins/bss.rb +3 -4
  35. data/lib/aspera/cli/plugins/config.rb +169 -186
  36. data/lib/aspera/cli/plugins/console.rb +8 -6
  37. data/lib/aspera/cli/plugins/cos.rb +19 -18
  38. data/lib/aspera/cli/plugins/faspex.rb +61 -54
  39. data/lib/aspera/cli/plugins/faspex5.rb +150 -103
  40. data/lib/aspera/cli/plugins/node.rb +68 -73
  41. data/lib/aspera/cli/plugins/orchestrator.rb +34 -44
  42. data/lib/aspera/cli/plugins/preview.rb +31 -31
  43. data/lib/aspera/cli/plugins/server.rb +31 -33
  44. data/lib/aspera/cli/plugins/shares.rb +13 -11
  45. data/lib/aspera/cli/sync_actions.rb +8 -8
  46. data/lib/aspera/cli/transfer_agent.rb +32 -19
  47. data/lib/aspera/cli/transfer_progress.rb +1 -1
  48. data/lib/aspera/cli/version.rb +1 -1
  49. data/lib/aspera/colors.rb +5 -0
  50. data/lib/aspera/command_line_builder.rb +14 -14
  51. data/lib/aspera/coverage.rb +1 -2
  52. data/lib/aspera/data_repository.rb +1 -1
  53. data/lib/aspera/environment.rb +2 -3
  54. data/lib/aspera/faspex_gw.rb +5 -6
  55. data/lib/aspera/faspex_postproc.rb +1 -1
  56. data/lib/aspera/id_generator.rb +2 -2
  57. data/lib/aspera/json_rpc.rb +5 -5
  58. data/lib/aspera/keychain/encrypted_hash.rb +6 -6
  59. data/lib/aspera/keychain/macos_security.rb +27 -22
  60. data/lib/aspera/log.rb +2 -2
  61. data/lib/aspera/nagios.rb +3 -3
  62. data/lib/aspera/node_simulator.rb +5 -6
  63. data/lib/aspera/oauth/base.rb +143 -0
  64. data/lib/aspera/oauth/factory.rb +124 -0
  65. data/lib/aspera/oauth/generic.rb +34 -0
  66. data/lib/aspera/oauth/jwt.rb +51 -0
  67. data/lib/aspera/oauth/url_json.rb +31 -0
  68. data/lib/aspera/oauth/web.rb +50 -0
  69. data/lib/aspera/oauth.rb +5 -331
  70. data/lib/aspera/open_application.rb +7 -7
  71. data/lib/aspera/persistency_action_once.rb +4 -4
  72. data/lib/aspera/persistency_folder.rb +2 -2
  73. data/lib/aspera/preview/generator.rb +5 -5
  74. data/lib/aspera/preview/terminal.rb +3 -2
  75. data/lib/aspera/preview/utils.rb +3 -3
  76. data/lib/aspera/proxy_auto_config.rb +4 -4
  77. data/lib/aspera/rest.rb +175 -144
  78. data/lib/aspera/rest_errors_aspera.rb +3 -3
  79. data/lib/aspera/resumer.rb +77 -0
  80. data/lib/aspera/ssh.rb +6 -1
  81. data/lib/aspera/{fasp → transfer}/error.rb +3 -3
  82. data/lib/aspera/{fasp → transfer}/error_info.rb +1 -1
  83. data/lib/aspera/{fasp → transfer}/faux_file.rb +1 -1
  84. data/lib/aspera/{fasp → transfer}/parameters.rb +58 -89
  85. data/lib/aspera/{fasp/transfer_spec.rb → transfer/spec.rb} +18 -16
  86. data/lib/aspera/{fasp/parameters.yaml → transfer/spec.yaml} +4 -99
  87. data/lib/aspera/{fasp → transfer}/sync.rb +32 -32
  88. data/lib/aspera/{fasp → transfer}/uri.rb +9 -8
  89. data/lib/aspera/web_server_simple.rb +11 -3
  90. data.tar.gz.sig +0 -0
  91. metadata +36 -63
  92. metadata.gz.sig +0 -0
  93. data/lib/aspera/aoc.rb +0 -601
  94. data/lib/aspera/ats_api.rb +0 -47
  95. data/lib/aspera/cos_node.rb +0 -94
  96. data/lib/aspera/fasp/resume_policy.rb +0 -79
  97. data/lib/aspera/node.rb +0 -339
@@ -6,19 +6,19 @@ require 'aspera/nagios'
6
6
  module Aspera
7
7
  module Cli
8
8
  module Plugins
9
- class Console < Aspera::Cli::BasicAuthPlugin
9
+ class Console < Cli::BasicAuthPlugin
10
10
  STANDARD_PATH = '/aspera/console'
11
11
  class << self
12
12
  def detect(address_or_url)
13
13
  address_or_url = "https://#{address_or_url}" unless address_or_url.match?(%r{^[a-z]{1,6}://})
14
14
  urls = [address_or_url]
15
15
  urls.push("#{address_or_url}#{STANDARD_PATH}") unless address_or_url.end_with?(STANDARD_PATH)
16
-
16
+ error = nil
17
17
  urls.each do |base_url|
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(operation: 'GET', subpath: test_endpoint, url_params: {local: true})
22
22
  next unless test_page[:http].body.include?('Aspera Console')
23
23
  version = 'unknown'
24
24
  if (m = test_page[:http].body.match(/\(v([1-9]\..*)\)/))
@@ -30,8 +30,10 @@ module Aspera
30
30
  url: url[0..url.index(test_endpoint) - 2]
31
31
  }
32
32
  rescue StandardError => e
33
+ error = e
33
34
  Log.log.debug{"detect error: #{e}"}
34
35
  end
36
+ raise error if error
35
37
  return nil
36
38
  end
37
39
 
@@ -49,8 +51,8 @@ module Aspera
49
51
  end
50
52
  DEFAULT_FILTER_AGE_SECONDS = 3 * 3600
51
53
  private_constant :DEFAULT_FILTER_AGE_SECONDS
52
- def initialize(env)
53
- super(env)
54
+ def initialize(**env)
55
+ super
54
56
  time_now = Time.now
55
57
  options.declare(:filter_from, 'Only after date', values: :date, default: Manager.time_to_string(time_now - DEFAULT_FILTER_AGE_SECONDS))
56
58
  options.declare(:filter_to, 'Only before date', values: :date, default: Manager.time_to_string(time_now))
@@ -83,7 +85,7 @@ module Aspera
83
85
  when :submit
84
86
  smart_id = options.get_next_argument('smart_id')
85
87
  params = options.get_next_argument('transfer parameters')
86
- return {type: :object_list, data: api_console.create('smart_transfers/' + smart_id, params)[:data]}
88
+ return {type: :object_list, data: api_console.create("smart_transfers/#{smart_id}", params)[:data]}
87
89
  end
88
90
  when :current
89
91
  command = options.get_next_command([:list])
@@ -2,22 +2,22 @@
2
2
 
3
3
  require 'aspera/cli/plugin'
4
4
  require 'aspera/cli/plugins/node'
5
- require 'aspera/cos_node'
5
+ require 'aspera/api/cos_node'
6
6
  require 'aspera/assert'
7
7
 
8
8
  module Aspera
9
9
  module Cli
10
10
  module Plugins
11
- class Cos < Aspera::Cli::Plugin
12
- def initialize(env)
13
- super(env)
11
+ class Cos < Cli::Plugin
12
+ def initialize(**env)
13
+ super
14
14
  options.declare(:bucket, 'Bucket name')
15
- options.declare(:endpoint, 'Storage endpoint url')
15
+ options.declare(:endpoint, 'Storage endpoint (URL)')
16
16
  options.declare(:apikey, 'Storage API key')
17
- options.declare(:crn, 'Resource instance id')
17
+ options.declare(:crn, 'Resource instance id (CRN)')
18
18
  options.declare(:service_credentials, 'IBM Cloud service credentials', types: Hash)
19
19
  options.declare(:region, 'Storage region')
20
- options.declare(:identity, "Authentication url (#{CosNode::IBM_CLOUD_TOKEN_URL})", default: CosNode::IBM_CLOUD_TOKEN_URL)
20
+ options.declare(:identity, "Authentication URL (#{Api::CosNode::IBM_CLOUD_TOKEN_URL})", default: Api::CosNode::IBM_CLOUD_TOKEN_URL)
21
21
  options.parse_options!
22
22
  end
23
23
 
@@ -27,22 +27,23 @@ module Aspera
27
27
  command = options.get_next_command(ACTIONS)
28
28
  case command
29
29
  when :node
30
- bucket_name = options.get_option(:bucket, mandatory: true)
31
30
  # get service credentials, Hash, e.g. @json:@file:...
32
31
  service_credentials = options.get_option(:service_credentials)
33
- storage_endpoint = options.get_option(:endpoint)
34
- assert(service_credentials.nil? ^ storage_endpoint.nil?, exception_class: Cli::BadArgument){'endpoint and service_credentials are mutually exclusive'}
32
+ cos_node_params = {
33
+ auth_url: options.get_option(:identity, mandatory: true),
34
+ bucket: options.get_option(:bucket, mandatory: true),
35
+ endpoint: options.get_option(:endpoint)
36
+ }
35
37
  if service_credentials.nil?
36
- service_api_key = options.get_option(:apikey, mandatory: true)
37
- instance_id = options.get_option(:crn, mandatory: true)
38
+ Aspera.assert(!cos_node_params[:endpoint].nil?, exception_class: Cli::BadArgument){'endpoint required when service credentials not provided'}
39
+ cos_node_params[:api_key] = options.get_option(:apikey, mandatory: true)
40
+ cos_node_params[:instance_id] = options.get_option(:crn, mandatory: true)
38
41
  else
39
- params = CosNode.parameters_from_svc_credentials(service_credentials, options.get_option(:region, mandatory: true))
40
- storage_endpoint = params[:storage_endpoint]
41
- service_api_key = params[:service_api_key]
42
- instance_id = params[:instance_id]
42
+ Aspera.assert(cos_node_params[:endpoint].nil?, exception_class: Cli::BadArgument){'endpoint not allowed when service credentials provided'}
43
+ cos_node_params.merge!(Api::CosNode.parameters_from_svc_credentials(service_credentials, options.get_option(:region, mandatory: true)))
43
44
  end
44
- api_node = CosNode.new(bucket_name, storage_endpoint, instance_id, service_api_key, options.get_option(:identity, mandatory: true))
45
- node_plugin = Node.new(@agents, api: api_node)
45
+ api_node = Api::CosNode.new(**cos_node_params)
46
+ node_plugin = Node.new(**init_params, api: api_node)
46
47
  command = options.get_next_command(Node::COMMANDS_COS)
47
48
  return node_plugin.execute_action(command)
48
49
  end
@@ -6,8 +6,8 @@ require 'aspera/cli/plugins/node'
6
6
  require 'aspera/cli/plugins/config'
7
7
  require 'aspera/cli/extended_value'
8
8
  require 'aspera/cli/transfer_agent'
9
- require 'aspera/fasp/uri'
10
- require 'aspera/fasp/transfer_spec'
9
+ require 'aspera/transfer/uri'
10
+ require 'aspera/transfer/spec'
11
11
  require 'aspera/persistency_action_once'
12
12
  require 'aspera/open_application'
13
13
  require 'aspera/nagios'
@@ -21,7 +21,7 @@ require 'cgi'
21
21
  module Aspera
22
22
  module Cli
23
23
  module Plugins
24
- class Faspex < Aspera::Cli::BasicAuthPlugin
24
+ class Faspex < Cli::BasicAuthPlugin
25
25
  # required hash key for source in config
26
26
  KEY_NODE = 'node' # value must be hash with url, username, password
27
27
  KEY_PATH = 'path' # value must be same sub-path as in Faspex's node
@@ -43,25 +43,32 @@ module Aspera
43
43
  address_or_url = "https://#{address_or_url}" unless address_or_url.match?(%r{^[a-z]{1,6}://})
44
44
  urls = [address_or_url]
45
45
  urls.push("#{address_or_url}#{STANDARD_PATH}") unless address_or_url.end_with?(STANDARD_PATH)
46
-
46
+ error = nil
47
47
  urls.each do |base_url|
48
48
  next unless base_url.start_with?('https://')
49
49
  api = Rest.new(base_url: base_url, redirect_max: 1)
50
50
  result = api.call(
51
51
  operation: 'POST',
52
- subpath: '',
53
- headers: {'Accept' => 'application/xrds+xml', 'Content-type' => 'text/plain'},
54
- text_body_params: '')
52
+ headers: {
53
+ 'Content-type' => 'text/plain',
54
+ 'Accept' => 'application/xrds+xml'
55
+ }
56
+ )
55
57
  # 4.x
56
58
  next unless result[:http].body.start_with?('<?xml')
57
59
  res_s = XmlSimple.xml_in(result[:http].body, {'ForceArray' => false})
58
60
  Log.log.debug{"version: #{result[:http]['X-IBM-Aspera']}"}
59
61
  version = res_s['XRD']['application']['version']
60
62
  # take redirect if any
61
- return {version: version, url: result[:http].uri.to_s}
63
+ return {
64
+ version: version,
65
+ url: result[:http].uri.to_s
66
+ }
62
67
  rescue StandardError => e
68
+ error = e
63
69
  Log.log.debug{"detect error: #{e}"}
64
70
  end
71
+ raise error if error
65
72
  return nil
66
73
  end
67
74
 
@@ -80,7 +87,7 @@ module Aspera
80
87
  # extract elements from faspex public link
81
88
  def get_link_data(public_url)
82
89
  public_uri = URI.parse(public_url)
83
- assert((m = public_uri.path.match(%r{^(.*)/(external.*)$})), exception_class: Cli::BadArgument){'Public link does not match Faspex format'}
90
+ Aspera.assert((m = public_uri.path.match(%r{^(.*)/(external.*)$})), exception_class: Cli::BadArgument){'Public link does not match Faspex format'}
84
91
  base = m[1]
85
92
  subpath = m[2]
86
93
  port_add = public_uri.port.eql?(public_uri.default_port) ? '' : ":#{public_uri.port}"
@@ -93,7 +100,7 @@ module Aspera
93
100
  return result
94
101
  end
95
102
 
96
- # get Fasp::Uri::SCHEME URI from entry in xml, and fix problems.
103
+ # get Transfer::Uri::SCHEME URI from entry in xml, and fix problems.
97
104
  def get_fasp_uri_from_entry(entry, raise_no_link: true)
98
105
  unless entry.key?('link')
99
106
  raise Cli::BadArgument, 'package has no link (deleted?)' if raise_no_link
@@ -111,10 +118,10 @@ module Aspera
111
118
  end
112
119
  end
113
120
 
114
- def initialize(env)
121
+ def initialize(**env)
122
+ super
115
123
  @api_v3 = nil
116
124
  @api_v4 = nil
117
- super(env)
118
125
  options.declare(:link, 'Public link for specific operation')
119
126
  options.declare(:delivery_info, 'Package delivery information', types: Hash)
120
127
  options.declare(:remote_source, 'Remote source for package send (id or %name:)')
@@ -134,16 +141,16 @@ module Aspera
134
141
  def api_v4
135
142
  if @api_v4.nil?
136
143
  faspex_api_base = options.get_option(:url, mandatory: true)
137
- @api_v4 = Rest.new({
138
- base_url: faspex_api_base + '/api',
144
+ @api_v4 = Rest.new(
145
+ base_url: "#{faspex_api_base}/api",
139
146
  auth: {
140
147
  type: :oauth2,
141
- base_url: faspex_api_base + '/auth/oauth2',
142
- auth: {type: :basic, username: options.get_option(:username, mandatory: true), password: options.get_option(:password, mandatory: true)},
143
148
  grant_method: :generic,
144
- generic: {grant_type: 'password'},
145
- scope: 'admin'
146
- }})
149
+ base_url: "#{faspex_api_base}/auth/oauth2",
150
+ auth: {type: :basic, username: options.get_option(:username, mandatory: true), password: options.get_option(:password, mandatory: true)},
151
+ scope: 'admin',
152
+ grant_type: 'password'
153
+ })
147
154
  end
148
155
  return @api_v4
149
156
  end
@@ -161,9 +168,9 @@ module Aspera
161
168
  max_pages = nil
162
169
  result = []
163
170
  if !mailbox_query.nil?
164
- assert_type(mailbox_query, Hash){'query'}
165
- assert((mailbox_query.keys - ATOM_EXT_PARAMS).empty?){"query: supported params: #{ATOM_EXT_PARAMS}"}
166
- assert(!(mailbox_query.key?('startIndex') && mailbox_query.key?('page'))){'query: startIndex and page are exclusive'}
171
+ Aspera.assert_type(mailbox_query, Hash){'query'}
172
+ Aspera.assert((mailbox_query.keys - ATOM_EXT_PARAMS).empty?){"query: supported params: #{ATOM_EXT_PARAMS}"}
173
+ Aspera.assert(!(mailbox_query.key?('startIndex') && mailbox_query.key?('page'))){'query: startIndex and page are exclusive'}
167
174
  max_items = mailbox_query[MAX_ITEMS]
168
175
  mailbox_query.delete(MAX_ITEMS)
169
176
  max_pages = mailbox_query[MAX_PAGES]
@@ -172,7 +179,7 @@ module Aspera
172
179
  loop do
173
180
  # get a batch of package information
174
181
  # order: first batch is latest packages, and then in a batch ids are increasing
175
- atom_xml = api_v3.call({operation: 'GET', subpath: "#{mailbox}.atom", headers: {'Accept' => 'application/xml'}, url_params: mailbox_query})[:http].body
182
+ atom_xml = api_v3.call(operation: 'GET', subpath: "#{mailbox}.atom", headers: {'Accept' => 'application/xml'}, url_params: mailbox_query)[:http].body
176
183
  box_data = XmlSimple.xml_in(atom_xml, {'ForceArray' => %w[entry field link to]})
177
184
  Log.log.debug{Log.dump(:box_data, box_data)}
178
185
  items = box_data.key?('entry') ? box_data['entry'] : []
@@ -232,15 +239,15 @@ module Aspera
232
239
  package_create_params[:passcode] = link_data[:query]['passcode']
233
240
  delivery_info[:transfer_type] = 'connect'
234
241
  delivery_info[:source_paths_list] = transfer.source_list.join("\r\n")
235
- api_public_link = Rest.new({base_url: link_data[:base_url]})
242
+ api_public_link = Rest.new(base_url: link_data[:base_url])
236
243
  # Hum, as this does not always work (only user, but not dropbox), we get the javascript and need hack
237
244
  # pkg_created=api_public_link.create(create_path,package_create_params)[:data]
238
245
  # so extract data from javascript
239
- package_creation_data = api_public_link.call({
246
+ package_creation_data = api_public_link.call(
240
247
  operation: 'POST',
241
248
  subpath: create_path,
242
249
  json_params: package_create_params,
243
- headers: {'Accept' => 'text/javascript'}})[:http].body
250
+ headers: {'Accept' => 'text/javascript'})[:http].body
244
251
  # get arguments of function call
245
252
  package_creation_data.delete!("\n") # one line
246
253
  package_creation_data.gsub!(/^[^"]+\("\{/, '{') # delete header
@@ -283,7 +290,7 @@ module Aspera
283
290
  }
284
291
  when :send
285
292
  delivery_info = options.get_option(:delivery_info, mandatory: true)
286
- assert_type(delivery_info, Hash, exception_class: Cli::BadArgument){'delivery_info'}
293
+ Aspera.assert_type(delivery_info, Hash, exception_class: Cli::BadArgument){'delivery_info'}
287
294
  # actual parameter to faspex API
288
295
  package_create_params = {'delivery' => delivery_info}
289
296
  public_link_url = options.get_option(:link)
@@ -293,17 +300,17 @@ module Aspera
293
300
  first_source = delivery_info['sources'].first
294
301
  first_source['paths'].push(*transfer.source_list)
295
302
  source_id = instance_identifier(as_option: :remote_source) do |field, value|
296
- assert(field.eql?('name'), exception_class: Cli::BadArgument){'only name as selector, or give id'}
297
- source_list = api_v3.call({operation: 'GET', subpath: 'source_shares', headers: {'Accept' => 'application/json'}})[:data]['items']
303
+ Aspera.assert(field.eql?('name'), exception_class: Cli::BadArgument){'only name as selector, or give id'}
304
+ source_list = api_v3.call(operation: 'GET', subpath: 'source_shares', headers: {'Accept' => 'application/json'})[:data]['items']
298
305
  self.class.get_source_id_by_name(value, source_list)
299
306
  end
300
307
  first_source['id'] = source_id.to_i unless source_id.nil?
301
- pkg_created = api_v3.call({
308
+ pkg_created = api_v3.call(
302
309
  operation: 'POST',
303
310
  subpath: 'send',
304
311
  json_params: package_create_params,
305
312
  headers: {'Accept' => 'application/json'}
306
- })[:data]
313
+ )[:data]
307
314
  if first_source.key?('id')
308
315
  # no transfer spec if remote source: handled by faspex
309
316
  return {data: [pkg_created['links']['status']], type: :value_list, name: 'link'}
@@ -327,7 +334,7 @@ module Aspera
327
334
  when nil # usual case: no link
328
335
  if options.get_option(:once_only, mandatory: true)
329
336
  skip_ids_persistency = PersistencyActionOnce.new(
330
- manager: @agents[:persistency],
337
+ manager: persistency,
331
338
  data: skip_ids_data,
332
339
  id: IdGenerator.from_list([
333
340
  'faspex_recv',
@@ -343,13 +350,13 @@ module Aspera
343
350
  if delivery_id.eql?(ExtendedValue::ALL)
344
351
  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)}}
345
352
  elsif delivery_id.eql?(ExtendedValue::INIT)
346
- assert(skip_ids_persistency){'Only with option once_only'}
353
+ Aspera.assert(skip_ids_persistency){'Only with option once_only'}
347
354
  skip_ids_persistency.data.clear.concat(mailbox_filtered_entries.map{|i|{id: i[PACKAGE_MATCH_FIELD]}})
348
355
  skip_ids_persistency.save
349
356
  return Main.result_status("Initialized skip for #{skip_ids_persistency.data.count} package(s)")
350
357
  elsif !recipient.nil? && recipient.start_with?('*')
351
358
  found_package_link = mailbox_filtered_entries(stop_at_id: delivery_id).find{|p|p[PACKAGE_MATCH_FIELD].eql?(delivery_id)}['link'].first['href']
352
- raise "Not Found. Dropbox and Workgroup packages can use the link option with #{Fasp::Uri::SCHEME}" if found_package_link.nil?
359
+ raise "Not Found. Dropbox and Workgroup packages can use the link option with #{Transfer::Uri::SCHEME}" if found_package_link.nil?
353
360
  pkg_id_uri = [{id: delivery_id, uri: found_package_link}]
354
361
  else
355
362
  # TODO: delivery id is the right one if package was receive by workgroup
@@ -358,11 +365,11 @@ module Aspera
358
365
  when :inbox, :archive then'received'
359
366
  when :sent then 'sent'
360
367
  end
361
- entry_xml = api_v3.call({operation: 'GET', subpath: "#{endpoint}/#{delivery_id}", headers: {'Accept' => 'application/xml'}})[:http].body
368
+ entry_xml = api_v3.call(operation: 'GET', subpath: "#{endpoint}/#{delivery_id}", headers: {'Accept' => 'application/xml'})[:http].body
362
369
  package_entry = XmlSimple.xml_in(entry_xml, {'ForceArray' => true})
363
370
  pkg_id_uri = [{id: delivery_id, uri: self.class.get_fasp_uri_from_entry(package_entry)}]
364
371
  end
365
- when /^#{Fasp::Uri::SCHEME}:/o
372
+ when /^#{Transfer::Uri::SCHEME}:/o
366
373
  pkg_id_uri = [{id: 'package', uri: link_url}]
367
374
  else
368
375
  link_data = self.class.get_link_data(link_url)
@@ -370,7 +377,7 @@ module Aspera
370
377
  raise Cli::BadArgument, "Pub link is #{link_data[:subpath]}. Expecting #{PUB_LINK_EXTERNAL_MATCH}"
371
378
  end
372
379
  # NOTE: unauthenticated API (authorization is in url params)
373
- api_public_link = Rest.new({base_url: link_data[:base_url]})
380
+ api_public_link = Rest.new(base_url: link_data[:base_url])
374
381
  package_creation_data = api_public_link.call(
375
382
  operation: 'GET',
376
383
  subpath: link_data[:subpath],
@@ -397,19 +404,19 @@ module Aspera
397
404
  # skip package with no link: empty or content deleted
398
405
  statuses = [:success]
399
406
  else
400
- transfer_spec = Fasp::Uri.new(id_uri[:uri]).transfer_spec
401
- # NOTE: only external users have token in Fasp::Uri::SCHEME link !
407
+ transfer_spec = Transfer::Uri.new(id_uri[:uri]).transfer_spec
408
+ # NOTE: only external users have token in Transfer::Uri::SCHEME link !
402
409
  if !transfer_spec.key?('token')
403
410
  sanitized = id_uri[:uri].gsub('&', '&amp;')
404
411
  xml_payload =
405
412
  %Q(<?xml version="1.0" encoding="UTF-8"?><url-list xmlns="http://schemas.asperasoft.com/xml/url-list"><url href="#{sanitized}"/></url-list>)
406
- transfer_spec['token'] = api_v3.call({
413
+ transfer_spec['token'] = api_v3.call(
407
414
  operation: 'POST',
408
415
  subpath: 'issue-token?direction=down',
409
416
  headers: {'Accept' => 'text/plain', 'Content-Type' => 'application/vnd.aspera.url-list+xml'},
410
- text_body_params: xml_payload})[:http].body
417
+ text_body_params: xml_payload)[:http].body
411
418
  end
412
- transfer_spec['direction'] = Fasp::TransferSpec::DIRECTION_RECEIVE
419
+ transfer_spec['direction'] = Transfer::Spec::DIRECTION_RECEIVE
413
420
  statuses = transfer.start(transfer_spec)
414
421
  end
415
422
  result_transfer.push({'package' => id_uri[:id], Main::STATUS_FIELD => statuses})
@@ -421,23 +428,23 @@ module Aspera
421
428
  end
422
429
  when :source
423
430
  command_source = options.get_next_command(%i[list info node])
424
- source_list = api_v3.call({operation: 'GET', subpath: 'source_shares', headers: {'Accept' => 'application/json'}})[:data]['items']
431
+ source_list = api_v3.call(operation: 'GET', subpath: 'source_shares', headers: {'Accept' => 'application/json'})[:data]['items']
425
432
  case command_source
426
433
  when :list
427
434
  return {type: :object_list, data: source_list}
428
435
  else # :info :node
429
436
  source_id = instance_identifier do |field, value|
430
- assert(field.eql?('name'), exception_class: Cli::BadArgument){'only name as selector, or give id'}
437
+ Aspera.assert(field.eql?('name'), exception_class: Cli::BadArgument){'only name as selector, or give id'}
431
438
  self.class.get_source_id_by_name(value, source_list)
432
439
  end.to_i
433
440
  source_name = source_list.find{|i|i['id'].eql?(source_id)}['name']
434
441
  source_hash = options.get_option(:storage, mandatory: true)
435
442
  # check value of option
436
- assert_type(source_hash, Hash, exception_class: Cli::Error){'storage option'}
443
+ Aspera.assert_type(source_hash, Hash, exception_class: Cli::Error){'storage option'}
437
444
  source_hash.each do |name, storage|
438
- assert_type(storage, Hash, exception_class: Cli::Error){"storage '#{name}'"}
445
+ Aspera.assert_type(storage, Hash, exception_class: Cli::Error){"storage '#{name}'"}
439
446
  [KEY_NODE, KEY_PATH].each do |key|
440
- assert(storage.key?(key), exception_class: Cli::Error){"storage '#{name}' must have a '#{key}'"}
447
+ Aspera.assert(storage.key?(key), exception_class: Cli::Error){"storage '#{name}' must have a '#{key}'"}
441
448
  end
442
449
  end
443
450
  if !source_hash.key?(source_name)
@@ -451,25 +458,25 @@ module Aspera
451
458
  when :node
452
459
  node_config = ExtendedValue.instance.evaluate(source_info[KEY_NODE])
453
460
  Log.log.debug{"node=#{node_config}"}
454
- assert_type(node_config, Hash, exception_class: Cli::Error){source_info[KEY_NODE]}
455
- api_node = Rest.new({
461
+ Aspera.assert_type(node_config, Hash, exception_class: Cli::Error){source_info[KEY_NODE]}
462
+ api_node = Rest.new(
456
463
  base_url: node_config['url'],
457
464
  auth: {
458
465
  type: :basic,
459
466
  username: node_config['username'],
460
- password: node_config['password']}})
467
+ password: node_config['password']})
461
468
  command = options.get_next_command(Node::COMMANDS_FASPEX)
462
- return Node.new(@agents, api: api_node).execute_action(command, source_info[KEY_PATH])
469
+ return Node.new(**init_params, api: api_node).execute_action(command, source_info[KEY_PATH])
463
470
  end
464
471
  end
465
472
  when :me
466
- my_info = api_v3.call({operation: 'GET', subpath: 'me', headers: {'Accept' => 'application/json'}})[:data]
473
+ my_info = api_v3.call(operation: 'GET', subpath: 'me', headers: {'Accept' => 'application/json'})[:data]
467
474
  return {data: my_info, type: :single_object}
468
475
  when :dropbox
469
476
  command_pkg = options.get_next_command([:list])
470
477
  case command_pkg
471
478
  when :list
472
- dropbox_list = api_v3.call({operation: 'GET', subpath: 'dropboxes', headers: {'Accept' => 'application/json'}})[:data]
479
+ dropbox_list = api_v3.call(operation: 'GET', subpath: 'dropboxes', headers: {'Accept' => 'application/json'})[:data]
473
480
  return {type: :object_list, data: dropbox_list['items'], fields: %w[name id description can_read can_write]}
474
481
  end
475
482
  when :v4
@@ -516,7 +523,7 @@ module Aspera
516
523
  end
517
524
  return {type: :object_list, data: users}
518
525
  when :login_methods
519
- login_meths = api_v3.call({operation: 'GET', subpath: 'login/new', headers: {'Accept' => 'application/xrds+xml'}})[:http].body
526
+ login_meths = api_v3.call(operation: 'GET', subpath: 'login/new', headers: {'Accept' => 'application/xrds+xml'})[:http].body
520
527
  login_methods = XmlSimple.xml_in(login_meths, {'ForceArray' => false})
521
528
  return {type: :object_list, data: login_methods['XRD']['Service']}
522
529
  end # command