aspera-cli 4.25.3 → 4.26.0.pre
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/CHANGELOG.md +39 -6
- data/CONTRIBUTING.md +119 -111
- data/README.md +9 -7
- data/lib/aspera/agent/direct.rb +10 -8
- data/lib/aspera/agent/factory.rb +3 -3
- data/lib/aspera/agent/node.rb +1 -1
- data/lib/aspera/api/alee.rb +1 -0
- data/lib/aspera/api/aoc.rb +13 -12
- data/lib/aspera/api/ats.rb +1 -1
- data/lib/aspera/api/cos_node.rb +5 -0
- data/lib/aspera/api/faspex.rb +15 -2
- data/lib/aspera/api/httpgw.rb +2 -0
- data/lib/aspera/api/node.rb +82 -29
- data/lib/aspera/ascp/installation.rb +9 -10
- data/lib/aspera/cli/error.rb +8 -0
- data/lib/aspera/cli/formatter.rb +27 -11
- data/lib/aspera/cli/info.rb +2 -1
- data/lib/aspera/cli/main.rb +30 -12
- data/lib/aspera/cli/manager.rb +43 -31
- data/lib/aspera/cli/plugins/aoc.rb +7 -5
- data/lib/aspera/cli/plugins/base.rb +2 -79
- data/lib/aspera/cli/plugins/config.rb +2 -1
- data/lib/aspera/cli/plugins/faspex.rb +1 -1
- data/lib/aspera/cli/plugins/faspex5.rb +51 -51
- data/lib/aspera/cli/plugins/node.rb +9 -14
- data/lib/aspera/cli/plugins/shares.rb +4 -2
- data/lib/aspera/cli/special_values.rb +1 -0
- data/lib/aspera/cli/transfer_agent.rb +3 -0
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/cli/wizard.rb +2 -1
- data/lib/aspera/dot_container.rb +10 -10
- data/lib/aspera/log.rb +1 -1
- data/lib/aspera/markdown.rb +1 -1
- data/lib/aspera/persistency_folder.rb +1 -1
- data/lib/aspera/rest.rb +34 -49
- data/lib/aspera/rest_list.rb +116 -0
- data/lib/aspera/sync/operations.rb +1 -1
- data/lib/aspera/transfer/parameters.rb +8 -8
- data/lib/aspera/transfer/spec.rb +1 -0
- data/lib/aspera/yaml.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +4 -3
- metadata.gz.sig +0 -0
data/lib/aspera/cli/manager.rb
CHANGED
|
@@ -194,7 +194,9 @@ module Aspera
|
|
|
194
194
|
[error_msg, 'Use:'].concat(accept_list.map{ |c| "- #{c}"}.sort).join("\n")
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
-
#
|
|
197
|
+
# Change option name with dash to name with underscore
|
|
198
|
+
# @param name [String] option name
|
|
199
|
+
# @return [String]
|
|
198
200
|
def option_line_to_name(name)
|
|
199
201
|
return name.gsub(OPTION_SEP_LINE, OPTION_SEP_SYMBOL)
|
|
200
202
|
end
|
|
@@ -211,7 +213,7 @@ module Aspera
|
|
|
211
213
|
def initialize(program_name, argv = nil)
|
|
212
214
|
# command line values *not* starting with '-'
|
|
213
215
|
@unprocessed_cmd_line_arguments = []
|
|
214
|
-
# command line values starting with '-'
|
|
216
|
+
# command line values starting with at least one '-'
|
|
215
217
|
@unprocessed_cmd_line_options = []
|
|
216
218
|
# a copy of all initial options
|
|
217
219
|
@initial_cli_options = []
|
|
@@ -330,7 +332,7 @@ module Aspera
|
|
|
330
332
|
|
|
331
333
|
# @param descr [String] description for help
|
|
332
334
|
# @param mandatory [Boolean] if true, raise error if option not set
|
|
333
|
-
# @param multiple [Boolean] if true, return remaining arguments (Array)
|
|
335
|
+
# @param multiple [Boolean] if true, return remaining arguments (Array) until END
|
|
334
336
|
# @param accept_list [Array, NilClass] list of allowed values (Symbol)
|
|
335
337
|
# @param validation [Class, Array, NilClass] Accepted value type(s) or list of Symbols
|
|
336
338
|
# @param aliases [Hash] map of aliases: key = alias, value = real value
|
|
@@ -345,10 +347,19 @@ module Aspera
|
|
|
345
347
|
descr = "#{descr} (#{validation.join(', ')})" unless validation.nil? || validation.eql?(Allowed::TYPES_STRING)
|
|
346
348
|
result =
|
|
347
349
|
if !@unprocessed_cmd_line_arguments.empty?
|
|
348
|
-
|
|
349
|
-
|
|
350
|
+
if multiple
|
|
351
|
+
index = @unprocessed_cmd_line_arguments.index(SpecialValues::EOA)
|
|
352
|
+
if index.nil?
|
|
353
|
+
values = @unprocessed_cmd_line_arguments.shift(@unprocessed_cmd_line_arguments.length)
|
|
354
|
+
else
|
|
355
|
+
values = @unprocessed_cmd_line_arguments.shift(index)
|
|
356
|
+
@unprocessed_cmd_line_arguments.shift # remove EOA
|
|
357
|
+
end
|
|
358
|
+
else
|
|
359
|
+
values = [@unprocessed_cmd_line_arguments.shift]
|
|
360
|
+
end
|
|
350
361
|
values = values.map{ |v| ExtendedValue.instance.evaluate(v, context: "argument: #{descr}", allowed: validation)}
|
|
351
|
-
#
|
|
362
|
+
# If expecting list and only one arg of type array : it is the list
|
|
352
363
|
values = values.first if multiple && values.length.eql?(1) && values.first.is_a?(Array)
|
|
353
364
|
if accept_list
|
|
354
365
|
allowed_values = [].concat(accept_list)
|
|
@@ -457,21 +468,17 @@ module Aspera
|
|
|
457
468
|
# @return [Hash] options as taken from config file and command line just before command execution
|
|
458
469
|
def unprocessed_options_with_value
|
|
459
470
|
result = {}
|
|
460
|
-
@initial_cli_options.each do |
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
@unprocessed_cmd_line_options.delete(option_value)
|
|
472
|
-
else
|
|
473
|
-
raise Cli::BadArgument, "wrong option format: #{option_value}"
|
|
474
|
-
end
|
|
471
|
+
@initial_cli_options.each do |option_argument|
|
|
472
|
+
# ignore short options
|
|
473
|
+
next unless option_argument.start_with?(OPTION_PREFIX)
|
|
474
|
+
name, value = option_argument[OPTION_PREFIX.length..-1].split(OPTION_VALUE_SEPARATOR, 2)
|
|
475
|
+
# ignore options without value
|
|
476
|
+
next if value.nil?
|
|
477
|
+
Log.log.debug{"option #{name}=#{value}"}
|
|
478
|
+
path = name.split(DotContainer::SEPARATOR)
|
|
479
|
+
path[0] = self.class.option_line_to_name(path[0])
|
|
480
|
+
DotContainer.dotted_to_container(path, smart_convert(value), result)
|
|
481
|
+
@unprocessed_cmd_line_options.delete(option_argument)
|
|
475
482
|
end
|
|
476
483
|
return result
|
|
477
484
|
end
|
|
@@ -507,20 +514,25 @@ module Aspera
|
|
|
507
514
|
rescue OptionParser::InvalidOption => e
|
|
508
515
|
Log.log.trace1{"InvalidOption #{e}".red}
|
|
509
516
|
# An option like --a.b.c=d does: a={"b":{"c":ext_val(d)}}
|
|
510
|
-
if
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
517
|
+
if e.args.first.start_with?(OPTION_PREFIX)
|
|
518
|
+
name, value = e.args.first[OPTION_PREFIX.length..-1].split(OPTION_VALUE_SEPARATOR, 2)
|
|
519
|
+
if !value.nil?
|
|
520
|
+
path = name.split(DotContainer::SEPARATOR)
|
|
521
|
+
option_sym = self.class.option_line_to_name(path.shift)
|
|
522
|
+
if @declared_options.key?(option_sym)
|
|
523
|
+
# it's a known option, so let's process it
|
|
524
|
+
set_option(option_sym, DotContainer.dotted_to_container(path, smart_convert(value), get_option(option_sym)), where: 'dotted')
|
|
525
|
+
# resume to next
|
|
526
|
+
retry
|
|
527
|
+
end
|
|
516
528
|
end
|
|
517
529
|
end
|
|
518
|
-
#
|
|
530
|
+
# Save for later processing
|
|
519
531
|
unknown_options.push(e.args.first)
|
|
520
532
|
retry
|
|
521
533
|
end
|
|
522
534
|
Log.log.trace1{"remains: #{unknown_options}"}
|
|
523
|
-
#
|
|
535
|
+
# Set unprocessed options for next time
|
|
524
536
|
@unprocessed_cmd_line_options = unknown_options
|
|
525
537
|
end
|
|
526
538
|
|
|
@@ -587,9 +599,9 @@ module Aspera
|
|
|
587
599
|
ExtendedValue.assert_no_value(arg, :p)
|
|
588
600
|
result = nil
|
|
589
601
|
get_next_argument(:args, multiple: true).each do |arg|
|
|
590
|
-
Aspera.assert(arg.include?(OPTION_VALUE_SEPARATOR)){"Positional argument: #{arg} does not
|
|
602
|
+
Aspera.assert(arg.include?(OPTION_VALUE_SEPARATOR)){"Positional argument: #{arg} does not include #{OPTION_VALUE_SEPARATOR}"}
|
|
591
603
|
path, value = arg.split(OPTION_VALUE_SEPARATOR, 2)
|
|
592
|
-
result = DotContainer.dotted_to_container(path, smart_convert(value), result)
|
|
604
|
+
result = DotContainer.dotted_to_container(path.split(DotContainer::SEPARATOR), smart_convert(value), result)
|
|
593
605
|
end
|
|
594
606
|
result
|
|
595
607
|
end
|
|
@@ -233,8 +233,7 @@ module Aspera
|
|
|
233
233
|
defaults: {workspace: nil},
|
|
234
234
|
scope: @scope,
|
|
235
235
|
subpath: aoc_base_path,
|
|
236
|
-
secret_finder: config
|
|
237
|
-
progress_disp: formatter
|
|
236
|
+
secret_finder: config
|
|
238
237
|
))
|
|
239
238
|
end
|
|
240
239
|
|
|
@@ -256,7 +255,10 @@ module Aspera
|
|
|
256
255
|
# @param hash [Hash,nil] Optional base `Hash` (modified)
|
|
257
256
|
# @param string [Boolean] `true` to set key as `String`, else as `Symbol`
|
|
258
257
|
# @param name [Boolean] Include name
|
|
259
|
-
# @return [Hash
|
|
258
|
+
# @return [Hash{Symbol, String => String}] the modified hash containing:
|
|
259
|
+
# * `workspace_id` [String] the unique identifier.
|
|
260
|
+
# * `workspace_name` [String] (optional) the name, included if +name+ is true.
|
|
261
|
+
# @note The key type (String or Symbol) depends on the +string+ parameter.
|
|
260
262
|
def workspace_id_hash(hash = nil, string: false, name: false)
|
|
261
263
|
info = aoc_api.workspace
|
|
262
264
|
hash = {} if hash.nil?
|
|
@@ -742,7 +744,7 @@ module Aspera
|
|
|
742
744
|
# Short link entity: `short_links` have:
|
|
743
745
|
# - a numerical id, e.g. `764412`
|
|
744
746
|
# - a resource type, e.g. `UrlToken`
|
|
745
|
-
# - a
|
|
747
|
+
# - a resource id, e.g. `scQ7uXPbvQ`
|
|
746
748
|
# - a short URL path, e.g. `dxyRpT9`
|
|
747
749
|
# @param shared_data [Hash] Information for shared data: dropbox_id+name or file_id+node_id
|
|
748
750
|
# @param &perm_block [Proc] Optional: create/modify/delete permissions on node
|
|
@@ -885,7 +887,7 @@ module Aspera
|
|
|
885
887
|
|
|
886
888
|
def reject_packages_from_persistency(all_packages, skip_ids_persistency)
|
|
887
889
|
return if skip_ids_persistency.nil?
|
|
888
|
-
skip_package = skip_ids_persistency.data.
|
|
890
|
+
skip_package = skip_ids_persistency.data.to_h{ |i| [i, true]}
|
|
889
891
|
all_packages.reject!{ |pkg| skip_package[pkg['id']]}
|
|
890
892
|
end
|
|
891
893
|
|
|
@@ -190,7 +190,7 @@ module Aspera
|
|
|
190
190
|
return Main.result_single_object(api.read(one_res_path), fields: display_fields)
|
|
191
191
|
when :list
|
|
192
192
|
if tclo
|
|
193
|
-
data, total = list_entities_limit_offset_total_count(
|
|
193
|
+
data, total = api.list_entities_limit_offset_total_count(entity:, items_key: items_key, query: query_read_delete(default: list_query))
|
|
194
194
|
return Main.result_object_list(data, total: total, fields: display_fields)
|
|
195
195
|
end
|
|
196
196
|
data, http = api.read(entity, query_read_delete, ret: :both)
|
|
@@ -259,86 +259,9 @@ module Aspera
|
|
|
259
259
|
return value
|
|
260
260
|
end
|
|
261
261
|
|
|
262
|
-
# Get a (full or partial) list of all entities of a given type with query: offset/limit
|
|
263
|
-
# @param api [Rest] API object
|
|
264
|
-
# @param entity [String,Symbol] API endpoint of entity to list
|
|
265
|
-
# @param items_key [String] Key in the result to get the list of items (Default: same as `entity`)
|
|
266
|
-
# @param query [Hash,nil] Additional query parameters
|
|
267
|
-
# @return [Array<(Array<Hash>, Integer)>] items, total_count
|
|
268
|
-
def list_entities_limit_offset_total_count(
|
|
269
|
-
api:,
|
|
270
|
-
entity:,
|
|
271
|
-
items_key: nil,
|
|
272
|
-
query: nil
|
|
273
|
-
)
|
|
274
|
-
entity = entity.to_s if entity.is_a?(Symbol)
|
|
275
|
-
items_key = entity.split('/').last if items_key.nil?
|
|
276
|
-
query = {} if query.nil?
|
|
277
|
-
Aspera.assert_type(entity, String)
|
|
278
|
-
Aspera.assert_type(items_key, String)
|
|
279
|
-
Aspera.assert_type(query, Hash)
|
|
280
|
-
Log.log.debug{"list_entities t=#{entity} k=#{items_key} q=#{query}"}
|
|
281
|
-
result = []
|
|
282
|
-
offset = 0
|
|
283
|
-
max_items = query.delete(MAX_ITEMS)
|
|
284
|
-
remain_pages = query.delete(MAX_PAGES)
|
|
285
|
-
# Merge default parameters, by default 100 per page
|
|
286
|
-
query = {'limit'=> PER_PAGE_DEFAULT}.merge(query)
|
|
287
|
-
total_count = nil
|
|
288
|
-
loop do
|
|
289
|
-
query['offset'] = offset
|
|
290
|
-
page_result = api.read(entity, query)
|
|
291
|
-
Aspera.assert_type(page_result[items_key], Array)
|
|
292
|
-
result.concat(page_result[items_key])
|
|
293
|
-
# Reach the limit set by user ?
|
|
294
|
-
if !max_items.nil? && (result.length >= max_items)
|
|
295
|
-
result = result.slice(0, max_items)
|
|
296
|
-
break
|
|
297
|
-
end
|
|
298
|
-
total_count ||= page_result['total_count']
|
|
299
|
-
break if result.length >= total_count
|
|
300
|
-
remain_pages -= 1 unless remain_pages.nil?
|
|
301
|
-
break if remain_pages == 0
|
|
302
|
-
offset += page_result[items_key].length
|
|
303
|
-
formatter.long_operation_running
|
|
304
|
-
end
|
|
305
|
-
formatter.long_operation_terminated
|
|
306
|
-
return result, total_count
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
# Lookup an entity id from its name.
|
|
310
|
-
# Uses query `q` if `query` is `:default` and `field` is `name`.
|
|
311
|
-
# @param entity [String] Type of entity to lookup, by default it is the path, and it is also the field name in result
|
|
312
|
-
# @param value [String] Value to lookup
|
|
313
|
-
# @param field [String] Field to match, by default it is `'name'`
|
|
314
|
-
# @param items_key [String] Key in the result to get the list of items (override entity)
|
|
315
|
-
# @param query [Hash] Additional query parameters (Default: `:default`)
|
|
316
|
-
def lookup_entity_by_field(api:, entity:, value:, field: 'name', items_key: nil, query: :default)
|
|
317
|
-
if query.eql?(:default)
|
|
318
|
-
Aspera.assert(field.eql?('name')){'Default query is on name only'}
|
|
319
|
-
query = {'q'=> value}
|
|
320
|
-
end
|
|
321
|
-
lookup_entity_generic(entity: entity, field: field, value: value){list_entities_limit_offset_total_count(api: api, entity: entity, items_key: items_key, query: query).first}
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
# Lookup entity by field and value. Extract single result from list of result returned by block.
|
|
325
|
-
# @param entity [String] Type of entity to lookup, by default it is the path, and it is also the field name in result
|
|
326
|
-
# @param value [String] Value to lookup
|
|
327
|
-
# @param field [String] Field to match, by default it is `'name'`
|
|
328
|
-
# @param block [Proc] Get list of entity matching query.
|
|
329
|
-
def lookup_entity_generic(entity:, value:, field: 'name', &block)
|
|
330
|
-
Aspera.assert(block_given?)
|
|
331
|
-
found = yield
|
|
332
|
-
Aspera.assert_array_all(found, Hash)
|
|
333
|
-
found = found.select{ |i| i[field].eql?(value)}
|
|
334
|
-
return found.first if found.length.eql?(1)
|
|
335
|
-
raise Cli::BadIdentifier.new(entity, value, field: field, count: found.length)
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
PER_PAGE_DEFAULT = 1000
|
|
339
262
|
# Percent selector: select by this field for this value
|
|
340
263
|
REGEX_LOOKUP_ID_BY_FIELD = /^%([^:]+):(.*)$/
|
|
341
|
-
private_constant :
|
|
264
|
+
private_constant :REGEX_LOOKUP_ID_BY_FIELD
|
|
342
265
|
end
|
|
343
266
|
end
|
|
344
267
|
end
|
|
@@ -191,7 +191,8 @@ module Aspera
|
|
|
191
191
|
def setup_rest_and_transfer_runtime
|
|
192
192
|
RestParameters.instance.user_agent = Info::CMD_NAME
|
|
193
193
|
RestParameters.instance.progress_bar = @progress_bar
|
|
194
|
-
RestParameters.instance.session_cb =
|
|
194
|
+
RestParameters.instance.session_cb = ->(http_session){update_http_session(http_session)}
|
|
195
|
+
RestParameters.instance.spinner_cb = ->(title = nil, action: :spin){formatter.long_operation(title, action: action)}
|
|
195
196
|
# Check http options that are global
|
|
196
197
|
keys_to_delete = []
|
|
197
198
|
@option_http_options.each do |k, v|
|
|
@@ -211,7 +211,7 @@ module Aspera
|
|
|
211
211
|
end
|
|
212
212
|
# add special key
|
|
213
213
|
package['items'] = package['link'].is_a?(Array) ? package['link'].length : 0
|
|
214
|
-
package['metadata'] = package['metadata']['field'].
|
|
214
|
+
package['metadata'] = package['metadata']['field'].to_h{ |i| [i['name'], i['content']]}
|
|
215
215
|
# if we look for a specific package
|
|
216
216
|
stop_condition = true if !stop_at_id.nil? && stop_at_id.eql?(package[PACKAGE_MATCH_FIELD])
|
|
217
217
|
# keep only those for the specified recipient
|
|
@@ -108,16 +108,17 @@ module Aspera
|
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
# if recipient is just an email, then convert to expected API hash : name and type
|
|
111
|
-
def normalize_recipients(parameters)
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
def normalize_recipients(parameters, type)
|
|
112
|
+
type = type.to_s
|
|
113
|
+
return unless parameters.key?(type)
|
|
114
|
+
Aspera.assert_type(parameters[type], Array){type}
|
|
114
115
|
recipient_types = Api::Faspex::RECIPIENT_TYPES
|
|
115
116
|
if parameters.key?('recipient_types')
|
|
116
117
|
recipient_types = parameters['recipient_types']
|
|
117
118
|
parameters.delete('recipient_types')
|
|
118
119
|
recipient_types = [recipient_types] unless recipient_types.is_a?(Array)
|
|
119
120
|
end
|
|
120
|
-
parameters[
|
|
121
|
+
parameters[type].map! do |recipient_data|
|
|
121
122
|
# If just a string, make a general lookup and build expected name/type hash
|
|
122
123
|
if recipient_data.is_a?(String)
|
|
123
124
|
matched = @api_v5.lookup_by_name('contacts', recipient_data, query: Rest.php_style({context: 'packages', type: recipient_types}))
|
|
@@ -157,17 +158,17 @@ module Aspera
|
|
|
157
158
|
end
|
|
158
159
|
end
|
|
159
160
|
|
|
160
|
-
# @param [
|
|
161
|
+
# @param [String] job identifier
|
|
161
162
|
# @return [Hash] result of API call for job status
|
|
162
163
|
def wait_for_job(job_id)
|
|
163
164
|
result = nil
|
|
164
165
|
loop do
|
|
165
166
|
result = @api_v5.read("jobs/#{job_id}", {type: :formatted})
|
|
166
167
|
break unless Api::Faspex::JOB_RUNNING.include?(result['status'])
|
|
167
|
-
|
|
168
|
+
RestParameters.instance.spinner_cb.call(result['status'])
|
|
168
169
|
sleep(0.5)
|
|
169
170
|
end
|
|
170
|
-
|
|
171
|
+
RestParameters.instance.spinner_cb.call(action: :success)
|
|
171
172
|
return result
|
|
172
173
|
end
|
|
173
174
|
|
|
@@ -182,16 +183,22 @@ module Aspera
|
|
|
182
183
|
when *Api::Faspex::API_LIST_MAILBOX_TYPES then "#{box}/packages"
|
|
183
184
|
else
|
|
184
185
|
group_type = options.get_option(:group_type)
|
|
185
|
-
"#{group_type}/#{lookup_entity_by_field(
|
|
186
|
+
"#{group_type}/#{@api_v5.lookup_entity_by_field(entity: group_type, value: box)['id']}/packages"
|
|
186
187
|
end
|
|
187
|
-
list, total = list_entities_limit_offset_total_count(
|
|
188
|
-
api: @api_v5,
|
|
189
|
-
entity: entity,
|
|
190
|
-
query: query_read_delete(default: query)
|
|
191
|
-
)
|
|
188
|
+
list, total = @api_v5.list_entities_limit_offset_total_count(entity: entity, query: query_read_delete(default: query))
|
|
192
189
|
return list.select(&filter), total
|
|
193
190
|
end
|
|
194
191
|
|
|
192
|
+
# Build query to get package recipients based on package info in case of shared inbox or workgroup recipient
|
|
193
|
+
# @param package_id [String] the package id to get info from
|
|
194
|
+
def recipient_query(package_id)
|
|
195
|
+
package_info = @api_v5.read("packages/#{package_id}")
|
|
196
|
+
base_query = {}
|
|
197
|
+
base_query['recipient_workgroup_id'] = package_info['recipients'].first['id'] if WORKGROUP_TYPES.include?(package_info['recipients'].first['recipient_type'])
|
|
198
|
+
base_query['recipient_user_id'] = package_info['recipients'].first['id'] if package_info['recipients'].first['recipient_type'].eql?('user')
|
|
199
|
+
base_query
|
|
200
|
+
end
|
|
201
|
+
|
|
195
202
|
def package_receive(package_ids)
|
|
196
203
|
# prepare persistency if needed
|
|
197
204
|
skip_ids_persistency = nil
|
|
@@ -241,7 +248,7 @@ module Aspera
|
|
|
241
248
|
type: Api::Faspex.box_type(box),
|
|
242
249
|
transfer_type: Api::Faspex::TRANSFER_CONNECT
|
|
243
250
|
}
|
|
244
|
-
download_params[:recipient_workgroup_id] = lookup_entity_by_field(
|
|
251
|
+
# download_params[:recipient_workgroup_id] = @api_v5.lookup_entity_by_field(entity: options.get_option(:group_type), value: box)['id'] if !Api::Faspex::API_LIST_MAILBOX_TYPES.include?(box) && box != SpecialValues::ALL
|
|
245
252
|
packages.each do |package|
|
|
246
253
|
pkg_id = package['id']
|
|
247
254
|
formatter.display_status("Receiving package #{pkg_id}")
|
|
@@ -249,7 +256,7 @@ module Aspera
|
|
|
249
256
|
transfer_spec = @api_v5.call(
|
|
250
257
|
operation: 'POST',
|
|
251
258
|
subpath: "packages/#{pkg_id}/transfer_spec/download",
|
|
252
|
-
query: download_params,
|
|
259
|
+
query: download_params.merge(recipient_query(pkg_id)),
|
|
253
260
|
content_type: Mime::JSON,
|
|
254
261
|
body: param_file_list,
|
|
255
262
|
headers: {'Accept' => Mime::JSON}
|
|
@@ -276,7 +283,7 @@ module Aspera
|
|
|
276
283
|
recipient_type: @api_v5.pub_link_context['recipient_type']
|
|
277
284
|
}]
|
|
278
285
|
end
|
|
279
|
-
normalize_recipients(parameters)
|
|
286
|
+
PACKAGE_RECIPIENT_TYPES.each{ |type| normalize_recipients(parameters, type)}
|
|
280
287
|
# User specified content prot in tspec, but faspex requires in package creation
|
|
281
288
|
# `transfer_spec/upload` will set `content_protection`
|
|
282
289
|
if transfer.user_transfer_spec['content_protection'] && !parameters.key?('ear_enabled')
|
|
@@ -298,8 +305,7 @@ module Aspera
|
|
|
298
305
|
else
|
|
299
306
|
# send from remote shared folder
|
|
300
307
|
if (m = Base.percent_selector(shared_folder))
|
|
301
|
-
shared_folder = lookup_entity_by_field(
|
|
302
|
-
api: @api_v5,
|
|
308
|
+
shared_folder = @api_v5.lookup_entity_by_field(
|
|
303
309
|
entity: 'shared_folders',
|
|
304
310
|
field: m[:field],
|
|
305
311
|
value: m[:value]
|
|
@@ -319,9 +325,9 @@ module Aspera
|
|
|
319
325
|
|
|
320
326
|
# Browse a folder
|
|
321
327
|
# @param browse_endpoint [String] the endpoint to browse
|
|
322
|
-
def browse_folder(browse_endpoint)
|
|
328
|
+
def browse_folder(browse_endpoint, base_query = {})
|
|
323
329
|
folders_to_process = [options.get_next_argument('folder path', default: '/')]
|
|
324
|
-
query = query_read_delete(default: {})
|
|
330
|
+
query = base_query.merge(query_read_delete(default: {}))
|
|
325
331
|
filters = query.delete('filters'){{}}
|
|
326
332
|
Aspera.assert_type(filters, Hash)
|
|
327
333
|
filters['basenames'] ||= []
|
|
@@ -357,7 +363,7 @@ module Aspera
|
|
|
357
363
|
end
|
|
358
364
|
folders_to_process.concat(data['items'].select{ |i| i['type'].eql?('directory')}.map{ |i| i['path']}) if recursive
|
|
359
365
|
if use_paging
|
|
360
|
-
iteration_token = http[Api::Faspex::
|
|
366
|
+
iteration_token = http[Api::Faspex::HEADER_X_NEXT_ITER_TOKEN]
|
|
361
367
|
break if iteration_token.nil? || iteration_token.empty?
|
|
362
368
|
query['iteration_token'] = iteration_token
|
|
363
369
|
else
|
|
@@ -365,12 +371,11 @@ module Aspera
|
|
|
365
371
|
break if data['item_count'].eql?(0)
|
|
366
372
|
query['offset'] += data['item_count']
|
|
367
373
|
end
|
|
368
|
-
|
|
374
|
+
RestParameters.instance.spinner_cb.call(all_items.count)
|
|
369
375
|
end
|
|
370
376
|
query.delete('iteration_token')
|
|
371
377
|
end
|
|
372
|
-
|
|
373
|
-
|
|
378
|
+
RestParameters.instance.spinner_cb.call(action: :success)
|
|
374
379
|
return Main.result_object_list(all_items, total: total_count)
|
|
375
380
|
end
|
|
376
381
|
|
|
@@ -384,7 +389,7 @@ module Aspera
|
|
|
384
389
|
when :show
|
|
385
390
|
return Main.result_single_object(@api_v5.read("packages/#{package_id}"))
|
|
386
391
|
when :browse
|
|
387
|
-
return browse_folder("packages/#{package_id}/files/#{Api::Faspex.box_type(options.get_option(:box))}")
|
|
392
|
+
return browse_folder("packages/#{package_id}/files/#{Api::Faspex.box_type(options.get_option(:box))}", recipient_query(package_id))
|
|
388
393
|
when :status
|
|
389
394
|
status_list = options.get_next_argument('list of states, or nothing', mandatory: false, validation: Array)
|
|
390
395
|
status = wait_package_status(package_id, status_list: status_list)
|
|
@@ -447,18 +452,20 @@ module Aspera
|
|
|
447
452
|
res_id_query = {'all': true}
|
|
448
453
|
when :nodes
|
|
449
454
|
available_commands += %i[shared_folders browse]
|
|
455
|
+
when :jobs
|
|
456
|
+
exec_args[:display_fields] = %w[id job_name job_type status]
|
|
450
457
|
end
|
|
451
458
|
res_command = options.get_next_command(available_commands)
|
|
452
459
|
return Main.result_value_list(Api::Faspex::EMAIL_NOTIF_LIST, name: 'email_id') if res_command.eql?(:list) && res_sym.eql?(:email_notifications)
|
|
453
460
|
case res_command
|
|
454
461
|
when *ALL_OPS
|
|
455
462
|
return entity_execute(command: res_command, **exec_args) do |field, value|
|
|
456
|
-
lookup_entity_by_field(
|
|
463
|
+
@api_v5.lookup_entity_by_field(entity: exec_args[:entity], value: value, field: field, items_key: exec_args[:items_key], query: res_id_query)['id']
|
|
457
464
|
end
|
|
458
465
|
when :shared_folders
|
|
459
466
|
# nodes
|
|
460
467
|
node_id = instance_identifier do |field, value|
|
|
461
|
-
lookup_entity_by_field(
|
|
468
|
+
@api_v5.lookup_entity_by_field(entity: 'nodes', field: field, value: value)['id']
|
|
462
469
|
end
|
|
463
470
|
shfld_entity = "nodes/#{node_id}/shared_folders"
|
|
464
471
|
sh_command = options.get_next_command(ALL_OPS + [:user])
|
|
@@ -469,33 +476,32 @@ module Aspera
|
|
|
469
476
|
entity: shfld_entity,
|
|
470
477
|
command: sh_command
|
|
471
478
|
) do |field, value|
|
|
472
|
-
lookup_entity_by_field(
|
|
479
|
+
@api_v5.lookup_entity_by_field(entity: shfld_entity, field: field, value: value)['id']
|
|
473
480
|
end
|
|
474
481
|
when :user
|
|
475
482
|
sh_id = instance_identifier do |field, value|
|
|
476
|
-
lookup_entity_by_field(
|
|
483
|
+
@api_v5.lookup_entity_by_field(entity: shfld_entity, field: field, value: value)['id']
|
|
477
484
|
end
|
|
478
485
|
user_path = "#{shfld_entity}/#{sh_id}/custom_access_users"
|
|
479
486
|
return entity_execute(api: @api_v5, entity: user_path, items_key: 'users') do |field, value|
|
|
480
|
-
lookup_entity_by_field(
|
|
487
|
+
@api_v5.lookup_entity_by_field(entity: user_path, items_key: 'users', field: field, value: value)['id']
|
|
481
488
|
end
|
|
482
489
|
|
|
483
490
|
end
|
|
484
491
|
when :browse
|
|
485
492
|
# nodes
|
|
486
493
|
node_id = instance_identifier do |field, value|
|
|
487
|
-
lookup_entity_by_field(
|
|
494
|
+
@api_v5.lookup_entity_by_field(entity: 'nodes', value: value, field: field)['id']
|
|
488
495
|
end
|
|
489
496
|
return browse_folder("nodes/#{node_id}/browse")
|
|
490
497
|
when :invite_external_collaborator
|
|
491
498
|
# :shared_inboxes, :workgroups
|
|
492
|
-
shared_inbox_id = instance_identifier{ |field, value| lookup_entity_by_field(
|
|
499
|
+
shared_inbox_id = instance_identifier{ |field, value| @api_v5.lookup_entity_by_field(entity: res_sym.to_s, field: field, value: value, query: res_id_query)['id']}
|
|
493
500
|
creation_payload = value_create_modify(command: res_command, type: [Hash, String])
|
|
494
501
|
creation_payload = {'email_address' => creation_payload} if creation_payload.is_a?(String)
|
|
495
502
|
result = @api_v5.create("#{res_sym}/#{shared_inbox_id}/external_collaborator", creation_payload)
|
|
496
503
|
formatter.display_status(result['message'])
|
|
497
|
-
result = lookup_entity_by_field(
|
|
498
|
-
api: @api_v5,
|
|
504
|
+
result = @api_v5.lookup_entity_by_field(
|
|
499
505
|
entity: "#{res_sym}/#{shared_inbox_id}/members",
|
|
500
506
|
items_key: 'members',
|
|
501
507
|
value: creation_payload['email_address'],
|
|
@@ -504,7 +510,7 @@ module Aspera
|
|
|
504
510
|
return Main.result_single_object(result)
|
|
505
511
|
when :members, :saml_groups
|
|
506
512
|
# res_command := :shared_inboxes, :workgroups
|
|
507
|
-
res_id = instance_identifier{ |field, value| lookup_entity_by_field(
|
|
513
|
+
res_id = instance_identifier{ |field, value| @api_v5.lookup_entity_by_field(entity: res_sym.to_s, field: field, value: value, query: res_id_query)['id']}
|
|
508
514
|
res_path = "#{res_sym}/#{res_id}/#{res_command}"
|
|
509
515
|
list_key = res_command.to_s
|
|
510
516
|
list_key = 'groups' if res_command.eql?(:saml_groups)
|
|
@@ -515,8 +521,7 @@ module Aspera
|
|
|
515
521
|
users = [users] unless users.is_a?(Array)
|
|
516
522
|
users = users.map do |user|
|
|
517
523
|
if (m = Base.percent_selector(user))
|
|
518
|
-
lookup_entity_by_field(
|
|
519
|
-
api: @api_v5,
|
|
524
|
+
@api_v5.lookup_entity_by_field(
|
|
520
525
|
entity: 'accounts',
|
|
521
526
|
field: m[:field],
|
|
522
527
|
value: m[:value],
|
|
@@ -537,8 +542,7 @@ module Aspera
|
|
|
537
542
|
command: sub_command,
|
|
538
543
|
items_key: list_key
|
|
539
544
|
) do |field, value|
|
|
540
|
-
lookup_entity_by_field(
|
|
541
|
-
api: @api_v5,
|
|
545
|
+
@api_v5.lookup_entity_by_field(
|
|
542
546
|
entity: res_path,
|
|
543
547
|
field: field,
|
|
544
548
|
value: value,
|
|
@@ -547,7 +551,7 @@ module Aspera
|
|
|
547
551
|
end
|
|
548
552
|
when :reset_password
|
|
549
553
|
# :accounts
|
|
550
|
-
contact_id = instance_identifier{ |field, value| lookup_entity_by_field(
|
|
554
|
+
contact_id = instance_identifier{ |field, value| @api_v5.lookup_entity_by_field(entity: 'accounts', field: field, value: value, query: res_id_query)['id']}
|
|
551
555
|
@api_v5.create("accounts/#{contact_id}/reset_password", {})
|
|
552
556
|
return Main.result_status('password reset, user shall check email')
|
|
553
557
|
end
|
|
@@ -568,16 +572,10 @@ module Aspera
|
|
|
568
572
|
event_type = options.get_next_command(%i[application webhook])
|
|
569
573
|
case event_type
|
|
570
574
|
when :application
|
|
571
|
-
list, total = list_entities_limit_offset_total_count(
|
|
572
|
-
api: @api_v5,
|
|
573
|
-
entity: 'application_events',
|
|
574
|
-
query: query_read_delete
|
|
575
|
-
)
|
|
576
|
-
|
|
575
|
+
list, total = @api_v5.list_entities_limit_offset_total_count(entity: 'application_events', query: query_read_delete)
|
|
577
576
|
return Main.result_object_list(list, total: total, fields: %w[event_type created_at application user.name])
|
|
578
577
|
when :webhook
|
|
579
|
-
list, total = list_entities_limit_offset_total_count(
|
|
580
|
-
api: @api_v5,
|
|
578
|
+
list, total = @api_v5.list_entities_limit_offset_total_count(
|
|
581
579
|
entity: 'all_webhooks_events',
|
|
582
580
|
query: query_read_delete,
|
|
583
581
|
items_key: 'events'
|
|
@@ -694,7 +692,7 @@ module Aspera
|
|
|
694
692
|
items_key: invitation_endpoint,
|
|
695
693
|
display_fields: %w[id public recipient_type recipient_name email_address]
|
|
696
694
|
) do |field, value|
|
|
697
|
-
lookup_entity_by_field(
|
|
695
|
+
@api_v5.lookup_entity_by_field(entity: invitation_endpoint, field: field, value: value, query: {})['id']
|
|
698
696
|
end
|
|
699
697
|
end
|
|
700
698
|
when :gateway
|
|
@@ -719,8 +717,10 @@ module Aspera
|
|
|
719
717
|
end
|
|
720
718
|
SHARED_INBOX_MEMBER_LEVELS = %i[submit_only standard shared_inbox_admin].freeze
|
|
721
719
|
ACCOUNT_TYPES = %w{local_user saml_user self_registered_user external_user}.freeze
|
|
722
|
-
|
|
723
|
-
|
|
720
|
+
WORKGROUP_TYPES = %w{workgroup shared_inbox}.freeze
|
|
721
|
+
CONTACT_TYPES = (WORKGROUP_TYPES + %w{distribution_list user external_user}).freeze
|
|
722
|
+
PACKAGE_RECIPIENT_TYPES = %i{recipients private_recipients notified_on_upload notified_on_download notified_on_receipt}
|
|
723
|
+
private_constant :SHARED_INBOX_MEMBER_LEVELS, :ACCOUNT_TYPES, :CONTACT_TYPES, :PACKAGE_RECIPIENT_TYPES
|
|
724
724
|
end
|
|
725
725
|
end
|
|
726
726
|
end
|
|
@@ -93,12 +93,9 @@ module Aspera
|
|
|
93
93
|
options.declare(:validator, 'Identifier of validator (optional for central)')
|
|
94
94
|
options.declare(:asperabrowserurl, 'URL for simple aspera web ui', default: 'https://asperabrowser.mybluemix.net')
|
|
95
95
|
options.declare(
|
|
96
|
-
:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
options.declare(
|
|
100
|
-
:node_cache, 'Gen4: Set to no to force actual file system read', allowed: Allowed::TYPES_BOOLEAN,
|
|
101
|
-
handler: {o: Api::Node, m: :use_node_cache}
|
|
96
|
+
:node_api, 'Gen4: standard_ports: Use standard FASP ports (true) or get from node API (false). cache: Set to false to force actual file system read',
|
|
97
|
+
allowed: Hash,
|
|
98
|
+
handler: {o: Api::Node, m: :api_options}
|
|
102
99
|
)
|
|
103
100
|
options.declare(:root_id, 'Gen4: File id of top folder when using access key (override AK root id)')
|
|
104
101
|
options.declare(:dynamic_key, 'Private key PEM to use for dynamic key auth', handler: {o: Api::Node, m: :use_dynamic_key})
|
|
@@ -242,14 +239,14 @@ module Aspera
|
|
|
242
239
|
break if all_items.count >= total_count
|
|
243
240
|
offset += items.count
|
|
244
241
|
query['skip'] = offset
|
|
245
|
-
|
|
242
|
+
RestParameters.instance.spinner_cb.call(all_items.count)
|
|
246
243
|
end
|
|
247
244
|
query.delete('skip')
|
|
248
245
|
end
|
|
249
246
|
@prefixer&.remove_in_object_list!(all_items)
|
|
250
247
|
return Main.result_object_list(all_items)
|
|
251
248
|
ensure
|
|
252
|
-
|
|
249
|
+
RestParameters.instance.spinner_cb.call(action: :success)
|
|
253
250
|
end
|
|
254
251
|
|
|
255
252
|
# Create async transfer spec request from direction and folders
|
|
@@ -388,7 +385,7 @@ module Aspera
|
|
|
388
385
|
when :transport
|
|
389
386
|
return Main.result_single_object(@api_node.transport_params)
|
|
390
387
|
when :spec
|
|
391
|
-
return Main.result_single_object(@api_node.base_spec)
|
|
388
|
+
return Main.result_single_object(@api_node.base_spec, fields: Formatter.all_but(Transfer::Spec::SPECIFIC))
|
|
392
389
|
end
|
|
393
390
|
Aspera.error_unreachable_line
|
|
394
391
|
end
|
|
@@ -523,7 +520,7 @@ module Aspera
|
|
|
523
520
|
return Main.result_text(result[:password])
|
|
524
521
|
when :browse
|
|
525
522
|
apifid = apifid_from_next_arg(top_file_id)
|
|
526
|
-
file_info = apifid[:api].read("files/#{apifid[:file_id]}",
|
|
523
|
+
file_info = apifid[:api].read("files/#{apifid[:file_id]}", headers: Api::Node.add_cache_control)
|
|
527
524
|
unless file_info['type'].eql?('folder')
|
|
528
525
|
# a single file
|
|
529
526
|
return Main.result_object_list([file_info], fields: GEN4_LS_FIELDS)
|
|
@@ -931,10 +928,8 @@ module Aspera
|
|
|
931
928
|
# do not process last one
|
|
932
929
|
break if end_date.nil?
|
|
933
930
|
# init data for this period
|
|
934
|
-
period_bandwidth = Transfer::Spec::DIRECTION_ENUM_VALUES.map(&:to_sym).
|
|
935
|
-
|
|
936
|
-
h2[k2] = 0
|
|
937
|
-
end
|
|
931
|
+
period_bandwidth = Transfer::Spec::DIRECTION_ENUM_VALUES.map(&:to_sym).to_h do |direction|
|
|
932
|
+
[direction, dir_info.to_h{ |k2| [k2, 0]}]
|
|
938
933
|
end
|
|
939
934
|
# find all transfers that were active at this time
|
|
940
935
|
transfers_data.each do |transfer|
|