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