aspera-cli 4.7.0 → 4.9.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
- checksums.yaml.gz.sig +0 -0
- data/README.md +1267 -999
- data/bin/ascli +20 -1
- data/bin/asession +37 -34
- data/docs/test_env.conf +7 -3
- data/examples/aoc.rb +13 -12
- data/examples/dascli +23 -0
- data/examples/faspex4.rb +34 -29
- data/examples/{transfer.rb → node.rb} +31 -59
- data/examples/server.rb +93 -0
- data/lib/aspera/aoc.rb +153 -143
- data/lib/aspera/ascmd.rb +56 -45
- data/lib/aspera/ats_api.rb +9 -6
- data/lib/aspera/cli/basic_auth_plugin.rb +18 -16
- data/lib/aspera/cli/extended_value.rb +33 -30
- data/lib/aspera/cli/formater.rb +105 -111
- data/lib/aspera/cli/info.rb +3 -2
- data/lib/aspera/cli/listener/line_dump.rb +1 -0
- data/lib/aspera/cli/listener/logger.rb +1 -0
- data/lib/aspera/cli/listener/progress.rb +13 -12
- data/lib/aspera/cli/listener/progress_multi.rb +21 -20
- data/lib/aspera/cli/main.rb +110 -90
- data/lib/aspera/cli/manager.rb +99 -88
- data/lib/aspera/cli/plugin.rb +98 -39
- data/lib/aspera/cli/plugins/alee.rb +6 -5
- data/lib/aspera/cli/plugins/aoc.rb +581 -450
- data/lib/aspera/cli/plugins/ats.rb +84 -83
- data/lib/aspera/cli/plugins/bss.rb +30 -27
- data/lib/aspera/cli/plugins/config.rb +488 -397
- data/lib/aspera/cli/plugins/console.rb +17 -15
- data/lib/aspera/cli/plugins/cos.rb +26 -35
- data/lib/aspera/cli/plugins/faspex.rb +206 -172
- data/lib/aspera/cli/plugins/faspex5.rb +109 -74
- data/lib/aspera/cli/plugins/node.rb +379 -189
- data/lib/aspera/cli/plugins/orchestrator.rb +71 -65
- data/lib/aspera/cli/plugins/preview.rb +131 -122
- data/lib/aspera/cli/plugins/server.rb +50 -150
- data/lib/aspera/cli/plugins/shares.rb +61 -27
- data/lib/aspera/cli/plugins/sync.rb +15 -14
- data/lib/aspera/cli/transfer_agent.rb +75 -64
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +29 -28
- data/lib/aspera/command_line_builder.rb +50 -43
- data/lib/aspera/cos_node.rb +64 -38
- data/lib/aspera/data_repository.rb +1 -0
- data/lib/aspera/environment.rb +33 -10
- data/lib/aspera/fasp/agent_base.rb +35 -30
- data/lib/aspera/fasp/agent_connect.rb +35 -30
- data/lib/aspera/fasp/agent_direct.rb +68 -60
- data/lib/aspera/fasp/agent_httpgw.rb +71 -64
- data/lib/aspera/fasp/agent_node.rb +24 -23
- data/lib/aspera/fasp/agent_trsdk.rb +19 -20
- data/lib/aspera/fasp/error.rb +2 -1
- data/lib/aspera/fasp/error_info.rb +79 -68
- data/lib/aspera/fasp/installation.rb +130 -126
- data/lib/aspera/fasp/listener.rb +1 -0
- data/lib/aspera/fasp/parameters.rb +71 -60
- data/lib/aspera/fasp/parameters.yaml +69 -17
- data/lib/aspera/fasp/resume_policy.rb +14 -11
- data/lib/aspera/fasp/transfer_spec.rb +6 -5
- data/lib/aspera/fasp/uri.rb +25 -24
- data/lib/aspera/faspex_gw.rb +83 -72
- data/lib/aspera/hash_ext.rb +23 -13
- data/lib/aspera/id_generator.rb +16 -13
- data/lib/aspera/keychain/encrypted_hash.rb +61 -46
- data/lib/aspera/keychain/macos_security.rb +26 -24
- data/lib/aspera/log.rb +35 -39
- data/lib/aspera/nagios.rb +36 -28
- data/lib/aspera/node.rb +19 -19
- data/lib/aspera/oauth.rb +120 -100
- data/lib/aspera/open_application.rb +25 -22
- data/lib/aspera/persistency_action_once.rb +9 -8
- data/lib/aspera/persistency_folder.rb +13 -9
- data/lib/aspera/preview/file_types.rb +261 -266
- data/lib/aspera/preview/generator.rb +74 -73
- data/lib/aspera/preview/image_error.png +0 -0
- data/lib/aspera/preview/options.rb +7 -6
- data/lib/aspera/preview/utils.rb +30 -33
- data/lib/aspera/preview/video_error.png +0 -0
- data/lib/aspera/proxy_auto_config.rb +27 -23
- data/lib/aspera/rest.rb +73 -74
- data/lib/aspera/rest_call_error.rb +1 -0
- data/lib/aspera/rest_error_analyzer.rb +23 -19
- data/lib/aspera/rest_errors_aspera.rb +43 -40
- data/lib/aspera/secret_hider.rb +74 -0
- data/lib/aspera/ssh.rb +13 -10
- data/lib/aspera/sync.rb +49 -47
- data/lib/aspera/temp_file_manager.rb +7 -5
- data/lib/aspera/timer_limiter.rb +9 -8
- data/lib/aspera/uri_reader.rb +17 -18
- data/lib/aspera/web_auth.rb +17 -15
- data.tar.gz.sig +5 -0
- metadata +119 -35
- metadata.gz.sig +0 -0
- data/bin/dascli +0 -13
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'aspera/cli/basic_auth_plugin'
|
3
4
|
require 'aspera/nagios'
|
4
5
|
require 'aspera/hash_ext'
|
@@ -14,49 +15,54 @@ module Aspera
|
|
14
15
|
class Node < BasicAuthPlugin
|
15
16
|
class << self
|
16
17
|
def detect(base_url)
|
17
|
-
api=Rest.new({ base_url: base_url})
|
18
|
-
result=api.call({ operation: 'GET', subpath: 'ping'})
|
18
|
+
api = Rest.new({ base_url: base_url})
|
19
|
+
result = api.call({ operation: 'GET', subpath: 'ping'})
|
19
20
|
if result[:http].body.eql?('')
|
20
21
|
return { product: :node, version: 'unknown'}
|
21
22
|
end
|
22
23
|
return nil
|
23
24
|
end
|
24
25
|
end
|
25
|
-
SAMPLE_SOAP_CALL='<?xml version="1.0" encoding="UTF-8"
|
26
|
-
|
26
|
+
SAMPLE_SOAP_CALL = '<?xml version="1.0" encoding="UTF-8"?>'\
|
27
|
+
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="urn:Aspera:XML:FASPSessionNET:2009/11:Types">'\
|
28
|
+
'<soapenv:Header></soapenv:Header>'\
|
29
|
+
'<soapenv:Body><typ:GetSessionInfoRequest><SessionFilter><SessionStatus>running</SessionStatus></SessionFilter></typ:GetSessionInfoRequest></soapenv:Body>'\
|
30
|
+
'</soapenv:Envelope>'
|
31
|
+
SEARCH_REMOVE_FIELDS=%w[basename permissions].freeze
|
32
|
+
private_constant :SAMPLE_SOAP_CALL,:SEARCH_REMOVE_FIELDS
|
27
33
|
|
28
34
|
def initialize(env)
|
29
35
|
super(env)
|
30
|
-
# this is added to
|
36
|
+
# this is added to transfer spec, for instance to add tags (COS)
|
31
37
|
@add_request_param = env[:add_request_param] || {}
|
32
38
|
options.add_opt_simple(:validator,'identifier of validator (optional for central)')
|
33
39
|
options.add_opt_simple(:asperabrowserurl,'URL for simple aspera web ui')
|
34
40
|
options.add_opt_simple(:sync_name,'sync name')
|
35
|
-
options.add_opt_list(:token_type
|
41
|
+
options.add_opt_list(:token_type,%i[aspera basic hybrid],'Type of token used for transfers')
|
36
42
|
options.set_option(:asperabrowserurl,'https://asperabrowser.mybluemix.net')
|
37
43
|
options.set_option(:token_type,:aspera)
|
38
44
|
options.parse_options!
|
39
45
|
return if env[:man_only]
|
40
|
-
@api_node=
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
46
|
+
@api_node =
|
47
|
+
if env.has_key?(:node_api)
|
48
|
+
env[:node_api]
|
49
|
+
elsif options.get_option(:password,is_type: :mandatory).start_with?('Bearer ')
|
50
|
+
# info is provided like node_info of aoc
|
51
|
+
Rest.new({
|
52
|
+
base_url: options.get_option(:url,is_type: :mandatory),
|
53
|
+
headers: {
|
54
|
+
'X-Aspera-AccessKey' => options.get_option(:username,is_type: :mandatory),
|
55
|
+
'Authorization' => options.get_option(:password,is_type: :mandatory)
|
56
|
+
}
|
57
|
+
})
|
58
|
+
else
|
59
|
+
# this is normal case
|
60
|
+
basic_auth_api
|
61
|
+
end
|
56
62
|
end
|
57
63
|
|
58
64
|
def c_textify_browse(table_data)
|
59
|
-
return table_data.map {|i| i['permissions']=i['permissions'].map { |x| x['name'] }.join(','); i }
|
65
|
+
return table_data.map {|i| i['permissions'] = i['permissions'].map { |x| x['name'] }.join(','); i }
|
60
66
|
end
|
61
67
|
|
62
68
|
# key/value is defined in main in hash_table
|
@@ -64,7 +70,7 @@ module Aspera
|
|
64
70
|
list.each_index do |i|
|
65
71
|
next unless name_list.include?(list[i]['key'])
|
66
72
|
list[i]['value'].each do |item|
|
67
|
-
list.push({'key'=>item['name'],'value'=>item['value']})
|
73
|
+
list.push({'key' => item['name'],'value' => item['value']})
|
68
74
|
end
|
69
75
|
list.delete_at(i)
|
70
76
|
# continue at same index because we delete current one
|
@@ -78,11 +84,11 @@ module Aspera
|
|
78
84
|
case result[:type]
|
79
85
|
when :object_list
|
80
86
|
result[:data].each do |item|
|
81
|
-
item[column]=item[column][path_prefix.length..-1] if item[column].start_with?(path_prefix)
|
87
|
+
item[column] = item[column][path_prefix.length..-1] if item[column].start_with?(path_prefix)
|
82
88
|
end
|
83
89
|
when :single_object
|
84
|
-
item=result[:data]
|
85
|
-
item[column]=item[column][path_prefix.length..-1] if item[column].start_with?(path_prefix)
|
90
|
+
item = result[:data]
|
91
|
+
item[column] = item[column][path_prefix.length..-1] if item[column].start_with?(path_prefix)
|
86
92
|
end
|
87
93
|
end
|
88
94
|
return result
|
@@ -90,39 +96,39 @@ module Aspera
|
|
90
96
|
|
91
97
|
# translates paths results into CLI result, and removes prefix
|
92
98
|
def c_result_translate_rem_prefix(resp,type,success_msg,path_prefix)
|
93
|
-
resres={ data: [], type: :object_list, fields: [type,'result']}
|
99
|
+
resres = { data: [], type: :object_list, fields: [type,'result']}
|
94
100
|
JSON.parse(resp[:http].body)['paths'].each do |p|
|
95
|
-
result=success_msg
|
101
|
+
result = success_msg
|
96
102
|
if p.has_key?('error')
|
97
103
|
Log.log.error("#{p['error']['user_message']} : #{p['path']}")
|
98
|
-
result='ERROR: '+p['error']['user_message']
|
104
|
+
result = 'ERROR: ' + p['error']['user_message']
|
99
105
|
end
|
100
|
-
resres[:data].push({type=>p['path'],'result'=>result})
|
106
|
+
resres[:data].push({type => p['path'],'result' => result})
|
101
107
|
end
|
102
108
|
return c_result_remove_prefix_path(resres,type,path_prefix)
|
103
109
|
end
|
104
110
|
|
105
111
|
# get path arguments from command line, and add prefix
|
106
112
|
def get_next_arg_add_prefix(path_prefix,name,number=:single)
|
107
|
-
thepath=options.get_next_argument(name,number)
|
113
|
+
thepath = options.get_next_argument(name,expected: number)
|
108
114
|
return thepath if path_prefix.nil?
|
109
115
|
return File.join(path_prefix,thepath) if thepath.is_a?(String)
|
110
116
|
return thepath.map {|p| File.join(path_prefix,p)} if thepath.is_a?(Array)
|
111
117
|
raise StandardError,'expect: nil, String or Array'
|
112
118
|
end
|
113
119
|
|
114
|
-
SIMPLE_ACTIONS=[
|
120
|
+
SIMPLE_ACTIONS = %i[health events space info license mkdir mklink mkfile rename delete search].freeze
|
115
121
|
|
116
|
-
COMMON_ACTIONS=[
|
122
|
+
COMMON_ACTIONS = %i[browse upload download api_details].concat(SIMPLE_ACTIONS).freeze
|
117
123
|
|
118
124
|
# common API to node and Shares
|
119
125
|
# prefix_path is used to list remote sources in Faspex
|
120
126
|
def execute_simple_common(command,prefix_path)
|
121
127
|
case command
|
122
128
|
when :health
|
123
|
-
nagios=Nagios.new
|
129
|
+
nagios = Nagios.new
|
124
130
|
begin
|
125
|
-
info
|
131
|
+
info = @api_node.read('info')[:data]
|
126
132
|
nagios.add_ok('node api','accessible')
|
127
133
|
nagios.check_time_offset(info['current_time'],'node api')
|
128
134
|
nagios.check_product_version('node api','entsrv', info['version'])
|
@@ -130,126 +136,130 @@ module Aspera
|
|
130
136
|
nagios.add_critical('node api',e.to_s)
|
131
137
|
end
|
132
138
|
begin
|
133
|
-
@api_node.call(
|
134
|
-
|
139
|
+
@api_node.call(
|
140
|
+
operation: 'POST',
|
141
|
+
subpath: 'services/soap/Transfer-201210',
|
142
|
+
headers: {'Content-Type' => 'text/xml;charset=UTF-8','SOAPAction' => 'FASPSessionNET-200911#GetSessionInfo'},
|
143
|
+
text_body_params: SAMPLE_SOAP_CALL)[:http].body
|
135
144
|
nagios.add_ok('central','accessible by node')
|
136
145
|
rescue StandardError => e
|
137
146
|
nagios.add_critical('central',e.to_s)
|
138
147
|
end
|
139
148
|
return nagios.result
|
140
149
|
when :events
|
141
|
-
events
|
150
|
+
events = @api_node.read('events',options.get_option(:value))[:data]
|
142
151
|
return { type: :object_list, data: events}
|
143
152
|
when :info
|
144
|
-
node_info
|
145
|
-
return { type: :single_object, data: node_info, textify: lambda { |table_data| c_textify_bool_list_result(table_data
|
153
|
+
node_info = @api_node.read('info')[:data]
|
154
|
+
return { type: :single_object, data: node_info, textify: lambda { |table_data| c_textify_bool_list_result(table_data,%w[capabilities settings])}}
|
146
155
|
when :license # requires: asnodeadmin -mu <node user> --acl-add=internal --internal
|
147
|
-
node_license
|
156
|
+
node_license = @api_node.read('license')[:data]
|
148
157
|
if node_license['failure'].is_a?(String) && node_license['failure'].include?('ACL')
|
149
158
|
Log.log.error('server must have: asnodeadmin -mu <node user> --acl-add=internal --internal')
|
150
159
|
end
|
151
160
|
return { type: :single_object, data: node_license}
|
152
161
|
when :delete
|
153
162
|
paths_to_delete = get_next_arg_add_prefix(prefix_path,'file list',:multiple)
|
154
|
-
resp
|
163
|
+
resp = @api_node.create('files/delete',{ paths: paths_to_delete.map{|i| {'path' => i.start_with?('/') ? i : '/' + i} }})
|
155
164
|
return c_result_translate_rem_prefix(resp,'file','deleted',prefix_path)
|
156
165
|
when :search
|
157
166
|
search_root = get_next_arg_add_prefix(prefix_path,'search root')
|
158
|
-
parameters={'path'=>search_root}
|
159
|
-
other_options=options.get_option(:value
|
167
|
+
parameters = {'path' => search_root}
|
168
|
+
other_options = options.get_option(:value)
|
160
169
|
parameters.merge!(other_options) unless other_options.nil?
|
161
|
-
resp
|
162
|
-
result={ type: :object_list, data: resp[:data]['items']}
|
170
|
+
resp = @api_node.create('files/search',parameters)
|
171
|
+
result = { type: :object_list, data: resp[:data]['items']}
|
163
172
|
return Main.result_empty if result[:data].empty?
|
164
|
-
result[:fields]=result[:data].first.keys.reject{|i|
|
173
|
+
result[:fields] = result[:data].first.keys.reject{|i|SEARCH_REMOVE_FIELDS.include?(i)}
|
165
174
|
self.format.display_status("Items: #{resp[:data]['item_count']}/#{resp[:data]['total_count']}")
|
166
175
|
self.format.display_status("params: #{resp[:data]['parameters'].keys.map{|k|"#{k}:#{resp[:data]['parameters'][k]}"}.join(',')}")
|
167
176
|
return c_result_remove_prefix_path(result,'path',prefix_path)
|
168
177
|
when :space
|
169
178
|
# TODO: could be a list of path
|
170
|
-
path_list=get_next_arg_add_prefix(prefix_path,'folder path or ext.val. list')
|
171
|
-
path_list=[path_list] unless path_list.is_a?(Array)
|
172
|
-
resp
|
173
|
-
result={ data: resp[:data]['paths'], type: :object_list}
|
179
|
+
path_list = get_next_arg_add_prefix(prefix_path,'folder path or ext.val. list')
|
180
|
+
path_list = [path_list] unless path_list.is_a?(Array)
|
181
|
+
resp = @api_node.create('space',{ 'paths' => path_list.map {|i| { path: i} } })
|
182
|
+
result = { data: resp[:data]['paths'], type: :object_list}
|
174
183
|
#return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
175
184
|
return c_result_remove_prefix_path(result,'path',prefix_path)
|
176
185
|
when :mkdir
|
177
|
-
path_list=get_next_arg_add_prefix(prefix_path,'folder path or ext.val. list')
|
178
|
-
path_list=[path_list] unless path_list.is_a?(Array)
|
186
|
+
path_list = get_next_arg_add_prefix(prefix_path,'folder path or ext.val. list')
|
187
|
+
path_list = [path_list] unless path_list.is_a?(Array)
|
179
188
|
#TODO: a command for that ?
|
180
189
|
#resp=@api_node.create('space',{ "paths" => path_list.map {|i| { type: :directory, path: i} } } )
|
181
|
-
resp
|
190
|
+
resp = @api_node.create('files/create',{ 'paths' => [{ type: :directory, path: path_list }] })
|
182
191
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
183
192
|
when :mklink
|
184
|
-
target=get_next_arg_add_prefix(prefix_path,'target')
|
185
|
-
path_list=get_next_arg_add_prefix(prefix_path,'link path')
|
186
|
-
resp
|
193
|
+
target = get_next_arg_add_prefix(prefix_path,'target')
|
194
|
+
path_list = get_next_arg_add_prefix(prefix_path,'link path')
|
195
|
+
resp = @api_node.create('files/create',{ 'paths' => [{ type: :symbolic_link, path: path_list, target: { path: target} }] })
|
187
196
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
188
197
|
when :mkfile
|
189
|
-
path_list=get_next_arg_add_prefix(prefix_path,'file path')
|
190
|
-
contents64=Base64.strict_encode64(options.get_next_argument('contents'))
|
191
|
-
resp
|
198
|
+
path_list = get_next_arg_add_prefix(prefix_path,'file path')
|
199
|
+
contents64 = Base64.strict_encode64(options.get_next_argument('contents'))
|
200
|
+
resp = @api_node.create('files/create',{ 'paths' => [{ type: :file, path: path_list, contents: contents64 }] })
|
192
201
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
193
202
|
when :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
|
203
|
+
path_base = get_next_arg_add_prefix(prefix_path,'path_base')
|
204
|
+
path_src = get_next_arg_add_prefix(prefix_path,'path_src')
|
205
|
+
path_dst = get_next_arg_add_prefix(prefix_path,'path_dst')
|
206
|
+
resp = @api_node.create('files/rename',{ 'paths' => [{ 'path' => path_base, 'source' => path_src, 'destination' => path_dst }] })
|
198
207
|
return c_result_translate_rem_prefix(resp,'entry','moved',prefix_path)
|
199
208
|
when :browse
|
200
|
-
thepath=get_next_arg_add_prefix(prefix_path,'path')
|
201
|
-
query={ path: thepath}
|
202
|
-
additional_query=options.get_option(:query
|
209
|
+
thepath = get_next_arg_add_prefix(prefix_path,'path')
|
210
|
+
query = { path: thepath}
|
211
|
+
additional_query = options.get_option(:query)
|
203
212
|
query.merge!(additional_query) unless additional_query.nil?
|
204
|
-
send_result
|
213
|
+
send_result = @api_node.create('files/browse', query)[:data]
|
205
214
|
#example: send_result={'items'=>[{'file'=>"filename1","permissions"=>[{'name'=>'read'},{'name'=>'write'}]}]}
|
206
215
|
# if there is no items
|
207
216
|
case send_result['self']['type']
|
208
217
|
when 'directory','container' # directory: node, container: shares
|
209
|
-
result={ data: send_result['items'], type: :object_list, textify: lambda { |table_data| c_textify_browse(table_data) } }
|
218
|
+
result = { data: send_result['items'], type: :object_list, textify: lambda { |table_data| c_textify_browse(table_data) } }
|
210
219
|
self.format.display_status("Items: #{send_result['item_count']}/#{send_result['total_count']}")
|
211
220
|
else # 'file','symbolic_link'
|
212
|
-
result={ data: send_result['self'], type: :single_object}
|
221
|
+
result = { data: send_result['self'], type: :single_object}
|
213
222
|
#result={ data: [send_result['self']] , type: :object_list, textify: lambda { |table_data| c_textify_browse(table_data) } }
|
214
223
|
#raise "unknown type: #{send_result['self']['type']}"
|
215
224
|
end
|
216
225
|
return c_result_remove_prefix_path(result,'path',prefix_path)
|
217
226
|
when :upload,:download
|
218
|
-
token_type=options.get_option(:token_type
|
227
|
+
token_type = options.get_option(:token_type)
|
219
228
|
# nil if Shares 1.x
|
220
|
-
token_type
|
229
|
+
token_type = :aspera if token_type.nil?
|
221
230
|
case token_type
|
222
231
|
when :aspera,:hybrid
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
232
|
+
# empty transfer spec for authorization request
|
233
|
+
request_transfer_spec={}
|
234
|
+
# set requested paths depending on direction
|
235
|
+
request_transfer_spec[:paths] = command.eql?(:download) ? transfer.ts_source_paths : [{ destination: transfer.destination_folder('send') }]
|
236
|
+
# add fixed parameters if any (for COS)
|
237
|
+
request_transfer_spec.deep_merge!(@add_request_param)
|
238
|
+
# prepare payload for single request
|
239
|
+
setup_payload={transfer_requests: [{transfer_request: request_transfer_spec}]}
|
228
240
|
# only one request, so only one answer
|
229
|
-
transfer_spec
|
230
|
-
paths: transfer_paths
|
231
|
-
}.deep_merge(@add_request_param) }] })[:data]['transfer_specs'].first['transfer_spec']
|
241
|
+
transfer_spec = @api_node.create("files/#{command}_setup",setup_payload)[:data]['transfer_specs'].first['transfer_spec']
|
232
242
|
# delete this part, as the returned value contains only destination, and not sources
|
233
243
|
transfer_spec.delete('paths') if command.eql?(:upload)
|
234
244
|
when :basic
|
235
245
|
raise 'shall have auth' unless @api_node.params[:auth].is_a?(Hash)
|
236
246
|
raise 'shall be basic auth' unless @api_node.params[:auth][:type].eql?(:basic)
|
237
|
-
ts_direction=
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
transfer_spec={
|
244
|
-
'remote_host'
|
245
|
-
'remote_user'
|
246
|
-
'ssh_port'
|
247
|
-
'direction'
|
248
|
-
'destination_root'=>transfer.destination_folder(ts_direction)
|
247
|
+
ts_direction =
|
248
|
+
case command
|
249
|
+
when :upload then Fasp::TransferSpec::DIRECTION_SEND
|
250
|
+
when :download then Fasp::TransferSpec::DIRECTION_RECEIVE
|
251
|
+
else raise 'Error: need upload or download'
|
252
|
+
end
|
253
|
+
transfer_spec = {
|
254
|
+
'remote_host' => URI.parse(@api_node.params[:base_url]).host,
|
255
|
+
'remote_user' => Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER,
|
256
|
+
'ssh_port' => Aspera::Fasp::TransferSpec::SSH_PORT,
|
257
|
+
'direction' => ts_direction,
|
258
|
+
'destination_root' => transfer.destination_folder(ts_direction)
|
249
259
|
}.deep_merge(@add_request_param)
|
250
260
|
else raise "ERROR: token_type #{tt}"
|
251
261
|
end
|
252
|
-
if [
|
262
|
+
if %i[basic hybrid].include?(token_type)
|
253
263
|
Aspera::Node.set_ak_basic_token(transfer_spec,@api_node.params[:auth][:username],@api_node.params[:auth][:password])
|
254
264
|
end
|
255
265
|
return Main.result_transfer(transfer.start(transfer_spec,{ src: :node_gen3}))
|
@@ -258,173 +268,353 @@ headers: {'Content-Type'=>'text/xml;charset=UTF-8','SOAPAction'=>'FASPSessionNET
|
|
258
268
|
end
|
259
269
|
end
|
260
270
|
|
271
|
+
# navigate the path from given file id
|
272
|
+
# @param id initial file id
|
273
|
+
# @param path file path
|
274
|
+
# @return {.api,.file_id}
|
275
|
+
def resolve_api_fid(id, path)
|
276
|
+
# TODO: implement
|
277
|
+
Log.log.debug("TODO #{path}")
|
278
|
+
return {api: @api_node, file_id: id}
|
279
|
+
end
|
280
|
+
|
281
|
+
NODE4_COMMANDS = %i[browse find mkdir rename delete upload download http_node_download file permission bearer_token_node node_info].freeze
|
282
|
+
|
283
|
+
def execute_node_gen4_command(command_repo, top_file_id)
|
284
|
+
#@api_node
|
285
|
+
case command_repo
|
286
|
+
when :node_info
|
287
|
+
thepath = options.get_next_argument('path')
|
288
|
+
apifid = resolve_api_fid(top_file_id,thepath)
|
289
|
+
apifid[:api] = aoc_api.get_node_api(apifid[:node_info], use_secret: false)
|
290
|
+
return {type: :single_object,data: {
|
291
|
+
url: apifid[:node_info]['url'],
|
292
|
+
username: apifid[:node_info]['access_key'],
|
293
|
+
password: apifid[:api].oauth_token,
|
294
|
+
root_id: apifid[:file_id]
|
295
|
+
}}
|
296
|
+
when :browse
|
297
|
+
thepath = options.get_next_argument('path')
|
298
|
+
apifid = resolve_api_fid(top_file_id,thepath)
|
299
|
+
file_info = apifid[:api].read("files/#{apifid[:file_id]}")[:data]
|
300
|
+
if file_info['type'].eql?('folder')
|
301
|
+
result = apifid[:api].read("files/#{apifid[:file_id]}/files",options.get_option(:value))
|
302
|
+
items = result[:data]
|
303
|
+
self.format.display_status("Items: #{result[:data].length}/#{result[:http]['X-Total-Count']}")
|
304
|
+
else
|
305
|
+
items = [file_info]
|
306
|
+
end
|
307
|
+
return {type: :object_list,data: items,fields: %w[name type recursive_size size modified_time access_level]}
|
308
|
+
when :find
|
309
|
+
thepath = options.get_next_argument('path')
|
310
|
+
apifid = resolve_api_fid(top_file_id,thepath)
|
311
|
+
test_block = Aspera::Node.file_matcher(options.get_option(:value))
|
312
|
+
return {type: :object_list,data: aoc_api.find_files(apifid,test_block),fields: ['path']}
|
313
|
+
when :mkdir
|
314
|
+
thepath = options.get_next_argument('path')
|
315
|
+
containing_folder_path = thepath.split(AoC::PATH_SEPARATOR)
|
316
|
+
new_folder = containing_folder_path.pop
|
317
|
+
apifid = resolve_api_fid(top_file_id,containing_folder_path.join(AoC::PATH_SEPARATOR))
|
318
|
+
result = apifid[:api].create("files/#{apifid[:file_id]}/files",{name: new_folder,type: :folder})[:data]
|
319
|
+
return Main.result_status("created: #{result['name']} (id=#{result['id']})")
|
320
|
+
when :rename
|
321
|
+
thepath = options.get_next_argument('source path')
|
322
|
+
newname = options.get_next_argument('new name')
|
323
|
+
apifid = resolve_api_fid(top_file_id,thepath)
|
324
|
+
result = apifid[:api].update("files/#{apifid[:file_id]}",{name: newname})[:data]
|
325
|
+
return Main.result_status("renamed #{thepath} to #{newname}")
|
326
|
+
when :delete
|
327
|
+
thepath = options.get_next_argument('path')
|
328
|
+
return do_bulk_operation(thepath,'deleted','path') do |l_path|
|
329
|
+
raise "expecting String (path), got #{l_path.class.name} (#{l_path})" unless l_path.is_a?(String)
|
330
|
+
apifid = resolve_api_fid(top_file_id,l_path)
|
331
|
+
result = apifid[:api].delete("files/#{apifid[:file_id]}")[:data]
|
332
|
+
{'path' => l_path}
|
333
|
+
end
|
334
|
+
when :upload
|
335
|
+
apifid = resolve_api_fid(top_file_id,transfer.destination_folder(Fasp::TransferSpec::DIRECTION_SEND))
|
336
|
+
add_ts = {'tags' => {'aspera' => {'files' => {'parentCwd' => "#{apifid[:node_info]['id']}:#{apifid[:file_id]}"}}}}
|
337
|
+
return Main.result_transfer(transfer_start(AoC::FILES_APP,Fasp::TransferSpec::DIRECTION_SEND,apifid,add_ts))
|
338
|
+
when :download
|
339
|
+
source_paths = transfer.ts_source_paths
|
340
|
+
# special case for AoC : all files must be in same folder
|
341
|
+
source_folder = source_paths.shift['source']
|
342
|
+
# if a single file: split into folder and path
|
343
|
+
if source_paths.empty?
|
344
|
+
source_folder = source_folder.split(AoC::PATH_SEPARATOR)
|
345
|
+
source_paths = [{'source' => source_folder.pop}]
|
346
|
+
source_folder = source_folder.join(AoC::PATH_SEPARATOR)
|
347
|
+
end
|
348
|
+
apifid = resolve_api_fid(top_file_id,source_folder)
|
349
|
+
# override paths with just filename
|
350
|
+
add_ts = {'tags' => {'aspera' => {'files' => {'parentCwd' => "#{apifid[:node_info]['id']}:#{apifid[:file_id]}"}}}}
|
351
|
+
add_ts['paths'] = source_paths
|
352
|
+
return Main.result_transfer(transfer_start(AoC::FILES_APP,Fasp::TransferSpec::DIRECTION_RECEIVE,apifid,add_ts))
|
353
|
+
when :http_node_download
|
354
|
+
source_paths = transfer.ts_source_paths
|
355
|
+
source_folder = source_paths.shift['source']
|
356
|
+
if source_paths.empty?
|
357
|
+
source_folder = source_folder.split(AoC::PATH_SEPARATOR)
|
358
|
+
source_paths = [{'source' => source_folder.pop}]
|
359
|
+
source_folder = source_folder.join(AoC::PATH_SEPARATOR)
|
360
|
+
end
|
361
|
+
raise CliBadArgument,'one file at a time only in HTTP mode' if source_paths.length > 1
|
362
|
+
file_name = source_paths.first['source']
|
363
|
+
apifid = resolve_api_fid(top_file_id,File.join(source_folder,file_name))
|
364
|
+
apifid[:api].call(
|
365
|
+
operation: 'GET',
|
366
|
+
subpath: "files/#{apifid[:file_id]}/content",
|
367
|
+
save_to_file: File.join(transfer.destination_folder(Fasp::TransferSpec::DIRECTION_RECEIVE),file_name))
|
368
|
+
return Main.result_status("downloaded: #{file_name}")
|
369
|
+
when :permission
|
370
|
+
command_perm = options.get_next_command(%i[list create])
|
371
|
+
case command_perm
|
372
|
+
when :list
|
373
|
+
# generic options : TODO: as arg ? option_url_query
|
374
|
+
list_options ||= {'include' => ['[]','access_level','permission_count']}
|
375
|
+
# special value: ALL will show all permissions
|
376
|
+
if !VAL_ALL.eql?(apifid[:file_id])
|
377
|
+
# add which one to get
|
378
|
+
list_options['file_id'] = apifid[:file_id]
|
379
|
+
list_options['inherited'] ||= false
|
380
|
+
end
|
381
|
+
items = apifid[:api].read('permissions',list_options)[:data]
|
382
|
+
return {type: :object_list,data: items}
|
383
|
+
when :create
|
384
|
+
#create_param=self.options.get_next_argument('creation data (Hash)')
|
385
|
+
set_workspace_info
|
386
|
+
access_id = "#{ID_AK_ADMIN}_WS_#{@workspace_id}"
|
387
|
+
apifid[:node_info]
|
388
|
+
params = {
|
389
|
+
'file_id' => apifid[:file_id], # mandatory
|
390
|
+
'access_type' => 'user', # mandatory: user or group
|
391
|
+
'access_id' => access_id, # id of user or group
|
392
|
+
'access_levels' => Aspera::Node::ACCESS_LEVELS,
|
393
|
+
'tags' => {'aspera' => {'files' => {'workspace' => {
|
394
|
+
'id' => @workspace_id,
|
395
|
+
'workspace_name' => @workspace_name,
|
396
|
+
'user_name' => aoc_api.user_info['name'],
|
397
|
+
'shared_by_user_id' => aoc_api.user_info['id'],
|
398
|
+
'shared_by_name' => aoc_api.user_info['name'],
|
399
|
+
'shared_by_email' => aoc_api.user_info['email'],
|
400
|
+
'shared_with_name' => access_id,
|
401
|
+
'access_key' => apifid[:node_info]['access_key'],
|
402
|
+
'node' => apifid[:node_info]['name']}}}}}
|
403
|
+
item = apifid[:api].create('permissions',params)[:data]
|
404
|
+
return {type: :single_object,data: item}
|
405
|
+
else raise "internal error:shall not reach here (#{command_perm})"
|
406
|
+
end
|
407
|
+
when :file
|
408
|
+
command_node_file = options.get_next_command(%i[show modify])
|
409
|
+
file_path = options.get_option(:path)
|
410
|
+
apifid =
|
411
|
+
if !file_path.nil?
|
412
|
+
resolve_api_fid(top_file_id,file_path) # TODO: allow follow link ?
|
413
|
+
else
|
414
|
+
{node_info: top_file_id[:node_info],file_id: instance_identifier}
|
415
|
+
end
|
416
|
+
case command_node_file
|
417
|
+
when :show
|
418
|
+
items = apifid[:api].read("files/#{apifid[:file_id]}")[:data]
|
419
|
+
return {type: :single_object,data: items}
|
420
|
+
when :modify
|
421
|
+
update_param = options.get_next_argument('update data (Hash)')
|
422
|
+
res = apifid[:api].update("files/#{apifid[:file_id]}",update_param)[:data]
|
423
|
+
return {type: :single_object,data: res}
|
424
|
+
else raise "internal error:shall not reach here (#{command_node_file})"
|
425
|
+
end
|
426
|
+
end # command_repo
|
427
|
+
raise 'ERR'
|
428
|
+
end # execute_node_gen4_command
|
429
|
+
|
261
430
|
def execute_async
|
262
|
-
command=options.get_next_command([
|
431
|
+
command = options.get_next_command(%i[list delete files show counters bandwidth])
|
263
432
|
unless command.eql?(:list)
|
264
|
-
asyncname=options.get_option(:sync_name
|
433
|
+
asyncname = options.get_option(:sync_name)
|
265
434
|
if asyncname.nil?
|
266
|
-
asyncid=instance_identifier
|
267
|
-
if asyncid.eql?('ALL') && [
|
268
|
-
asyncids
|
435
|
+
asyncid = instance_identifier
|
436
|
+
if asyncid.eql?('ALL') && %i[show delete].include?(command)
|
437
|
+
asyncids = @api_node.read('async/list')[:data]['sync_ids']
|
269
438
|
else
|
270
439
|
Integer(asyncid) # must be integer
|
271
|
-
asyncids=[asyncid]
|
440
|
+
asyncids = [asyncid]
|
272
441
|
end
|
273
442
|
else
|
274
|
-
asyncids
|
275
|
-
summaries
|
276
|
-
selected=summaries.
|
443
|
+
asyncids = @api_node.read('async/list')[:data]['sync_ids']
|
444
|
+
summaries = @api_node.create('async/summary',{'syncs' => asyncids})[:data]['sync_summaries']
|
445
|
+
selected = summaries.find{|s|s['name'].eql?(asyncname)}
|
277
446
|
raise "no such sync: #{asyncname}" if selected.nil?
|
278
|
-
asyncid=selected['snid']
|
279
|
-
asyncids=[asyncid]
|
447
|
+
asyncid = selected['snid']
|
448
|
+
asyncids = [asyncid]
|
280
449
|
end
|
281
|
-
pdata={'syncs' => asyncids}
|
450
|
+
pdata = {'syncs' => asyncids}
|
282
451
|
end
|
283
452
|
case command
|
284
453
|
when :list
|
285
|
-
resp
|
454
|
+
resp = @api_node.read('async/list')[:data]['sync_ids']
|
286
455
|
return { type: :value_list, data: resp, name: 'id' }
|
287
456
|
when :show
|
288
|
-
resp
|
457
|
+
resp = @api_node.create('async/summary',pdata)[:data]['sync_summaries']
|
289
458
|
return Main.result_empty if resp.empty?
|
290
|
-
return { type: :object_list, data: resp, fields: [
|
459
|
+
return { type: :object_list, data: resp, fields: %w[snid name local_dir remote_dir] } if asyncid.eql?('ALL')
|
291
460
|
return { type: :single_object, data: resp.first }
|
292
461
|
when :delete
|
293
|
-
resp
|
462
|
+
resp = @api_node.create('async/delete',pdata)[:data]
|
294
463
|
return { type: :single_object, data: resp, name: 'id' }
|
295
464
|
when :bandwidth
|
296
|
-
pdata['seconds']=100 # TODO: as parameter with --value
|
297
|
-
resp
|
298
|
-
data=resp['bandwidth_data']
|
465
|
+
pdata['seconds'] = 100 # TODO: as parameter with --value
|
466
|
+
resp = @api_node.create('async/bandwidth',pdata)[:data]
|
467
|
+
data = resp['bandwidth_data']
|
299
468
|
return Main.result_empty if data.empty?
|
300
|
-
data=data.first[asyncid]['data']
|
469
|
+
data = data.first[asyncid]['data']
|
301
470
|
return { type: :object_list, data: data, name: 'id' }
|
302
471
|
when :files
|
303
472
|
# count int
|
304
473
|
# filename str
|
305
474
|
# skip int
|
306
475
|
# status int
|
307
|
-
filter=options.get_option(:value
|
476
|
+
filter = options.get_option(:value)
|
308
477
|
pdata.merge!(filter) unless filter.nil?
|
309
|
-
resp
|
310
|
-
data=resp['sync_files']
|
311
|
-
data=data.first[asyncid] unless data.empty?
|
312
|
-
iteration_data=[]
|
313
|
-
skip_ids_persistency=nil
|
314
|
-
if options.get_option(:once_only
|
315
|
-
skip_ids_persistency=PersistencyActionOnce.new(
|
316
|
-
|
317
|
-
|
318
|
-
|
478
|
+
resp = @api_node.create('async/files',pdata)[:data]
|
479
|
+
data = resp['sync_files']
|
480
|
+
data = data.first[asyncid] unless data.empty?
|
481
|
+
iteration_data = []
|
482
|
+
skip_ids_persistency = nil
|
483
|
+
if options.get_option(:once_only,is_type: :mandatory)
|
484
|
+
skip_ids_persistency = PersistencyActionOnce.new(
|
485
|
+
manager: @agents[:persistency],
|
486
|
+
data: iteration_data,
|
487
|
+
id: IdGenerator.from_list([
|
488
|
+
'sync_files',
|
489
|
+
options.get_option(:url,is_type: :mandatory),
|
490
|
+
options.get_option(:username,is_type: :mandatory),
|
491
|
+
asyncid]))
|
319
492
|
unless iteration_data.first.nil?
|
320
|
-
data.select!{|l| l['fnid'].to_i>iteration_data.first}
|
493
|
+
data.select!{|l| l['fnid'].to_i > iteration_data.first}
|
321
494
|
end
|
322
|
-
iteration_data[0]=data.last['fnid'].to_i unless data.empty?
|
495
|
+
iteration_data[0] = data.last['fnid'].to_i unless data.empty?
|
323
496
|
end
|
324
497
|
return Main.result_empty if data.empty?
|
325
|
-
skip_ids_persistency
|
498
|
+
skip_ids_persistency&.save
|
326
499
|
return { type: :object_list, data: data, name: 'id' }
|
327
500
|
when :counters
|
328
|
-
resp
|
501
|
+
resp = @api_node.create('async/counters',pdata)[:data]['sync_counters'].first[asyncid].last
|
329
502
|
return Main.result_empty if resp.nil?
|
330
503
|
return { type: :single_object, data: resp }
|
331
504
|
end
|
332
505
|
end
|
333
506
|
|
334
|
-
ACTIONS=[
|
507
|
+
ACTIONS = %i[postprocess stream transfer cleanup forward access_key watch_folder service async central asperabrowser basic_token].concat(COMMON_ACTIONS).freeze
|
335
508
|
|
336
509
|
def execute_action(command=nil,prefix_path=nil)
|
337
|
-
command||=options.get_next_command(ACTIONS)
|
510
|
+
command ||= options.get_next_command(ACTIONS)
|
338
511
|
case command
|
339
512
|
when *COMMON_ACTIONS then return execute_simple_common(command,prefix_path)
|
340
|
-
when :async then return execute_async
|
513
|
+
when :async then return execute_async
|
341
514
|
when :stream
|
342
|
-
command=options.get_next_command([
|
515
|
+
command = options.get_next_command(%i[list create show modify cancel])
|
343
516
|
case command
|
344
517
|
when :list
|
345
|
-
resp
|
346
|
-
return { type: :object_list, data: resp[:data], fields: [
|
518
|
+
resp = @api_node.read('ops/transfers',options.get_option(:value))
|
519
|
+
return { type: :object_list, data: resp[:data], fields: %w[id status] } # TODO: useful?
|
347
520
|
when :create
|
348
|
-
resp
|
521
|
+
resp = @api_node.create('streams',options.get_option(:value,is_type: :mandatory))
|
349
522
|
return { type: :single_object, data: resp[:data] }
|
350
523
|
when :show
|
351
|
-
trid=options.get_next_argument('transfer id')
|
352
|
-
resp
|
524
|
+
trid = options.get_next_argument('transfer id')
|
525
|
+
resp = @api_node.read('ops/transfers/' + trid)
|
353
526
|
return { type: :other_struct, data: resp[:data] }
|
354
527
|
when :modify
|
355
|
-
trid=options.get_next_argument('transfer id')
|
356
|
-
resp
|
528
|
+
trid = options.get_next_argument('transfer id')
|
529
|
+
resp = @api_node.update('streams/' + trid,options.get_option(:value,is_type: :mandatory))
|
357
530
|
return { type: :other_struct, data: resp[:data] }
|
358
531
|
when :cancel
|
359
|
-
trid=options.get_next_argument('transfer id')
|
360
|
-
resp
|
532
|
+
trid = options.get_next_argument('transfer id')
|
533
|
+
resp = @api_node.cancel('streams/' + trid)
|
361
534
|
return { type: :other_struct, data: resp[:data] }
|
362
535
|
else
|
363
536
|
raise 'error'
|
364
537
|
end
|
365
538
|
when :transfer
|
366
|
-
command=options.get_next_command([
|
367
|
-
res_class_path='ops/transfers'
|
368
|
-
if [
|
369
|
-
one_res_id=instance_identifier
|
370
|
-
one_res_path="#{res_class_path}/#{one_res_id}"
|
539
|
+
command = options.get_next_command(%i[list cancel show])
|
540
|
+
res_class_path = 'ops/transfers'
|
541
|
+
if %i[cancel show].include?(command)
|
542
|
+
one_res_id = instance_identifier
|
543
|
+
one_res_path = "#{res_class_path}/#{one_res_id}"
|
371
544
|
end
|
372
545
|
case command
|
373
546
|
when :list
|
374
547
|
# could use ? subpath: 'transfers'
|
375
|
-
resp
|
376
|
-
return {
|
377
|
-
|
548
|
+
resp = @api_node.read(res_class_path,options.get_option(:value))
|
549
|
+
return {
|
550
|
+
type: :object_list,
|
551
|
+
data: resp[:data],
|
552
|
+
fields: %w[id status start_spec.direction start_spec.remote_user start_spec.remote_host start_spec.destination_path]
|
553
|
+
}
|
378
554
|
when :cancel
|
379
|
-
resp
|
555
|
+
resp = @api_node.cancel(one_res_path)
|
380
556
|
return { type: :other_struct, data: resp[:data] }
|
381
557
|
when :show
|
382
|
-
resp
|
558
|
+
resp = @api_node.read(one_res_path)
|
383
559
|
return { type: :other_struct, data: resp[:data] }
|
384
560
|
else
|
385
561
|
raise 'error'
|
386
562
|
end
|
387
563
|
when :access_key
|
388
|
-
|
564
|
+
ak_command = options.get_next_command([Plugin::ALL_OPS,:do].flatten)
|
565
|
+
case ak_command
|
566
|
+
when *Plugin::ALL_OPS then return entity_command(ak_command,@api_node,'access_keys',id_default: 'self')
|
567
|
+
when :do
|
568
|
+
access_key = options.get_next_argument('access key id')
|
569
|
+
ak_info=@api_node.read("access_keys/#{access_key}")[:data]
|
570
|
+
# change API if needed
|
571
|
+
if !access_key.eql?('self')
|
572
|
+
secret=config.vault.get(username: access_key)[:secret] #, url: @api_node.params[:base_url] : TODO: better handle vault
|
573
|
+
@api_node.params[:auth][:username]=access_key
|
574
|
+
@api_node.params[:auth][:password]=secret
|
575
|
+
end
|
576
|
+
command_repo = options.get_next_command(NODE4_COMMANDS)
|
577
|
+
return execute_node_gen4_command(command_repo,ak_info['root_file_id'])
|
578
|
+
end
|
389
579
|
when :service
|
390
|
-
command=options.get_next_command([
|
580
|
+
command = options.get_next_command(%i[list create delete])
|
391
581
|
if [:delete].include?(command)
|
392
|
-
svcid=instance_identifier
|
582
|
+
svcid = instance_identifier
|
393
583
|
end
|
394
584
|
case command
|
395
585
|
when :list
|
396
|
-
resp
|
586
|
+
resp = @api_node.read('rund/services')
|
397
587
|
return { type: :object_list, data: resp[:data]['services'] }
|
398
588
|
when :create
|
399
589
|
# @json:'{"type":"WATCHFOLDERD","run_as":{"user":"user1"}}'
|
400
|
-
params=options.get_next_argument('Run creation data (structure)')
|
401
|
-
resp
|
590
|
+
params = options.get_next_argument('Run creation data (structure)')
|
591
|
+
resp = @api_node.create('rund/services',params)
|
402
592
|
return Main.result_status("#{resp[:data]['id']} created")
|
403
593
|
when :delete
|
404
594
|
@api_node.delete("rund/services/#{svcid}")
|
405
595
|
return Main.result_status("#{svcid} deleted")
|
406
596
|
end
|
407
597
|
when :watch_folder
|
408
|
-
res_class_path='v3/watchfolders'
|
409
|
-
command=options.get_next_command([
|
410
|
-
if [
|
411
|
-
one_res_id=instance_identifier
|
412
|
-
one_res_path="#{res_class_path}/#{one_res_id}"
|
598
|
+
res_class_path = 'v3/watchfolders'
|
599
|
+
command = options.get_next_command(%i[create list show modify delete state])
|
600
|
+
if %i[show modify delete state].include?(command)
|
601
|
+
one_res_id = instance_identifier
|
602
|
+
one_res_path = "#{res_class_path}/#{one_res_id}"
|
413
603
|
end
|
414
604
|
# hum, to avoid: Unable to convert 2016_09_14 configuration
|
415
|
-
@api_node.params[:headers]||={}
|
416
|
-
@api_node.params[:headers]['X-aspera-WF-version']='2017_10_23'
|
605
|
+
@api_node.params[:headers] ||= {}
|
606
|
+
@api_node.params[:headers]['X-aspera-WF-version'] = '2017_10_23'
|
417
607
|
case command
|
418
608
|
when :create
|
419
|
-
resp
|
609
|
+
resp = @api_node.create(res_class_path,options.get_option(:value,is_type: :mandatory))
|
420
610
|
return Main.result_status("#{resp[:data]['id']} created")
|
421
611
|
when :list
|
422
|
-
resp
|
612
|
+
resp = @api_node.read(res_class_path,options.get_option(:value))
|
423
613
|
return { type: :value_list, data: resp[:data]['ids'], name: 'id' }
|
424
614
|
when :show
|
425
615
|
return { type: :single_object, data: @api_node.read(one_res_path)[:data]}
|
426
616
|
when :modify
|
427
|
-
@api_node.update(one_res_path,options.get_option(:value
|
617
|
+
@api_node.update(one_res_path,options.get_option(:value,is_type: :mandatory))
|
428
618
|
return Main.result_status("#{one_res_id} updated")
|
429
619
|
when :delete
|
430
620
|
@api_node.delete(one_res_path)
|
@@ -433,30 +623,30 @@ fields: ['id','status','start_spec.direction','start_spec.remote_user','start_sp
|
|
433
623
|
return { type: :single_object, data: @api_node.read("#{one_res_path}/state")[:data] }
|
434
624
|
end
|
435
625
|
when :central
|
436
|
-
command=options.get_next_command([
|
437
|
-
validator_id=options.get_option(:validator)
|
438
|
-
validation={'validator_id'=>validator_id} unless validator_id.nil?
|
439
|
-
request_data=options.get_option(:value
|
440
|
-
request_data||={}
|
626
|
+
command = options.get_next_command(%i[session file])
|
627
|
+
validator_id = options.get_option(:validator)
|
628
|
+
validation = {'validator_id' => validator_id} unless validator_id.nil?
|
629
|
+
request_data = options.get_option(:value)
|
630
|
+
request_data ||= {}
|
441
631
|
case command
|
442
632
|
when :session
|
443
|
-
command=options.get_next_command([:list])
|
633
|
+
command = options.get_next_command([:list])
|
444
634
|
case command
|
445
635
|
when :list
|
446
|
-
request_data.deep_merge!({'validation'=>validation}) unless validation.nil?
|
447
|
-
resp
|
636
|
+
request_data.deep_merge!({'validation' => validation}) unless validation.nil?
|
637
|
+
resp = @api_node.create('services/rest/transfers/v1/sessions',request_data)
|
448
638
|
return { type: :object_list, data: resp[:data]['session_info_result']['session_info'],
|
449
|
-
fields: [
|
639
|
+
fields: %w[session_uuid status transport direction bytes_transferred]}
|
450
640
|
end
|
451
641
|
when :file
|
452
|
-
command=options.get_next_command([
|
642
|
+
command = options.get_next_command(%i[list modify])
|
453
643
|
case command
|
454
644
|
when :list
|
455
|
-
request_data.deep_merge!({'validation'=>validation}) unless validation.nil?
|
456
|
-
resp
|
457
|
-
resp=JSON.parse(resp) if resp.is_a?(String)
|
645
|
+
request_data.deep_merge!({'validation' => validation}) unless validation.nil?
|
646
|
+
resp = @api_node.create('services/rest/transfers/v1/files',request_data)[:data]
|
647
|
+
resp = JSON.parse(resp) if resp.is_a?(String)
|
458
648
|
Log.dump(:resp,resp)
|
459
|
-
return { type: :object_list, data: resp['file_transfer_info_result']['file_transfer_info'], fields: [
|
649
|
+
return { type: :object_list, data: resp['file_transfer_info_result']['file_transfer_info'], fields: %w[session_uuid file_id status path]}
|
460
650
|
when :modify
|
461
651
|
request_data.deep_merge!(validation) unless validation.nil?
|
462
652
|
@api_node.update('services/rest/transfers/v1/files',request_data)
|
@@ -464,17 +654,17 @@ fields: ['session_uuid','status','transport','direction','bytes_transferred']}
|
|
464
654
|
end
|
465
655
|
end
|
466
656
|
when :asperabrowser
|
467
|
-
browse_params={
|
468
|
-
'nodeUser' => options.get_option(:username
|
469
|
-
'nodePW' => options.get_option(:password
|
470
|
-
'nodeURL' => options.get_option(:url
|
657
|
+
browse_params = {
|
658
|
+
'nodeUser' => options.get_option(:username,is_type: :mandatory),
|
659
|
+
'nodePW' => options.get_option(:password,is_type: :mandatory),
|
660
|
+
'nodeURL' => options.get_option(:url,is_type: :mandatory)
|
471
661
|
}
|
472
662
|
# encode parameters so that it looks good in url
|
473
|
-
encoded_params=Base64.strict_encode64(Zlib::Deflate.deflate(JSON.generate(browse_params))).gsub(/=+$/, '').tr('+/', '-_').reverse
|
474
|
-
OpenApplication.instance.uri(options.get_option(:asperabrowserurl)+'?goto='+encoded_params)
|
663
|
+
encoded_params = Base64.strict_encode64(Zlib::Deflate.deflate(JSON.generate(browse_params))).gsub(/=+$/, '').tr('+/', '-_').reverse
|
664
|
+
OpenApplication.instance.uri(options.get_option(:asperabrowserurl) + '?goto=' + encoded_params)
|
475
665
|
return Main.result_status('done')
|
476
666
|
when :basic_token
|
477
|
-
return Main.result_status(
|
667
|
+
return Main.result_status(Rest.basic_creds(options.get_option(:username,is_type: :mandatory),options.get_option(:password,is_type: :mandatory)))
|
478
668
|
end # case command
|
479
669
|
raise 'ERROR: shall not reach this line'
|
480
670
|
end # execute_action
|