aspera-cli 4.18.0 → 4.18.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -2
- data/CHANGELOG.md +10 -0
- data/README.md +96 -59
- data/examples/build_package.sh +28 -0
- data/lib/aspera/agent/alpha.rb +4 -4
- data/lib/aspera/agent/connect.rb +3 -4
- data/lib/aspera/agent/httpgw.rb +1 -1
- data/lib/aspera/api/httpgw.rb +4 -1
- data/lib/aspera/api/node.rb +110 -77
- data/lib/aspera/ascp/products.rb +1 -1
- data/lib/aspera/cli/extended_value.rb +27 -14
- data/lib/aspera/cli/formatter.rb +11 -10
- data/lib/aspera/cli/main.rb +11 -11
- data/lib/aspera/cli/manager.rb +99 -84
- data/lib/aspera/cli/plugin.rb +2 -5
- data/lib/aspera/cli/plugins/aoc.rb +15 -14
- data/lib/aspera/cli/plugins/config.rb +20 -19
- data/lib/aspera/cli/plugins/faspex.rb +5 -4
- data/lib/aspera/cli/plugins/faspex5.rb +16 -13
- data/lib/aspera/cli/plugins/node.rb +46 -38
- data/lib/aspera/cli/plugins/orchestrator.rb +3 -2
- data/lib/aspera/cli/plugins/preview.rb +1 -1
- data/lib/aspera/cli/plugins/server.rb +1 -1
- data/lib/aspera/cli/special_values.rb +13 -0
- data/lib/aspera/cli/sync_actions.rb +4 -4
- data/lib/aspera/cli/transfer_agent.rb +2 -2
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/environment.rb +64 -4
- data/lib/aspera/oauth/web.rb +2 -2
- data/lib/aspera/rest.rb +46 -15
- data.tar.gz.sig +0 -0
- metadata +4 -3
- metadata.gz.sig +0 -0
- data/lib/aspera/open_application.rb +0 -69
@@ -5,11 +5,12 @@ require 'aspera/cli/basic_auth_plugin'
|
|
5
5
|
require 'aspera/cli/plugins/node'
|
6
6
|
require 'aspera/cli/plugins/config'
|
7
7
|
require 'aspera/cli/extended_value'
|
8
|
+
require 'aspera/cli/special_values'
|
8
9
|
require 'aspera/cli/transfer_agent'
|
9
10
|
require 'aspera/transfer/uri'
|
10
11
|
require 'aspera/transfer/spec'
|
11
12
|
require 'aspera/persistency_action_once'
|
12
|
-
require 'aspera/
|
13
|
+
require 'aspera/environment'
|
13
14
|
require 'aspera/nagios'
|
14
15
|
require 'aspera/id_generator'
|
15
16
|
require 'aspera/log'
|
@@ -353,9 +354,9 @@ module Aspera
|
|
353
354
|
delivery_id = instance_identifier
|
354
355
|
raise 'empty id' if delivery_id.empty?
|
355
356
|
recipient = options.get_option(:recipient)
|
356
|
-
if delivery_id.eql?(
|
357
|
+
if delivery_id.eql?(SpecialValues::ALL)
|
357
358
|
pkg_id_uri = mailbox_filtered_entries.map{|i|{id: i[PACKAGE_MATCH_FIELD], uri: self.class.get_fasp_uri_from_entry(i, raise_no_link: false)}}
|
358
|
-
elsif delivery_id.eql?(
|
359
|
+
elsif delivery_id.eql?(SpecialValues::INIT)
|
359
360
|
Aspera.assert(skip_ids_persistency){'Only with option once_only'}
|
360
361
|
skip_ids_persistency.data.clear.concat(mailbox_filtered_entries.map{|i|{id: i[PACKAGE_MATCH_FIELD]}})
|
361
362
|
skip_ids_persistency.save
|
@@ -390,7 +391,7 @@ module Aspera
|
|
390
391
|
headers: {'Accept' => 'application/xml'},
|
391
392
|
query: {passcode: link_data[:query]['passcode']})
|
392
393
|
if !package_creation_data[:http].body.start_with?('<?xml ')
|
393
|
-
|
394
|
+
Environment.instance.open_uri(link_url)
|
394
395
|
raise Cli::Error, 'Unexpected response: package not found ?'
|
395
396
|
end
|
396
397
|
package_entry = XmlSimple.xml_in(package_creation_data[:http].body, {'ForceArray' => false})
|
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
require 'aspera/cli/basic_auth_plugin'
|
6
6
|
require 'aspera/cli/extended_value'
|
7
|
+
require 'aspera/cli/special_values'
|
7
8
|
require 'aspera/persistency_action_once'
|
8
9
|
require 'aspera/id_generator'
|
9
10
|
require 'aspera/nagios'
|
@@ -81,7 +82,7 @@ module Aspera
|
|
81
82
|
if options.get_option(:client_id).nil? || options.get_option(:client_secret).nil?
|
82
83
|
formatter.display_status('Ask the ascli client id and secret to your Administrator.'.red)
|
83
84
|
formatter.display_status("Admin should login to: #{instance_url}")
|
84
|
-
|
85
|
+
Environment.instance.open_uri(instance_url)
|
85
86
|
formatter.display_status('Navigate to: 𓃑 → Admin → Configurations → API clients')
|
86
87
|
formatter.display_status('Create an API client with:')
|
87
88
|
formatter.display_status('- name: ascli')
|
@@ -118,7 +119,7 @@ module Aspera
|
|
118
119
|
options.declare(:auth, 'OAuth type of authentication', values: STD_AUTH_TYPES, default: :jwt)
|
119
120
|
options.declare(:private_key, 'OAuth JWT RSA private key PEM value (prefix file path with @file:)')
|
120
121
|
options.declare(:passphrase, 'OAuth JWT RSA private key passphrase')
|
121
|
-
options.declare(:box, "Package inbox, either shared inbox name or one of: #{API_LIST_MAILBOX_TYPES.join(', ')} or #{
|
122
|
+
options.declare(:box, "Package inbox, either shared inbox name or one of: #{API_LIST_MAILBOX_TYPES.join(', ')} or #{SpecialValues::ALL}", default: 'inbox')
|
122
123
|
options.declare(:shared_folder, 'Send package with files from shared folder')
|
123
124
|
options.declare(:group_type, 'Type of shared box', values: %i[shared_inboxes workgroups], default: :shared_inboxes)
|
124
125
|
options.parse_options!
|
@@ -304,12 +305,12 @@ module Aspera
|
|
304
305
|
|
305
306
|
# list all packages with optional filter
|
306
307
|
def list_packages_with_filter(query: {})
|
307
|
-
filter = options.get_next_argument('filter', mandatory: false,
|
308
|
+
filter = options.get_next_argument('filter', mandatory: false, validation: Proc, default: ->(_x){true})
|
308
309
|
# translate box name to API prefix (with ending slash)
|
309
310
|
box = options.get_option(:box)
|
310
311
|
real_path =
|
311
312
|
case box
|
312
|
-
when
|
313
|
+
when SpecialValues::ALL then 'packages' # only admin can list all packages globally
|
313
314
|
when *API_LIST_MAILBOX_TYPES then "#{box}/packages"
|
314
315
|
else
|
315
316
|
group_type = options.get_option(:group_type)
|
@@ -338,12 +339,12 @@ module Aspera
|
|
338
339
|
end
|
339
340
|
packages = []
|
340
341
|
case package_ids
|
341
|
-
when
|
342
|
+
when SpecialValues::INIT
|
342
343
|
Aspera.assert(skip_ids_persistency){'Only with option once_only'}
|
343
344
|
skip_ids_persistency.data.clear.concat(list_packages_with_filter.map{|p|p['id']})
|
344
345
|
skip_ids_persistency.save
|
345
346
|
return Main.result_status("Initialized skip for #{skip_ids_persistency.data.count} package(s)")
|
346
|
-
when
|
347
|
+
when SpecialValues::ALL
|
347
348
|
# TODO: if packages have same name, they will overwrite ?
|
348
349
|
packages = list_packages_with_filter(query: {'status' => 'completed'})
|
349
350
|
Log.log.trace1{Log.dump(:package_ids, packages.map{|p|p['id']})}
|
@@ -562,10 +563,12 @@ module Aspera
|
|
562
563
|
res_command = options.get_next_command(available_commands)
|
563
564
|
case res_command
|
564
565
|
when *Plugin::ALL_OPS
|
565
|
-
return entity_command(
|
566
|
-
|
567
|
-
|
568
|
-
|
566
|
+
return entity_command(
|
567
|
+
res_command, adm_api, res_path, item_list_key: list_key, display_fields: display_fields, id_as_arg: id_as_arg,
|
568
|
+
delete_style: delete_style) do |field, value|
|
569
|
+
lookup_entity_by_field(
|
570
|
+
type: res_type, value: value, field: field, real_path: res_path, item_list_key: list_key, query: res_id_query)['id']
|
571
|
+
end
|
569
572
|
when :shared_folders
|
570
573
|
node_id = instance_identifier do |field, value|
|
571
574
|
lookup_entity_by_field(type: res_type, field: field, value: value)['id']
|
@@ -626,7 +629,7 @@ module Aspera
|
|
626
629
|
user
|
627
630
|
end
|
628
631
|
end
|
629
|
-
access = options.get_next_argument('level', mandatory: false,
|
632
|
+
access = options.get_next_argument('level', mandatory: false, accept_list: %i[submit_only standard shared_inbox_admin], default: :standard)
|
630
633
|
# TODO: unshift to command line parameters instead of using deprecated option "value"
|
631
634
|
options.set_option(:value, {user: users.map{|u|{id: u, access: access}}})
|
632
635
|
end
|
@@ -644,7 +647,7 @@ module Aspera
|
|
644
647
|
command = options.get_next_command(%i[configuration smtp resource events clean_deleted].concat(ADMIN_RESOURCES).freeze)
|
645
648
|
case command
|
646
649
|
when :resource
|
647
|
-
# resource
|
650
|
+
# resource will be deprecated
|
648
651
|
Log.log.warn('resource command is deprecated (4.18), directly use the specific command instead')
|
649
652
|
return execute_resource(options.get_next_command(ADMIN_RESOURCES))
|
650
653
|
when *ADMIN_RESOURCES
|
@@ -722,7 +725,7 @@ module Aspera
|
|
722
725
|
when :show
|
723
726
|
return { type: :single_object, data: @api_v5.read('account/preferences')[:data] }
|
724
727
|
when :modify
|
725
|
-
@api_v5.update('account/preferences', options.get_next_argument('modified parameters',
|
728
|
+
@api_v5.update('account/preferences', options.get_next_argument('modified parameters', validation: Hash))
|
726
729
|
return Main.result_status('modified')
|
727
730
|
end
|
728
731
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# cspell:ignore snid fnid bidi ssync asyncs rund asnodeadmin mkfile mklink asperabrowser asperabrowserurl watchfolders watchfolderd entsrv
|
4
4
|
require 'aspera/cli/basic_auth_plugin'
|
5
5
|
require 'aspera/cli/sync_actions'
|
6
|
+
require 'aspera/cli/special_values'
|
6
7
|
require 'aspera/transfer/spec'
|
7
8
|
require 'aspera/nagios'
|
8
9
|
require 'aspera/hash_ext'
|
@@ -162,7 +163,7 @@ module Aspera
|
|
162
163
|
# translates paths results into CLI result, and removes prefix
|
163
164
|
def c_result_translate_rem_prefix(response, type, success_msg, path_prefix)
|
164
165
|
errors = []
|
165
|
-
final_result = { data: [],
|
166
|
+
final_result = {type: :object_list, data: [], fields: [type, 'result']}
|
166
167
|
JSON.parse(response[:http].body)['paths'].each do |p|
|
167
168
|
result = success_msg
|
168
169
|
if p.key?('error')
|
@@ -179,20 +180,11 @@ module Aspera
|
|
179
180
|
return c_result_remove_prefix_path(final_result, type, path_prefix)
|
180
181
|
end
|
181
182
|
|
182
|
-
# get path arguments from command line, and add prefix
|
183
|
-
def get_next_arg_add_prefix(path_prefix, name, number=:single)
|
184
|
-
path_or_list = options.get_next_argument(name, expected: number)
|
185
|
-
return path_or_list if path_prefix.nil?
|
186
|
-
return File.join(path_prefix, path_or_list) if path_or_list.is_a?(String)
|
187
|
-
return path_or_list.map {|p| File.join(path_prefix, p)} if path_or_list.is_a?(Array)
|
188
|
-
raise StandardError, 'expect: nil, String or Array'
|
189
|
-
end
|
190
|
-
|
191
183
|
# directory: node, container: shares
|
192
184
|
FOLDER_TYPE = %w[directory container].freeze
|
193
185
|
|
194
186
|
def browse_gen3(prefix_path)
|
195
|
-
folders_to_process = [
|
187
|
+
folders_to_process = [get_one_argument_with_prefix(prefix_path, 'path')]
|
196
188
|
query = options.get_option(:query, default: {})
|
197
189
|
# special parameter: max number of entries in result
|
198
190
|
max_items = query.delete('max')
|
@@ -254,11 +246,12 @@ module Aspera
|
|
254
246
|
def execute_command_gen3(command, prefix_path)
|
255
247
|
case command
|
256
248
|
when :delete
|
257
|
-
|
249
|
+
# TODO: add query for recursive
|
250
|
+
paths_to_delete = get_all_arguments_with_prefix(prefix_path, 'file list')
|
258
251
|
resp = @api_node.create('files/delete', { paths: paths_to_delete.map{|i| {'path' => i.start_with?('/') ? i : "/#{i}"} }})
|
259
252
|
return c_result_translate_rem_prefix(resp, 'file', 'deleted', prefix_path)
|
260
253
|
when :search
|
261
|
-
search_root =
|
254
|
+
search_root = get_one_argument_with_prefix(prefix_path, 'search root')
|
262
255
|
parameters = {'path' => search_root}
|
263
256
|
other_options = query_option
|
264
257
|
parameters.merge!(other_options) unless other_options.nil?
|
@@ -270,31 +263,30 @@ module Aspera
|
|
270
263
|
formatter.display_status("params: #{resp[:data]['parameters'].keys.map{|k|"#{k}:#{resp[:data]['parameters'][k]}"}.join(',')}")
|
271
264
|
return c_result_remove_prefix_path(result, 'path', prefix_path)
|
272
265
|
when :space
|
273
|
-
path_list =
|
274
|
-
path_list = [path_list] unless path_list.is_a?(Array)
|
266
|
+
path_list = get_all_arguments_with_prefix(prefix_path, 'folder path or ext.val. list')
|
275
267
|
resp = @api_node.create('space', { 'paths' => path_list.map {|i| { path: i} } })
|
276
|
-
result = { data: resp[:data]['paths']
|
268
|
+
result = { type: :object_list, data: resp[:data]['paths']}
|
277
269
|
# return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
278
270
|
return c_result_remove_prefix_path(result, 'path', prefix_path)
|
279
271
|
when :mkdir
|
280
|
-
path_list =
|
281
|
-
|
282
|
-
resp = @api_node.create('files/create', { 'paths' => [{ type: :directory, path: path_list }] })
|
272
|
+
path_list = get_all_arguments_with_prefix(prefix_path, 'folder path or ext.val. list')
|
273
|
+
resp = @api_node.create('files/create', { 'paths' => path_list.map{|i|{ type: :directory, path: i }}})
|
283
274
|
return c_result_translate_rem_prefix(resp, 'folder', 'created', prefix_path)
|
284
275
|
when :mklink
|
285
|
-
target =
|
286
|
-
|
287
|
-
resp = @api_node.create('files/create', { 'paths' => [{ type: :symbolic_link, path:
|
276
|
+
target = get_one_argument_with_prefix(prefix_path, 'target')
|
277
|
+
one_path = get_one_argument_with_prefix(prefix_path, 'link path')
|
278
|
+
resp = @api_node.create('files/create', { 'paths' => [{ type: :symbolic_link, path: one_path, target: { path: target} }] })
|
288
279
|
return c_result_translate_rem_prefix(resp, 'folder', 'created', prefix_path)
|
289
280
|
when :mkfile
|
290
|
-
|
281
|
+
one_path = get_one_argument_with_prefix(prefix_path, 'file path')
|
291
282
|
contents64 = Base64.strict_encode64(options.get_next_argument('contents'))
|
292
|
-
resp = @api_node.create('files/create', { 'paths' => [{ type: :file, path:
|
283
|
+
resp = @api_node.create('files/create', { 'paths' => [{ type: :file, path: one_path, contents: contents64 }] })
|
293
284
|
return c_result_translate_rem_prefix(resp, 'folder', 'created', prefix_path)
|
294
285
|
when :rename
|
295
|
-
|
296
|
-
|
297
|
-
|
286
|
+
# TODO: multiple ?
|
287
|
+
path_base = get_one_argument_with_prefix(prefix_path, 'path_base')
|
288
|
+
path_src = get_one_argument_with_prefix(prefix_path, 'path_src')
|
289
|
+
path_dst = get_one_argument_with_prefix(prefix_path, 'path_dst')
|
298
290
|
resp = @api_node.create('files/rename', { 'paths' => [{ 'path' => path_base, 'source' => path_src, 'destination' => path_dst }] })
|
299
291
|
return c_result_translate_rem_prefix(resp, 'entry', 'moved', prefix_path)
|
300
292
|
when :browse
|
@@ -346,7 +338,7 @@ module Aspera
|
|
346
338
|
transfer_spec.delete('paths') if command.eql?(:upload)
|
347
339
|
return Main.result_transfer(transfer.start(transfer_spec))
|
348
340
|
when :http_node_download
|
349
|
-
remote_path =
|
341
|
+
remote_path = get_one_argument_with_prefix(prefix_path, 'remote path')
|
350
342
|
file_name = File.basename(remote_path)
|
351
343
|
@api_node.call(
|
352
344
|
operation: 'GET',
|
@@ -390,7 +382,7 @@ module Aspera
|
|
390
382
|
when :set_bearer_key
|
391
383
|
access_key_id = options.get_next_argument('access key id')
|
392
384
|
access_key_id = @api_node.read('access_keys/self')[:data]['id'] if access_key_id.eql?('self')
|
393
|
-
bearer_key_pem = options.get_next_argument('public or private RSA key PEM value',
|
385
|
+
bearer_key_pem = options.get_next_argument('public or private RSA key PEM value', validation: String)
|
394
386
|
key = OpenSSL::PKey.read(bearer_key_pem)
|
395
387
|
key = key.public_key if key.private?
|
396
388
|
bearer_key_pem = key.to_pem
|
@@ -581,7 +573,7 @@ module Aspera
|
|
581
573
|
return {type: :single_object, data: items}
|
582
574
|
when :modify
|
583
575
|
apifid = apifid_from_next_arg(top_file_id)
|
584
|
-
update_param = options.get_next_argument('update data',
|
576
|
+
update_param = options.get_next_argument('update data', validation: Hash)
|
585
577
|
apifid[:api].update("files/#{apifid[:file_id]}", update_param)[:data]
|
586
578
|
return Main.result_status('Done')
|
587
579
|
when :thumbnail
|
@@ -612,7 +604,7 @@ module Aspera
|
|
612
604
|
{'id' => one_id}
|
613
605
|
end
|
614
606
|
when :create
|
615
|
-
create_param = options.get_next_argument('creation data',
|
607
|
+
create_param = options.get_next_argument('creation data', validation: Hash)
|
616
608
|
raise 'no file_id' if create_param.key?('file_id')
|
617
609
|
create_param['file_id'] = apifid[:file_id]
|
618
610
|
create_param['access_levels'] = Api::Node::ACCESS_LEVELS unless create_param.key?('access_levels')
|
@@ -638,7 +630,7 @@ module Aspera
|
|
638
630
|
async_name = options.get_option(:sync_name)
|
639
631
|
if async_name.nil?
|
640
632
|
async_id = instance_identifier
|
641
|
-
if async_id.eql?(
|
633
|
+
if async_id.eql?(SpecialValues::ALL) && %i[show delete].include?(command)
|
642
634
|
async_ids = @api_node.read('async/list')[:data]['sync_ids']
|
643
635
|
else
|
644
636
|
Integer(async_id) # must be integer
|
@@ -661,7 +653,7 @@ module Aspera
|
|
661
653
|
when :show
|
662
654
|
resp = @api_node.create('async/summary', post_data)[:data]['sync_summaries']
|
663
655
|
return Main.result_empty if resp.empty?
|
664
|
-
return { type: :object_list, data: resp, fields: %w[snid name local_dir remote_dir] } if async_id.eql?(
|
656
|
+
return { type: :object_list, data: resp, fields: %w[snid name local_dir remote_dir] } if async_id.eql?(SpecialValues::ALL)
|
665
657
|
return { type: :single_object, data: resp.first }
|
666
658
|
when :delete
|
667
659
|
resp = @api_node.create('async/delete', post_data)[:data]
|
@@ -815,7 +807,7 @@ module Aspera
|
|
815
807
|
resp = @api_node.read(one_res_path)
|
816
808
|
return { type: :other_struct, data: resp[:data] }
|
817
809
|
when :modify
|
818
|
-
resp = @api_node.update(one_res_path, options.get_next_argument('update value',
|
810
|
+
resp = @api_node.update(one_res_path, options.get_next_argument('update value', validation: Hash))
|
819
811
|
return { type: :other_struct, data: resp[:data] }
|
820
812
|
when :bandwidth_average
|
821
813
|
transfers_data = @api_node.read(res_class_path, query_read_delete)[:data]
|
@@ -876,7 +868,7 @@ module Aspera
|
|
876
868
|
return { type: :object_list, data: resp[:data]['services'] }
|
877
869
|
when :create
|
878
870
|
# @json:'{"type":"WATCHFOLDERD","run_as":{"user":"user1"}}'
|
879
|
-
params = options.get_next_argument('
|
871
|
+
params = options.get_next_argument('creation data', validation: Hash)
|
880
872
|
resp = @api_node.create('rund/services', params)
|
881
873
|
return Main.result_status("#{resp[:data]['id']} created")
|
882
874
|
when :delete
|
@@ -952,13 +944,13 @@ module Aspera
|
|
952
944
|
}
|
953
945
|
# encode parameters so that it looks good in url
|
954
946
|
encoded_params = Base64.strict_encode64(Zlib::Deflate.deflate(JSON.generate(browse_params))).gsub(/=+$/, '').tr('+/', '-_').reverse
|
955
|
-
|
947
|
+
Environment.instance.open_uri("#{options.get_option(:asperabrowserurl)}?goto=#{encoded_params}")
|
956
948
|
return Main.result_status('done')
|
957
949
|
when :basic_token
|
958
950
|
return Main.result_status(Rest.basic_token(options.get_option(:username, mandatory: true), options.get_option(:password, mandatory: true)))
|
959
951
|
when :bearer_token
|
960
|
-
private_key = OpenSSL::PKey::RSA.new(options.get_next_argument('private RSA key PEM value',
|
961
|
-
token_info = options.get_next_argument('user and group identification',
|
952
|
+
private_key = OpenSSL::PKey::RSA.new(options.get_next_argument('private RSA key PEM value', validation: String))
|
953
|
+
token_info = options.get_next_argument('user and group identification', validation: Hash)
|
962
954
|
access_key = options.get_option(:username, mandatory: true)
|
963
955
|
return Main.result_status(Api::Node.bearer_token(payload: token_info, access_key: access_key, private_key: private_key))
|
964
956
|
when :simulator
|
@@ -974,6 +966,22 @@ module Aspera
|
|
974
966
|
end
|
975
967
|
raise 'ERROR: shall not reach this line'
|
976
968
|
end
|
969
|
+
|
970
|
+
private
|
971
|
+
|
972
|
+
# get remaining path arguments from command line, and add prefix
|
973
|
+
def get_all_arguments_with_prefix(path_prefix, name)
|
974
|
+
path_args = options.get_next_argument(name, multiple: true)
|
975
|
+
return path_args if path_prefix.nil?
|
976
|
+
return path_args.map {|p| File.join(path_prefix, p)}
|
977
|
+
end
|
978
|
+
|
979
|
+
# get next path argument from command line, and add prefix
|
980
|
+
def get_one_argument_with_prefix(path_prefix, name)
|
981
|
+
path_arg = options.get_next_argument(name, validation: String)
|
982
|
+
return path_arg if path_prefix.nil?
|
983
|
+
return File.join(path_prefix, path_arg)
|
984
|
+
end
|
977
985
|
end
|
978
986
|
end
|
979
987
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'aspera/cli/basic_auth_plugin'
|
4
|
+
require 'aspera/cli/special_values'
|
4
5
|
require 'aspera/nagios'
|
5
6
|
require 'aspera/log'
|
6
7
|
require 'aspera/assert'
|
@@ -150,7 +151,7 @@ module Aspera
|
|
150
151
|
end
|
151
152
|
case command
|
152
153
|
when :status
|
153
|
-
wf_id = nil if wf_id.eql?(
|
154
|
+
wf_id = nil if wf_id.eql?(SpecialValues::ALL)
|
154
155
|
result = call_ao('workflows_status', id: wf_id)[:data]
|
155
156
|
return {type: :object_list, data: result['workflows']['workflow']}
|
156
157
|
when :list
|
@@ -176,7 +177,7 @@ module Aspera
|
|
176
177
|
}
|
177
178
|
call_params = {format: :json}
|
178
179
|
# get external parameters if any
|
179
|
-
options.get_next_argument('external_parameters', mandatory: false,
|
180
|
+
options.get_next_argument('external_parameters', mandatory: false, validation: Hash, default: {}).each do |name, value|
|
180
181
|
call_params["external_parameters[#{name}]"] = value
|
181
182
|
end
|
182
183
|
# synchronous call ?
|
@@ -489,7 +489,7 @@ module Aspera
|
|
489
489
|
return Main.result_status('Tools validated')
|
490
490
|
when :test, :show
|
491
491
|
source = options.get_next_argument('source file')
|
492
|
-
format = options.get_next_argument('format',
|
492
|
+
format = options.get_next_argument('format', accept_list: Aspera::Preview::Generator::PREVIEW_FORMATS, default: :png)
|
493
493
|
generated_file_path = preview_filename(format, options.get_option(:base))
|
494
494
|
g = Aspera::Preview::Generator.new(source, generated_file_path, @gen_options, @tmp_folder, nil)
|
495
495
|
g.generate
|
@@ -232,7 +232,7 @@ module Aspera
|
|
232
232
|
when *TRANSFER_COMMANDS
|
233
233
|
return execute_transfer(command, server_transfer_spec)
|
234
234
|
when *AsCmd::OPERATIONS
|
235
|
-
command_arguments = options.get_next_argument('ascmd command arguments',
|
235
|
+
command_arguments = options.get_next_argument('ascmd command arguments', multiple: true, mandatory: false)
|
236
236
|
ascmd = AsCmd.new(ascmd_executor)
|
237
237
|
begin
|
238
238
|
result = ascmd.execute_single(command, command_arguments)
|
@@ -29,9 +29,9 @@ module Aspera
|
|
29
29
|
SIMPLE_ARGUMENTS_SYNC.each do |arg, check|
|
30
30
|
value = options.get_next_argument(
|
31
31
|
arg,
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
mandatory: false,
|
33
|
+
validation: check.is_a?(Class) ? check : nil,
|
34
|
+
accept_list: check.is_a?(Class) ? nil : check)
|
35
35
|
break if value.nil?
|
36
36
|
simple_session_args[arg] = value.to_s
|
37
37
|
end
|
@@ -57,7 +57,7 @@ module Aspera
|
|
57
57
|
command2 = options.get_next_command([:status])
|
58
58
|
case command2
|
59
59
|
when :status
|
60
|
-
sync_session_name = options.get_next_argument('name of sync session', mandatory: false,
|
60
|
+
sync_session_name = options.get_next_argument('name of sync session', mandatory: false, validation: String)
|
61
61
|
async_params = options.get_option(:sync_info, mandatory: true)
|
62
62
|
return {type: :single_object, data: Transfer::Sync.admin_status(async_params, sync_session_name)}
|
63
63
|
end
|
@@ -175,7 +175,7 @@ module Aspera
|
|
175
175
|
when nil, FILE_LIST_FROM_ARGS
|
176
176
|
Log.log.debug('getting file list as parameters')
|
177
177
|
# get remaining arguments
|
178
|
-
file_list = @opt_mgr.get_next_argument('source file list',
|
178
|
+
file_list = @opt_mgr.get_next_argument('source file list', multiple: true)
|
179
179
|
raise Cli::BadArgument, 'specify at least one file on command line or use ' \
|
180
180
|
"--sources=#{FILE_LIST_FROM_TRANSFER_SPEC} to use transfer spec" if !file_list.is_a?(Array) || file_list.empty?
|
181
181
|
when FILE_LIST_FROM_TRANSFER_SPEC
|
@@ -244,7 +244,7 @@ module Aspera
|
|
244
244
|
updated_ts(transfer_spec)
|
245
245
|
# if TS from app has content_protection (e.g. F5), that means content is protected: ask password if not provided
|
246
246
|
if transfer_spec['content_protection'].eql?('decrypt') && !transfer_spec.key?('content_protection_password')
|
247
|
-
transfer_spec['content_protection_password'] = @opt_mgr.prompt_user_input('content protection password', true)
|
247
|
+
transfer_spec['content_protection_password'] = @opt_mgr.prompt_user_input('content protection password', sensitive: true)
|
248
248
|
end
|
249
249
|
# create transfer agent
|
250
250
|
agent_instance.start_transfer(transfer_spec, token_regenerator: rest_token)
|
data/lib/aspera/cli/version.rb
CHANGED
data/lib/aspera/environment.rb
CHANGED
@@ -4,17 +4,21 @@
|
|
4
4
|
require 'aspera/log'
|
5
5
|
require 'aspera/assert'
|
6
6
|
require 'rbconfig'
|
7
|
+
require 'singleton'
|
7
8
|
|
8
9
|
# cspell:words MEBI mswin bccwin
|
9
10
|
|
10
11
|
module Aspera
|
11
12
|
# detect OS, architecture, and specific stuff
|
12
13
|
class Environment
|
14
|
+
include Singleton
|
15
|
+
USER_INTERFACES = %i[text graphical].freeze
|
16
|
+
|
13
17
|
OS_WINDOWS = :windows
|
14
|
-
|
18
|
+
OS_MACOS = :osx
|
15
19
|
OS_LINUX = :linux
|
16
20
|
OS_AIX = :aix
|
17
|
-
OS_LIST = [OS_WINDOWS,
|
21
|
+
OS_LIST = [OS_WINDOWS, OS_MACOS, OS_LINUX, OS_AIX].freeze
|
18
22
|
CPU_X86_64 = :x86_64
|
19
23
|
CPU_ARM64 = :arm64
|
20
24
|
CPU_PPC64 = :ppc64
|
@@ -37,7 +41,7 @@ module Aspera
|
|
37
41
|
when /mswin/, /msys/, /mingw/, /cygwin/, /bccwin/, /wince/, /emc/
|
38
42
|
return OS_WINDOWS
|
39
43
|
when /darwin/, /mac os/
|
40
|
-
return
|
44
|
+
return OS_MACOS
|
41
45
|
when /linux/
|
42
46
|
return OS_LINUX
|
43
47
|
when /aix/
|
@@ -122,10 +126,66 @@ module Aspera
|
|
122
126
|
end
|
123
127
|
|
124
128
|
# @return true if we can display Unicode characters
|
129
|
+
# https://www.gnu.org/software/libc/manual/html_node/Locale-Categories.html
|
130
|
+
# https://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html
|
125
131
|
def terminal_supports_unicode?
|
126
|
-
@terminal_supports_unicode = terminal? &&
|
132
|
+
@terminal_supports_unicode = terminal? && %w(LC_ALL LC_CTYPE LANG).any?{|var|ENV[var]&.include?('UTF-8')} if @terminal_supports_unicode.nil?
|
127
133
|
return @terminal_supports_unicode
|
128
134
|
end
|
135
|
+
|
136
|
+
def default_gui_mode
|
137
|
+
# assume not remotely connected on macos and windows
|
138
|
+
return :graphical if [Environment::OS_WINDOWS, Environment::OS_MACOS].include?(Environment.os)
|
139
|
+
# unix family
|
140
|
+
return :graphical if ENV.key?('DISPLAY') && !ENV['DISPLAY'].empty?
|
141
|
+
return :text
|
142
|
+
end
|
143
|
+
|
144
|
+
# command must be non blocking
|
145
|
+
def open_uri_graphical(uri)
|
146
|
+
case Environment.os
|
147
|
+
when Environment::OS_MACOS then return system('open', uri.to_s)
|
148
|
+
when Environment::OS_WINDOWS then return system('start', 'explorer', %Q{"#{uri}"})
|
149
|
+
when Environment::OS_LINUX then return system('xdg-open', uri.to_s)
|
150
|
+
else
|
151
|
+
raise "no graphical open method for #{Environment.os}"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def open_editor(file_path)
|
156
|
+
if ENV.key?('EDITOR')
|
157
|
+
system(ENV['EDITOR'], file_path.to_s)
|
158
|
+
elsif Environment.os.eql?(Environment::OS_WINDOWS)
|
159
|
+
system('notepad.exe', %Q{"#{file_path}"})
|
160
|
+
else
|
161
|
+
open_uri_graphical(file_path.to_s)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
attr_accessor :url_method
|
166
|
+
|
167
|
+
def initialize
|
168
|
+
@url_method = self.class.default_gui_mode
|
169
|
+
end
|
170
|
+
|
171
|
+
# Allows a user to open a Url
|
172
|
+
# if method is "text", then URL is displayed on terminal
|
173
|
+
# if method is "graphical", then the URL will be opened with the default browser.
|
174
|
+
# this is non blocking
|
175
|
+
def open_uri(the_url)
|
176
|
+
case @url_method
|
177
|
+
when :graphical
|
178
|
+
self.class.open_uri_graphical(the_url)
|
179
|
+
when :text
|
180
|
+
case the_url.to_s
|
181
|
+
when /^http/
|
182
|
+
puts "USER ACTION: please enter this url in a browser:\n#{the_url.to_s.red}\n"
|
183
|
+
else
|
184
|
+
puts "USER ACTION: open this:\n#{the_url.to_s.red}\n"
|
185
|
+
end
|
186
|
+
else
|
187
|
+
raise StandardError, "unsupported url open method: #{@url_method}"
|
188
|
+
end
|
129
189
|
end
|
130
190
|
end
|
131
191
|
end
|
data/lib/aspera/oauth/web.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'aspera/oauth/base'
|
4
|
-
require 'aspera/
|
4
|
+
require 'aspera/environment'
|
5
5
|
require 'aspera/web_auth'
|
6
6
|
require 'aspera/assert'
|
7
7
|
module Aspera
|
@@ -34,7 +34,7 @@ module Aspera
|
|
34
34
|
# start a web server to receive request code
|
35
35
|
web_server = WebAuth.new(@redirect_uri)
|
36
36
|
# start browser on login page
|
37
|
-
|
37
|
+
Environment.instance.open_uri(login_page_url)
|
38
38
|
# wait for code in request
|
39
39
|
received_params = web_server.received_request
|
40
40
|
Aspera.assert(random_state.eql?(received_params['state'])){'wrong received state'}
|