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