aspera-cli 4.21.2 → 4.22.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 +1 -1
- data/CHANGELOG.md +34 -16
- data/CONTRIBUTING.md +6 -10
- data/README.md +805 -574
- data/examples/get_proto_file.rb +1 -1
- data/lib/aspera/agent/base.rb +9 -5
- data/lib/aspera/agent/connect.rb +30 -28
- data/lib/aspera/agent/desktop.rb +29 -25
- data/lib/aspera/agent/direct.rb +137 -125
- data/lib/aspera/agent/httpgw.rb +22 -26
- data/lib/aspera/agent/node.rb +14 -11
- data/lib/aspera/agent/transferd.rb +6 -2
- data/lib/aspera/api/aoc.rb +6 -6
- data/lib/aspera/api/cos_node.rb +1 -1
- data/lib/aspera/api/httpgw.rb +7 -3
- data/lib/aspera/api/node.rb +6 -4
- data/lib/aspera/ascmd.rb +3 -3
- data/lib/aspera/ascp/installation.rb +15 -16
- data/lib/aspera/ascp/management.rb +1 -1
- data/lib/aspera/assert.rb +11 -2
- data/lib/aspera/cli/error.rb +2 -2
- data/lib/aspera/cli/extended_value.rb +38 -19
- data/lib/aspera/cli/formatter.rb +48 -48
- data/lib/aspera/cli/hints.rb +1 -1
- data/lib/aspera/cli/main.rb +190 -168
- data/lib/aspera/cli/manager.rb +15 -15
- data/lib/aspera/cli/plugin.rb +23 -20
- data/lib/aspera/cli/plugin_factory.rb +1 -1
- data/lib/aspera/cli/plugins/alee.rb +1 -1
- data/lib/aspera/cli/plugins/aoc.rb +144 -107
- data/lib/aspera/cli/plugins/ats.rb +19 -17
- data/lib/aspera/cli/plugins/config.rb +67 -83
- data/lib/aspera/cli/plugins/console.rb +5 -3
- data/lib/aspera/cli/plugins/faspex.rb +39 -35
- data/lib/aspera/cli/plugins/faspex5.rb +104 -80
- data/lib/aspera/cli/plugins/faspio.rb +13 -1
- data/lib/aspera/cli/plugins/httpgw.rb +13 -1
- data/lib/aspera/cli/plugins/node.rb +306 -179
- data/lib/aspera/cli/plugins/orchestrator.rb +34 -40
- data/lib/aspera/cli/plugins/preview.rb +3 -3
- data/lib/aspera/cli/plugins/server.rb +6 -6
- data/lib/aspera/cli/plugins/shares.rb +5 -5
- data/lib/aspera/cli/sync_actions.rb +19 -18
- data/lib/aspera/cli/transfer_agent.rb +5 -5
- data/lib/aspera/cli/transfer_progress.rb +2 -2
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/command_line_builder.rb +116 -95
- data/lib/aspera/coverage.rb +4 -3
- data/lib/aspera/environment.rb +6 -6
- data/lib/aspera/faspex_gw.rb +14 -14
- data/lib/aspera/faspex_postproc.rb +7 -6
- data/lib/aspera/hash_ext.rb +2 -2
- data/lib/aspera/json_rpc.rb +1 -1
- data/lib/aspera/keychain/encrypted_hash.rb +47 -34
- data/lib/aspera/keychain/factory.rb +41 -0
- data/lib/aspera/keychain/hashicorp_vault.rb +71 -0
- data/lib/aspera/keychain/macos_security.rb +19 -11
- data/lib/aspera/log.rb +28 -34
- data/lib/aspera/nagios.rb +6 -6
- data/lib/aspera/node_simulator.rb +8 -8
- data/lib/aspera/oauth/base.rb +8 -6
- data/lib/aspera/oauth/factory.rb +5 -6
- data/lib/aspera/oauth/url_json.rb +6 -6
- data/lib/aspera/persistency_action_once.rb +6 -4
- data/lib/aspera/persistency_folder.rb +2 -2
- data/lib/aspera/preview/generator.rb +1 -1
- data/lib/aspera/preview/options.rb +16 -16
- data/lib/aspera/preview/terminal.rb +3 -3
- data/lib/aspera/preview/utils.rb +11 -13
- data/lib/aspera/products/connect.rb +1 -1
- data/lib/aspera/products/desktop.rb +1 -1
- data/lib/aspera/products/transferd.rb +1 -1
- data/lib/aspera/proxy_auto_config.rb +2 -2
- data/lib/aspera/rest.rb +52 -43
- data/lib/aspera/rest_errors_aspera.rb +1 -1
- data/lib/aspera/secret_hider.rb +5 -5
- data/lib/aspera/ssh.rb +4 -4
- data/lib/aspera/transfer/convert.rb +29 -0
- data/lib/aspera/transfer/error_info.rb +66 -66
- data/lib/aspera/transfer/parameters.rb +13 -68
- data/lib/aspera/transfer/spec.rb +5 -6
- data/lib/aspera/transfer/spec.schema.yaml +753 -0
- data/lib/aspera/transfer/spec_doc.rb +62 -0
- data/lib/aspera/transfer/sync.rb +23 -72
- data/lib/aspera/transfer/sync_instance.schema.yaml +13 -0
- data/lib/aspera/transfer/sync_session.schema.yaml +79 -0
- data/lib/aspera/transfer/uri.rb +6 -6
- data/lib/aspera/uri_reader.rb +1 -1
- data/lib/aspera/web_auth.rb +1 -1
- data/lib/aspera/web_server_simple.rb +53 -44
- data.tar.gz.sig +1 -2
- metadata +37 -4
- metadata.gz.sig +0 -0
- data/examples/build_package.sh +0 -28
- data/lib/aspera/transfer/spec.yaml +0 -718
@@ -53,7 +53,9 @@ module Aspera
|
|
53
53
|
'completed' => true}.freeze
|
54
54
|
# options and parameters for Api::AoC.new
|
55
55
|
OPTIONS_NEW = %i[url auth client_id client_secret scope redirect_uri private_key passphrase username password workspace].freeze
|
56
|
-
|
56
|
+
PACKAGE_LIST_DEFAULT_FIELDS = %w[id name created_at files_completed bytes_transferred].freeze
|
57
|
+
|
58
|
+
private_constant :REDIRECT_LOCALHOST, :STD_AUTH_TYPES, :ADMIN_OBJECTS, :PACKAGE_RECEIVED_BASE_QUERY, :OPTIONS_NEW, :PACKAGE_LIST_DEFAULT_FIELDS
|
57
59
|
class << self
|
58
60
|
def application_name
|
59
61
|
'Aspera on Cloud'
|
@@ -78,15 +80,16 @@ module Aspera
|
|
78
80
|
}
|
79
81
|
end
|
80
82
|
|
81
|
-
# @param [String] url
|
83
|
+
# @param url [String] url to check
|
82
84
|
# @return [Bool] true if private key is required for the url (i.e. no passcode)
|
83
85
|
def private_key_required?(url)
|
84
86
|
# pub link do not need private key
|
85
87
|
return Api::AoC.link_info(url)[:token].nil?
|
86
88
|
end
|
87
89
|
|
88
|
-
# @param [
|
89
|
-
# @param [
|
90
|
+
# @param object [Plugin] An instance of this class
|
91
|
+
# @param private_key_path [String] path to private key
|
92
|
+
# @param pub_key_pem [String] PEM of public key
|
90
93
|
# @return [Hash] :preset_value, :test_args
|
91
94
|
def wizard(object:, private_key_path: nil, pub_key_pem: nil)
|
92
95
|
# set vars to look like object
|
@@ -121,7 +124,7 @@ module Aspera
|
|
121
124
|
formatter.display_status('Please Login to your Aspera on Cloud instance.')
|
122
125
|
formatter.display_status('Navigate to: 👤 → Account Settings → Profile → Public Key')
|
123
126
|
formatter.display_status('Check or update the value to:'.red.blink)
|
124
|
-
formatter.display_status(pub_key_pem)
|
127
|
+
formatter.display_status(pub_key_pem, hide_secrets: false)
|
125
128
|
if !options.get_option(:test_mode)
|
126
129
|
formatter.display_status('Once updated or validated, press enter.')
|
127
130
|
Environment.instance.open_uri(instance_url)
|
@@ -203,7 +206,7 @@ module Aspera
|
|
203
206
|
def api_from_options(new_base_path)
|
204
207
|
create_values = {subpath: new_base_path, secret_finder: config}
|
205
208
|
# create an API object with the same options, but with a different subpath
|
206
|
-
return Api::AoC.new(**OPTIONS_NEW.each_with_object(create_values)
|
209
|
+
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?})
|
207
210
|
rescue ArgumentError => e
|
208
211
|
if (m = e.message.match(/missing keyword: :(.*)$/))
|
209
212
|
raise Cli::Error, "Missing option: #{m[1]}"
|
@@ -216,13 +219,31 @@ module Aspera
|
|
216
219
|
@cache_api_aoc = api_from_options(Api::AoC::API_V1)
|
217
220
|
organization = @cache_api_aoc.read('organization')
|
218
221
|
if organization['http_gateway_enabled'] && organization['http_gateway_server_url']
|
219
|
-
transfer.httpgw_url_cb = lambda
|
222
|
+
transfer.httpgw_url_cb = lambda{organization['http_gateway_server_url']}
|
220
223
|
# @cache_api_aoc.current_user_info['connect_disabled']
|
221
224
|
end
|
222
225
|
end
|
223
226
|
return @cache_api_aoc
|
224
227
|
end
|
225
228
|
|
229
|
+
# Generate or update Hash with workspace id and name (option), if not already set
|
230
|
+
# @param hash [Hash, Nil] set in provided hash
|
231
|
+
# @param string [Bool] true to set key as string, else as symbol
|
232
|
+
# @param name [Bool] include name
|
233
|
+
# @return [Hash] with key `workspace_[id,name]` (symbol or string) only if defined
|
234
|
+
def workspace_id_hash(hash: nil, string: false, name: false)
|
235
|
+
info = aoc_api.workspace
|
236
|
+
hash = {} if hash.nil?
|
237
|
+
fields = %i[id]
|
238
|
+
fields.push(:name) if name
|
239
|
+
fields.each do |i|
|
240
|
+
k = "workspace_#{i}"
|
241
|
+
k = k.to_sym unless string
|
242
|
+
hash[k] = info[i] unless info[i].nil? || hash.key?(k)
|
243
|
+
end
|
244
|
+
return hash
|
245
|
+
end
|
246
|
+
|
226
247
|
# Get resource identifier from command line, either directly or from name.
|
227
248
|
# @param resource_class_path url path for resource
|
228
249
|
# @return identifier
|
@@ -240,7 +261,7 @@ module Aspera
|
|
240
261
|
|
241
262
|
# Call block with same query using paging and response information
|
242
263
|
# block must return a hash with :data and :http keys
|
243
|
-
# @return [Hash] {
|
264
|
+
# @return [Hash] {items: , total: }
|
244
265
|
def api_call_paging(base_query={})
|
245
266
|
Aspera.assert_type(base_query, Hash){'query'}
|
246
267
|
Aspera.assert(block_given?)
|
@@ -268,46 +289,59 @@ module Aspera
|
|
268
289
|
item_list += add_items
|
269
290
|
break if !max_items.nil? && item_list.count >= max_items
|
270
291
|
break if !max_pages.nil? && page_count >= max_pages
|
292
|
+
formatter.long_operation_running("#{item_list.count} / #{total_count}") unless total_count.eql?(item_list.count.to_s)
|
271
293
|
end
|
294
|
+
formatter.long_operation_terminated
|
272
295
|
item_list = item_list[0..max_items - 1] if !max_items.nil? && item_list.count > max_items
|
273
|
-
return {
|
296
|
+
return {items: item_list, total: total_count}
|
274
297
|
end
|
275
298
|
|
276
299
|
# read using the query and paging
|
277
300
|
# @return [Hash] {data: , total: }
|
278
301
|
def api_read_all(resource_class_path, base_query={})
|
279
302
|
return api_call_paging(base_query) do |query|
|
280
|
-
aoc_api.call(operation: 'GET', subpath: resource_class_path, headers: {'Accept' =>
|
303
|
+
aoc_api.call(operation: 'GET', subpath: resource_class_path, headers: {'Accept' => Rest::MIME_JSON}, query: query)
|
281
304
|
end
|
282
305
|
end
|
283
306
|
|
284
|
-
#
|
307
|
+
# List all entities, given additional, default and user's queries
|
285
308
|
# @param resource_class_path path to query on API
|
286
309
|
# @param fields fields to display
|
287
310
|
# @param base_query a query applied always
|
288
311
|
# @param default_query default query unless overriden by user
|
312
|
+
# @param &block (Optional) calls block with user's or default query
|
289
313
|
def result_list(resource_class_path, fields: nil, base_query: {}, default_query: {})
|
290
314
|
Aspera.assert_type(base_query, Hash)
|
291
315
|
Aspera.assert_type(default_query, Hash)
|
292
|
-
|
293
|
-
# caller may add specific modifications or checks
|
294
|
-
yield(
|
295
|
-
|
316
|
+
query = query_read_delete(default: default_query)
|
317
|
+
# caller may add specific modifications or checks to query
|
318
|
+
yield(query) if block_given?
|
319
|
+
result = api_read_all(resource_class_path, base_query.merge(query).compact)
|
320
|
+
return Main.result_object_list(result[:items], fields: fields, total: result[:total])
|
296
321
|
end
|
297
322
|
|
323
|
+
# Translates `dropbox_name` to `dropbox_id` and fills current workspace_id
|
298
324
|
def resolve_dropbox_name_default_ws_id(query)
|
299
325
|
if query.key?('dropbox_name')
|
300
326
|
# convenience: specify name instead of id
|
301
|
-
raise '
|
327
|
+
raise 'Use field dropbox_name or dropbox_id, not both' if query.key?('dropbox_id')
|
302
328
|
# TODO : craft a query that looks for dropbox only in current workspace
|
303
|
-
query['dropbox_id'] = aoc_api.lookup_by_name('dropboxes', query
|
304
|
-
query.delete('dropbox_name')
|
329
|
+
query['dropbox_id'] = aoc_api.lookup_by_name('dropboxes', query.delete('dropbox_name'))['id']
|
305
330
|
end
|
306
|
-
query
|
331
|
+
workspace_id_hash(hash: query, string: true)
|
307
332
|
# by default show dropbox packages only for dropboxes
|
308
333
|
query['exclude_dropbox_packages'] = !query.key?('dropbox_id') unless query.key?('exclude_dropbox_packages')
|
309
334
|
end
|
310
335
|
|
336
|
+
# @return [Hash] {items,total} with all packages according to combination of user's query and default query
|
337
|
+
def list_all_packages_with_query
|
338
|
+
query = query_read_delete(default: {})
|
339
|
+
Aspera.assert_type(query, Hash){'query'}
|
340
|
+
PACKAGE_RECEIVED_BASE_QUERY.each{ |k, v| query[k] = v unless query.key?(k)}
|
341
|
+
resolve_dropbox_name_default_ws_id(query)
|
342
|
+
return api_read_all('packages', query.compact)
|
343
|
+
end
|
344
|
+
|
311
345
|
NODE4_EXT_COMMANDS = %i[transfer].concat(Node::COMMANDS_GEN4).freeze
|
312
346
|
private_constant :NODE4_EXT_COMMANDS
|
313
347
|
|
@@ -316,9 +350,8 @@ module Aspera
|
|
316
350
|
def execute_nodegen4_command(command_repo, node_id, file_id: nil, scope: nil)
|
317
351
|
top_node_api = aoc_api.node_api_from(
|
318
352
|
node_id: node_id,
|
319
|
-
|
320
|
-
|
321
|
-
scope: scope
|
353
|
+
scope: scope,
|
354
|
+
**workspace_id_hash(name: true)
|
322
355
|
)
|
323
356
|
file_id = top_node_api.read("access_keys/#{top_node_api.app_info[:node_info]['access_key']}")['root_file_id'] if file_id.nil?
|
324
357
|
node_plugin = Node.new(**init_params, api: top_node_api)
|
@@ -422,8 +455,8 @@ module Aspera
|
|
422
455
|
when :show
|
423
456
|
object = aoc_api.read(resource_instance_path)
|
424
457
|
# default: show all, but certificate
|
425
|
-
fields = object.keys.reject{|k|k.eql?('certificate')}
|
426
|
-
return
|
458
|
+
fields = object.keys.reject{ |k| k.eql?('certificate')}
|
459
|
+
return Main.result_single_object(object, fields: fields)
|
427
460
|
when :modify
|
428
461
|
changes = options.get_next_argument('properties', validation: Hash)
|
429
462
|
return do_bulk_operation(command: command, descr: 'identifier', values: res_id) do |one_id|
|
@@ -529,7 +562,7 @@ module Aspera
|
|
529
562
|
GRAPHQL
|
530
563
|
# cspell:enable
|
531
564
|
result = bss_graphql.create(nil, {query: graphql_query, variables: {organization_id: org['id']}})['data']
|
532
|
-
return
|
565
|
+
return Main.result_single_object(result['aoc']['bssSubscription'])
|
533
566
|
when :usage
|
534
567
|
# cspell:disable
|
535
568
|
graphql_query = <<-GRAPHQL
|
@@ -576,7 +609,7 @@ module Aspera
|
|
576
609
|
aggregate: aggregate,
|
577
610
|
startDate: start_date,
|
578
611
|
endDate: end_date}})['data']
|
579
|
-
return
|
612
|
+
return Main.result_single_object(result['aoc'])
|
580
613
|
end
|
581
614
|
when :ats
|
582
615
|
ats_api = Rest.new(**aoc_api.params.deep_merge({
|
@@ -594,7 +627,7 @@ module Aspera
|
|
594
627
|
when :application_events
|
595
628
|
event_type = command_analytics.to_s
|
596
629
|
events = analytics_api.read("organizations/#{aoc_api.current_user_info['organization_id']}/#{event_type}")[event_type]
|
597
|
-
return
|
630
|
+
return Main.result_object_list(events)
|
598
631
|
when :transfers
|
599
632
|
event_type = command_analytics.to_s
|
600
633
|
filter_resource = options.get_next_argument('resource', accept_list: %i[organizations users nodes])
|
@@ -635,25 +668,26 @@ module Aspera
|
|
635
668
|
config.send_email_template(values: {ev: tr_event})
|
636
669
|
end
|
637
670
|
end
|
638
|
-
return
|
671
|
+
return Main.result_object_list(events)
|
639
672
|
end
|
640
673
|
when :usage_reports
|
641
674
|
aoc_api.context = :files
|
642
|
-
return result_list('usage_reports', base_query:
|
675
|
+
return result_list('usage_reports', base_query: workspace_id_hash)
|
643
676
|
end
|
644
677
|
end
|
645
678
|
|
646
679
|
# Create a shared link for the given entity
|
647
|
-
# @param
|
648
|
-
# @param
|
649
|
-
|
680
|
+
# @param purpose_public [Symbol]
|
681
|
+
# @param shared_data [Hash] information for shared data
|
682
|
+
# @param block [Proc] Optional: called on creation
|
683
|
+
def short_link_command(purpose_public:, **shared_data)
|
650
684
|
link_type = options.get_next_argument('link type', accept_list: %i[public private])
|
651
685
|
purpose_local = case link_type
|
652
686
|
when :public
|
653
687
|
case purpose_public
|
654
688
|
when /package/ then 'send_package_to_dropbox'
|
655
689
|
when /shared/ then 'token_auth_redirection'
|
656
|
-
else
|
690
|
+
else Aspera.error_unexpected_value(purpose_public){'public link purpose'}
|
657
691
|
end
|
658
692
|
when :private then 'shared_folder_auth_link'
|
659
693
|
else Aspera.error_unreachable_line
|
@@ -682,7 +716,7 @@ module Aspera
|
|
682
716
|
result_create_short_link = aoc_api.create('short_links', creation_params)
|
683
717
|
# public: Creation: permission on node
|
684
718
|
yield(result_create_short_link['resource_id']) if block_given? && link_type.eql?(:public)
|
685
|
-
return
|
719
|
+
return Main.result_single_object(result_create_short_link)
|
686
720
|
when :list
|
687
721
|
query = if link_type.eql?(:private)
|
688
722
|
shared_data
|
@@ -718,6 +752,26 @@ module Aspera
|
|
718
752
|
end
|
719
753
|
end
|
720
754
|
|
755
|
+
# @return persistency object if option `once_only` is used.
|
756
|
+
def package_persistency
|
757
|
+
return nil unless options.get_option(:once_only, mandatory: true)
|
758
|
+
# TODO: add query info to id
|
759
|
+
PersistencyActionOnce.new(
|
760
|
+
manager: persistency,
|
761
|
+
data: [],
|
762
|
+
id: IdGenerator.from_list(
|
763
|
+
['aoc_recv',
|
764
|
+
options.get_option(:url, mandatory: true),
|
765
|
+
aoc_api.workspace[:id]
|
766
|
+
].concat(aoc_api.additional_persistence_ids)))
|
767
|
+
end
|
768
|
+
|
769
|
+
def reject_packages_from_persistency(all_packages, skip_ids_persistency)
|
770
|
+
return if skip_ids_persistency.nil?
|
771
|
+
skip_package = skip_ids_persistency.data.each_with_object({}){ |i, m| m[i] = true}
|
772
|
+
all_packages.reject!{ |pkg| skip_package[pkg['id']]}
|
773
|
+
end
|
774
|
+
|
721
775
|
# must be public
|
722
776
|
ACTIONS = %i[reminder servers bearer_token organization tier_restrictions user packages files admin automation gateway].freeze
|
723
777
|
|
@@ -739,29 +793,29 @@ module Aspera
|
|
739
793
|
Rest.new(base_url: "#{Api::AoC.api_base_url}/#{Api::AoC::API_V1}").create('organization_reminders', {email: user_email})
|
740
794
|
return Main.result_status("List of organizations user is member of, has been sent by e-mail to #{user_email}")
|
741
795
|
when :servers
|
742
|
-
return
|
796
|
+
return Main.result_object_list(Rest.new(base_url: "#{Api::AoC.api_base_url}/#{Api::AoC::API_V1}").read('servers'))
|
743
797
|
when :bearer_token
|
744
|
-
return
|
798
|
+
return Main.result_text(aoc_api.oauth.authorization)
|
745
799
|
when :organization
|
746
|
-
return
|
800
|
+
return Main.result_single_object(aoc_api.read('organization'))
|
747
801
|
when :tier_restrictions
|
748
|
-
return
|
802
|
+
return Main.result_single_object(aoc_api.read('tier_restrictions'))
|
749
803
|
when :user
|
750
804
|
case options.get_next_command(%i[workspaces profile preferences])
|
751
805
|
# when :settings
|
752
|
-
# return
|
806
|
+
# return Main.result_object_list(aoc_api.read('client_settings/'))
|
753
807
|
when :workspaces
|
754
808
|
case options.get_next_command(%i[list current])
|
755
809
|
when :list
|
756
810
|
return result_list('workspaces', fields: %w[id name])
|
757
811
|
when :current
|
758
812
|
aoc_api.context = :files
|
759
|
-
return
|
813
|
+
return Main.result_single_object(aoc_api.workspace)
|
760
814
|
end
|
761
815
|
when :profile
|
762
816
|
case options.get_next_command(%i[show modify])
|
763
817
|
when :show
|
764
|
-
return
|
818
|
+
return Main.result_single_object(aoc_api.current_user_info(exception: true))
|
765
819
|
when :modify
|
766
820
|
aoc_api.update("users/#{aoc_api.current_user_info(exception: true)['id']}", options.get_next_argument('properties', validation: Hash))
|
767
821
|
return Main.result_status('modified')
|
@@ -770,7 +824,7 @@ module Aspera
|
|
770
824
|
user_preferences_res = "users/#{aoc_api.current_user_info(exception: true)['id']}/user_interaction_preferences"
|
771
825
|
case options.get_next_command(%i[show modify])
|
772
826
|
when :show
|
773
|
-
return
|
827
|
+
return Main.result_single_object(aoc_api.read(user_preferences_res))
|
774
828
|
when :modify
|
775
829
|
aoc_api.update(user_preferences_res, options.get_next_argument('properties', validation: Hash))
|
776
830
|
return Main.result_status('modified')
|
@@ -783,26 +837,24 @@ module Aspera
|
|
783
837
|
case options.get_next_command(%i[list show short_link])
|
784
838
|
when :list
|
785
839
|
default_query = {'embed[]' => 'dropbox', 'aggregate_permissions_by_dropbox' => true, 'sort' => 'dropbox_name'}
|
786
|
-
default_query
|
840
|
+
workspace_id_hash(hash: default_query, string: true)
|
787
841
|
return result_list('dropbox_memberships', fields: %w[dropbox_id dropbox.name], default_query: default_query)
|
788
842
|
when :show
|
789
|
-
return
|
843
|
+
return Main.result_single_object(aoc_api.read(get_resource_path_from_args('dropboxes')))
|
790
844
|
when :short_link
|
791
845
|
return short_link_command(
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
purpose_public: 'send_package_to_dropbox')
|
846
|
+
purpose_public: 'send_package_to_dropbox',
|
847
|
+
dropbox_id: get_resource_id_from_args('dropboxes'),
|
848
|
+
name: '',
|
849
|
+
**workspace_id_hash
|
850
|
+
)
|
798
851
|
end
|
799
852
|
when :send
|
800
853
|
package_data = value_create_modify(command: package_command)
|
801
854
|
new_user_option = options.get_option(:new_user_option)
|
802
855
|
option_validate = options.get_option(:validate_metadata)
|
803
|
-
# works for both normal
|
804
|
-
package_data
|
805
|
-
|
856
|
+
# works for both normal user auth and link auth
|
857
|
+
workspace_id_hash(hash: package_data, string: true) unless package_data.key?('workspace_id')
|
806
858
|
if !aoc_api.public_link.nil?
|
807
859
|
aoc_api.assert_public_link_types(%w[send_package_to_user send_package_to_dropbox])
|
808
860
|
box_type = aoc_api.public_link['purpose'].split('_').last
|
@@ -815,64 +867,49 @@ module Aspera
|
|
815
867
|
created_package = aoc_api.create_package_simple(package_data, option_validate, new_user_option)
|
816
868
|
Main.result_transfer(transfer.start(created_package[:spec], rest_token: created_package[:node]))
|
817
869
|
# return all info on package (especially package id)
|
818
|
-
return
|
870
|
+
return Main.result_single_object(created_package[:info])
|
819
871
|
when :receive
|
820
872
|
ids_to_download = nil
|
821
873
|
if !aoc_api.public_link.nil?
|
822
874
|
aoc_api.assert_public_link_types(['view_received_package'])
|
823
|
-
# set the package id
|
875
|
+
# set the package id from link
|
824
876
|
ids_to_download = aoc_api.public_link['data']['package_id']
|
825
877
|
end
|
826
878
|
# get from command line unless it was a public link
|
827
879
|
ids_to_download ||= instance_identifier
|
828
|
-
|
829
|
-
skip_ids_persistency = nil
|
830
|
-
if options.get_option(:once_only, mandatory: true)
|
831
|
-
# TODO: add query info to id
|
832
|
-
skip_ids_persistency = PersistencyActionOnce.new(
|
833
|
-
manager: persistency,
|
834
|
-
data: skip_ids_data,
|
835
|
-
id: IdGenerator.from_list(
|
836
|
-
['aoc_recv',
|
837
|
-
options.get_option(:url, mandatory: true),
|
838
|
-
aoc_api.workspace[:id]
|
839
|
-
].concat(aoc_api.additional_persistence_ids)))
|
840
|
-
end
|
880
|
+
skip_ids_persistency = package_persistency
|
841
881
|
case ids_to_download
|
842
882
|
when SpecialValues::ALL, SpecialValues::INIT
|
843
|
-
|
844
|
-
Aspera.assert_type(query, Hash){'query'}
|
845
|
-
resolve_dropbox_name_default_ws_id(query)
|
846
|
-
# remove from list the ones already downloaded
|
847
|
-
all_ids = api_read_all('packages', query)[:data].map{|e|e['id']}
|
883
|
+
all_packages = list_all_packages_with_query[:items]
|
848
884
|
if ids_to_download.eql?(SpecialValues::INIT)
|
849
|
-
Aspera.assert(skip_ids_persistency){'
|
850
|
-
skip_ids_persistency.data.clear.concat(
|
885
|
+
Aspera.assert(skip_ids_persistency){'INIT requires option once_only'}
|
886
|
+
skip_ids_persistency.data.clear.concat(all_packages.map{ |e| e['id']})
|
851
887
|
skip_ids_persistency.save
|
852
888
|
return Main.result_status("Initialized skip for #{skip_ids_persistency.data.count} package(s)")
|
853
889
|
end
|
854
|
-
#
|
855
|
-
|
890
|
+
# remove from list the ones already downloaded
|
891
|
+
reject_packages_from_persistency(all_packages, skip_ids_persistency)
|
892
|
+
ids_to_download = all_packages.map{ |e| e['id']}
|
856
893
|
else
|
894
|
+
# single id to array
|
857
895
|
ids_to_download = [ids_to_download] unless ids_to_download.is_a?(Array)
|
858
896
|
end
|
859
897
|
file_list =
|
860
898
|
begin
|
861
|
-
transfer.source_list.map{|i|{'source'=>i}}
|
899
|
+
transfer.source_list.map{ |i| {'source'=>i}}
|
862
900
|
rescue Cli::BadArgument
|
863
901
|
[{'source' => '.'}]
|
864
902
|
end
|
865
903
|
# list here
|
866
904
|
result_transfer = []
|
867
|
-
formatter.display_status("
|
905
|
+
formatter.display_status("Found #{ids_to_download.length} package(s).")
|
868
906
|
ids_to_download.each do |package_id|
|
869
907
|
package_info = aoc_api.read("packages/#{package_id}")
|
870
908
|
formatter.display_status("downloading package: [#{package_info['id']}] #{package_info['name']}")
|
871
909
|
package_node_api = aoc_api.node_api_from(
|
872
910
|
node_id: package_info['node_id'],
|
873
|
-
|
874
|
-
|
875
|
-
package_info: package_info)
|
911
|
+
package_info: package_info,
|
912
|
+
**workspace_id_hash(name: true))
|
876
913
|
statuses = transfer.start(
|
877
914
|
package_node_api.transfer_spec_gen4(
|
878
915
|
package_info['contents_file_id'],
|
@@ -881,22 +918,23 @@ module Aspera
|
|
881
918
|
rest_token: package_node_api)
|
882
919
|
result_transfer.push({'package' => package_id, Main::STATUS_FIELD => statuses})
|
883
920
|
# update skip list only if all transfer sessions completed
|
884
|
-
if TransferAgent.session_status(statuses).eql?(:success)
|
885
|
-
|
886
|
-
skip_ids_persistency
|
921
|
+
if skip_ids_persistency && TransferAgent.session_status(statuses).eql?(:success)
|
922
|
+
skip_ids_persistency.data.push(package_id)
|
923
|
+
skip_ids_persistency.save
|
887
924
|
end
|
888
925
|
end
|
889
926
|
return Main.result_transfer_multiple(result_transfer)
|
890
927
|
when :show
|
891
928
|
package_id = instance_identifier
|
892
929
|
package_info = aoc_api.read("packages/#{package_id}")
|
893
|
-
return
|
930
|
+
return Main.result_single_object(package_info)
|
894
931
|
when :list
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
932
|
+
result = list_all_packages_with_query
|
933
|
+
skip_ids_persistency = package_persistency
|
934
|
+
reject_packages_from_persistency(result[:items], skip_ids_persistency)
|
935
|
+
display_fields = PACKAGE_LIST_DEFAULT_FIELDS
|
936
|
+
display_fields += ['workspace_id'] if aoc_api.workspace[:id].nil?
|
937
|
+
return Main.result_object_list(result[:items], fields: display_fields, total: result[:total])
|
900
938
|
when :delete
|
901
939
|
return do_bulk_operation(command: package_command, descr: 'identifier', values: instance_identifier) do |id|
|
902
940
|
Aspera.assert_values(id.class, [String, Integer]){'identifier'}
|
@@ -915,16 +953,15 @@ module Aspera
|
|
915
953
|
when :short_link
|
916
954
|
folder_dest = options.get_next_argument('path', validation: String)
|
917
955
|
home_node_api = aoc_api.node_api_from(
|
918
|
-
node_id:
|
919
|
-
|
920
|
-
workspace_name: aoc_api.workspace[:name])
|
956
|
+
node_id: aoc_api.home[:node_id],
|
957
|
+
**workspace_id_hash(name: true))
|
921
958
|
shared_apfid = home_node_api.resolve_api_fid(aoc_api.home[:file_id], folder_dest)
|
922
959
|
return short_link_command(
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
960
|
+
purpose_public: 'view_shared_file',
|
961
|
+
node_id: shared_apfid[:api].app_info[:node_info]['id'],
|
962
|
+
file_id: shared_apfid[:file_id],
|
963
|
+
**workspace_id_hash
|
964
|
+
) do |resource_id|
|
928
965
|
# TODO: merge with node permissions ?
|
929
966
|
# TODO: access level as arg
|
930
967
|
access_levels = Api::Node::ACCESS_LEVELS # ['delete','list','mkdir','preview','read','rename','write']
|
@@ -936,13 +973,12 @@ module Aspera
|
|
936
973
|
'tags' => {
|
937
974
|
# TODO: really just here ? not in tags.aspera.files.workspace ?
|
938
975
|
'url_token' => true,
|
939
|
-
'workspace_id' => aoc_api.workspace[:id],
|
940
|
-
'workspace_name' => aoc_api.workspace[:name],
|
941
976
|
'folder_name' => File.basename(folder_dest),
|
942
977
|
'created_by_name' => aoc_api.current_user_info['name'],
|
943
978
|
'created_by_email' => aoc_api.current_user_info['email'],
|
944
979
|
'access_key' => shared_apfid[:api].app_info[:node_info]['access_key'],
|
945
|
-
'node' => shared_apfid[:api].app_info[:node_info]['host']
|
980
|
+
'node' => shared_apfid[:api].app_info[:node_info]['host'],
|
981
|
+
**workspace_id_hash(string: true, name: true)
|
946
982
|
}
|
947
983
|
}
|
948
984
|
created_data = shared_apfid[:api].create('permissions', perm_data)
|
@@ -965,7 +1001,7 @@ module Aspera
|
|
965
1001
|
when :launch
|
966
1002
|
wf_id = instance_identifier
|
967
1003
|
data = automation_api.create("workflows/#{wf_id}/launch", {})
|
968
|
-
return
|
1004
|
+
return Main.result_single_object(data)
|
969
1005
|
when :action
|
970
1006
|
# TODO: not complete
|
971
1007
|
wf_id = instance_identifier
|
@@ -976,16 +1012,17 @@ module Aspera
|
|
976
1012
|
action = automation_api.create('actions', {'step_id' => step['id'], 'type' => 'manual'})
|
977
1013
|
automation_api.update("steps/#{step['id']}", {'action_order' => [action['id']]})
|
978
1014
|
wf = automation_api.read("workflows/#{wf_id}")
|
979
|
-
return
|
1015
|
+
return Main.result_single_object(wf)
|
980
1016
|
end
|
981
1017
|
end
|
982
1018
|
when :admin
|
983
1019
|
return execute_admin_action
|
984
1020
|
when :gateway
|
985
1021
|
require 'aspera/faspex_gw'
|
986
|
-
|
987
|
-
uri = URI.parse(url)
|
988
|
-
server = WebServerSimple.new(uri)
|
1022
|
+
parameters = value_create_modify(command: command, default: {}).symbolize_keys
|
1023
|
+
uri = URI.parse(parameters.delete(:url){WebServerSimple::DEFAULT_URL})
|
1024
|
+
server = WebServerSimple.new(uri, **parameters.slice(*WebServerSimple::PARAMS))
|
1025
|
+
Aspera.assert(parameters.except(*WebServerSimple::PARAMS).empty?)
|
989
1026
|
aoc_api.context = :files
|
990
1027
|
server.mount(uri.path, Faspex4GWServlet, aoc_api, aoc_api.workspace[:id])
|
991
1028
|
server.start
|