aspera-cli 4.17.0 → 4.18.1
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 +3 -4
- data/CHANGELOG.md +33 -0
- data/CONTRIBUTING.md +15 -1
- data/README.md +711 -432
- data/bin/ascli +5 -0
- data/bin/asession +2 -2
- data/examples/build_package.sh +28 -0
- data/lib/aspera/agent/alpha.rb +10 -8
- data/lib/aspera/agent/base.rb +9 -6
- data/lib/aspera/agent/connect.rb +7 -8
- data/lib/aspera/agent/direct.rb +56 -37
- data/lib/aspera/agent/httpgw.rb +23 -324
- data/lib/aspera/agent/node.rb +19 -20
- data/lib/aspera/agent/trsdk.rb +19 -20
- data/lib/aspera/api/aoc.rb +17 -14
- data/lib/aspera/api/cos_node.rb +4 -4
- data/lib/aspera/api/httpgw.rb +342 -0
- data/lib/aspera/api/node.rb +135 -89
- data/lib/aspera/ascmd.rb +4 -3
- data/lib/aspera/ascp/installation.rb +15 -7
- data/lib/aspera/ascp/management.rb +2 -2
- data/lib/aspera/ascp/products.rb +1 -1
- data/lib/aspera/cli/basic_auth_plugin.rb +5 -9
- data/lib/aspera/cli/extended_value.rb +35 -16
- data/lib/aspera/cli/formatter.rb +161 -70
- data/lib/aspera/cli/hints.rb +18 -0
- data/lib/aspera/cli/main.rb +32 -39
- data/lib/aspera/cli/manager.rb +151 -119
- data/lib/aspera/cli/plugin.rb +27 -21
- data/lib/aspera/cli/plugin_factory.rb +31 -20
- data/lib/aspera/cli/plugins/alee.rb +14 -2
- data/lib/aspera/cli/plugins/aoc.rb +152 -141
- data/lib/aspera/cli/plugins/ats.rb +1 -1
- data/lib/aspera/cli/plugins/config.rb +72 -65
- data/lib/aspera/cli/plugins/console.rb +8 -5
- data/lib/aspera/cli/plugins/faspex.rb +32 -23
- data/lib/aspera/cli/plugins/faspex5.rb +232 -156
- data/lib/aspera/cli/plugins/faspio.rb +85 -0
- data/lib/aspera/cli/plugins/httpgw.rb +55 -0
- data/lib/aspera/cli/plugins/node.rb +129 -64
- data/lib/aspera/cli/plugins/orchestrator.rb +33 -30
- data/lib/aspera/cli/plugins/preview.rb +7 -3
- data/lib/aspera/cli/plugins/server.rb +6 -6
- data/lib/aspera/cli/plugins/shares.rb +16 -14
- data/lib/aspera/cli/special_values.rb +13 -0
- data/lib/aspera/cli/sync_actions.rb +10 -10
- data/lib/aspera/cli/transfer_agent.rb +7 -6
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/environment.rb +70 -9
- data/lib/aspera/faspex_gw.rb +5 -4
- data/lib/aspera/faspex_postproc.rb +2 -2
- data/lib/aspera/log.rb +6 -3
- data/lib/aspera/node_simulator.rb +2 -2
- data/lib/aspera/oauth/base.rb +31 -19
- data/lib/aspera/oauth/factory.rb +12 -13
- data/lib/aspera/oauth/generic.rb +1 -0
- data/lib/aspera/oauth/jwt.rb +18 -15
- data/lib/aspera/oauth/url_json.rb +8 -6
- data/lib/aspera/oauth/web.rb +2 -2
- data/lib/aspera/persistency_folder.rb +2 -2
- data/lib/aspera/preview/generator.rb +3 -3
- data/lib/aspera/preview/options.rb +3 -3
- data/lib/aspera/preview/terminal.rb +4 -4
- data/lib/aspera/preview/utils.rb +3 -3
- data/lib/aspera/proxy_auto_config.rb +5 -1
- data/lib/aspera/rest.rb +105 -88
- data/lib/aspera/rest_call_error.rb +1 -1
- data/lib/aspera/rest_error_analyzer.rb +2 -2
- data/lib/aspera/rest_errors_aspera.rb +1 -1
- data/lib/aspera/resumer.rb +1 -1
- data/lib/aspera/secret_hider.rb +2 -4
- data/lib/aspera/ssh.rb +1 -1
- data/lib/aspera/transfer/parameters.rb +39 -36
- data/lib/aspera/transfer/spec.rb +2 -0
- data/lib/aspera/transfer/sync.rb +2 -1
- data/lib/aspera/transfer/uri.rb +1 -1
- data/lib/aspera/uri_reader.rb +5 -4
- data/lib/aspera/web_auth.rb +1 -1
- data/lib/aspera/web_server_simple.rb +4 -3
- data.tar.gz.sig +0 -0
- metadata +7 -4
- metadata.gz.sig +0 -0
- data/lib/aspera/cli/plugins/bss.rb +0 -71
- data/lib/aspera/open_application.rb +0 -71
|
@@ -6,34 +6,25 @@ module Aspera
|
|
|
6
6
|
# option is retrieved from another object using accessor
|
|
7
7
|
class PluginFactory
|
|
8
8
|
include Singleton
|
|
9
|
-
attr_reader :lookup_folders, :plugins
|
|
10
9
|
|
|
11
10
|
RUBY_FILE_EXT = '.rb'
|
|
12
11
|
PLUGINS_MODULE = 'Plugins'
|
|
13
|
-
private_constant :RUBY_FILE_EXT
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
# plugins must be Capitalized
|
|
17
|
-
def plugin_class(plugin_name_sym)
|
|
18
|
-
# Module.nesting[2] is Cli::Plugins
|
|
19
|
-
return Object.const_get("#{Module.nesting[2]}::#{PLUGINS_MODULE}::#{plugin_name_sym.to_s.capitalize}")
|
|
20
|
-
end
|
|
21
|
-
end
|
|
12
|
+
private_constant :RUBY_FILE_EXT, :PLUGINS_MODULE
|
|
13
|
+
|
|
14
|
+
attr_reader :lookup_folders
|
|
22
15
|
|
|
23
16
|
def initialize
|
|
24
17
|
@lookup_folders = []
|
|
18
|
+
# information on plugins
|
|
25
19
|
@plugins = {}
|
|
26
20
|
end
|
|
27
21
|
|
|
28
|
-
def
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return
|
|
35
|
-
end
|
|
36
|
-
@plugins[plugin_symbol] = {source: path, require_stanza: req}
|
|
22
|
+
def plugin_list
|
|
23
|
+
@plugins.keys
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def plugin_source(plugin_name_sym)
|
|
27
|
+
@plugins[plugin_name_sym][:source]
|
|
37
28
|
end
|
|
38
29
|
|
|
39
30
|
def add_lookup_folder(folder)
|
|
@@ -52,9 +43,29 @@ module Aspera
|
|
|
52
43
|
end
|
|
53
44
|
end
|
|
54
45
|
|
|
46
|
+
def plugin_class(plugin_name_sym)
|
|
47
|
+
raise "ERROR: plugin not found: #{plugin_name_sym}" unless @plugins.key?(plugin_name_sym)
|
|
48
|
+
require @plugins[plugin_name_sym][:require_stanza]
|
|
49
|
+
# Module.nesting[1] is Aspera::Cli
|
|
50
|
+
return Object.const_get("#{Module.nesting[1]}::#{PLUGINS_MODULE}::#{plugin_name_sym.to_s.capitalize}")
|
|
51
|
+
end
|
|
52
|
+
|
|
55
53
|
def create(plugin_name_sym, **args)
|
|
56
54
|
# TODO: check that ancestor is Plugin?
|
|
57
|
-
|
|
55
|
+
plugin_class(plugin_name_sym).new(**args)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def add_plugin_info(path)
|
|
61
|
+
raise "ERROR: plugin path must end with #{RUBY_FILE_EXT}" if !path.end_with?(RUBY_FILE_EXT)
|
|
62
|
+
plugin_symbol = File.basename(path, RUBY_FILE_EXT).to_sym
|
|
63
|
+
req = path.sub(/#{RUBY_FILE_EXT}$/o, '')
|
|
64
|
+
if @plugins.key?(plugin_symbol)
|
|
65
|
+
Log.log.warn{"skipping plugin already registered: #{plugin_symbol}"}
|
|
66
|
+
return
|
|
67
|
+
end
|
|
68
|
+
@plugins[plugin_symbol] = {source: path, require_stanza: req}
|
|
58
69
|
end
|
|
59
70
|
end
|
|
60
71
|
end
|
|
@@ -1,20 +1,32 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'aspera/api/aoc'
|
|
4
|
+
require 'aspera/nagios'
|
|
4
5
|
|
|
5
6
|
module Aspera
|
|
6
7
|
module Cli
|
|
7
8
|
module Plugins
|
|
8
9
|
class Alee < Cli::BasicAuthPlugin
|
|
9
|
-
ACTIONS = %i[entitlement].freeze
|
|
10
|
+
ACTIONS = %i[health entitlement].freeze
|
|
10
11
|
|
|
11
12
|
def execute_action
|
|
12
13
|
command = options.get_next_command(ACTIONS)
|
|
13
14
|
case command
|
|
15
|
+
when :health
|
|
16
|
+
nagios = Nagios.new
|
|
17
|
+
begin
|
|
18
|
+
api = Api::Alee.new(nil, nil, version: 'ping')
|
|
19
|
+
result = api.call(operation: 'GET', subpath: '')
|
|
20
|
+
raise "unexpected response: #{result[:http].body}" unless result[:http].body.eql?('pong')
|
|
21
|
+
nagios.add_ok('api', 'answered ok')
|
|
22
|
+
rescue StandardError => e
|
|
23
|
+
nagios.add_critical('api', e.to_s)
|
|
24
|
+
end
|
|
25
|
+
return nagios.result
|
|
14
26
|
when :entitlement
|
|
15
27
|
entitlement_id = options.get_option(:username, mandatory: true)
|
|
16
28
|
customer_id = options.get_option(:password, mandatory: true)
|
|
17
|
-
api_metering = Api::
|
|
29
|
+
api_metering = Api::Alee.new(entitlement_id, customer_id)
|
|
18
30
|
return {type: :single_object, data: api_metering.read('entitlement')[:data]}
|
|
19
31
|
end
|
|
20
32
|
end
|
|
@@ -4,6 +4,7 @@ require 'aspera/cli/plugins/node'
|
|
|
4
4
|
require 'aspera/cli/plugins/ats'
|
|
5
5
|
require 'aspera/cli/basic_auth_plugin'
|
|
6
6
|
require 'aspera/cli/transfer_agent'
|
|
7
|
+
require 'aspera/cli/special_values'
|
|
7
8
|
require 'aspera/agent/node'
|
|
8
9
|
require 'aspera/transfer/spec'
|
|
9
10
|
require 'aspera/api/aoc'
|
|
@@ -18,12 +19,41 @@ module Aspera
|
|
|
18
19
|
module Cli
|
|
19
20
|
module Plugins
|
|
20
21
|
class Aoc < Cli::BasicAuthPlugin
|
|
21
|
-
AOC_PATH_API_CLIENTS = 'admin/api-clients'
|
|
22
22
|
# default redirect for AoC web auth
|
|
23
23
|
REDIRECT_LOCALHOST = 'http://localhost:12345'
|
|
24
24
|
# OAuth methods supported
|
|
25
25
|
STD_AUTH_TYPES = %i[web jwt].freeze
|
|
26
|
-
|
|
26
|
+
# admin objects that can be manipulated
|
|
27
|
+
ADMIN_OBJECTS = %i[
|
|
28
|
+
self
|
|
29
|
+
organization
|
|
30
|
+
user
|
|
31
|
+
group
|
|
32
|
+
group_membership
|
|
33
|
+
client
|
|
34
|
+
contact
|
|
35
|
+
dropbox
|
|
36
|
+
node
|
|
37
|
+
operation
|
|
38
|
+
package
|
|
39
|
+
saml_configuration
|
|
40
|
+
workspace
|
|
41
|
+
workspace_membership
|
|
42
|
+
dropbox_membership
|
|
43
|
+
short_link
|
|
44
|
+
application
|
|
45
|
+
client_registration_token
|
|
46
|
+
client_access_key
|
|
47
|
+
kms_profile].freeze
|
|
48
|
+
# query to list fully received packages
|
|
49
|
+
PACKAGE_RECEIVED_BASE_QUERY = {
|
|
50
|
+
'archived' => false,
|
|
51
|
+
'has_content' => true,
|
|
52
|
+
'received' => true,
|
|
53
|
+
'completed' => true}.freeze
|
|
54
|
+
# options and parameters for Api::AoC.new
|
|
55
|
+
OPTIONS_NEW = %i[url auth client_id client_secret scope redirect_uri private_key passphrase username password workspace].freeze
|
|
56
|
+
private_constant :REDIRECT_LOCALHOST, :STD_AUTH_TYPES, :ADMIN_OBJECTS, :PACKAGE_RECEIVED_BASE_QUERY, :OPTIONS_NEW
|
|
27
57
|
class << self
|
|
28
58
|
def application_name
|
|
29
59
|
'Aspera on Cloud'
|
|
@@ -33,12 +63,12 @@ module Aspera
|
|
|
33
63
|
# no protocol ?
|
|
34
64
|
base_url = "https://#{base_url}" unless base_url.match?(%r{^[a-z]{1,6}://})
|
|
35
65
|
# only org provided ?
|
|
36
|
-
base_url = "#{base_url}.#{Api::
|
|
66
|
+
base_url = "#{base_url}.#{Api::SAAS_DOMAIN_PROD}" unless base_url.include?('.')
|
|
37
67
|
# AoC is only https
|
|
38
68
|
return nil unless base_url.start_with?('https://')
|
|
39
69
|
result = Rest.new(base_url: base_url, redirect_max: 10).read('')
|
|
40
70
|
# Any AoC is on this domain
|
|
41
|
-
return nil unless result[:http].uri.host.end_with?(Api::
|
|
71
|
+
return nil unless result[:http].uri.host.end_with?(Api::SAAS_DOMAIN_PROD)
|
|
42
72
|
Log.log.debug{"AoC Main page: #{result[:http].body.include?(Api::AoC::PRODUCT_NAME)}"}
|
|
43
73
|
base_url = result[:http].uri.to_s if result[:http].uri.path.include?('/public')
|
|
44
74
|
# either in standard domain, or product name in page
|
|
@@ -48,6 +78,8 @@ module Aspera
|
|
|
48
78
|
}
|
|
49
79
|
end
|
|
50
80
|
|
|
81
|
+
# @param [String] url : url to check
|
|
82
|
+
# @return [Bool] true if private key is required for the url (i.e. no passcode)
|
|
51
83
|
def private_key_required?(url)
|
|
52
84
|
# pub link do not need private key
|
|
53
85
|
return Api::AoC.link_info(url)[:token].nil?
|
|
@@ -92,7 +124,7 @@ module Aspera
|
|
|
92
124
|
formatter.display_status(pub_key_pem)
|
|
93
125
|
if !options.get_option(:test_mode)
|
|
94
126
|
formatter.display_status('Once updated or validated, press enter.')
|
|
95
|
-
|
|
127
|
+
Environment.instance.open_uri(instance_url)
|
|
96
128
|
$stdin.gets
|
|
97
129
|
end
|
|
98
130
|
else
|
|
@@ -106,7 +138,7 @@ module Aspera
|
|
|
106
138
|
formatter.display_status('- origin: localhost')
|
|
107
139
|
formatter.display_status('Use the generated client id and secret in the following prompts.'.red)
|
|
108
140
|
end
|
|
109
|
-
|
|
141
|
+
Environment.instance.open_uri("#{instance_url}/admin/api-clients")
|
|
110
142
|
options.get_option(:client_id, mandatory: true)
|
|
111
143
|
options.get_option(:client_secret, mandatory: true)
|
|
112
144
|
use_browser_authentication = true
|
|
@@ -147,35 +179,8 @@ module Aspera
|
|
|
147
179
|
}
|
|
148
180
|
end
|
|
149
181
|
end
|
|
150
|
-
# special value for package id
|
|
151
|
-
KNOWN_AOC_RES = %i[
|
|
152
|
-
self
|
|
153
|
-
organization
|
|
154
|
-
user
|
|
155
|
-
group
|
|
156
|
-
group_membership
|
|
157
|
-
client
|
|
158
|
-
contact
|
|
159
|
-
dropbox
|
|
160
|
-
node
|
|
161
|
-
operation
|
|
162
|
-
package
|
|
163
|
-
saml_configuration
|
|
164
|
-
workspace
|
|
165
|
-
workspace_membership
|
|
166
|
-
dropbox_membership
|
|
167
|
-
short_link
|
|
168
|
-
application
|
|
169
|
-
client_registration_token
|
|
170
|
-
client_access_key
|
|
171
|
-
kms_profile].freeze
|
|
172
|
-
PACKAGE_RECEIVED_BASE_QUERY = {
|
|
173
|
-
'archived' => false,
|
|
174
|
-
'has_content' => true,
|
|
175
|
-
'received' => true,
|
|
176
|
-
'completed' => true}.freeze
|
|
177
182
|
|
|
178
|
-
def initialize(**
|
|
183
|
+
def initialize(**_)
|
|
179
184
|
super
|
|
180
185
|
@cache_workspace_info = nil
|
|
181
186
|
@cache_home_node_file = nil
|
|
@@ -186,17 +191,15 @@ module Aspera
|
|
|
186
191
|
options.declare(:scope, 'OAuth scope for AoC API calls', default: Api::AoC::SCOPE_FILES_USER)
|
|
187
192
|
options.declare(:redirect_uri, 'OAuth API client redirect URI')
|
|
188
193
|
options.declare(:private_key, 'OAuth JWT RSA private key PEM value (prefix file path with @file:)')
|
|
189
|
-
options.declare(:passphrase, 'RSA private key passphrase')
|
|
194
|
+
options.declare(:passphrase, 'RSA private key passphrase', types: String)
|
|
190
195
|
options.declare(:workspace, 'Name of workspace', types: [String, NilClass], default: Api::AoC::DEFAULT_WORKSPACE)
|
|
191
|
-
options.declare(:new_user_option, 'New user creation option for unknown package recipients')
|
|
196
|
+
options.declare(:new_user_option, 'New user creation option for unknown package recipients', types: Hash)
|
|
192
197
|
options.declare(:validate_metadata, 'Validate shared inbox metadata', values: :bool, default: true)
|
|
193
198
|
options.parse_options!
|
|
194
199
|
# add node plugin options (for manual)
|
|
195
200
|
Node.declare_options(options)
|
|
196
201
|
end
|
|
197
202
|
|
|
198
|
-
OPTIONS_NEW = %i[url auth client_id client_secret scope redirect_uri private_key passphrase username password workspace].freeze
|
|
199
|
-
|
|
200
203
|
def api_from_options(new_base_path)
|
|
201
204
|
create_values = {subpath: new_base_path, secret_finder: config}
|
|
202
205
|
# create an API object with the same options, but with a different subpath
|
|
@@ -317,8 +320,8 @@ module Aspera
|
|
|
317
320
|
# client side is agent
|
|
318
321
|
# server side is transfer server
|
|
319
322
|
# in same workspace
|
|
320
|
-
push_pull = options.get_next_argument('direction',
|
|
321
|
-
source_folder = options.get_next_argument('folder of source files',
|
|
323
|
+
push_pull = options.get_next_argument('direction', accept_list: %i[push pull])
|
|
324
|
+
source_folder = options.get_next_argument('folder of source files', validation: String)
|
|
322
325
|
case push_pull
|
|
323
326
|
when :push
|
|
324
327
|
client_direction = Transfer::Spec::DIRECTION_SEND
|
|
@@ -333,12 +336,12 @@ module Aspera
|
|
|
333
336
|
client_apfid = top_node_api.resolve_api_fid(file_id, client_folder)
|
|
334
337
|
server_apfid = top_node_api.resolve_api_fid(file_id, server_folder)
|
|
335
338
|
# force node as transfer agent
|
|
336
|
-
transfer.agent_instance = Agent::Node.new(
|
|
339
|
+
transfer.agent_instance = Agent::Node.new(
|
|
337
340
|
url: client_apfid[:api].base_url,
|
|
338
341
|
username: client_apfid[:api].app_info[:node_info]['access_key'],
|
|
339
|
-
password: client_apfid[:api].
|
|
342
|
+
password: client_apfid[:api].oauth.token,
|
|
340
343
|
root_id: client_apfid[:file_id]
|
|
341
|
-
|
|
344
|
+
)
|
|
342
345
|
# additional node to node TS info
|
|
343
346
|
add_ts = {
|
|
344
347
|
'remote_access_key' => server_apfid[:api].app_info[:node_info]['access_key'],
|
|
@@ -350,15 +353,106 @@ module Aspera
|
|
|
350
353
|
client_direction,
|
|
351
354
|
add_ts)))
|
|
352
355
|
else Aspera.error_unreachable_line
|
|
353
|
-
end
|
|
356
|
+
end
|
|
354
357
|
Aspera.error_unreachable_line
|
|
355
|
-
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def execute_resource_action(resource_type)
|
|
361
|
+
# get path on API, resource type is singular, but api is plural
|
|
362
|
+
resource_class_path =
|
|
363
|
+
case resource_type
|
|
364
|
+
# special cases: singleton, in admin, with x
|
|
365
|
+
when :self, :organization then resource_type
|
|
366
|
+
when :client_registration_token, :client_access_key then "admin/#{resource_type}s"
|
|
367
|
+
when :application then 'admin/apps_new'
|
|
368
|
+
when :dropbox then "#{resource_type}es"
|
|
369
|
+
when :kms_profile then "integrations/#{resource_type}s"
|
|
370
|
+
else "#{resource_type}s"
|
|
371
|
+
end
|
|
372
|
+
# build list of supported operations
|
|
373
|
+
singleton_object = %i[self organization].include?(resource_type)
|
|
374
|
+
global_operations = %i[create list]
|
|
375
|
+
supported_operations = %i[show modify]
|
|
376
|
+
supported_operations.push(:delete, *global_operations) unless singleton_object
|
|
377
|
+
supported_operations.push(:do) if resource_type.eql?(:node)
|
|
378
|
+
supported_operations.push(:set_pub_key) if resource_type.eql?(:client)
|
|
379
|
+
command = options.get_next_command(supported_operations)
|
|
380
|
+
# require identifier for non global commands
|
|
381
|
+
if !singleton_object && !global_operations.include?(command)
|
|
382
|
+
res_id = get_resource_id_from_args(resource_class_path)
|
|
383
|
+
resource_instance_path = "#{resource_class_path}/#{res_id}"
|
|
384
|
+
end
|
|
385
|
+
resource_instance_path = resource_class_path if singleton_object
|
|
386
|
+
case command
|
|
387
|
+
when :create
|
|
388
|
+
id_result = 'id'
|
|
389
|
+
id_result = 'token' if resource_class_path.eql?('admin/client_registration_tokens')
|
|
390
|
+
# TODO: report inconsistency: creation url is !=, and does not return id.
|
|
391
|
+
resource_class_path = 'admin/client_registration/token' if resource_class_path.eql?('admin/client_registration_tokens')
|
|
392
|
+
return do_bulk_operation(command: command, descr: 'creation data', id_result: id_result) do |params|
|
|
393
|
+
aoc_api.create(resource_class_path, params)[:data]
|
|
394
|
+
end
|
|
395
|
+
when :list
|
|
396
|
+
default_fields = ['id']
|
|
397
|
+
default_query = {}
|
|
398
|
+
case resource_type
|
|
399
|
+
when :application
|
|
400
|
+
default_query = {organization_apps: true}
|
|
401
|
+
default_fields.push('app_type', 'app_name', 'available', 'direct_authorizations_allowed', 'workspace_authorizations_allowed')
|
|
402
|
+
when :client, :client_access_key, :dropbox, :group, :package, :saml_configuration, :workspace then default_fields.push('name')
|
|
403
|
+
when :client_registration_token then default_fields.push('value', 'data.client_subject_scopes', 'created_at')
|
|
404
|
+
when :contact then default_fields = %w[email name source_id source_type]
|
|
405
|
+
when :node then default_fields.push('name', 'host', 'access_key')
|
|
406
|
+
when :operation then default_fields = nil
|
|
407
|
+
when :short_link then default_fields.push('short_url', 'data.url_token_data.purpose')
|
|
408
|
+
when :user then default_fields.push('name', 'email')
|
|
409
|
+
when :group_membership then default_fields.push(*%w[group_id member_type member_id])
|
|
410
|
+
when :workspace_membership then default_fields.push(*%w[workspace_id member_type member_id])
|
|
411
|
+
end
|
|
412
|
+
return result_list(resource_class_path, fields: default_fields, default_query: default_query)
|
|
413
|
+
when :show
|
|
414
|
+
object = aoc_api.read(resource_instance_path)[:data]
|
|
415
|
+
# default: show all, but certificate
|
|
416
|
+
fields = object.keys.reject{|k|k.eql?('certificate')}
|
|
417
|
+
return { type: :single_object, data: object, fields: fields }
|
|
418
|
+
when :modify
|
|
419
|
+
changes = options.get_next_argument('properties', validation: Hash)
|
|
420
|
+
return do_bulk_operation(command: command, descr: 'identifier', values: res_id) do |one_id|
|
|
421
|
+
aoc_api.update("#{resource_class_path}/#{one_id}", changes)
|
|
422
|
+
{'id' => one_id}
|
|
423
|
+
end
|
|
424
|
+
when :delete
|
|
425
|
+
return do_bulk_operation(command: command, descr: 'identifier', values: res_id) do |one_id|
|
|
426
|
+
aoc_api.delete("#{resource_class_path}/#{one_id}")
|
|
427
|
+
{'id' => one_id}
|
|
428
|
+
end
|
|
429
|
+
when :set_pub_key
|
|
430
|
+
# special : reads private and generate public
|
|
431
|
+
the_private_key = options.get_next_argument('private_key PEM value', validation: String)
|
|
432
|
+
the_public_key = OpenSSL::PKey::RSA.new(the_private_key).public_key.to_s
|
|
433
|
+
aoc_api.update(resource_instance_path, {jwt_grant_enabled: true, public_key: the_public_key})
|
|
434
|
+
return Main.result_success
|
|
435
|
+
when :do
|
|
436
|
+
command_repo = options.get_next_command(NODE4_EXT_COMMANDS)
|
|
437
|
+
# init context
|
|
438
|
+
aoc_api.context(:files)
|
|
439
|
+
return execute_nodegen4_command(command_repo, res_id)
|
|
440
|
+
else Aspera.error_unexpected_value(command)
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
ADMIN_ACTIONS = %i[ats resource usage_reports analytics subscription auth_providers].concat(ADMIN_OBJECTS).freeze
|
|
356
445
|
|
|
357
446
|
def execute_admin_action
|
|
358
447
|
# upgrade scope to admin
|
|
359
448
|
aoc_api.oauth.scope = Api::AoC::SCOPE_FILES_ADMIN
|
|
360
|
-
command_admin = options.get_next_command(
|
|
449
|
+
command_admin = options.get_next_command(ADMIN_ACTIONS)
|
|
361
450
|
case command_admin
|
|
451
|
+
when :resource
|
|
452
|
+
Log.log.warn('resource command is deprecated (4.18), directly use the specific command instead')
|
|
453
|
+
return execute_resource_action(options.get_next_argument('resource', accept_list: ADMIN_OBJECTS))
|
|
454
|
+
when *ADMIN_OBJECTS
|
|
455
|
+
return execute_resource_action(command_admin)
|
|
362
456
|
when :auth_providers
|
|
363
457
|
command_auth_prov = options.get_next_command(%i[list update])
|
|
364
458
|
case command_auth_prov
|
|
@@ -441,7 +535,7 @@ module Aspera
|
|
|
441
535
|
return {type: :object_list, data: events}
|
|
442
536
|
when :transfers
|
|
443
537
|
event_type = command_analytics.to_s
|
|
444
|
-
filter_resource = options.get_next_argument('resource',
|
|
538
|
+
filter_resource = options.get_next_argument('resource', accept_list: %i[organizations users nodes])
|
|
445
539
|
filter_id = options.get_next_argument('identifier', mandatory: false) ||
|
|
446
540
|
case filter_resource
|
|
447
541
|
when :organizations then aoc_api.current_user_info['organization_id']
|
|
@@ -480,89 +574,6 @@ module Aspera
|
|
|
480
574
|
end
|
|
481
575
|
return {type: :object_list, data: events}
|
|
482
576
|
end
|
|
483
|
-
when :resource
|
|
484
|
-
resource_type = options.get_next_argument('resource', expected: KNOWN_AOC_RES)
|
|
485
|
-
# get path on API, resource type is singular, but api is plural
|
|
486
|
-
resource_class_path =
|
|
487
|
-
case resource_type
|
|
488
|
-
# special cases: singleton, in admin, with x
|
|
489
|
-
when :self, :organization then resource_type
|
|
490
|
-
when :client_registration_token, :client_access_key then "admin/#{resource_type}s"
|
|
491
|
-
when :application then 'admin/apps_new'
|
|
492
|
-
when :dropbox then "#{resource_type}es"
|
|
493
|
-
when :kms_profile then "integrations/#{resource_type}s"
|
|
494
|
-
else "#{resource_type}s"
|
|
495
|
-
end
|
|
496
|
-
# build list of supported operations
|
|
497
|
-
singleton_object = %i[self organization].include?(resource_type)
|
|
498
|
-
global_operations = %i[create list]
|
|
499
|
-
supported_operations = %i[show modify]
|
|
500
|
-
supported_operations.push(:delete, *global_operations) unless singleton_object
|
|
501
|
-
supported_operations.push(:do) if resource_type.eql?(:node)
|
|
502
|
-
supported_operations.push(:set_pub_key) if resource_type.eql?(:client)
|
|
503
|
-
command = options.get_next_command(supported_operations)
|
|
504
|
-
# require identifier for non global commands
|
|
505
|
-
if !singleton_object && !global_operations.include?(command)
|
|
506
|
-
res_id = get_resource_id_from_args(resource_class_path)
|
|
507
|
-
resource_instance_path = "#{resource_class_path}/#{res_id}"
|
|
508
|
-
end
|
|
509
|
-
resource_instance_path = resource_class_path if singleton_object
|
|
510
|
-
case command
|
|
511
|
-
when :create
|
|
512
|
-
id_result = 'id'
|
|
513
|
-
id_result = 'token' if resource_class_path.eql?('admin/client_registration_tokens')
|
|
514
|
-
# TODO: report inconsistency: creation url is !=, and does not return id.
|
|
515
|
-
resource_class_path = 'admin/client_registration/token' if resource_class_path.eql?('admin/client_registration_tokens')
|
|
516
|
-
return do_bulk_operation(command: command, descr: 'creation data', id_result: id_result) do |params|
|
|
517
|
-
aoc_api.create(resource_class_path, params)[:data]
|
|
518
|
-
end
|
|
519
|
-
when :list
|
|
520
|
-
default_fields = ['id']
|
|
521
|
-
default_query = {}
|
|
522
|
-
case resource_type
|
|
523
|
-
when :application
|
|
524
|
-
default_query = {organization_apps: true}
|
|
525
|
-
default_fields.push('app_type', 'app_name', 'available', 'direct_authorizations_allowed', 'workspace_authorizations_allowed')
|
|
526
|
-
when :client, :client_access_key, :dropbox, :group, :package, :saml_configuration, :workspace then default_fields.push('name')
|
|
527
|
-
when :client_registration_token then default_fields.push('value', 'data.client_subject_scopes', 'created_at')
|
|
528
|
-
when :contact then default_fields = %w[email name source_id source_type]
|
|
529
|
-
when :node then default_fields.push('name', 'host', 'access_key')
|
|
530
|
-
when :operation then default_fields = nil
|
|
531
|
-
when :short_link then default_fields.push('short_url', 'data.url_token_data.purpose')
|
|
532
|
-
when :user then default_fields.push('name', 'email')
|
|
533
|
-
when :group_membership then default_fields.push(*%w[group_id member_type member_id])
|
|
534
|
-
when :workspace_membership then default_fields.push(*%w[workspace_id member_type member_id])
|
|
535
|
-
end
|
|
536
|
-
return result_list(resource_class_path, fields: default_fields, default_query: default_query)
|
|
537
|
-
when :show
|
|
538
|
-
object = aoc_api.read(resource_instance_path)[:data]
|
|
539
|
-
# default: show all, but certificate
|
|
540
|
-
fields = object.keys.reject{|k|k.eql?('certificate')}
|
|
541
|
-
return { type: :single_object, data: object, fields: fields }
|
|
542
|
-
when :modify
|
|
543
|
-
changes = options.get_next_argument('properties', type: Hash)
|
|
544
|
-
return do_bulk_operation(command: command, descr: 'identifier', values: res_id) do |one_id|
|
|
545
|
-
aoc_api.update("#{resource_class_path}/#{one_id}", changes)
|
|
546
|
-
{'id' => one_id}
|
|
547
|
-
end
|
|
548
|
-
when :delete
|
|
549
|
-
return do_bulk_operation(command: command, descr: 'identifier', values: res_id) do |one_id|
|
|
550
|
-
aoc_api.delete("#{resource_class_path}/#{one_id}")
|
|
551
|
-
{'id' => one_id}
|
|
552
|
-
end
|
|
553
|
-
when :set_pub_key
|
|
554
|
-
# special : reads private and generate public
|
|
555
|
-
the_private_key = options.get_next_argument('private_key PEM value', type: String)
|
|
556
|
-
the_public_key = OpenSSL::PKey::RSA.new(the_private_key).public_key.to_s
|
|
557
|
-
aoc_api.update(resource_instance_path, {jwt_grant_enabled: true, public_key: the_public_key})
|
|
558
|
-
return Main.result_success
|
|
559
|
-
when :do
|
|
560
|
-
command_repo = options.get_next_command(NODE4_EXT_COMMANDS)
|
|
561
|
-
# init context
|
|
562
|
-
aoc_api.context(:files)
|
|
563
|
-
return execute_nodegen4_command(command_repo, res_id)
|
|
564
|
-
else Aspera.error_unexpected_value(command)
|
|
565
|
-
end
|
|
566
577
|
when :usage_reports
|
|
567
578
|
return result_list('usage_reports', base_query: {workspace_id: aoc_api.context(:files)[:workspace_id]})
|
|
568
579
|
end
|
|
@@ -591,7 +602,7 @@ module Aspera
|
|
|
591
602
|
when :servers
|
|
592
603
|
return {type: :object_list, data: Rest.new(base_url: "#{Api::AoC.api_base_url}/#{Api::AoC::API_V1}").read('servers')[:data]}
|
|
593
604
|
when :bearer_token
|
|
594
|
-
return {type: :text, data: aoc_api.
|
|
605
|
+
return {type: :text, data: aoc_api.oauth.token}
|
|
595
606
|
when :organization
|
|
596
607
|
return { type: :single_object, data: aoc_api.read('organization')[:data] }
|
|
597
608
|
when :tier_restrictions
|
|
@@ -612,7 +623,7 @@ module Aspera
|
|
|
612
623
|
when :show
|
|
613
624
|
return { type: :single_object, data: aoc_api.current_user_info(exception: true) }
|
|
614
625
|
when :modify
|
|
615
|
-
aoc_api.update("users/#{aoc_api.current_user_info(exception: true)['id']}", options.get_next_argument('properties',
|
|
626
|
+
aoc_api.update("users/#{aoc_api.current_user_info(exception: true)['id']}", options.get_next_argument('properties', validation: Hash))
|
|
616
627
|
return Main.result_status('modified')
|
|
617
628
|
end
|
|
618
629
|
when :preferences
|
|
@@ -621,7 +632,7 @@ module Aspera
|
|
|
621
632
|
when :show
|
|
622
633
|
return { type: :single_object, data: aoc_api.read(user_preferences_res)[:data] }
|
|
623
634
|
when :modify
|
|
624
|
-
aoc_api.update(user_preferences_res, options.get_next_argument('properties',
|
|
635
|
+
aoc_api.update(user_preferences_res, options.get_next_argument('properties', validation: Hash))
|
|
625
636
|
return Main.result_status('modified')
|
|
626
637
|
end
|
|
627
638
|
end
|
|
@@ -680,13 +691,13 @@ module Aspera
|
|
|
680
691
|
].concat(aoc_api.additional_persistence_ids)))
|
|
681
692
|
end
|
|
682
693
|
case ids_to_download
|
|
683
|
-
when
|
|
694
|
+
when SpecialValues::ALL, SpecialValues::INIT
|
|
684
695
|
query = query_read_delete(default: PACKAGE_RECEIVED_BASE_QUERY)
|
|
685
696
|
Aspera.assert_type(query, Hash){'query'}
|
|
686
697
|
resolve_dropbox_name_default_ws_id(query)
|
|
687
698
|
# remove from list the ones already downloaded
|
|
688
699
|
all_ids = api_read_all('packages', query)[:data].map{|e|e['id']}
|
|
689
|
-
if ids_to_download.eql?(
|
|
700
|
+
if ids_to_download.eql?(SpecialValues::INIT)
|
|
690
701
|
Aspera.assert(skip_ids_persistency){'Only with option once_only'}
|
|
691
702
|
skip_ids_persistency.data.clear.concat(all_ids)
|
|
692
703
|
skip_ids_persistency.save
|
|
@@ -696,7 +707,7 @@ module Aspera
|
|
|
696
707
|
ids_to_download = all_ids.reject{|id|skip_ids_data.include?(id)}
|
|
697
708
|
else
|
|
698
709
|
ids_to_download = [ids_to_download] unless ids_to_download.is_a?(Array)
|
|
699
|
-
end
|
|
710
|
+
end
|
|
700
711
|
# list here
|
|
701
712
|
result_transfer = []
|
|
702
713
|
formatter.display_status("found #{ids_to_download.length} package(s).")
|
|
@@ -748,9 +759,9 @@ module Aspera
|
|
|
748
759
|
when *NODE4_EXT_COMMANDS
|
|
749
760
|
return execute_nodegen4_command(command_repo, aoc_api.context[:home_node_id], file_id: aoc_api.context[:home_file_id], scope: Api::Node::SCOPE_USER)
|
|
750
761
|
when :short_link
|
|
751
|
-
link_type = options.get_next_argument('link type',
|
|
762
|
+
link_type = options.get_next_argument('link type', accept_list: %i[public private])
|
|
752
763
|
short_link_command = options.get_next_command(%i[create delete list])
|
|
753
|
-
folder_dest = options.get_next_argument('path',
|
|
764
|
+
folder_dest = options.get_next_argument('path', validation: String)
|
|
754
765
|
home_node_api = aoc_api.node_api_from(
|
|
755
766
|
node_id: aoc_api.context[:home_node_id],
|
|
756
767
|
workspace_id: aoc_api.context[:workspace_id],
|
|
@@ -847,8 +858,8 @@ module Aspera
|
|
|
847
858
|
# TODO: event ?
|
|
848
859
|
end
|
|
849
860
|
return {type: :single_object, data: result_create_short_link}
|
|
850
|
-
end
|
|
851
|
-
end
|
|
861
|
+
end
|
|
862
|
+
end
|
|
852
863
|
raise 'Error: shall not reach this line'
|
|
853
864
|
when :automation
|
|
854
865
|
Log.log.warn('BETA: work under progress')
|
|
@@ -891,7 +902,7 @@ module Aspera
|
|
|
891
902
|
server.start
|
|
892
903
|
return Main.result_status('Gateway terminated')
|
|
893
904
|
else Aspera.error_unreachable_line
|
|
894
|
-
end
|
|
905
|
+
end
|
|
895
906
|
Aspera.error_unreachable_line
|
|
896
907
|
end
|
|
897
908
|
|
|
@@ -100,7 +100,7 @@ module Aspera
|
|
|
100
100
|
return Main.result_status('modified')
|
|
101
101
|
when :entitlement
|
|
102
102
|
ak = ats_api_pub_v1.read("access_keys/#{access_key_id}")[:data]
|
|
103
|
-
api_bss = Api::
|
|
103
|
+
api_bss = Api::Alee.new(ak['license']['entitlement_id'], ak['license']['customer_id'])
|
|
104
104
|
return {type: :single_object, data: api_bss.read('entitlement')[:data]}
|
|
105
105
|
when :delete
|
|
106
106
|
ats_api_pub_v1.delete("access_keys/#{access_key_id}")
|