aspera-cli 4.4.0 → 4.7.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 +2095 -1503
- data/bin/ascli +2 -1
- data/bin/asession +4 -5
- data/docs/test_env.conf +3 -0
- data/examples/aoc.rb +4 -3
- data/examples/faspex4.rb +25 -25
- data/examples/proxy.pac +1 -1
- data/examples/transfer.rb +17 -17
- data/lib/aspera/aoc.rb +238 -185
- data/lib/aspera/ascmd.rb +93 -83
- data/lib/aspera/ats_api.rb +11 -10
- data/lib/aspera/cli/basic_auth_plugin.rb +13 -14
- data/lib/aspera/cli/extended_value.rb +42 -33
- data/lib/aspera/cli/formater.rb +142 -108
- data/lib/aspera/cli/info.rb +17 -0
- data/lib/aspera/cli/listener/line_dump.rb +3 -2
- data/lib/aspera/cli/listener/logger.rb +2 -1
- data/lib/aspera/cli/listener/progress.rb +16 -18
- data/lib/aspera/cli/listener/progress_multi.rb +18 -21
- data/lib/aspera/cli/main.rb +173 -149
- data/lib/aspera/cli/manager.rb +163 -168
- data/lib/aspera/cli/plugin.rb +43 -31
- data/lib/aspera/cli/plugins/alee.rb +6 -6
- data/lib/aspera/cli/plugins/aoc.rb +405 -370
- data/lib/aspera/cli/plugins/ats.rb +86 -79
- data/lib/aspera/cli/plugins/bss.rb +14 -16
- data/lib/aspera/cli/plugins/config.rb +580 -362
- data/lib/aspera/cli/plugins/console.rb +23 -19
- data/lib/aspera/cli/plugins/cos.rb +18 -18
- data/lib/aspera/cli/plugins/faspex.rb +201 -158
- data/lib/aspera/cli/plugins/faspex5.rb +80 -57
- data/lib/aspera/cli/plugins/node.rb +183 -166
- data/lib/aspera/cli/plugins/orchestrator.rb +71 -67
- data/lib/aspera/cli/plugins/preview.rb +92 -96
- data/lib/aspera/cli/plugins/server.rb +79 -75
- data/lib/aspera/cli/plugins/shares.rb +35 -19
- data/lib/aspera/cli/plugins/sync.rb +20 -22
- data/lib/aspera/cli/transfer_agent.rb +76 -113
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +35 -27
- data/lib/aspera/command_line_builder.rb +48 -34
- data/lib/aspera/cos_node.rb +29 -21
- data/lib/aspera/data_repository.rb +3 -2
- data/lib/aspera/environment.rb +50 -45
- data/lib/aspera/fasp/{manager.rb → agent_base.rb} +28 -25
- data/lib/aspera/fasp/{connect.rb → agent_connect.rb} +52 -43
- data/lib/aspera/fasp/{local.rb → agent_direct.rb} +58 -72
- data/lib/aspera/fasp/{http_gw.rb → agent_httpgw.rb} +37 -43
- data/lib/aspera/fasp/{node.rb → agent_node.rb} +35 -16
- data/lib/aspera/fasp/agent_trsdk.rb +104 -0
- data/lib/aspera/fasp/error.rb +2 -1
- data/lib/aspera/fasp/error_info.rb +68 -52
- data/lib/aspera/fasp/installation.rb +152 -124
- data/lib/aspera/fasp/listener.rb +1 -0
- data/lib/aspera/fasp/parameters.rb +87 -92
- data/lib/aspera/fasp/parameters.yaml +305 -249
- data/lib/aspera/fasp/resume_policy.rb +11 -14
- data/lib/aspera/fasp/transfer_spec.rb +26 -0
- data/lib/aspera/fasp/uri.rb +22 -21
- data/lib/aspera/faspex_gw.rb +55 -89
- data/lib/aspera/hash_ext.rb +4 -3
- data/lib/aspera/id_generator.rb +8 -7
- data/lib/aspera/keychain/encrypted_hash.rb +121 -0
- data/lib/aspera/keychain/macos_security.rb +90 -0
- data/lib/aspera/log.rb +55 -37
- data/lib/aspera/nagios.rb +13 -12
- data/lib/aspera/node.rb +30 -25
- data/lib/aspera/oauth.rb +175 -226
- data/lib/aspera/open_application.rb +4 -3
- data/lib/aspera/persistency_action_once.rb +6 -6
- data/lib/aspera/persistency_folder.rb +5 -9
- data/lib/aspera/preview/file_types.rb +6 -5
- data/lib/aspera/preview/generator.rb +25 -24
- data/lib/aspera/preview/options.rb +16 -14
- data/lib/aspera/preview/utils.rb +98 -98
- data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
- data/lib/aspera/proxy_auto_config.rb +111 -20
- data/lib/aspera/rest.rb +154 -135
- data/lib/aspera/rest_call_error.rb +2 -2
- data/lib/aspera/rest_error_analyzer.rb +23 -25
- data/lib/aspera/rest_errors_aspera.rb +15 -14
- data/lib/aspera/ssh.rb +12 -10
- data/lib/aspera/sync.rb +42 -41
- data/lib/aspera/temp_file_manager.rb +18 -14
- data/lib/aspera/timer_limiter.rb +2 -1
- data/lib/aspera/uri_reader.rb +7 -5
- data/lib/aspera/web_auth.rb +79 -76
- metadata +116 -29
- data/docs/Makefile +0 -66
- data/docs/README.erb.md +0 -3973
- data/docs/README.md +0 -13
- data/docs/diagrams.txt +0 -49
- data/docs/doc_tools.rb +0 -58
- data/lib/aspera/api_detector.rb +0 -60
- data/lib/aspera/cli/plugins/shares2.rb +0 -114
- data/lib/aspera/secrets.rb +0 -20
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'aspera/cli/basic_auth_plugin'
|
2
3
|
require 'aspera/nagios'
|
3
4
|
require 'aspera/hash_ext'
|
4
5
|
require 'aspera/id_generator'
|
6
|
+
require 'aspera/node'
|
7
|
+
require 'aspera/fasp/transfer_spec'
|
5
8
|
require 'base64'
|
6
9
|
require 'zlib'
|
7
10
|
|
@@ -9,38 +12,46 @@ module Aspera
|
|
9
12
|
module Cli
|
10
13
|
module Plugins
|
11
14
|
class Node < BasicAuthPlugin
|
15
|
+
class << self
|
16
|
+
def detect(base_url)
|
17
|
+
api=Rest.new({ base_url: base_url})
|
18
|
+
result=api.call({ operation: 'GET', subpath: 'ping'})
|
19
|
+
if result[:http].body.eql?('')
|
20
|
+
return { product: :node, version: 'unknown'}
|
21
|
+
end
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
end
|
12
25
|
SAMPLE_SOAP_CALL='<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="urn:Aspera:XML:FASPSessionNET:2009/11:Types"><soapenv:Header></soapenv:Header><soapenv:Body><typ:GetSessionInfoRequest><SessionFilter><SessionStatus>running</SessionStatus></SessionFilter></typ:GetSessionInfoRequest></soapenv:Body></soapenv:Envelope>'
|
13
26
|
private_constant :SAMPLE_SOAP_CALL
|
27
|
+
|
14
28
|
def initialize(env)
|
15
29
|
super(env)
|
16
30
|
# this is added to some requests , for instance to add tags (COS)
|
17
31
|
@add_request_param = env[:add_request_param] || {}
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
self.options.parse_options!
|
26
|
-
end
|
32
|
+
options.add_opt_simple(:validator,'identifier of validator (optional for central)')
|
33
|
+
options.add_opt_simple(:asperabrowserurl,'URL for simple aspera web ui')
|
34
|
+
options.add_opt_simple(:sync_name,'sync name')
|
35
|
+
options.add_opt_list(:token_type,[:aspera,:basic,:hybrid],'Type of token used for transfers')
|
36
|
+
options.set_option(:asperabrowserurl,'https://asperabrowser.mybluemix.net')
|
37
|
+
options.set_option(:token_type,:aspera)
|
38
|
+
options.parse_options!
|
27
39
|
return if env[:man_only]
|
40
|
+
@api_node=
|
28
41
|
if env.has_key?(:node_api)
|
29
|
-
|
42
|
+
env[:node_api]
|
43
|
+
elsif options.get_option(:password,:mandatory).start_with?('Bearer ')
|
44
|
+
# info is provided like node_info of aoc
|
45
|
+
Rest.new({
|
46
|
+
base_url: options.get_option(:url,:mandatory),
|
47
|
+
headers: {
|
48
|
+
'Authorization' => options.get_option(:password,:mandatory),
|
49
|
+
'X-Aspera-AccessKey' => options.get_option(:username,:mandatory)
|
50
|
+
}
|
51
|
+
})
|
30
52
|
else
|
31
|
-
|
32
|
-
|
33
|
-
@api_node=Rest.new({
|
34
|
-
base_url: self.options.get_option(:url,:mandatory),
|
35
|
-
headers: {
|
36
|
-
'Authorization' => self.options.get_option(:password,:mandatory),
|
37
|
-
'X-Aspera-AccessKey' => self.options.get_option(:username,:mandatory),
|
38
|
-
}
|
39
|
-
})
|
40
|
-
else
|
41
|
-
# this is normal case
|
42
|
-
@api_node=basic_auth_api
|
43
|
-
end
|
53
|
+
# this is normal case
|
54
|
+
basic_auth_api
|
44
55
|
end
|
45
56
|
end
|
46
57
|
|
@@ -51,14 +62,13 @@ module Aspera
|
|
51
62
|
# key/value is defined in main in hash_table
|
52
63
|
def c_textify_bool_list_result(list,name_list)
|
53
64
|
list.each_index do |i|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
58
|
-
list.delete_at(i)
|
59
|
-
# continue at same index because we delete current one
|
60
|
-
redo
|
65
|
+
next unless name_list.include?(list[i]['key'])
|
66
|
+
list[i]['value'].each do |item|
|
67
|
+
list.push({'key'=>item['name'],'value'=>item['value']})
|
61
68
|
end
|
69
|
+
list.delete_at(i)
|
70
|
+
# continue at same index because we delete current one
|
71
|
+
redo
|
62
72
|
end
|
63
73
|
end
|
64
74
|
|
@@ -68,11 +78,11 @@ module Aspera
|
|
68
78
|
case result[:type]
|
69
79
|
when :object_list
|
70
80
|
result[:data].each do |item|
|
71
|
-
item[column]
|
81
|
+
item[column]=item[column][path_prefix.length..-1] if item[column].start_with?(path_prefix)
|
72
82
|
end
|
73
83
|
when :single_object
|
74
84
|
item=result[:data]
|
75
|
-
item[column]
|
85
|
+
item[column]=item[column][path_prefix.length..-1] if item[column].start_with?(path_prefix)
|
76
86
|
end
|
77
87
|
end
|
78
88
|
return result
|
@@ -80,12 +90,12 @@ module Aspera
|
|
80
90
|
|
81
91
|
# translates paths results into CLI result, and removes prefix
|
82
92
|
def c_result_translate_rem_prefix(resp,type,success_msg,path_prefix)
|
83
|
-
resres={:
|
93
|
+
resres={ data: [], type: :object_list, fields: [type,'result']}
|
84
94
|
JSON.parse(resp[:http].body)['paths'].each do |p|
|
85
95
|
result=success_msg
|
86
96
|
if p.has_key?('error')
|
87
97
|
Log.log.error("#{p['error']['user_message']} : #{p['path']}")
|
88
|
-
result=
|
98
|
+
result='ERROR: '+p['error']['user_message']
|
89
99
|
end
|
90
100
|
resres[:data].push({type=>p['path'],'result'=>result})
|
91
101
|
end
|
@@ -94,16 +104,16 @@ module Aspera
|
|
94
104
|
|
95
105
|
# get path arguments from command line, and add prefix
|
96
106
|
def get_next_arg_add_prefix(path_prefix,name,number=:single)
|
97
|
-
thepath=
|
107
|
+
thepath=options.get_next_argument(name,number)
|
98
108
|
return thepath if path_prefix.nil?
|
99
109
|
return File.join(path_prefix,thepath) if thepath.is_a?(String)
|
100
110
|
return thepath.map {|p| File.join(path_prefix,p)} if thepath.is_a?(Array)
|
101
|
-
raise StandardError,
|
111
|
+
raise StandardError,'expect: nil, String or Array'
|
102
112
|
end
|
103
113
|
|
104
|
-
SIMPLE_ACTIONS=[:health,:events, :space, :info, :license, :mkdir, :mklink, :mkfile, :rename, :delete, :search
|
114
|
+
SIMPLE_ACTIONS=[:health,:events, :space, :info, :license, :mkdir, :mklink, :mkfile, :rename, :delete, :search]
|
105
115
|
|
106
|
-
COMMON_ACTIONS=[:browse, :upload, :download, :api_details
|
116
|
+
COMMON_ACTIONS=[:browse, :upload, :download, :api_details].concat(SIMPLE_ACTIONS)
|
107
117
|
|
108
118
|
# common API to node and Shares
|
109
119
|
# prefix_path is used to list remote sources in Faspex
|
@@ -115,137 +125,146 @@ module Aspera
|
|
115
125
|
info=@api_node.read('info')[:data]
|
116
126
|
nagios.add_ok('node api','accessible')
|
117
127
|
nagios.check_time_offset(info['current_time'],'node api')
|
118
|
-
nagios.check_product_version(
|
119
|
-
rescue => e
|
128
|
+
nagios.check_product_version('node api','entsrv', info['version'])
|
129
|
+
rescue StandardError => e
|
120
130
|
nagios.add_critical('node api',e.to_s)
|
121
131
|
end
|
122
132
|
begin
|
123
|
-
@api_node.call({:
|
133
|
+
@api_node.call({ operation: 'POST', subpath: 'services/soap/Transfer-201210',
|
134
|
+
headers: {'Content-Type'=>'text/xml;charset=UTF-8','SOAPAction'=>'FASPSessionNET-200911#GetSessionInfo'}, text_body_params: SAMPLE_SOAP_CALL})[:http].body
|
124
135
|
nagios.add_ok('central','accessible by node')
|
125
|
-
rescue => e
|
136
|
+
rescue StandardError => e
|
126
137
|
nagios.add_critical('central',e.to_s)
|
127
138
|
end
|
128
139
|
return nagios.result
|
129
140
|
when :events
|
130
|
-
events=@api_node.read('events',
|
131
|
-
return { :
|
141
|
+
events=@api_node.read('events',options.get_option(:value,:optional))[:data]
|
142
|
+
return { type: :object_list, data: events}
|
132
143
|
when :info
|
133
144
|
node_info=@api_node.read('info')[:data]
|
134
|
-
return { :
|
145
|
+
return { type: :single_object, data: node_info, textify: lambda { |table_data| c_textify_bool_list_result(table_data,['capabilities','settings'])}}
|
135
146
|
when :license # requires: asnodeadmin -mu <node user> --acl-add=internal --internal
|
136
147
|
node_license=@api_node.read('license')[:data]
|
137
|
-
if node_license['failure'].is_a?(String)
|
138
|
-
Log.log.error(
|
148
|
+
if node_license['failure'].is_a?(String) && node_license['failure'].include?('ACL')
|
149
|
+
Log.log.error('server must have: asnodeadmin -mu <node user> --acl-add=internal --internal')
|
139
150
|
end
|
140
|
-
return { :
|
151
|
+
return { type: :single_object, data: node_license}
|
141
152
|
when :delete
|
142
|
-
paths_to_delete = get_next_arg_add_prefix(prefix_path,
|
143
|
-
resp=@api_node.create('files/delete',{:
|
153
|
+
paths_to_delete = get_next_arg_add_prefix(prefix_path,'file list',:multiple)
|
154
|
+
resp=@api_node.create('files/delete',{ paths: paths_to_delete.map{|i| {'path'=>i.start_with?('/') ? i : '/'+i} }})
|
144
155
|
return c_result_translate_rem_prefix(resp,'file','deleted',prefix_path)
|
145
156
|
when :search
|
146
|
-
search_root = get_next_arg_add_prefix(prefix_path,
|
157
|
+
search_root = get_next_arg_add_prefix(prefix_path,'search root')
|
147
158
|
parameters={'path'=>search_root}
|
148
|
-
other_options=
|
159
|
+
other_options=options.get_option(:value,:optional)
|
149
160
|
parameters.merge!(other_options) unless other_options.nil?
|
150
161
|
resp=@api_node.create('files/search',parameters)
|
151
|
-
result={ :
|
162
|
+
result={ type: :object_list, data: resp[:data]['items']}
|
152
163
|
return Main.result_empty if result[:data].empty?
|
153
|
-
result[:fields]=result[:data].first.keys.
|
164
|
+
result[:fields]=result[:data].first.keys.reject{|i|['basename','permissions'].include?(i)}
|
154
165
|
self.format.display_status("Items: #{resp[:data]['item_count']}/#{resp[:data]['total_count']}")
|
155
166
|
self.format.display_status("params: #{resp[:data]['parameters'].keys.map{|k|"#{k}:#{resp[:data]['parameters'][k]}"}.join(',')}")
|
156
167
|
return c_result_remove_prefix_path(result,'path',prefix_path)
|
157
168
|
when :space
|
158
169
|
# TODO: could be a list of path
|
159
|
-
path_list=get_next_arg_add_prefix(prefix_path,
|
170
|
+
path_list=get_next_arg_add_prefix(prefix_path,'folder path or ext.val. list')
|
160
171
|
path_list=[path_list] unless path_list.is_a?(Array)
|
161
|
-
resp=@api_node.create('space',{
|
162
|
-
result={:
|
172
|
+
resp=@api_node.create('space',{ 'paths' => path_list.map {|i| { path: i} } })
|
173
|
+
result={ data: resp[:data]['paths'], type: :object_list}
|
163
174
|
#return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
164
175
|
return c_result_remove_prefix_path(result,'path',prefix_path)
|
165
176
|
when :mkdir
|
166
|
-
path_list=get_next_arg_add_prefix(prefix_path,
|
177
|
+
path_list=get_next_arg_add_prefix(prefix_path,'folder path or ext.val. list')
|
167
178
|
path_list=[path_list] unless path_list.is_a?(Array)
|
168
|
-
#TODO
|
169
|
-
#resp=@api_node.create('space',{ "paths" => path_list.map {|i| {:
|
170
|
-
resp=@api_node.create('files/create',{
|
179
|
+
#TODO: a command for that ?
|
180
|
+
#resp=@api_node.create('space',{ "paths" => path_list.map {|i| { type: :directory, path: i} } } )
|
181
|
+
resp=@api_node.create('files/create',{ 'paths' => [{ type: :directory, path: path_list }] })
|
171
182
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
172
183
|
when :mklink
|
173
|
-
target=get_next_arg_add_prefix(prefix_path,
|
174
|
-
path_list=get_next_arg_add_prefix(prefix_path,
|
175
|
-
resp=@api_node.create('files/create',{
|
184
|
+
target=get_next_arg_add_prefix(prefix_path,'target')
|
185
|
+
path_list=get_next_arg_add_prefix(prefix_path,'link path')
|
186
|
+
resp=@api_node.create('files/create',{ 'paths' => [{ type: :symbolic_link, path: path_list, target: { path: target} }] })
|
176
187
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
177
188
|
when :mkfile
|
178
|
-
path_list=get_next_arg_add_prefix(prefix_path,
|
179
|
-
contents64=Base64.strict_encode64(
|
180
|
-
resp=@api_node.create('files/create',{
|
189
|
+
path_list=get_next_arg_add_prefix(prefix_path,'file path')
|
190
|
+
contents64=Base64.strict_encode64(options.get_next_argument('contents'))
|
191
|
+
resp=@api_node.create('files/create',{ 'paths' => [{ type: :file, path: path_list, contents: contents64 }] })
|
181
192
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
182
193
|
when :rename
|
183
|
-
path_base=get_next_arg_add_prefix(prefix_path,
|
184
|
-
path_src=get_next_arg_add_prefix(prefix_path,
|
185
|
-
path_dst=get_next_arg_add_prefix(prefix_path,
|
186
|
-
resp=@api_node.create('files/rename',{
|
194
|
+
path_base=get_next_arg_add_prefix(prefix_path,'path_base')
|
195
|
+
path_src=get_next_arg_add_prefix(prefix_path,'path_src')
|
196
|
+
path_dst=get_next_arg_add_prefix(prefix_path,'path_dst')
|
197
|
+
resp=@api_node.create('files/rename',{ 'paths' => [{ 'path' => path_base, 'source' => path_src, 'destination' => path_dst }] })
|
187
198
|
return c_result_translate_rem_prefix(resp,'entry','moved',prefix_path)
|
188
199
|
when :browse
|
189
|
-
thepath=get_next_arg_add_prefix(prefix_path,
|
190
|
-
query={ :
|
191
|
-
additional_query=
|
200
|
+
thepath=get_next_arg_add_prefix(prefix_path,'path')
|
201
|
+
query={ path: thepath}
|
202
|
+
additional_query=options.get_option(:query,:optional)
|
192
203
|
query.merge!(additional_query) unless additional_query.nil?
|
193
204
|
send_result=@api_node.create('files/browse', query)[:data]
|
194
205
|
#example: send_result={'items'=>[{'file'=>"filename1","permissions"=>[{'name'=>'read'},{'name'=>'write'}]}]}
|
195
206
|
# if there is no items
|
196
207
|
case send_result['self']['type']
|
197
208
|
when 'directory','container' # directory: node, container: shares
|
198
|
-
result={ :
|
209
|
+
result={ data: send_result['items'], type: :object_list, textify: lambda { |table_data| c_textify_browse(table_data) } }
|
199
210
|
self.format.display_status("Items: #{send_result['item_count']}/#{send_result['total_count']}")
|
200
211
|
else # 'file','symbolic_link'
|
201
|
-
result={ :
|
202
|
-
#result={ :
|
212
|
+
result={ data: send_result['self'], type: :single_object}
|
213
|
+
#result={ data: [send_result['self']] , type: :object_list, textify: lambda { |table_data| c_textify_browse(table_data) } }
|
203
214
|
#raise "unknown type: #{send_result['self']['type']}"
|
204
215
|
end
|
205
216
|
return c_result_remove_prefix_path(result,'path',prefix_path)
|
206
217
|
when :upload,:download
|
207
|
-
token_type=
|
218
|
+
token_type=options.get_option(:token_type,:optional)
|
208
219
|
# nil if Shares 1.x
|
209
220
|
token_type=:aspera if token_type.nil?
|
210
221
|
case token_type
|
211
222
|
when :aspera,:hybrid
|
212
|
-
transfer_paths=
|
213
|
-
|
214
|
-
when :
|
223
|
+
transfer_paths=
|
224
|
+
case command
|
225
|
+
when :upload then[{ destination: transfer.destination_folder('send') }]
|
226
|
+
when :download then transfer.ts_source_paths
|
215
227
|
end
|
216
228
|
# only one request, so only one answer
|
217
|
-
transfer_spec=@api_node.create("files/#{command}_setup",{:
|
229
|
+
transfer_spec=@api_node.create("files/#{command}_setup",{ transfer_requests: [{ transfer_request: {
|
218
230
|
paths: transfer_paths
|
219
|
-
}.deep_merge(@add_request_param) }
|
231
|
+
}.deep_merge(@add_request_param) }] })[:data]['transfer_specs'].first['transfer_spec']
|
220
232
|
# delete this part, as the returned value contains only destination, and not sources
|
221
233
|
transfer_spec.delete('paths') if command.eql?(:upload)
|
222
234
|
when :basic
|
223
|
-
raise
|
224
|
-
raise
|
235
|
+
raise 'shall have auth' unless @api_node.params[:auth].is_a?(Hash)
|
236
|
+
raise 'shall be basic auth' unless @api_node.params[:auth][:type].eql?(:basic)
|
237
|
+
ts_direction=
|
238
|
+
case command
|
239
|
+
when :upload then Fasp::TransferSpec::DIRECTION_SEND
|
240
|
+
when :download then Fasp::TransferSpec::DIRECTION_RECEIVE
|
241
|
+
else raise 'Error: need upload or download'
|
242
|
+
end
|
225
243
|
transfer_spec={
|
226
|
-
'remote_host'=>URI.parse(@api_node.params[:base_url]).host,
|
227
|
-
'remote_user'=>Aspera::
|
228
|
-
'ssh_port'=>Aspera::
|
229
|
-
'direction'=>
|
230
|
-
|
244
|
+
'remote_host' =>URI.parse(@api_node.params[:base_url]).host,
|
245
|
+
'remote_user' =>Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER,
|
246
|
+
'ssh_port' =>Aspera::Fasp::TransferSpec::SSH_PORT,
|
247
|
+
'direction' =>ts_direction,
|
248
|
+
'destination_root'=>transfer.destination_folder(ts_direction)
|
249
|
+
}.deep_merge(@add_request_param)
|
231
250
|
else raise "ERROR: token_type #{tt}"
|
232
251
|
end
|
233
252
|
if [:basic,:hybrid].include?(token_type)
|
234
253
|
Aspera::Node.set_ak_basic_token(transfer_spec,@api_node.params[:auth][:username],@api_node.params[:auth][:password])
|
235
254
|
end
|
236
|
-
return Main.result_transfer(
|
255
|
+
return Main.result_transfer(transfer.start(transfer_spec,{ src: :node_gen3}))
|
237
256
|
when :api_details
|
238
|
-
return { :
|
257
|
+
return { type: :single_object, data: @api_node.params }
|
239
258
|
end
|
240
259
|
end
|
241
260
|
|
242
261
|
def execute_async
|
243
|
-
command=
|
262
|
+
command=options.get_next_command([:list,:delete,:files,:show,:counters,:bandwidth])
|
244
263
|
unless command.eql?(:list)
|
245
|
-
asyncname=
|
264
|
+
asyncname=options.get_option(:sync_name,:optional)
|
246
265
|
if asyncname.nil?
|
247
|
-
asyncid=
|
248
|
-
if asyncid.eql?('ALL')
|
266
|
+
asyncid=instance_identifier()
|
267
|
+
if asyncid.eql?('ALL') && [:show,:delete].include?(command)
|
249
268
|
asyncids=@api_node.read('async/list')[:data]['sync_ids']
|
250
269
|
else
|
251
270
|
Integer(asyncid) # must be integer
|
@@ -264,42 +283,39 @@ module Aspera
|
|
264
283
|
case command
|
265
284
|
when :list
|
266
285
|
resp=@api_node.read('async/list')[:data]['sync_ids']
|
267
|
-
return { :
|
286
|
+
return { type: :value_list, data: resp, name: 'id' }
|
268
287
|
when :show
|
269
288
|
resp=@api_node.create('async/summary',pdata)[:data]['sync_summaries']
|
270
289
|
return Main.result_empty if resp.empty?
|
271
|
-
if asyncid.eql?('ALL')
|
272
|
-
|
273
|
-
else
|
274
|
-
return { :type => :single_object, :data => resp.first }
|
275
|
-
end
|
290
|
+
return { type: :object_list, data: resp, fields: ['snid','name','local_dir','remote_dir'] } if asyncid.eql?('ALL')
|
291
|
+
return { type: :single_object, data: resp.first }
|
276
292
|
when :delete
|
277
293
|
resp=@api_node.create('async/delete',pdata)[:data]
|
278
|
-
return { :
|
294
|
+
return { type: :single_object, data: resp, name: 'id' }
|
279
295
|
when :bandwidth
|
280
|
-
pdata['seconds']=100
|
296
|
+
pdata['seconds']=100 # TODO: as parameter with --value
|
281
297
|
resp=@api_node.create('async/bandwidth',pdata)[:data]
|
282
298
|
data=resp['bandwidth_data']
|
283
299
|
return Main.result_empty if data.empty?
|
284
300
|
data=data.first[asyncid]['data']
|
285
|
-
return { :
|
301
|
+
return { type: :object_list, data: data, name: 'id' }
|
286
302
|
when :files
|
287
303
|
# count int
|
288
304
|
# filename str
|
289
305
|
# skip int
|
290
306
|
# status int
|
291
|
-
filter=
|
307
|
+
filter=options.get_option(:value,:optional)
|
292
308
|
pdata.merge!(filter) unless filter.nil?
|
293
309
|
resp=@api_node.create('async/files',pdata)[:data]
|
294
310
|
data=resp['sync_files']
|
295
311
|
data=data.first[asyncid] unless data.empty?
|
296
312
|
iteration_data=[]
|
297
313
|
skip_ids_persistency=nil
|
298
|
-
if
|
314
|
+
if options.get_option(:once_only,:mandatory)
|
299
315
|
skip_ids_persistency=PersistencyActionOnce.new(
|
300
316
|
manager: @agents[:persistency],
|
301
317
|
data: iteration_data,
|
302
|
-
id: IdGenerator.from_list(['sync_files',
|
318
|
+
id: IdGenerator.from_list(['sync_files',options.get_option(:url,:mandatory),options.get_option(:username,:mandatory),asyncid]))
|
303
319
|
unless iteration_data.first.nil?
|
304
320
|
data.select!{|l| l['fnid'].to_i>iteration_data.first}
|
305
321
|
end
|
@@ -307,92 +323,92 @@ module Aspera
|
|
307
323
|
end
|
308
324
|
return Main.result_empty if data.empty?
|
309
325
|
skip_ids_persistency.save unless skip_ids_persistency.nil?
|
310
|
-
return { :
|
326
|
+
return { type: :object_list, data: data, name: 'id' }
|
311
327
|
when :counters
|
312
|
-
resp=@api_node.create('async/counters',pdata)[:data][
|
328
|
+
resp=@api_node.create('async/counters',pdata)[:data]['sync_counters'].first[asyncid].last
|
313
329
|
return Main.result_empty if resp.nil?
|
314
|
-
return { :
|
330
|
+
return { type: :single_object, data: resp }
|
315
331
|
end
|
316
332
|
end
|
317
333
|
|
318
|
-
ACTIONS=[
|
334
|
+
ACTIONS=[:postprocess,:stream, :transfer, :cleanup, :forward, :access_key, :watch_folder, :service, :async, :central, :asperabrowser, :basic_token].concat(COMMON_ACTIONS)
|
319
335
|
|
320
336
|
def execute_action(command=nil,prefix_path=nil)
|
321
|
-
command||=
|
337
|
+
command||=options.get_next_command(ACTIONS)
|
322
338
|
case command
|
323
|
-
when *COMMON_ACTIONS
|
324
|
-
when :async
|
339
|
+
when *COMMON_ACTIONS then return execute_simple_common(command,prefix_path)
|
340
|
+
when :async then return execute_async()
|
325
341
|
when :stream
|
326
|
-
command=
|
342
|
+
command=options.get_next_command([:list, :create, :show, :modify, :cancel])
|
327
343
|
case command
|
328
344
|
when :list
|
329
|
-
resp=@api_node.read('ops/transfers',
|
330
|
-
return { :
|
345
|
+
resp=@api_node.read('ops/transfers',options.get_option(:value,:optional))
|
346
|
+
return { type: :object_list, data: resp[:data], fields: ['id','status'] } # TODO: useful?
|
331
347
|
when :create
|
332
|
-
resp=@api_node.create('streams',
|
333
|
-
return { :
|
348
|
+
resp=@api_node.create('streams',options.get_option(:value,:mandatory))
|
349
|
+
return { type: :single_object, data: resp[:data] }
|
334
350
|
when :show
|
335
|
-
trid=
|
351
|
+
trid=options.get_next_argument('transfer id')
|
336
352
|
resp=@api_node.read('ops/transfers/'+trid)
|
337
|
-
return { :
|
353
|
+
return { type: :other_struct, data: resp[:data] }
|
338
354
|
when :modify
|
339
|
-
trid=
|
340
|
-
resp=@api_node.update('streams/'+trid,
|
341
|
-
return { :
|
355
|
+
trid=options.get_next_argument('transfer id')
|
356
|
+
resp=@api_node.update('streams/'+trid,options.get_option(:value,:mandatory))
|
357
|
+
return { type: :other_struct, data: resp[:data] }
|
342
358
|
when :cancel
|
343
|
-
trid=
|
359
|
+
trid=options.get_next_argument('transfer id')
|
344
360
|
resp=@api_node.cancel('streams/'+trid)
|
345
|
-
return { :
|
361
|
+
return { type: :other_struct, data: resp[:data] }
|
346
362
|
else
|
347
|
-
raise
|
363
|
+
raise 'error'
|
348
364
|
end
|
349
365
|
when :transfer
|
350
|
-
command=
|
366
|
+
command=options.get_next_command([:list, :cancel, :show])
|
351
367
|
res_class_path='ops/transfers'
|
352
368
|
if [:cancel, :show].include?(command)
|
353
|
-
one_res_id=
|
369
|
+
one_res_id=instance_identifier()
|
354
370
|
one_res_path="#{res_class_path}/#{one_res_id}"
|
355
371
|
end
|
356
372
|
case command
|
357
373
|
when :list
|
358
|
-
# could use ? :
|
359
|
-
resp=@api_node.read(res_class_path,
|
360
|
-
return { :
|
374
|
+
# could use ? subpath: 'transfers'
|
375
|
+
resp=@api_node.read(res_class_path,options.get_option(:value,:optional))
|
376
|
+
return { type: :object_list, data: resp[:data],
|
377
|
+
fields: ['id','status','start_spec.direction','start_spec.remote_user','start_spec.remote_host','start_spec.destination_path']}
|
361
378
|
when :cancel
|
362
379
|
resp=@api_node.cancel(one_res_path)
|
363
|
-
return { :
|
380
|
+
return { type: :other_struct, data: resp[:data] }
|
364
381
|
when :show
|
365
382
|
resp=@api_node.read(one_res_path)
|
366
|
-
return { :
|
383
|
+
return { type: :other_struct, data: resp[:data] }
|
367
384
|
else
|
368
|
-
raise
|
385
|
+
raise 'error'
|
369
386
|
end
|
370
387
|
when :access_key
|
371
|
-
return
|
388
|
+
return entity_action(@api_node,'access_keys',id_default: 'self')
|
372
389
|
when :service
|
373
|
-
command=
|
390
|
+
command=options.get_next_command([:list, :create, :delete])
|
374
391
|
if [:delete].include?(command)
|
375
|
-
svcid=
|
392
|
+
svcid=instance_identifier()
|
376
393
|
end
|
377
394
|
case command
|
378
395
|
when :list
|
379
396
|
resp=@api_node.read('rund/services')
|
380
|
-
return { :
|
397
|
+
return { type: :object_list, data: resp[:data]['services'] }
|
381
398
|
when :create
|
382
399
|
# @json:'{"type":"WATCHFOLDERD","run_as":{"user":"user1"}}'
|
383
|
-
params=
|
400
|
+
params=options.get_next_argument('Run creation data (structure)')
|
384
401
|
resp=@api_node.create('rund/services',params)
|
385
402
|
return Main.result_status("#{resp[:data]['id']} created")
|
386
403
|
when :delete
|
387
|
-
|
404
|
+
@api_node.delete("rund/services/#{svcid}")
|
388
405
|
return Main.result_status("#{svcid} deleted")
|
389
406
|
end
|
390
407
|
when :watch_folder
|
391
408
|
res_class_path='v3/watchfolders'
|
392
|
-
|
393
|
-
command=self.options.get_next_command([ :create, :list, :show, :modify, :delete, :state])
|
409
|
+
command=options.get_next_command([:create, :list, :show, :modify, :delete, :state])
|
394
410
|
if [:show,:modify,:delete,:state].include?(command)
|
395
|
-
one_res_id=
|
411
|
+
one_res_id=instance_identifier()
|
396
412
|
one_res_path="#{res_class_path}/#{one_res_id}"
|
397
413
|
end
|
398
414
|
# hum, to avoid: Unable to convert 2016_09_14 configuration
|
@@ -400,46 +416,47 @@ module Aspera
|
|
400
416
|
@api_node.params[:headers]['X-aspera-WF-version']='2017_10_23'
|
401
417
|
case command
|
402
418
|
when :create
|
403
|
-
resp=@api_node.create(res_class_path,
|
419
|
+
resp=@api_node.create(res_class_path,options.get_option(:value,:mandatory))
|
404
420
|
return Main.result_status("#{resp[:data]['id']} created")
|
405
421
|
when :list
|
406
|
-
resp=@api_node.read(res_class_path,
|
407
|
-
return { :
|
422
|
+
resp=@api_node.read(res_class_path,options.get_option(:value,:optional))
|
423
|
+
return { type: :value_list, data: resp[:data]['ids'], name: 'id' }
|
408
424
|
when :show
|
409
|
-
return {:
|
425
|
+
return { type: :single_object, data: @api_node.read(one_res_path)[:data]}
|
410
426
|
when :modify
|
411
|
-
@api_node.update(one_res_path,
|
427
|
+
@api_node.update(one_res_path,options.get_option(:value,:mandatory))
|
412
428
|
return Main.result_status("#{one_res_id} updated")
|
413
429
|
when :delete
|
414
430
|
@api_node.delete(one_res_path)
|
415
431
|
return Main.result_status("#{one_res_id} deleted")
|
416
432
|
when :state
|
417
|
-
return { :
|
433
|
+
return { type: :single_object, data: @api_node.read("#{one_res_path}/state")[:data] }
|
418
434
|
end
|
419
435
|
when :central
|
420
|
-
command=
|
421
|
-
validator_id=
|
422
|
-
validation={
|
423
|
-
request_data=
|
436
|
+
command=options.get_next_command([:session,:file])
|
437
|
+
validator_id=options.get_option(:validator)
|
438
|
+
validation={'validator_id'=>validator_id} unless validator_id.nil?
|
439
|
+
request_data=options.get_option(:value,:optional)
|
424
440
|
request_data||={}
|
425
441
|
case command
|
426
442
|
when :session
|
427
|
-
command=
|
443
|
+
command=options.get_next_command([:list])
|
428
444
|
case command
|
429
445
|
when :list
|
430
|
-
request_data.deep_merge!({
|
446
|
+
request_data.deep_merge!({'validation'=>validation}) unless validation.nil?
|
431
447
|
resp=@api_node.create('services/rest/transfers/v1/sessions',request_data)
|
432
|
-
return {:
|
448
|
+
return { type: :object_list, data: resp[:data]['session_info_result']['session_info'],
|
449
|
+
fields: ['session_uuid','status','transport','direction','bytes_transferred']}
|
433
450
|
end
|
434
451
|
when :file
|
435
|
-
command=
|
452
|
+
command=options.get_next_command([:list, :modify])
|
436
453
|
case command
|
437
454
|
when :list
|
438
455
|
request_data.deep_merge!({'validation'=>validation}) unless validation.nil?
|
439
456
|
resp=@api_node.create('services/rest/transfers/v1/files',request_data)[:data]
|
440
457
|
resp=JSON.parse(resp) if resp.is_a?(String)
|
441
458
|
Log.dump(:resp,resp)
|
442
|
-
return {:
|
459
|
+
return { type: :object_list, data: resp['file_transfer_info_result']['file_transfer_info'], fields: ['session_uuid','file_id','status','path']}
|
443
460
|
when :modify
|
444
461
|
request_data.deep_merge!(validation) unless validation.nil?
|
445
462
|
@api_node.update('services/rest/transfers/v1/files',request_data)
|
@@ -448,18 +465,18 @@ module Aspera
|
|
448
465
|
end
|
449
466
|
when :asperabrowser
|
450
467
|
browse_params={
|
451
|
-
'nodeUser' =>
|
452
|
-
'nodePW' =>
|
453
|
-
'nodeURL' =>
|
468
|
+
'nodeUser' => options.get_option(:username,:mandatory),
|
469
|
+
'nodePW' => options.get_option(:password,:mandatory),
|
470
|
+
'nodeURL' => options.get_option(:url,:mandatory)
|
454
471
|
}
|
455
472
|
# encode parameters so that it looks good in url
|
456
473
|
encoded_params=Base64.strict_encode64(Zlib::Deflate.deflate(JSON.generate(browse_params))).gsub(/=+$/, '').tr('+/', '-_').reverse
|
457
|
-
OpenApplication.instance.uri(
|
474
|
+
OpenApplication.instance.uri(options.get_option(:asperabrowserurl)+'?goto='+encoded_params)
|
458
475
|
return Main.result_status('done')
|
459
476
|
when :basic_token
|
460
|
-
return Main.result_status(
|
477
|
+
return Main.result_status('Basic '+Base64.strict_encode64("#{options.get_option(:username,:mandatory)}:#{options.get_option(:password,:mandatory)}"))
|
461
478
|
end # case command
|
462
|
-
raise
|
479
|
+
raise 'ERROR: shall not reach this line'
|
463
480
|
end # execute_action
|
464
481
|
end # Main
|
465
482
|
end # Plugin
|