aspera-cli 4.2.1 → 4.5.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 +1580 -946
- data/bin/ascli +1 -1
- data/bin/asession +3 -5
- data/docs/Makefile +8 -11
- data/docs/README.erb.md +1521 -829
- data/docs/doc_tools.rb +58 -0
- data/docs/test_env.conf +3 -1
- data/examples/faspex4.rb +28 -19
- data/examples/transfer.rb +2 -2
- data/lib/aspera/aoc.rb +157 -134
- data/lib/aspera/cli/listener/progress_multi.rb +5 -5
- data/lib/aspera/cli/main.rb +106 -48
- data/lib/aspera/cli/manager.rb +19 -20
- data/lib/aspera/cli/plugin.rb +22 -7
- data/lib/aspera/cli/plugins/aoc.rb +260 -208
- data/lib/aspera/cli/plugins/ats.rb +11 -10
- data/lib/aspera/cli/plugins/bss.rb +2 -2
- data/lib/aspera/cli/plugins/config.rb +360 -189
- data/lib/aspera/cli/plugins/faspex.rb +119 -56
- data/lib/aspera/cli/plugins/faspex5.rb +32 -17
- data/lib/aspera/cli/plugins/node.rb +72 -31
- data/lib/aspera/cli/plugins/orchestrator.rb +5 -3
- data/lib/aspera/cli/plugins/preview.rb +94 -68
- data/lib/aspera/cli/plugins/server.rb +16 -5
- data/lib/aspera/cli/plugins/shares.rb +17 -0
- data/lib/aspera/cli/transfer_agent.rb +64 -82
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/command_line_builder.rb +48 -31
- data/lib/aspera/cos_node.rb +4 -3
- data/lib/aspera/environment.rb +4 -4
- data/lib/aspera/fasp/{manager.rb → agent_base.rb} +7 -6
- data/lib/aspera/fasp/{connect.rb → agent_connect.rb} +46 -39
- data/lib/aspera/fasp/{local.rb → agent_direct.rb} +42 -38
- data/lib/aspera/fasp/{http_gw.rb → agent_httpgw.rb} +50 -29
- data/lib/aspera/fasp/{node.rb → agent_node.rb} +43 -4
- data/lib/aspera/fasp/agent_trsdk.rb +106 -0
- data/lib/aspera/fasp/default.rb +17 -0
- data/lib/aspera/fasp/installation.rb +64 -48
- data/lib/aspera/fasp/parameters.rb +78 -91
- data/lib/aspera/fasp/parameters.yaml +531 -0
- data/lib/aspera/fasp/uri.rb +1 -1
- data/lib/aspera/faspex_gw.rb +12 -11
- data/lib/aspera/id_generator.rb +22 -0
- data/lib/aspera/keychain/encrypted_hash.rb +120 -0
- data/lib/aspera/keychain/macos_security.rb +94 -0
- data/lib/aspera/log.rb +45 -32
- data/lib/aspera/node.rb +9 -4
- data/lib/aspera/oauth.rb +116 -100
- data/lib/aspera/persistency_action_once.rb +11 -7
- data/lib/aspera/persistency_folder.rb +6 -26
- data/lib/aspera/rest.rb +66 -50
- data/lib/aspera/sync.rb +40 -35
- data/lib/aspera/timer_limiter.rb +22 -0
- metadata +86 -29
- data/docs/transfer_spec.html +0 -99
- data/lib/aspera/api_detector.rb +0 -60
- data/lib/aspera/fasp/aoc.rb +0 -24
- data/lib/aspera/secrets.rb +0 -20
@@ -2,19 +2,32 @@ require 'aspera/cli/plugins/node'
|
|
2
2
|
require 'aspera/cli/plugins/ats'
|
3
3
|
require 'aspera/cli/basic_auth_plugin'
|
4
4
|
require 'aspera/cli/transfer_agent'
|
5
|
+
require 'aspera/fasp/agent_node'
|
5
6
|
require 'aspera/aoc'
|
6
7
|
require 'aspera/node'
|
7
8
|
require 'aspera/persistency_action_once'
|
9
|
+
require 'aspera/id_generator'
|
8
10
|
require 'securerandom'
|
9
|
-
require 'resolv'
|
10
11
|
require 'date'
|
11
12
|
|
12
13
|
module Aspera
|
13
14
|
module Cli
|
14
15
|
module Plugins
|
15
16
|
class Aoc < BasicAuthPlugin
|
17
|
+
class << self
|
18
|
+
def detect(base_url)
|
19
|
+
api=Rest.new({base_url: base_url})
|
20
|
+
result=api.call({operation: 'GET',subpath: '',headers: {'Accept'=>'text/html'}})
|
21
|
+
if result[:http].body.include?('content="AoC"')
|
22
|
+
return {product: :aoc,version: 'unknown'}
|
23
|
+
end
|
24
|
+
return nil
|
25
|
+
end
|
26
|
+
end
|
16
27
|
# special value for package id
|
17
28
|
VAL_ALL='ALL'
|
29
|
+
ID_AK_ADMIN='ASPERA_ACCESS_KEY_ADMIN'
|
30
|
+
|
18
31
|
def initialize(env)
|
19
32
|
super(env)
|
20
33
|
@default_workspace_id=nil
|
@@ -24,7 +37,6 @@ module Aspera
|
|
24
37
|
@home_node_file=nil
|
25
38
|
@api_aoc=nil
|
26
39
|
@url_token_data=nil
|
27
|
-
@user_info=nil
|
28
40
|
@api_aoc=nil
|
29
41
|
self.options.add_opt_list(:auth,Oauth.auth_types,'OAuth type of authentication')
|
30
42
|
self.options.add_opt_list(:operation,[:push,:pull],'client operation for transfers')
|
@@ -39,7 +51,6 @@ module Aspera
|
|
39
51
|
self.options.add_opt_simple(:new_user_option,'new user creation option')
|
40
52
|
self.options.add_opt_simple(:from_folder,'share to share source folder')
|
41
53
|
self.options.add_opt_simple(:scope,'OAuth scope for AoC API calls')
|
42
|
-
self.options.add_opt_simple(:notify,'notify users that file was received')
|
43
54
|
self.options.add_opt_boolean(:bulk,'bulk operation')
|
44
55
|
self.options.add_opt_boolean(:default_ports,'use standard FASP ports or get from node api')
|
45
56
|
self.options.set_option(:bulk,:no)
|
@@ -58,44 +69,41 @@ module Aspera
|
|
58
69
|
if @api_aoc.nil?
|
59
70
|
@api_aoc=AoC.new(aoc_params(AoC::API_V1))
|
60
71
|
# add keychain for access key secrets
|
61
|
-
@api_aoc.key_chain=@agents[:
|
72
|
+
@api_aoc.key_chain=@agents[:config]
|
62
73
|
end
|
63
74
|
return @api_aoc
|
64
75
|
end
|
65
76
|
|
66
|
-
# cached user information
|
67
|
-
def c_user_info
|
68
|
-
if @user_info.nil?
|
69
|
-
# get our user's default information
|
70
|
-
# self?embed[]=default_workspace&embed[]=organization
|
71
|
-
@user_info=@api_aoc.read('self')[:data] rescue {
|
72
|
-
'name' => 'unknown',
|
73
|
-
'email' => 'unknown',
|
74
|
-
}
|
75
|
-
end
|
76
|
-
return @user_info
|
77
|
-
end
|
78
|
-
|
79
77
|
# starts transfer using transfer agent
|
80
78
|
def transfer_start(app,direction,node_file,ts_add)
|
81
79
|
ts_add.deep_merge!(AoC.analytics_ts(app,direction,@workspace_id,@workspace_name))
|
82
|
-
ts_add.deep_merge!(
|
80
|
+
ts_add.deep_merge!(@api_aoc.console_ts(app))
|
83
81
|
return self.transfer.start(*@api_aoc.tr_spec(app,direction,node_file,ts_add))
|
84
82
|
end
|
85
83
|
|
86
|
-
NODE4_COMMANDS=[ :browse, :find, :mkdir, :rename, :delete, :upload, :download, :transfer, :http_node_download, :v3, :file, :bearer_token_node ]
|
84
|
+
NODE4_COMMANDS=[ :browse, :find, :mkdir, :rename, :delete, :upload, :download, :transfer, :http_node_download, :v3, :file, :bearer_token_node, :node_info ].freeze
|
87
85
|
|
88
86
|
def execute_node_gen4_command(command_repo,top_node_file)
|
89
87
|
case command_repo
|
90
88
|
when :bearer_token_node
|
91
89
|
thepath=self.options.get_next_argument('path')
|
92
90
|
node_file = @api_aoc.resolve_node_file(top_node_file,thepath)
|
93
|
-
node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
91
|
+
node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER, use_secret: false)
|
94
92
|
return Main.result_status(node_api.oauth_token)
|
93
|
+
when :node_info
|
94
|
+
thepath=self.options.get_next_argument('path')
|
95
|
+
node_file = @api_aoc.resolve_node_file(top_node_file,thepath)
|
96
|
+
node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER, use_secret: false)
|
97
|
+
return {type: :single_object,data: {
|
98
|
+
url: node_file[:node_info]['url'],
|
99
|
+
username: node_file[:node_info]['access_key'],
|
100
|
+
password: node_api.oauth_token,
|
101
|
+
root_id: node_file[:file_id]
|
102
|
+
}}
|
95
103
|
when :browse
|
96
104
|
thepath=self.options.get_next_argument('path')
|
97
105
|
node_file = @api_aoc.resolve_node_file(top_node_file,thepath)
|
98
|
-
node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
106
|
+
node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
|
99
107
|
file_info = node_api.read("files/#{node_file[:file_id]}")[:data]
|
100
108
|
if file_info['type'].eql?('folder')
|
101
109
|
result=node_api.read("files/#{node_file[:file_id]}/files",self.options.get_option(:value,:optional))
|
@@ -104,33 +112,33 @@ module Aspera
|
|
104
112
|
else
|
105
113
|
items=[file_info]
|
106
114
|
end
|
107
|
-
return {:
|
115
|
+
return {type: :object_list,data: items,fields: ['name','type','recursive_size','size','modified_time','access_level']}
|
108
116
|
when :find
|
109
117
|
thepath=self.options.get_next_argument('path')
|
110
118
|
node_file=@api_aoc.resolve_node_file(top_node_file,thepath)
|
111
119
|
test_block=Aspera::Node.file_matcher(self.options.get_option(:value,:optional))
|
112
|
-
return {:
|
120
|
+
return {type: :object_list,data: @api_aoc.find_files(node_file,test_block),fields: ['path']}
|
113
121
|
when :mkdir
|
114
122
|
thepath=self.options.get_next_argument('path')
|
115
123
|
containing_folder_path = thepath.split(AoC::PATH_SEPARATOR)
|
116
124
|
new_folder=containing_folder_path.pop
|
117
125
|
node_file = @api_aoc.resolve_node_file(top_node_file,containing_folder_path.join(AoC::PATH_SEPARATOR))
|
118
|
-
node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
119
|
-
result=node_api.create("files/#{node_file[:file_id]}/files",{:
|
126
|
+
node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
|
127
|
+
result=node_api.create("files/#{node_file[:file_id]}/files",{name: new_folder,type: :folder})[:data]
|
120
128
|
return Main.result_status("created: #{result['name']} (id=#{result['id']})")
|
121
129
|
when :rename
|
122
130
|
thepath=self.options.get_next_argument('source path')
|
123
131
|
newname=self.options.get_next_argument('new name')
|
124
132
|
node_file = @api_aoc.resolve_node_file(top_node_file,thepath)
|
125
|
-
node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
126
|
-
result=node_api.update("files/#{node_file[:file_id]}",{:
|
133
|
+
node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
|
134
|
+
result=node_api.update("files/#{node_file[:file_id]}",{name: newname})[:data]
|
127
135
|
return Main.result_status("renamed #{thepath} to #{newname}")
|
128
136
|
when :delete
|
129
137
|
thepath=self.options.get_next_argument('path')
|
130
138
|
return do_bulk_operation(thepath,'deleted','path') do |l_path|
|
131
139
|
raise "expecting String (path), got #{l_path.class.name} (#{l_path})" unless l_path.is_a?(String)
|
132
140
|
node_file = @api_aoc.resolve_node_file(top_node_file,l_path)
|
133
|
-
node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
141
|
+
node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
|
134
142
|
result=node_api.delete("files/#{node_file[:file_id]}")[:data]
|
135
143
|
{'path'=>l_path}
|
136
144
|
end
|
@@ -153,7 +161,13 @@ module Aspera
|
|
153
161
|
client_node_file = @api_aoc.resolve_node_file(client_home_node_file,client_folder)
|
154
162
|
server_node_file = @api_aoc.resolve_node_file(server_home_node_file,server_folder)
|
155
163
|
# force node as transfer agent
|
156
|
-
|
164
|
+
client_node_api=@api_aoc.get_node_api(client_node_file[:node_info],scope: AoC::SCOPE_NODE_USER, use_secret: false)
|
165
|
+
@agents[:transfer].set_agent_instance(Fasp::AgentNode.new({
|
166
|
+
url: client_node_api.params[:base_url],
|
167
|
+
username: client_node_file[:node_info]['access_key'],
|
168
|
+
password: client_node_api.oauth_token,
|
169
|
+
root_id: client_node_file[:file_id]
|
170
|
+
}))
|
157
171
|
# additional node to node TS info
|
158
172
|
add_ts={
|
159
173
|
'remote_access_key' => server_node_file[:node_info]['access_key'],
|
@@ -191,37 +205,37 @@ module Aspera
|
|
191
205
|
raise CliBadArgument,'one file at a time only in HTTP mode' if source_paths.length > 1
|
192
206
|
file_name = source_paths.first['source']
|
193
207
|
node_file = @api_aoc.resolve_node_file(top_node_file,File.join(source_folder,file_name))
|
194
|
-
node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
195
|
-
node_api.call({:
|
208
|
+
node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
|
209
|
+
node_api.call({operation: 'GET',subpath: "files/#{node_file[:file_id]}/content",save_to_file: File.join(self.transfer.destination_folder('receive'),file_name)})
|
196
210
|
return Main.result_status("downloaded: #{file_name}")
|
197
211
|
when :v3
|
198
|
-
# Note: other
|
212
|
+
# Note: other common actions are unauthorized with user scope
|
199
213
|
command_legacy=self.options.get_next_command(Node::SIMPLE_ACTIONS)
|
200
214
|
# TODO: shall we support all methods here ? what if there is a link ?
|
201
|
-
node_api=@api_aoc.get_node_api(top_node_file[:node_info],AoC::SCOPE_NODE_USER)
|
215
|
+
node_api=@api_aoc.get_node_api(top_node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
|
202
216
|
return Node.new(@agents.merge(skip_basic_auth_options: true, node_api: node_api)).execute_action(command_legacy)
|
203
217
|
when :file
|
218
|
+
command_node_file=self.options.get_next_command([:show,:permission,:modify])
|
204
219
|
file_path=self.options.get_option(:path,:optional)
|
205
220
|
node_file = if !file_path.nil?
|
206
221
|
@api_aoc.resolve_node_file(top_node_file,file_path) # TODO: allow follow link ?
|
207
222
|
else
|
208
|
-
{node_info: top_node_file[:node_info],file_id: self.
|
223
|
+
{node_info: top_node_file[:node_info],file_id: self.instance_identifier()}
|
209
224
|
end
|
210
|
-
node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
211
|
-
command_node_file=self.options.get_next_command([:show,:permission,:modify])
|
225
|
+
node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
|
212
226
|
case command_node_file
|
213
227
|
when :show
|
214
228
|
items=node_api.read("files/#{node_file[:file_id]}")[:data]
|
215
|
-
return {:
|
229
|
+
return {type: :single_object,data: items}
|
216
230
|
when :modify
|
217
|
-
update_param=self.options.get_next_argument(
|
231
|
+
update_param=self.options.get_next_argument('update data (Hash)')
|
218
232
|
res=node_api.update("files/#{node_file[:file_id]}",update_param)[:data]
|
219
|
-
return {:
|
233
|
+
return {type: :single_object,data: res}
|
220
234
|
when :permission
|
221
235
|
command_perm=self.options.get_next_command([:list,:create])
|
222
236
|
case command_perm
|
223
237
|
when :list
|
224
|
-
# generic options : TODO: as arg ?
|
238
|
+
# generic options : TODO: as arg ? option_url_query
|
225
239
|
list_options||={'include'=>['[]','access_level','permission_count']}
|
226
240
|
# special value: ALL will show all permissions
|
227
241
|
if !VAL_ALL.eql?(node_file[:file_id])
|
@@ -229,13 +243,12 @@ module Aspera
|
|
229
243
|
list_options['file_id']=node_file[:file_id]
|
230
244
|
list_options['inherited']||=false
|
231
245
|
end
|
232
|
-
#option_url_query
|
233
246
|
items=node_api.read('permissions',list_options)[:data]
|
234
|
-
return {:
|
247
|
+
return {type: :object_list,data: items}
|
235
248
|
when :create
|
236
|
-
#create_param=self.options.get_next_argument(
|
249
|
+
#create_param=self.options.get_next_argument('creation data (Hash)')
|
237
250
|
set_workspace_info
|
238
|
-
access_id="
|
251
|
+
access_id="#{ID_AK_ADMIN}_WS_#{@workspace_id}"
|
239
252
|
node_file[:node_info]
|
240
253
|
params={
|
241
254
|
'file_id' =>node_file[:file_id], # mandatory
|
@@ -245,25 +258,23 @@ module Aspera
|
|
245
258
|
'tags' =>{'aspera'=>{'files'=>{'workspace'=>{
|
246
259
|
'id' =>@workspace_id,
|
247
260
|
'workspace_name' =>@workspace_name,
|
248
|
-
'user_name'
|
249
|
-
'shared_by_user_id'
|
250
|
-
'shared_by_name'
|
251
|
-
'shared_by_email'
|
261
|
+
'user_name' =>@api_aoc.user_info['name'],
|
262
|
+
'shared_by_user_id'=>@api_aoc.user_info['id'],
|
263
|
+
'shared_by_name' =>@api_aoc.user_info['name'],
|
264
|
+
'shared_by_email' =>@api_aoc.user_info['email'],
|
252
265
|
'shared_with_name' =>access_id,
|
253
266
|
'access_key' =>node_file[:node_info]['access_key'],
|
254
267
|
'node' =>node_file[:node_info]['name']}}}}}
|
255
268
|
item=node_api.create('permissions',params)[:data]
|
256
|
-
return {:
|
269
|
+
return {type: :single_object,data: item}
|
257
270
|
else raise "internal error:shall not reach here (#{command_perm})"
|
258
271
|
end
|
259
|
-
raise
|
272
|
+
raise 'internal error:shall not reach here'
|
260
273
|
else raise "internal error:shall not reach here (#{command_node_file})"
|
261
274
|
end
|
262
|
-
raise
|
263
|
-
when :permissions
|
264
|
-
|
275
|
+
raise 'internal error:shall not reach here'
|
265
276
|
end # command_repo
|
266
|
-
raise
|
277
|
+
raise 'ERR'
|
267
278
|
end # execute_node_gen4_command
|
268
279
|
|
269
280
|
# build constructor option list for AoC based on options of CLI
|
@@ -288,21 +299,21 @@ module Aspera
|
|
288
299
|
@default_workspace_id=@url_token_data['data']['workspace_id']
|
289
300
|
@persist_ids=[] # TODO : @url_token_data['id'] ?
|
290
301
|
else
|
291
|
-
@default_workspace_id
|
292
|
-
@persist_ids=[
|
302
|
+
@default_workspace_id=@api_aoc.user_info['default_workspace_id']
|
303
|
+
@persist_ids=[@api_aoc.user_info['id']]
|
293
304
|
end
|
294
305
|
|
295
306
|
ws_name=self.options.get_option(:workspace,:optional)
|
296
307
|
if ws_name.nil?
|
297
|
-
Log.log.debug(
|
308
|
+
Log.log.debug('using default workspace'.green)
|
298
309
|
if @default_workspace_id.eql?(nil)
|
299
|
-
raise CliError,
|
310
|
+
raise CliError,'no default workspace defined for user, please specify workspace'
|
300
311
|
end
|
301
312
|
# get default workspace
|
302
313
|
@workspace_id=@default_workspace_id
|
303
314
|
else
|
304
315
|
# lookup another workspace
|
305
|
-
wss=@api_aoc.read(
|
316
|
+
wss=@api_aoc.read('workspaces',{'q'=>ws_name})[:data]
|
306
317
|
wss=wss.select { |i| i['name'].eql?(ws_name) }
|
307
318
|
case wss.length
|
308
319
|
when 0
|
@@ -310,14 +321,14 @@ module Aspera
|
|
310
321
|
when 1
|
311
322
|
@workspace_id=wss.first['id']
|
312
323
|
else
|
313
|
-
raise
|
324
|
+
raise 'unexpected case'
|
314
325
|
end
|
315
326
|
end
|
316
327
|
@workspace_data=@api_aoc.read("workspaces/#{@workspace_id}")[:data]
|
317
328
|
Log.log.debug("workspace_id=#{@workspace_id},@workspace_data=#{@workspace_data}".red)
|
318
329
|
|
319
330
|
@workspace_name||=@workspace_data['name']
|
320
|
-
Log.log.info(
|
331
|
+
Log.log.info('current workspace is '+@workspace_name.red)
|
321
332
|
|
322
333
|
# display workspace
|
323
334
|
self.format.display_status("Current Workspace: #{@workspace_name.red}#{@workspace_id == @default_workspace_id ? ' (default)' : ''}")
|
@@ -333,7 +344,7 @@ module Aspera
|
|
333
344
|
end
|
334
345
|
home_node_id||=@workspace_data['home_node_id']||@workspace_data['node_id']
|
335
346
|
home_file_id||=@workspace_data['home_file_id']
|
336
|
-
raise
|
347
|
+
raise 'node_id must be defined' if home_node_id.to_s.empty?
|
337
348
|
@home_node_file={
|
338
349
|
node_info: @api_aoc.read("nodes/#{home_node_id}")[:data],
|
339
350
|
file_id: home_file_id
|
@@ -345,7 +356,7 @@ module Aspera
|
|
345
356
|
|
346
357
|
def do_bulk_operation(ids_or_one,success_msg,id_result='id',&do_action)
|
347
358
|
ids_or_one=[ids_or_one] unless self.options.get_option(:bulk)
|
348
|
-
raise
|
359
|
+
raise 'expecting Array' unless ids_or_one.is_a?(Array)
|
349
360
|
result_list=[]
|
350
361
|
ids_or_one.each do |id|
|
351
362
|
one={id_result=>id}
|
@@ -358,7 +369,27 @@ module Aspera
|
|
358
369
|
end
|
359
370
|
result_list.push(one)
|
360
371
|
end
|
361
|
-
return {:
|
372
|
+
return {type: :object_list,data: result_list,fields: [id_result,'status']}
|
373
|
+
end
|
374
|
+
|
375
|
+
NOT_FOUND="not found"
|
376
|
+
|
377
|
+
def lookup_single(entity_type,entity_name,options={})
|
378
|
+
# returns entities whose name contains value (case insensitive)
|
379
|
+
matching_items=@api_aoc.read(entity_type,options.merge({'q'=>entity_name}))[:data]
|
380
|
+
case matching_items.length
|
381
|
+
when 1; return matching_items.first
|
382
|
+
when 0; raise RuntimeError,NOT_FOUND
|
383
|
+
else
|
384
|
+
# multiple case insensitive partial matches, try case insensitive full match
|
385
|
+
# (anyway AoC does not allow creation of 2 entities with same case insensitive name)
|
386
|
+
icase_matches=matching_items.select{|i|i['name'].casecmp?(entity_name)}
|
387
|
+
case icase_matches.length
|
388
|
+
when 1; return icase_matches.first
|
389
|
+
when 0; raise CliBadArgument,"#{entity_type}: multiple case insensitive partial match for: \"#{entity_name}\": #{matching_items.map{|i|i['name']}} but no case insensitive full match. Please be more specific or give exact name."
|
390
|
+
else raise "Two entities cannot have the same case insensitive name: #{icase_matches.map{|i|i['name']}}"
|
391
|
+
end
|
392
|
+
end
|
362
393
|
end
|
363
394
|
|
364
395
|
# package creation params can give just email, and full hash is created
|
@@ -366,42 +397,44 @@ module Aspera
|
|
366
397
|
return unless package_creation.has_key?(recipient_list_field)
|
367
398
|
raise CliBadArgument,"#{recipient_list_field} must be an Array" unless package_creation[recipient_list_field].is_a?(Array)
|
368
399
|
new_user_option=self.options.get_option(:new_user_option,:mandatory)
|
400
|
+
# list with resolved elements
|
369
401
|
resolved_list=[]
|
370
|
-
package_creation[recipient_list_field].each do |
|
371
|
-
case
|
372
|
-
when Hash
|
373
|
-
raise
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
else
|
402
|
+
package_creation[recipient_list_field].each do |short_recipient_info|
|
403
|
+
case short_recipient_info
|
404
|
+
when Hash # native api information, check keys
|
405
|
+
raise "#{recipient_list_field} element shall have fields: id and type" unless short_recipient_info.keys.sort.eql?(['id','type'])
|
406
|
+
when String # need to resolve name to type/id
|
407
|
+
# email: user, else dropbox
|
408
|
+
entity_type=short_recipient_info.include?('@') ? 'contacts' : 'dropboxes'
|
409
|
+
begin
|
410
|
+
full_recipient_info=lookup_single(entity_type,short_recipient_info,{'current_workspace_id'=>@workspace_id})
|
411
|
+
rescue RuntimeError => e
|
412
|
+
raise e unless e.message.eql?(NOT_FOUND)
|
413
|
+
if entity_type.eql?('contacts')
|
414
|
+
full_recipient_info=@api_aoc.create('contacts',{'current_workspace_id'=>@workspace_id,'email'=>short_recipient_info}.merge(new_user_option))[:data]
|
415
|
+
else
|
416
|
+
raise "no such shared inbox in workspace #{@workspace_name}"
|
384
417
|
end
|
385
|
-
|
418
|
+
end
|
419
|
+
if entity_type.eql?('dropboxes')
|
420
|
+
short_recipient_info={'id'=>full_recipient_info['id'],'type'=>'dropbox'}
|
386
421
|
else
|
387
|
-
|
388
|
-
case item_lookup.length
|
389
|
-
when 1; recipient_user_id=item_lookup.first
|
390
|
-
when 0; raise "no such shared inbox in workspace #{@workspace_name}"
|
391
|
-
else raise CliBadArgument,"multiple match for: #{recipient_email_or_info}"
|
392
|
-
end
|
393
|
-
resolved_list.push({'id'=>recipient_user_id['id'],'type'=>'dropbox'})
|
422
|
+
short_recipient_info={'id'=>full_recipient_info['source_id'],'type'=>full_recipient_info['source_type']}
|
394
423
|
end
|
395
|
-
else
|
396
|
-
raise "
|
397
|
-
end
|
424
|
+
else # unexpected extended value, must be String or Hash
|
425
|
+
raise "#{recipient_list_field} item must be a String (email, shared inbox) or Hash (id,type)"
|
426
|
+
end # type of recipient info
|
427
|
+
# add original or resolved recipient info
|
428
|
+
resolved_list.push(short_recipient_info)
|
398
429
|
end
|
430
|
+
# replace with resolved elements
|
399
431
|
package_creation[recipient_list_field]=resolved_list
|
400
432
|
end
|
401
433
|
|
402
434
|
# private
|
403
435
|
def option_url_query(default)
|
404
|
-
query=self.options.get_option(:query,:optional)
|
436
|
+
query=self.options.get_option(:query,:optional)
|
437
|
+
query=default if query.nil?
|
405
438
|
Log.log.debug("Query=#{query}".bg_red)
|
406
439
|
begin
|
407
440
|
# check it is suitable
|
@@ -418,6 +451,37 @@ module Aspera
|
|
418
451
|
end
|
419
452
|
end
|
420
453
|
|
454
|
+
# Call @api_aoc.read with same parameters, but use paging if necessary to get all results
|
455
|
+
def read_with_paging(resource_class_path,base_query)
|
456
|
+
raise "Query must be Hash" unless base_query.is_a?(Hash)
|
457
|
+
# set default large page if user does not specify own parameters. AoC Caps to 1000 anyway
|
458
|
+
base_query['per_page']=1000 unless base_query.has_key?('per_page')
|
459
|
+
max_items=base_query[MAX_ITEMS]
|
460
|
+
base_query.delete(MAX_ITEMS)
|
461
|
+
max_pages=base_query[MAX_PAGES]
|
462
|
+
base_query.delete(MAX_PAGES)
|
463
|
+
item_list=[]
|
464
|
+
total_count=nil
|
465
|
+
current_page=base_query['page']
|
466
|
+
current_page=1 if current_page.nil?
|
467
|
+
page_count=0
|
468
|
+
loop do
|
469
|
+
query=base_query.clone
|
470
|
+
query['page']=current_page
|
471
|
+
result=@api_aoc.read(resource_class_path,query)
|
472
|
+
total_count=result[:http]['X-Total-Count']
|
473
|
+
page_count+=1
|
474
|
+
current_page+=1
|
475
|
+
add_items=result[:data]
|
476
|
+
break if add_items.empty?
|
477
|
+
# append new items to full list
|
478
|
+
item_list += add_items
|
479
|
+
break if !max_pages.nil? and page_count > max_pages
|
480
|
+
break if !max_items.nil? and item_list.count > max_items
|
481
|
+
end
|
482
|
+
return item_list,total_count
|
483
|
+
end
|
484
|
+
|
421
485
|
def execute_admin_action
|
422
486
|
@api_aoc.oauth.params[:scope]=AoC::SCOPE_FILES_ADMIN
|
423
487
|
command_admin=self.options.get_next_command([ :ats, :resource, :usage_reports, :analytics, :subscription, :auth_providers ])
|
@@ -427,7 +491,7 @@ module Aspera
|
|
427
491
|
case command_auth_prov
|
428
492
|
when :list
|
429
493
|
providers=@api_aoc.read('admin/auth_providers')[:data]
|
430
|
-
return {:
|
494
|
+
return {type: :object_list,data: providers}
|
431
495
|
when :update
|
432
496
|
end
|
433
497
|
when :subscription
|
@@ -482,43 +546,43 @@ module Aspera
|
|
482
546
|
}
|
483
547
|
"
|
484
548
|
result=bss_api.create('graphql',{'variables'=>{'organization_id'=>org['id']},'query'=>graphql_query})[:data]['data']
|
485
|
-
return {:
|
549
|
+
return {type: :single_object,data: result['aoc']['bssSubscription']}
|
486
550
|
when :ats
|
487
551
|
ats_api = Rest.new(@api_aoc.params.deep_merge({
|
488
|
-
:
|
489
|
-
:
|
552
|
+
base_url: @api_aoc.params[:base_url]+'/admin/ats/pub/v1',
|
553
|
+
auth: {scope: AoC::SCOPE_FILES_ADMIN_USER}
|
490
554
|
}))
|
491
555
|
return Ats.new(@agents).execute_action_gen(ats_api)
|
492
556
|
when :analytics
|
493
557
|
analytics_api = Rest.new(@api_aoc.params.deep_merge({
|
494
|
-
:
|
495
|
-
:
|
558
|
+
base_url: @api_aoc.params[:base_url].gsub('/api/v1','')+'/analytics/v2',
|
559
|
+
auth: {scope: AoC::SCOPE_FILES_ADMIN_USER}
|
496
560
|
}))
|
497
561
|
command_analytics=self.options.get_next_command([ :application_events, :transfers ])
|
498
562
|
case command_analytics
|
499
563
|
when :application_events
|
500
564
|
event_type=command_analytics.to_s
|
501
|
-
events=analytics_api.read("organizations/#{
|
502
|
-
return {:
|
565
|
+
events=analytics_api.read("organizations/#{@api_aoc.user_info['organization_id']}/#{event_type}")[:data][event_type]
|
566
|
+
return {type: :object_list,data: events}
|
503
567
|
when :transfers
|
504
568
|
event_type=command_analytics.to_s
|
505
569
|
filter_resource=self.options.get_option(:name,:optional) || 'organizations'
|
506
570
|
filter_id=self.options.get_option(:id,:optional) || case filter_resource
|
507
|
-
when 'organizations';
|
508
|
-
when 'users';
|
509
|
-
when 'nodes';
|
510
|
-
else raise
|
571
|
+
when 'organizations'; @api_aoc.user_info['organization_id']
|
572
|
+
when 'users'; @api_aoc.user_info['id']
|
573
|
+
when 'nodes'; @api_aoc.user_info['id']
|
574
|
+
else raise 'organizations or users for option --name'
|
511
575
|
end
|
512
576
|
#
|
513
577
|
filter=self.options.get_option(:query,:optional) || {}
|
514
|
-
raise
|
578
|
+
raise 'query must be Hash' unless filter.is_a?(Hash)
|
515
579
|
filter['limit']||=100
|
516
580
|
if self.options.get_option(:once_only,:mandatory)
|
517
581
|
saved_date=[]
|
518
582
|
startdate_persistency=PersistencyActionOnce.new(
|
519
583
|
manager: @agents[:persistency],
|
520
584
|
data: saved_date,
|
521
|
-
ids:
|
585
|
+
ids: IdGenerator.from_list(['aoc_ana_date',self.options.get_option(:url,:mandatory),@workspace_name].push(filter_resource,filter_id)))
|
522
586
|
start_datetime=saved_date.first
|
523
587
|
stop_datetime=Time.now.utc.strftime('%FT%T.%LZ')
|
524
588
|
#Log.log().error("start: #{start_datetime}")
|
@@ -527,38 +591,26 @@ module Aspera
|
|
527
591
|
filter['start_time'] = start_datetime unless start_datetime.nil?
|
528
592
|
filter['stop_time'] = stop_datetime
|
529
593
|
end
|
530
|
-
notification=self.options.get_option(:notify,:optional)
|
531
594
|
events=analytics_api.read("#{filter_resource}/#{filter_id}/#{event_type}",option_url_query(filter))[:data][event_type]
|
532
595
|
startdate_persistency.save unless startdate_persistency.nil?
|
533
|
-
if !
|
534
|
-
|
535
|
-
|
536
|
-
email_to_send={}
|
537
|
-
notification.each do |k,v|
|
538
|
-
email_to_send[k.to_sym]=ERB.new(v).result(binding)
|
539
|
-
end
|
540
|
-
Log.log().error("send email: #{email_to_send}")
|
541
|
-
self.config.send_email(email_to_send)
|
596
|
+
if !self.options.get_option(:notif_to,:optional).nil?
|
597
|
+
events.each do |tr_event|
|
598
|
+
self.config.send_email_template({ev: tr_event})
|
542
599
|
end
|
543
600
|
end
|
544
|
-
return {:
|
601
|
+
return {type: :object_list,data: events}
|
545
602
|
end
|
546
603
|
when :resource
|
547
|
-
resource_type=self.options.get_next_argument('resource',[:self,:organization,:user,:group,:client,:contact,:dropbox,:node,:operation,:package,:saml_configuration, :workspace, :dropbox_membership,:short_link,:workspace_membership,:
|
548
|
-
# get path on API
|
604
|
+
resource_type=self.options.get_next_argument('resource',[:self,:organization,:user,:group,:client,:contact,:dropbox,:node,:operation,:package,:saml_configuration, :workspace, :dropbox_membership,:short_link,:workspace_membership,:application,:client_registration_token,:client_access_key,:kms_profile])
|
605
|
+
# get path on API, resource type is singular, but api is plural
|
549
606
|
resource_class_path=case resource_type
|
550
|
-
|
551
|
-
|
552
|
-
when :
|
553
|
-
|
554
|
-
when :dropbox
|
555
|
-
|
556
|
-
|
557
|
-
"admin/#{resource_type}s"
|
558
|
-
when :kms_profile
|
559
|
-
"integrations/#{resource_type}s"
|
560
|
-
else
|
561
|
-
resource_type.to_s+'s'
|
607
|
+
# special cases: singleton, in admin, with x
|
608
|
+
when :self,:organization; resource_type
|
609
|
+
when :client_registration_token,:client_access_key; "admin/#{resource_type}s"
|
610
|
+
when :application; 'admin/apps_new'
|
611
|
+
when :dropbox; resource_type.to_s+'es'
|
612
|
+
when :kms_profile; "integrations/#{resource_type}s"
|
613
|
+
else resource_type.to_s+'s'
|
562
614
|
end
|
563
615
|
# build list of supported operations
|
564
616
|
singleton_object=[:self,:organization].include?(resource_type)
|
@@ -573,19 +625,14 @@ module Aspera
|
|
573
625
|
if !singleton_object and !global_operations.include?(command)
|
574
626
|
res_id=self.options.get_option(:id)
|
575
627
|
res_name=self.options.get_option(:name)
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
matching=@api_aoc.read(resource_class_path,{:q=>res_name})[:data]
|
584
|
-
raise CliError,"no resource match name" if matching.empty?
|
585
|
-
raise CliError,"several resources match name (#{matching.join(',')})" unless matching.length.eql?(1)
|
586
|
-
res_id=matching.first['id']
|
628
|
+
raise "Provide id or name, not both" unless res_id.nil? or res_name.nil?
|
629
|
+
# try to find item by name (single partial match or exact match)
|
630
|
+
res_id=lookup_single(resource_class_path,res_name)['id'] if !res_name.nil?
|
631
|
+
# if no name or id option, taken on command line (after command)
|
632
|
+
if res_id.nil?
|
633
|
+
res_id=self.options.get_next_argument('identifier')
|
634
|
+
res_id=lookup_single(resource_class_path,self.options.get_next_argument('identifier'))['id'] if res_id.eql?('name')
|
587
635
|
end
|
588
|
-
raise CliBadArgument,"provide either id or name" if res_id.nil?
|
589
636
|
resource_instance_path="#{resource_class_path}/#{res_id}"
|
590
637
|
end
|
591
638
|
resource_instance_path=resource_class_path if singleton_object
|
@@ -595,30 +642,33 @@ module Aspera
|
|
595
642
|
id_result='token' if resource_class_path.eql?('admin/client_registration_tokens')
|
596
643
|
# TODO: report inconsistency: creation url is !=, and does not return id.
|
597
644
|
resource_class_path='admin/client_registration/token' if resource_class_path.eql?('admin/client_registration_tokens')
|
598
|
-
list_or_one=self.options.get_next_argument(
|
645
|
+
list_or_one=self.options.get_next_argument('creation data (Hash)')
|
599
646
|
return do_bulk_operation(list_or_one,'created',id_result)do|params|
|
600
|
-
raise
|
647
|
+
raise 'expecting Hash' unless params.is_a?(Hash)
|
601
648
|
@api_aoc.create(resource_class_path,params)[:data]
|
602
649
|
end
|
603
650
|
when :list
|
604
|
-
default_fields=['id'
|
605
|
-
|
651
|
+
default_fields=['id']
|
652
|
+
default_query={}
|
606
653
|
case resource_type
|
607
|
-
when :
|
654
|
+
when :application; default_query={organization_apps: true};default_fields.push('app_type','app_name','available','direct_authorizations_allowed','workspace_authorizations_allowed')
|
655
|
+
when :client,:client_access_key,:dropbox,:group,:package,:saml_configuration,:workspace; default_fields.push('name')
|
656
|
+
when :client_registration_token; default_fields.push('value','data.client_subject_scopes','created_at')
|
657
|
+
when :contact; default_fields=['email','name','source_id','source_type']
|
658
|
+
when :node; default_fields.push('name','host','access_key')
|
608
659
|
when :operation; default_fields=nil
|
609
|
-
when :
|
610
|
-
when :
|
611
|
-
when :client_registration_token; default_fields=['id','value','data.client_subject_scopes','created_at']
|
660
|
+
when :short_link; default_fields.push('short_url','data.url_token_data.purpose')
|
661
|
+
when :user; default_fields.push('name','email')
|
612
662
|
end
|
613
|
-
|
614
|
-
count_msg="Items: #{
|
615
|
-
count_msg=count_msg.bg_red unless
|
663
|
+
item_list,total_count=read_with_paging(resource_class_path,option_url_query(default_query))
|
664
|
+
count_msg="Items: #{item_list.length}/#{total_count}"
|
665
|
+
count_msg=count_msg.bg_red unless item_list.length.eql?(total_count.to_i)
|
616
666
|
self.format.display_status(count_msg)
|
617
|
-
return {:
|
667
|
+
return {type: :object_list,data: item_list,fields: default_fields}
|
618
668
|
when :show
|
619
669
|
object=@api_aoc.read(resource_instance_path)[:data]
|
620
670
|
fields=object.keys.select{|k|!k.eql?('certificate')}
|
621
|
-
return { :
|
671
|
+
return { type: :single_object, data: object, fields: fields }
|
622
672
|
when :modify
|
623
673
|
changes=self.options.get_next_argument('modified parameters (hash)')
|
624
674
|
@api_aoc.update(resource_instance_path,changes)
|
@@ -632,20 +682,20 @@ module Aspera
|
|
632
682
|
# special : reads private and generate public
|
633
683
|
the_private_key=self.options.get_next_argument('private_key')
|
634
684
|
the_public_key=OpenSSL::PKey::RSA.new(the_private_key).public_key.to_s
|
635
|
-
@api_aoc.update(resource_instance_path,{:
|
685
|
+
@api_aoc.update(resource_instance_path,{jwt_grant_enabled: true, public_key: the_public_key})
|
636
686
|
return Main.result_success
|
637
687
|
when :v3,:v4
|
638
688
|
res_data=@api_aoc.read(resource_instance_path)[:data]
|
639
689
|
api_node=@api_aoc.get_node_api(res_data)
|
640
690
|
return Node.new(@agents.merge(skip_basic_auth_options: true, node_api: api_node)).execute_action if command.eql?(:v3)
|
641
|
-
ak_data=api_node.call({:
|
691
|
+
ak_data=api_node.call({operation: 'GET',subpath: "access_keys/#{res_data['access_key']}",headers: {'Accept'=>'application/json'}})[:data]
|
642
692
|
command_repo=self.options.get_next_command(NODE4_COMMANDS)
|
643
693
|
return execute_node_gen4_command(command_repo,{node_info: res_data, file_id: ak_data['root_file_id']})
|
644
694
|
when :shared_folders
|
645
695
|
read_params = case resource_type
|
646
|
-
when :workspace;{'access_id'=>"
|
647
|
-
when :node;{'include'=>['[]','access_level','permission_count'],'created_by_id'=>
|
648
|
-
else raise
|
696
|
+
when :workspace;{'access_id'=>"#{ID_AK_ADMIN}_WS_#{res_id}",'access_type'=>'user'}
|
697
|
+
when :node;{'include'=>['[]','access_level','permission_count'],'created_by_id'=>ID_AK_ADMIN}
|
698
|
+
else raise 'error'
|
649
699
|
end
|
650
700
|
res_data=@api_aoc.read("#{resource_class_path}/#{res_id}/permissions",read_params)[:data]
|
651
701
|
fields=case resource_type
|
@@ -653,18 +703,18 @@ module Aspera
|
|
653
703
|
when :workspace;['id','node_id','file_id','node_name','file.path','tags.aspera.files.workspace.share_as']
|
654
704
|
else raise "unexpected resource type #{resource_type}"
|
655
705
|
end
|
656
|
-
return { :
|
706
|
+
return { type: :object_list, data: res_data , fields: fields}
|
657
707
|
when :shared_create
|
658
|
-
# TODO
|
708
|
+
# TODO: finish implementation
|
659
709
|
folder_path=self.options.get_next_argument('folder path in node')
|
660
710
|
user_create_data=self.options.get_next_argument('creation data (Hash)')
|
661
711
|
res_data=@api_aoc.read(resource_instance_path)[:data]
|
662
712
|
node_file = @api_aoc.resolve_node_file({node_info: res_data, file_id: ak_data['root_file_id']},folder_path)
|
663
713
|
|
664
|
-
#node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
714
|
+
#node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
|
665
715
|
#file_info = node_api.read("files/#{node_file[:file_id]}")[:data]
|
666
716
|
|
667
|
-
access_id="
|
717
|
+
access_id="#{ID_AK_ADMIN}_WS_#{@workspace_id}"
|
668
718
|
create_data={
|
669
719
|
'file_id' =>node_file[:file_id],
|
670
720
|
'access_type' =>'user',
|
@@ -674,10 +724,10 @@ module Aspera
|
|
674
724
|
'id' =>@workspace_id,
|
675
725
|
'workspace_name' =>@workspace_name,
|
676
726
|
'share_as' =>File.basename(folder_path),
|
677
|
-
'user_name'
|
678
|
-
'shared_by_user_id'
|
679
|
-
'shared_by_name'
|
680
|
-
'shared_by_email'
|
727
|
+
'user_name' =>@api_aoc.user_info['name'],
|
728
|
+
'shared_by_user_id'=>@api_aoc.user_info['id'],
|
729
|
+
'shared_by_name' =>@api_aoc.user_info['name'],
|
730
|
+
'shared_by_email' =>@api_aoc.user_info['email'],
|
681
731
|
'shared_with_name' =>access_id,
|
682
732
|
'access_key' =>node_file[:node_info]['access_key'],
|
683
733
|
'node' =>node_file[:node_info]['name']}
|
@@ -685,15 +735,15 @@ module Aspera
|
|
685
735
|
create_data.deep_merge!(user_create_data)
|
686
736
|
Log.dump(:data,create_data)
|
687
737
|
raise :ERROR
|
688
|
-
else raise
|
738
|
+
else raise 'unknown command'
|
689
739
|
end
|
690
740
|
when :usage_reports
|
691
|
-
return {:
|
741
|
+
return {type: :object_list,data: @api_aoc.read('usage_reports',{workspace_id: @workspace_id})[:data]}
|
692
742
|
end
|
693
743
|
end
|
694
744
|
|
695
745
|
# must be public
|
696
|
-
ACTIONS=[ :reminder, :bearer_token, :organization, :tier_restrictions, :user, :workspace, :packages, :files, :gateway, :admin, :automation, :servers]
|
746
|
+
ACTIONS=[ :reminder, :bearer_token, :organization, :tier_restrictions, :user, :workspace, :packages, :files, :gateway, :admin, :automation, :servers].freeze
|
697
747
|
|
698
748
|
def execute_action
|
699
749
|
command=self.options.get_next_command(ACTIONS)
|
@@ -705,38 +755,38 @@ module Aspera
|
|
705
755
|
Rest.new(base_url: "#{AoC.api_base_url}/#{AoC::API_V1}").create('organization_reminders',{email: user_email})[:data]
|
706
756
|
return Main.result_status("List of organizations user is member of, has been sent by e-mail to #{user_email}")
|
707
757
|
when :bearer_token
|
708
|
-
return {:
|
758
|
+
return {type: :text,data: @api_aoc.oauth_token}
|
709
759
|
when :organization
|
710
|
-
return { :
|
760
|
+
return { type: :single_object, data: @api_aoc.read('organization')[:data] }
|
711
761
|
when :tier_restrictions
|
712
|
-
return { :
|
762
|
+
return { type: :single_object, data: @api_aoc.read('tier_restrictions')[:data] }
|
713
763
|
when :user
|
714
764
|
command=self.options.get_next_command([ :workspaces,:info,:shared_inboxes ])
|
715
765
|
case command
|
716
766
|
when :workspaces
|
717
|
-
return {:
|
767
|
+
return {type: :object_list,data: @api_aoc.read('workspaces')[:data],fields: ['id','name']}
|
718
768
|
# when :settings
|
719
|
-
# return {:
|
769
|
+
# return {type: :object_list,data: @api_aoc.read('client_settings/')[:data]}
|
720
770
|
when :shared_inboxes
|
721
771
|
query=option_url_query(nil)
|
722
772
|
if query.nil?
|
723
773
|
set_workspace_info
|
724
774
|
query={'embed[]'=>'dropbox','workspace_id'=>@workspace_id,'aggregate_permissions_by_dropbox'=>true,'sort'=>'dropbox_name'}
|
725
775
|
end
|
726
|
-
return {:
|
776
|
+
return {type: :object_list,data: @api_aoc.read('dropbox_memberships',query)[:data],fields: ['dropbox_id','dropbox.name']}
|
727
777
|
when :info
|
728
778
|
command=self.options.get_next_command([ :show,:modify ])
|
729
779
|
case command
|
730
780
|
when :show
|
731
|
-
return { :
|
781
|
+
return { type: :single_object, data: @api_aoc.user_info }
|
732
782
|
when :modify
|
733
|
-
@api_aoc.update("users/#{
|
783
|
+
@api_aoc.update("users/#{@api_aoc.user_info['id']}",self.options.get_next_argument('modified parameters (hash)'))
|
734
784
|
return Main.result_status('modified')
|
735
785
|
end
|
736
786
|
end
|
737
787
|
when :workspace # show current workspace parameters
|
738
788
|
set_workspace_info
|
739
|
-
return { :
|
789
|
+
return { type: :single_object, data: @workspace_data }
|
740
790
|
when :packages
|
741
791
|
set_workspace_info if @url_token_data.nil?
|
742
792
|
command_pkg=self.options.get_next_command([ :send, :recv, :list, :show, :delete ])
|
@@ -761,7 +811,7 @@ module Aspera
|
|
761
811
|
resolve_package_recipients(package_creation,'recipients')
|
762
812
|
resolve_package_recipients(package_creation,'bcc_recipients')
|
763
813
|
|
764
|
-
# create a new package
|
814
|
+
# create a new package container
|
765
815
|
package_info=@api_aoc.create('packages',package_creation)[:data]
|
766
816
|
|
767
817
|
# get node information for the node on which package must be created
|
@@ -772,24 +822,24 @@ module Aspera
|
|
772
822
|
|
773
823
|
# execute transfer
|
774
824
|
node_file = {node_info: node_info, file_id: package_info['contents_file_id']}
|
775
|
-
# raise
|
825
|
+
# raise exception if at least one error
|
776
826
|
Main.result_transfer(transfer_start(AoC::PACKAGES_APP,'send',node_file,AoC.package_tags(package_info,'upload')))
|
777
827
|
# return all info on package
|
778
|
-
return { :
|
828
|
+
return { type: :single_object, data: package_info}
|
779
829
|
when :recv
|
780
830
|
if !@url_token_data.nil?
|
781
831
|
assert_public_link_types(['view_received_package'])
|
782
832
|
self.options.set_option(:id,@url_token_data['data']['package_id'])
|
783
833
|
end
|
784
834
|
# scalar here
|
785
|
-
ids_to_download=self.
|
835
|
+
ids_to_download=self.instance_identifier()
|
786
836
|
skip_ids_data=[]
|
787
837
|
skip_ids_persistency=nil
|
788
838
|
if self.options.get_option(:once_only,:mandatory)
|
789
839
|
skip_ids_persistency=PersistencyActionOnce.new(
|
790
840
|
manager: @agents[:persistency],
|
791
841
|
data: skip_ids_data,
|
792
|
-
|
842
|
+
id: IdGenerator.from_list(['aoc_recv',self.options.get_option(:url,:mandatory),@workspace_id].push(*@persist_ids)))
|
793
843
|
end
|
794
844
|
if ids_to_download.eql?(VAL_ALL)
|
795
845
|
# get list of packages in inbox
|
@@ -810,24 +860,26 @@ module Aspera
|
|
810
860
|
add_ts={'paths'=>[{'source'=>'.'}]}
|
811
861
|
node_file = {node_info: node_info, file_id: package_info['contents_file_id']}
|
812
862
|
statuses=transfer_start(AoC::PACKAGES_APP,'receive',node_file,AoC.package_tags(package_info,'download').merge(add_ts))
|
813
|
-
result_transfer.push({'package'=>package_id,
|
863
|
+
result_transfer.push({'package'=>package_id,Main::STATUS_FIELD=>statuses})
|
814
864
|
# update skip list only if all transfer sessions completed
|
815
865
|
if TransferAgent.session_status(statuses).eql?(:success)
|
816
866
|
skip_ids_data.push(package_id)
|
817
867
|
skip_ids_persistency.save unless skip_ids_persistency.nil?
|
818
868
|
end
|
819
869
|
end
|
820
|
-
return
|
870
|
+
return Main.result_transfer_multiple(result_transfer)
|
821
871
|
when :show
|
822
872
|
package_id=self.options.get_next_argument('package ID')
|
823
873
|
package_info=@api_aoc.read("packages/#{package_id}")[:data]
|
824
|
-
return { :
|
874
|
+
return { type: :single_object, data: package_info }
|
825
875
|
when :list
|
826
|
-
|
827
|
-
|
828
|
-
|
876
|
+
query=option_url_query({'archived'=>false,'exclude_dropbox_packages'=>true,'has_content'=>true,'received'=>true})
|
877
|
+
raise 'option must be Hash' unless query.is_a?(Hash)
|
878
|
+
query['workspace_id']||=@workspace_id
|
879
|
+
packages=@api_aoc.read('packages',query)[:data]
|
880
|
+
return {type: :object_list,data: packages,fields: ['id','name','bytes_transferred']}
|
829
881
|
when :delete
|
830
|
-
list_or_one=self.
|
882
|
+
list_or_one=self.instance_identifier()
|
831
883
|
return do_bulk_operation(list_or_one,'deleted')do|id|
|
832
884
|
raise 'expecting String identifier' unless id.is_a?(String) or id.is_a?(Integer)
|
833
885
|
@api_aoc.delete("packages/#{id}")[:data]
|
@@ -837,7 +889,7 @@ module Aspera
|
|
837
889
|
# get workspace related information
|
838
890
|
set_workspace_info
|
839
891
|
set_home_node_file
|
840
|
-
command_repo=self.options.get_next_command(NODE4_COMMANDS
|
892
|
+
command_repo=self.options.get_next_command([NODE4_COMMANDS,:short_link].flatten)
|
841
893
|
case command_repo
|
842
894
|
when *NODE4_COMMANDS; return execute_node_gen4_command(command_repo,@home_node_file)
|
843
895
|
when :short_link
|
@@ -883,7 +935,7 @@ module Aspera
|
|
883
935
|
end
|
884
936
|
result=self.entity_action(@api_aoc,'short_links',nil,:id,'self')
|
885
937
|
if result[:data].is_a?(Hash) and result[:data].has_key?('created_at') and result[:data]['resource_type'].eql?('UrlToken')
|
886
|
-
node_api=@api_aoc.get_node_api(node_file[:node_info],AoC::SCOPE_NODE_USER)
|
938
|
+
node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
|
887
939
|
# TODO: access level as arg
|
888
940
|
access_levels=Aspera::Node::ACCESS_LEVELS #['delete','list','mkdir','preview','read','rename','write']
|
889
941
|
perm_data={
|
@@ -896,8 +948,8 @@ module Aspera
|
|
896
948
|
'workspace_id' =>@workspace_id,
|
897
949
|
'workspace_name' =>@workspace_name,
|
898
950
|
'folder_name' =>'my folder',
|
899
|
-
'created_by_name'
|
900
|
-
'created_by_email'
|
951
|
+
'created_by_name' =>@api_aoc.user_info['name'],
|
952
|
+
'created_by_email'=>@api_aoc.user_info['email'],
|
901
953
|
'access_key' =>node_file[:node_info]['access_key'],
|
902
954
|
'node' =>node_file[:node_info]['host']
|
903
955
|
}
|
@@ -907,9 +959,9 @@ module Aspera
|
|
907
959
|
end
|
908
960
|
return result
|
909
961
|
end # files command
|
910
|
-
throw
|
962
|
+
throw 'Error: shall not reach this line'
|
911
963
|
when :automation
|
912
|
-
Log.log.warn(
|
964
|
+
Log.log.warn('BETA: work under progress')
|
913
965
|
# automation api is not in the same place
|
914
966
|
automation_rest_params=@api_aoc.params.clone
|
915
967
|
automation_rest_params[:base_url].gsub!('/api/','/automation/')
|
@@ -925,18 +977,18 @@ module Aspera
|
|
925
977
|
when *Plugin::ALL_OPS
|
926
978
|
return self.entity_command(wf_command,automation_api,'workflows',nil,:id)
|
927
979
|
when :launch
|
928
|
-
wf_id=self.
|
980
|
+
wf_id=self.instance_identifier()
|
929
981
|
data=automation_api.create("workflows/#{wf_id}/launch",{})[:data]
|
930
|
-
return {:
|
982
|
+
return {type: :single_object,data: data}
|
931
983
|
when :action
|
932
984
|
wf_command=self.options.get_next_command([:list,:create,:show])
|
933
|
-
wf_id=self.
|
985
|
+
wf_id=self.instance_identifier()
|
934
986
|
step=automation_api.create('steps',{'workflow_id'=>wf_id})[:data]
|
935
|
-
automation_api.update("workflows/#{wf_id}",{'step_order'=>[step[
|
936
|
-
action=automation_api.create('actions',{'step_id'=>step[
|
937
|
-
automation_api.update("steps/#{step[
|
987
|
+
automation_api.update("workflows/#{wf_id}",{'step_order'=>[step['id']]})
|
988
|
+
action=automation_api.create('actions',{'step_id'=>step['id'],'type'=>'manual'})[:data]
|
989
|
+
automation_api.update("steps/#{step['id']}",{'action_order'=>[action['id']]})
|
938
990
|
wf=automation_api.read("workflows/#{wf_id}")[:data]
|
939
|
-
return {:
|
991
|
+
return {type: :single_object,data: wf}
|
940
992
|
end
|
941
993
|
end
|
942
994
|
when :gateway
|
@@ -946,15 +998,15 @@ module Aspera
|
|
946
998
|
when :admin
|
947
999
|
return execute_admin_action
|
948
1000
|
when :servers
|
949
|
-
return {:
|
1001
|
+
return {type: :object_list,data: Rest.new(base_url: "#{AoC.api_base_url}/#{AoC::API_V1}").read('servers')[:data]}
|
950
1002
|
else
|
951
1003
|
raise "internal error: #{command}"
|
952
1004
|
end # action
|
953
|
-
raise RuntimeError,
|
1005
|
+
raise RuntimeError, 'internal error: command shall return'
|
954
1006
|
end
|
955
1007
|
|
956
|
-
private :
|
957
|
-
private_constant :VAL_ALL,:NODE4_COMMANDS
|
1008
|
+
private :aoc_params,:set_workspace_info,:set_home_node_file,:do_bulk_operation,:resolve_package_recipients,:option_url_query,:assert_public_link_types,:execute_admin_action
|
1009
|
+
private_constant :VAL_ALL,:NODE4_COMMANDS, :ID_AK_ADMIN
|
958
1010
|
|
959
1011
|
end # AoC
|
960
1012
|
end # Plugins
|