aspera-cli 4.15.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/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
@@ -4,23 +4,26 @@ require 'aspera/cli/plugins/node'
|
|
4
4
|
require 'aspera/cli/plugins/ats'
|
5
5
|
require 'aspera/cli/basic_auth_plugin'
|
6
6
|
require 'aspera/cli/transfer_agent'
|
7
|
-
require 'aspera/
|
8
|
-
require 'aspera/
|
9
|
-
require 'aspera/aoc'
|
10
|
-
require 'aspera/node'
|
7
|
+
require 'aspera/agent/node'
|
8
|
+
require 'aspera/transfer/spec'
|
9
|
+
require 'aspera/api/aoc'
|
10
|
+
require 'aspera/api/node'
|
11
11
|
require 'aspera/persistency_action_once'
|
12
12
|
require 'aspera/id_generator'
|
13
|
+
require 'aspera/assert'
|
13
14
|
require 'securerandom'
|
14
15
|
require 'date'
|
15
16
|
|
16
17
|
module Aspera
|
17
18
|
module Cli
|
18
19
|
module Plugins
|
19
|
-
class Aoc <
|
20
|
+
class Aoc < Cli::BasicAuthPlugin
|
20
21
|
AOC_PATH_API_CLIENTS = 'admin/api-clients'
|
21
22
|
# default redirect for AoC web auth
|
22
|
-
|
23
|
-
|
23
|
+
REDIRECT_LOCALHOST = 'http://localhost:12345'
|
24
|
+
# OAuth methods supported
|
25
|
+
STD_AUTH_TYPES = %i[web jwt].freeze
|
26
|
+
private_constant :AOC_PATH_API_CLIENTS, :REDIRECT_LOCALHOST, :STD_AUTH_TYPES
|
24
27
|
class << self
|
25
28
|
def application_name
|
26
29
|
'Aspera on Cloud'
|
@@ -30,13 +33,13 @@ module Aspera
|
|
30
33
|
# no protocol ?
|
31
34
|
base_url = "https://#{base_url}" unless base_url.match?(%r{^[a-z]{1,6}://})
|
32
35
|
# only org provided ?
|
33
|
-
base_url = "#{base_url}.#{
|
36
|
+
base_url = "#{base_url}.#{Api::AoC::PROD_DOMAIN}" unless base_url.include?('.')
|
34
37
|
# AoC is only https
|
35
38
|
return nil unless base_url.start_with?('https://')
|
36
|
-
result = Rest.new(
|
39
|
+
result = Rest.new(base_url: base_url, redirect_max: 10).read('')
|
37
40
|
# Any AoC is on this domain
|
38
|
-
return nil unless result[:http].uri.host.end_with?(
|
39
|
-
Log.log.debug{
|
41
|
+
return nil unless result[:http].uri.host.end_with?(Api::AoC::PROD_DOMAIN)
|
42
|
+
Log.log.debug{"AoC Main page: #{result[:http].body.include?(Api::AoC::PRODUCT_NAME)}"}
|
40
43
|
base_url = result[:http].uri.to_s if result[:http].uri.path.include?('/public')
|
41
44
|
# either in standard domain, or product name in page
|
42
45
|
return {
|
@@ -47,7 +50,7 @@ module Aspera
|
|
47
50
|
|
48
51
|
def private_key_required?(url)
|
49
52
|
# pub link do not need private key
|
50
|
-
return AoC.link_info(url)[:token].nil?
|
53
|
+
return Api::AoC.link_info(url)[:token].nil?
|
51
54
|
end
|
52
55
|
|
53
56
|
# @param [Hash] env : options, formatter
|
@@ -60,9 +63,9 @@ module Aspera
|
|
60
63
|
options.declare(:use_generic_client, 'Wizard: AoC: use global or org specific jwt client id', values: :bool, default: true)
|
61
64
|
options.parse_options!
|
62
65
|
instance_url = options.get_option(:url, mandatory: true)
|
63
|
-
pub_link_info = AoC.link_info(instance_url)
|
66
|
+
pub_link_info = Api::AoC.link_info(instance_url)
|
64
67
|
if !pub_link_info[:token].nil?
|
65
|
-
pub_api = Rest.new(
|
68
|
+
pub_api = Rest.new(base_url: "https://#{URI.parse(pub_link_info[:url]).host}/api/v1")
|
66
69
|
pub_info = pub_api.read('env/url_token_check', {token: pub_link_info[:token]})[:data]
|
67
70
|
preset_value = {
|
68
71
|
link: instance_url
|
@@ -99,7 +102,7 @@ module Aspera
|
|
99
102
|
formatter.display_status('Navigate to: 𓃑 → Admin → Integrations → API Clients')
|
100
103
|
formatter.display_status('Check or create in integration:')
|
101
104
|
formatter.display_status("- name: #{@info[:name]}")
|
102
|
-
formatter.display_status("- redirect uri: #{
|
105
|
+
formatter.display_status("- redirect uri: #{REDIRECT_LOCALHOST}")
|
103
106
|
formatter.display_status('- origin: localhost')
|
104
107
|
formatter.display_status('Use the generated client id and secret in the following prompts.'.red)
|
105
108
|
end
|
@@ -112,13 +115,14 @@ module Aspera
|
|
112
115
|
formatter.display_status('We will use web authentication to bootstrap.')
|
113
116
|
auto_set_pub_key = true
|
114
117
|
auto_set_jwt = true
|
115
|
-
|
116
|
-
aoc_api.oauth.
|
117
|
-
aoc_api.oauth.
|
118
|
+
raise 'TODO'
|
119
|
+
# aoc_api.oauth.grant_method = :web
|
120
|
+
# aoc_api.oauth.scope = Api::AoC::SCOPE_FILES_ADMIN
|
121
|
+
# aoc_api.oauth.specific_parameters[:redirect_uri] = REDIRECT_LOCALHOST
|
118
122
|
end
|
119
123
|
myself = object.aoc_api.read('self')[:data]
|
120
124
|
if auto_set_pub_key
|
121
|
-
|
125
|
+
Aspera.assert(myself['public_key'].empty?, exception_class: Cli::Error){'Public key is already set in profile (use --override=yes)'} unless option_override
|
122
126
|
formatter.display_status('Updating profile with the public key.')
|
123
127
|
aoc_api.update("users/#{myself['id']}", {'public_key' => pub_key_pem})
|
124
128
|
end
|
@@ -165,21 +169,25 @@ module Aspera
|
|
165
169
|
client_registration_token
|
166
170
|
client_access_key
|
167
171
|
kms_profile].freeze
|
168
|
-
|
172
|
+
PACKAGE_RECEIVED_BASE_QUERY = {
|
173
|
+
'archived' => false,
|
174
|
+
'has_content' => true,
|
175
|
+
'received' => true,
|
176
|
+
'completed' => true}.freeze
|
169
177
|
|
170
|
-
def initialize(env)
|
171
|
-
super
|
178
|
+
def initialize(**env)
|
179
|
+
super
|
172
180
|
@cache_workspace_info = nil
|
173
181
|
@cache_home_node_file = nil
|
174
182
|
@cache_api_aoc = nil
|
175
|
-
options.declare(:auth, 'OAuth type of authentication', values:
|
183
|
+
options.declare(:auth, 'OAuth type of authentication', values: STD_AUTH_TYPES, default: :jwt)
|
176
184
|
options.declare(:client_id, 'OAuth API client identifier')
|
177
185
|
options.declare(:client_secret, 'OAuth API client secret')
|
178
|
-
options.declare(:scope, 'OAuth scope for AoC API calls', default: AoC::SCOPE_FILES_USER)
|
186
|
+
options.declare(:scope, 'OAuth scope for AoC API calls', default: Api::AoC::SCOPE_FILES_USER)
|
179
187
|
options.declare(:redirect_uri, 'OAuth API client redirect URI')
|
180
188
|
options.declare(:private_key, 'OAuth JWT RSA private key PEM value (prefix file path with @file:)')
|
181
189
|
options.declare(:passphrase, 'RSA private key passphrase')
|
182
|
-
options.declare(:workspace, 'Name of workspace', types: [String, NilClass], default:
|
190
|
+
options.declare(:workspace, 'Name of workspace', types: [String, NilClass], default: Api::AoC::DEFAULT_WORKSPACE)
|
183
191
|
options.declare(:new_user_option, 'New user creation option for unknown package recipients')
|
184
192
|
options.declare(:validate_metadata, 'Validate shared inbox metadata', values: :bool, default: true)
|
185
193
|
options.parse_options!
|
@@ -190,9 +198,9 @@ module Aspera
|
|
190
198
|
OPTIONS_NEW = %i[url auth client_id client_secret scope redirect_uri private_key passphrase username password workspace].freeze
|
191
199
|
|
192
200
|
def api_from_options(new_base_path)
|
193
|
-
create_values = {subpath: new_base_path, secret_finder:
|
201
|
+
create_values = {subpath: new_base_path, secret_finder: config}
|
194
202
|
# create an API object with the same options, but with a different subpath
|
195
|
-
return
|
203
|
+
return Api::AoC.new(**OPTIONS_NEW.each_with_object(create_values) { |i, m|m[i] = options.get_option(i) unless options.get_option(i).nil?})
|
196
204
|
rescue ArgumentError => e
|
197
205
|
if (m = e.message.match(/missing keyword: :(.*)$/))
|
198
206
|
raise Cli::Error, "Missing option: #{m[1]}"
|
@@ -201,7 +209,14 @@ module Aspera
|
|
201
209
|
end
|
202
210
|
|
203
211
|
def aoc_api
|
204
|
-
|
212
|
+
if @cache_api_aoc.nil?
|
213
|
+
@cache_api_aoc = api_from_options(Api::AoC::API_V1)
|
214
|
+
organization = @cache_api_aoc.read('organization')[:data]
|
215
|
+
if organization['http_gateway_enabled'] && organization['http_gateway_server_url']
|
216
|
+
transfer.httpgw_url_cb = lambda { organization['http_gateway_server_url'] }
|
217
|
+
# @cache_api_aoc.current_user_info['connect_disabled']
|
218
|
+
end
|
219
|
+
end
|
205
220
|
return @cache_api_aoc
|
206
221
|
end
|
207
222
|
|
@@ -209,7 +224,7 @@ module Aspera
|
|
209
224
|
# @return identifier
|
210
225
|
def get_resource_id_from_args(resource_class_path)
|
211
226
|
return instance_identifier do |field, value|
|
212
|
-
|
227
|
+
Aspera.assert(field.eql?('name'), exception_class: Cli::BadArgument){'only selection by name is supported'}
|
213
228
|
aoc_api.lookup_by_name(resource_class_path, value)['id']
|
214
229
|
end
|
215
230
|
end
|
@@ -218,11 +233,11 @@ module Aspera
|
|
218
233
|
return "#{resource_class_path}/#{get_resource_id_from_args(resource_class_path)}"
|
219
234
|
end
|
220
235
|
|
221
|
-
# Call
|
222
|
-
#
|
223
|
-
|
224
|
-
|
225
|
-
|
236
|
+
# Call block with same query using paging and response information
|
237
|
+
# @return [Hash] {data: , total: }
|
238
|
+
def api_call_paging(base_query={})
|
239
|
+
Aspera.assert_type(base_query, Hash){'query'}
|
240
|
+
Aspera.assert(block_given?)
|
226
241
|
# set default large page if user does not specify own parameters. AoC Caps to 1000 anyway
|
227
242
|
base_query['per_page'] = 1000 unless base_query.key?('per_page')
|
228
243
|
max_items = base_query.delete(MAX_ITEMS)
|
@@ -235,7 +250,7 @@ module Aspera
|
|
235
250
|
loop do
|
236
251
|
query = base_query.clone
|
237
252
|
query['page'] = current_page
|
238
|
-
result =
|
253
|
+
result = yield(query)
|
239
254
|
total_count = result[:http]['X-Total-Count']
|
240
255
|
page_count += 1
|
241
256
|
current_page += 1
|
@@ -247,7 +262,38 @@ module Aspera
|
|
247
262
|
break if !max_pages.nil? && page_count >= max_pages
|
248
263
|
end
|
249
264
|
item_list = item_list[0..max_items - 1] if !max_items.nil? && item_list.count > max_items
|
250
|
-
return {
|
265
|
+
return {data: item_list, total: total_count}
|
266
|
+
end
|
267
|
+
|
268
|
+
# read using the query and paging
|
269
|
+
# @return [Hash] {data: , total: }
|
270
|
+
def api_read_all(resource_class_path, base_query={})
|
271
|
+
return api_call_paging(base_query) do |query|
|
272
|
+
aoc_api.read(resource_class_path, query)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
# list all entities, given additional, default and user's queries
|
277
|
+
def result_list(resource_class_path, fields: nil, base_query: {}, default_query: {})
|
278
|
+
Aspera.assert_type(base_query, Hash)
|
279
|
+
Aspera.assert_type(default_query, Hash)
|
280
|
+
user_query = query_read_delete(default: default_query)
|
281
|
+
# caller may add specific modifications or checks
|
282
|
+
yield(user_query) if block_given?
|
283
|
+
return {type: :object_list, fields: fields}.merge(api_read_all(resource_class_path, base_query.merge(user_query)))
|
284
|
+
end
|
285
|
+
|
286
|
+
def resolve_dropbox_name_default_ws_id(query)
|
287
|
+
if query.key?('dropbox_name')
|
288
|
+
# convenience: specify name instead of id
|
289
|
+
raise 'not both dropbox_name and dropbox_id' if query.key?('dropbox_id')
|
290
|
+
# TODO : craft a query that looks for dropbox only in current workspace
|
291
|
+
query['dropbox_id'] = aoc_api.lookup_by_name('dropboxes', query['dropbox_name'])['id']
|
292
|
+
query.delete('dropbox_name')
|
293
|
+
end
|
294
|
+
query['workspace_id'] ||= aoc_api.context[:workspace_id] unless aoc_api.context[:workspace_id].eql?(:undefined)
|
295
|
+
# by default show dropbox packages only for dropboxes
|
296
|
+
query['exclude_dropbox_packages'] = !query.key?('dropbox_id') unless query.key?('exclude_dropbox_packages')
|
251
297
|
end
|
252
298
|
|
253
299
|
NODE4_EXT_COMMANDS = %i[transfer].concat(Node::COMMANDS_GEN4).freeze
|
@@ -263,7 +309,7 @@ module Aspera
|
|
263
309
|
scope: scope
|
264
310
|
)
|
265
311
|
file_id = top_node_api.read("access_keys/#{top_node_api.app_info[:node_info]['access_key']}")[:data]['root_file_id'] if file_id.nil?
|
266
|
-
node_plugin = Node.new(
|
312
|
+
node_plugin = Node.new(**init_params, api: top_node_api)
|
267
313
|
case command_repo
|
268
314
|
when *Node::COMMANDS_GEN4
|
269
315
|
return node_plugin.execute_command_gen4(command_repo, file_id)
|
@@ -275,20 +321,20 @@ module Aspera
|
|
275
321
|
source_folder = options.get_next_argument('folder of source files', type: String)
|
276
322
|
case push_pull
|
277
323
|
when :push
|
278
|
-
client_direction =
|
324
|
+
client_direction = Transfer::Spec::DIRECTION_SEND
|
279
325
|
client_folder = source_folder
|
280
326
|
server_folder = transfer.destination_folder(client_direction)
|
281
327
|
when :pull
|
282
|
-
client_direction =
|
328
|
+
client_direction = Transfer::Spec::DIRECTION_RECEIVE
|
283
329
|
client_folder = transfer.destination_folder(client_direction)
|
284
330
|
server_folder = source_folder
|
285
|
-
else
|
331
|
+
else Aspera.error_unreachable_line
|
286
332
|
end
|
287
333
|
client_apfid = top_node_api.resolve_api_fid(file_id, client_folder)
|
288
334
|
server_apfid = top_node_api.resolve_api_fid(file_id, server_folder)
|
289
335
|
# force node as transfer agent
|
290
|
-
|
291
|
-
url: client_apfid[:api].
|
336
|
+
transfer.agent_instance = Agent::Node.new({
|
337
|
+
url: client_apfid[:api].base_url,
|
292
338
|
username: client_apfid[:api].app_info[:node_info]['access_key'],
|
293
339
|
password: client_apfid[:api].oauth_token,
|
294
340
|
root_id: client_apfid[:file_id]
|
@@ -303,22 +349,21 @@ module Aspera
|
|
303
349
|
server_apfid[:file_id],
|
304
350
|
client_direction,
|
305
351
|
add_ts)))
|
306
|
-
else
|
352
|
+
else Aspera.error_unreachable_line
|
307
353
|
end # command_repo
|
308
|
-
|
354
|
+
Aspera.error_unreachable_line
|
309
355
|
end # execute_nodegen4_command
|
310
356
|
|
311
357
|
def execute_admin_action
|
312
358
|
# upgrade scope to admin
|
313
|
-
aoc_api.oauth.
|
359
|
+
aoc_api.oauth.scope = Api::AoC::SCOPE_FILES_ADMIN
|
314
360
|
command_admin = options.get_next_command(%i[ats resource usage_reports analytics subscription auth_providers])
|
315
361
|
case command_admin
|
316
362
|
when :auth_providers
|
317
363
|
command_auth_prov = options.get_next_command(%i[list update])
|
318
364
|
case command_auth_prov
|
319
365
|
when :list
|
320
|
-
|
321
|
-
return {type: :object_list, data: providers}
|
366
|
+
return result_list('admin/auth_providers')
|
322
367
|
when :update
|
323
368
|
raise 'not implemented'
|
324
369
|
end
|
@@ -378,15 +423,15 @@ module Aspera
|
|
378
423
|
result = bss_api.create('graphql', {'variables' => {'organization_id' => org['id']}, 'query' => graphql_query})[:data]['data']
|
379
424
|
return {type: :single_object, data: result['aoc']['bssSubscription']}
|
380
425
|
when :ats
|
381
|
-
ats_api = Rest.new(aoc_api.params.deep_merge({
|
382
|
-
base_url: "#{aoc_api.
|
383
|
-
auth: {scope: AoC::SCOPE_FILES_ADMIN_USER}
|
426
|
+
ats_api = Rest.new(**aoc_api.params.deep_merge({
|
427
|
+
base_url: "#{aoc_api.base_url}/admin/ats/pub/v1",
|
428
|
+
auth: {scope: Api::AoC::SCOPE_FILES_ADMIN_USER}
|
384
429
|
}))
|
385
|
-
return Ats.new(
|
430
|
+
return Ats.new(**init_params).execute_action_gen(ats_api)
|
386
431
|
when :analytics
|
387
|
-
analytics_api = Rest.new(aoc_api.params.deep_merge({
|
388
|
-
base_url: "#{aoc_api.
|
389
|
-
auth: {scope: AoC::SCOPE_FILES_ADMIN_USER}
|
432
|
+
analytics_api = Rest.new(**aoc_api.params.deep_merge({
|
433
|
+
base_url: "#{aoc_api.base_url.gsub('/api/v1', '')}/analytics/v2",
|
434
|
+
auth: {scope: Api::AoC::SCOPE_FILES_ADMIN_USER}
|
390
435
|
}))
|
391
436
|
command_analytics = options.get_next_command(%i[application_events transfers])
|
392
437
|
case command_analytics
|
@@ -402,18 +447,22 @@ module Aspera
|
|
402
447
|
when :organizations then aoc_api.current_user_info['organization_id']
|
403
448
|
when :users then aoc_api.current_user_info['id']
|
404
449
|
when :nodes then aoc_api.current_user_info['id'] # TODO: consistent ? # rubocop:disable Lint/DuplicateBranch
|
405
|
-
else
|
450
|
+
else Aspera.error_unreachable_line
|
406
451
|
end
|
407
452
|
filter = options.get_option(:query) || {}
|
408
453
|
filter['limit'] ||= 100
|
409
454
|
if options.get_option(:once_only, mandatory: true)
|
410
455
|
saved_date = []
|
411
456
|
start_date_persistency = PersistencyActionOnce.new(
|
412
|
-
manager:
|
457
|
+
manager: persistency,
|
413
458
|
data: saved_date,
|
414
|
-
|
459
|
+
id: IdGenerator.from_list([
|
460
|
+
'aoc_ana_date',
|
461
|
+
options.get_option(:url, mandatory: true),
|
462
|
+
aoc_api.context(:files)[:workspace_name],
|
415
463
|
filter_resource.to_s,
|
416
|
-
filter_id
|
464
|
+
filter_id
|
465
|
+
]))
|
417
466
|
start_date_time = saved_date.first
|
418
467
|
stop_date_time = Time.now.utc.strftime('%FT%T.%LZ')
|
419
468
|
# Log.log().error("start: #{start_date_time}")
|
@@ -484,9 +533,7 @@ module Aspera
|
|
484
533
|
when :group_membership then default_fields.push(*%w[group_id member_type member_id])
|
485
534
|
when :workspace_membership then default_fields.push(*%w[workspace_id member_type member_id])
|
486
535
|
end
|
487
|
-
|
488
|
-
formatter.display_item_count(items[:list].length, items[:total])
|
489
|
-
return {type: :object_list, data: items[:list], fields: default_fields}
|
536
|
+
return result_list(resource_class_path, fields: default_fields, default_query: default_query)
|
490
537
|
when :show
|
491
538
|
object = aoc_api.read(resource_instance_path)[:data]
|
492
539
|
# default: show all, but certificate
|
@@ -511,12 +558,13 @@ module Aspera
|
|
511
558
|
return Main.result_success
|
512
559
|
when :do
|
513
560
|
command_repo = options.get_next_command(NODE4_EXT_COMMANDS)
|
514
|
-
|
561
|
+
# init context
|
562
|
+
aoc_api.context(:files)
|
515
563
|
return execute_nodegen4_command(command_repo, res_id)
|
516
|
-
else
|
564
|
+
else Aspera.error_unexpected_value(command)
|
517
565
|
end
|
518
566
|
when :usage_reports
|
519
|
-
return
|
567
|
+
return result_list('usage_reports', base_query: {workspace_id: aoc_api.context(:files)[:workspace_id]})
|
520
568
|
end
|
521
569
|
end
|
522
570
|
|
@@ -538,10 +586,10 @@ module Aspera
|
|
538
586
|
when :reminder
|
539
587
|
# send an email reminder with list of orgs
|
540
588
|
user_email = options.get_option(:username, mandatory: true)
|
541
|
-
Rest.new(base_url: "#{AoC.api_base_url}/#{AoC::API_V1}").create('organization_reminders', {email: user_email})[:data]
|
589
|
+
Rest.new(base_url: "#{Api::AoC.api_base_url}/#{Api::AoC::API_V1}").create('organization_reminders', {email: user_email})[:data]
|
542
590
|
return Main.result_status("List of organizations user is member of, has been sent by e-mail to #{user_email}")
|
543
591
|
when :servers
|
544
|
-
return {type: :object_list, data: Rest.new(base_url: "#{AoC.api_base_url}/#{AoC::API_V1}").read('servers')[:data]}
|
592
|
+
return {type: :object_list, data: Rest.new(base_url: "#{Api::AoC.api_base_url}/#{Api::AoC::API_V1}").read('servers')[:data]}
|
545
593
|
when :bearer_token
|
546
594
|
return {type: :text, data: aoc_api.oauth_token}
|
547
595
|
when :organization
|
@@ -549,15 +597,15 @@ module Aspera
|
|
549
597
|
when :tier_restrictions
|
550
598
|
return { type: :single_object, data: aoc_api.read('tier_restrictions')[:data] }
|
551
599
|
when :user
|
552
|
-
case options.get_next_command(%i[workspaces profile])
|
600
|
+
case options.get_next_command(%i[workspaces profile preferences])
|
553
601
|
# when :settings
|
554
602
|
# return {type: :object_list,data: aoc_api.read('client_settings/')[:data]}
|
555
603
|
when :workspaces
|
556
604
|
case options.get_next_command(%i[list current])
|
557
605
|
when :list
|
558
|
-
return
|
606
|
+
return result_list('workspaces', fields: %w[id name])
|
559
607
|
when :current
|
560
|
-
return { type: :single_object, data: aoc_api.read("workspaces/#{aoc_api.context(:
|
608
|
+
return { type: :single_object, data: aoc_api.read("workspaces/#{aoc_api.context(:files)[:workspace_id]}")[:data] }
|
561
609
|
end
|
562
610
|
when :profile
|
563
611
|
case options.get_next_command(%i[show modify])
|
@@ -567,19 +615,25 @@ module Aspera
|
|
567
615
|
aoc_api.update("users/#{aoc_api.current_user_info(exception: true)['id']}", options.get_next_argument('properties', type: Hash))
|
568
616
|
return Main.result_status('modified')
|
569
617
|
end
|
618
|
+
when :preferences
|
619
|
+
user_preferences_res = "users/#{aoc_api.current_user_info(exception: true)['id']}/user_interaction_preferences"
|
620
|
+
case options.get_next_command(%i[show modify])
|
621
|
+
when :show
|
622
|
+
return { type: :single_object, data: aoc_api.read(user_preferences_res)[:data] }
|
623
|
+
when :modify
|
624
|
+
aoc_api.update(user_preferences_res, options.get_next_argument('properties', type: Hash))
|
625
|
+
return Main.result_status('modified')
|
626
|
+
end
|
570
627
|
end
|
571
628
|
when :packages
|
572
|
-
package_command = options.get_next_command(%i[shared_inboxes send
|
629
|
+
package_command = options.get_next_command(%i[shared_inboxes send receive list show delete].concat(Node::NODE4_READ_ACTIONS), aliases: {recv: :receive})
|
573
630
|
case package_command
|
574
631
|
when :shared_inboxes
|
575
632
|
case options.get_next_command(%i[list show])
|
576
633
|
when :list
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
query['workspace_id'] = aoc_api.context[:workspace_id] unless aoc_api.context[:workspace_id].eql?(:undefined)
|
581
|
-
end
|
582
|
-
return {type: :object_list, data: aoc_api.read('dropbox_memberships', query)[:data], fields: ['dropbox_id', 'dropbox.name']}
|
634
|
+
default_query = {'embed[]' => 'dropbox', 'aggregate_permissions_by_dropbox' => true, 'sort' => 'dropbox_name'}
|
635
|
+
default_query['workspace_id'] = aoc_api.context[:workspace_id] unless aoc_api.context[:workspace_id].eql?(:undefined)
|
636
|
+
return result_list('dropbox_memberships', fields: %w[dropbox_id dropbox.name], default_query: default_query)
|
583
637
|
when :show
|
584
638
|
return {type: :single_object, data: aoc_api.read(get_resource_path_from_args('dropboxes'), query)[:data]}
|
585
639
|
end
|
@@ -603,7 +657,7 @@ module Aspera
|
|
603
657
|
Main.result_transfer(transfer.start(created_package[:spec], rest_token: created_package[:node]))
|
604
658
|
# return all info on package (especially package id)
|
605
659
|
return { type: :single_object, data: created_package[:info]}
|
606
|
-
when :
|
660
|
+
when :receive
|
607
661
|
ids_to_download = nil
|
608
662
|
if !aoc_api.public_link.nil?
|
609
663
|
aoc_api.assert_public_link_types(['view_received_package'])
|
@@ -615,8 +669,9 @@ module Aspera
|
|
615
669
|
skip_ids_data = []
|
616
670
|
skip_ids_persistency = nil
|
617
671
|
if options.get_option(:once_only, mandatory: true)
|
672
|
+
# TODO: add query info to id
|
618
673
|
skip_ids_persistency = PersistencyActionOnce.new(
|
619
|
-
manager:
|
674
|
+
manager: persistency,
|
620
675
|
data: skip_ids_data,
|
621
676
|
id: IdGenerator.from_list(
|
622
677
|
['aoc_recv',
|
@@ -624,30 +679,30 @@ module Aspera
|
|
624
679
|
aoc_api.context[:workspace_id]
|
625
680
|
].concat(aoc_api.additional_persistence_ids)))
|
626
681
|
end
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
raise 'not both dropbox_name and dropbox_id' if query.key?('dropbox_id')
|
633
|
-
query['dropbox_id'] = aoc_api.lookup_by_name('dropboxes', query['dropbox_name'])['id']
|
634
|
-
query.delete('dropbox_name')
|
635
|
-
end
|
636
|
-
query['workspace_id'] ||= aoc_api.context[:workspace_id] unless aoc_api.context[:workspace_id].eql?(:undefined)
|
637
|
-
# get list of packages in inbox
|
638
|
-
package_info = aoc_api.read('packages', query)[:data]
|
682
|
+
case ids_to_download
|
683
|
+
when ExtendedValue::ALL, ExtendedValue::INIT
|
684
|
+
query = query_read_delete(default: PACKAGE_RECEIVED_BASE_QUERY)
|
685
|
+
Aspera.assert_type(query, Hash){'query'}
|
686
|
+
resolve_dropbox_name_default_ws_id(query)
|
639
687
|
# remove from list the ones already downloaded
|
640
|
-
|
688
|
+
all_ids = api_read_all('packages', query)[:data].map{|e|e['id']}
|
689
|
+
if ids_to_download.eql?(ExtendedValue::INIT)
|
690
|
+
Aspera.assert(skip_ids_persistency){'Only with option once_only'}
|
691
|
+
skip_ids_persistency.data.clear.concat(all_ids)
|
692
|
+
skip_ids_persistency.save
|
693
|
+
return Main.result_status("Initialized skip for #{skip_ids_persistency.data.count} package(s)")
|
694
|
+
end
|
641
695
|
# array here
|
642
|
-
ids_to_download.reject
|
696
|
+
ids_to_download = all_ids.reject{|id|skip_ids_data.include?(id)}
|
697
|
+
else
|
698
|
+
ids_to_download = [ids_to_download] unless ids_to_download.is_a?(Array)
|
643
699
|
end # ExtendedValue::ALL
|
644
700
|
# list here
|
645
|
-
ids_to_download = [ids_to_download] unless ids_to_download.is_a?(Array)
|
646
701
|
result_transfer = []
|
647
702
|
formatter.display_status("found #{ids_to_download.length} package(s).")
|
648
703
|
ids_to_download.each do |package_id|
|
649
704
|
package_info = aoc_api.read("packages/#{package_id}")[:data]
|
650
|
-
formatter.display_status("downloading package: #{package_info['name']}")
|
705
|
+
formatter.display_status("downloading package: [#{package_info['id']}] #{package_info['name']}")
|
651
706
|
package_node_api = aoc_api.node_api_from(
|
652
707
|
node_id: package_info['node_id'],
|
653
708
|
workspace_id: aoc_api.context[:workspace_id],
|
@@ -656,7 +711,7 @@ module Aspera
|
|
656
711
|
statuses = transfer.start(
|
657
712
|
package_node_api.transfer_spec_gen4(
|
658
713
|
package_info['contents_file_id'],
|
659
|
-
|
714
|
+
Transfer::Spec::DIRECTION_RECEIVE,
|
660
715
|
{'paths'=> [{'source' => '.'}]}),
|
661
716
|
rest_token: package_node_api)
|
662
717
|
result_transfer.push({'package' => package_id, Main::STATUS_FIELD => statuses})
|
@@ -673,36 +728,25 @@ module Aspera
|
|
673
728
|
return { type: :single_object, data: package_info }
|
674
729
|
when :list
|
675
730
|
display_fields = %w[id name bytes_transferred]
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
raise 'not both dropbox_name and dropbox_id' if query.key?('dropbox_id')
|
681
|
-
query['dropbox_id'] = aoc_api.lookup_by_name('dropboxes', query['dropbox_name'])['id']
|
682
|
-
query.delete('dropbox_name')
|
683
|
-
end
|
684
|
-
if aoc_api.context[:workspace_id].eql?(:undefined)
|
685
|
-
display_fields.push('workspace_id')
|
686
|
-
else
|
687
|
-
query['workspace_id'] ||= aoc_api.context[:workspace_id]
|
688
|
-
end
|
689
|
-
packages = aoc_api.read('packages', query)[:data]
|
690
|
-
return {type: :object_list, data: packages, fields: display_fields}
|
731
|
+
display_fields.push('workspace_id') if aoc_api.context[:workspace_id].eql?(:undefined)
|
732
|
+
return result_list('packages', fields: display_fields, base_query: PACKAGE_RECEIVED_BASE_QUERY) do |query|
|
733
|
+
resolve_dropbox_name_default_ws_id(query)
|
734
|
+
end
|
691
735
|
when :delete
|
692
736
|
return do_bulk_operation(command: package_command, descr: 'identifier', values: identifier) do |id|
|
693
|
-
|
737
|
+
Aspera.assert_values(id.class, [String, Integer]){'identifier'}
|
694
738
|
aoc_api.delete("packages/#{id}")[:data]
|
695
739
|
end
|
696
740
|
when *Node::NODE4_READ_ACTIONS
|
697
741
|
package_id = instance_identifier
|
698
742
|
package_info = aoc_api.read("packages/#{package_id}")[:data]
|
699
|
-
return execute_nodegen4_command(package_command, package_info['node_id'], file_id: package_info['file_id'], scope:
|
743
|
+
return execute_nodegen4_command(package_command, package_info['node_id'], file_id: package_info['file_id'], scope: Api::Node::SCOPE_USER)
|
700
744
|
end
|
701
745
|
when :files
|
702
746
|
command_repo = options.get_next_command([:short_link].concat(NODE4_EXT_COMMANDS))
|
703
747
|
case command_repo
|
704
748
|
when *NODE4_EXT_COMMANDS
|
705
|
-
return execute_nodegen4_command(command_repo, aoc_api.context[:home_node_id], file_id: aoc_api.context[:home_file_id], scope:
|
749
|
+
return execute_nodegen4_command(command_repo, aoc_api.context[:home_node_id], file_id: aoc_api.context[:home_file_id], scope: Api::Node::SCOPE_USER)
|
706
750
|
when :short_link
|
707
751
|
link_type = options.get_next_argument('link type', expected: %i[public private])
|
708
752
|
short_link_command = options.get_next_command(%i[create delete list])
|
@@ -720,7 +764,7 @@ module Aspera
|
|
720
764
|
purpose = case link_type
|
721
765
|
when :public then 'token_auth_redirection'
|
722
766
|
when :private then 'shared_folder_auth_link'
|
723
|
-
else
|
767
|
+
else Aspera.error_unreachable_line
|
724
768
|
end
|
725
769
|
case short_link_command
|
726
770
|
when :delete
|
@@ -754,8 +798,7 @@ module Aspera
|
|
754
798
|
# embed: 'updated_by_user',
|
755
799
|
sort: '-created_at'
|
756
800
|
}
|
757
|
-
|
758
|
-
return {type: :object_list, data: result, fields: Formatter.all_but('data')}
|
801
|
+
return result_list('short_links', fields: Formatter.all_but('data'), base_query: list_params)
|
759
802
|
when :create
|
760
803
|
creation_params = {
|
761
804
|
purpose: purpose,
|
@@ -781,7 +824,7 @@ module Aspera
|
|
781
824
|
if link_type.eql?(:public)
|
782
825
|
# TODO: merge with node permissions ?
|
783
826
|
# TODO: access level as arg
|
784
|
-
access_levels =
|
827
|
+
access_levels = Api::Node::ACCESS_LEVELS # ['delete','list','mkdir','preview','read','rename','write']
|
785
828
|
folder_name = File.basename(folder_dest)
|
786
829
|
perm_data = {
|
787
830
|
'file_id' => shared_apfid[:file_id],
|
@@ -810,9 +853,7 @@ module Aspera
|
|
810
853
|
when :automation
|
811
854
|
Log.log.warn('BETA: work under progress')
|
812
855
|
# automation api is not in the same place
|
813
|
-
|
814
|
-
automation_rest_params[:base_url].gsub!('/api/', '/automation/')
|
815
|
-
automation_api = Rest.new(automation_rest_params)
|
856
|
+
automation_api = Rest.new(**aoc_api.params.merge(base_url: aoc_api.base_url.gsub('/api/', '/automation/')))
|
816
857
|
command_automation = options.get_next_command(%i[workflows instances])
|
817
858
|
case command_automation
|
818
859
|
when :instances
|
@@ -846,21 +887,16 @@ module Aspera
|
|
846
887
|
url = value_create_modify(command: command, type: String)
|
847
888
|
uri = URI.parse(url)
|
848
889
|
server = WebServerSimple.new(uri)
|
849
|
-
server.mount(uri.path, Faspex4GWServlet, aoc_api, aoc_api.context(:
|
850
|
-
trap('INT') { server.shutdown }
|
851
|
-
formatter.display_status("Faspex 4 gateway listening on #{url}")
|
852
|
-
Log.log.info("Listening on #{url}")
|
853
|
-
# this is blocking until server exits
|
890
|
+
server.mount(uri.path, Faspex4GWServlet, aoc_api, aoc_api.context(:files)[:workspace_id])
|
854
891
|
server.start
|
855
892
|
return Main.result_status('Gateway terminated')
|
856
|
-
else
|
857
|
-
raise "internal error: #{command}"
|
893
|
+
else Aspera.error_unreachable_line
|
858
894
|
end # action
|
859
|
-
|
895
|
+
Aspera.error_unreachable_line
|
860
896
|
end
|
861
897
|
|
862
898
|
private :execute_admin_action
|
863
|
-
end
|
864
|
-
end
|
865
|
-
end
|
866
|
-
end
|
899
|
+
end
|
900
|
+
end
|
901
|
+
end
|
902
|
+
end
|