aspera-cli 4.10.0 → 4.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/BUGS.md +19 -0
- data/CHANGELOG.md +528 -0
- data/CONTRIBUTING.md +143 -0
- data/README.md +977 -589
- data/bin/ascli +4 -4
- data/bin/asession +12 -12
- data/docs/test_env.conf +29 -19
- data/examples/aoc.rb +6 -6
- data/examples/dascli +18 -16
- data/examples/faspex4.rb +15 -15
- data/examples/node.rb +12 -12
- data/examples/proxy.pac +2 -2
- data/examples/server.rb +12 -12
- data/lib/aspera/aoc.rb +344 -272
- data/lib/aspera/ascmd.rb +56 -54
- data/lib/aspera/ats_api.rb +4 -4
- data/lib/aspera/cli/basic_auth_plugin.rb +15 -12
- data/lib/aspera/cli/extended_value.rb +9 -9
- data/lib/aspera/cli/{formater.rb → formatter.rb} +69 -69
- data/lib/aspera/cli/listener/line_dump.rb +1 -1
- data/lib/aspera/cli/listener/logger.rb +1 -1
- data/lib/aspera/cli/listener/progress.rb +5 -6
- data/lib/aspera/cli/listener/progress_multi.rb +16 -21
- data/lib/aspera/cli/main.rb +72 -73
- data/lib/aspera/cli/manager.rb +112 -112
- data/lib/aspera/cli/plugin.rb +68 -48
- data/lib/aspera/cli/plugins/alee.rb +4 -4
- data/lib/aspera/cli/plugins/aoc.rb +322 -720
- data/lib/aspera/cli/plugins/ats.rb +50 -52
- data/lib/aspera/cli/plugins/bss.rb +10 -10
- data/lib/aspera/cli/plugins/config.rb +514 -410
- data/lib/aspera/cli/plugins/console.rb +12 -12
- data/lib/aspera/cli/plugins/cos.rb +18 -20
- data/lib/aspera/cli/plugins/faspex.rb +134 -136
- data/lib/aspera/cli/plugins/faspex5.rb +235 -70
- data/lib/aspera/cli/plugins/node.rb +378 -309
- data/lib/aspera/cli/plugins/orchestrator.rb +52 -49
- data/lib/aspera/cli/plugins/preview.rb +129 -120
- data/lib/aspera/cli/plugins/server.rb +137 -83
- data/lib/aspera/cli/plugins/shares.rb +77 -52
- data/lib/aspera/cli/plugins/sync.rb +13 -33
- data/lib/aspera/cli/transfer_agent.rb +61 -61
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +3 -3
- data/lib/aspera/command_line_builder.rb +78 -74
- data/lib/aspera/cos_node.rb +31 -29
- data/lib/aspera/data_repository.rb +1 -1
- data/lib/aspera/environment.rb +30 -28
- data/lib/aspera/fasp/agent_base.rb +17 -15
- data/lib/aspera/fasp/agent_connect.rb +34 -32
- data/lib/aspera/fasp/agent_direct.rb +70 -73
- data/lib/aspera/fasp/agent_httpgw.rb +79 -74
- data/lib/aspera/fasp/agent_node.rb +26 -26
- data/lib/aspera/fasp/agent_trsdk.rb +20 -20
- data/lib/aspera/fasp/error.rb +3 -2
- data/lib/aspera/fasp/error_info.rb +11 -8
- data/lib/aspera/fasp/installation.rb +80 -80
- data/lib/aspera/fasp/listener.rb +2 -2
- data/lib/aspera/fasp/parameters.rb +103 -92
- data/lib/aspera/fasp/parameters.yaml +313 -214
- data/lib/aspera/fasp/resume_policy.rb +10 -10
- data/lib/aspera/fasp/transfer_spec.rb +22 -2
- data/lib/aspera/fasp/uri.rb +7 -7
- data/lib/aspera/faspex_gw.rb +80 -159
- data/lib/aspera/faspex_postproc.rb +77 -0
- data/lib/aspera/hash_ext.rb +3 -3
- data/lib/aspera/id_generator.rb +5 -5
- data/lib/aspera/keychain/encrypted_hash.rb +23 -28
- data/lib/aspera/keychain/macos_security.rb +21 -20
- data/lib/aspera/log.rb +13 -13
- data/lib/aspera/nagios.rb +24 -23
- data/lib/aspera/node.rb +217 -38
- data/lib/aspera/oauth.rb +78 -74
- data/lib/aspera/open_application.rb +19 -11
- data/lib/aspera/persistency_action_once.rb +4 -4
- data/lib/aspera/persistency_folder.rb +13 -13
- data/lib/aspera/preview/file_types.rb +8 -8
- data/lib/aspera/preview/generator.rb +67 -67
- data/lib/aspera/preview/utils.rb +27 -27
- data/lib/aspera/proxy_auto_config.js +63 -63
- data/lib/aspera/proxy_auto_config.rb +19 -19
- data/lib/aspera/rest.rb +65 -67
- data/lib/aspera/rest_call_error.rb +2 -1
- data/lib/aspera/rest_error_analyzer.rb +22 -21
- data/lib/aspera/rest_errors_aspera.rb +16 -16
- data/lib/aspera/secret_hider.rb +17 -14
- data/lib/aspera/ssh.rb +15 -14
- data/lib/aspera/sync.rb +177 -62
- data/lib/aspera/temp_file_manager.rb +2 -2
- data/lib/aspera/uri_reader.rb +4 -4
- data/lib/aspera/web_auth.rb +13 -64
- data/lib/aspera/web_server_simple.rb +76 -0
- data.tar.gz.sig +0 -0
- metadata +11 -6
- metadata.gz.sig +0 -0
@@ -1,104 +1,170 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# spellchecker: ignore workgroups,mypackages
|
4
|
+
|
3
5
|
require 'aspera/cli/basic_auth_plugin'
|
4
6
|
require 'aspera/persistency_action_once'
|
5
7
|
require 'aspera/id_generator'
|
6
8
|
require 'aspera/nagios'
|
9
|
+
require 'aspera/environment'
|
7
10
|
require 'securerandom'
|
11
|
+
require 'ruby-progressbar'
|
12
|
+
require 'tty-spinner'
|
8
13
|
|
9
14
|
module Aspera
|
10
15
|
module Cli
|
11
16
|
module Plugins
|
12
|
-
class Faspex5 < BasicAuthPlugin
|
17
|
+
class Faspex5 < Aspera::Cli::BasicAuthPlugin
|
18
|
+
RECIPIENT_TYPES = %w[user workgroup external_user distribution_list shared_inbox].freeze
|
19
|
+
PACKAGE_TERMINATED = %w[completed failed].freeze
|
20
|
+
API_DETECT = 'api/v5/configuration/ping'
|
13
21
|
class << self
|
14
22
|
def detect(base_url)
|
15
23
|
api = Rest.new(base_url: base_url, redirect_max: 1)
|
16
|
-
result = api.read(
|
24
|
+
result = api.read(API_DETECT)
|
17
25
|
if result[:http].code.start_with?('2') && result[:http].body.strip.empty?
|
18
|
-
return {version: '5'}
|
26
|
+
return {version: '5', url: result[:http].uri.to_s[0..-(API_DETECT.length + 2)]}
|
19
27
|
end
|
20
28
|
return nil
|
21
29
|
end
|
22
30
|
end
|
23
31
|
|
24
|
-
VAL_ALL = 'ALL'
|
25
32
|
TRANSFER_CONNECT = 'connect'
|
26
|
-
private_constant :VAL_ALL,:TRANSFER_CONNECT
|
27
33
|
|
28
34
|
def initialize(env)
|
29
35
|
super(env)
|
30
|
-
options.add_opt_simple(:client_id,'OAuth client identifier')
|
31
|
-
options.add_opt_simple(:client_secret,'OAuth client secret')
|
32
|
-
options.add_opt_simple(:redirect_uri,'OAuth redirect URI for web authentication')
|
33
|
-
options.add_opt_list(:auth,[Oauth::STD_AUTH_TYPES
|
34
|
-
options.add_opt_simple(:private_key,'OAuth JWT RSA private key PEM value (prefix file path with @file:)')
|
35
|
-
options.add_opt_simple(:passphrase,'RSA private key passphrase')
|
36
|
-
options.
|
36
|
+
options.add_opt_simple(:client_id, 'OAuth client identifier')
|
37
|
+
options.add_opt_simple(:client_secret, 'OAuth client secret')
|
38
|
+
options.add_opt_simple(:redirect_uri, 'OAuth redirect URI for web authentication')
|
39
|
+
options.add_opt_list(:auth, [:boot].concat(Oauth::STD_AUTH_TYPES), 'OAuth type of authentication')
|
40
|
+
options.add_opt_simple(:private_key, 'OAuth JWT RSA private key PEM value (prefix file path with @file:)')
|
41
|
+
options.add_opt_simple(:passphrase, 'RSA private key passphrase')
|
42
|
+
options.add_opt_simple(:shared_folder, 'Shared folder source for package files')
|
43
|
+
options.set_option(:auth, :jwt)
|
37
44
|
options.parse_options!
|
38
45
|
end
|
39
46
|
|
40
47
|
def set_api
|
41
|
-
@
|
42
|
-
@
|
43
|
-
|
44
|
-
case options.get_option(:auth,is_type: :mandatory)
|
48
|
+
@faspex5_api_base_url = options.get_option(:url, is_type: :mandatory).gsub(%r{/+$}, '')
|
49
|
+
@faspex5_api_auth_url = "#{@faspex5_api_base_url}/auth"
|
50
|
+
faspex5_api_v5_url = "#{@faspex5_api_base_url}/api/v5"
|
51
|
+
case options.get_option(:auth, is_type: :mandatory)
|
45
52
|
when :boot
|
46
53
|
# the password here is the token copied directly from browser in developer mode
|
47
54
|
@api_v5 = Rest.new({
|
48
|
-
base_url:
|
49
|
-
headers: {'Authorization' => options.get_option(:password,is_type: :mandatory)}
|
55
|
+
base_url: faspex5_api_v5_url,
|
56
|
+
headers: {'Authorization' => options.get_option(:password, is_type: :mandatory)}
|
50
57
|
})
|
51
58
|
when :web
|
52
59
|
# opens a browser and ask user to auth using web
|
53
60
|
@api_v5 = Rest.new({
|
54
|
-
base_url:
|
61
|
+
base_url: faspex5_api_v5_url,
|
55
62
|
auth: {
|
56
|
-
type:
|
57
|
-
base_url:
|
58
|
-
|
59
|
-
client_id:
|
60
|
-
web:
|
63
|
+
type: :oauth2,
|
64
|
+
base_url: @faspex5_api_auth_url,
|
65
|
+
grant_method: :web,
|
66
|
+
client_id: options.get_option(:client_id, is_type: :mandatory),
|
67
|
+
web: {redirect_uri: options.get_option(:redirect_uri, is_type: :mandatory)}
|
61
68
|
}})
|
62
69
|
when :jwt
|
63
|
-
app_client_id = options.get_option(:client_id,is_type: :mandatory)
|
70
|
+
app_client_id = options.get_option(:client_id, is_type: :mandatory)
|
64
71
|
@api_v5 = Rest.new({
|
65
|
-
base_url:
|
72
|
+
base_url: faspex5_api_v5_url,
|
66
73
|
auth: {
|
67
|
-
type:
|
68
|
-
base_url:
|
69
|
-
|
70
|
-
client_id:
|
71
|
-
jwt:
|
74
|
+
type: :oauth2,
|
75
|
+
base_url: @faspex5_api_auth_url,
|
76
|
+
grant_method: :jwt,
|
77
|
+
client_id: app_client_id,
|
78
|
+
jwt: {
|
72
79
|
payload: {
|
73
80
|
iss: app_client_id, # issuer
|
74
81
|
aud: app_client_id, # audience TODO: ???
|
75
|
-
sub: "user:#{options.get_option(:username,is_type: :mandatory)}" # subject also "client:#{app_client_id}" + auth user/pass
|
82
|
+
sub: "user:#{options.get_option(:username, is_type: :mandatory)}" # subject also "client:#{app_client_id}" + auth user/pass
|
76
83
|
},
|
77
|
-
#auth: {type: :basic, options.get_option(:username,is_type: :mandatory), options.get_option(:password,is_type: :mandatory),
|
78
|
-
private_key_obj: OpenSSL::PKey::RSA.new(options.get_option(:private_key,is_type: :mandatory),options.get_option(:passphrase)),
|
84
|
+
# auth: {type: :basic, options.get_option(:username,is_type: :mandatory), options.get_option(:password,is_type: :mandatory),
|
85
|
+
private_key_obj: OpenSSL::PKey::RSA.new(options.get_option(:private_key, is_type: :mandatory), options.get_option(:passphrase)),
|
79
86
|
headers: {typ: 'JWT'}
|
80
87
|
}
|
81
88
|
}})
|
82
89
|
end
|
83
90
|
end
|
84
91
|
|
85
|
-
|
92
|
+
def normalize_recipients(parameters)
|
93
|
+
return unless parameters.key?('recipients')
|
94
|
+
raise 'Field recipients must be an Array' unless parameters['recipients'].is_a?(Array)
|
95
|
+
parameters['recipients'] = parameters['recipients'].map do |recipient_data|
|
96
|
+
# if just a string, assume it is the name
|
97
|
+
if recipient_data.is_a?(String)
|
98
|
+
result = @api_v5.read('contacts', {q: recipient_data, context: 'packages', type: [Rest::ARRAY_PARAMS, *RECIPIENT_TYPES]})[:data]
|
99
|
+
raise "No matching contact for #{recipient_data}" if result.empty?
|
100
|
+
raise "Multiple matching contact for #{recipient_data} : #{result['contacts'].map{|i|i['name']}.join(', ')}" unless 1.eql?(result['total_count'])
|
101
|
+
matched = result['contacts'].first
|
102
|
+
recipient_data = {
|
103
|
+
name: matched['name'],
|
104
|
+
recipient_type: matched['type']
|
105
|
+
}
|
106
|
+
end
|
107
|
+
# result for mapping
|
108
|
+
recipient_data
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def wait_for_complete_upload(id)
|
113
|
+
parameters = options.get_option(:value)
|
114
|
+
spinner = nil
|
115
|
+
progress = nil
|
116
|
+
while true
|
117
|
+
status = @api_v5.read("packages/#{id}/upload_details")[:data]
|
118
|
+
# user asked to not follow
|
119
|
+
break unless parameters
|
120
|
+
if status['upload_status'].eql?('submitted')
|
121
|
+
if spinner.nil?
|
122
|
+
spinner = TTY::Spinner.new('[:spinner] :title', format: :classic)
|
123
|
+
spinner.start
|
124
|
+
end
|
125
|
+
spinner.update(title: status['upload_status'])
|
126
|
+
spinner.spin
|
127
|
+
elsif progress.nil?
|
128
|
+
progress = ProgressBar.create(
|
129
|
+
format: '%a %B %p%% %r Mbps %e',
|
130
|
+
rate_scale: lambda{|rate|rate / Environment::BYTES_PER_MEBIBIT},
|
131
|
+
title: 'progress',
|
132
|
+
total: status['bytes_total'].to_i)
|
133
|
+
else
|
134
|
+
progress.progress = status['bytes_written'].to_i
|
135
|
+
end
|
136
|
+
break if PACKAGE_TERMINATED.include?(status['upload_status'])
|
137
|
+
sleep(0.5)
|
138
|
+
end
|
139
|
+
status['id'] = id
|
140
|
+
return status
|
141
|
+
end
|
142
|
+
|
143
|
+
def lookup_entity(entity_type, property, value)
|
144
|
+
# TODO: what if too many, use paging ?
|
145
|
+
all = @api_v5.read(entity_type)[:data][entity_type]
|
146
|
+
found = all.find{|i|i[property].eql?(value)}
|
147
|
+
raise "No #{entity_type} with #{property} = #{value}" if found.nil?
|
148
|
+
return found
|
149
|
+
end
|
150
|
+
|
151
|
+
ACTIONS = %i[health version user bearer_token package shared_folders admin gateway postprocessing].freeze
|
86
152
|
|
87
153
|
def execute_action
|
88
|
-
set_api
|
89
154
|
command = options.get_next_command(ACTIONS)
|
155
|
+
set_api unless command.eql?(:postprocessing)
|
90
156
|
case command
|
91
157
|
when :version
|
92
158
|
return { type: :single_object, data: @api_v5.read('version')[:data] }
|
93
159
|
when :health
|
94
160
|
nagios = Nagios.new
|
95
161
|
begin
|
96
|
-
result=Rest.new(base_url: @
|
97
|
-
result.each do |k,v|
|
98
|
-
nagios.add_ok(k,v.to_s)
|
162
|
+
result = Rest.new(base_url: @faspex5_api_base_url).read('health')[:data]
|
163
|
+
result.each do |k, v|
|
164
|
+
nagios.add_ok(k, v.to_s)
|
99
165
|
end
|
100
166
|
rescue StandardError => e
|
101
|
-
nagios.add_critical('faspex api',e.to_s)
|
167
|
+
nagios.add_critical('faspex api', e.to_s)
|
102
168
|
end
|
103
169
|
return nagios.result
|
104
170
|
when :user
|
@@ -108,88 +174,187 @@ module Aspera
|
|
108
174
|
when :show
|
109
175
|
return { type: :single_object, data: @api_v5.read('account/preferences')[:data] }
|
110
176
|
when :modify
|
111
|
-
@api_v5.update('account/preferences',options.get_next_argument('modified parameters
|
177
|
+
@api_v5.update('account/preferences', options.get_next_argument('modified parameters', type: Hash))
|
112
178
|
return Main.result_status('modified')
|
113
179
|
end
|
114
180
|
end
|
115
181
|
when :bearer_token
|
116
|
-
return {type: :text,data: @api_v5.oauth_token}
|
182
|
+
return {type: :text, data: @api_v5.oauth_token}
|
117
183
|
when :package
|
118
|
-
command = options.get_next_command(%i[list show send receive])
|
184
|
+
command = options.get_next_command(%i[list show send receive status])
|
119
185
|
case command
|
120
186
|
when :list
|
121
187
|
parameters = options.get_option(:value)
|
122
188
|
return {
|
123
189
|
type: :object_list,
|
124
|
-
data: @api_v5.read('packages',parameters)[:data]['packages'],
|
190
|
+
data: @api_v5.read('packages', parameters)[:data]['packages'],
|
125
191
|
fields: %w[id title release_date total_bytes total_files created_time state]
|
126
192
|
}
|
127
193
|
when :show
|
128
194
|
id = instance_identifier
|
129
195
|
return {type: :single_object, data: @api_v5.read("packages/#{id}")[:data]}
|
196
|
+
when :status
|
197
|
+
status = wait_for_complete_upload(instance_identifier)
|
198
|
+
return {type: :single_object, data: status}
|
130
199
|
when :send
|
131
|
-
parameters = options.get_option(:value,is_type: :mandatory)
|
132
|
-
raise CliBadArgument,'
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
200
|
+
parameters = options.get_option(:value, is_type: :mandatory)
|
201
|
+
raise CliBadArgument, 'Value must be Hash, refer to API' unless parameters.is_a?(Hash)
|
202
|
+
normalize_recipients(parameters)
|
203
|
+
package = @api_v5.create('packages', parameters)[:data]
|
204
|
+
shared_folder = options.get_option(:shared_folder)
|
205
|
+
if shared_folder.nil?
|
206
|
+
# TODO: option to send from remote source or httpgw
|
207
|
+
transfer_spec = @api_v5.call(
|
208
|
+
operation: 'POST',
|
209
|
+
subpath: "packages/#{package['id']}/transfer_spec/upload",
|
210
|
+
headers: {'Accept' => 'application/json'},
|
211
|
+
url_params: {transfer_type: TRANSFER_CONNECT},
|
212
|
+
json_params: {paths: transfer.source_list}
|
213
|
+
)[:data]
|
214
|
+
transfer_spec.delete('authentication')
|
215
|
+
return Main.result_transfer(transfer.start(transfer_spec))
|
216
|
+
else
|
217
|
+
if !shared_folder.to_i.to_s.eql?(shared_folder)
|
218
|
+
shared_folder = lookup_entity('shared_folders', 'name', shared_folder)['id']
|
219
|
+
end
|
220
|
+
transfer_request = {shared_folder_id: shared_folder, paths: transfer.source_list}
|
221
|
+
# start remote transfer and get first status
|
222
|
+
result = @api_v5.create("packages/#{package['id']}/remote_transfer", transfer_request)[:data]
|
223
|
+
result['id'] = package['id']
|
224
|
+
unless result['status'].eql?('completed')
|
225
|
+
formatter.display_status("Package #{package['id']}")
|
226
|
+
result = wait_for_complete_upload(package['id'])
|
227
|
+
end
|
228
|
+
return {type: :single_object, data: result}
|
229
|
+
end
|
138
230
|
when :receive
|
139
231
|
pkg_type = 'received'
|
140
232
|
pack_id = instance_identifier
|
141
233
|
package_ids = [pack_id]
|
142
234
|
skip_ids_data = []
|
143
235
|
skip_ids_persistency = nil
|
144
|
-
if options.get_option(:once_only,is_type: :mandatory)
|
236
|
+
if options.get_option(:once_only, is_type: :mandatory)
|
145
237
|
# read ids from persistency
|
146
238
|
skip_ids_persistency = PersistencyActionOnce.new(
|
147
239
|
manager: @agents[:persistency],
|
148
240
|
data: skip_ids_data,
|
149
|
-
id: IdGenerator.from_list([
|
241
|
+
id: IdGenerator.from_list([
|
242
|
+
'faspex_recv',
|
243
|
+
options.get_option(:url, is_type: :mandatory),
|
244
|
+
options.get_option(:username, is_type: :mandatory),
|
245
|
+
pkg_type]))
|
150
246
|
end
|
151
|
-
if
|
247
|
+
if VAL_ALL.eql?(pack_id)
|
152
248
|
# TODO: if packages have same name, they will overwrite
|
153
249
|
parameters = options.get_option(:value)
|
154
|
-
parameters ||= {'type' => 'received','subtype' => 'mypackages','limit' => 1000}
|
155
|
-
raise CliBadArgument,'value filter must be Hash (API GET)' unless parameters.is_a?(Hash)
|
156
|
-
package_ids = @api_v5.read('packages',parameters)[:data]['packages'].map{|p|p['id']}
|
250
|
+
parameters ||= {'type' => 'received', 'subtype' => 'mypackages', 'limit' => 1000}
|
251
|
+
raise CliBadArgument, 'value filter must be Hash (API GET)' unless parameters.is_a?(Hash)
|
252
|
+
package_ids = @api_v5.read('packages', parameters)[:data]['packages'].map{|p|p['id']}
|
157
253
|
package_ids.reject!{|i|skip_ids_data.include?(i)}
|
158
254
|
end
|
159
255
|
result_transfer = []
|
160
|
-
package_ids.each do |
|
256
|
+
package_ids.each do |pkg_id|
|
257
|
+
param_file_list = {}
|
258
|
+
begin
|
259
|
+
param_file_list['paths'] = transfer.source_list
|
260
|
+
rescue Aspera::Cli::CliBadArgument
|
261
|
+
# paths is optional
|
262
|
+
end
|
161
263
|
# TODO: allow from sent as well ?
|
162
|
-
transfer_spec = @api_v5.
|
264
|
+
transfer_spec = @api_v5.call(
|
265
|
+
operation: 'POST',
|
266
|
+
subpath: "packages/#{pkg_id}/transfer_spec/download",
|
267
|
+
headers: {'Accept' => 'application/json'},
|
268
|
+
url_params: {transfer_type: TRANSFER_CONNECT, type: pkg_type},
|
269
|
+
json_params: param_file_list
|
270
|
+
)[:data]
|
163
271
|
transfer_spec.delete('authentication')
|
164
|
-
statuses = transfer.start(transfer_spec
|
165
|
-
result_transfer.push({'package' =>
|
272
|
+
statuses = transfer.start(transfer_spec)
|
273
|
+
result_transfer.push({'package' => pkg_id, Main::STATUS_FIELD => statuses})
|
166
274
|
# skip only if all sessions completed
|
167
|
-
skip_ids_data.push(
|
275
|
+
skip_ids_data.push(pkg_id) if TransferAgent.session_status(statuses).eql?(:success)
|
168
276
|
end
|
169
277
|
skip_ids_persistency&.save
|
170
278
|
return Main.result_transfer_multiple(result_transfer)
|
171
279
|
end # case package
|
280
|
+
when :shared_folders
|
281
|
+
all_shared_folders = @api_v5.read('shared_folders')[:data]['shared_folders']
|
282
|
+
case options.get_next_command(%i[list browse])
|
283
|
+
when :list
|
284
|
+
return {type: :object_list, data: all_shared_folders}
|
285
|
+
when :browse
|
286
|
+
shared_folder_id = instance_identifier
|
287
|
+
path = options.get_next_argument('folder path', mandatory: false) || '/'
|
288
|
+
node = all_shared_folders.find{|i|i['id'].eql?(shared_folder_id)}
|
289
|
+
raise "No such shared folder id #{shared_folder_id}" if node.nil?
|
290
|
+
result = @api_v5.call({
|
291
|
+
operation: 'POST',
|
292
|
+
subpath: "nodes/#{node['node_id']}/shared_folders/#{shared_folder_id}/browse",
|
293
|
+
headers: {'Accept' => 'application/json', 'Content-Type' => 'application/json'},
|
294
|
+
json_params: {'path': path, 'filters': {'basenames': []}},
|
295
|
+
url_params: {offset: 0, limit: 100}
|
296
|
+
})[:data]
|
297
|
+
if result.key?('items')
|
298
|
+
return {type: :object_list, data: result['items']}
|
299
|
+
else
|
300
|
+
return {type: :single_object, data: result['self']}
|
301
|
+
end
|
302
|
+
end
|
172
303
|
when :admin
|
173
|
-
case options.get_next_command([
|
304
|
+
case options.get_next_command(%i[resource])
|
174
305
|
when :resource
|
175
|
-
res_type = options.get_next_command(%i[accounts contacts jobs workgroups shared_inboxes nodes oauth_clients registrations saml_configs metadata_profiles
|
306
|
+
res_type = options.get_next_command(%i[accounts contacts jobs workgroups shared_inboxes nodes oauth_clients registrations saml_configs metadata_profiles
|
307
|
+
email_notifications])
|
176
308
|
res_path = list_key = res_type.to_s
|
309
|
+
id_as_arg = false
|
177
310
|
case res_type
|
178
311
|
when :metadata_profiles
|
179
|
-
res_path='configuration/metadata_profiles'
|
180
|
-
list_key='profiles'
|
312
|
+
res_path = 'configuration/metadata_profiles'
|
313
|
+
list_key = 'profiles'
|
314
|
+
when :email_notifications
|
315
|
+
list_key = false
|
316
|
+
id_as_arg = 'type'
|
181
317
|
end
|
182
318
|
display_fields =
|
183
319
|
case res_type
|
184
|
-
when :accounts then [:all_but,'user_profile_data_attributes']
|
185
|
-
when :oauth_clients then [:all_but,'public_key']
|
320
|
+
when :accounts then [:all_but, 'user_profile_data_attributes']
|
321
|
+
when :oauth_clients then [:all_but, 'public_key']
|
186
322
|
end
|
187
323
|
adm_api = @api_v5
|
188
324
|
if res_type.eql?(:oauth_clients)
|
189
|
-
adm_api = Rest.new(@api_v5.params.merge({base_url: @
|
325
|
+
adm_api = Rest.new(@api_v5.params.merge({base_url: @faspex5_api_auth_url}))
|
190
326
|
end
|
191
|
-
return entity_action(adm_api,res_path,item_list_key: list_key, display_fields: display_fields)
|
327
|
+
return entity_action(adm_api, res_path, item_list_key: list_key, display_fields: display_fields, id_as_arg: id_as_arg)
|
192
328
|
end
|
329
|
+
when :gateway
|
330
|
+
require 'aspera/faspex_gw'
|
331
|
+
url = options.get_option(:value, is_type: :mandatory)
|
332
|
+
uri = URI.parse(url)
|
333
|
+
server = WebServerSimple.new(uri)
|
334
|
+
server.mount(uri.path, Faspex4GWServlet, @api_v5, nil)
|
335
|
+
trap('INT') { server.shutdown }
|
336
|
+
formatter.display_status("Faspex 4 gateway listening on #{url}")
|
337
|
+
Log.log.info("Listening on #{url}")
|
338
|
+
# this is blocking until server exits
|
339
|
+
server.start
|
340
|
+
return Main.result_status('Gateway terminated')
|
341
|
+
when :postprocessing
|
342
|
+
require 'aspera/faspex_postproc'
|
343
|
+
parameters = options.get_option(:value, is_type: :mandatory)
|
344
|
+
raise 'parameters must be Hash' unless parameters.is_a?(Hash)
|
345
|
+
parameters = parameters.symbolize_keys
|
346
|
+
raise 'Missing key: url' unless parameters.key?(:url)
|
347
|
+
uri = URI.parse(parameters[:url])
|
348
|
+
parameters[:processing] ||= {}
|
349
|
+
parameters[:processing][:root] = uri.path
|
350
|
+
server = WebServerSimple.new(uri, certificate: parameters[:certificate])
|
351
|
+
server.mount(uri.path, Faspex4PostProcServlet, parameters[:processing])
|
352
|
+
trap('INT') { server.shutdown }
|
353
|
+
formatter.display_status("Faspex 4 post processing listening on #{uri.port}")
|
354
|
+
Log.log.info("Listening on #{uri.port}")
|
355
|
+
# this is blocking until server exits
|
356
|
+
server.start
|
357
|
+
return Main.result_status('Gateway terminated')
|
193
358
|
end # case command
|
194
359
|
end # action
|
195
360
|
end # Faspex5
|