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
|
@@ -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
|