aspera-cli 4.27.0 → 4.27.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 +0 -0
- data/CHANGELOG.md +29 -0
- data/CONTRIBUTING.md +1 -7
- data/TODO.md +50 -0
- data/docs/README.md +708 -488
- data/lib/aspera/agent/base.rb +10 -2
- data/lib/aspera/agent/connect.rb +7 -7
- data/lib/aspera/agent/desktop.rb +3 -3
- data/lib/aspera/agent/direct.rb +48 -19
- data/lib/aspera/agent/factory.rb +3 -3
- data/lib/aspera/agent/httpgw.rb +55 -14
- data/lib/aspera/agent/node.rb +2 -2
- data/lib/aspera/agent/transferd.rb +12 -12
- data/lib/aspera/api/aoc.rb +28 -28
- data/lib/aspera/api/cos_node.rb +10 -9
- data/lib/aspera/api/faspex.rb +2 -2
- data/lib/aspera/api/httpgw.rb +20 -20
- data/lib/aspera/api/node.rb +31 -53
- data/lib/aspera/ascmd.rb +13 -13
- data/lib/aspera/ascp/installation.rb +43 -36
- data/lib/aspera/ascp/management.rb +6 -6
- data/lib/aspera/assert.rb +12 -13
- data/lib/aspera/cli/ascp_actions.rb +7 -7
- data/lib/aspera/cli/async_transfer_store.rb +49 -5
- data/lib/aspera/cli/bootstrapper.rb +9 -9
- data/lib/aspera/cli/command_registry.rb +1 -1
- data/lib/aspera/cli/command_spec.rb +6 -3
- data/lib/aspera/cli/context.rb +3 -3
- data/lib/aspera/cli/extended_value.rb +26 -26
- data/lib/aspera/cli/formatter.rb +76 -54
- data/lib/aspera/cli/gem_checker.rb +1 -1
- data/lib/aspera/cli/hints.rb +2 -2
- data/lib/aspera/cli/http.rb +22 -29
- data/lib/aspera/cli/mailer.rb +7 -7
- data/lib/aspera/cli/mcp_tool.rb +31 -4
- data/lib/aspera/cli/option_declarator.rb +77 -0
- data/lib/aspera/cli/options.schema.yaml +273 -3
- data/lib/aspera/cli/parser.rb +539 -280
- data/lib/aspera/cli/plugins/alee.rb +1 -1
- data/lib/aspera/cli/plugins/aoc.rb +297 -313
- data/lib/aspera/cli/plugins/ats.rb +25 -21
- data/lib/aspera/cli/plugins/base.rb +357 -186
- data/lib/aspera/cli/plugins/basic_auth.rb +0 -12
- data/lib/aspera/cli/plugins/config.rb +76 -73
- data/lib/aspera/cli/plugins/console.rb +8 -8
- data/lib/aspera/cli/plugins/cos.rb +4 -3
- data/lib/aspera/cli/plugins/factory.rb +2 -2
- data/lib/aspera/cli/plugins/faspex5.rb +259 -248
- data/lib/aspera/cli/plugins/faspio.rb +7 -2
- data/lib/aspera/cli/plugins/httpgw.rb +1 -1
- data/lib/aspera/cli/plugins/mcp.rb +11 -11
- data/lib/aspera/cli/plugins/node.rb +227 -283
- data/lib/aspera/cli/plugins/orchestrator.rb +23 -23
- data/lib/aspera/cli/plugins/preview.rb +61 -64
- data/lib/aspera/cli/plugins/server.rb +36 -31
- data/lib/aspera/cli/plugins/shares.rb +174 -135
- data/lib/aspera/cli/preset_actions.rb +39 -19
- data/lib/aspera/cli/preset_manager.rb +74 -32
- data/lib/aspera/cli/result.rb +18 -16
- data/lib/aspera/cli/runner.rb +75 -39
- data/lib/aspera/cli/secret_finder.rb +1 -1
- data/lib/aspera/cli/sync_actions.rb +36 -35
- data/lib/aspera/cli/terminal_formatter.rb +2 -2
- data/lib/aspera/cli/transfer_actions.rb +17 -10
- data/lib/aspera/cli/transfer_agent.rb +44 -44
- data/lib/aspera/cli/transfer_progress.rb +7 -7
- data/lib/aspera/cli/vault_manager.rb +34 -12
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/cli/wizard.rb +17 -20
- data/lib/aspera/colors.rb +3 -3
- data/lib/aspera/command_line_builder.rb +16 -16
- data/lib/aspera/command_line_converter.rb +1 -1
- data/lib/aspera/coverage.rb +1 -2
- data/lib/aspera/data_repository.rb +1 -1
- data/lib/aspera/dot_container.rb +8 -8
- data/lib/aspera/environment.rb +12 -12
- data/lib/aspera/faspex_gw.rb +4 -4
- data/lib/aspera/faspex_postproc.rb +14 -9
- data/lib/aspera/graphql.rb +4 -2
- data/lib/aspera/hash_ext.rb +2 -2
- data/lib/aspera/json_rpc/client.rb +1 -1
- data/lib/aspera/keychain/base.rb +10 -3
- data/lib/aspera/keychain/encrypted_hash.rb +92 -17
- data/lib/aspera/keychain/factory.rb +17 -5
- data/lib/aspera/keychain/hashicorp_vault.rb +1 -1
- data/lib/aspera/keychain/macos_security.rb +23 -25
- data/lib/aspera/keychain/one_password_api.rb +86 -0
- data/lib/aspera/keychain/one_password_base.rb +34 -0
- data/lib/aspera/keychain/one_password_cli.rb +98 -0
- data/lib/aspera/link_header.rb +2 -2
- data/lib/aspera/log.rb +13 -13
- data/lib/aspera/markdown.rb +5 -5
- data/lib/aspera/nagios.rb +8 -8
- data/lib/aspera/node_simulator.rb +33 -27
- data/lib/aspera/oauth/base.rb +4 -5
- data/lib/aspera/oauth/boot.rb +3 -3
- data/lib/aspera/oauth/factory.rb +5 -5
- data/lib/aspera/oauth/jwt.rb +5 -7
- data/lib/aspera/oauth/web.rb +4 -4
- data/lib/aspera/persistency_action_once.rb +4 -4
- data/lib/aspera/persistency_folder.rb +8 -8
- data/lib/aspera/preview/file_types.rb +4 -4
- data/lib/aspera/preview/generator.rb +49 -46
- data/lib/aspera/preview/options.rb +3 -2
- data/lib/aspera/preview/terminal.rb +5 -5
- data/lib/aspera/preview/utils.rb +65 -18
- data/lib/aspera/products/connect.rb +2 -2
- data/lib/aspera/products/desktop.rb +1 -1
- data/lib/aspera/products/other.rb +2 -2
- data/lib/aspera/products/transferd.rb +3 -3
- data/lib/aspera/proxy_auto_config.rb +10 -10
- data/lib/aspera/rest.rb +149 -115
- data/lib/aspera/rest_error_analyzer.rb +3 -3
- data/lib/aspera/rest_list.rb +10 -9
- data/lib/aspera/schema/IBM Aspera Node API-4.4.6.yaml +6232 -0
- data/lib/aspera/schema/IBM Aspera faspio Gateway API-1.0.0.yaml +249 -0
- data/lib/aspera/schema/IBM_Aspera_Shares.yaml +4653 -0
- data/lib/aspera/schema/documentation.rb +17 -11
- data/lib/aspera/schema/reader.rb +78 -4
- data/lib/aspera/schema/registry.rb +26 -7
- data/lib/aspera/secret_hider.rb +5 -5
- data/lib/aspera/ssh.rb +64 -31
- data/lib/aspera/ssl.rb +3 -3
- data/lib/aspera/sync/database.rb +2 -2
- data/lib/aspera/sync/operations.rb +13 -13
- data/lib/aspera/temp_file_manager.rb +24 -4
- data/lib/aspera/transfer/faux_file.rb +2 -2
- data/lib/aspera/transfer/parameters.rb +15 -15
- data/lib/aspera/transfer/resumer.rb +9 -9
- data/lib/aspera/transfer/spec.rb +1 -1
- data/lib/aspera/uri_reader.rb +52 -15
- data/lib/aspera/web_auth.rb +6 -5
- data/lib/aspera/web_server_simple.rb +9 -9
- data/lib/aspera/yaml.rb +4 -4
- data.tar.gz.sig +0 -0
- metadata +10 -4
- metadata.gz.sig +0 -0
- data/lib/aspera/cli/plugins/faspex.rb +0 -576
- data/lib/aspera/transfer/uri.rb +0 -56
|
@@ -102,8 +102,8 @@ module Aspera
|
|
|
102
102
|
# @param destination_folder [String] Base folder
|
|
103
103
|
# @param fld [Array] List of fields of package
|
|
104
104
|
def unique_folder(package_info, destination_folder, fld: nil, seq: false, opt: false)
|
|
105
|
-
Aspera.assert_array_all(fld, String, type: BadArgument){'fld'}
|
|
106
|
-
Aspera.assert_values(fld.length, [1, 2]){'fld length'}
|
|
105
|
+
Aspera.assert_array_all(fld, String, type: BadArgument) { 'fld' }
|
|
106
|
+
Aspera.assert_values(fld.length, [1, 2]) { 'fld length' }
|
|
107
107
|
folder = Environment.instance.sanitized_filename(package_info[fld[0]])
|
|
108
108
|
if seq
|
|
109
109
|
folder = next_available_folder(folder, always: !opt)
|
|
@@ -113,6 +113,71 @@ module Aspera
|
|
|
113
113
|
end
|
|
114
114
|
File.join(destination_folder, folder)
|
|
115
115
|
end
|
|
116
|
+
|
|
117
|
+
# @return [String] AoC REST path for an admin resource type
|
|
118
|
+
def aoc_res_path(res)
|
|
119
|
+
cfg = ADMIN_OBJECT_CONFIG.fetch(res, {})
|
|
120
|
+
return cfg[:path] if cfg[:path]
|
|
121
|
+
"#{res}s".gsub(/ys$/, 'ies')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# @return [Hash] {path:, ops:, id_result:, require_ws_id:, list_fields:, schema:, query_component:}
|
|
125
|
+
def aoc_res_cfg(res)
|
|
126
|
+
cfg = ADMIN_OBJECT_CONFIG.fetch(res, {})
|
|
127
|
+
path = aoc_res_path(res)
|
|
128
|
+
ops = cfg[:ops] || (Base::Operations::ALL + (cfg[:extra_ops] || []))
|
|
129
|
+
schema = cfg[:create_schema] == false ? nil : Schema::Registry.req_body(Schema::Registry::AOC, "#{path}.post")
|
|
130
|
+
{
|
|
131
|
+
path: path,
|
|
132
|
+
ops: ops,
|
|
133
|
+
id_result: cfg[:id_result] || 'id',
|
|
134
|
+
require_ws_id: cfg[:require_ws_id] || false,
|
|
135
|
+
list_fields: cfg.key?(:list_fields) ? cfg[:list_fields] : %w[id name],
|
|
136
|
+
schema: schema,
|
|
137
|
+
query_component: Schema::Registry::AOC
|
|
138
|
+
}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# DSL helper: register the 5 short_link leaf commands under the given parent path
|
|
142
|
+
# and define the corresponding action methods on `base`.
|
|
143
|
+
# @param base [Class] the plugin class
|
|
144
|
+
# @param parent_path [Array<Symbol>] full path ending with :short_link
|
|
145
|
+
def register_short_link_commands(base, parent_path)
|
|
146
|
+
base.commands_under(parent_path) do
|
|
147
|
+
base.command(
|
|
148
|
+
:create, description: 'Create',
|
|
149
|
+
arguments: [{name: :custom_data, type: Hash, mandatory: false, default: {}}]
|
|
150
|
+
)
|
|
151
|
+
base.command(
|
|
152
|
+
:modify, description: 'Modify',
|
|
153
|
+
arguments: [{name: :short_link_id, type: :identifier}, {name: :custom_data, type: Hash, mandatory: false, default: {}}]
|
|
154
|
+
)
|
|
155
|
+
base.command(:list, description: 'List short links')
|
|
156
|
+
base.command(
|
|
157
|
+
:show, description: 'Show a short link',
|
|
158
|
+
arguments: [{name: :short_link_id, type: :identifier}]
|
|
159
|
+
)
|
|
160
|
+
base.command(
|
|
161
|
+
:delete, description: 'Delete a short link',
|
|
162
|
+
arguments: [{name: :short_link_id, type: :identifier}]
|
|
163
|
+
)
|
|
164
|
+
end
|
|
165
|
+
base.define_action_method(parent_path + [:create]) do |custom_data: {}, **ctx|
|
|
166
|
+
sl_exec_create(custom_data, **ctx)
|
|
167
|
+
end
|
|
168
|
+
base.define_action_method(parent_path + [:list]) do |**ctx|
|
|
169
|
+
sl_exec_list(**sl_fetch_list(**ctx))
|
|
170
|
+
end
|
|
171
|
+
base.define_action_method(parent_path + [:show]) do |**ctx|
|
|
172
|
+
sl_exec_show(**sl_fetch_list(**ctx))
|
|
173
|
+
end
|
|
174
|
+
base.define_action_method(parent_path + [:delete]) do |**ctx|
|
|
175
|
+
sl_exec_delete(**sl_fetch_list(**ctx), **ctx)
|
|
176
|
+
end
|
|
177
|
+
base.define_action_method(parent_path + [:modify]) do |custom_data: {}, **ctx|
|
|
178
|
+
sl_exec_modify(custom_data, **sl_fetch_list(**ctx), **ctx)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
116
181
|
end
|
|
117
182
|
|
|
118
183
|
# @param wizard [Wizard] The wizard object
|
|
@@ -133,7 +198,7 @@ module Aspera
|
|
|
133
198
|
test_args: 'organization'
|
|
134
199
|
}
|
|
135
200
|
end
|
|
136
|
-
options.declare(:use_generic_client, description: 'Wizard: AoC: use global or org specific jwt client id', allowed:
|
|
201
|
+
options.declare(:use_generic_client, description: 'Wizard: AoC: use global or org specific jwt client id', allowed: Type::BOOLEAN, default: Api::AoC.saas_url?(app_url))
|
|
137
202
|
options.parse_options!
|
|
138
203
|
# make username mandatory for jwt, this triggers interactive input
|
|
139
204
|
wiz_username = options.get_option(:username, mandatory: true)
|
|
@@ -203,9 +268,11 @@ module Aspera
|
|
|
203
268
|
|
|
204
269
|
option :workspace, description: 'Name of workspace', allowed: [String, NilClass], default: Api::AoC::DEFAULT_WORKSPACE
|
|
205
270
|
option :new_user_option, description: 'New user creation option for unknown package recipients', allowed: [Hash, NilClass]
|
|
206
|
-
option :validate_metadata, description: 'Validate shared inbox metadata', allowed:
|
|
271
|
+
option :validate_metadata, description: 'Validate shared inbox metadata', allowed: Type::BOOLEAN, default: true
|
|
207
272
|
option :package_folder, schema: Schema::Registry::PACKAGE_FOLDER_OPTIONS
|
|
208
273
|
|
|
274
|
+
use_options Node
|
|
275
|
+
|
|
209
276
|
def initialize(**_)
|
|
210
277
|
super
|
|
211
278
|
@cache_workspace_info = nil
|
|
@@ -213,8 +280,6 @@ module Aspera
|
|
|
213
280
|
@cache_api_aoc = nil
|
|
214
281
|
@scope = Api::AoC::Scope::USER
|
|
215
282
|
options.parse_options!
|
|
216
|
-
# add node plugin options (for manual)
|
|
217
|
-
Node.declare_options(options)
|
|
218
283
|
end
|
|
219
284
|
|
|
220
285
|
# Change API scope for subsequent calls, re-instantiate API object
|
|
@@ -244,7 +309,7 @@ module Aspera
|
|
|
244
309
|
case m[:field]
|
|
245
310
|
when 'name' then api.ws_ids[:name] = m[:value]
|
|
246
311
|
when 'id' then api.ws_ids[:id] = m[:value]
|
|
247
|
-
else Aspera.error_unexpected_value(m[:field]){'workspace selector: only `name` or `id`'}
|
|
312
|
+
else Aspera.error_unexpected_value(m[:field]) { 'workspace selector: only `name` or `id`' }
|
|
248
313
|
end
|
|
249
314
|
else
|
|
250
315
|
api.ws_ids[:name] = workspace
|
|
@@ -292,7 +357,7 @@ module Aspera
|
|
|
292
357
|
# @return [String] identifier
|
|
293
358
|
def get_resource_id_from_args(resource_class_path)
|
|
294
359
|
return options.instance_identifier do |field, value|
|
|
295
|
-
Aspera.assert_values(field, ['name'], type: BadArgument){'selector field'}
|
|
360
|
+
Aspera.assert_values(field, ['name'], type: BadArgument) { 'selector field' }
|
|
296
361
|
aoc_api.lookup_with_q(resource_class_path, value: value)['id']
|
|
297
362
|
end
|
|
298
363
|
end
|
|
@@ -324,7 +389,7 @@ module Aspera
|
|
|
324
389
|
def resolve_dropbox_name_default_ws_id(query)
|
|
325
390
|
if query.key?('dropbox_name')
|
|
326
391
|
# convenience: specify name instead of id
|
|
327
|
-
Aspera.assert(!query.key?('dropbox_id'), type: BadArgument){'Use field dropbox_name or dropbox_id, not both'}
|
|
392
|
+
Aspera.assert(!query.key?('dropbox_id'), type: BadArgument) { 'Use field dropbox_name or dropbox_id, not both' }
|
|
328
393
|
# TODO : craft a query that looks for dropbox only in current workspace
|
|
329
394
|
query['dropbox_id'] = aoc_api.lookup_with_q('dropboxes', value: query.delete('dropbox_name'))['id']
|
|
330
395
|
end
|
|
@@ -333,26 +398,34 @@ module Aspera
|
|
|
333
398
|
query['exclude_dropbox_packages'] = !query.key?('dropbox_id') unless query.key?('exclude_dropbox_packages')
|
|
334
399
|
end
|
|
335
400
|
|
|
336
|
-
# List all packages
|
|
337
|
-
#
|
|
401
|
+
# List all packages from the API using the current `--query` option.
|
|
402
|
+
# The special `max` key is extracted *before* the API call and returned separately,
|
|
403
|
+
# so callers that apply a post-API filter (e.g. once_only) can enforce the limit
|
|
404
|
+
# after filtering rather than before.
|
|
405
|
+
# @return [Array(Hash, Integer, nil)] [{items:,total:} paging result, max (or nil)]
|
|
338
406
|
def list_all_packages_with_query
|
|
339
|
-
query = query_read_delete(default: {})
|
|
340
|
-
Aspera.assert_type(query, Hash){'query'}
|
|
341
|
-
PACKAGE_RECEIVED_BASE_QUERY.each{ |k, v| query[k] = v unless query.key?(k)}
|
|
407
|
+
query = query_read_delete(default: {}, schema: Schema::Registry.query_params(Schema::Registry::AOC, 'packages'))
|
|
408
|
+
Aspera.assert_type(query, Hash) { 'query' }
|
|
409
|
+
PACKAGE_RECEIVED_BASE_QUERY.each { |k, v| query[k] = v unless query.key?(k) }
|
|
342
410
|
resolve_dropbox_name_default_ws_id(query)
|
|
343
|
-
|
|
411
|
+
# Extract `max` before paging so callers can apply it after post-API filtering
|
|
412
|
+
max_items = query.delete(RestList::MAX_ITEMS)&.to_i
|
|
413
|
+
return aoc_api.read_with_paging('packages', query.compact), max_items
|
|
344
414
|
end
|
|
345
415
|
|
|
346
416
|
FILES_COMMANDS = (Node::COMMANDS_GEN4 + %i[transfer]).freeze
|
|
347
417
|
|
|
348
|
-
# Execute a node gen4 command starting at given node and file IDs
|
|
349
|
-
#
|
|
418
|
+
# Execute a node gen4 command starting at given node and file IDs.
|
|
419
|
+
# Arguments already resolved by the DSL (e.g. path:) are forwarded via +resolved_args+
|
|
420
|
+
# and injected into the dispatch context so node.rb does not re-consume them from the CLI.
|
|
421
|
+
# @param command_repo [Symbol] Command to execute (from Node::COMMANDS_GEN4 or :transfer)
|
|
350
422
|
# @param node_id [String] Node identifier
|
|
351
|
-
# @param file_id [String] Root file id
|
|
352
|
-
# @param scope [String] node scope (Node::
|
|
353
|
-
# @param transfer_direction [Symbol] :push or :pull (only for command_repo == :transfer)
|
|
354
|
-
# @param transfer_source [String] source folder
|
|
355
|
-
|
|
423
|
+
# @param file_id [String, nil] Root file id; if nil, the AK root file id is used
|
|
424
|
+
# @param scope [String, nil] node scope (Node::Scope::USER/ADMIN), or nil (requires secret)
|
|
425
|
+
# @param transfer_direction [Symbol, nil] :push or :pull (only for command_repo == :transfer)
|
|
426
|
+
# @param transfer_source [String, nil] source folder (only for command_repo == :transfer)
|
|
427
|
+
# @param resolved_args [Hash] already-resolved CLI arguments (e.g. path:) forwarded to dispatch
|
|
428
|
+
def execute_nodegen4_command(command_repo, node_id, file_id: nil, scope: nil, transfer_direction: nil, transfer_source: nil, **resolved_args)
|
|
356
429
|
top_node_api = aoc_api.node_api_from(
|
|
357
430
|
node_id: node_id,
|
|
358
431
|
scope: scope,
|
|
@@ -364,8 +437,8 @@ module Aspera
|
|
|
364
437
|
when *Node::COMMANDS_GEN4
|
|
365
438
|
# For permission: the handler consumes the path first then re-dispatches to sub-commands.
|
|
366
439
|
# Calling dispatch_from_registry with skip_setup would bypass path consumption and fail.
|
|
367
|
-
return node_plugin.send(:"action_access_keys_do_#{command_repo}", do_root_file_id: file_id) if command_repo.eql?(:permission)
|
|
368
|
-
return node_plugin.dispatch_from_registry([:access_keys, :do, command_repo], {do_root_file_id: file_id}, skip_setup: true)
|
|
440
|
+
return node_plugin.send(:"action_access_keys_do_#{command_repo}", do_root_file_id: file_id, **resolved_args) if command_repo.eql?(:permission)
|
|
441
|
+
return node_plugin.dispatch_from_registry([:access_keys, :do, command_repo], {do_root_file_id: file_id, **resolved_args}, skip_setup: true)
|
|
369
442
|
when :transfer
|
|
370
443
|
# client side is agent
|
|
371
444
|
# server side is transfer server
|
|
@@ -403,7 +476,7 @@ module Aspera
|
|
|
403
476
|
client_direction,
|
|
404
477
|
add_ts
|
|
405
478
|
)))
|
|
406
|
-
else Aspera.error_unexpected_value(command_repo){'command'}
|
|
479
|
+
else Aspera.error_unexpected_value(command_repo) { 'command' }
|
|
407
480
|
end
|
|
408
481
|
Aspera.error_unreachable_line
|
|
409
482
|
end
|
|
@@ -440,73 +513,6 @@ module Aspera
|
|
|
440
513
|
}.freeze
|
|
441
514
|
private_constant :ADMIN_OBJECT_CONFIG
|
|
442
515
|
|
|
443
|
-
class << self
|
|
444
|
-
# @return [String] AoC REST path for an admin resource type
|
|
445
|
-
def aoc_res_path(res)
|
|
446
|
-
cfg = ADMIN_OBJECT_CONFIG.fetch(res, {})
|
|
447
|
-
return cfg[:path] if cfg[:path]
|
|
448
|
-
"#{res}s".gsub(/ys$/, 'ies')
|
|
449
|
-
end
|
|
450
|
-
|
|
451
|
-
# @return [Hash] {path:, ops:, id_result:, require_ws_id:, list_fields:, schema:, query_component:}
|
|
452
|
-
def aoc_res_cfg(res)
|
|
453
|
-
cfg = ADMIN_OBJECT_CONFIG.fetch(res, {})
|
|
454
|
-
path = aoc_res_path(res)
|
|
455
|
-
ops = cfg[:ops] || (Base::Operations::ALL + (cfg[:extra_ops] || []))
|
|
456
|
-
schema = cfg[:create_schema] == false ? nil : Schema::Registry.req_body(Schema::Registry::AOC, "#{path}.post")
|
|
457
|
-
{
|
|
458
|
-
path: path,
|
|
459
|
-
ops: ops,
|
|
460
|
-
id_result: cfg[:id_result] || 'id',
|
|
461
|
-
require_ws_id: cfg[:require_ws_id] || false,
|
|
462
|
-
list_fields: cfg.key?(:list_fields) ? cfg[:list_fields] : %w[id name],
|
|
463
|
-
schema: schema,
|
|
464
|
-
query_component: Schema::Registry::AOC
|
|
465
|
-
}
|
|
466
|
-
end
|
|
467
|
-
|
|
468
|
-
# DSL helper: register the 5 short_link leaf commands under the given parent path
|
|
469
|
-
# and define the corresponding action methods on `base`.
|
|
470
|
-
# @param base [Class] the plugin class
|
|
471
|
-
# @param parent_path [Array<Symbol>] full path ending with :short_link
|
|
472
|
-
def register_short_link_commands(base, parent_path)
|
|
473
|
-
base.commands_under(parent_path) do
|
|
474
|
-
base.command(
|
|
475
|
-
:create, description: 'Create',
|
|
476
|
-
arguments: [{name: :custom_data, type: Hash, mandatory: false, default: {}}]
|
|
477
|
-
)
|
|
478
|
-
base.command(
|
|
479
|
-
:modify, description: 'Modify',
|
|
480
|
-
arguments: [{name: :short_link_id, type: :identifier}, {name: :custom_data, type: Hash, mandatory: false, default: {}}]
|
|
481
|
-
)
|
|
482
|
-
base.command(:list, description: 'List short links')
|
|
483
|
-
base.command(
|
|
484
|
-
:show, description: 'Show a short link',
|
|
485
|
-
arguments: [{name: :short_link_id, type: :identifier}]
|
|
486
|
-
)
|
|
487
|
-
base.command(
|
|
488
|
-
:delete, description: 'Delete a short link',
|
|
489
|
-
arguments: [{name: :short_link_id, type: :identifier}]
|
|
490
|
-
)
|
|
491
|
-
end
|
|
492
|
-
base.define_action_method(parent_path + [:create]) do |custom_data: {}, **ctx|
|
|
493
|
-
sl_exec_create(custom_data, **ctx)
|
|
494
|
-
end
|
|
495
|
-
base.define_action_method(parent_path + [:list]) do |**ctx|
|
|
496
|
-
sl_exec_list(**sl_fetch_list(**ctx))
|
|
497
|
-
end
|
|
498
|
-
base.define_action_method(parent_path + [:show]) do |**ctx|
|
|
499
|
-
sl_exec_show(**sl_fetch_list(**ctx))
|
|
500
|
-
end
|
|
501
|
-
base.define_action_method(parent_path + [:delete]) do |**ctx|
|
|
502
|
-
sl_exec_delete(**sl_fetch_list(**ctx), **ctx)
|
|
503
|
-
end
|
|
504
|
-
base.define_action_method(parent_path + [:modify]) do |custom_data: {}, **ctx|
|
|
505
|
-
sl_exec_modify(custom_data, **sl_fetch_list(**ctx), **ctx)
|
|
506
|
-
end
|
|
507
|
-
end
|
|
508
|
-
end
|
|
509
|
-
|
|
510
516
|
# Instance delegators so instance methods can call aoc_res_path/aoc_res_cfg without self.class.
|
|
511
517
|
def aoc_res_path(res) = self.class.aoc_res_path(res)
|
|
512
518
|
def aoc_res_cfg(res) = self.class.aoc_res_cfg(res)
|
|
@@ -514,7 +520,7 @@ module Aspera
|
|
|
514
520
|
# Known fixed set of AoC application types (verified against API: activity, automation, files, packages)
|
|
515
521
|
APP_TYPES = %i[activity automation files packages].freeze
|
|
516
522
|
|
|
517
|
-
ADMIN_ACTIONS = %i[bearer_token application ats usage_reports analytics subscription auth_providers]
|
|
523
|
+
ADMIN_ACTIONS = (%i[bearer_token application ats usage_reports analytics subscription auth_providers] + ADMIN_OBJECTS).freeze
|
|
518
524
|
|
|
519
525
|
# Build analytics REST API (shared by action_admin_analytics_*)
|
|
520
526
|
def build_analytics_api
|
|
@@ -575,8 +581,8 @@ module Aspera
|
|
|
575
581
|
|
|
576
582
|
def reject_packages_from_persistency(all_packages, skip_ids_persistency)
|
|
577
583
|
return if skip_ids_persistency.nil?
|
|
578
|
-
skip_package = skip_ids_persistency.data.to_h{ |i| [i, true]}
|
|
579
|
-
all_packages.reject!{ |pkg| skip_package[pkg['id']]}
|
|
584
|
+
skip_package = skip_ids_persistency.data.to_h { |i| [i, true] }
|
|
585
|
+
all_packages.reject! { |pkg| skip_package[pkg['id']] }
|
|
580
586
|
end
|
|
581
587
|
|
|
582
588
|
# --- DSL command declarations ---
|
|
@@ -591,31 +597,23 @@ module Aspera
|
|
|
591
597
|
end
|
|
592
598
|
)
|
|
593
599
|
command :bearer_token, description: 'Display bearer token',
|
|
594
|
-
action: ->{Result::Text.new(aoc_api.oauth.authorization)}
|
|
600
|
+
action: -> { Result::Text.new(aoc_api.oauth.authorization) }
|
|
595
601
|
command :organization, description: 'Show organization info',
|
|
596
|
-
action: ->{Result::SingleObject.new(aoc_api.read('organization'))}
|
|
602
|
+
action: -> { Result::SingleObject.new(aoc_api.read('organization')) }
|
|
597
603
|
command :tier_restrictions, description: 'Show tier restrictions',
|
|
598
|
-
action: ->{Result::SingleObject.new(aoc_api.read('tier_restrictions'))}
|
|
604
|
+
action: -> { Result::SingleObject.new(aoc_api.read('tier_restrictions')) }
|
|
599
605
|
command :user, description: 'User commands'
|
|
600
606
|
command :packages, description: 'Package commands', setup: :setup_workspace_display
|
|
601
607
|
command :files, description: 'Files commands (workspace-aware)', setup: :setup_workspace_display
|
|
602
608
|
command :admin, description: 'Administration commands', setup: :setup_admin_scope
|
|
603
|
-
commands_under
|
|
609
|
+
commands_under :admin do
|
|
604
610
|
command :bearer_token, description: 'Show admin bearer token',
|
|
605
|
-
action: ->{Result::Text.new(aoc_api.oauth.authorization)}
|
|
611
|
+
action: -> { Result::Text.new(aoc_api.oauth.authorization) }
|
|
606
612
|
command :application, description: 'Manage applications'
|
|
607
|
-
command(
|
|
608
|
-
:
|
|
609
|
-
action: lambda do
|
|
610
|
-
ats_api = Rest.new(**aoc_api.params.deep_merge({
|
|
611
|
-
base_url: "#{aoc_api.base_url}/admin/ats/pub/v1",
|
|
612
|
-
auth: {params: {scope: Api::AoC::Scope::ADMIN_USER}}
|
|
613
|
-
}))
|
|
614
|
-
Ats.new(context: context, api: ats_api).execute_action
|
|
615
|
-
end
|
|
616
|
-
)
|
|
613
|
+
command :ats, description: 'Manage ATS (Aspera Transfer Service)',
|
|
614
|
+
delegate_instance: :build_ats_plugin, delegates_to: []
|
|
617
615
|
command :usage_reports, description: 'List usage reports',
|
|
618
|
-
action: ->{result_list('usage_reports', base_query: workspace_id_hash)}
|
|
616
|
+
action: -> { result_list('usage_reports', base_query: workspace_id_hash) }
|
|
619
617
|
command :auth_providers, description: 'Manage auth providers'
|
|
620
618
|
command :subscription, description: 'Show subscription info'
|
|
621
619
|
command :analytics, description: 'Query analytics'
|
|
@@ -624,7 +622,7 @@ module Aspera
|
|
|
624
622
|
op_setup = cfg[:op_setup] || {}
|
|
625
623
|
extra_op_args = cfg[:extra_op_args] || {}
|
|
626
624
|
is_singleton = cfg[:singleton]
|
|
627
|
-
id_arg_spec = is_singleton ? [] : [{name: :
|
|
625
|
+
id_arg_spec = is_singleton ? [] : [{name: :"#{res}_id", type: :identifier, lookup: :"lookup_aoc_#{res}_id"}]
|
|
628
626
|
ops = if cfg[:ops]
|
|
629
627
|
cfg[:ops]
|
|
630
628
|
elsif is_singleton
|
|
@@ -632,8 +630,8 @@ module Aspera
|
|
|
632
630
|
else
|
|
633
631
|
Operations::ALL + (cfg[:extra_ops] || [])
|
|
634
632
|
end
|
|
635
|
-
command
|
|
636
|
-
commands_under
|
|
633
|
+
command res, description: "Manage #{res.to_s.tr('_', ' ')}"
|
|
634
|
+
commands_under res do
|
|
637
635
|
ops.each do |op|
|
|
638
636
|
extra_setup = op_setup[op]
|
|
639
637
|
base_attrs = extra_setup ? {setup: extra_setup} : {}
|
|
@@ -657,13 +655,13 @@ module Aspera
|
|
|
657
655
|
c = aoc_res_cfg(res)
|
|
658
656
|
merged = merged.merge(query_schema: Schema::Registry.query_params(c[:query_component], c[:path]))
|
|
659
657
|
end
|
|
660
|
-
command
|
|
658
|
+
command op, description: op.to_s.tr('_', ' ').capitalize, **merged
|
|
661
659
|
end
|
|
662
660
|
end
|
|
663
661
|
end
|
|
664
662
|
end
|
|
665
663
|
# admin > workspace > shared_folder sub-tree
|
|
666
|
-
commands_under
|
|
664
|
+
commands_under %i[admin workspace shared_folder] do
|
|
667
665
|
command :list, description: 'List shared folders'
|
|
668
666
|
command :node, description: 'Execute node command on shared folder',
|
|
669
667
|
arguments: [{name: :sf_id, type: :identifier}],
|
|
@@ -672,20 +670,30 @@ module Aspera
|
|
|
672
670
|
arguments: [{name: :sf_id, type: :identifier}],
|
|
673
671
|
setup: :setup_admin_workspace_shared_folder_member
|
|
674
672
|
end
|
|
675
|
-
# admin > workspace > shared_folder > node sub-tree (
|
|
676
|
-
commands_under
|
|
677
|
-
|
|
673
|
+
# admin > workspace > shared_folder > node sub-tree (Gen4 commands)
|
|
674
|
+
commands_under %i[admin workspace shared_folder node] do
|
|
675
|
+
command :transfer, description: 'Transfer files (node-to-node)'
|
|
676
|
+
command :permission, description: 'Manage permissions'
|
|
677
|
+
command :sync, description: 'Synchronize folders'
|
|
678
|
+
Node::COMMANDS_GEN4_SPEC.each do |cmd, spec|
|
|
679
|
+
command cmd, **spec
|
|
680
|
+
end
|
|
678
681
|
end
|
|
679
|
-
commands_under
|
|
682
|
+
commands_under %i[admin workspace shared_folder member] do
|
|
680
683
|
command :list, description: 'List members of a shared folder'
|
|
681
684
|
end
|
|
682
685
|
# admin > workspace > dropbox sub-tree
|
|
683
|
-
commands_under
|
|
686
|
+
commands_under %i[admin workspace dropbox] do
|
|
684
687
|
command :list, description: 'List dropboxes in workspace'
|
|
685
688
|
end
|
|
686
|
-
# admin > node > do sub-tree (
|
|
687
|
-
commands_under
|
|
688
|
-
|
|
689
|
+
# admin > node > do sub-tree (Gen4 commands)
|
|
690
|
+
commands_under %i[admin node do] do
|
|
691
|
+
command :transfer, description: 'Transfer files (node-to-node)'
|
|
692
|
+
command :permission, description: 'Manage permissions'
|
|
693
|
+
command :sync, description: 'Synchronize folders'
|
|
694
|
+
Node::COMMANDS_GEN4_SPEC.each do |cmd, spec|
|
|
695
|
+
command cmd, **spec
|
|
696
|
+
end
|
|
689
697
|
end
|
|
690
698
|
# admin > user > preferences|notifications sub-trees
|
|
691
699
|
%i[preferences notifications].each do |pref|
|
|
@@ -695,12 +703,12 @@ module Aspera
|
|
|
695
703
|
arguments: [{name: :properties, type: Hash}]
|
|
696
704
|
end
|
|
697
705
|
end
|
|
698
|
-
commands_under
|
|
706
|
+
commands_under %i[admin auth_providers] do
|
|
699
707
|
command :list, description: 'List auth providers',
|
|
700
|
-
action: ->{result_list('admin/auth_providers')}
|
|
701
|
-
command :update, description: 'Update auth provider', action: ->{Aspera.error_not_implemented}
|
|
708
|
+
action: -> { result_list('admin/auth_providers') }
|
|
709
|
+
command :update, description: 'Update auth provider', action: -> { Aspera.error_not_implemented }
|
|
702
710
|
end
|
|
703
|
-
commands_under
|
|
711
|
+
commands_under %i[admin subscription] do
|
|
704
712
|
command :account, description: 'Show subscription account'
|
|
705
713
|
command :usage, description: 'Show subscription usage',
|
|
706
714
|
arguments: [
|
|
@@ -709,7 +717,7 @@ module Aspera
|
|
|
709
717
|
{name: :end_date, mandatory: false, default: nil}
|
|
710
718
|
]
|
|
711
719
|
end
|
|
712
|
-
commands_under
|
|
720
|
+
commands_under %i[admin analytics] do
|
|
713
721
|
command :application_events, description: 'List application events'
|
|
714
722
|
command :transfers, description: 'List transfer events',
|
|
715
723
|
arguments: [
|
|
@@ -724,9 +732,9 @@ module Aspera
|
|
|
724
732
|
]
|
|
725
733
|
end
|
|
726
734
|
# application sub-commands
|
|
727
|
-
commands_under
|
|
735
|
+
commands_under %i[admin application] do
|
|
728
736
|
command :types, description: 'List application types',
|
|
729
|
-
action: ->{Result::ObjectList.new(aoc_api.read('admin/apps'))}
|
|
737
|
+
action: -> { Result::ObjectList.new(aoc_api.read('admin/apps')) }
|
|
730
738
|
command :settings, description: 'Manage per-app-type settings'
|
|
731
739
|
command :instance, description: 'Manage app instances'
|
|
732
740
|
command :membership, description: 'Manage app memberships'
|
|
@@ -734,12 +742,12 @@ module Aspera
|
|
|
734
742
|
APP_SETTINGS_PATH = %i[admin application settings].freeze
|
|
735
743
|
APP_INSTANCE_PATH = %i[admin application instance].freeze
|
|
736
744
|
private_constant :APP_SETTINGS_PATH, :APP_INSTANCE_PATH
|
|
737
|
-
commands_under
|
|
745
|
+
commands_under APP_SETTINGS_PATH do
|
|
738
746
|
APP_TYPES.each do |app_type|
|
|
739
|
-
command
|
|
740
|
-
commands_under
|
|
747
|
+
command app_type, description: "Settings for #{app_type} app"
|
|
748
|
+
commands_under app_type do
|
|
741
749
|
command :show, description: "Show #{app_type} settings",
|
|
742
|
-
action: ->{Result::SingleObject.new(aoc_api.read("/apps/#{app_type}/settings"))}
|
|
750
|
+
action: -> { Result::SingleObject.new(aoc_api.read("/apps/#{app_type}/settings")) }
|
|
743
751
|
command(
|
|
744
752
|
:modify, description: "Modify #{app_type} settings",
|
|
745
753
|
arguments: [{name: :properties, type: Hash}],
|
|
@@ -751,7 +759,7 @@ module Aspera
|
|
|
751
759
|
end
|
|
752
760
|
end
|
|
753
761
|
end
|
|
754
|
-
commands_under
|
|
762
|
+
commands_under APP_INSTANCE_PATH do
|
|
755
763
|
command(:list, description: 'List app instances', action: lambda do
|
|
756
764
|
result_list(
|
|
757
765
|
'admin/apps_new',
|
|
@@ -760,64 +768,57 @@ module Aspera
|
|
|
760
768
|
)
|
|
761
769
|
end)
|
|
762
770
|
APP_TYPES.each do |app_type|
|
|
763
|
-
command
|
|
764
|
-
commands_under
|
|
771
|
+
command app_type, description: "Show or modify a #{app_type} instance"
|
|
772
|
+
commands_under app_type do
|
|
765
773
|
command :show, description: "Show a #{app_type} instance",
|
|
766
|
-
arguments: [{name: :
|
|
774
|
+
arguments: [{name: :"#{app_type}_id", type: :identifier}]
|
|
767
775
|
command :modify, description: "Modify a #{app_type} instance",
|
|
768
|
-
arguments: [{name: :
|
|
776
|
+
arguments: [{name: :"#{app_type}_id", type: :identifier}, {name: :properties, type: Hash}]
|
|
769
777
|
end
|
|
770
778
|
end
|
|
771
779
|
end
|
|
772
|
-
commands_under
|
|
773
|
-
command :list, description: 'List app memberships',
|
|
774
|
-
|
|
775
|
-
command :
|
|
776
|
-
|
|
777
|
-
command :delete, description: 'Delete an app membership',
|
|
778
|
-
arguments: [{name: :res_id, type: :identifier}]
|
|
779
|
-
command :create, description: 'Create an app membership',
|
|
780
|
-
arguments: [{name: :membership, type: Hash}]
|
|
780
|
+
commands_under %i[admin application membership] do
|
|
781
|
+
command :list, description: 'List app memberships', action: -> { result_list('apps/app_memberships') }
|
|
782
|
+
command :show, description: 'Show an app membership', arguments: [{name: :membership_id, type: :identifier}]
|
|
783
|
+
command :delete, description: 'Delete an app membership', arguments: [{name: :membership_id, type: :identifier}]
|
|
784
|
+
command :create, description: 'Create an app membership', arguments: [{name: :membership, type: Hash}]
|
|
781
785
|
end
|
|
782
786
|
command :automation, description: 'Automation commands (BETA)', setup: :setup_automation_api
|
|
783
787
|
command :gateway, description: 'Start AoC Faspex4 gateway',
|
|
784
788
|
arguments: [{name: :parameters, type: Hash, mandatory: false, default: {}}]
|
|
785
789
|
|
|
786
790
|
# user sub-commands
|
|
787
|
-
commands_under
|
|
788
|
-
|
|
789
|
-
|
|
791
|
+
commands_under :user do
|
|
792
|
+
commands_under :workspaces, description: "User's workspaces" do
|
|
793
|
+
command :list, description: 'List workspaces', action: -> { result_list('workspaces', fields: %w[id name]) }
|
|
794
|
+
command :current, description: 'Show current workspace', action: -> { Result::SingleObject.new(aoc_api.workspace_info) }
|
|
795
|
+
end
|
|
796
|
+
# command :profile, description: 'User profile commands'
|
|
797
|
+
commands_under :profile, description: "Manager user's profile" do
|
|
798
|
+
command :show, description: 'Show user profile', action: -> { Result::SingleObject.new(aoc_api.current_user_info(exception: true)) }
|
|
799
|
+
command(
|
|
800
|
+
:modify, description: 'Modify user profile',
|
|
801
|
+
arguments: [{name: :properties, type: Hash}],
|
|
802
|
+
action: lambda do |properties:, **|
|
|
803
|
+
aoc_api.update("users/#{aoc_api.current_user_info(exception: true)['id']}", properties)
|
|
804
|
+
Result::Status.new('modified')
|
|
805
|
+
end
|
|
806
|
+
)
|
|
807
|
+
end
|
|
790
808
|
command :preferences, description: 'User interaction preferences'
|
|
791
809
|
command :notifications, description: 'Notification preferences'
|
|
792
810
|
command :contacts, description: 'Manage contacts'
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
command :list, description: 'List workspaces',
|
|
802
|
-
action: ->{result_list('workspaces', fields: %w[id name])}
|
|
803
|
-
command :current, description: 'Show current workspace',
|
|
804
|
-
action: ->{Result::SingleObject.new(aoc_api.workspace_info)}
|
|
805
|
-
end
|
|
806
|
-
|
|
807
|
-
commands_under(%i[user profile]) do
|
|
808
|
-
command :show, description: 'Show user profile',
|
|
809
|
-
action: ->{Result::SingleObject.new(aoc_api.current_user_info(exception: true))}
|
|
810
|
-
command(
|
|
811
|
-
:modify, description: 'Modify user profile',
|
|
812
|
-
arguments: [{name: :properties, type: Hash}],
|
|
813
|
-
action: lambda do |properties:, **|
|
|
814
|
-
aoc_api.update("users/#{aoc_api.current_user_info(exception: true)['id']}", properties)
|
|
815
|
-
Result::Status.new('modified')
|
|
816
|
-
end
|
|
817
|
-
)
|
|
811
|
+
# user > contacts sub-commands (same CRUD as admin > contact)
|
|
812
|
+
commands_under %i[contacts] do
|
|
813
|
+
Operations::ALL.each { |op| command op, description: op.to_s.capitalize }
|
|
814
|
+
end
|
|
815
|
+
command :settings, description: 'Manage client settings'
|
|
816
|
+
commands_under %i[settings] do
|
|
817
|
+
crud_commands api: :aoc_api, entity: 'client_settings', name: 'client setting'
|
|
818
|
+
end
|
|
818
819
|
end
|
|
819
820
|
|
|
820
|
-
commands_under
|
|
821
|
+
commands_under %i[user preferences] do
|
|
821
822
|
command(
|
|
822
823
|
:show, description: 'Show user preferences',
|
|
823
824
|
action: lambda do
|
|
@@ -836,7 +837,7 @@ module Aspera
|
|
|
836
837
|
)
|
|
837
838
|
end
|
|
838
839
|
|
|
839
|
-
commands_under
|
|
840
|
+
commands_under %i[user notifications] do
|
|
840
841
|
command(
|
|
841
842
|
:show, description: 'Show notification preferences',
|
|
842
843
|
action: lambda do
|
|
@@ -856,31 +857,31 @@ module Aspera
|
|
|
856
857
|
end
|
|
857
858
|
|
|
858
859
|
# packages sub-commands — instance commands consume package_id
|
|
859
|
-
commands_under
|
|
860
|
-
command :shared_inboxes,
|
|
861
|
-
command :send,
|
|
860
|
+
commands_under :packages do
|
|
861
|
+
command :shared_inboxes, description: 'Shared inbox commands'
|
|
862
|
+
command :send, description: 'Send a package', transfer_paths: :send,
|
|
862
863
|
arguments: [{name: :data, type: Hash, schema: Schema::Registry.req_body(Schema::Registry::AOC, 'packages.post')}]
|
|
863
|
-
command :receive,
|
|
864
|
+
command :receive, description: 'Receive packages', aliases: [:recv], transfer_paths: :receive,
|
|
864
865
|
arguments: [{name: :package_id, type: :identifier}]
|
|
865
|
-
command :list,
|
|
866
|
-
command :show,
|
|
866
|
+
command :list, description: 'List packages'
|
|
867
|
+
command :show, description: 'Show a package',
|
|
867
868
|
arguments: [{name: :package_id, type: :identifier}]
|
|
868
|
-
command :delete,
|
|
869
|
+
command :delete, description: 'Delete packages',
|
|
869
870
|
arguments: [{name: :package_id, type: :identifier}]
|
|
870
|
-
command :modify,
|
|
871
|
+
command :modify, description: 'Modify a package',
|
|
871
872
|
arguments: [{name: :package_id, type: :identifier}, {name: :data, type: Hash}]
|
|
872
873
|
# Node Gen4 read-only actions on packages
|
|
873
874
|
command :bearer_token_node, description: 'Show bearer token for package node',
|
|
874
875
|
arguments: [{name: :package_id, type: :identifier}]
|
|
875
876
|
command :node_info, description: 'Show node info for package',
|
|
876
877
|
arguments: [{name: :package_id, type: :identifier}]
|
|
877
|
-
command :
|
|
878
|
+
command :ls, description: 'List package contents', aliases: [:browse],
|
|
878
879
|
arguments: [{name: :package_id, type: :identifier}]
|
|
879
880
|
command :find, description: 'Find files in package',
|
|
880
881
|
arguments: [{name: :package_id, type: :identifier}]
|
|
881
882
|
end
|
|
882
883
|
|
|
883
|
-
commands_under
|
|
884
|
+
commands_under %i[packages shared_inboxes] do
|
|
884
885
|
command :list, description: 'List shared inboxes',
|
|
885
886
|
action: (lambda do
|
|
886
887
|
result_list(
|
|
@@ -891,7 +892,7 @@ module Aspera
|
|
|
891
892
|
end)
|
|
892
893
|
command :show, description: 'Show a shared inbox',
|
|
893
894
|
arguments: [{name: :dropbox_id, type: :identifier, lookup: :lookup_aoc_dropbox_id}],
|
|
894
|
-
action: ->(dropbox_id:, **){Result::SingleObject.new(aoc_api.read("dropboxes/#{dropbox_id}"))}
|
|
895
|
+
action: ->(dropbox_id:, **) { Result::SingleObject.new(aoc_api.read("dropboxes/#{dropbox_id}")) }
|
|
895
896
|
command :short_link, description: 'Manage shared inbox short links',
|
|
896
897
|
arguments: [{name: :link_type, allowed: %i[public private]}],
|
|
897
898
|
setup: :setup_packages_short_link
|
|
@@ -899,61 +900,41 @@ module Aspera
|
|
|
899
900
|
# packages > shared_inboxes > short_link sub-commands
|
|
900
901
|
register_short_link_commands(self, %i[packages shared_inboxes short_link])
|
|
901
902
|
|
|
902
|
-
# files sub-commands:
|
|
903
|
-
|
|
904
|
-
commands_under(:files) do
|
|
903
|
+
# files sub-commands: AoC-specific commands + all Gen4 commands from COMMANDS_GEN4_SPEC
|
|
904
|
+
commands_under :files do
|
|
905
905
|
command :short_link, description: 'Manage file short link',
|
|
906
906
|
arguments: [{name: :folder_dest, type: String}, {name: :link_type, allowed: %i[public private]}],
|
|
907
907
|
setup: :setup_files_short_link
|
|
908
908
|
command :transfer, description: 'Transfer files (node-to-node)',
|
|
909
909
|
arguments: [{name: :direction, allowed: %i[push pull]}, {name: :source_folder, type: String}]
|
|
910
|
-
command :
|
|
911
|
-
command :
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
command :upload, description: 'Upload files', transfer_paths: :send
|
|
916
|
-
command :download, description: 'Download files', transfer_paths: :receive
|
|
917
|
-
command :sync, description: 'Synchronize folders'
|
|
918
|
-
command :cat, description: 'Show file contents'
|
|
919
|
-
command :show, description: 'Show file info'
|
|
920
|
-
command :modify, description: 'Modify file'
|
|
921
|
-
command :permission, description: 'Manage permissions'
|
|
922
|
-
command :thumbnail, description: 'Show file thumbnail'
|
|
923
|
-
command :v3, description: 'Legacy v3 commands on files'
|
|
924
|
-
command :bearer_token_node, description: 'Show bearer token for file node'
|
|
925
|
-
command :node_info, description: 'Show node info for file'
|
|
926
|
-
command :browse, description: 'Browse files'
|
|
927
|
-
command :find, description: 'Find files'
|
|
910
|
+
command :permission, description: 'Manage permissions'
|
|
911
|
+
command :sync, description: 'Synchronize folders'
|
|
912
|
+
Node::COMMANDS_GEN4_SPEC.each do |cmd, spec|
|
|
913
|
+
command cmd, **spec
|
|
914
|
+
end
|
|
928
915
|
end
|
|
929
916
|
# files > short_link sub-commands
|
|
930
917
|
register_short_link_commands(self, %i[files short_link])
|
|
931
918
|
|
|
932
919
|
# automation sub-commands
|
|
933
|
-
commands_under
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
commands_under(%i[automation workflows]) do
|
|
939
|
-
command :create, description: 'Create a workflow'
|
|
940
|
-
command :list, description: 'List workflows'
|
|
941
|
-
command :show, description: 'Show a workflow'
|
|
942
|
-
command :modify, description: 'Modify a workflow'
|
|
943
|
-
command :delete, description: 'Delete a workflow'
|
|
944
|
-
command :launch, description: 'Launch a workflow',
|
|
945
|
-
arguments: [{name: :wf_id, type: :identifier}],
|
|
946
|
-
action: ->(wf_id:, **){Result::SingleObject.new(@automation_api.create("workflows/#{wf_id}/launch", {}))}
|
|
947
|
-
command :action, description: 'Add action to workflow (TODO)'
|
|
948
|
-
end
|
|
920
|
+
commands_under :automation do
|
|
921
|
+
commands_under :instances do
|
|
922
|
+
crud_commands api: :aoc_api, entity: 'workflow_instances', name: 'workflow instance'
|
|
923
|
+
end
|
|
949
924
|
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
925
|
+
commands_under :workflows do
|
|
926
|
+
crud_commands api: :@automation_api, entity: 'workflows'
|
|
927
|
+
command :launch, description: 'Launch a workflow',
|
|
928
|
+
arguments: [{name: :wf_id, type: :identifier}],
|
|
929
|
+
action: ->(wf_id:, **) { Result::SingleObject.new(@automation_api.create("workflows/#{wf_id}/launch", {})) }
|
|
930
|
+
commands_under :action, description: 'Add action to workflow (TODO)' do
|
|
931
|
+
%i[list create show].each do |cmd|
|
|
932
|
+
command cmd,
|
|
933
|
+
description: "#{cmd.capitalize} action (TODO)",
|
|
934
|
+
arguments: [{name: :wf_id, type: :identifier}]
|
|
935
|
+
end
|
|
936
|
+
end
|
|
937
|
+
end
|
|
957
938
|
end
|
|
958
939
|
|
|
959
940
|
# --- setup methods ---
|
|
@@ -1015,15 +996,16 @@ module Aspera
|
|
|
1015
996
|
skip_ids_persistency = package_persistency
|
|
1016
997
|
case ids_to_download
|
|
1017
998
|
when SpecialValues::INIT
|
|
1018
|
-
all_packages = list_all_packages_with_query
|
|
999
|
+
all_packages, = list_all_packages_with_query
|
|
1019
1000
|
Aspera.assert(skip_ids_persistency, 'INIT requires option once_only')
|
|
1020
|
-
skip_ids_persistency.data.clear.concat(all_packages.map{ |e| e['id']})
|
|
1001
|
+
skip_ids_persistency.data.clear.concat(all_packages[:items].map { |e| e['id'] })
|
|
1021
1002
|
skip_ids_persistency.save
|
|
1022
1003
|
return Result::Status.new("Initialized skip for #{skip_ids_persistency.data.count} package(s)")
|
|
1023
1004
|
when SpecialValues::ALL
|
|
1024
|
-
all_packages = list_all_packages_with_query
|
|
1025
|
-
reject_packages_from_persistency(all_packages, skip_ids_persistency)
|
|
1026
|
-
|
|
1005
|
+
all_packages, max_items = list_all_packages_with_query
|
|
1006
|
+
reject_packages_from_persistency(all_packages[:items], skip_ids_persistency)
|
|
1007
|
+
all_packages[:items] = all_packages[:items][0, max_items] if max_items
|
|
1008
|
+
ids_to_download = all_packages[:items].map { |e| e['id'] }
|
|
1027
1009
|
formatter.display_status("Found #{ids_to_download.length} package(s).")
|
|
1028
1010
|
else
|
|
1029
1011
|
ids_to_download = [ids_to_download] unless ids_to_download.is_a?(Array)
|
|
@@ -1061,9 +1043,10 @@ module Aspera
|
|
|
1061
1043
|
|
|
1062
1044
|
# packages > list
|
|
1063
1045
|
def action_packages_list
|
|
1064
|
-
result = list_all_packages_with_query
|
|
1046
|
+
result, max_items = list_all_packages_with_query
|
|
1065
1047
|
skip_ids_persistency = package_persistency
|
|
1066
1048
|
reject_packages_from_persistency(result[:items], skip_ids_persistency)
|
|
1049
|
+
result[:items] = result[:items][0, max_items] if max_items
|
|
1067
1050
|
display_fields = PACKAGE_LIST_DEFAULT_FIELDS
|
|
1068
1051
|
display_fields += ['workspace_id'] if aoc_api.workspace_info[:id].nil?
|
|
1069
1052
|
Result::ObjectList.new(result[:items], fields: display_fields, total: result[:total])
|
|
@@ -1076,10 +1059,8 @@ module Aspera
|
|
|
1076
1059
|
|
|
1077
1060
|
# packages > delete
|
|
1078
1061
|
def action_packages_delete(package_id:, **)
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
Result.bulk(items, is_bulk: is_bulk, command: :delete, bfail: options.get_option(:bfail)) do |one_id|
|
|
1082
|
-
Aspera.assert_type(one_id, String, Integer){'identifier'}
|
|
1062
|
+
bulk_result(package_id, command: :delete) do |one_id|
|
|
1063
|
+
Aspera.assert_type(one_id, String, Integer) { 'identifier' }
|
|
1083
1064
|
aoc_api.delete("packages/#{one_id}")
|
|
1084
1065
|
end
|
|
1085
1066
|
end
|
|
@@ -1090,7 +1071,7 @@ module Aspera
|
|
|
1090
1071
|
Result::Status.new('modified')
|
|
1091
1072
|
end
|
|
1092
1073
|
|
|
1093
|
-
# packages > bearer_token_node / node_info /
|
|
1074
|
+
# packages > bearer_token_node / node_info / ls / find
|
|
1094
1075
|
# (NODE4_READ_ACTIONS dispatched by full path: action_packages_bearer_token_node, etc.)
|
|
1095
1076
|
Node::NODE4_READ_ACTIONS.each do |action|
|
|
1096
1077
|
define_action_method([:packages, action]) do |package_id:, **|
|
|
@@ -1134,12 +1115,12 @@ module Aspera
|
|
|
1134
1115
|
created_data = shared_apifid.node_api.create('permissions', perm_data)
|
|
1135
1116
|
aoc_api.permissions_send_event(event_data: created_data, app_info: shared_apifid.node_api.app_info)
|
|
1136
1117
|
when :update
|
|
1137
|
-
found = shared_apifid.node_api.read('permissions', {file_id: shared_apifid.file_id, inherited: false, access_type: 'user', access_id: id}).find{ |i| i['access_id'].eql?(id)}
|
|
1138
|
-
Aspera.assert(!found.nil?, type: Error){"Short link not found: #{id}"}
|
|
1118
|
+
found = shared_apifid.node_api.read('permissions', {file_id: shared_apifid.file_id, inherited: false, access_type: 'user', access_id: id}).find { |i| i['access_id'].eql?(id) }
|
|
1119
|
+
Aspera.assert(!found.nil?, type: Error) { "Short link not found: #{id}" }
|
|
1139
1120
|
shared_apifid.node_api.update("permissions/#{found['id']}", {access_levels: Api::AoC.expand_access_levels(access_levels)})
|
|
1140
1121
|
when :delete
|
|
1141
1122
|
found = shared_apifid.node_api.read('permissions', {file_id: shared_apifid.file_id, inherited: false, access_type: 'user', access_id: id}).first
|
|
1142
|
-
Aspera.assert(!found.nil?, type: Error){"Short link not found: #{id}"}
|
|
1123
|
+
Aspera.assert(!found.nil?, type: Error) { "Short link not found: #{id}" }
|
|
1143
1124
|
shared_apifid.node_api.delete("permissions/#{found['id']}")
|
|
1144
1125
|
else Aspera.error_unexpected_value(op)
|
|
1145
1126
|
end
|
|
@@ -1216,7 +1197,7 @@ module Aspera
|
|
|
1216
1197
|
def sl_exec_delete(sl_shared_data_ws:, sl_short_list:, sl_link_type:, sl_perm_block:, short_link_id: nil, **)
|
|
1217
1198
|
one_id = short_link_id
|
|
1218
1199
|
if sl_link_type.eql?(:public)
|
|
1219
|
-
found = sl_short_list[:items].find{ |item| item['id'].eql?(one_id)}
|
|
1200
|
+
found = sl_short_list[:items].find { |item| item['id'].eql?(one_id) }
|
|
1220
1201
|
raise BadIdentifier.new('Short link', one_id) if found.nil?
|
|
1221
1202
|
sl_perm_block&.call(:delete, found['resource_id'], nil)
|
|
1222
1203
|
end
|
|
@@ -1232,14 +1213,14 @@ module Aspera
|
|
|
1232
1213
|
# Shared implementation for short_link > show
|
|
1233
1214
|
def sl_exec_show(sl_short_list:, short_link_id: nil, **)
|
|
1234
1215
|
one_id = short_link_id
|
|
1235
|
-
found = sl_short_list[:items].find{ |item| item['id'].eql?(one_id)}
|
|
1216
|
+
found = sl_short_list[:items].find { |item| item['id'].eql?(one_id) }
|
|
1236
1217
|
raise BadIdentifier.new('Short link', one_id) if found.nil?
|
|
1237
1218
|
Result::SingleObject.new(found, fields: Formatter.all_but('data'))
|
|
1238
1219
|
end
|
|
1239
1220
|
|
|
1240
1221
|
# Shared implementation for short_link > modify
|
|
1241
1222
|
def sl_exec_modify(custom_data = {}, sl_shared_data:, sl_short_list:, sl_link_type:, sl_perm_block:, short_link_id: nil, **)
|
|
1242
|
-
Aspera.assert_values(sl_link_type, [:public], type: Cli::BadArgument){'link_type'}
|
|
1223
|
+
Aspera.assert_values(sl_link_type, [:public], type: Cli::BadArgument) { 'link_type' }
|
|
1243
1224
|
one_id = short_link_id
|
|
1244
1225
|
node_file = sl_shared_data.slice(:node_id, :file_id)
|
|
1245
1226
|
modify_payload = {edit_access: true, json_query: node_file}
|
|
@@ -1251,7 +1232,7 @@ module Aspera
|
|
|
1251
1232
|
modify_payload[:password_enabled] = false
|
|
1252
1233
|
end
|
|
1253
1234
|
if custom_data.delete('access_levels')
|
|
1254
|
-
found = sl_short_list[:items].find{ |item| item['id'].eql?(one_id)}
|
|
1235
|
+
found = sl_short_list[:items].find { |item| item['id'].eql?(one_id) }
|
|
1255
1236
|
raise BadIdentifier.new('Short link', one_id) if found.nil?
|
|
1256
1237
|
sl_perm_block&.call(:update, found['resource_id'], nil)
|
|
1257
1238
|
end
|
|
@@ -1272,20 +1253,22 @@ module Aspera
|
|
|
1272
1253
|
end
|
|
1273
1254
|
|
|
1274
1255
|
# files > FILES_COMMANDS (all Gen4 node commands except :transfer, handled above)
|
|
1275
|
-
FILES_COMMANDS.reject{ |a| a.eql?(:transfer)}.each do |action|
|
|
1276
|
-
define_action_method([:files, action]) do
|
|
1277
|
-
execute_nodegen4_command(action, aoc_api.home[:node_id], file_id: aoc_api.home[:file_id], scope: Api::Node::Scope::USER)
|
|
1256
|
+
FILES_COMMANDS.reject { |a| a.eql?(:transfer) }.each do |action|
|
|
1257
|
+
define_action_method([:files, action]) do |**ctx|
|
|
1258
|
+
execute_nodegen4_command(action, aoc_api.home[:node_id], file_id: aoc_api.home[:file_id], scope: Api::Node::Scope::USER, **ctx)
|
|
1278
1259
|
end
|
|
1279
1260
|
end
|
|
1280
1261
|
|
|
1281
1262
|
# admin > application > instance > <type> > show|modify
|
|
1282
1263
|
APP_TYPES.each do |app_type|
|
|
1283
|
-
define_action_method([:admin, :application, :instance, app_type, :show]) do |
|
|
1284
|
-
|
|
1264
|
+
define_action_method([:admin, :application, :instance, app_type, :show]) do |**kwargs|
|
|
1265
|
+
app_id = kwargs[:"#{app_type}_id"]
|
|
1266
|
+
Result::SingleObject.new(aoc_api.read("admin/apps_new/#{app_type}/#{app_id}", query_read_delete))
|
|
1285
1267
|
end
|
|
1286
1268
|
|
|
1287
|
-
define_action_method([:admin, :application, :instance, app_type, :modify]) do |properties:,
|
|
1288
|
-
|
|
1269
|
+
define_action_method([:admin, :application, :instance, app_type, :modify]) do |properties:, **kwargs|
|
|
1270
|
+
app_id = kwargs[:"#{app_type}_id"]
|
|
1271
|
+
aoc_api.update("admin/apps_new/#{app_type}/#{app_id}", properties)
|
|
1289
1272
|
Result::Status.new('modified')
|
|
1290
1273
|
end
|
|
1291
1274
|
end
|
|
@@ -1293,18 +1276,18 @@ module Aspera
|
|
|
1293
1276
|
def action_admin_application_membership_create(membership:, **)
|
|
1294
1277
|
data = membership.dup
|
|
1295
1278
|
app_type = data.delete('app_type')
|
|
1296
|
-
Aspera.assert_type(app_type, String){'app_type'}
|
|
1297
|
-
Aspera.assert_values(app_type.to_sym, APP_TYPES){'app_type'}
|
|
1279
|
+
Aspera.assert_type(app_type, String) { 'app_type' }
|
|
1280
|
+
Aspera.assert_values(app_type.to_sym, APP_TYPES) { 'app_type' }
|
|
1298
1281
|
Result::SingleObject.new(aoc_api.create("apps/#{app_type}/app_memberships", data))
|
|
1299
1282
|
end
|
|
1300
1283
|
|
|
1301
1284
|
# admin > application > membership > show|delete
|
|
1302
|
-
def action_admin_application_membership_show(
|
|
1303
|
-
Result::SingleObject.new(aoc_api.read("apps/app_memberships/#{
|
|
1285
|
+
def action_admin_application_membership_show(membership_id:, **)
|
|
1286
|
+
Result::SingleObject.new(aoc_api.read("apps/app_memberships/#{membership_id}", query_read_delete))
|
|
1304
1287
|
end
|
|
1305
1288
|
|
|
1306
|
-
def action_admin_application_membership_delete(
|
|
1307
|
-
aoc_api.delete("apps/app_memberships/#{
|
|
1289
|
+
def action_admin_application_membership_delete(membership_id:, **)
|
|
1290
|
+
aoc_api.delete("apps/app_memberships/#{membership_id}")
|
|
1308
1291
|
Result::Status.new('deleted')
|
|
1309
1292
|
end
|
|
1310
1293
|
|
|
@@ -1337,14 +1320,12 @@ module Aspera
|
|
|
1337
1320
|
|
|
1338
1321
|
# admin > analytics > application_events
|
|
1339
1322
|
def action_admin_analytics_application_events
|
|
1340
|
-
|
|
1341
|
-
events = analytics_api.read("organizations/#{aoc_api.current_user_info['organization_id']}/application_events")['application_events']
|
|
1323
|
+
events = build_analytics_api.read("organizations/#{aoc_api.current_user_info['organization_id']}/application_events")['application_events']
|
|
1342
1324
|
Result::ObjectList.new(events)
|
|
1343
1325
|
end
|
|
1344
1326
|
|
|
1345
1327
|
# admin > analytics > transfers
|
|
1346
1328
|
def action_admin_analytics_transfers(event_resource_type:, event_resource_id:, **)
|
|
1347
|
-
analytics_api = build_analytics_api
|
|
1348
1329
|
event_resource_id ||=
|
|
1349
1330
|
case event_resource_type
|
|
1350
1331
|
when :organizations then aoc_api.current_user_info['organization_id']
|
|
@@ -1367,15 +1348,14 @@ module Aspera
|
|
|
1367
1348
|
filter['start_time'] = start_date_time unless start_date_time.nil?
|
|
1368
1349
|
filter['stop_time'] = stop_date_time
|
|
1369
1350
|
end
|
|
1370
|
-
events =
|
|
1351
|
+
events = build_analytics_api.read("#{event_resource_type}/#{event_resource_id}/transfers", filter)['transfers']
|
|
1371
1352
|
start_date_persistency&.save
|
|
1372
|
-
events.each{ |tr_event| context.mailer.send_email_template(values: {ev: tr_event})} if !options.get_option(:notify_to).nil?
|
|
1353
|
+
events.each { |tr_event| context.mailer.send_email_template(values: {ev: tr_event}) } if !options.get_option(:notify_to).nil?
|
|
1373
1354
|
Result::ObjectList.new(events)
|
|
1374
1355
|
end
|
|
1375
1356
|
|
|
1376
1357
|
# admin > analytics > files
|
|
1377
1358
|
def action_admin_analytics_files(event_resource_type:, event_resource_id:, event_uuid:, **)
|
|
1378
|
-
analytics_api = build_analytics_api
|
|
1379
1359
|
event_resource_id =
|
|
1380
1360
|
case event_resource_type
|
|
1381
1361
|
when :organizations then aoc_api.current_user_info['organization_id']
|
|
@@ -1385,13 +1365,13 @@ module Aspera
|
|
|
1385
1365
|
end if event_resource_id.to_s.empty?
|
|
1386
1366
|
filter = query_read_delete(default: {})
|
|
1387
1367
|
filter['limit'] ||= 100
|
|
1388
|
-
events =
|
|
1368
|
+
events = build_analytics_api.read("#{event_resource_type}/#{event_resource_id}/transfers/#{event_uuid}/files", filter)['files']
|
|
1389
1369
|
Result::ObjectList.new(events)
|
|
1390
1370
|
end
|
|
1391
1371
|
|
|
1392
1372
|
# Lookup methods for arguments:(:identifier) + lookup: on admin resources.
|
|
1393
1373
|
# One method per non-singleton resource; each delegates to get_resource_id_from_args.
|
|
1394
|
-
ADMIN_OBJECTS.reject{ |r| ADMIN_OBJECT_CONFIG.dig(r, :singleton)}.each do |res|
|
|
1374
|
+
ADMIN_OBJECTS.reject { |r| ADMIN_OBJECT_CONFIG.dig(r, :singleton) }.each do |res|
|
|
1395
1375
|
define_method(:"lookup_aoc_#{res}_id") do |_field, value, **|
|
|
1396
1376
|
aoc_api.lookup_with_q(aoc_res_path(res), value: value)['id']
|
|
1397
1377
|
end
|
|
@@ -1406,8 +1386,9 @@ module Aspera
|
|
|
1406
1386
|
end
|
|
1407
1387
|
|
|
1408
1388
|
# admin > <res> > show
|
|
1409
|
-
ADMIN_OBJECTS.reject{ |r| ADMIN_OBJECT_CONFIG.dig(r, :singleton)}.each do |res|
|
|
1410
|
-
define_action_method([:admin, res, :show]) do |
|
|
1389
|
+
ADMIN_OBJECTS.reject { |r| ADMIN_OBJECT_CONFIG.dig(r, :singleton) }.each do |res|
|
|
1390
|
+
define_action_method([:admin, res, :show]) do |**kwargs|
|
|
1391
|
+
res_id = kwargs[:"#{res}_id"]
|
|
1411
1392
|
c = aoc_res_cfg(res)
|
|
1412
1393
|
Result::SingleObject.new(aoc_api.read("#{c[:path]}/#{res_id}", query_read_delete), fields: Formatter.all_but('certificate'))
|
|
1413
1394
|
end
|
|
@@ -1421,15 +1402,14 @@ module Aspera
|
|
|
1421
1402
|
end
|
|
1422
1403
|
|
|
1423
1404
|
# admin > <res> > create
|
|
1424
|
-
ADMIN_OBJECTS.reject{ |r| ADMIN_OBJECT_CONFIG.dig(r, :singleton)}.each do |res|
|
|
1405
|
+
ADMIN_OBJECTS.reject { |r| ADMIN_OBJECT_CONFIG.dig(r, :singleton) }.each do |res|
|
|
1425
1406
|
define_action_method([:admin, res, :create]) do |data:, **|
|
|
1426
1407
|
c = aoc_res_cfg(res)
|
|
1427
1408
|
path = c[:path]
|
|
1428
1409
|
# Special case: client_registration_token has a different creation URL
|
|
1429
1410
|
path = 'admin/client_registration/token' if path.eql?('admin/client_registration_tokens')
|
|
1430
1411
|
workspace_id = aoc_api.workspace_info[:id] if c[:require_ws_id]
|
|
1431
|
-
|
|
1432
|
-
Result.bulk(data, is_bulk: is_bulk, command: :create, id_result: c[:id_result], bfail: options.get_option(:bfail)) do |params|
|
|
1412
|
+
bulk_result(data, command: :create, id_result: c[:id_result]) do |params|
|
|
1433
1413
|
params['workspace_id'] = workspace_id if c[:require_ws_id] && workspace_id && !params.key?('workspace_id')
|
|
1434
1414
|
aoc_api.create(path, params)
|
|
1435
1415
|
end
|
|
@@ -1437,8 +1417,9 @@ module Aspera
|
|
|
1437
1417
|
end
|
|
1438
1418
|
|
|
1439
1419
|
# admin > <res> > modify
|
|
1440
|
-
ADMIN_OBJECTS.reject{ |r| ADMIN_OBJECT_CONFIG.dig(r, :singleton) || ADMIN_OBJECT_CONFIG.dig(r, :ops)&.then{ |o| !o.include?(:modify)}}.each do |res|
|
|
1441
|
-
define_action_method([:admin, res, :modify]) do |data:,
|
|
1420
|
+
ADMIN_OBJECTS.reject { |r| ADMIN_OBJECT_CONFIG.dig(r, :singleton) || ADMIN_OBJECT_CONFIG.dig(r, :ops)&.then { |o| !o.include?(:modify) } }.each do |res|
|
|
1421
|
+
define_action_method([:admin, res, :modify]) do |data:, **kwargs|
|
|
1422
|
+
res_id = kwargs[:"#{res}_id"]
|
|
1442
1423
|
c = aoc_res_cfg(res)
|
|
1443
1424
|
aoc_api.update("#{c[:path]}/#{res_id}", data)
|
|
1444
1425
|
Result::Status.new('modified')
|
|
@@ -1450,11 +1431,10 @@ module Aspera
|
|
|
1450
1431
|
cfg = ADMIN_OBJECT_CONFIG.fetch(r, {})
|
|
1451
1432
|
cfg[:singleton] || (cfg[:ops] && !cfg[:ops].include?(:delete))
|
|
1452
1433
|
end.each do |res|
|
|
1453
|
-
define_action_method([:admin, res, :delete]) do |
|
|
1434
|
+
define_action_method([:admin, res, :delete]) do |**kwargs|
|
|
1435
|
+
res_id = kwargs[:"#{res}_id"]
|
|
1454
1436
|
c = aoc_res_cfg(res)
|
|
1455
|
-
|
|
1456
|
-
items = res_id.is_a?(Array) ? res_id : [res_id]
|
|
1457
|
-
Result.bulk(items, is_bulk: is_bulk, command: :delete, bfail: options.get_option(:bfail)) do |one_id|
|
|
1437
|
+
bulk_result(res_id, command: :delete) do |one_id|
|
|
1458
1438
|
aoc_api.delete("#{c[:path]}/#{one_id}")
|
|
1459
1439
|
{'id' => one_id}
|
|
1460
1440
|
end
|
|
@@ -1469,33 +1449,44 @@ module Aspera
|
|
|
1469
1449
|
end
|
|
1470
1450
|
|
|
1471
1451
|
# admin > client > set_pub_key
|
|
1472
|
-
def action_admin_client_set_pub_key(private_key_pem:,
|
|
1452
|
+
def action_admin_client_set_pub_key(private_key_pem:, client_id:, **)
|
|
1473
1453
|
c = aoc_res_cfg(:client)
|
|
1474
1454
|
the_public_key = OpenSSL::PKey::RSA.new(private_key_pem).public_key.to_s
|
|
1475
|
-
aoc_api.update("#{c[:path]}/#{
|
|
1455
|
+
aoc_api.update("#{c[:path]}/#{client_id}", {jwt_grant_enabled: true, public_key: the_public_key})
|
|
1476
1456
|
Result::Success.new
|
|
1477
1457
|
end
|
|
1478
1458
|
|
|
1459
|
+
# admin > ats — build and return an Ats plugin instance wired to the AoC ATS API.
|
|
1460
|
+
# Used as delegate_instance: target so --help traverses the Ats registry.
|
|
1461
|
+
# @return [Ats] configured Ats plugin instance
|
|
1462
|
+
def build_ats_plugin
|
|
1463
|
+
ats_api = Rest.new(**aoc_api.params.deep_merge({
|
|
1464
|
+
base_url: "#{aoc_api.base_url}/admin/ats/pub/v1",
|
|
1465
|
+
auth: {params: {scope: Api::AoC::Scope::ADMIN_USER}}
|
|
1466
|
+
}))
|
|
1467
|
+
Ats.new(context: context, api: ats_api)
|
|
1468
|
+
end
|
|
1469
|
+
|
|
1479
1470
|
# admin > node > do | bearer_token — setup reuses the generic instance setup
|
|
1480
1471
|
# (setup_admin_node_instance is auto-generated above, providing res_id:)
|
|
1481
1472
|
|
|
1482
1473
|
# admin > node > do > <FILES_COMMAND>
|
|
1483
1474
|
FILES_COMMANDS.each do |cmd|
|
|
1484
|
-
define_action_method([:admin, :node, :do, cmd]) do |
|
|
1485
|
-
execute_nodegen4_command(cmd,
|
|
1475
|
+
define_action_method([:admin, :node, :do, cmd]) do |node_id:, **ctx|
|
|
1476
|
+
execute_nodegen4_command(cmd, node_id, scope: Api::Node::Scope::ADMIN, **ctx)
|
|
1486
1477
|
end
|
|
1487
1478
|
end
|
|
1488
1479
|
|
|
1489
1480
|
# admin > node > bearer_token
|
|
1490
|
-
def action_admin_node_bearer_token(scope:,
|
|
1481
|
+
def action_admin_node_bearer_token(scope:, node_id:, **)
|
|
1491
1482
|
scope ||= Api::Node::Scope::ADMIN
|
|
1492
|
-
node_api = aoc_api.node_api_from(node_id:
|
|
1483
|
+
node_api = aoc_api.node_api_from(node_id: node_id, scope: scope)
|
|
1493
1484
|
Result::Text.new(node_api.oauth.authorization)
|
|
1494
1485
|
end
|
|
1495
1486
|
|
|
1496
1487
|
# admin > workspace > dropbox — res_id: already in ctx via arguments:(:identifier)
|
|
1497
|
-
def setup_admin_workspace_dropbox(
|
|
1498
|
-
{ws_res_id:
|
|
1488
|
+
def setup_admin_workspace_dropbox(workspace_id:, **)
|
|
1489
|
+
{ws_res_id: workspace_id}
|
|
1499
1490
|
end
|
|
1500
1491
|
|
|
1501
1492
|
# admin > workspace > dropbox > list
|
|
@@ -1505,11 +1496,11 @@ module Aspera
|
|
|
1505
1496
|
end
|
|
1506
1497
|
|
|
1507
1498
|
# admin > workspace > shared_folder — res_id: already in ctx via arguments:(:identifier)
|
|
1508
|
-
def setup_admin_workspace_shared_folder(
|
|
1509
|
-
resource_instance_path = "#{aoc_res_path(:workspace)}/#{
|
|
1510
|
-
query = options.get_option(:query) || Api::AoC.workspace_access(
|
|
1499
|
+
def setup_admin_workspace_shared_folder(workspace_id:, **)
|
|
1500
|
+
resource_instance_path = "#{aoc_res_path(:workspace)}/#{workspace_id}"
|
|
1501
|
+
query = options.get_option(:query) || Api::AoC.workspace_access(workspace_id).merge({'admin' => true})
|
|
1511
1502
|
shared_folders = aoc_api.read_with_paging("#{resource_instance_path}/permissions", query)[:items]
|
|
1512
|
-
{ws_res_id:
|
|
1503
|
+
{ws_res_id: workspace_id, shared_folders: shared_folders}
|
|
1513
1504
|
end
|
|
1514
1505
|
|
|
1515
1506
|
# admin > workspace > shared_folder > list
|
|
@@ -1519,7 +1510,7 @@ module Aspera
|
|
|
1519
1510
|
|
|
1520
1511
|
# admin > workspace > shared_folder > node|member — sf_id: already in ctx via arguments:(:identifier)
|
|
1521
1512
|
def resolve_sf_item(shared_folders:, sf_id:, **)
|
|
1522
|
-
sf_item = shared_folders.find{ |i| i['id'].eql?(sf_id)}
|
|
1513
|
+
sf_item = shared_folders.find { |i| i['id'].eql?(sf_id) }
|
|
1523
1514
|
Aspera.assert(sf_item, 'shared folder not found')
|
|
1524
1515
|
{sf_item: sf_item}
|
|
1525
1516
|
end
|
|
@@ -1529,8 +1520,8 @@ module Aspera
|
|
|
1529
1520
|
|
|
1530
1521
|
# admin > workspace > shared_folder > node > <FILES_COMMAND>
|
|
1531
1522
|
FILES_COMMANDS.each do |cmd|
|
|
1532
|
-
define_action_method([:admin, :workspace, :shared_folder, :node, cmd]) do |sf_item:,
|
|
1533
|
-
execute_nodegen4_command(cmd, sf_item['node_id'], file_id: sf_item['file_id'], scope: Api::Node::Scope::ADMIN)
|
|
1523
|
+
define_action_method([:admin, :workspace, :shared_folder, :node, cmd]) do |sf_item:, **ctx|
|
|
1524
|
+
execute_nodegen4_command(cmd, sf_item['node_id'], file_id: sf_item['file_id'], scope: Api::Node::Scope::ADMIN, **ctx)
|
|
1534
1525
|
end
|
|
1535
1526
|
end
|
|
1536
1527
|
|
|
@@ -1562,26 +1553,19 @@ module Aspera
|
|
|
1562
1553
|
# (setup_admin_user_instance is auto-generated, providing res_id:)
|
|
1563
1554
|
%i[preferences notifications].each do |pref|
|
|
1564
1555
|
pref_path = pref.eql?(:preferences) ? 'user_interaction_preferences' : 'notification_preferences'
|
|
1565
|
-
define_action_method([:admin, :user, pref, :show]) do |
|
|
1566
|
-
Result::SingleObject.new(aoc_api.read("#{aoc_res_path(:user)}/#{
|
|
1556
|
+
define_action_method([:admin, :user, pref, :show]) do |user_id:, **|
|
|
1557
|
+
Result::SingleObject.new(aoc_api.read("#{aoc_res_path(:user)}/#{user_id}/#{pref_path}"))
|
|
1567
1558
|
end
|
|
1568
|
-
define_action_method([:admin, :user, pref, :modify]) do |properties:,
|
|
1569
|
-
aoc_api.update("#{aoc_res_path(:user)}/#{
|
|
1559
|
+
define_action_method([:admin, :user, pref, :modify]) do |properties:, user_id:, **|
|
|
1560
|
+
aoc_api.update("#{aoc_res_path(:user)}/#{user_id}/#{pref_path}", properties)
|
|
1570
1561
|
Result::Status.new('modified')
|
|
1571
1562
|
end
|
|
1572
1563
|
end
|
|
1573
1564
|
|
|
1574
|
-
# automation > workflows > CRUD operations
|
|
1575
|
-
Operations::ALL.each do |op|
|
|
1576
|
-
define_action_method([:automation, :workflows, op]) do
|
|
1577
|
-
entity_execute(api: @automation_api, entity: 'workflows', command: op)
|
|
1578
|
-
end
|
|
1579
|
-
end
|
|
1580
|
-
|
|
1581
1565
|
# automation > workflows > action > * (TODO: not fully implemented)
|
|
1582
1566
|
%i[list create show].each do |cmd|
|
|
1583
1567
|
define_action_method([:automation, :workflows, :action, cmd]) do |wf_id:, **|
|
|
1584
|
-
Log.log.warn{"Not implemented: #{cmd}"}
|
|
1568
|
+
Log.log.warn { "Not implemented: #{cmd}" }
|
|
1585
1569
|
step = @automation_api.create('steps', {'workflow_id' => wf_id})
|
|
1586
1570
|
@automation_api.update("workflows/#{wf_id}", {'step_order' => [step['id']]})
|
|
1587
1571
|
action = @automation_api.create('actions', {'step_id' => step['id'], 'type' => 'manual'})
|
|
@@ -1593,9 +1577,9 @@ module Aspera
|
|
|
1593
1577
|
def action_gateway(parameters: {}, **)
|
|
1594
1578
|
require 'aspera/faspex_gw'
|
|
1595
1579
|
parameters = parameters.symbolize_keys
|
|
1596
|
-
uri = URI.parse(parameters.delete(:url){WebServerSimple::DEFAULT_URL})
|
|
1580
|
+
uri = URI.parse(parameters.delete(:url) { WebServerSimple::DEFAULT_URL })
|
|
1597
1581
|
server = WebServerSimple.new(uri, **parameters.slice(*WebServerSimple::PARAMS))
|
|
1598
|
-
Aspera.assert(parameters.except(*WebServerSimple::PARAMS).empty?){"unexpected parameters: #{parameters.except(*WebServerSimple::PARAMS).keys}"}
|
|
1582
|
+
Aspera.assert(parameters.except(*WebServerSimple::PARAMS).empty?) { "unexpected parameters: #{parameters.except(*WebServerSimple::PARAMS).keys}" }
|
|
1599
1583
|
server.mount(uri.path, Faspex4GWServlet, aoc_api, aoc_api.workspace_info[:id])
|
|
1600
1584
|
server.start
|
|
1601
1585
|
return Result::Status.new('Gateway terminated')
|