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