aspera-cli 4.5.0 → 4.6.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 +1063 -853
- data/docs/Makefile +3 -1
- data/docs/README.erb.md +1011 -808
- data/docs/doc_tools.rb +1 -1
- data/docs/test_env.conf +1 -0
- data/lib/aspera/aoc.rb +21 -0
- data/lib/aspera/ascmd.rb +14 -14
- data/lib/aspera/cli/formater.rb +8 -1
- data/lib/aspera/cli/main.rb +23 -21
- data/lib/aspera/cli/manager.rb +5 -1
- data/lib/aspera/cli/plugins/aoc.rb +94 -69
- data/lib/aspera/cli/plugins/config.rb +99 -49
- data/lib/aspera/cli/plugins/node.rb +55 -57
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/environment.rb +1 -1
- data/lib/aspera/faspex_gw.rb +2 -1
- data/lib/aspera/log.rb +1 -1
- data/lib/aspera/rest.rb +1 -0
- metadata +6 -3
@@ -64,6 +64,7 @@ END_OF_TEMPLATE
|
|
64
64
|
# special extended values
|
65
65
|
EXTV_INCLUDE_PRESETS='incps'
|
66
66
|
EXTV_PRESET='preset'
|
67
|
+
PRESET_DIG_SEPARATOR='.'
|
67
68
|
DEFAULT_CHECK_NEW_VERSION_DAYS=7
|
68
69
|
DEFAULT_PRIV_KEY_FILENAME='aspera_aoc_key'
|
69
70
|
DEFAULT_PRIVKEY_LENGTH=4096
|
@@ -71,7 +72,8 @@ END_OF_TEMPLATE
|
|
71
72
|
:CONF_PRESET_GLOBAL,:PROGRAM_NAME_V1,:PROGRAM_NAME_V2,:DEFAULT_REDIRECT,:ASPERA_PLUGINS_FOLDERNAME,
|
72
73
|
:RUBY_FILE_EXT,:AOC_COMMAND_V1,:AOC_COMMAND_V2,:AOC_COMMAND_V3,:AOC_COMMAND_CURRENT,:DEMO,
|
73
74
|
:TRANSFER_SDK_ARCHIVE_URL,:AOC_PATH_API_CLIENTS,:DEMO_SERVER_PRESET,:EMAIL_TEST_TEMPLATE,:EXTV_INCLUDE_PRESETS,
|
74
|
-
:EXTV_PRESET,:DEFAULT_CHECK_NEW_VERSION_DAYS,:DEFAULT_PRIV_KEY_FILENAME,:SERVER_COMMAND,:CONF_PRESET_SECRETS
|
75
|
+
:EXTV_PRESET,:DEFAULT_CHECK_NEW_VERSION_DAYS,:DEFAULT_PRIV_KEY_FILENAME,:SERVER_COMMAND,:CONF_PRESET_SECRETS,
|
76
|
+
:PRESET_DIG_SEPARATOR
|
75
77
|
def option_preset; nil; end
|
76
78
|
|
77
79
|
def option_preset=(value)
|
@@ -81,7 +83,7 @@ END_OF_TEMPLATE
|
|
81
83
|
when Hash
|
82
84
|
self.options.add_option_preset(value)
|
83
85
|
else
|
84
|
-
raise
|
86
|
+
raise 'Preset definition must be a String for name, or Hash for value'
|
85
87
|
end
|
86
88
|
nil
|
87
89
|
end
|
@@ -102,8 +104,8 @@ END_OF_TEMPLATE
|
|
102
104
|
@option_config_file=@conf_file_default
|
103
105
|
Log.log.debug("#{tool_name} folder: #{@main_folder}")
|
104
106
|
# set folder for FASP SDK
|
105
|
-
add_plugin_lookup_folder(File.join(@main_folder,ASPERA_PLUGINS_FOLDERNAME))
|
106
107
|
add_plugin_lookup_folder(self.class.gem_plugins_folder)
|
108
|
+
add_plugin_lookup_folder(File.join(@main_folder,ASPERA_PLUGINS_FOLDERNAME))
|
107
109
|
# do file parameter first
|
108
110
|
self.options.set_obj_attr(:config_file,self,:option_config_file)
|
109
111
|
self.options.add_opt_simple(:config_file,"read parameters from file in YAML format, current=#{@option_config_file}")
|
@@ -119,6 +121,7 @@ END_OF_TEMPLATE
|
|
119
121
|
self.options.set_obj_attr(:ascp_path,self,:option_ascp_path)
|
120
122
|
self.options.set_obj_attr(:use_product,self,:option_use_product)
|
121
123
|
self.options.set_obj_attr(:preset,self,:option_preset)
|
124
|
+
self.options.set_obj_attr(:plugin_folder,self,:option_plugin_folder)
|
122
125
|
self.options.add_opt_switch(:no_default,'-N','do not load default configuration for plugin') { @use_plugin_defaults=false }
|
123
126
|
self.options.add_opt_boolean(:override,'Wizard: override existing value')
|
124
127
|
self.options.add_opt_boolean(:use_generic_client,'Wizard: AoC: use global or org specific jwt client id')
|
@@ -137,6 +140,7 @@ END_OF_TEMPLATE
|
|
137
140
|
self.options.add_opt_simple(:notif_to,'email recipient for notification of transfers')
|
138
141
|
self.options.add_opt_simple(:notif_template,'email ERB template for notification of transfers')
|
139
142
|
self.options.add_opt_simple(:version_check_days,Integer,'period in days to check new version (zero to disable)')
|
143
|
+
self.options.add_opt_simple(:plugin_folder,'folder where to find additional plugins')
|
140
144
|
self.options.set_option(:use_generic_client,true)
|
141
145
|
self.options.set_option(:test_mode,false)
|
142
146
|
self.options.set_option(:default,true)
|
@@ -282,15 +286,30 @@ END_OF_TEMPLATE
|
|
282
286
|
attr_accessor :option_config_file
|
283
287
|
|
284
288
|
# @return the hash from name (also expands possible includes)
|
289
|
+
# @param config_name name of the preset in config file
|
290
|
+
# @param include_path used to detect and avoid include loops
|
285
291
|
def preset_by_name(config_name, include_path=[])
|
286
|
-
raise CliError,"no such config preset: #{config_name}" unless @config_presets.has_key?(config_name)
|
287
292
|
raise CliError,'loop in include' if include_path.include?(config_name)
|
288
|
-
|
293
|
+
include_path=include_path.clone # avoid messing up if there are multiple branches
|
294
|
+
current=@config_presets
|
295
|
+
config_name.split(PRESET_DIG_SEPARATOR).each do |name|
|
296
|
+
raise CliError,"not a Hash: #{include_path} (#{current.class})" unless current.is_a?(Hash)
|
297
|
+
include_path.push(name)
|
298
|
+
current=current[name]
|
299
|
+
raise CliError,"no such config preset: #{include_path}" if nil?
|
300
|
+
end
|
301
|
+
case current
|
302
|
+
when Hash;return expanded_with_preset_includes(current,include_path)
|
303
|
+
when String; return ExtendedValue.instance.evaluate(current)
|
304
|
+
else return current
|
305
|
+
end
|
289
306
|
end
|
290
307
|
|
308
|
+
# @return the hash value with 'incps' keys expanced to include other presets
|
291
309
|
# @param hash_val
|
310
|
+
# @param include_path to avoid inclusion loop
|
292
311
|
def expanded_with_preset_includes(hash_val, include_path=[])
|
293
|
-
raise CliError,"#{EXTV_INCLUDE_PRESETS} requires a Hash" unless hash_val.is_a?(Hash)
|
312
|
+
raise CliError,"#{EXTV_INCLUDE_PRESETS} requires a Hash, have #{hash_val.class}" unless hash_val.is_a?(Hash)
|
294
313
|
if hash_val.has_key?(EXTV_INCLUDE_PRESETS)
|
295
314
|
memory=hash_val.clone
|
296
315
|
includes=memory[EXTV_INCLUDE_PRESETS]
|
@@ -322,6 +341,18 @@ END_OF_TEMPLATE
|
|
322
341
|
'write-only value'
|
323
342
|
end
|
324
343
|
|
344
|
+
def option_plugin_folder=(value)
|
345
|
+
case value
|
346
|
+
when String; add_plugin_lookup_folder(value)
|
347
|
+
when Array; value.each{|f|add_plugin_lookup_folder(f)}
|
348
|
+
else raise "folder shall be Array or String, not #{value.class}"
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
def option_plugin_folder
|
353
|
+
return @plugin_lookup_folders
|
354
|
+
end
|
355
|
+
|
325
356
|
def convert_preset_path(old_name,new_name,files_to_copy)
|
326
357
|
old_subpath=File.join('',ASPERA_HOME_FOLDER_NAME,old_name,'')
|
327
358
|
new_subpath=File.join('',ASPERA_HOME_FOLDER_NAME,new_name,'')
|
@@ -442,7 +473,7 @@ END_OF_TEMPLATE
|
|
442
473
|
end
|
443
474
|
|
444
475
|
def add_plugin_lookup_folder(folder)
|
445
|
-
@plugin_lookup_folders.
|
476
|
+
@plugin_lookup_folders.unshift(folder)
|
446
477
|
end
|
447
478
|
|
448
479
|
def add_plugin_info(path)
|
@@ -485,43 +516,40 @@ END_OF_TEMPLATE
|
|
485
516
|
end
|
486
517
|
|
487
518
|
def execute_connect_action
|
488
|
-
command=self.options.get_next_command([:list,:
|
489
|
-
|
490
|
-
when :list
|
491
|
-
return {type: :object_list, data: connect_versions, fields: ['id','title','version']}
|
492
|
-
when :id
|
519
|
+
command=self.options.get_next_command([:list,:info,:version])
|
520
|
+
if [:info,:version].include?(command)
|
493
521
|
connect_id=self.options.get_next_argument('id or title')
|
494
522
|
one_res=connect_versions.select{|i|i['id'].eql?(connect_id) || i['title'].eql?(connect_id)}.first
|
495
523
|
raise CliNoSuchId.new(:connect,connect_id) if one_res.nil?
|
496
|
-
|
524
|
+
end
|
525
|
+
case command
|
526
|
+
when :list
|
527
|
+
return {type: :object_list, data: connect_versions, fields: ['id','title','version']}
|
528
|
+
when :info # shows files used
|
529
|
+
one_res.delete('links')
|
530
|
+
return {type: :single_object, data: one_res}
|
531
|
+
when :version # shows files used
|
532
|
+
all_links=one_res['links']
|
533
|
+
command=self.options.get_next_command([:list,:download,:open])
|
534
|
+
if [:download,:open].include?(command)
|
535
|
+
link_title=self.options.get_next_argument('title or rel')
|
536
|
+
one_link=all_links.select {|i| i['title'].eql?(link_title) or i['rel'].eql?(link_title)}.first
|
537
|
+
raise "no such value" if one_link.nil?
|
538
|
+
end
|
497
539
|
case command
|
498
|
-
when :
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
case command
|
512
|
-
when :download #
|
513
|
-
folder_dest=self.transfer.destination_folder('receive')
|
514
|
-
#folder_dest=self.options.get_next_argument('destination folder')
|
515
|
-
api_connect_cdn=Rest.new({base_url: CONNECT_WEB_URL})
|
516
|
-
fileurl = one_link['href']
|
517
|
-
filename=fileurl.gsub(%r{.*/},'')
|
518
|
-
api_connect_cdn.call({operation: 'GET',subpath: fileurl,save_to_file: File.join(folder_dest,filename)})
|
519
|
-
return Main.result_status("Downloaded: #{filename}")
|
520
|
-
when :open #
|
521
|
-
OpenApplication.instance.uri(one_link['href'])
|
522
|
-
return Main.result_status("Opened: #{one_link['href']}")
|
523
|
-
end
|
524
|
-
end
|
540
|
+
when :list # shows files used
|
541
|
+
return {type: :object_list, data: all_links}
|
542
|
+
when :download #
|
543
|
+
folder_dest=self.transfer.destination_folder('receive')
|
544
|
+
#folder_dest=self.options.get_next_argument('destination folder')
|
545
|
+
api_connect_cdn=Rest.new({base_url: CONNECT_WEB_URL})
|
546
|
+
fileurl = one_link['href']
|
547
|
+
filename=fileurl.gsub(%r{.*/},'')
|
548
|
+
api_connect_cdn.call({operation: 'GET',subpath: fileurl,save_to_file: File.join(folder_dest,filename)})
|
549
|
+
return Main.result_status("Downloaded: #{filename}")
|
550
|
+
when :open #
|
551
|
+
OpenApplication.instance.uri(one_link['href'])
|
552
|
+
return Main.result_status("Opened: #{one_link['href']}")
|
525
553
|
end
|
526
554
|
end
|
527
555
|
end
|
@@ -666,7 +694,7 @@ END_OF_TEMPLATE
|
|
666
694
|
end
|
667
695
|
end
|
668
696
|
|
669
|
-
ACTIONS=[PRESET_GBL_ACTIONS,:id,:preset,:open,:documentation,:genkey,:gem_path,:
|
697
|
+
ACTIONS=[PRESET_GBL_ACTIONS,:id,:preset,:open,:documentation,:genkey,:gem_path,:plugin,:flush_tokens,:echo,:wizard,:export_to_cli,:detect,:coffee,:ascp,:email_test,:smtp_settings,:proxy_check,:folder,:file,:check_update,:initdemo,:vault].flatten.freeze
|
670
698
|
|
671
699
|
# "config" plugin
|
672
700
|
def execute_action
|
@@ -698,8 +726,30 @@ END_OF_TEMPLATE
|
|
698
726
|
when :flush_tokens
|
699
727
|
deleted_files=Oauth.flush_tokens
|
700
728
|
return {type: :value_list, data: deleted_files, name: 'file'}
|
701
|
-
when :
|
702
|
-
|
729
|
+
when :plugin
|
730
|
+
case self.options.get_next_command([:list,:create])
|
731
|
+
when :list
|
732
|
+
return {type: :object_list, data: @plugins.keys.map { |i| { 'plugin' => i.to_s, 'path' => @plugins[i][:source] } } , fields: ['plugin','path']}
|
733
|
+
when :create
|
734
|
+
plugin_name=options.get_next_argument('name',:single,:mandatory).downcase
|
735
|
+
plugin_folder=options.get_next_argument('folder',:single,:optional) || File.join(@main_folder,ASPERA_PLUGINS_FOLDERNAME)
|
736
|
+
plugin_file=File.join(plugin_folder,"#{plugin_name}.rb")
|
737
|
+
content=<<_EOF_
|
738
|
+
require 'aspera/cli/plugin'
|
739
|
+
module Aspera
|
740
|
+
module Cli
|
741
|
+
module Plugins
|
742
|
+
class #{plugin_name.capitalize} < Plugin
|
743
|
+
ACTIONS=[]
|
744
|
+
def execute_action; return Main.result_status("You called plugin #{plugin_name}"); end
|
745
|
+
end # #{plugin_name.capitalize}
|
746
|
+
end # Plugins
|
747
|
+
end # Cli
|
748
|
+
end # Aspera
|
749
|
+
_EOF_
|
750
|
+
File.write(plugin_file,content)
|
751
|
+
return Main.result_status("Created #{plugin_file}")
|
752
|
+
end
|
703
753
|
when :wizard
|
704
754
|
# interactive mode
|
705
755
|
self.options.ask_missing_mandatory=true
|
@@ -815,7 +865,7 @@ END_OF_TEMPLATE
|
|
815
865
|
o=self.options.get_option(s)
|
816
866
|
@config_presets[preset_name][s.to_s] = o unless o.nil?
|
817
867
|
end
|
818
|
-
test_args="#{plugin_name} user
|
868
|
+
test_args="#{plugin_name} user profile show"
|
819
869
|
else
|
820
870
|
raise CliBadArgument,"Supports only: aoc. Detected: #{appli}"
|
821
871
|
end # product
|
@@ -905,7 +955,7 @@ END_OF_TEMPLATE
|
|
905
955
|
Log.log.info("Setting server default preset to : #{DEMO_SERVER_PRESET}")
|
906
956
|
end
|
907
957
|
save_presets_to_config_file
|
908
|
-
return Main.result_status(
|
958
|
+
return Main.result_status('Done')
|
909
959
|
when :vault
|
910
960
|
command=self.options.get_next_command([:init,:list,:get,:set,:delete])
|
911
961
|
case command
|
@@ -916,9 +966,9 @@ END_OF_TEMPLATE
|
|
916
966
|
raise "default secrets already exists" if @config_presets.has_key?(CONF_PRESET_SECRETS)
|
917
967
|
@config_presets[CONF_PRESET_SECRETS]={}
|
918
968
|
set_global_default(:secrets,"@preset:#{CONF_PRESET_SECRETS}")
|
919
|
-
else raise
|
969
|
+
else raise 'no such vault type'
|
920
970
|
end
|
921
|
-
return Main.result_status(
|
971
|
+
return Main.result_status('Done')
|
922
972
|
when :list
|
923
973
|
return {type: :object_list, data: vault.list}
|
924
974
|
when :set
|
@@ -930,7 +980,7 @@ END_OF_TEMPLATE
|
|
930
980
|
secret=self.options.get_next_argument('secret')
|
931
981
|
vault.set(username: username, url: url, description: description, secret: secret)
|
932
982
|
save_presets_to_config_file if vault.is_a?(Keychain::EncryptedHash)
|
933
|
-
return Main.result_status(
|
983
|
+
return Main.result_status('Done')
|
934
984
|
when :get
|
935
985
|
# register url option
|
936
986
|
BasicAuthPlugin.new(@agents.merge(skip_option_header: true))
|
@@ -944,7 +994,7 @@ END_OF_TEMPLATE
|
|
944
994
|
username=self.options.get_option(:username,:mandatory)
|
945
995
|
url=self.options.get_option(:url,:optional)
|
946
996
|
result=vault.delete(username: username, url: url)
|
947
|
-
return Main.result_status(
|
997
|
+
return Main.result_status('Done')
|
948
998
|
end
|
949
999
|
else raise 'INTERNAL ERROR: wrong case'
|
950
1000
|
end
|
@@ -12,10 +12,10 @@ module Aspera
|
|
12
12
|
class Node < BasicAuthPlugin
|
13
13
|
class << self
|
14
14
|
def detect(base_url)
|
15
|
-
api=Rest.new({:base_url
|
16
|
-
result=api.call({:
|
15
|
+
api=Rest.new({ base_url: base_url})
|
16
|
+
result=api.call({ operation: 'GET', subpath: 'ping'})
|
17
17
|
if result[:http].body.eql?('')
|
18
|
-
return {:
|
18
|
+
return { product: :node, version: 'unknown'}
|
19
19
|
end
|
20
20
|
return nil
|
21
21
|
end
|
@@ -27,15 +27,13 @@ module Aspera
|
|
27
27
|
super(env)
|
28
28
|
# this is added to some requests , for instance to add tags (COS)
|
29
29
|
@add_request_param = env[:add_request_param] || {}
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
self.options.parse_options!
|
38
|
-
end
|
30
|
+
self.options.add_opt_simple(:validator,"identifier of validator (optional for central)")
|
31
|
+
self.options.add_opt_simple(:asperabrowserurl,"URL for simple aspera web ui")
|
32
|
+
self.options.add_opt_simple(:sync_name,"sync name")
|
33
|
+
self.options.add_opt_list(:token_type,[:aspera,:basic,:hybrid],'Type of token used for transfers')
|
34
|
+
self.options.set_option(:asperabrowserurl,'https://asperabrowser.mybluemix.net')
|
35
|
+
self.options.set_option(:token_type,:aspera)
|
36
|
+
self.options.parse_options!
|
39
37
|
return if env[:man_only]
|
40
38
|
if env.has_key?(:node_api)
|
41
39
|
@api_node=env[:node_api]
|
@@ -92,7 +90,7 @@ module Aspera
|
|
92
90
|
|
93
91
|
# translates paths results into CLI result, and removes prefix
|
94
92
|
def c_result_translate_rem_prefix(resp,type,success_msg,path_prefix)
|
95
|
-
resres={:
|
93
|
+
resres={ data: [], type: :object_list, fields: [type,'result']}
|
96
94
|
JSON.parse(resp[:http].body)['paths'].each do |p|
|
97
95
|
result=success_msg
|
98
96
|
if p.has_key?('error')
|
@@ -132,7 +130,7 @@ module Aspera
|
|
132
130
|
nagios.add_critical('node api',e.to_s)
|
133
131
|
end
|
134
132
|
begin
|
135
|
-
@api_node.call({:
|
133
|
+
@api_node.call({ operation: 'POST', subpath: 'services/soap/Transfer-201210', headers: {'Content-Type'=>'text/xml;charset=UTF-8','SOAPAction'=>'FASPSessionNET-200911#GetSessionInfo'}, text_body_params: SAMPLE_SOAP_CALL})[:http].body
|
136
134
|
nagios.add_ok('central','accessible by node')
|
137
135
|
rescue => e
|
138
136
|
nagios.add_critical('central',e.to_s)
|
@@ -140,19 +138,19 @@ module Aspera
|
|
140
138
|
return nagios.result
|
141
139
|
when :events
|
142
140
|
events=@api_node.read('events',self.options.get_option(:value,:optional))[:data]
|
143
|
-
return { :
|
141
|
+
return { type: :object_list, data: events}
|
144
142
|
when :info
|
145
143
|
node_info=@api_node.read('info')[:data]
|
146
|
-
return { :
|
144
|
+
return { type: :single_object, data: node_info, textify: lambda { |table_data| c_textify_bool_list_result(table_data,['capabilities','settings'])}}
|
147
145
|
when :license # requires: asnodeadmin -mu <node user> --acl-add=internal --internal
|
148
146
|
node_license=@api_node.read('license')[:data]
|
149
147
|
if node_license['failure'].is_a?(String) and node_license['failure'].include?('ACL')
|
150
148
|
Log.log.error("server must have: asnodeadmin -mu <node user> --acl-add=internal --internal")
|
151
149
|
end
|
152
|
-
return { :
|
150
|
+
return { type: :single_object, data: node_license}
|
153
151
|
when :delete
|
154
152
|
paths_to_delete = get_next_arg_add_prefix(prefix_path,"file list",:multiple)
|
155
|
-
resp=@api_node.create('files/delete',{:
|
153
|
+
resp=@api_node.create('files/delete',{ paths: paths_to_delete.map{|i| {'path'=>i.start_with?('/') ? i : '/'+i} }})
|
156
154
|
return c_result_translate_rem_prefix(resp,'file','deleted',prefix_path)
|
157
155
|
when :search
|
158
156
|
search_root = get_next_arg_add_prefix(prefix_path,"search root")
|
@@ -160,7 +158,7 @@ module Aspera
|
|
160
158
|
other_options=self.options.get_option(:value,:optional)
|
161
159
|
parameters.merge!(other_options) unless other_options.nil?
|
162
160
|
resp=@api_node.create('files/search',parameters)
|
163
|
-
result={ :
|
161
|
+
result={ type: :object_list, data: resp[:data]['items']}
|
164
162
|
return Main.result_empty if result[:data].empty?
|
165
163
|
result[:fields]=result[:data].first.keys.select{|i|!['basename','permissions'].include?(i)}
|
166
164
|
self.format.display_status("Items: #{resp[:data]['item_count']}/#{resp[:data]['total_count']}")
|
@@ -170,26 +168,26 @@ module Aspera
|
|
170
168
|
# TODO: could be a list of path
|
171
169
|
path_list=get_next_arg_add_prefix(prefix_path,"folder path or ext.val. list")
|
172
170
|
path_list=[path_list] unless path_list.is_a?(Array)
|
173
|
-
resp=@api_node.create('space',{ "paths" => path_list.map {|i| {:
|
174
|
-
result={:
|
171
|
+
resp=@api_node.create('space',{ "paths" => path_list.map {|i| { path: i} } } )
|
172
|
+
result={ data: resp[:data]['paths'], type: :object_list}
|
175
173
|
#return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
176
174
|
return c_result_remove_prefix_path(result,'path',prefix_path)
|
177
175
|
when :mkdir
|
178
176
|
path_list=get_next_arg_add_prefix(prefix_path,"folder path or ext.val. list")
|
179
177
|
path_list=[path_list] unless path_list.is_a?(Array)
|
180
178
|
#TODO: a command for that ?
|
181
|
-
#resp=@api_node.create('space',{ "paths" => path_list.map {|i| {:
|
182
|
-
resp=@api_node.create('files/create',{ "paths" => [{ :
|
179
|
+
#resp=@api_node.create('space',{ "paths" => path_list.map {|i| { type: :directory, path: i} } } )
|
180
|
+
resp=@api_node.create('files/create',{ "paths" => [{ type: :directory, path: path_list } ] } )
|
183
181
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
184
182
|
when :mklink
|
185
183
|
target=get_next_arg_add_prefix(prefix_path,"target")
|
186
184
|
path_list=get_next_arg_add_prefix(prefix_path,"link path")
|
187
|
-
resp=@api_node.create('files/create',{ "paths" => [{ :
|
185
|
+
resp=@api_node.create('files/create',{ "paths" => [{ type: :symbolic_link, path: path_list, target: { path: target} } ] } )
|
188
186
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
189
187
|
when :mkfile
|
190
188
|
path_list=get_next_arg_add_prefix(prefix_path,"file path")
|
191
189
|
contents64=Base64.strict_encode64(self.options.get_next_argument("contents"))
|
192
|
-
resp=@api_node.create('files/create',{ "paths" => [{ :
|
190
|
+
resp=@api_node.create('files/create',{ "paths" => [{ type: :file, path: path_list, contents: contents64 } ] } )
|
193
191
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
194
192
|
when :rename
|
195
193
|
path_base=get_next_arg_add_prefix(prefix_path,"path_base")
|
@@ -199,7 +197,7 @@ module Aspera
|
|
199
197
|
return c_result_translate_rem_prefix(resp,'entry','moved',prefix_path)
|
200
198
|
when :browse
|
201
199
|
thepath=get_next_arg_add_prefix(prefix_path,"path")
|
202
|
-
query={ :
|
200
|
+
query={ path: thepath}
|
203
201
|
additional_query=self.options.get_option(:query,:optional)
|
204
202
|
query.merge!(additional_query) unless additional_query.nil?
|
205
203
|
send_result=@api_node.create('files/browse', query)[:data]
|
@@ -207,11 +205,11 @@ module Aspera
|
|
207
205
|
# if there is no items
|
208
206
|
case send_result['self']['type']
|
209
207
|
when 'directory','container' # directory: node, container: shares
|
210
|
-
result={ :
|
208
|
+
result={ data: send_result['items'] , type: :object_list, textify: lambda { |table_data| c_textify_browse(table_data) } }
|
211
209
|
self.format.display_status("Items: #{send_result['item_count']}/#{send_result['total_count']}")
|
212
210
|
else # 'file','symbolic_link'
|
213
|
-
result={ :
|
214
|
-
#result={ :
|
211
|
+
result={ data: send_result['self'] , type: :single_object}
|
212
|
+
#result={ data: [send_result['self']] , type: :object_list, textify: lambda { |table_data| c_textify_browse(table_data) } }
|
215
213
|
#raise "unknown type: #{send_result['self']['type']}"
|
216
214
|
end
|
217
215
|
return c_result_remove_prefix_path(result,'path',prefix_path)
|
@@ -222,11 +220,11 @@ module Aspera
|
|
222
220
|
case token_type
|
223
221
|
when :aspera,:hybrid
|
224
222
|
transfer_paths=case command
|
225
|
-
when :upload;[ { :
|
223
|
+
when :upload;[ { destination: self.transfer.destination_folder('send') } ]
|
226
224
|
when :download;self.transfer.ts_source_paths
|
227
225
|
end
|
228
226
|
# only one request, so only one answer
|
229
|
-
transfer_spec=@api_node.create("files/#{command}_setup",{:
|
227
|
+
transfer_spec=@api_node.create("files/#{command}_setup",{ transfer_requests: [ { transfer_request: {
|
230
228
|
paths: transfer_paths
|
231
229
|
}.deep_merge(@add_request_param) } ] } )[:data]['transfer_specs'].first['transfer_spec']
|
232
230
|
# delete this part, as the returned value contains only destination, and not sources
|
@@ -239,22 +237,22 @@ module Aspera
|
|
239
237
|
'remote_user'=>Aspera::Fasp::Default::ACCESS_KEY_TRANSFER_USER,
|
240
238
|
'ssh_port' =>Aspera::Fasp::Default::SSH_PORT,
|
241
239
|
'direction' =>case command;when :upload;'send';when :download;'recv';else raise "Error";end
|
242
|
-
}
|
240
|
+
}.deep_merge(@add_request_param)
|
243
241
|
else raise "ERROR: token_type #{tt}"
|
244
242
|
end
|
245
243
|
if [:basic,:hybrid].include?(token_type)
|
246
244
|
Aspera::Node.set_ak_basic_token(transfer_spec,@api_node.params[:auth][:username],@api_node.params[:auth][:password])
|
247
245
|
end
|
248
|
-
return Main.result_transfer(self.transfer.start(transfer_spec,{:
|
246
|
+
return Main.result_transfer(self.transfer.start(transfer_spec,{ src: :node_gen3}))
|
249
247
|
when :api_details
|
250
|
-
return { :
|
248
|
+
return { type: :single_object, data: @api_node.params }
|
251
249
|
end
|
252
250
|
end
|
253
251
|
|
254
252
|
def execute_async
|
255
253
|
command=self.options.get_next_command([:list,:delete,:files,:show,:counters,:bandwidth])
|
256
254
|
unless command.eql?(:list)
|
257
|
-
asyncname=self.options.get_option(:
|
255
|
+
asyncname=self.options.get_option(:sync_name,:optional)
|
258
256
|
if asyncname.nil?
|
259
257
|
asyncid=self.instance_identifier()
|
260
258
|
if asyncid.eql?('ALL') and [:show,:delete].include?(command)
|
@@ -276,25 +274,25 @@ module Aspera
|
|
276
274
|
case command
|
277
275
|
when :list
|
278
276
|
resp=@api_node.read('async/list')[:data]['sync_ids']
|
279
|
-
return { :
|
277
|
+
return { type: :value_list, data: resp, name: 'id' }
|
280
278
|
when :show
|
281
279
|
resp=@api_node.create('async/summary',pdata)[:data]['sync_summaries']
|
282
280
|
return Main.result_empty if resp.empty?
|
283
281
|
if asyncid.eql?('ALL')
|
284
|
-
return { :
|
282
|
+
return { type: :object_list, data: resp, fields: ['snid','name','local_dir','remote_dir'] }
|
285
283
|
else
|
286
|
-
return { :
|
284
|
+
return { type: :single_object, data: resp.first }
|
287
285
|
end
|
288
286
|
when :delete
|
289
287
|
resp=@api_node.create('async/delete',pdata)[:data]
|
290
|
-
return { :
|
288
|
+
return { type: :single_object, data: resp, name: 'id' }
|
291
289
|
when :bandwidth
|
292
290
|
pdata['seconds']=100 # TODO: as parameter with --value
|
293
291
|
resp=@api_node.create('async/bandwidth',pdata)[:data]
|
294
292
|
data=resp['bandwidth_data']
|
295
293
|
return Main.result_empty if data.empty?
|
296
294
|
data=data.first[asyncid]['data']
|
297
|
-
return { :
|
295
|
+
return { type: :object_list, data: data, name: 'id' }
|
298
296
|
when :files
|
299
297
|
# count int
|
300
298
|
# filename str
|
@@ -319,11 +317,11 @@ module Aspera
|
|
319
317
|
end
|
320
318
|
return Main.result_empty if data.empty?
|
321
319
|
skip_ids_persistency.save unless skip_ids_persistency.nil?
|
322
|
-
return { :
|
320
|
+
return { type: :object_list, data: data, name: 'id' }
|
323
321
|
when :counters
|
324
322
|
resp=@api_node.create('async/counters',pdata)[:data]["sync_counters"].first[asyncid].last
|
325
323
|
return Main.result_empty if resp.nil?
|
326
|
-
return { :
|
324
|
+
return { type: :single_object, data: resp }
|
327
325
|
end
|
328
326
|
end
|
329
327
|
|
@@ -339,22 +337,22 @@ module Aspera
|
|
339
337
|
case command
|
340
338
|
when :list
|
341
339
|
resp=@api_node.read('ops/transfers',self.options.get_option(:value,:optional))
|
342
|
-
return { :
|
340
|
+
return { type: :object_list, data: resp[:data], fields: ['id','status'] } # TODO: useful?
|
343
341
|
when :create
|
344
342
|
resp=@api_node.create('streams',self.options.get_option(:value,:mandatory))
|
345
|
-
return { :
|
343
|
+
return { type: :single_object, data: resp[:data] }
|
346
344
|
when :show
|
347
345
|
trid=self.options.get_next_argument("transfer id")
|
348
346
|
resp=@api_node.read('ops/transfers/'+trid)
|
349
|
-
return { :
|
347
|
+
return { type: :other_struct, data: resp[:data] }
|
350
348
|
when :modify
|
351
349
|
trid=self.options.get_next_argument("transfer id")
|
352
350
|
resp=@api_node.update('streams/'+trid,self.options.get_option(:value,:mandatory))
|
353
|
-
return { :
|
351
|
+
return { type: :other_struct, data: resp[:data] }
|
354
352
|
when :cancel
|
355
353
|
trid=self.options.get_next_argument("transfer id")
|
356
354
|
resp=@api_node.cancel('streams/'+trid)
|
357
|
-
return { :
|
355
|
+
return { type: :other_struct, data: resp[:data] }
|
358
356
|
else
|
359
357
|
raise "error"
|
360
358
|
end
|
@@ -367,15 +365,15 @@ module Aspera
|
|
367
365
|
end
|
368
366
|
case command
|
369
367
|
when :list
|
370
|
-
# could use ? :
|
368
|
+
# could use ? subpath: 'transfers'
|
371
369
|
resp=@api_node.read(res_class_path,self.options.get_option(:value,:optional))
|
372
|
-
return { :
|
370
|
+
return { type: :object_list, data: resp[:data], fields: ['id','status','start_spec.direction','start_spec.remote_user','start_spec.remote_host','start_spec.destination_path']}
|
373
371
|
when :cancel
|
374
372
|
resp=@api_node.cancel(one_res_path)
|
375
|
-
return { :
|
373
|
+
return { type: :other_struct, data: resp[:data] }
|
376
374
|
when :show
|
377
375
|
resp=@api_node.read(one_res_path)
|
378
|
-
return { :
|
376
|
+
return { type: :other_struct, data: resp[:data] }
|
379
377
|
else
|
380
378
|
raise "error"
|
381
379
|
end
|
@@ -389,7 +387,7 @@ module Aspera
|
|
389
387
|
case command
|
390
388
|
when :list
|
391
389
|
resp=@api_node.read('rund/services')
|
392
|
-
return { :
|
390
|
+
return { type: :object_list, data: resp[:data]["services"] }
|
393
391
|
when :create
|
394
392
|
# @json:'{"type":"WATCHFOLDERD","run_as":{"user":"user1"}}'
|
395
393
|
params=self.options.get_next_argument("Run creation data (structure)")
|
@@ -416,9 +414,9 @@ module Aspera
|
|
416
414
|
return Main.result_status("#{resp[:data]['id']} created")
|
417
415
|
when :list
|
418
416
|
resp=@api_node.read(res_class_path,self.options.get_option(:value,:optional))
|
419
|
-
return { :
|
417
|
+
return { type: :value_list, data: resp[:data]['ids'], name: 'id' }
|
420
418
|
when :show
|
421
|
-
return {:
|
419
|
+
return { type: :single_object, data: @api_node.read(one_res_path)[:data]}
|
422
420
|
when :modify
|
423
421
|
@api_node.update(one_res_path,self.options.get_option(:value,:mandatory))
|
424
422
|
return Main.result_status("#{one_res_id} updated")
|
@@ -426,7 +424,7 @@ module Aspera
|
|
426
424
|
@api_node.delete(one_res_path)
|
427
425
|
return Main.result_status("#{one_res_id} deleted")
|
428
426
|
when :state
|
429
|
-
return { :
|
427
|
+
return { type: :single_object, data: @api_node.read("#{one_res_path}/state")[:data] }
|
430
428
|
end
|
431
429
|
when :central
|
432
430
|
command=self.options.get_next_command([ :session,:file])
|
@@ -441,7 +439,7 @@ module Aspera
|
|
441
439
|
when :list
|
442
440
|
request_data.deep_merge!({"validation"=>validation}) unless validation.nil?
|
443
441
|
resp=@api_node.create('services/rest/transfers/v1/sessions',request_data)
|
444
|
-
return {:
|
442
|
+
return { type: :object_list, data: resp[:data]["session_info_result"]["session_info"], fields: ["session_uuid","status","transport","direction","bytes_transferred"]}
|
445
443
|
end
|
446
444
|
when :file
|
447
445
|
command=self.options.get_next_command([ :list, :modify])
|
@@ -451,7 +449,7 @@ module Aspera
|
|
451
449
|
resp=@api_node.create('services/rest/transfers/v1/files',request_data)[:data]
|
452
450
|
resp=JSON.parse(resp) if resp.is_a?(String)
|
453
451
|
Log.dump(:resp,resp)
|
454
|
-
return {:
|
452
|
+
return { type: :object_list, data: resp['file_transfer_info_result']['file_transfer_info'], fields: ["session_uuid","file_id","status","path"]}
|
455
453
|
when :modify
|
456
454
|
request_data.deep_merge!(validation) unless validation.nil?
|
457
455
|
@api_node.update('services/rest/transfers/v1/files',request_data)
|
data/lib/aspera/cli/version.rb
CHANGED
data/lib/aspera/environment.rb
CHANGED
data/lib/aspera/faspex_gw.rb
CHANGED
@@ -172,7 +172,7 @@ module Aspera
|
|
172
172
|
:SSLEnable => true,
|
173
173
|
:SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
|
174
174
|
}
|
175
|
-
case
|
175
|
+
case 1
|
176
176
|
when 0
|
177
177
|
# generate self signed cert
|
178
178
|
webrick_options[:SSLCertName] = [ [ 'CN',WEBrick::Utils::getservername ] ]
|
@@ -180,6 +180,7 @@ module Aspera
|
|
180
180
|
when 1
|
181
181
|
fill_self_signed_cert(webrick_options)
|
182
182
|
when 2
|
183
|
+
# TODO: args to set certificate of server
|
183
184
|
webrick_options[:SSLPrivateKey] =OpenSSL::PKey::RSA.new(File.read('/Users/laurent/workspace/Tools/certificate/myserver.key'))
|
184
185
|
webrick_options[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.read('/Users/laurent/workspace/Tools/certificate/myserver.crt'))
|
185
186
|
end
|