aspera-cli 4.16.0 → 4.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +50 -19
- data/CONTRIBUTING.md +3 -1
- data/README.md +965 -793
- data/bin/asession +29 -21
- data/lib/aspera/{fasp/agent_alpha.rb → agent/alpha.rb} +26 -25
- data/lib/aspera/{fasp/agent_base.rb → agent/base.rb} +15 -12
- data/lib/aspera/{fasp/agent_connect.rb → agent/connect.rb} +13 -11
- data/lib/aspera/{fasp/agent_direct.rb → agent/direct.rb} +49 -53
- data/lib/aspera/{fasp/agent_httpgw.rb → agent/httpgw.rb} +20 -19
- data/lib/aspera/{fasp/agent_node.rb → agent/node.rb} +20 -33
- data/lib/aspera/{fasp/agent_trsdk.rb → agent/trsdk.rb} +11 -11
- data/lib/aspera/api/aoc.rb +586 -0
- data/lib/aspera/api/ats.rb +46 -0
- data/lib/aspera/api/cos_node.rb +95 -0
- data/lib/aspera/api/node.rb +344 -0
- data/lib/aspera/ascmd.rb +46 -10
- data/lib/aspera/{fasp → ascp}/installation.rb +5 -5
- data/lib/aspera/{fasp → ascp}/management.rb +3 -8
- data/lib/aspera/{fasp → ascp}/products.rb +1 -1
- data/lib/aspera/assert.rb +30 -30
- data/lib/aspera/cli/basic_auth_plugin.rb +11 -10
- data/lib/aspera/cli/extended_value.rb +1 -1
- data/lib/aspera/cli/formatter.rb +13 -13
- data/lib/aspera/cli/hints.rb +5 -5
- data/lib/aspera/cli/main.rb +35 -28
- data/lib/aspera/cli/manager.rb +25 -24
- data/lib/aspera/cli/plugin.rb +22 -15
- data/lib/aspera/cli/plugin_factory.rb +61 -0
- data/lib/aspera/cli/plugins/alee.rb +7 -7
- data/lib/aspera/cli/plugins/aoc.rb +83 -77
- data/lib/aspera/cli/plugins/ats.rb +32 -33
- data/lib/aspera/cli/plugins/bss.rb +3 -4
- data/lib/aspera/cli/plugins/config.rb +169 -186
- data/lib/aspera/cli/plugins/console.rb +8 -6
- data/lib/aspera/cli/plugins/cos.rb +19 -18
- data/lib/aspera/cli/plugins/faspex.rb +61 -54
- data/lib/aspera/cli/plugins/faspex5.rb +150 -103
- data/lib/aspera/cli/plugins/node.rb +68 -73
- data/lib/aspera/cli/plugins/orchestrator.rb +34 -44
- data/lib/aspera/cli/plugins/preview.rb +31 -31
- data/lib/aspera/cli/plugins/server.rb +31 -33
- data/lib/aspera/cli/plugins/shares.rb +13 -11
- data/lib/aspera/cli/sync_actions.rb +8 -8
- data/lib/aspera/cli/transfer_agent.rb +32 -19
- data/lib/aspera/cli/transfer_progress.rb +1 -1
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/colors.rb +5 -0
- data/lib/aspera/command_line_builder.rb +14 -14
- data/lib/aspera/coverage.rb +1 -2
- data/lib/aspera/data_repository.rb +1 -1
- data/lib/aspera/environment.rb +2 -3
- data/lib/aspera/faspex_gw.rb +5 -6
- data/lib/aspera/faspex_postproc.rb +1 -1
- data/lib/aspera/id_generator.rb +2 -2
- data/lib/aspera/json_rpc.rb +5 -5
- data/lib/aspera/keychain/encrypted_hash.rb +6 -6
- data/lib/aspera/keychain/macos_security.rb +27 -22
- data/lib/aspera/log.rb +2 -2
- data/lib/aspera/nagios.rb +3 -3
- data/lib/aspera/node_simulator.rb +5 -6
- data/lib/aspera/oauth/base.rb +143 -0
- data/lib/aspera/oauth/factory.rb +124 -0
- data/lib/aspera/oauth/generic.rb +34 -0
- data/lib/aspera/oauth/jwt.rb +51 -0
- data/lib/aspera/oauth/url_json.rb +31 -0
- data/lib/aspera/oauth/web.rb +50 -0
- data/lib/aspera/oauth.rb +5 -331
- data/lib/aspera/open_application.rb +7 -7
- data/lib/aspera/persistency_action_once.rb +4 -4
- data/lib/aspera/persistency_folder.rb +2 -2
- data/lib/aspera/preview/generator.rb +5 -5
- data/lib/aspera/preview/terminal.rb +3 -2
- data/lib/aspera/preview/utils.rb +3 -3
- data/lib/aspera/proxy_auto_config.rb +4 -4
- data/lib/aspera/rest.rb +175 -144
- data/lib/aspera/rest_errors_aspera.rb +3 -3
- data/lib/aspera/resumer.rb +77 -0
- data/lib/aspera/ssh.rb +6 -1
- data/lib/aspera/{fasp → transfer}/error.rb +3 -3
- data/lib/aspera/{fasp → transfer}/error_info.rb +1 -1
- data/lib/aspera/{fasp → transfer}/faux_file.rb +1 -1
- data/lib/aspera/{fasp → transfer}/parameters.rb +58 -89
- data/lib/aspera/{fasp/transfer_spec.rb → transfer/spec.rb} +18 -16
- data/lib/aspera/{fasp/parameters.yaml → transfer/spec.yaml} +4 -99
- data/lib/aspera/{fasp → transfer}/sync.rb +32 -32
- data/lib/aspera/{fasp → transfer}/uri.rb +9 -8
- data/lib/aspera/web_server_simple.rb +11 -3
- data.tar.gz.sig +0 -0
- metadata +36 -63
- metadata.gz.sig +0 -0
- data/lib/aspera/aoc.rb +0 -601
- data/lib/aspera/ats_api.rb +0 -47
- data/lib/aspera/cos_node.rb +0 -94
- data/lib/aspera/fasp/resume_policy.rb +0 -79
- 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 <
|
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(
|
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
|
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(
|
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 <
|
12
|
-
def initialize(env)
|
13
|
-
super
|
11
|
+
class Cos < Cli::Plugin
|
12
|
+
def initialize(**env)
|
13
|
+
super
|
14
14
|
options.declare(:bucket, 'Bucket name')
|
15
|
-
options.declare(:endpoint, 'Storage endpoint
|
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
|
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
|
-
|
34
|
-
|
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
|
-
|
37
|
-
|
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
|
-
|
40
|
-
|
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(
|
45
|
-
node_plugin = Node.new(
|
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/
|
10
|
-
require 'aspera/
|
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 <
|
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
|
-
|
53
|
-
|
54
|
-
|
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 {
|
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
|
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
|
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
|
-
|
145
|
-
|
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(
|
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(
|
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'}
|
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(
|
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
|
-
|
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:
|
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 #{
|
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(
|
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 /^#{
|
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(
|
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 =
|
401
|
-
# NOTE: only external users have token in
|
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('&', '&')
|
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
|
417
|
+
text_body_params: xml_payload)[:http].body
|
411
418
|
end
|
412
|
-
transfer_spec['direction'] =
|
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(
|
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(
|
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(
|
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(
|
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(
|
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
|