aspera-cli 4.5.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 +1894 -1574
- data/bin/ascli +21 -1
- data/bin/asession +38 -34
- data/docs/test_env.conf +14 -3
- data/examples/aoc.rb +17 -15
- data/examples/dascli +26 -0
- data/examples/faspex4.rb +42 -35
- data/examples/proxy.pac +1 -1
- data/examples/transfer.rb +38 -37
- data/lib/aspera/aoc.rb +245 -205
- data/lib/aspera/ascmd.rb +111 -90
- data/lib/aspera/ats_api.rb +16 -14
- data/lib/aspera/cli/basic_auth_plugin.rb +19 -18
- data/lib/aspera/cli/extended_value.rb +50 -39
- data/lib/aspera/cli/formater.rb +161 -135
- data/lib/aspera/cli/info.rb +18 -0
- data/lib/aspera/cli/listener/line_dump.rb +4 -2
- data/lib/aspera/cli/listener/logger.rb +3 -1
- data/lib/aspera/cli/listener/progress.rb +20 -21
- data/lib/aspera/cli/listener/progress_multi.rb +29 -31
- data/lib/aspera/cli/main.rb +194 -183
- data/lib/aspera/cli/manager.rb +213 -206
- data/lib/aspera/cli/plugin.rb +71 -49
- data/lib/aspera/cli/plugins/alee.rb +8 -7
- data/lib/aspera/cli/plugins/aoc.rb +675 -558
- data/lib/aspera/cli/plugins/ats.rb +116 -109
- data/lib/aspera/cli/plugins/bss.rb +35 -34
- data/lib/aspera/cli/plugins/config.rb +722 -542
- data/lib/aspera/cli/plugins/console.rb +28 -22
- data/lib/aspera/cli/plugins/cos.rb +28 -37
- data/lib/aspera/cli/plugins/faspex.rb +281 -227
- data/lib/aspera/cli/plugins/faspex5.rb +129 -84
- data/lib/aspera/cli/plugins/node.rb +426 -232
- data/lib/aspera/cli/plugins/orchestrator.rb +106 -98
- data/lib/aspera/cli/plugins/preview.rb +196 -191
- data/lib/aspera/cli/plugins/server.rb +131 -126
- data/lib/aspera/cli/plugins/shares.rb +49 -36
- data/lib/aspera/cli/plugins/sync.rb +27 -28
- data/lib/aspera/cli/transfer_agent.rb +84 -79
- data/lib/aspera/cli/version.rb +3 -1
- data/lib/aspera/colors.rb +37 -28
- data/lib/aspera/command_line_builder.rb +84 -63
- data/lib/aspera/cos_node.rb +68 -34
- data/lib/aspera/data_repository.rb +4 -2
- data/lib/aspera/environment.rb +61 -46
- data/lib/aspera/fasp/agent_base.rb +36 -31
- data/lib/aspera/fasp/agent_connect.rb +44 -37
- data/lib/aspera/fasp/agent_direct.rb +101 -104
- data/lib/aspera/fasp/agent_httpgw.rb +91 -90
- data/lib/aspera/fasp/agent_node.rb +36 -33
- data/lib/aspera/fasp/agent_trsdk.rb +28 -31
- data/lib/aspera/fasp/error.rb +3 -1
- data/lib/aspera/fasp/error_info.rb +81 -54
- data/lib/aspera/fasp/installation.rb +171 -151
- data/lib/aspera/fasp/listener.rb +2 -0
- data/lib/aspera/fasp/parameters.rb +105 -111
- data/lib/aspera/fasp/parameters.yaml +305 -249
- data/lib/aspera/fasp/resume_policy.rb +20 -20
- data/lib/aspera/fasp/transfer_spec.rb +27 -0
- data/lib/aspera/fasp/uri.rb +31 -29
- data/lib/aspera/faspex_gw.rb +95 -118
- data/lib/aspera/hash_ext.rb +12 -13
- data/lib/aspera/id_generator.rb +11 -9
- data/lib/aspera/keychain/encrypted_hash.rb +73 -57
- data/lib/aspera/keychain/macos_security.rb +27 -29
- data/lib/aspera/log.rb +40 -39
- data/lib/aspera/nagios.rb +24 -22
- data/lib/aspera/node.rb +38 -30
- data/lib/aspera/oauth.rb +217 -248
- data/lib/aspera/open_application.rb +9 -7
- data/lib/aspera/persistency_action_once.rb +15 -14
- data/lib/aspera/persistency_folder.rb +15 -18
- data/lib/aspera/preview/file_types.rb +266 -270
- data/lib/aspera/preview/generator.rb +94 -92
- data/lib/aspera/preview/image_error.png +0 -0
- data/lib/aspera/preview/options.rb +20 -17
- data/lib/aspera/preview/utils.rb +99 -102
- data/lib/aspera/preview/video_error.png +0 -0
- data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
- data/lib/aspera/proxy_auto_config.rb +114 -21
- data/lib/aspera/rest.rb +144 -142
- data/lib/aspera/rest_call_error.rb +3 -2
- data/lib/aspera/rest_error_analyzer.rb +31 -31
- data/lib/aspera/rest_errors_aspera.rb +18 -16
- data/lib/aspera/secret_hider.rb +68 -0
- data/lib/aspera/ssh.rb +20 -16
- data/lib/aspera/sync.rb +57 -54
- data/lib/aspera/temp_file_manager.rb +20 -14
- data/lib/aspera/timer_limiter.rb +10 -8
- data/lib/aspera/uri_reader.rb +14 -15
- data/lib/aspera/web_auth.rb +85 -80
- data.tar.gz.sig +0 -0
- metadata +169 -40
- metadata.gz.sig +2 -0
- data/bin/dascli +0 -13
- data/docs/Makefile +0 -63
- data/docs/README.erb.md +0 -4221
- data/docs/README.md +0 -13
- data/docs/diagrams.txt +0 -49
- data/docs/doc_tools.rb +0 -58
- data/lib/aspera/cli/plugins/shares2.rb +0 -114
- data/lib/aspera/fasp/default.rb +0 -17
@@ -1,8 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'aspera/cli/basic_auth_plugin'
|
2
4
|
require 'aspera/nagios'
|
3
5
|
require 'aspera/hash_ext'
|
4
6
|
require 'aspera/id_generator'
|
5
7
|
require 'aspera/node'
|
8
|
+
require 'aspera/fasp/transfer_spec'
|
6
9
|
require 'base64'
|
7
10
|
require 'zlib'
|
8
11
|
|
@@ -12,65 +15,66 @@ module Aspera
|
|
12
15
|
class Node < BasicAuthPlugin
|
13
16
|
class << self
|
14
17
|
def detect(base_url)
|
15
|
-
api=Rest.new({:base_url
|
16
|
-
result=api.call({:
|
18
|
+
api = Rest.new({ base_url: base_url})
|
19
|
+
result = api.call({ operation: 'GET', subpath: 'ping'})
|
17
20
|
if result[:http].body.eql?('')
|
18
|
-
return {:
|
21
|
+
return { product: :node, version: 'unknown'}
|
19
22
|
end
|
20
23
|
return nil
|
21
24
|
end
|
22
25
|
end
|
23
|
-
SAMPLE_SOAP_CALL='<?xml version="1.0" encoding="UTF-8"
|
24
|
-
|
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
|
25
33
|
|
26
34
|
def initialize(env)
|
27
35
|
super(env)
|
28
|
-
# this is added to
|
36
|
+
# this is added to transfer spec, for instance to add tags (COS)
|
29
37
|
@add_request_param = env[:add_request_param] || {}
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
self.options.parse_options!
|
38
|
-
end
|
38
|
+
options.add_opt_simple(:validator,'identifier of validator (optional for central)')
|
39
|
+
options.add_opt_simple(:asperabrowserurl,'URL for simple aspera web ui')
|
40
|
+
options.add_opt_simple(:sync_name,'sync name')
|
41
|
+
options.add_opt_list(:token_type,%i[aspera basic hybrid],'Type of token used for transfers')
|
42
|
+
options.set_option(:asperabrowserurl,'https://asperabrowser.mybluemix.net')
|
43
|
+
options.set_option(:token_type,:aspera)
|
44
|
+
options.parse_options!
|
39
45
|
return if env[:man_only]
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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 ')
|
44
50
|
# info is provided like node_info of aoc
|
45
|
-
|
46
|
-
base_url:
|
47
|
-
headers:
|
48
|
-
|
49
|
-
|
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)
|
50
56
|
}
|
51
57
|
})
|
52
58
|
else
|
53
59
|
# this is normal case
|
54
|
-
|
60
|
+
basic_auth_api
|
55
61
|
end
|
56
|
-
end
|
57
62
|
end
|
58
63
|
|
59
64
|
def c_textify_browse(table_data)
|
60
|
-
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 }
|
61
66
|
end
|
62
67
|
|
63
68
|
# key/value is defined in main in hash_table
|
64
69
|
def c_textify_bool_list_result(list,name_list)
|
65
70
|
list.each_index do |i|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
70
|
-
list.delete_at(i)
|
71
|
-
# continue at same index because we delete current one
|
72
|
-
redo
|
71
|
+
next unless name_list.include?(list[i]['key'])
|
72
|
+
list[i]['value'].each do |item|
|
73
|
+
list.push({'key' => item['name'],'value' => item['value']})
|
73
74
|
end
|
75
|
+
list.delete_at(i)
|
76
|
+
# continue at same index because we delete current one
|
77
|
+
redo
|
74
78
|
end
|
75
79
|
end
|
76
80
|
|
@@ -80,11 +84,11 @@ module Aspera
|
|
80
84
|
case result[:type]
|
81
85
|
when :object_list
|
82
86
|
result[:data].each do |item|
|
83
|
-
item[column]
|
87
|
+
item[column] = item[column][path_prefix.length..-1] if item[column].start_with?(path_prefix)
|
84
88
|
end
|
85
89
|
when :single_object
|
86
|
-
item=result[:data]
|
87
|
-
item[column]
|
90
|
+
item = result[:data]
|
91
|
+
item[column] = item[column][path_prefix.length..-1] if item[column].start_with?(path_prefix)
|
88
92
|
end
|
89
93
|
end
|
90
94
|
return result
|
@@ -92,366 +96,556 @@ module Aspera
|
|
92
96
|
|
93
97
|
# translates paths results into CLI result, and removes prefix
|
94
98
|
def c_result_translate_rem_prefix(resp,type,success_msg,path_prefix)
|
95
|
-
resres={:
|
99
|
+
resres = { data: [], type: :object_list, fields: [type,'result']}
|
96
100
|
JSON.parse(resp[:http].body)['paths'].each do |p|
|
97
|
-
result=success_msg
|
101
|
+
result = success_msg
|
98
102
|
if p.has_key?('error')
|
99
103
|
Log.log.error("#{p['error']['user_message']} : #{p['path']}")
|
100
|
-
result=
|
104
|
+
result = 'ERROR: ' + p['error']['user_message']
|
101
105
|
end
|
102
|
-
resres[:data].push({type=>p['path'],'result'=>result})
|
106
|
+
resres[:data].push({type => p['path'],'result' => result})
|
103
107
|
end
|
104
108
|
return c_result_remove_prefix_path(resres,type,path_prefix)
|
105
109
|
end
|
106
110
|
|
107
111
|
# get path arguments from command line, and add prefix
|
108
112
|
def get_next_arg_add_prefix(path_prefix,name,number=:single)
|
109
|
-
thepath=
|
113
|
+
thepath = options.get_next_argument(name,expected: number)
|
110
114
|
return thepath if path_prefix.nil?
|
111
115
|
return File.join(path_prefix,thepath) if thepath.is_a?(String)
|
112
116
|
return thepath.map {|p| File.join(path_prefix,p)} if thepath.is_a?(Array)
|
113
|
-
raise StandardError,
|
117
|
+
raise StandardError,'expect: nil, String or Array'
|
114
118
|
end
|
115
119
|
|
116
|
-
SIMPLE_ACTIONS=[
|
120
|
+
SIMPLE_ACTIONS = %i[health events space info license mkdir mklink mkfile rename delete search].freeze
|
117
121
|
|
118
|
-
COMMON_ACTIONS=[
|
122
|
+
COMMON_ACTIONS = %i[browse upload download api_details].concat(SIMPLE_ACTIONS).freeze
|
119
123
|
|
120
124
|
# common API to node and Shares
|
121
125
|
# prefix_path is used to list remote sources in Faspex
|
122
126
|
def execute_simple_common(command,prefix_path)
|
123
127
|
case command
|
124
128
|
when :health
|
125
|
-
nagios=Nagios.new
|
129
|
+
nagios = Nagios.new
|
126
130
|
begin
|
127
|
-
info
|
131
|
+
info = @api_node.read('info')[:data]
|
128
132
|
nagios.add_ok('node api','accessible')
|
129
133
|
nagios.check_time_offset(info['current_time'],'node api')
|
130
|
-
nagios.check_product_version(
|
131
|
-
rescue => e
|
134
|
+
nagios.check_product_version('node api','entsrv', info['version'])
|
135
|
+
rescue StandardError => e
|
132
136
|
nagios.add_critical('node api',e.to_s)
|
133
137
|
end
|
134
138
|
begin
|
135
|
-
@api_node.call(
|
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
|
136
144
|
nagios.add_ok('central','accessible by node')
|
137
|
-
rescue => e
|
145
|
+
rescue StandardError => e
|
138
146
|
nagios.add_critical('central',e.to_s)
|
139
147
|
end
|
140
148
|
return nagios.result
|
141
149
|
when :events
|
142
|
-
events
|
143
|
-
return { :
|
150
|
+
events = @api_node.read('events',options.get_option(:value))[:data]
|
151
|
+
return { type: :object_list, data: events}
|
144
152
|
when :info
|
145
|
-
node_info
|
146
|
-
return { :
|
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])}}
|
147
155
|
when :license # requires: asnodeadmin -mu <node user> --acl-add=internal --internal
|
148
|
-
node_license
|
149
|
-
if node_license['failure'].is_a?(String)
|
150
|
-
Log.log.error(
|
156
|
+
node_license = @api_node.read('license')[:data]
|
157
|
+
if node_license['failure'].is_a?(String) && node_license['failure'].include?('ACL')
|
158
|
+
Log.log.error('server must have: asnodeadmin -mu <node user> --acl-add=internal --internal')
|
151
159
|
end
|
152
|
-
return { :
|
160
|
+
return { type: :single_object, data: node_license}
|
153
161
|
when :delete
|
154
|
-
paths_to_delete = get_next_arg_add_prefix(prefix_path,
|
155
|
-
resp
|
162
|
+
paths_to_delete = get_next_arg_add_prefix(prefix_path,'file list',:multiple)
|
163
|
+
resp = @api_node.create('files/delete',{ paths: paths_to_delete.map{|i| {'path' => i.start_with?('/') ? i : '/' + i} }})
|
156
164
|
return c_result_translate_rem_prefix(resp,'file','deleted',prefix_path)
|
157
165
|
when :search
|
158
|
-
search_root = get_next_arg_add_prefix(prefix_path,
|
159
|
-
parameters={'path'=>search_root}
|
160
|
-
other_options=
|
166
|
+
search_root = get_next_arg_add_prefix(prefix_path,'search root')
|
167
|
+
parameters = {'path' => search_root}
|
168
|
+
other_options = options.get_option(:value)
|
161
169
|
parameters.merge!(other_options) unless other_options.nil?
|
162
|
-
resp
|
163
|
-
result={ :
|
170
|
+
resp = @api_node.create('files/search',parameters)
|
171
|
+
result = { type: :object_list, data: resp[:data]['items']}
|
164
172
|
return Main.result_empty if result[:data].empty?
|
165
|
-
result[:fields]=result[:data].first.keys.
|
173
|
+
result[:fields] = result[:data].first.keys.reject{|i|SEARCH_REMOVE_FIELDS.include?(i)}
|
166
174
|
self.format.display_status("Items: #{resp[:data]['item_count']}/#{resp[:data]['total_count']}")
|
167
175
|
self.format.display_status("params: #{resp[:data]['parameters'].keys.map{|k|"#{k}:#{resp[:data]['parameters'][k]}"}.join(',')}")
|
168
176
|
return c_result_remove_prefix_path(result,'path',prefix_path)
|
169
177
|
when :space
|
170
178
|
# TODO: could be a list of path
|
171
|
-
path_list=get_next_arg_add_prefix(prefix_path,
|
172
|
-
path_list=[path_list] unless path_list.is_a?(Array)
|
173
|
-
resp
|
174
|
-
result={:
|
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}
|
175
183
|
#return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
176
184
|
return c_result_remove_prefix_path(result,'path',prefix_path)
|
177
185
|
when :mkdir
|
178
|
-
path_list=get_next_arg_add_prefix(prefix_path,
|
179
|
-
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)
|
180
188
|
#TODO: a command for that ?
|
181
|
-
#resp=@api_node.create('space',{ "paths" => path_list.map {|i| {:
|
182
|
-
resp
|
189
|
+
#resp=@api_node.create('space',{ "paths" => path_list.map {|i| { type: :directory, path: i} } } )
|
190
|
+
resp = @api_node.create('files/create',{ 'paths' => [{ type: :directory, path: path_list }] })
|
183
191
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
184
192
|
when :mklink
|
185
|
-
target=get_next_arg_add_prefix(prefix_path,
|
186
|
-
path_list=get_next_arg_add_prefix(prefix_path,
|
187
|
-
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} }] })
|
188
196
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
189
197
|
when :mkfile
|
190
|
-
path_list=get_next_arg_add_prefix(prefix_path,
|
191
|
-
contents64=Base64.strict_encode64(
|
192
|
-
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 }] })
|
193
201
|
return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
|
194
202
|
when :rename
|
195
|
-
path_base=get_next_arg_add_prefix(prefix_path,
|
196
|
-
path_src=get_next_arg_add_prefix(prefix_path,
|
197
|
-
path_dst=get_next_arg_add_prefix(prefix_path,
|
198
|
-
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 }] })
|
199
207
|
return c_result_translate_rem_prefix(resp,'entry','moved',prefix_path)
|
200
208
|
when :browse
|
201
|
-
thepath=get_next_arg_add_prefix(prefix_path,
|
202
|
-
query={ :
|
203
|
-
additional_query=
|
209
|
+
thepath = get_next_arg_add_prefix(prefix_path,'path')
|
210
|
+
query = { path: thepath}
|
211
|
+
additional_query = options.get_option(:query)
|
204
212
|
query.merge!(additional_query) unless additional_query.nil?
|
205
|
-
send_result
|
213
|
+
send_result = @api_node.create('files/browse', query)[:data]
|
206
214
|
#example: send_result={'items'=>[{'file'=>"filename1","permissions"=>[{'name'=>'read'},{'name'=>'write'}]}]}
|
207
215
|
# if there is no items
|
208
216
|
case send_result['self']['type']
|
209
217
|
when 'directory','container' # directory: node, container: shares
|
210
|
-
result={ :
|
218
|
+
result = { data: send_result['items'], type: :object_list, textify: lambda { |table_data| c_textify_browse(table_data) } }
|
211
219
|
self.format.display_status("Items: #{send_result['item_count']}/#{send_result['total_count']}")
|
212
220
|
else # 'file','symbolic_link'
|
213
|
-
result={ :
|
214
|
-
#result={ :
|
221
|
+
result = { data: send_result['self'], type: :single_object}
|
222
|
+
#result={ data: [send_result['self']] , type: :object_list, textify: lambda { |table_data| c_textify_browse(table_data) } }
|
215
223
|
#raise "unknown type: #{send_result['self']['type']}"
|
216
224
|
end
|
217
225
|
return c_result_remove_prefix_path(result,'path',prefix_path)
|
218
226
|
when :upload,:download
|
219
|
-
token_type=
|
227
|
+
token_type = options.get_option(:token_type)
|
220
228
|
# nil if Shares 1.x
|
221
|
-
token_type
|
229
|
+
token_type = :aspera if token_type.nil?
|
222
230
|
case token_type
|
223
231
|
when :aspera,:hybrid
|
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
|
-
raise
|
236
|
-
raise
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
'
|
242
|
-
|
245
|
+
raise 'shall have auth' unless @api_node.params[:auth].is_a?(Hash)
|
246
|
+
raise 'shall be basic auth' unless @api_node.params[:auth][:type].eql?(:basic)
|
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)
|
259
|
+
}.deep_merge(@add_request_param)
|
243
260
|
else raise "ERROR: token_type #{tt}"
|
244
261
|
end
|
245
|
-
if [
|
262
|
+
if %i[basic hybrid].include?(token_type)
|
246
263
|
Aspera::Node.set_ak_basic_token(transfer_spec,@api_node.params[:auth][:username],@api_node.params[:auth][:password])
|
247
264
|
end
|
248
|
-
return Main.result_transfer(
|
265
|
+
return Main.result_transfer(transfer.start(transfer_spec,{ src: :node_gen3}))
|
249
266
|
when :api_details
|
250
|
-
return { :
|
267
|
+
return { type: :single_object, data: @api_node.params }
|
251
268
|
end
|
252
269
|
end
|
253
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
|
+
|
254
429
|
def execute_async
|
255
|
-
command=
|
430
|
+
command = options.get_next_command(%i[list delete files show counters bandwidth])
|
256
431
|
unless command.eql?(:list)
|
257
|
-
asyncname=
|
432
|
+
asyncname = options.get_option(:sync_name)
|
258
433
|
if asyncname.nil?
|
259
|
-
asyncid=
|
260
|
-
if asyncid.eql?('ALL')
|
261
|
-
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']
|
262
437
|
else
|
263
438
|
Integer(asyncid) # must be integer
|
264
|
-
asyncids=[asyncid]
|
439
|
+
asyncids = [asyncid]
|
265
440
|
end
|
266
441
|
else
|
267
|
-
asyncids
|
268
|
-
summaries
|
269
|
-
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)}
|
270
445
|
raise "no such sync: #{asyncname}" if selected.nil?
|
271
|
-
asyncid=selected['snid']
|
272
|
-
asyncids=[asyncid]
|
446
|
+
asyncid = selected['snid']
|
447
|
+
asyncids = [asyncid]
|
273
448
|
end
|
274
|
-
pdata={'syncs' => asyncids}
|
449
|
+
pdata = {'syncs' => asyncids}
|
275
450
|
end
|
276
451
|
case command
|
277
452
|
when :list
|
278
|
-
resp
|
279
|
-
return { :
|
453
|
+
resp = @api_node.read('async/list')[:data]['sync_ids']
|
454
|
+
return { type: :value_list, data: resp, name: 'id' }
|
280
455
|
when :show
|
281
|
-
resp
|
456
|
+
resp = @api_node.create('async/summary',pdata)[:data]['sync_summaries']
|
282
457
|
return Main.result_empty if resp.empty?
|
283
|
-
if asyncid.eql?('ALL')
|
284
|
-
|
285
|
-
else
|
286
|
-
return { :type => :single_object, :data => resp.first }
|
287
|
-
end
|
458
|
+
return { type: :object_list, data: resp, fields: %w[snid name local_dir remote_dir] } if asyncid.eql?('ALL')
|
459
|
+
return { type: :single_object, data: resp.first }
|
288
460
|
when :delete
|
289
|
-
resp
|
290
|
-
return { :
|
461
|
+
resp = @api_node.create('async/delete',pdata)[:data]
|
462
|
+
return { type: :single_object, data: resp, name: 'id' }
|
291
463
|
when :bandwidth
|
292
|
-
pdata['seconds']=100
|
293
|
-
resp
|
294
|
-
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']
|
295
467
|
return Main.result_empty if data.empty?
|
296
|
-
data=data.first[asyncid]['data']
|
297
|
-
return { :
|
468
|
+
data = data.first[asyncid]['data']
|
469
|
+
return { type: :object_list, data: data, name: 'id' }
|
298
470
|
when :files
|
299
471
|
# count int
|
300
472
|
# filename str
|
301
473
|
# skip int
|
302
474
|
# status int
|
303
|
-
filter=
|
475
|
+
filter = options.get_option(:value)
|
304
476
|
pdata.merge!(filter) unless filter.nil?
|
305
|
-
resp
|
306
|
-
data=resp['sync_files']
|
307
|
-
data=data.first[asyncid] unless data.empty?
|
308
|
-
iteration_data=[]
|
309
|
-
skip_ids_persistency=nil
|
310
|
-
if
|
311
|
-
skip_ids_persistency=PersistencyActionOnce.new(
|
312
|
-
|
313
|
-
|
314
|
-
|
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]))
|
315
491
|
unless iteration_data.first.nil?
|
316
|
-
data.select!{|l| l['fnid'].to_i>iteration_data.first}
|
492
|
+
data.select!{|l| l['fnid'].to_i > iteration_data.first}
|
317
493
|
end
|
318
|
-
iteration_data[0]=data.last['fnid'].to_i unless data.empty?
|
494
|
+
iteration_data[0] = data.last['fnid'].to_i unless data.empty?
|
319
495
|
end
|
320
496
|
return Main.result_empty if data.empty?
|
321
|
-
skip_ids_persistency
|
322
|
-
return { :
|
497
|
+
skip_ids_persistency&.save
|
498
|
+
return { type: :object_list, data: data, name: 'id' }
|
323
499
|
when :counters
|
324
|
-
resp
|
500
|
+
resp = @api_node.create('async/counters',pdata)[:data]['sync_counters'].first[asyncid].last
|
325
501
|
return Main.result_empty if resp.nil?
|
326
|
-
return { :
|
502
|
+
return { type: :single_object, data: resp }
|
327
503
|
end
|
328
504
|
end
|
329
505
|
|
330
|
-
ACTIONS=[
|
506
|
+
ACTIONS = %i[postprocess stream transfer cleanup forward access_key watch_folder service async central asperabrowser basic_token].concat(COMMON_ACTIONS).freeze
|
331
507
|
|
332
508
|
def execute_action(command=nil,prefix_path=nil)
|
333
|
-
command||=
|
509
|
+
command ||= options.get_next_command(ACTIONS)
|
334
510
|
case command
|
335
|
-
when *COMMON_ACTIONS
|
336
|
-
when :async
|
511
|
+
when *COMMON_ACTIONS then return execute_simple_common(command,prefix_path)
|
512
|
+
when :async then return execute_async
|
337
513
|
when :stream
|
338
|
-
command=
|
514
|
+
command = options.get_next_command(%i[list create show modify cancel])
|
339
515
|
case command
|
340
516
|
when :list
|
341
|
-
resp
|
342
|
-
return { :
|
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?
|
343
519
|
when :create
|
344
|
-
resp
|
345
|
-
return { :
|
520
|
+
resp = @api_node.create('streams',options.get_option(:value,is_type: :mandatory))
|
521
|
+
return { type: :single_object, data: resp[:data] }
|
346
522
|
when :show
|
347
|
-
trid=
|
348
|
-
resp
|
349
|
-
return { :
|
523
|
+
trid = options.get_next_argument('transfer id')
|
524
|
+
resp = @api_node.read('ops/transfers/' + trid)
|
525
|
+
return { type: :other_struct, data: resp[:data] }
|
350
526
|
when :modify
|
351
|
-
trid=
|
352
|
-
resp
|
353
|
-
return { :
|
527
|
+
trid = options.get_next_argument('transfer id')
|
528
|
+
resp = @api_node.update('streams/' + trid,options.get_option(:value,is_type: :mandatory))
|
529
|
+
return { type: :other_struct, data: resp[:data] }
|
354
530
|
when :cancel
|
355
|
-
trid=
|
356
|
-
resp
|
357
|
-
return { :
|
531
|
+
trid = options.get_next_argument('transfer id')
|
532
|
+
resp = @api_node.cancel('streams/' + trid)
|
533
|
+
return { type: :other_struct, data: resp[:data] }
|
358
534
|
else
|
359
|
-
raise
|
535
|
+
raise 'error'
|
360
536
|
end
|
361
537
|
when :transfer
|
362
|
-
command=
|
363
|
-
res_class_path='ops/transfers'
|
364
|
-
if [
|
365
|
-
one_res_id=
|
366
|
-
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}"
|
367
543
|
end
|
368
544
|
case command
|
369
545
|
when :list
|
370
|
-
# could use ? :
|
371
|
-
resp
|
372
|
-
return {
|
546
|
+
# could use ? subpath: 'transfers'
|
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
|
+
}
|
373
553
|
when :cancel
|
374
|
-
resp
|
375
|
-
return { :
|
554
|
+
resp = @api_node.cancel(one_res_path)
|
555
|
+
return { type: :other_struct, data: resp[:data] }
|
376
556
|
when :show
|
377
|
-
resp
|
378
|
-
return { :
|
557
|
+
resp = @api_node.read(one_res_path)
|
558
|
+
return { type: :other_struct, data: resp[:data] }
|
379
559
|
else
|
380
|
-
raise
|
560
|
+
raise 'error'
|
381
561
|
end
|
382
562
|
when :access_key
|
383
|
-
|
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
|
384
578
|
when :service
|
385
|
-
command=
|
579
|
+
command = options.get_next_command(%i[list create delete])
|
386
580
|
if [:delete].include?(command)
|
387
|
-
svcid=
|
581
|
+
svcid = instance_identifier
|
388
582
|
end
|
389
583
|
case command
|
390
584
|
when :list
|
391
|
-
resp
|
392
|
-
return { :
|
585
|
+
resp = @api_node.read('rund/services')
|
586
|
+
return { type: :object_list, data: resp[:data]['services'] }
|
393
587
|
when :create
|
394
588
|
# @json:'{"type":"WATCHFOLDERD","run_as":{"user":"user1"}}'
|
395
|
-
params=
|
396
|
-
resp
|
589
|
+
params = options.get_next_argument('Run creation data (structure)')
|
590
|
+
resp = @api_node.create('rund/services',params)
|
397
591
|
return Main.result_status("#{resp[:data]['id']} created")
|
398
592
|
when :delete
|
399
|
-
|
593
|
+
@api_node.delete("rund/services/#{svcid}")
|
400
594
|
return Main.result_status("#{svcid} deleted")
|
401
595
|
end
|
402
596
|
when :watch_folder
|
403
|
-
res_class_path='v3/watchfolders'
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
one_res_id
|
408
|
-
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}"
|
409
602
|
end
|
410
603
|
# hum, to avoid: Unable to convert 2016_09_14 configuration
|
411
|
-
@api_node.params[:headers]||={}
|
412
|
-
@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'
|
413
606
|
case command
|
414
607
|
when :create
|
415
|
-
resp
|
608
|
+
resp = @api_node.create(res_class_path,options.get_option(:value,is_type: :mandatory))
|
416
609
|
return Main.result_status("#{resp[:data]['id']} created")
|
417
610
|
when :list
|
418
|
-
resp
|
419
|
-
return { :
|
611
|
+
resp = @api_node.read(res_class_path,options.get_option(:value))
|
612
|
+
return { type: :value_list, data: resp[:data]['ids'], name: 'id' }
|
420
613
|
when :show
|
421
|
-
return {:
|
614
|
+
return { type: :single_object, data: @api_node.read(one_res_path)[:data]}
|
422
615
|
when :modify
|
423
|
-
@api_node.update(one_res_path,
|
616
|
+
@api_node.update(one_res_path,options.get_option(:value,is_type: :mandatory))
|
424
617
|
return Main.result_status("#{one_res_id} updated")
|
425
618
|
when :delete
|
426
619
|
@api_node.delete(one_res_path)
|
427
620
|
return Main.result_status("#{one_res_id} deleted")
|
428
621
|
when :state
|
429
|
-
return { :
|
622
|
+
return { type: :single_object, data: @api_node.read("#{one_res_path}/state")[:data] }
|
430
623
|
end
|
431
624
|
when :central
|
432
|
-
command=
|
433
|
-
validator_id=
|
434
|
-
validation={
|
435
|
-
request_data=
|
436
|
-
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 ||= {}
|
437
630
|
case command
|
438
631
|
when :session
|
439
|
-
command=
|
632
|
+
command = options.get_next_command([:list])
|
440
633
|
case command
|
441
634
|
when :list
|
442
|
-
request_data.deep_merge!({
|
443
|
-
resp
|
444
|
-
return {:
|
635
|
+
request_data.deep_merge!({'validation' => validation}) unless validation.nil?
|
636
|
+
resp = @api_node.create('services/rest/transfers/v1/sessions',request_data)
|
637
|
+
return { type: :object_list, data: resp[:data]['session_info_result']['session_info'],
|
638
|
+
fields: %w[session_uuid status transport direction bytes_transferred]}
|
445
639
|
end
|
446
640
|
when :file
|
447
|
-
command=
|
641
|
+
command = options.get_next_command(%i[list modify])
|
448
642
|
case command
|
449
643
|
when :list
|
450
|
-
request_data.deep_merge!({'validation'=>validation}) unless validation.nil?
|
451
|
-
resp
|
452
|
-
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)
|
453
647
|
Log.dump(:resp,resp)
|
454
|
-
return {:
|
648
|
+
return { type: :object_list, data: resp['file_transfer_info_result']['file_transfer_info'], fields: %w[session_uuid file_id status path]}
|
455
649
|
when :modify
|
456
650
|
request_data.deep_merge!(validation) unless validation.nil?
|
457
651
|
@api_node.update('services/rest/transfers/v1/files',request_data)
|
@@ -459,19 +653,19 @@ module Aspera
|
|
459
653
|
end
|
460
654
|
end
|
461
655
|
when :asperabrowser
|
462
|
-
browse_params={
|
463
|
-
'nodeUser' =>
|
464
|
-
'nodePW' =>
|
465
|
-
'nodeURL' =>
|
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)
|
466
660
|
}
|
467
661
|
# encode parameters so that it looks good in url
|
468
|
-
encoded_params=Base64.strict_encode64(Zlib::Deflate.deflate(JSON.generate(browse_params))).gsub(/=+$/, '').tr('+/', '-_').reverse
|
469
|
-
OpenApplication.instance.uri(
|
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)
|
470
664
|
return Main.result_status('done')
|
471
665
|
when :basic_token
|
472
|
-
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)))
|
473
667
|
end # case command
|
474
|
-
raise
|
668
|
+
raise 'ERROR: shall not reach this line'
|
475
669
|
end # execute_action
|
476
670
|
end # Main
|
477
671
|
end # Plugin
|