aspera-cli 4.7.0 → 4.8.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 +1 -0
- data/README.md +844 -861
- data/bin/ascli +20 -1
- data/bin/asession +37 -34
- data/docs/test_env.conf +11 -3
- data/examples/aoc.rb +13 -12
- data/examples/dascli +26 -0
- data/examples/faspex4.rb +34 -29
- data/examples/transfer.rb +30 -29
- data/lib/aspera/aoc.rb +151 -143
- data/lib/aspera/ascmd.rb +56 -45
- data/lib/aspera/ats_api.rb +6 -5
- data/lib/aspera/cli/basic_auth_plugin.rb +18 -16
- data/lib/aspera/cli/extended_value.rb +32 -30
- data/lib/aspera/cli/formater.rb +103 -111
- data/lib/aspera/cli/info.rb +2 -1
- 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 +106 -89
- data/lib/aspera/cli/manager.rb +96 -85
- data/lib/aspera/cli/plugin.rb +50 -32
- data/lib/aspera/cli/plugins/alee.rb +6 -5
- data/lib/aspera/cli/plugins/aoc.rb +521 -426
- 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 +483 -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 +201 -168
- data/lib/aspera/cli/plugins/faspex5.rb +109 -74
- data/lib/aspera/cli/plugins/node.rb +378 -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 +94 -93
- data/lib/aspera/cli/plugins/shares.rb +42 -28
- data/lib/aspera/cli/plugins/sync.rb +15 -14
- data/lib/aspera/cli/transfer_agent.rb +56 -52
- 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 +18 -8
- data/lib/aspera/fasp/agent_base.rb +26 -23
- 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 +122 -114
- data/lib/aspera/fasp/listener.rb +1 -0
- data/lib/aspera/fasp/parameters.rb +44 -41
- 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 +10 -12
- data/lib/aspera/id_generator.rb +8 -7
- data/lib/aspera/keychain/encrypted_hash.rb +60 -45
- data/lib/aspera/keychain/macos_security.rb +26 -24
- data/lib/aspera/log.rb +34 -38
- data/lib/aspera/nagios.rb +14 -13
- data/lib/aspera/node.rb +19 -19
- data/lib/aspera/oauth.rb +121 -101
- data/lib/aspera/open_application.rb +6 -5
- data/lib/aspera/persistency_action_once.rb +9 -8
- data/lib/aspera/persistency_folder.rb +10 -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 +25 -23
- data/lib/aspera/rest.rb +73 -74
- data/lib/aspera/rest_call_error.rb +1 -0
- data/lib/aspera/rest_error_analyzer.rb +11 -9
- data/lib/aspera/rest_errors_aspera.rb +5 -4
- data/lib/aspera/secret_hider.rb +68 -0
- data/lib/aspera/ssh.rb +12 -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 +11 -14
- data/lib/aspera/web_auth.rb +17 -15
- data.tar.gz.sig +0 -0
- metadata +117 -34
- metadata.gz.sig +2 -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,352 @@ 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
|
+
return {api: @api_node, file_id: id}
|
278
|
+
end
|
279
|
+
|
280
|
+
NODE4_COMMANDS = %i[browse find mkdir rename delete upload download http_node_download file permission bearer_token_node node_info].freeze
|
281
|
+
|
282
|
+
def execute_node_gen4_command(command_repo, top_file_id)
|
283
|
+
#@api_node
|
284
|
+
case command_repo
|
285
|
+
when :node_info
|
286
|
+
thepath = options.get_next_argument('path')
|
287
|
+
apifid = resolve_api_fid(top_file_id,thepath)
|
288
|
+
apifid[:api] = aoc_api.get_node_api(apifid[:node_info], use_secret: false)
|
289
|
+
return {type: :single_object,data: {
|
290
|
+
url: apifid[:node_info]['url'],
|
291
|
+
username: apifid[:node_info]['access_key'],
|
292
|
+
password: apifid[:api].oauth_token,
|
293
|
+
root_id: apifid[:file_id]
|
294
|
+
}}
|
295
|
+
when :browse
|
296
|
+
thepath = options.get_next_argument('path')
|
297
|
+
apifid = resolve_api_fid(top_file_id,thepath)
|
298
|
+
file_info = apifid[:api].read("files/#{apifid[:file_id]}")[:data]
|
299
|
+
if file_info['type'].eql?('folder')
|
300
|
+
result = apifid[:api].read("files/#{apifid[:file_id]}/files",options.get_option(:value))
|
301
|
+
items = result[:data]
|
302
|
+
self.format.display_status("Items: #{result[:data].length}/#{result[:http]['X-Total-Count']}")
|
303
|
+
else
|
304
|
+
items = [file_info]
|
305
|
+
end
|
306
|
+
return {type: :object_list,data: items,fields: %w[name type recursive_size size modified_time access_level]}
|
307
|
+
when :find
|
308
|
+
thepath = options.get_next_argument('path')
|
309
|
+
apifid = resolve_api_fid(top_file_id,thepath)
|
310
|
+
test_block = Aspera::Node.file_matcher(options.get_option(:value))
|
311
|
+
return {type: :object_list,data: aoc_api.find_files(apifid,test_block),fields: ['path']}
|
312
|
+
when :mkdir
|
313
|
+
thepath = options.get_next_argument('path')
|
314
|
+
containing_folder_path = thepath.split(AoC::PATH_SEPARATOR)
|
315
|
+
new_folder = containing_folder_path.pop
|
316
|
+
apifid = resolve_api_fid(top_file_id,containing_folder_path.join(AoC::PATH_SEPARATOR))
|
317
|
+
result = apifid[:api].create("files/#{apifid[:file_id]}/files",{name: new_folder,type: :folder})[:data]
|
318
|
+
return Main.result_status("created: #{result['name']} (id=#{result['id']})")
|
319
|
+
when :rename
|
320
|
+
thepath = options.get_next_argument('source path')
|
321
|
+
newname = options.get_next_argument('new name')
|
322
|
+
apifid = resolve_api_fid(top_file_id,thepath)
|
323
|
+
result = apifid[:api].update("files/#{apifid[:file_id]}",{name: newname})[:data]
|
324
|
+
return Main.result_status("renamed #{thepath} to #{newname}")
|
325
|
+
when :delete
|
326
|
+
thepath = options.get_next_argument('path')
|
327
|
+
return do_bulk_operation(thepath,'deleted','path') do |l_path|
|
328
|
+
raise "expecting String (path), got #{l_path.class.name} (#{l_path})" unless l_path.is_a?(String)
|
329
|
+
apifid = resolve_api_fid(top_file_id,l_path)
|
330
|
+
result = apifid[:api].delete("files/#{apifid[:file_id]}")[:data]
|
331
|
+
{'path' => l_path}
|
332
|
+
end
|
333
|
+
when :upload
|
334
|
+
apifid = resolve_api_fid(top_file_id,transfer.destination_folder(Fasp::TransferSpec::DIRECTION_SEND))
|
335
|
+
add_ts = {'tags' => {'aspera' => {'files' => {'parentCwd' => "#{apifid[:node_info]['id']}:#{apifid[:file_id]}"}}}}
|
336
|
+
return Main.result_transfer(transfer_start(AoC::FILES_APP,Fasp::TransferSpec::DIRECTION_SEND,apifid,add_ts))
|
337
|
+
when :download
|
338
|
+
source_paths = transfer.ts_source_paths
|
339
|
+
# special case for AoC : all files must be in same folder
|
340
|
+
source_folder = source_paths.shift['source']
|
341
|
+
# if a single file: split into folder and path
|
342
|
+
if source_paths.empty?
|
343
|
+
source_folder = source_folder.split(AoC::PATH_SEPARATOR)
|
344
|
+
source_paths = [{'source' => source_folder.pop}]
|
345
|
+
source_folder = source_folder.join(AoC::PATH_SEPARATOR)
|
346
|
+
end
|
347
|
+
apifid = resolve_api_fid(top_file_id,source_folder)
|
348
|
+
# override paths with just filename
|
349
|
+
add_ts = {'tags' => {'aspera' => {'files' => {'parentCwd' => "#{apifid[:node_info]['id']}:#{apifid[:file_id]}"}}}}
|
350
|
+
add_ts['paths'] = source_paths
|
351
|
+
return Main.result_transfer(transfer_start(AoC::FILES_APP,Fasp::TransferSpec::DIRECTION_RECEIVE,apifid,add_ts))
|
352
|
+
when :http_node_download
|
353
|
+
source_paths = transfer.ts_source_paths
|
354
|
+
source_folder = source_paths.shift['source']
|
355
|
+
if source_paths.empty?
|
356
|
+
source_folder = source_folder.split(AoC::PATH_SEPARATOR)
|
357
|
+
source_paths = [{'source' => source_folder.pop}]
|
358
|
+
source_folder = source_folder.join(AoC::PATH_SEPARATOR)
|
359
|
+
end
|
360
|
+
raise CliBadArgument,'one file at a time only in HTTP mode' if source_paths.length > 1
|
361
|
+
file_name = source_paths.first['source']
|
362
|
+
apifid = resolve_api_fid(top_file_id,File.join(source_folder,file_name))
|
363
|
+
apifid[:api].call(
|
364
|
+
operation: 'GET',
|
365
|
+
subpath: "files/#{apifid[:file_id]}/content",
|
366
|
+
save_to_file: File.join(transfer.destination_folder(Fasp::TransferSpec::DIRECTION_RECEIVE),file_name))
|
367
|
+
return Main.result_status("downloaded: #{file_name}")
|
368
|
+
when :permission
|
369
|
+
command_perm = options.get_next_command(%i[list create])
|
370
|
+
case command_perm
|
371
|
+
when :list
|
372
|
+
# generic options : TODO: as arg ? option_url_query
|
373
|
+
list_options ||= {'include' => ['[]','access_level','permission_count']}
|
374
|
+
# special value: ALL will show all permissions
|
375
|
+
if !VAL_ALL.eql?(apifid[:file_id])
|
376
|
+
# add which one to get
|
377
|
+
list_options['file_id'] = apifid[:file_id]
|
378
|
+
list_options['inherited'] ||= false
|
379
|
+
end
|
380
|
+
items = apifid[:api].read('permissions',list_options)[:data]
|
381
|
+
return {type: :object_list,data: items}
|
382
|
+
when :create
|
383
|
+
#create_param=self.options.get_next_argument('creation data (Hash)')
|
384
|
+
set_workspace_info
|
385
|
+
access_id = "#{ID_AK_ADMIN}_WS_#{@workspace_id}"
|
386
|
+
apifid[:node_info]
|
387
|
+
params = {
|
388
|
+
'file_id' => apifid[:file_id], # mandatory
|
389
|
+
'access_type' => 'user', # mandatory: user or group
|
390
|
+
'access_id' => access_id, # id of user or group
|
391
|
+
'access_levels' => Aspera::Node::ACCESS_LEVELS,
|
392
|
+
'tags' => {'aspera' => {'files' => {'workspace' => {
|
393
|
+
'id' => @workspace_id,
|
394
|
+
'workspace_name' => @workspace_name,
|
395
|
+
'user_name' => aoc_api.user_info['name'],
|
396
|
+
'shared_by_user_id' => aoc_api.user_info['id'],
|
397
|
+
'shared_by_name' => aoc_api.user_info['name'],
|
398
|
+
'shared_by_email' => aoc_api.user_info['email'],
|
399
|
+
'shared_with_name' => access_id,
|
400
|
+
'access_key' => apifid[:node_info]['access_key'],
|
401
|
+
'node' => apifid[:node_info]['name']}}}}}
|
402
|
+
item = apifid[:api].create('permissions',params)[:data]
|
403
|
+
return {type: :single_object,data: item}
|
404
|
+
else raise "internal error:shall not reach here (#{command_perm})"
|
405
|
+
end
|
406
|
+
when :file
|
407
|
+
command_node_file = options.get_next_command(%i[show modify])
|
408
|
+
file_path = options.get_option(:path)
|
409
|
+
apifid =
|
410
|
+
if !file_path.nil?
|
411
|
+
resolve_api_fid(top_file_id,file_path) # TODO: allow follow link ?
|
412
|
+
else
|
413
|
+
{node_info: top_file_id[:node_info],file_id: instance_identifier}
|
414
|
+
end
|
415
|
+
case command_node_file
|
416
|
+
when :show
|
417
|
+
items = apifid[:api].read("files/#{apifid[:file_id]}")[:data]
|
418
|
+
return {type: :single_object,data: items}
|
419
|
+
when :modify
|
420
|
+
update_param = options.get_next_argument('update data (Hash)')
|
421
|
+
res = apifid[:api].update("files/#{apifid[:file_id]}",update_param)[:data]
|
422
|
+
return {type: :single_object,data: res}
|
423
|
+
else raise "internal error:shall not reach here (#{command_node_file})"
|
424
|
+
end
|
425
|
+
end # command_repo
|
426
|
+
raise 'ERR'
|
427
|
+
end # execute_node_gen4_command
|
428
|
+
|
261
429
|
def execute_async
|
262
|
-
command=options.get_next_command([
|
430
|
+
command = options.get_next_command(%i[list delete files show counters bandwidth])
|
263
431
|
unless command.eql?(:list)
|
264
|
-
asyncname=options.get_option(:sync_name
|
432
|
+
asyncname = options.get_option(:sync_name)
|
265
433
|
if asyncname.nil?
|
266
|
-
asyncid=instance_identifier
|
267
|
-
if asyncid.eql?('ALL') && [
|
268
|
-
asyncids
|
434
|
+
asyncid = instance_identifier
|
435
|
+
if asyncid.eql?('ALL') && %i[show delete].include?(command)
|
436
|
+
asyncids = @api_node.read('async/list')[:data]['sync_ids']
|
269
437
|
else
|
270
438
|
Integer(asyncid) # must be integer
|
271
|
-
asyncids=[asyncid]
|
439
|
+
asyncids = [asyncid]
|
272
440
|
end
|
273
441
|
else
|
274
|
-
asyncids
|
275
|
-
summaries
|
276
|
-
selected=summaries.
|
442
|
+
asyncids = @api_node.read('async/list')[:data]['sync_ids']
|
443
|
+
summaries = @api_node.create('async/summary',{'syncs' => asyncids})[:data]['sync_summaries']
|
444
|
+
selected = summaries.find{|s|s['name'].eql?(asyncname)}
|
277
445
|
raise "no such sync: #{asyncname}" if selected.nil?
|
278
|
-
asyncid=selected['snid']
|
279
|
-
asyncids=[asyncid]
|
446
|
+
asyncid = selected['snid']
|
447
|
+
asyncids = [asyncid]
|
280
448
|
end
|
281
|
-
pdata={'syncs' => asyncids}
|
449
|
+
pdata = {'syncs' => asyncids}
|
282
450
|
end
|
283
451
|
case command
|
284
452
|
when :list
|
285
|
-
resp
|
453
|
+
resp = @api_node.read('async/list')[:data]['sync_ids']
|
286
454
|
return { type: :value_list, data: resp, name: 'id' }
|
287
455
|
when :show
|
288
|
-
resp
|
456
|
+
resp = @api_node.create('async/summary',pdata)[:data]['sync_summaries']
|
289
457
|
return Main.result_empty if resp.empty?
|
290
|
-
return { type: :object_list, data: resp, fields: [
|
458
|
+
return { type: :object_list, data: resp, fields: %w[snid name local_dir remote_dir] } if asyncid.eql?('ALL')
|
291
459
|
return { type: :single_object, data: resp.first }
|
292
460
|
when :delete
|
293
|
-
resp
|
461
|
+
resp = @api_node.create('async/delete',pdata)[:data]
|
294
462
|
return { type: :single_object, data: resp, name: 'id' }
|
295
463
|
when :bandwidth
|
296
|
-
pdata['seconds']=100 # TODO: as parameter with --value
|
297
|
-
resp
|
298
|
-
data=resp['bandwidth_data']
|
464
|
+
pdata['seconds'] = 100 # TODO: as parameter with --value
|
465
|
+
resp = @api_node.create('async/bandwidth',pdata)[:data]
|
466
|
+
data = resp['bandwidth_data']
|
299
467
|
return Main.result_empty if data.empty?
|
300
|
-
data=data.first[asyncid]['data']
|
468
|
+
data = data.first[asyncid]['data']
|
301
469
|
return { type: :object_list, data: data, name: 'id' }
|
302
470
|
when :files
|
303
471
|
# count int
|
304
472
|
# filename str
|
305
473
|
# skip int
|
306
474
|
# status int
|
307
|
-
filter=options.get_option(:value
|
475
|
+
filter = options.get_option(:value)
|
308
476
|
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
|
-
|
477
|
+
resp = @api_node.create('async/files',pdata)[:data]
|
478
|
+
data = resp['sync_files']
|
479
|
+
data = data.first[asyncid] unless data.empty?
|
480
|
+
iteration_data = []
|
481
|
+
skip_ids_persistency = nil
|
482
|
+
if options.get_option(:once_only,is_type: :mandatory)
|
483
|
+
skip_ids_persistency = PersistencyActionOnce.new(
|
484
|
+
manager: @agents[:persistency],
|
485
|
+
data: iteration_data,
|
486
|
+
id: IdGenerator.from_list([
|
487
|
+
'sync_files',
|
488
|
+
options.get_option(:url,is_type: :mandatory),
|
489
|
+
options.get_option(:username,is_type: :mandatory),
|
490
|
+
asyncid]))
|
319
491
|
unless iteration_data.first.nil?
|
320
|
-
data.select!{|l| l['fnid'].to_i>iteration_data.first}
|
492
|
+
data.select!{|l| l['fnid'].to_i > iteration_data.first}
|
321
493
|
end
|
322
|
-
iteration_data[0]=data.last['fnid'].to_i unless data.empty?
|
494
|
+
iteration_data[0] = data.last['fnid'].to_i unless data.empty?
|
323
495
|
end
|
324
496
|
return Main.result_empty if data.empty?
|
325
|
-
skip_ids_persistency
|
497
|
+
skip_ids_persistency&.save
|
326
498
|
return { type: :object_list, data: data, name: 'id' }
|
327
499
|
when :counters
|
328
|
-
resp
|
500
|
+
resp = @api_node.create('async/counters',pdata)[:data]['sync_counters'].first[asyncid].last
|
329
501
|
return Main.result_empty if resp.nil?
|
330
502
|
return { type: :single_object, data: resp }
|
331
503
|
end
|
332
504
|
end
|
333
505
|
|
334
|
-
ACTIONS=[
|
506
|
+
ACTIONS = %i[postprocess stream transfer cleanup forward access_key watch_folder service async central asperabrowser basic_token].concat(COMMON_ACTIONS).freeze
|
335
507
|
|
336
508
|
def execute_action(command=nil,prefix_path=nil)
|
337
|
-
command||=options.get_next_command(ACTIONS)
|
509
|
+
command ||= options.get_next_command(ACTIONS)
|
338
510
|
case command
|
339
511
|
when *COMMON_ACTIONS then return execute_simple_common(command,prefix_path)
|
340
|
-
when :async then return execute_async
|
512
|
+
when :async then return execute_async
|
341
513
|
when :stream
|
342
|
-
command=options.get_next_command([
|
514
|
+
command = options.get_next_command(%i[list create show modify cancel])
|
343
515
|
case command
|
344
516
|
when :list
|
345
|
-
resp
|
346
|
-
return { type: :object_list, data: resp[:data], fields: [
|
517
|
+
resp = @api_node.read('ops/transfers',options.get_option(:value))
|
518
|
+
return { type: :object_list, data: resp[:data], fields: %w[id status] } # TODO: useful?
|
347
519
|
when :create
|
348
|
-
resp
|
520
|
+
resp = @api_node.create('streams',options.get_option(:value,is_type: :mandatory))
|
349
521
|
return { type: :single_object, data: resp[:data] }
|
350
522
|
when :show
|
351
|
-
trid=options.get_next_argument('transfer id')
|
352
|
-
resp
|
523
|
+
trid = options.get_next_argument('transfer id')
|
524
|
+
resp = @api_node.read('ops/transfers/' + trid)
|
353
525
|
return { type: :other_struct, data: resp[:data] }
|
354
526
|
when :modify
|
355
|
-
trid=options.get_next_argument('transfer id')
|
356
|
-
resp
|
527
|
+
trid = options.get_next_argument('transfer id')
|
528
|
+
resp = @api_node.update('streams/' + trid,options.get_option(:value,is_type: :mandatory))
|
357
529
|
return { type: :other_struct, data: resp[:data] }
|
358
530
|
when :cancel
|
359
|
-
trid=options.get_next_argument('transfer id')
|
360
|
-
resp
|
531
|
+
trid = options.get_next_argument('transfer id')
|
532
|
+
resp = @api_node.cancel('streams/' + trid)
|
361
533
|
return { type: :other_struct, data: resp[:data] }
|
362
534
|
else
|
363
535
|
raise 'error'
|
364
536
|
end
|
365
537
|
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}"
|
538
|
+
command = options.get_next_command(%i[list cancel show])
|
539
|
+
res_class_path = 'ops/transfers'
|
540
|
+
if %i[cancel show].include?(command)
|
541
|
+
one_res_id = instance_identifier
|
542
|
+
one_res_path = "#{res_class_path}/#{one_res_id}"
|
371
543
|
end
|
372
544
|
case command
|
373
545
|
when :list
|
374
546
|
# could use ? subpath: 'transfers'
|
375
|
-
resp
|
376
|
-
return {
|
377
|
-
|
547
|
+
resp = @api_node.read(res_class_path,options.get_option(:value))
|
548
|
+
return {
|
549
|
+
type: :object_list,
|
550
|
+
data: resp[:data],
|
551
|
+
fields: %w[id status start_spec.direction start_spec.remote_user start_spec.remote_host start_spec.destination_path]
|
552
|
+
}
|
378
553
|
when :cancel
|
379
|
-
resp
|
554
|
+
resp = @api_node.cancel(one_res_path)
|
380
555
|
return { type: :other_struct, data: resp[:data] }
|
381
556
|
when :show
|
382
|
-
resp
|
557
|
+
resp = @api_node.read(one_res_path)
|
383
558
|
return { type: :other_struct, data: resp[:data] }
|
384
559
|
else
|
385
560
|
raise 'error'
|
386
561
|
end
|
387
562
|
when :access_key
|
388
|
-
|
563
|
+
ak_command = options.get_next_command([Plugin::ALL_OPS,:do].flatten)
|
564
|
+
case ak_command
|
565
|
+
when *Plugin::ALL_OPS then return entity_command(ak_command,@api_node,'access_keys',id_default: 'self')
|
566
|
+
when :do
|
567
|
+
access_key = options.get_next_argument('access key id')
|
568
|
+
ak_info=@api_node.read("access_keys/#{access_key}")[:data]
|
569
|
+
# change API if needed
|
570
|
+
if !access_key.eql?('self')
|
571
|
+
secret=config.vault.get(username: access_key)[:secret] #, url: @api_node.params[:base_url] : TODO: better handle vault
|
572
|
+
@api_node.params[:username]=access_key
|
573
|
+
@api_node.params[:password]=secret
|
574
|
+
end
|
575
|
+
command_repo = options.get_next_command(NODE4_COMMANDS)
|
576
|
+
return execute_node_gen4_command(command_repo,ak_info['root_file_id'])
|
577
|
+
end
|
389
578
|
when :service
|
390
|
-
command=options.get_next_command([
|
579
|
+
command = options.get_next_command(%i[list create delete])
|
391
580
|
if [:delete].include?(command)
|
392
|
-
svcid=instance_identifier
|
581
|
+
svcid = instance_identifier
|
393
582
|
end
|
394
583
|
case command
|
395
584
|
when :list
|
396
|
-
resp
|
585
|
+
resp = @api_node.read('rund/services')
|
397
586
|
return { type: :object_list, data: resp[:data]['services'] }
|
398
587
|
when :create
|
399
588
|
# @json:'{"type":"WATCHFOLDERD","run_as":{"user":"user1"}}'
|
400
|
-
params=options.get_next_argument('Run creation data (structure)')
|
401
|
-
resp
|
589
|
+
params = options.get_next_argument('Run creation data (structure)')
|
590
|
+
resp = @api_node.create('rund/services',params)
|
402
591
|
return Main.result_status("#{resp[:data]['id']} created")
|
403
592
|
when :delete
|
404
593
|
@api_node.delete("rund/services/#{svcid}")
|
405
594
|
return Main.result_status("#{svcid} deleted")
|
406
595
|
end
|
407
596
|
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}"
|
597
|
+
res_class_path = 'v3/watchfolders'
|
598
|
+
command = options.get_next_command(%i[create list show modify delete state])
|
599
|
+
if %i[show modify delete state].include?(command)
|
600
|
+
one_res_id = instance_identifier
|
601
|
+
one_res_path = "#{res_class_path}/#{one_res_id}"
|
413
602
|
end
|
414
603
|
# 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'
|
604
|
+
@api_node.params[:headers] ||= {}
|
605
|
+
@api_node.params[:headers]['X-aspera-WF-version'] = '2017_10_23'
|
417
606
|
case command
|
418
607
|
when :create
|
419
|
-
resp
|
608
|
+
resp = @api_node.create(res_class_path,options.get_option(:value,is_type: :mandatory))
|
420
609
|
return Main.result_status("#{resp[:data]['id']} created")
|
421
610
|
when :list
|
422
|
-
resp
|
611
|
+
resp = @api_node.read(res_class_path,options.get_option(:value))
|
423
612
|
return { type: :value_list, data: resp[:data]['ids'], name: 'id' }
|
424
613
|
when :show
|
425
614
|
return { type: :single_object, data: @api_node.read(one_res_path)[:data]}
|
426
615
|
when :modify
|
427
|
-
@api_node.update(one_res_path,options.get_option(:value
|
616
|
+
@api_node.update(one_res_path,options.get_option(:value,is_type: :mandatory))
|
428
617
|
return Main.result_status("#{one_res_id} updated")
|
429
618
|
when :delete
|
430
619
|
@api_node.delete(one_res_path)
|
@@ -433,30 +622,30 @@ fields: ['id','status','start_spec.direction','start_spec.remote_user','start_sp
|
|
433
622
|
return { type: :single_object, data: @api_node.read("#{one_res_path}/state")[:data] }
|
434
623
|
end
|
435
624
|
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||={}
|
625
|
+
command = options.get_next_command(%i[session file])
|
626
|
+
validator_id = options.get_option(:validator)
|
627
|
+
validation = {'validator_id' => validator_id} unless validator_id.nil?
|
628
|
+
request_data = options.get_option(:value)
|
629
|
+
request_data ||= {}
|
441
630
|
case command
|
442
631
|
when :session
|
443
|
-
command=options.get_next_command([:list])
|
632
|
+
command = options.get_next_command([:list])
|
444
633
|
case command
|
445
634
|
when :list
|
446
|
-
request_data.deep_merge!({'validation'=>validation}) unless validation.nil?
|
447
|
-
resp
|
635
|
+
request_data.deep_merge!({'validation' => validation}) unless validation.nil?
|
636
|
+
resp = @api_node.create('services/rest/transfers/v1/sessions',request_data)
|
448
637
|
return { type: :object_list, data: resp[:data]['session_info_result']['session_info'],
|
449
|
-
fields: [
|
638
|
+
fields: %w[session_uuid status transport direction bytes_transferred]}
|
450
639
|
end
|
451
640
|
when :file
|
452
|
-
command=options.get_next_command([
|
641
|
+
command = options.get_next_command(%i[list modify])
|
453
642
|
case command
|
454
643
|
when :list
|
455
|
-
request_data.deep_merge!({'validation'=>validation}) unless validation.nil?
|
456
|
-
resp
|
457
|
-
resp=JSON.parse(resp) if resp.is_a?(String)
|
644
|
+
request_data.deep_merge!({'validation' => validation}) unless validation.nil?
|
645
|
+
resp = @api_node.create('services/rest/transfers/v1/files',request_data)[:data]
|
646
|
+
resp = JSON.parse(resp) if resp.is_a?(String)
|
458
647
|
Log.dump(:resp,resp)
|
459
|
-
return { type: :object_list, data: resp['file_transfer_info_result']['file_transfer_info'], fields: [
|
648
|
+
return { type: :object_list, data: resp['file_transfer_info_result']['file_transfer_info'], fields: %w[session_uuid file_id status path]}
|
460
649
|
when :modify
|
461
650
|
request_data.deep_merge!(validation) unless validation.nil?
|
462
651
|
@api_node.update('services/rest/transfers/v1/files',request_data)
|
@@ -464,17 +653,17 @@ fields: ['session_uuid','status','transport','direction','bytes_transferred']}
|
|
464
653
|
end
|
465
654
|
end
|
466
655
|
when :asperabrowser
|
467
|
-
browse_params={
|
468
|
-
'nodeUser' => options.get_option(:username
|
469
|
-
'nodePW' => options.get_option(:password
|
470
|
-
'nodeURL' => options.get_option(:url
|
656
|
+
browse_params = {
|
657
|
+
'nodeUser' => options.get_option(:username,is_type: :mandatory),
|
658
|
+
'nodePW' => options.get_option(:password,is_type: :mandatory),
|
659
|
+
'nodeURL' => options.get_option(:url,is_type: :mandatory)
|
471
660
|
}
|
472
661
|
# 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)
|
662
|
+
encoded_params = Base64.strict_encode64(Zlib::Deflate.deflate(JSON.generate(browse_params))).gsub(/=+$/, '').tr('+/', '-_').reverse
|
663
|
+
OpenApplication.instance.uri(options.get_option(:asperabrowserurl) + '?goto=' + encoded_params)
|
475
664
|
return Main.result_status('done')
|
476
665
|
when :basic_token
|
477
|
-
return Main.result_status(
|
666
|
+
return Main.result_status(Rest.basic_creds(options.get_option(:username,is_type: :mandatory),options.get_option(:password,is_type: :mandatory)))
|
478
667
|
end # case command
|
479
668
|
raise 'ERROR: shall not reach this line'
|
480
669
|
end # execute_action
|