aspera-cli 4.0.0 → 4.1.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
- data/README.md +518 -137
- data/bin/dascli +13 -0
- data/docs/README.erb.md +473 -105
- data/docs/test_env.conf +4 -1
- data/docs/transfer_spec.html +1 -1
- data/lib/aspera/aoc.rb +68 -86
- data/lib/aspera/cli/formater.rb +2 -0
- data/lib/aspera/cli/main.rb +27 -19
- data/lib/aspera/cli/plugin.rb +9 -4
- data/lib/aspera/cli/plugins/alee.rb +1 -1
- data/lib/aspera/cli/plugins/aoc.rb +173 -136
- data/lib/aspera/cli/plugins/config.rb +80 -27
- data/lib/aspera/cli/plugins/console.rb +2 -2
- data/lib/aspera/cli/plugins/faspex.rb +13 -6
- data/lib/aspera/cli/plugins/faspex5.rb +93 -37
- data/lib/aspera/cli/plugins/node.rb +3 -3
- data/lib/aspera/cli/plugins/preview.rb +25 -24
- data/lib/aspera/cli/plugins/server.rb +23 -8
- data/lib/aspera/cli/transfer_agent.rb +1 -1
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/fasp/connect.rb +28 -21
- data/lib/aspera/fasp/http_gw.rb +140 -28
- data/lib/aspera/fasp/installation.rb +28 -4
- data/lib/aspera/fasp/local.rb +24 -16
- data/lib/aspera/fasp/manager.rb +12 -0
- data/lib/aspera/fasp/node.rb +4 -4
- data/lib/aspera/fasp/parameters.rb +3 -16
- data/lib/aspera/log.rb +1 -1
- data/lib/aspera/node.rb +48 -1
- data/lib/aspera/oauth.rb +24 -11
- data/lib/aspera/persistency_folder.rb +9 -4
- data/lib/aspera/preview/file_types.rb +53 -21
- data/lib/aspera/preview/generator.rb +3 -3
- data/lib/aspera/rest.rb +38 -18
- data/lib/aspera/temp_file_manager.rb +19 -0
- metadata +37 -20
data/docs/test_env.conf
CHANGED
@@ -19,7 +19,6 @@ default:
|
|
19
19
|
cli_default:
|
20
20
|
interactive: your value here
|
21
21
|
smtp: your value here
|
22
|
-
ascp_path: your value here
|
23
22
|
local_user:
|
24
23
|
ssh_keys: your value here
|
25
24
|
smtp_config:
|
@@ -50,6 +49,7 @@ tst_node_faspex:
|
|
50
49
|
password: your value here
|
51
50
|
tst_faspex5:
|
52
51
|
url: your value here
|
52
|
+
auth: your value here
|
53
53
|
username: your value here
|
54
54
|
password: your value here
|
55
55
|
tst_shares:
|
@@ -94,6 +94,7 @@ tst_ak_preview:
|
|
94
94
|
url: your value here
|
95
95
|
username: your value here
|
96
96
|
password: your value here
|
97
|
+
mimemagic: your value here
|
97
98
|
tst_node_preview:
|
98
99
|
url: your value here
|
99
100
|
username: your value here
|
@@ -122,6 +123,7 @@ misc:
|
|
122
123
|
aoc_publink_recv_from_aocuser: your value here
|
123
124
|
aoc_publink_send_shd_inbox: your value here
|
124
125
|
aoc_publink_send_aoc_user: your value here
|
126
|
+
aoc_publink_send_use_pass: your value here
|
125
127
|
aoc_publink_folder: your value here
|
126
128
|
aoc_shbx_ws: your value here
|
127
129
|
aoc_shbx_name: your value here
|
@@ -138,3 +140,4 @@ misc:
|
|
138
140
|
email_external: your value here
|
139
141
|
aoc_org: your value here
|
140
142
|
aoc_user: your value here
|
143
|
+
http_gw_fqdn_port: your value here
|
data/docs/transfer_spec.html
CHANGED
@@ -28,7 +28,7 @@ arg: related ascp argument or env var suffix (PASS for ASPERA_SCP_PASS)
|
|
28
28
|
</p>
|
29
29
|
<p>
|
30
30
|
UNDER CONSTRUCTION<br/>
|
31
|
-
<a href="https://developer.ibm.com/
|
31
|
+
<a href="https://developer.ibm.com/apis/catalog/?search=aspera">Aspera API Documentation</a>→Node API→/opt/transfers<br/>
|
32
32
|
</p>
|
33
33
|
|
34
34
|
<table>
|
data/lib/aspera/aoc.rb
CHANGED
@@ -121,7 +121,7 @@ module Aspera
|
|
121
121
|
raise RuntimeError,'too many redirections'
|
122
122
|
end
|
123
123
|
|
124
|
-
# @param :link,:url,:auth,:client_id,:client_secret,:scope,:redirect_uri,:private_key,:username,:subpath
|
124
|
+
# @param :link,:url,:auth,:client_id,:client_secret,:scope,:redirect_uri,:private_key,:username,:subpath,:password (for pub link)
|
125
125
|
def initialize(opt)
|
126
126
|
# access key secrets are provided out of band to get node api access
|
127
127
|
# key: access key
|
@@ -185,6 +185,7 @@ module Aspera
|
|
185
185
|
aoc_auth_p[:jwt_subject] = opt[:username]
|
186
186
|
aoc_auth_p[:jwt_private_key_obj] = OpenSSL::PKey::RSA.new(private_key_PEM_string)
|
187
187
|
when :url_token
|
188
|
+
aoc_auth_p[:password]=opt[:password] unless opt[:password].nil?
|
188
189
|
# nothing more
|
189
190
|
else raise "ERROR: unsupported auth method: #{aoc_auth_p[:grant]}"
|
190
191
|
end
|
@@ -293,6 +294,7 @@ module Aspera
|
|
293
294
|
# no scope: requires secret
|
294
295
|
# if secret provided beforehand: use it
|
295
296
|
def get_node_api(node_info,node_scope=nil)
|
297
|
+
# X-Aspera-AccessKey required for bearer token only
|
296
298
|
node_rest_params={
|
297
299
|
:base_url => node_info['url'],
|
298
300
|
:headers => {'X-Aspera-AccessKey'=>node_info['access_key']},
|
@@ -312,7 +314,7 @@ module Aspera
|
|
312
314
|
node_rest_params[:auth]=self.params[:auth].clone
|
313
315
|
node_rest_params[:auth][:scope]=self.class.node_scope(node_info['access_key'],node_scope)
|
314
316
|
end
|
315
|
-
return
|
317
|
+
return Node.new(node_rest_params)
|
316
318
|
end
|
317
319
|
|
318
320
|
# check that parameter has necessary types
|
@@ -328,102 +330,82 @@ module Aspera
|
|
328
330
|
return node_info,file_id
|
329
331
|
end
|
330
332
|
|
331
|
-
#
|
332
|
-
def
|
333
|
-
|
334
|
-
|
333
|
+
# add entry to list if test block is success
|
334
|
+
def process_find_files(entry,path)
|
335
|
+
begin
|
336
|
+
# add to result if match filter
|
337
|
+
@find_state[:found].push(entry.merge({'path'=>path})) if @find_state[:test_block].call(entry)
|
338
|
+
# process link
|
339
|
+
if entry[:type].eql?('link')
|
340
|
+
sub_node_info=self.read("nodes/#{entry['target_node_id']}")[:data]
|
341
|
+
sub_opt={method: process_find_files, top_file_id: entry['target_id'], top_file_path: path}
|
342
|
+
get_node_api(sub_node_info,SCOPE_NODE_USER).crawl(self,sub_opt)
|
343
|
+
end
|
344
|
+
rescue => e
|
345
|
+
Log.log.error("#{path}: #{e.message}")
|
346
|
+
end
|
347
|
+
# process all folders
|
348
|
+
return true
|
335
349
|
end
|
336
350
|
|
337
|
-
# @returns list of file paths that match given regex
|
338
351
|
def find_files( top_node_file, test_block )
|
339
352
|
top_node_info,top_file_id=check_get_node_file(top_node_file)
|
340
353
|
Log.log.debug("find_files: node_info=#{top_node_info}, fileid=#{top_file_id}")
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
354
|
+
@find_state={found: [], test_block: test_block}
|
355
|
+
get_node_api(top_node_info,SCOPE_NODE_USER).crawl(self,{method: :process_find_files, top_file_id: top_file_id})
|
356
|
+
result=@find_state[:found]
|
357
|
+
@find_state=nil
|
358
|
+
return result
|
359
|
+
end
|
360
|
+
|
361
|
+
def process_resolve_node_file(entry,path)
|
362
|
+
# stop digging here if not in right path
|
363
|
+
return false unless entry['name'].eql?(@resolve_state[:path].first)
|
364
|
+
# ok it matches, so we remove the match
|
365
|
+
@resolve_state[:path].shift
|
366
|
+
case entry['type']
|
367
|
+
when 'file'
|
368
|
+
# file must be terminal
|
369
|
+
raise "#{entry['name']} is a file, expecting folder to find: #{@resolve_state[:path]}" unless @resolve_state[:path].empty?
|
370
|
+
@resolve_state[:result][:file_id]=entry['id']
|
371
|
+
when 'link'
|
372
|
+
@resolve_state[:result][:node_info]=self.read("nodes/#{entry['target_node_id']}")[:data]
|
373
|
+
if @resolve_state[:path].empty?
|
374
|
+
@resolve_state[:result][:file_id]=entry['target_id']
|
375
|
+
else
|
376
|
+
get_node_api(@resolve_state[:result][:node_info],SCOPE_NODE_USER).crawl(self,{method: :process_resolve_node_file, top_file_id: entry['target_id']})
|
356
377
|
end
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
begin
|
363
|
-
# does item match ?
|
364
|
-
result.push(current_file_info.merge({'path'=>item_path})) if test_block.call(current_file_info)
|
365
|
-
# does it need further processing ?
|
366
|
-
case current_file_info['type']
|
367
|
-
when 'file'
|
368
|
-
Log.log.debug("testing : #{current_file_info['name']}")
|
369
|
-
when 'folder'
|
370
|
-
items_to_explore.push({:node_api=>current_item[:node_api],:folder_id=>current_file_info['id'],:path=>item_path})
|
371
|
-
when 'link' # .*.asp-lnk
|
372
|
-
items_to_explore.push(read_asplnk(current_file_info).merge({:path=>item_path}))
|
373
|
-
else
|
374
|
-
Log.log.error("unknown folder item type: #{current_file_info['type']}")
|
375
|
-
end
|
376
|
-
rescue => e
|
377
|
-
Log.log.error("#{item_path}: #{e.message}")
|
378
|
-
end
|
378
|
+
when 'folder'
|
379
|
+
if @resolve_state[:path].empty?
|
380
|
+
# found: store
|
381
|
+
@resolve_state[:result][:file_id]=entry['id']
|
382
|
+
return false
|
379
383
|
end
|
384
|
+
else
|
385
|
+
Log.log.warn("unknown element type: #{entry['type']}")
|
380
386
|
end
|
381
|
-
|
387
|
+
# continue to dig folder
|
388
|
+
return true
|
382
389
|
end
|
383
390
|
|
384
|
-
# @return
|
391
|
+
# @return Array(node_info,file_id) for the given path
|
392
|
+
# @param top_node_file Array [root node,file id]
|
393
|
+
# @param element_path_string String path of element
|
385
394
|
# supports links to secondary nodes
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
current_node_api=get_node_api(current_node_info,SCOPE_NODE_USER) if current_node_api.nil?
|
399
|
-
# get folder content
|
400
|
-
folder_contents = current_node_api.read("files/#{current_file_id}/files")
|
401
|
-
Log.dump(:folder_contents,folder_contents)
|
402
|
-
matching_folders = folder_contents[:data].select { |i| i['name'].eql?(current_item)}
|
403
|
-
#Log.log.debug "matching_folders: #{matching_folders}"
|
404
|
-
raise "no such folder: #{current_item} in #{folder_contents[:data].map { |i| i['name']}}" if matching_folders.empty?
|
405
|
-
current_file_info = matching_folders.first
|
406
|
-
# process type of file
|
407
|
-
case current_file_info['type']
|
408
|
-
when 'file'
|
409
|
-
current_file_id=current_file_info['id']
|
410
|
-
# a file shall be terminal
|
411
|
-
if !items_to_explore.empty? then
|
412
|
-
raise "#{current_item} is a file, expecting folder to find: #{items_to_explore}"
|
413
|
-
end
|
414
|
-
when 'link'
|
415
|
-
current_node_info=self.read("nodes/#{current_file_info['target_node_id']}")[:data]
|
416
|
-
current_file_id=current_file_info['target_id']
|
417
|
-
# need to switch node
|
418
|
-
current_node_api=nil
|
419
|
-
when 'folder'
|
420
|
-
current_file_id=current_file_info['id']
|
421
|
-
else
|
422
|
-
Log.log.warn("unknown element type: #{current_file_info['type']}")
|
423
|
-
end
|
395
|
+
def resolve_node_file( top_node_file, element_path_string )
|
396
|
+
top_node_info,top_file_id=check_get_node_file(top_node_file)
|
397
|
+
path_elements=element_path_string.split(PATH_SEPARATOR).select{|i| !i.empty?}
|
398
|
+
result={node_info: top_node_info, file_id: nil}
|
399
|
+
if path_elements.empty?
|
400
|
+
result[:file_id]=top_file_id
|
401
|
+
else
|
402
|
+
@resolve_state={path: path_elements, result: result}
|
403
|
+
get_node_api(top_node_info,SCOPE_NODE_USER).crawl(self,{method: :process_resolve_node_file, top_file_id: top_file_id})
|
404
|
+
not_found=@resolve_state[:path]
|
405
|
+
@resolve_state=nil
|
406
|
+
raise "entry not found: #{not_found}" if result[:file_id].nil?
|
424
407
|
end
|
425
|
-
|
426
|
-
return {node_info: current_node_info, file_id: current_file_id}
|
408
|
+
return result
|
427
409
|
end
|
428
410
|
|
429
411
|
end # AoC
|
data/lib/aspera/cli/formater.rb
CHANGED
@@ -151,6 +151,8 @@ module Aspera
|
|
151
151
|
else
|
152
152
|
if user_asked_fields_list_str.start_with?('+')
|
153
153
|
result_default_fields(results,table_rows_hash_val).push(*user_asked_fields_list_str.gsub(/^\+/,'').split(','))
|
154
|
+
elsif user_asked_fields_list_str.start_with?('-')
|
155
|
+
result_default_fields(results,table_rows_hash_val).select{|i| ! user_asked_fields_list_str.gsub(/^\-/,'').split(',').include?(i)}
|
154
156
|
else
|
155
157
|
user_asked_fields_list_str.split(',')
|
156
158
|
end
|
data/lib/aspera/cli/main.rb
CHANGED
@@ -53,13 +53,20 @@ module Aspera
|
|
53
53
|
@help_url='http://www.rubydoc.info/gems/'+GEM_NAME
|
54
54
|
@gem_url='https://rubygems.org/gems/'+GEM_NAME
|
55
55
|
# give command line arguments to option manager (no parsing)
|
56
|
-
|
56
|
+
app_main_folder=ENV[conf_dir_env_var]
|
57
|
+
# if env var undefined or empty
|
58
|
+
if app_main_folder.nil? or app_main_folder.empty?
|
59
|
+
user_home_folder=Dir.home
|
60
|
+
raise CliError,"Home folder does not exist: #{user_home_folder}. Check your user environment or use #{conf_dir_env_var}." unless Dir.exist?(user_home_folder)
|
61
|
+
app_main_folder=File.join(user_home_folder,Plugins::Config::ASPERA_HOME_FOLDER_NAME,PROGRAM_NAME)
|
62
|
+
end
|
63
|
+
@plugin_env[:options]=@opt_mgr=Manager.new(PROGRAM_NAME,argv,app_banner())
|
57
64
|
@plugin_env[:formater]=Formater.new(@plugin_env[:options])
|
58
|
-
Rest.user_agent=
|
65
|
+
Rest.user_agent=PROGRAM_NAME
|
59
66
|
# must override help methods before parser called (in other constructors)
|
60
67
|
init_global_options()
|
61
68
|
# the Config plugin adds the @preset parser
|
62
|
-
@plugin_env[:config]=Plugins::Config.new(@plugin_env,
|
69
|
+
@plugin_env[:config]=Plugins::Config.new(@plugin_env,PROGRAM_NAME,@help_url,Aspera::Cli::VERSION,app_main_folder)
|
63
70
|
# the TransferAgent plugin may use the @preset parser
|
64
71
|
@plugin_env[:transfer]=TransferAgent.new(@plugin_env)
|
65
72
|
Log.log.debug('created plugin env'.red)
|
@@ -73,21 +80,21 @@ module Aspera
|
|
73
80
|
end
|
74
81
|
|
75
82
|
def app_banner
|
76
|
-
banner = "NAME\n\t#{
|
83
|
+
banner = "NAME\n\t#{PROGRAM_NAME} -- a command line tool for Aspera Applications (v#{Aspera::Cli::VERSION})\n\n"
|
77
84
|
banner << "SYNOPSIS\n"
|
78
|
-
banner << "\t#{
|
79
|
-
banner << "\n"
|
80
|
-
banner << "DESCRIPTION\n"
|
85
|
+
banner << "\t#{PROGRAM_NAME} COMMANDS [OPTIONS] [ARGS]\n"
|
86
|
+
banner << "\nDESCRIPTION\n"
|
81
87
|
banner << "\tUse Aspera application to perform operations on command line.\n"
|
82
88
|
banner << "\tDocumentation and examples: #{@gem_url}\n"
|
83
|
-
banner << "\texecute: #{
|
89
|
+
banner << "\texecute: #{PROGRAM_NAME} conf doc\n"
|
84
90
|
banner << "\tor visit: #{@help_url}\n"
|
85
|
-
banner << "\n"
|
86
|
-
banner << "
|
87
|
-
banner << "\
|
91
|
+
banner << "\nENVIRONMENT VARIABLES\n"
|
92
|
+
banner << "\t#{conf_dir_env_var} config folder, default: $HOME/#{Plugins::Config::ASPERA_HOME_FOLDER_NAME}/#{PROGRAM_NAME}\n"
|
93
|
+
banner << "\t#any option can be set as an environment variable, refer to the manual\n"
|
94
|
+
banner << "\nCOMMANDS\n"
|
95
|
+
banner << "\tTo list first level commands, execute: #{PROGRAM_NAME}\n"
|
88
96
|
banner << "\tNote that commands can be written shortened (provided it is unique).\n"
|
89
|
-
banner << "\n"
|
90
|
-
banner << "OPTIONS\n"
|
97
|
+
banner << "\nOPTIONS\n"
|
91
98
|
banner << "\tOptions begin with a '-' (minus), and value is provided on command line.\n"
|
92
99
|
banner << "\tSpecial values are supported beginning with special prefix, like: #{ExtendedValue.instance.modifiers.map{|m|"@#{m}:"}.join(' ')}.\n"
|
93
100
|
banner << "\tDates format is 'DD-MM-YY HH:MM:SS', or 'now' or '-<num>h'\n\n"
|
@@ -167,7 +174,7 @@ module Aspera
|
|
167
174
|
# override main option parser with a brand new, to avoid having global options
|
168
175
|
plugin_env=@plugin_env.clone
|
169
176
|
plugin_env[:man_only]=true
|
170
|
-
plugin_env[:options]=Manager.new(
|
177
|
+
plugin_env[:options]=Manager.new(PROGRAM_NAME,[],'')
|
171
178
|
get_plugin_instance_with_options(plugin_name_sym,plugin_env)
|
172
179
|
# display generated help for plugin options
|
173
180
|
@plugin_env[:formater].display_message(:error,plugin_env[:options].parser.to_s)
|
@@ -178,10 +185,14 @@ module Aspera
|
|
178
185
|
|
179
186
|
protected
|
180
187
|
|
188
|
+
def conf_dir_env_var
|
189
|
+
return "#{PROGRAM_NAME}_home".upcase
|
190
|
+
end
|
191
|
+
|
181
192
|
# early debug for parser
|
182
193
|
# Note: does not accept shortcuts
|
183
194
|
def early_debug_setup(argv)
|
184
|
-
Log.instance.program_name=
|
195
|
+
Log.instance.program_name=PROGRAM_NAME
|
185
196
|
argv.each do |arg|
|
186
197
|
case arg
|
187
198
|
when '--'
|
@@ -205,10 +216,6 @@ module Aspera
|
|
205
216
|
return Main.result_nothing
|
206
217
|
end
|
207
218
|
|
208
|
-
def options;@opt_mgr;end
|
209
|
-
|
210
|
-
def program_name;PROGRAM_NAME;end
|
211
|
-
|
212
219
|
# this is the main function called by initial script just after constructor
|
213
220
|
def process_command_line
|
214
221
|
Log.log.debug('process_command_line')
|
@@ -232,6 +239,7 @@ module Aspera
|
|
232
239
|
raise CliError,"Another instance is already running (lock port=#{lock_port})."
|
233
240
|
end
|
234
241
|
end
|
242
|
+
@plugin_env[:config].periodic_check_newer_gem_version
|
235
243
|
if @option_show_config and @opt_mgr.command_or_arg_empty?
|
236
244
|
command_sym=Plugins::Config::CONF_PLUGIN_SYM
|
237
245
|
else
|
data/lib/aspera/cli/plugin.rb
CHANGED
@@ -67,7 +67,10 @@ module Aspera
|
|
67
67
|
when :delete
|
68
68
|
rest_api.delete(one_res_path)
|
69
69
|
return Main.result_status("deleted")
|
70
|
+
else
|
71
|
+
raise "unknown action: #{command}"
|
70
72
|
end
|
73
|
+
raise "internal error should not reach here"
|
71
74
|
end
|
72
75
|
|
73
76
|
# implement generic rest operations on given resource path
|
@@ -77,13 +80,15 @@ module Aspera
|
|
77
80
|
return entity_command(command,rest_api,res_class_path,display_fields,id_symb,id_default,subkey)
|
78
81
|
end
|
79
82
|
|
80
|
-
def options
|
83
|
+
def options; return @agents[:options];end
|
81
84
|
|
82
|
-
def transfer
|
85
|
+
def transfer; return @agents[:transfer];end
|
83
86
|
|
84
|
-
def config;return @agents[:config];end
|
87
|
+
def config; return @agents[:config];end
|
85
88
|
|
86
|
-
def format;return @agents[:formater];end
|
89
|
+
def format; return @agents[:formater];end
|
90
|
+
|
91
|
+
def persistency; return @agents[:persistency];end
|
87
92
|
|
88
93
|
end # Plugin
|
89
94
|
end # Cli
|
@@ -12,7 +12,7 @@ module Aspera
|
|
12
12
|
command=self.options.get_next_command(ACTIONS)
|
13
13
|
case command
|
14
14
|
when :entitlement
|
15
|
-
entitlement_id = self.options.get_option(:username,:mandatory)
|
15
|
+
entitlement_id = self.options.get_option(:username,:mandatory)
|
16
16
|
customer_id = self.options.get_option(:password,:mandatory)
|
17
17
|
api_metering=AoC.metering_api(entitlement_id,customer_id)
|
18
18
|
return {:type=>:single_object, :data=>api_metering.read('entitlement')[:data]}
|
@@ -3,6 +3,7 @@ require 'aspera/cli/plugins/ats'
|
|
3
3
|
require 'aspera/cli/basic_auth_plugin'
|
4
4
|
require 'aspera/cli/transfer_agent'
|
5
5
|
require 'aspera/aoc'
|
6
|
+
require 'aspera/node'
|
6
7
|
require 'aspera/persistency_action_once'
|
7
8
|
require 'securerandom'
|
8
9
|
require 'resolv'
|
@@ -12,8 +13,8 @@ module Aspera
|
|
12
13
|
module Cli
|
13
14
|
module Plugins
|
14
15
|
class Aoc < BasicAuthPlugin
|
16
|
+
# special value for package id
|
15
17
|
VAL_ALL='ALL'
|
16
|
-
private_constant :VAL_ALL
|
17
18
|
attr_reader :api_aoc
|
18
19
|
def initialize(env)
|
19
20
|
super(env)
|
@@ -25,23 +26,22 @@ module Aspera
|
|
25
26
|
@api_aoc=nil
|
26
27
|
@url_token_data=nil
|
27
28
|
@user_info=nil
|
28
|
-
|
29
|
-
self.options.add_opt_list(:
|
30
|
-
self.options.
|
31
|
-
self.options.add_opt_simple(:
|
32
|
-
self.options.add_opt_simple(:
|
33
|
-
self.options.add_opt_simple(:
|
34
|
-
self.options.add_opt_simple(:
|
35
|
-
self.options.add_opt_simple(:
|
36
|
-
self.options.add_opt_simple(:
|
37
|
-
self.options.add_opt_simple(:
|
38
|
-
self.options.add_opt_simple(:
|
39
|
-
self.options.add_opt_simple(:
|
40
|
-
self.options.add_opt_simple(:
|
41
|
-
self.options.add_opt_simple(:
|
42
|
-
self.options.
|
43
|
-
self.options.add_opt_boolean(:
|
44
|
-
self.options.add_opt_boolean(:default_ports,"use standard FASP ports or get from node api")
|
29
|
+
self.options.add_opt_list(:auth,Oauth.auth_types,'type of Oauth authentication')
|
30
|
+
self.options.add_opt_list(:operation,[:push,:pull],'client operation for transfers')
|
31
|
+
self.options.add_opt_simple(:client_id,'API client identifier in application')
|
32
|
+
self.options.add_opt_simple(:client_secret,'API client passcode')
|
33
|
+
self.options.add_opt_simple(:redirect_uri,'API client redirect URI')
|
34
|
+
self.options.add_opt_simple(:private_key,'RSA private key PEM value for JWT (prefix file path with @val:@file:)')
|
35
|
+
self.options.add_opt_simple(:workspace,'name of workspace')
|
36
|
+
self.options.add_opt_simple(:name,'resource name')
|
37
|
+
self.options.add_opt_simple(:path,'file or folder path')
|
38
|
+
self.options.add_opt_simple(:link,'public link to shared resource')
|
39
|
+
self.options.add_opt_simple(:new_user_option,'new user creation option')
|
40
|
+
self.options.add_opt_simple(:from_folder,'share to share source folder')
|
41
|
+
self.options.add_opt_simple(:scope,'scope for AoC API calls')
|
42
|
+
self.options.add_opt_simple(:notify,'notify users that file was received')
|
43
|
+
self.options.add_opt_boolean(:bulk,'bulk operation')
|
44
|
+
self.options.add_opt_boolean(:default_ports,'use standard FASP ports or get from node api')
|
45
45
|
self.options.set_option(:bulk,:no)
|
46
46
|
self.options.set_option(:default_ports,:yes)
|
47
47
|
self.options.set_option(:new_user_option,{'package_contact'=>true})
|
@@ -52,7 +52,9 @@ module Aspera
|
|
52
52
|
self.options.parse_options!
|
53
53
|
AoC.set_use_default_ports(self.options.get_option(:default_ports))
|
54
54
|
return if env[:man_only]
|
55
|
-
|
55
|
+
@api_aoc=AoC.new(aoc_params('api/v1'))
|
56
|
+
# add access key secrets
|
57
|
+
@api_aoc.add_secrets(self.config.get_secrets)
|
56
58
|
end
|
57
59
|
|
58
60
|
# call this to populate single AK secret in AoC API object, from options
|
@@ -65,7 +67,8 @@ module Aspera
|
|
65
67
|
raise CliBadArgument,"Please provide option secret or entry in option secrets for: #{ak}" unless @api_aoc.has_secret(ak) or !mandatory
|
66
68
|
end
|
67
69
|
|
68
|
-
|
70
|
+
# cached user information
|
71
|
+
def c_user_info
|
69
72
|
if @user_info.nil?
|
70
73
|
# get our user's default information
|
71
74
|
# self?embed[]=default_workspace&embed[]=organization
|
@@ -80,16 +83,11 @@ module Aspera
|
|
80
83
|
# starts transfer using transfer agent
|
81
84
|
def transfer_start(app,direction,node_file,ts_add)
|
82
85
|
ts_add.deep_merge!(AoC.analytics_ts(app,direction,@workspace_id,@workspace_name))
|
83
|
-
ts_add.deep_merge!(AoC.console_ts(app,
|
86
|
+
ts_add.deep_merge!(AoC.console_ts(app,c_user_info['name'],c_user_info['email']))
|
84
87
|
return self.transfer.start(*@api_aoc.tr_spec(app,direction,node_file,ts_add))
|
85
88
|
end
|
86
89
|
|
87
|
-
NODE4_COMMANDS=[ :browse, :find, :mkdir, :rename, :delete, :upload, :download, :transfer, :http_node_download, :v3, :file, :bearer_token_node
|
88
|
-
|
89
|
-
def node_gen4_execute_action(top_node_file)
|
90
|
-
command_repo=self.options.get_next_command(NODE4_COMMANDS)
|
91
|
-
return execute_node_gen4_command(command_repo,top_node_file)
|
92
|
-
end
|
90
|
+
NODE4_COMMANDS=[ :browse, :find, :mkdir, :rename, :delete, :upload, :download, :transfer, :http_node_download, :v3, :file, :bearer_token_node ]
|
93
91
|
|
94
92
|
def execute_node_gen4_command(command_repo,top_node_file)
|
95
93
|
case command_repo
|
@@ -213,69 +211,79 @@ module Aspera
|
|
213
211
|
node_api=@api_aoc.get_node_api(top_node_file[:node_info],AoC::SCOPE_NODE_USER)
|
214
212
|
return Node.new(@agents.merge(skip_basic_auth_options: true, node_api: node_api)).execute_action(command_legacy)
|
215
213
|
when :file
|
216
|
-
|
217
|
-
node_file =
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
fileid=self.options.get_next_argument('file id')
|
223
|
-
node_file = @api_aoc.resolve_node_file(top_node_file)
|
214
|
+
file_path=self.options.get_option(:path,:optional)
|
215
|
+
node_file = if !file_path.nil?
|
216
|
+
@api_aoc.resolve_node_file(top_node_file,file_path) # TODO: allow follow link ?
|
217
|
+
else
|
218
|
+
{node_info: top_node_file[:node_info],file_id: self.options.get_option(:id,:mandatory)}
|
219
|
+
end
|
224
220
|
node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
225
|
-
|
226
|
-
case
|
221
|
+
command_node_file=self.options.get_next_command([:show,:permission,:modify])
|
222
|
+
case command_node_file
|
227
223
|
when :show
|
228
|
-
items=node_api.read(
|
229
|
-
return {:type=>:
|
230
|
-
when :
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
"
|
251
|
-
|
252
|
-
"
|
253
|
-
|
254
|
-
|
255
|
-
|
224
|
+
items=node_api.read("files/#{node_file[:file_id]}")[:data]
|
225
|
+
return {:type=>:single_object,:data=>items}
|
226
|
+
when :modify
|
227
|
+
update_param=self.options.get_next_argument("update data (Hash)")
|
228
|
+
res=node_api.update("files/#{node_file[:file_id]}",update_param)[:data]
|
229
|
+
return {:type=>:single_object,:data=>res}
|
230
|
+
when :permission
|
231
|
+
command_perm=self.options.get_next_command([:list,:create])
|
232
|
+
case command_perm
|
233
|
+
when :list
|
234
|
+
# generic options : TODO: as arg ?
|
235
|
+
list_options||={'include'=>['[]','access_level','permission_count']}
|
236
|
+
# special value: ALL will show all permissions
|
237
|
+
if !VAL_ALL.eql?(node_file[:file_id])
|
238
|
+
# add which one to get
|
239
|
+
list_options['file_id']=node_file[:file_id]
|
240
|
+
list_options['inherited']||=false
|
241
|
+
end
|
242
|
+
#option_url_query
|
243
|
+
items=node_api.read('permissions',list_options)[:data]
|
244
|
+
return {:type=>:object_list,:data=>items}
|
245
|
+
when :create
|
246
|
+
#create_param=self.options.get_next_argument("creation data (Hash)")
|
247
|
+
set_workspace_info
|
248
|
+
access_id="ASPERA_ACCESS_KEY_ADMIN_WS_#{@workspace_id}"
|
249
|
+
node_file[:node_info]
|
250
|
+
params={
|
251
|
+
'file_id' =>node_file[:file_id], # mandatory
|
252
|
+
'access_type' =>'user', # mandatory: user or group
|
253
|
+
'access_id' =>access_id, # id of user or group
|
254
|
+
'access_levels'=>Aspera::Node::ACCESS_LEVELS,
|
255
|
+
'tags' =>{'aspera'=>{'files'=>{'workspace'=>{
|
256
|
+
'id' =>@workspace_id,
|
257
|
+
'workspace_name' =>@workspace_name,
|
258
|
+
'user_name' =>c_user_info['name'],
|
259
|
+
'shared_by_user_id'=>c_user_info['id'],
|
260
|
+
'shared_by_name' =>c_user_info['name'],
|
261
|
+
'shared_by_email' =>c_user_info['email'],
|
262
|
+
'shared_with_name' =>access_id,
|
263
|
+
'access_key' =>node_file[:node_info]['access_key'],
|
264
|
+
'node' =>node_file[:node_info]['name']}}}}}
|
265
|
+
item=node_api.create('permissions',params)[:data]
|
266
|
+
return {:type=>:single_object,:data=>item}
|
267
|
+
else raise "internal error:shall not reach here (#{command_perm})"
|
268
|
+
end
|
269
|
+
raise "internal error:shall not reach here"
|
270
|
+
else raise "internal error:shall not reach here (#{command_node_file})"
|
256
271
|
end
|
272
|
+
raise "internal error:shall not reach here"
|
273
|
+
when :permissions
|
274
|
+
|
257
275
|
end # command_repo
|
258
|
-
|
276
|
+
raise "ERR"
|
259
277
|
end # execute_node_gen4_command
|
260
278
|
|
261
279
|
# build constructor option list for AoC based on options of CLI
|
262
280
|
def aoc_params(subpath)
|
263
281
|
# copy command line options to args
|
264
|
-
opt=[:link,:url,:auth,:client_id,:client_secret,:scope,:redirect_uri,:private_key,:username].inject({}){|m,i|m[i]=self.options.get_option(i,:optional);m}
|
282
|
+
opt=[:link,:url,:auth,:client_id,:client_secret,:scope,:redirect_uri,:private_key,:username,:password].inject({}){|m,i|m[i]=self.options.get_option(i,:optional);m}
|
265
283
|
opt[:subpath]=subpath
|
266
284
|
return opt
|
267
285
|
end
|
268
286
|
|
269
|
-
# Create a new AoC API REST object and set @api_aoc.
|
270
|
-
# Parameters based on command line options
|
271
|
-
# @return nil
|
272
|
-
def update_aoc_api
|
273
|
-
@api_aoc=AoC.new(aoc_params('api/v1'))
|
274
|
-
# add access key secrets
|
275
|
-
@api_aoc.add_secrets(self.config.get_secrets)
|
276
|
-
return nil
|
277
|
-
end
|
278
|
-
|
279
287
|
# initialize apis and authentication
|
280
288
|
# set:
|
281
289
|
# @default_workspace_id
|
@@ -290,8 +298,8 @@ module Aspera
|
|
290
298
|
@default_workspace_id=@url_token_data['data']['workspace_id']
|
291
299
|
@persist_ids=[] # TODO : @url_token_data['id'] ?
|
292
300
|
else
|
293
|
-
@default_workspace_id=
|
294
|
-
@persist_ids=[
|
301
|
+
@default_workspace_id=c_user_info['default_workspace_id']
|
302
|
+
@persist_ids=[c_user_info['id']]
|
295
303
|
end
|
296
304
|
|
297
305
|
ws_name=self.options.get_option(:workspace,:optional)
|
@@ -401,7 +409,8 @@ module Aspera
|
|
401
409
|
package_creation[recipient_list_field]=resolved_list
|
402
410
|
end
|
403
411
|
|
404
|
-
|
412
|
+
# private
|
413
|
+
def option_url_query(default)
|
405
414
|
query=self.options.get_option(:query,:optional)||default
|
406
415
|
Log.log.debug("Query=#{query}".bg_red)
|
407
416
|
begin
|
@@ -420,8 +429,7 @@ module Aspera
|
|
420
429
|
end
|
421
430
|
|
422
431
|
def execute_admin_action
|
423
|
-
|
424
|
-
update_aoc_api
|
432
|
+
@api_aoc.oauth.params[:scope]=AoC::SCOPE_FILES_ADMIN
|
425
433
|
command_admin=self.options.get_next_command([ :ats, :resource, :usage_reports, :analytics, :subscription, :auth_providers ])
|
426
434
|
case command_admin
|
427
435
|
when :auth_providers
|
@@ -490,20 +498,7 @@ module Aspera
|
|
490
498
|
:base_url => @api_aoc.params[:base_url]+'/admin/ats/pub/v1',
|
491
499
|
:auth => {:scope => AoC::SCOPE_FILES_ADMIN_USER}
|
492
500
|
}))
|
493
|
-
return @
|
494
|
-
# when :search_nodes
|
495
|
-
# query=self.options.get_option(:query,:optional) || '*'
|
496
|
-
# nodes=@api_aoc.read("search_nodes",{'q'=>query})[:data]
|
497
|
-
# # simplify output
|
498
|
-
# nodes=nodes.map do |i|
|
499
|
-
# item=i['_source']
|
500
|
-
# item['score']=i['_score']
|
501
|
-
# nodedata=item['access_key_recursive_counts'].first
|
502
|
-
# item.delete('access_key_recursive_counts')
|
503
|
-
# item['node']=nodedata
|
504
|
-
# item
|
505
|
-
# end
|
506
|
-
# return {:type=>:object_list,:data=>nodes,:fields=>['host_name','node_status.cluster_id','node_status.node_id']}
|
501
|
+
return Ats.new(@agents).execute_action_gen(ats_api)
|
507
502
|
when :analytics
|
508
503
|
analytics_api = Rest.new(@api_aoc.params.deep_merge({
|
509
504
|
:base_url => @api_aoc.params[:base_url].gsub('/api/v1','')+'/analytics/v2',
|
@@ -513,19 +508,20 @@ module Aspera
|
|
513
508
|
case command_analytics
|
514
509
|
when :application_events
|
515
510
|
event_type=command_analytics.to_s
|
516
|
-
events=analytics_api.read("organizations/#{
|
511
|
+
events=analytics_api.read("organizations/#{c_user_info['organization_id']}/#{event_type}")[:data][event_type]
|
517
512
|
return {:type=>:object_list,:data=>events}
|
518
513
|
when :transfers
|
519
514
|
event_type=command_analytics.to_s
|
520
515
|
filter_resource=self.options.get_option(:name,:optional) || 'organizations'
|
521
516
|
filter_id=self.options.get_option(:id,:optional) || case filter_resource
|
522
|
-
when 'organizations';
|
523
|
-
when 'users';
|
524
|
-
when 'nodes';
|
517
|
+
when 'organizations'; c_user_info['organization_id']
|
518
|
+
when 'users'; c_user_info['id']
|
519
|
+
when 'nodes'; c_user_info['id']
|
525
520
|
else raise "organizations or users for option --name"
|
526
521
|
end
|
527
522
|
#
|
528
523
|
filter=self.options.get_option(:query,:optional) || {}
|
524
|
+
raise "query must be Hash" unless filter.is_a?(Hash)
|
529
525
|
filter['limit']||=100
|
530
526
|
if self.options.get_option(:once_only,:mandatory)
|
531
527
|
saved_date=[]
|
@@ -542,7 +538,7 @@ module Aspera
|
|
542
538
|
filter['stop_time'] = stop_datetime
|
543
539
|
end
|
544
540
|
notification=self.options.get_option(:notify,:optional)
|
545
|
-
events=analytics_api.read("#{filter_resource}/#{filter_id}/#{event_type}",
|
541
|
+
events=analytics_api.read("#{filter_resource}/#{filter_id}/#{event_type}",option_url_query(filter))[:data][event_type]
|
546
542
|
startdate_persistency.save unless startdate_persistency.nil?
|
547
543
|
if !notification.nil?
|
548
544
|
require 'erb'
|
@@ -581,7 +577,7 @@ module Aspera
|
|
581
577
|
supported_operations.push(:delete,*global_operations) unless singleton_object
|
582
578
|
supported_operations.push(:v4,:v3) if resource_type.eql?(:node)
|
583
579
|
supported_operations.push(:set_pub_key) if resource_type.eql?(:client)
|
584
|
-
supported_operations.push(:shared_folders) if [:node,:workspace].include?(resource_type)
|
580
|
+
supported_operations.push(:shared_folders,:shared_create) if [:node,:workspace].include?(resource_type)
|
585
581
|
command=self.options.get_next_command(supported_operations)
|
586
582
|
# require identifier for non global commands
|
587
583
|
if !singleton_object and !global_operations.include?(command)
|
@@ -624,8 +620,10 @@ module Aspera
|
|
624
620
|
when :apps_new; list_query={:organization_apps=>true};default_fields=['app_type','available']
|
625
621
|
when :client_registration_token; default_fields=['id','value','data.client_subject_scopes','created_at']
|
626
622
|
end
|
627
|
-
result=@api_aoc.read(resource_class_path,
|
628
|
-
|
623
|
+
result=@api_aoc.read(resource_class_path,option_url_query(list_query))
|
624
|
+
count_msg="Items: #{result[:data].length}/#{result[:http]['X-Total-Count']}"
|
625
|
+
count_msg=count_msg.bg_red unless result[:data].length.eql?(result[:http]['X-Total-Count'].to_i)
|
626
|
+
self.format.display_status(count_msg)
|
629
627
|
return {:type=>:object_list,:data=>result[:data],:fields=>default_fields}
|
630
628
|
when :show
|
631
629
|
object=@api_aoc.read(resource_instance_path)[:data]
|
@@ -652,7 +650,8 @@ module Aspera
|
|
652
650
|
api_node=@api_aoc.get_node_api(res_data)
|
653
651
|
return Node.new(@agents.merge(skip_basic_auth_options: true, node_api: api_node)).execute_action if command.eql?(:v3)
|
654
652
|
ak_data=api_node.call({:operation=>'GET',:subpath=>"access_keys/#{res_data['access_key']}",:headers=>{'Accept'=>'application/json'}})[:data]
|
655
|
-
|
653
|
+
command_repo=self.options.get_next_command(NODE4_COMMANDS)
|
654
|
+
return execute_node_gen4_command(command_repo,{node_info: res_data, file_id: ak_data['root_file_id']})
|
656
655
|
when :shared_folders
|
657
656
|
read_params = case resource_type
|
658
657
|
when :workspace;{'access_id'=>"ASPERA_ACCESS_KEY_ADMIN_WS_#{res_id}",'access_type'=>'user'}
|
@@ -663,16 +662,48 @@ module Aspera
|
|
663
662
|
fields=case resource_type
|
664
663
|
when :node;['id','file_id','file.path','access_type']
|
665
664
|
when :workspace;['id','node_id','file_id','node_name','file.path','tags.aspera.files.workspace.share_as']
|
666
|
-
else raise "
|
665
|
+
else raise "unexpected resource type #{resource_type}"
|
667
666
|
end
|
668
667
|
return { :type=>:object_list, :data =>res_data , :fields=>fields}
|
669
|
-
|
668
|
+
when :shared_create
|
669
|
+
# TODO
|
670
|
+
folder_path=self.options.get_next_argument('folder path in node')
|
671
|
+
user_create_data=self.options.get_next_argument('creation data (Hash)')
|
672
|
+
res_data=@api_aoc.read(resource_instance_path)[:data]
|
673
|
+
node_file = @api_aoc.resolve_node_file({node_info: res_data, file_id: ak_data['root_file_id']},folder_path)
|
674
|
+
|
675
|
+
#node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
676
|
+
#file_info = node_api.read("files/#{node_file[:file_id]}")[:data]
|
677
|
+
|
678
|
+
access_id="ASPERA_ACCESS_KEY_ADMIN_WS_#{@workspace_id}"
|
679
|
+
create_data={
|
680
|
+
'file_id' =>node_file[:file_id],
|
681
|
+
'access_type' =>'user',
|
682
|
+
'access_id' =>access_id,
|
683
|
+
'access_levels'=>['list','read','write','delete','mkdir','rename','preview'],
|
684
|
+
'tags' =>{'aspera'=>{'files'=>{'workspace'=>{
|
685
|
+
'id' =>@workspace_id,
|
686
|
+
'workspace_name' =>@workspace_name,
|
687
|
+
'share_as' =>File.basename(folder_path),
|
688
|
+
'user_name' =>c_user_info['name'],
|
689
|
+
'shared_by_user_id'=>c_user_info['id'],
|
690
|
+
'shared_by_name' =>c_user_info['name'],
|
691
|
+
'shared_by_email' =>c_user_info['email'],
|
692
|
+
'shared_with_name' =>access_id,
|
693
|
+
'access_key' =>node_file[:node_info]['access_key'],
|
694
|
+
'node' =>node_file[:node_info]['name']}
|
695
|
+
}}}}
|
696
|
+
create_data.deep_merge!(user_create_data)
|
697
|
+
Log.dump(:data,create_data)
|
698
|
+
raise :ERROR
|
699
|
+
else raise "unknown command"
|
670
700
|
end
|
671
701
|
when :usage_reports
|
672
|
-
return {:type=>:object_list,:data=>@api_aoc.read(
|
702
|
+
return {:type=>:object_list,:data=>@api_aoc.read('usage_reports',{:workspace_id=>@workspace_id})[:data]}
|
673
703
|
end
|
674
704
|
end
|
675
705
|
|
706
|
+
# must be public
|
676
707
|
ACTIONS=[ :apiinfo, :bearer_token, :organization, :tier_restrictions, :user, :workspace, :packages, :files, :gateway, :admin, :automation, :servers]
|
677
708
|
|
678
709
|
def execute_action
|
@@ -693,23 +724,23 @@ module Aspera
|
|
693
724
|
command=self.options.get_next_command([ :workspaces,:info,:shared_inboxes ])
|
694
725
|
case command
|
695
726
|
when :workspaces
|
696
|
-
return {:type=>:object_list,:data=>@api_aoc.read(
|
727
|
+
return {:type=>:object_list,:data=>@api_aoc.read('workspaces')[:data],:fields=>['id','name']}
|
697
728
|
# when :settings
|
698
729
|
# return {:type=>:object_list,:data=>@api_aoc.read("client_settings/")[:data]}
|
699
730
|
when :shared_inboxes
|
700
|
-
query=
|
731
|
+
query=option_url_query(nil)
|
701
732
|
if query.nil?
|
702
733
|
set_workspace_info
|
703
734
|
query={'embed[]'=>'dropbox','workspace_id'=>@workspace_id,'aggregate_permissions_by_dropbox'=>true,'sort'=>'dropbox_name'}
|
704
735
|
end
|
705
|
-
return {:type=>:object_list,:data=>@api_aoc.read(
|
736
|
+
return {:type=>:object_list,:data=>@api_aoc.read('dropbox_memberships',query)[:data],:fields=>['dropbox_id','dropbox.name']}
|
706
737
|
when :info
|
707
738
|
command=self.options.get_next_command([ :show,:modify ])
|
708
739
|
case command
|
709
740
|
when :show
|
710
|
-
return { :type=>:single_object, :data =>
|
741
|
+
return { :type=>:single_object, :data =>c_user_info }
|
711
742
|
when :modify
|
712
|
-
@api_aoc.update("users/#{
|
743
|
+
@api_aoc.update("users/#{c_user_info['id']}",self.options.get_next_argument('modified parameters (hash)'))
|
713
744
|
return Main.result_status('modified')
|
714
745
|
end
|
715
746
|
end
|
@@ -722,7 +753,7 @@ module Aspera
|
|
722
753
|
case command_pkg
|
723
754
|
when :send
|
724
755
|
package_creation=self.options.get_option(:value,:mandatory)
|
725
|
-
raise CliBadArgument,
|
756
|
+
raise CliBadArgument,'value must be hash, refer to doc' unless package_creation.is_a?(Hash)
|
726
757
|
|
727
758
|
if !@url_token_data.nil?
|
728
759
|
assert_public_link_types(['send_package_to_user','send_package_to_dropbox'])
|
@@ -803,12 +834,12 @@ module Aspera
|
|
803
834
|
return { :type=>:single_object, :data =>package_info }
|
804
835
|
when :list
|
805
836
|
# list all packages ('page'=>1,'per_page'=>10,)'sort'=>'-sent_at',
|
806
|
-
packages=@api_aoc.read(
|
837
|
+
packages=@api_aoc.read('packages',{'archived'=>false,'exclude_dropbox_packages'=>true,'has_content'=>true,'received'=>true,'workspace_id'=>@workspace_id})[:data]
|
807
838
|
return {:type=>:object_list,:data=>packages,:fields=>['id','name','bytes_transferred']}
|
808
839
|
when :delete
|
809
840
|
list_or_one=self.options.get_option(:id,:mandatory)
|
810
841
|
return do_bulk_operation(list_or_one,'deleted')do|id|
|
811
|
-
raise
|
842
|
+
raise 'expecting String identifier' unless id.is_a?(String) or id.is_a?(Integer)
|
812
843
|
@api_aoc.delete("packages/#{id}")[:data]
|
813
844
|
end
|
814
845
|
end
|
@@ -829,7 +860,7 @@ module Aspera
|
|
829
860
|
when 'private'
|
830
861
|
value_option={'purpose'=>'shared_folder_auth_link'}
|
831
862
|
when NilClass,Hash
|
832
|
-
else raise
|
863
|
+
else raise 'value must be either: public, private, Hash or nil'
|
833
864
|
end
|
834
865
|
create_params=nil
|
835
866
|
node_file=nil
|
@@ -857,30 +888,33 @@ module Aspera
|
|
857
888
|
}
|
858
889
|
value_option['user_selected_name']=nil
|
859
890
|
else
|
860
|
-
raise
|
891
|
+
raise 'purpose must be one of: token_auth_redirection or shared_folder_auth_link'
|
861
892
|
end
|
862
893
|
self.options.set_option(:value,value_option)
|
863
894
|
end
|
864
895
|
result=self.entity_action(@api_aoc,'short_links',nil,:id,'self')
|
865
896
|
if result[:data].is_a?(Hash) and result[:data].has_key?('created_at') and result[:data]['resource_type'].eql?('UrlToken')
|
866
897
|
node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
898
|
+
# TODO: access level as arg
|
899
|
+
access_levels=Aspera::Node::ACCESS_LEVELS #['delete','list','mkdir','preview','read','rename','write']
|
867
900
|
perm_data={
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
901
|
+
'file_id' =>node_file[:file_id],
|
902
|
+
'access_type' =>'user',
|
903
|
+
'access_id' =>result[:data]['resource_id'],
|
904
|
+
'access_levels'=>access_levels,
|
905
|
+
'tags' =>{
|
906
|
+
'url_token' =>true,
|
907
|
+
'workspace_id' =>@workspace_id,
|
908
|
+
'workspace_name' =>@workspace_name,
|
909
|
+
'folder_name' =>'my folder',
|
910
|
+
'created_by_name' =>c_user_info['name'],
|
911
|
+
'created_by_email'=>c_user_info['email'],
|
912
|
+
'access_key' =>node_file[:node_info]['access_key'],
|
913
|
+
'node' =>node_file[:node_info]['host']
|
881
914
|
}
|
882
915
|
}
|
883
916
|
node_api.create("permissions?file_id=#{node_file[:file_id]}",perm_data)
|
917
|
+
# TODO: event ?
|
884
918
|
end
|
885
919
|
return result
|
886
920
|
end # files command
|
@@ -923,17 +957,20 @@ module Aspera
|
|
923
957
|
when :admin
|
924
958
|
return execute_admin_action
|
925
959
|
when :servers
|
926
|
-
self.format.display_status("Beta feature")
|
927
|
-
server_api=Rest.new(base_url:
|
928
|
-
|
929
|
-
servers=JSON.parse(server_api.read('servers')[:data])
|
960
|
+
self.format.display_status("Beta feature: #{@api_aoc.params[:base_url]}")
|
961
|
+
server_api=Rest.new(base_url: @api_aoc.params[:base_url])
|
962
|
+
servers=server_api.read('servers')[:data]
|
930
963
|
return {:type=>:object_list,:data=>servers}
|
931
964
|
else
|
932
965
|
raise "internal error: #{command}"
|
933
966
|
end # action
|
934
967
|
raise RuntimeError, "internal error: command shall return"
|
935
968
|
end
|
936
|
-
|
969
|
+
|
970
|
+
private :find_ak_secret,:c_user_info,:aoc_params,:set_workspace_info,:set_home_node_file,:do_bulk_operation,:resolve_package_recipients,:option_url_query,:assert_public_link_types,:execute_admin_action
|
971
|
+
private_constant :VAL_ALL,:NODE4_COMMANDS
|
972
|
+
|
973
|
+
end # AoC
|
937
974
|
end # Plugins
|
938
975
|
end # Cli
|
939
976
|
end # Aspera
|