aspera-cli 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|