aspera-cli 4.25.6 → 4.26.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 +89 -48
- data/CONTRIBUTING.md +1 -1
- data/lib/aspera/api/aoc.rb +120 -79
- data/lib/aspera/api/node.rb +103 -51
- data/lib/aspera/ascp/installation.rb +99 -32
- data/lib/aspera/assert.rb +17 -13
- data/lib/aspera/cli/extended_value.rb +7 -2
- data/lib/aspera/cli/formatter.rb +107 -95
- data/lib/aspera/cli/main.rb +69 -10
- data/lib/aspera/cli/manager.rb +158 -78
- data/lib/aspera/cli/options.schema.yaml +82 -0
- data/lib/aspera/cli/plugins/aoc.rb +247 -144
- data/lib/aspera/cli/plugins/ats.rb +3 -3
- data/lib/aspera/cli/plugins/base.rb +60 -76
- data/lib/aspera/cli/plugins/config.rb +14 -12
- data/lib/aspera/cli/plugins/console.rb +3 -3
- data/lib/aspera/cli/plugins/faspex.rb +6 -6
- data/lib/aspera/cli/plugins/faspex5.rb +24 -23
- data/lib/aspera/cli/plugins/node.rb +67 -71
- data/lib/aspera/cli/plugins/oauth.rb +5 -12
- data/lib/aspera/cli/plugins/orchestrator.rb +13 -13
- data/lib/aspera/cli/plugins/preview.rb +116 -80
- data/lib/aspera/cli/plugins/server.rb +2 -10
- data/lib/aspera/cli/plugins/shares.rb +7 -7
- data/lib/aspera/cli/sync_actions.rb +1 -1
- data/lib/aspera/cli/transfer_agent.rb +17 -15
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/command_line_builder.rb +22 -18
- data/lib/aspera/dot_container.rb +7 -3
- data/lib/aspera/environment.rb +6 -5
- data/lib/aspera/formatter_interface.rb +14 -0
- data/lib/aspera/hash_ext.rb +6 -0
- data/lib/aspera/log.rb +5 -4
- data/lib/aspera/markdown.rb +4 -1
- data/lib/aspera/oauth/factory.rb +1 -1
- data/lib/aspera/preview/file_types.rb +1 -1
- data/lib/aspera/preview/generator.rb +146 -91
- data/lib/aspera/preview/options.rb +4 -1
- data/lib/aspera/preview/terminal.rb +50 -20
- data/lib/aspera/preview/utils.rb +76 -34
- data/lib/aspera/products/transferd.rb +1 -1
- data/lib/aspera/proxy_auto_config.rb +3 -0
- data/lib/aspera/rest.rb +2 -1
- data/lib/aspera/rest_list.rb +23 -16
- data/lib/aspera/schema/IBM Aspera Faspex API-5.0-enhanced.yaml +62801 -0
- data/lib/aspera/schema/IBM Aspera on Cloud API-0.2.6-enhanced.yaml +8898 -0
- data/lib/aspera/schema/documentation.rb +107 -0
- data/lib/aspera/schema/reader.rb +75 -0
- data/lib/aspera/schema/registry.rb +63 -0
- data/lib/aspera/secret_hider.rb +3 -1
- data/lib/aspera/sync/conf.schema.yaml +0 -26
- data/lib/aspera/sync/operations.rb +9 -5
- data/lib/aspera/transfer/faux_file.rb +1 -1
- data/lib/aspera/transfer/resumer.rb +1 -1
- data/lib/aspera/transfer/spec.rb +3 -3
- data/lib/aspera/transfer/spec.schema.yaml +1 -1
- data/lib/aspera/uri_reader.rb +17 -2
- data/lib/aspera/yaml.rb +4 -2
- data.tar.gz.sig +0 -0
- metadata +13 -7
- metadata.gz.sig +0 -0
- data/lib/aspera/transfer/spec_doc.rb +0 -76
|
@@ -56,7 +56,7 @@ module Aspera
|
|
|
56
56
|
commands = %i[create list show modify delete node cluster entitlement]
|
|
57
57
|
command = options.get_next_command(commands)
|
|
58
58
|
# those do not require access key id
|
|
59
|
-
access_key_id = instance_identifier unless %i[create list].include?(command)
|
|
59
|
+
access_key_id = options.instance_identifier unless %i[create list].include?(command)
|
|
60
60
|
case command
|
|
61
61
|
when :create
|
|
62
62
|
params = value_create_modify(command: command, default: {})
|
|
@@ -151,7 +151,7 @@ module Aspera
|
|
|
151
151
|
if options.get_option(:cloud) || options.get_option(:region)
|
|
152
152
|
server_data = server_by_cloud_region
|
|
153
153
|
else
|
|
154
|
-
server_id = instance_identifier
|
|
154
|
+
server_id = options.instance_identifier
|
|
155
155
|
server_data = @ats_api_open.all_servers.find{ |i| i['id'].eql?(server_id)}
|
|
156
156
|
raise BadIdentifier.new('server', server_id) if server_data.nil?
|
|
157
157
|
end
|
|
@@ -179,7 +179,7 @@ module Aspera
|
|
|
179
179
|
|
|
180
180
|
def execute_action_api_key
|
|
181
181
|
command = options.get_next_command(%i[instances create list show delete])
|
|
182
|
-
concerned_id = instance_identifier if %i[show delete].include?(command)
|
|
182
|
+
concerned_id = options.instance_identifier if %i[show delete].include?(command)
|
|
183
183
|
rest_add_header = {}
|
|
184
184
|
if !command.eql?(:instances)
|
|
185
185
|
instance = options.get_option(:instance)
|
|
@@ -8,28 +8,22 @@ module Aspera
|
|
|
8
8
|
module Plugins
|
|
9
9
|
# Base class for command plugins
|
|
10
10
|
class Base
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
module Operations
|
|
12
|
+
# Operations without id: `create` `list`
|
|
13
|
+
GLOBAL = %i[create list].freeze
|
|
14
|
+
# Operations on singleton: `modify` `show`
|
|
15
|
+
SINGLETON = %i[modify show].freeze
|
|
16
|
+
# Operations with id: `modify` `show` `delete`
|
|
17
|
+
INSTANCE = (SINGLETON + %i[delete]).freeze
|
|
18
|
+
# All standard operations: `create` `list` `modify` `show` `delete`
|
|
19
|
+
ALL = (GLOBAL + INSTANCE).freeze
|
|
20
|
+
end
|
|
18
21
|
class << self
|
|
19
22
|
def declare_options(options)
|
|
20
23
|
options.declare(:query, 'Additional filter for for some commands (list/delete)', allowed: [Hash, Array, NilClass])
|
|
21
24
|
options.declare(:bulk, 'Bulk operation (only some)', allowed: Allowed::TYPES_BOOLEAN, default: false)
|
|
22
25
|
options.declare(:bfail, 'Bulk operation error handling', allowed: Allowed::TYPES_BOOLEAN, default: true)
|
|
23
26
|
end
|
|
24
|
-
|
|
25
|
-
# @return [Hash,NilClass] `{field:,value:}` if identifier is a percent selector, else `nil`
|
|
26
|
-
def percent_selector(identifier)
|
|
27
|
-
Aspera.assert_type(identifier, String)
|
|
28
|
-
if (m = identifier.match(REGEX_LOOKUP_ID_BY_FIELD))
|
|
29
|
-
return {field: m[1], value: ExtendedValue.instance.evaluate(m[2], context: "percent selector: #{m[1]}")}
|
|
30
|
-
end
|
|
31
|
-
return
|
|
32
|
-
end
|
|
33
27
|
end
|
|
34
28
|
|
|
35
29
|
def initialize(context:)
|
|
@@ -43,15 +37,15 @@ module Aspera
|
|
|
43
37
|
# Global objects
|
|
44
38
|
attr_reader :context
|
|
45
39
|
|
|
46
|
-
# @return [Manager]
|
|
40
|
+
# @return [Aspera::Cli::Manager]
|
|
47
41
|
def options; @context.options; end
|
|
48
|
-
# @return [TransferAgent]
|
|
42
|
+
# @return [Aspera::Cli::TransferAgent]
|
|
49
43
|
def transfer; @context.transfer; end
|
|
50
|
-
# @return [Config]
|
|
44
|
+
# @return [Aspera::Cli::Plugins::Config]
|
|
51
45
|
def config; @context.config; end
|
|
52
|
-
# @return [Formatter]
|
|
46
|
+
# @return [Aspera::Cli::Formatter]
|
|
53
47
|
def formatter; @context.formatter; end
|
|
54
|
-
# @return [PersistencyFolder]
|
|
48
|
+
# @return [Aspera::PersistencyFolder]
|
|
55
49
|
def persistency; @context.persistency; end
|
|
56
50
|
|
|
57
51
|
def add_manual_header(has_options = true)
|
|
@@ -62,36 +56,24 @@ module Aspera
|
|
|
62
56
|
options.parser.separator('OPTIONS:') if has_options
|
|
63
57
|
end
|
|
64
58
|
|
|
65
|
-
# Resource identifier as positional parameter
|
|
66
|
-
#
|
|
67
|
-
# @param description [String] description of the identifier
|
|
68
|
-
# @param &block [Proc] block to search for identifier based on attribute value
|
|
69
|
-
# @return [String, Array] identifier or list of ids
|
|
70
|
-
def instance_identifier(description: 'identifier')
|
|
71
|
-
res_id = options.get_next_argument(description, multiple: options.get_option(:bulk)) if res_id.nil?
|
|
72
|
-
# Can be an Array
|
|
73
|
-
if res_id.is_a?(String) && (m = Base.percent_selector(res_id))
|
|
74
|
-
Aspera.assert(block_given?, type: Cli::BadArgument){"Percent syntax for #{description} not supported in this context"}
|
|
75
|
-
res_id = yield(m[:field], m[:value])
|
|
76
|
-
end
|
|
77
|
-
return res_id
|
|
78
|
-
end
|
|
79
|
-
|
|
80
59
|
# For create and delete operations: execute one action or multiple if bulk is yes
|
|
81
|
-
# @param command
|
|
82
|
-
# @param descr
|
|
83
|
-
# @param values
|
|
84
|
-
# @param id_result [String] Key in result
|
|
85
|
-
# @param fields
|
|
86
|
-
# @param
|
|
87
|
-
|
|
60
|
+
# @param command [Symbol] Operation: :create, :delete, ...
|
|
61
|
+
# @param descr [String, nil] Description of the value
|
|
62
|
+
# @param values [Class, Array, Symbol] Type, or list of values, or :identifier, result is given to the block in loop
|
|
63
|
+
# @param id_result [String] Key in result Hash to use as identifier
|
|
64
|
+
# @param fields [Symbol, Array] Fields to display
|
|
65
|
+
# @param schema [Hash, nil] JSON schema for validation
|
|
66
|
+
# @yieldparam param [Object] The parameter value to process
|
|
67
|
+
# @yieldreturn [Hash, nil] Result hash for the operation (optional)
|
|
68
|
+
# @return [Hash] Result suitable for CLI output
|
|
69
|
+
def do_bulk_operation(command:, descr: nil, values: Hash, id_result: 'id', fields: :default, schema: nil, &block)
|
|
88
70
|
Aspera.assert(block_given?){'missing block'}
|
|
89
71
|
is_bulk = options.get_option(:bulk)
|
|
90
72
|
case values
|
|
91
73
|
when :identifier
|
|
92
|
-
values = instance_identifier(description: descr)
|
|
74
|
+
values = options.instance_identifier(description: descr)
|
|
93
75
|
when Class
|
|
94
|
-
values = value_create_modify(command: command, description: descr, type: values, bulk: is_bulk)
|
|
76
|
+
values = value_create_modify(command: command, description: descr, type: values, bulk: is_bulk, schema: schema)
|
|
95
77
|
end
|
|
96
78
|
# If not bulk, there is a single value
|
|
97
79
|
params = is_bulk ? values : [values]
|
|
@@ -126,15 +108,17 @@ module Aspera
|
|
|
126
108
|
end
|
|
127
109
|
|
|
128
110
|
# Operations: Create, Delete, Show, List, Modify
|
|
129
|
-
# @param api
|
|
130
|
-
# @param entity
|
|
131
|
-
# @param command
|
|
132
|
-
# @param display_fields [Array]
|
|
133
|
-
# @param items_key
|
|
134
|
-
# @param delete_style
|
|
135
|
-
# @param id_as_arg
|
|
136
|
-
# @param is_singleton
|
|
137
|
-
# @param
|
|
111
|
+
# @param api [Aspera::Rest] API to use
|
|
112
|
+
# @param entity [String] Sub path in URL to resource relative to base url
|
|
113
|
+
# @param command [Symbol, nil] Command to execute: :create, :show, :list, :modify, :delete
|
|
114
|
+
# @param display_fields [Array, nil] Fields to display by default
|
|
115
|
+
# @param items_key [String, nil] Result is in a sub key of the JSON
|
|
116
|
+
# @param delete_style [String, nil] If set, the delete operation by array in payload
|
|
117
|
+
# @param id_as_arg [Boolean, String] If set, the id is provided as url argument ?<id_as_arg>=<id>
|
|
118
|
+
# @param is_singleton [Boolean] If `true`, entity is the full path to the resource
|
|
119
|
+
# @param list_query [Hash, nil] Query parameters for list operation
|
|
120
|
+
# @yieldparam value [String] Value to search for identifier
|
|
121
|
+
# @yieldreturn [String] The identifier
|
|
138
122
|
# @return [Hash] Result suitable for CLI result
|
|
139
123
|
def entity_execute(
|
|
140
124
|
api:,
|
|
@@ -148,11 +132,11 @@ module Aspera
|
|
|
148
132
|
list_query: nil,
|
|
149
133
|
&block
|
|
150
134
|
)
|
|
151
|
-
command = options.get_next_command(
|
|
135
|
+
command = options.get_next_command(Operations::ALL) if command.nil?
|
|
152
136
|
if is_singleton
|
|
153
137
|
one_res_path = entity
|
|
154
|
-
elsif
|
|
155
|
-
one_res_id = instance_identifier(&block)
|
|
138
|
+
elsif Operations::INSTANCE.include?(command)
|
|
139
|
+
one_res_id = options.instance_identifier(&block)
|
|
156
140
|
one_res_path = "#{entity}/#{one_res_id}"
|
|
157
141
|
one_res_path = "#{entity}?#{id_as_arg}=#{one_res_id}" if id_as_arg
|
|
158
142
|
end
|
|
@@ -210,6 +194,8 @@ module Aspera
|
|
|
210
194
|
end
|
|
211
195
|
|
|
212
196
|
# Query parameters in URL suitable for REST: list/`GET` and delete/`DELETE`
|
|
197
|
+
# @param default [Hash, nil] Default query parameters
|
|
198
|
+
# @return [Hash, nil] Query parameters
|
|
213
199
|
def query_read_delete(default: nil)
|
|
214
200
|
# Dup default, as it could be frozen
|
|
215
201
|
query = options.get_option(:query) || default.dup
|
|
@@ -223,35 +209,33 @@ module Aspera
|
|
|
223
209
|
return query
|
|
224
210
|
end
|
|
225
211
|
|
|
226
|
-
# Retrieves an extended value from command line
|
|
227
|
-
#
|
|
228
|
-
# @param
|
|
229
|
-
# @param
|
|
230
|
-
# @param
|
|
231
|
-
|
|
212
|
+
# Retrieves an extended value from command line.
|
|
213
|
+
# Used for creation or modification of entities.
|
|
214
|
+
# @param command [Symbol] Command name for error message
|
|
215
|
+
# @param description [String, nil] Description of the value
|
|
216
|
+
# @param type [Class, nil] Expected type of value
|
|
217
|
+
# @param bulk [Boolean] If `true`, value must be an Array of `type`
|
|
218
|
+
# @param default [Object, nil] Default value if not provided
|
|
219
|
+
# @param schema [Hash, nil] JSON schema for validation
|
|
220
|
+
# @return [Hash, Array<Hash>] The value(s) to create object(s)
|
|
221
|
+
def value_create_modify(command:, description: nil, type: Hash, bulk: false, default: nil, schema: nil)
|
|
232
222
|
value = options.get_next_argument(
|
|
233
|
-
"parameters for #{command}#{" (#{description})" unless description.nil?}",
|
|
234
|
-
|
|
223
|
+
"parameters for #{command}#{" (#{description})" unless description.nil?}",
|
|
224
|
+
mandatory: default.nil?,
|
|
225
|
+
validation: bulk ? Array : type,
|
|
226
|
+
schema: schema
|
|
235
227
|
)
|
|
236
228
|
value = default if value.nil?
|
|
237
229
|
unless type.nil?
|
|
238
|
-
type
|
|
239
|
-
Aspera.assert_array_all(type, Class){'check types'}
|
|
230
|
+
Aspera.assert_type(type, Class){'type'}
|
|
240
231
|
if bulk
|
|
241
|
-
Aspera.
|
|
242
|
-
value.each do |v|
|
|
243
|
-
Aspera.assert_values(v.class, type, type: Cli::BadArgument)
|
|
244
|
-
end
|
|
232
|
+
Aspera.assert_array_all(value, type, type: Cli::BadArgument){'type'}
|
|
245
233
|
else
|
|
246
|
-
Aspera.
|
|
234
|
+
Aspera.assert_type(value, type, type: Cli::BadArgument){'type'}
|
|
247
235
|
end
|
|
248
236
|
end
|
|
249
237
|
return value
|
|
250
238
|
end
|
|
251
|
-
|
|
252
|
-
# Percent selector: select by this field for this value
|
|
253
|
-
REGEX_LOOKUP_ID_BY_FIELD = /^%([^:]+):(.*)$/
|
|
254
|
-
private_constant :REGEX_LOOKUP_ID_BY_FIELD
|
|
255
239
|
end
|
|
256
240
|
end
|
|
257
241
|
end
|
|
@@ -16,7 +16,7 @@ require 'aspera/sync/operations'
|
|
|
16
16
|
require 'aspera/products/transferd'
|
|
17
17
|
require 'aspera/transfer/parameters'
|
|
18
18
|
require 'aspera/transfer/spec'
|
|
19
|
-
require 'aspera/
|
|
19
|
+
require 'aspera/schema/documentation'
|
|
20
20
|
require 'aspera/keychain/macos_security'
|
|
21
21
|
require 'aspera/proxy_auto_config'
|
|
22
22
|
require 'aspera/environment'
|
|
@@ -436,7 +436,7 @@ module Aspera
|
|
|
436
436
|
end
|
|
437
437
|
|
|
438
438
|
def set_preset_key(preset, param_name, param_value)
|
|
439
|
-
Aspera.
|
|
439
|
+
Aspera.assert_type(param_name, String, Symbol){'parameter'}
|
|
440
440
|
param_name = param_name.to_s
|
|
441
441
|
selected_preset = @config_presets[preset]
|
|
442
442
|
if selected_preset.nil?
|
|
@@ -568,7 +568,9 @@ module Aspera
|
|
|
568
568
|
|
|
569
569
|
def install_transfer_sdk
|
|
570
570
|
asked_version = options.get_next_argument('transferd version', mandatory: false)
|
|
571
|
-
|
|
571
|
+
sdk_url = options.get_option(:sdk_url, mandatory: true)
|
|
572
|
+
sdk_url = nil if sdk_url.eql?(SpecialValues::DEF)
|
|
573
|
+
name, version, folder = Ascp::Installation.instance.retrieve_sdk(url: sdk_url, version: asked_version)
|
|
572
574
|
return Main.result_status("Installed #{name} version #{version} in #{folder}")
|
|
573
575
|
end
|
|
574
576
|
|
|
@@ -596,10 +598,10 @@ module Aspera
|
|
|
596
598
|
when :install
|
|
597
599
|
return install_transfer_sdk
|
|
598
600
|
when :spec
|
|
599
|
-
|
|
600
|
-
return Main.result_object_list(
|
|
601
|
+
builder = Schema::Documentation.new(TerminalFormatter, Transfer::Spec::SCHEMA, include_option: true, agent_columns: true).build
|
|
602
|
+
return Main.result_object_list(builder.rows, fields: builder.columns)
|
|
601
603
|
when :schema
|
|
602
|
-
schema = Transfer::Spec::SCHEMA.merge({'$comment'=>'DO NOT EDIT, this file was generated from the YAML.'})
|
|
604
|
+
schema = Transfer::Spec::SCHEMA.current.merge({'$comment'=>'DO NOT EDIT, this file was generated from the YAML.'})
|
|
603
605
|
agent = options.get_next_argument('transfer agent name', mandatory: false)
|
|
604
606
|
schema['properties'] = schema['properties'].select{ |_k, v| CommandLineBuilder.supported_by_agent(agent, v)} unless agent.nil?
|
|
605
607
|
schema['properties'] = schema['properties'].sort.to_h
|
|
@@ -641,7 +643,7 @@ module Aspera
|
|
|
641
643
|
|
|
642
644
|
def execute_preset(action: nil, name: nil)
|
|
643
645
|
action = options.get_next_command(PRESET_ALL_ACTIONS) if action.nil?
|
|
644
|
-
name = instance_identifier if name.nil? && PRESET_INSTANCE_ACTIONS.include?(action)
|
|
646
|
+
name = options.instance_identifier if name.nil? && PRESET_INSTANCE_ACTIONS.include?(action)
|
|
645
647
|
name = global_default_preset if name.eql?(GLOBAL_DEFAULT_KEYWORD)
|
|
646
648
|
# Those operations require existing option
|
|
647
649
|
raise "no such preset: #{name}" if PRESET_EXIST_ACTIONS.include?(action) && !@config_presets.key?(name)
|
|
@@ -820,7 +822,7 @@ module Aspera
|
|
|
820
822
|
when :list
|
|
821
823
|
return Main.result_object_list(OAuth::Factory.instance.persisted_tokens)
|
|
822
824
|
when :show
|
|
823
|
-
data = OAuth::Factory.instance.get_token_info(instance_identifier)
|
|
825
|
+
data = OAuth::Factory.instance.get_token_info(options.instance_identifier)
|
|
824
826
|
raise Cli::Error, 'Unknown identifier' if data.nil?
|
|
825
827
|
return Main.result_single_object(data)
|
|
826
828
|
end
|
|
@@ -832,8 +834,8 @@ module Aspera
|
|
|
832
834
|
plugin_class = Plugins::Factory.instance.plugin_class(name)
|
|
833
835
|
result.push({
|
|
834
836
|
plugin: name,
|
|
835
|
-
detect:
|
|
836
|
-
wizard:
|
|
837
|
+
detect: TerminalFormatter.tick(plugin_class.respond_to?(:detect)),
|
|
838
|
+
wizard: TerminalFormatter.tick(plugin_class.method_defined?(:wizard)),
|
|
837
839
|
path: Plugins::Factory.instance.plugin_source(name)
|
|
838
840
|
})
|
|
839
841
|
end
|
|
@@ -876,8 +878,8 @@ module Aspera
|
|
|
876
878
|
when :sync
|
|
877
879
|
case options.get_next_command(%i[spec admin translate])
|
|
878
880
|
when :spec
|
|
879
|
-
|
|
880
|
-
return Main.result_object_list(
|
|
881
|
+
builder = Schema::Documentation.new(TerminalFormatter, Sync::Operations::CONF_SCHEMA, include_option: true).build
|
|
882
|
+
return Main.result_object_list(builder.rows, fields: builder.columns)
|
|
881
883
|
when :admin
|
|
882
884
|
return execute_sync_admin
|
|
883
885
|
when :translate
|
|
@@ -130,15 +130,15 @@ module Aspera
|
|
|
130
130
|
fields: %w[id contact name status]
|
|
131
131
|
)
|
|
132
132
|
when :show
|
|
133
|
-
transfer_id = instance_identifier(description: 'transfer ID')
|
|
133
|
+
transfer_id = options.instance_identifier(description: 'transfer ID')
|
|
134
134
|
return Main.result_single_object(api_console.read("transfers/#{transfer_id}"))
|
|
135
135
|
when :files
|
|
136
|
-
transfer_id = instance_identifier(description: 'transfer ID')
|
|
136
|
+
transfer_id = options.instance_identifier(description: 'transfer ID')
|
|
137
137
|
query = query_read_delete(default: {})
|
|
138
138
|
query['limit'] ||= 100
|
|
139
139
|
return Main.result_object_list(api_console.read("transfers/#{transfer_id}/files", query))
|
|
140
140
|
when :start, :pause, :cancel, :resume, :rerun, :change_rate, :change_policy, :move_forwards, :move_back
|
|
141
|
-
transfer_id = instance_identifier(description: 'transfer ID')
|
|
141
|
+
transfer_id = options.instance_identifier(description: 'transfer ID')
|
|
142
142
|
return Main.result_single_object(api_console.update("transfers/#{transfer_id}/#{command}", query_read_delete))
|
|
143
143
|
end
|
|
144
144
|
end
|
|
@@ -165,7 +165,7 @@ module Aspera
|
|
|
165
165
|
def mailbox_filtered_entries(stop_at_id: nil)
|
|
166
166
|
recipient_names = [options.get_option(:recipient) || options.get_option(:username, mandatory: true)]
|
|
167
167
|
# some workgroup messages have no star in recipient name
|
|
168
|
-
recipient_names.push(recipient_names.first
|
|
168
|
+
recipient_names.push(recipient_names.first.delete_prefix('*')) if recipient_names.first.start_with?('*')
|
|
169
169
|
# mailbox is in ATOM_MAILBOXES
|
|
170
170
|
mailbox = options.get_option(:box, mandatory: true)
|
|
171
171
|
# parameters
|
|
@@ -291,7 +291,7 @@ module Aspera
|
|
|
291
291
|
command_pkg = options.get_next_command(%i[send receive list show], aliases: {recv: :receive})
|
|
292
292
|
case command_pkg
|
|
293
293
|
when :show
|
|
294
|
-
delivery_id = instance_identifier
|
|
294
|
+
delivery_id = options.instance_identifier
|
|
295
295
|
return Main.result_single_object(mailbox_filtered_entries(stop_at_id: delivery_id).find{ |p| p[PACKAGE_MATCH_FIELD].eql?(delivery_id)})
|
|
296
296
|
when :list
|
|
297
297
|
return Main.result_object_list(mailbox_filtered_entries, fields: [PACKAGE_MATCH_FIELD, 'title', 'items'])
|
|
@@ -307,7 +307,7 @@ module Aspera
|
|
|
307
307
|
first_source = delivery_info['sources'].first
|
|
308
308
|
first_source['paths'].concat(transfer.source_list)
|
|
309
309
|
source_id = options.get_option(:remote_source)
|
|
310
|
-
if source_id && (m =
|
|
310
|
+
if source_id && (m = Manager.percent_selector(source_id))
|
|
311
311
|
Aspera.assert(m[:field].eql?('name'), type: Cli::BadArgument){'only name as selector, or give id'}
|
|
312
312
|
source_list = api_v3.read('source_shares')['items']
|
|
313
313
|
source_id = self.class.get_source_id_by_name(m[:value], source_list)
|
|
@@ -348,7 +348,7 @@ module Aspera
|
|
|
348
348
|
)
|
|
349
349
|
end
|
|
350
350
|
# get command line parameters
|
|
351
|
-
delivery_id = instance_identifier
|
|
351
|
+
delivery_id = options.instance_identifier
|
|
352
352
|
Aspera.assert(!delivery_id.empty?){'empty id'}
|
|
353
353
|
recipient = options.get_option(:recipient)
|
|
354
354
|
if delivery_id.eql?(SpecialValues::ALL)
|
|
@@ -441,7 +441,7 @@ module Aspera
|
|
|
441
441
|
when :list
|
|
442
442
|
return Main.result_object_list(source_list)
|
|
443
443
|
else # :info :node
|
|
444
|
-
source_id = instance_identifier do |field, value|
|
|
444
|
+
source_id = options.instance_identifier do |field, value|
|
|
445
445
|
Aspera.assert(field.eql?('name'), type: Cli::BadArgument){'only name as selector, or give id'}
|
|
446
446
|
self.class.get_source_id_by_name(value, source_list)
|
|
447
447
|
end.to_i
|
|
@@ -506,7 +506,7 @@ module Aspera
|
|
|
506
506
|
return entity_execute(api: api_v4, entity: 'metadata_profiles')
|
|
507
507
|
when :package
|
|
508
508
|
pkg_box_type = options.get_next_command([:users])
|
|
509
|
-
pkg_box_id = instance_identifier
|
|
509
|
+
pkg_box_id = options.instance_identifier
|
|
510
510
|
return entity_execute(api: api_v4, entity: "#{pkg_box_type}/#{pkg_box_id}/packages")
|
|
511
511
|
end
|
|
512
512
|
when :address_book
|
|
@@ -98,6 +98,8 @@ module Aspera
|
|
|
98
98
|
options.declare(:shared_folder, 'Send package with files from shared folder')
|
|
99
99
|
options.declare(:group_type, 'Type of shared box', allowed: %i[shared_inboxes workgroups], default: :shared_inboxes)
|
|
100
100
|
options.parse_options!
|
|
101
|
+
# [Aspera::Api::Faspex]
|
|
102
|
+
@api_v5 = nil
|
|
101
103
|
end
|
|
102
104
|
|
|
103
105
|
# if recipient is just an email, then convert to expected API hash : name and type
|
|
@@ -114,7 +116,7 @@ module Aspera
|
|
|
114
116
|
parameters[type].map! do |recipient_data|
|
|
115
117
|
# If just a string, make a general lookup and build expected name/type hash
|
|
116
118
|
if recipient_data.is_a?(String)
|
|
117
|
-
matched = @api_v5.
|
|
119
|
+
matched = @api_v5.lookup_with_q('contacts', value: recipient_data, query: Rest.php_style({context: 'packages', type: recipient_types}))
|
|
118
120
|
recipient_data = {
|
|
119
121
|
name: matched['name'],
|
|
120
122
|
recipient_type: matched['type']
|
|
@@ -232,8 +234,8 @@ module Aspera
|
|
|
232
234
|
result_transfer = []
|
|
233
235
|
param_file_list = {}
|
|
234
236
|
begin
|
|
235
|
-
param_file_list['paths'] = transfer.
|
|
236
|
-
rescue Cli::
|
|
237
|
+
param_file_list['paths'] = transfer.ts_source_paths
|
|
238
|
+
rescue Cli::MissingArgument
|
|
237
239
|
# paths is optional
|
|
238
240
|
end
|
|
239
241
|
box = options.get_option(:box)
|
|
@@ -268,7 +270,7 @@ module Aspera
|
|
|
268
270
|
end
|
|
269
271
|
|
|
270
272
|
def package_send
|
|
271
|
-
parameters = value_create_modify(command: :send)
|
|
273
|
+
parameters = value_create_modify(command: :send, schema: Schema::Registry.req_body(Schema::Registry::FASPEX, 'packages.post'))
|
|
272
274
|
# autofill recipient for public url
|
|
273
275
|
if @api_v5.pub_link_context&.key?('recipient_type') && !parameters.key?('recipients')
|
|
274
276
|
parameters['recipients'] = [{
|
|
@@ -297,7 +299,7 @@ module Aspera
|
|
|
297
299
|
return Main.result_transfer(transfer.start(transfer_spec))
|
|
298
300
|
else
|
|
299
301
|
# send from remote shared folder
|
|
300
|
-
if (m =
|
|
302
|
+
if (m = Manager.percent_selector(shared_folder))
|
|
301
303
|
shared_folder = @api_v5.lookup_entity_by_field(
|
|
302
304
|
entity: 'shared_folders',
|
|
303
305
|
field: m[:field],
|
|
@@ -376,7 +378,7 @@ module Aspera
|
|
|
376
378
|
command = options.get_next_command(%i[show browse status delete receive send list])
|
|
377
379
|
package_id =
|
|
378
380
|
if %i[receive show browse status delete].include?(command)
|
|
379
|
-
@api_v5.pub_link_context&.key?('package_id') ? @api_v5.pub_link_context['package_id'] : instance_identifier
|
|
381
|
+
@api_v5.pub_link_context&.key?('package_id') ? @api_v5.pub_link_context['package_id'] : options.instance_identifier
|
|
380
382
|
end
|
|
381
383
|
case command
|
|
382
384
|
when :show
|
|
@@ -419,7 +421,7 @@ module Aspera
|
|
|
419
421
|
entity: res_sym.to_s
|
|
420
422
|
}
|
|
421
423
|
res_id_query = :default
|
|
422
|
-
available_commands =
|
|
424
|
+
available_commands = Operations::ALL
|
|
423
425
|
case res_sym
|
|
424
426
|
when :metadata_profiles
|
|
425
427
|
exec_args[:entity] = 'configuration/metadata_profiles'
|
|
@@ -437,7 +439,7 @@ module Aspera
|
|
|
437
439
|
available_commands += [:reset_password]
|
|
438
440
|
when :oauth_clients
|
|
439
441
|
exec_args[:display_fields] = Formatter.all_but('public_key')
|
|
440
|
-
exec_args[:api] = Api::Faspex.new(root: Api::Faspex::PATH_AUTH, **Oauth.
|
|
442
|
+
exec_args[:api] = Api::Faspex.new(root: Api::Faspex::PATH_AUTH, **Oauth.kwargs_from_options(options))
|
|
441
443
|
exec_args[:list_query] = {'expand': true, 'no_api_path': true, 'client_types[]': 'public'}
|
|
442
444
|
when :shared_inboxes, :workgroups
|
|
443
445
|
available_commands += %i[members saml_groups invite_external_collaborator]
|
|
@@ -459,13 +461,13 @@ module Aspera
|
|
|
459
461
|
return Main.result_object_list(data, total: total, fields: exec_args[:display_fields])
|
|
460
462
|
when :shared_folders
|
|
461
463
|
# nodes
|
|
462
|
-
node_id = instance_identifier do |field, value|
|
|
464
|
+
node_id = options.instance_identifier do |field, value|
|
|
463
465
|
@api_v5.lookup_entity_by_field(entity: 'nodes', field: field, value: value)['id']
|
|
464
466
|
end
|
|
465
467
|
shfld_entity = "nodes/#{node_id}/shared_folders"
|
|
466
|
-
sh_command = options.get_next_command(
|
|
468
|
+
sh_command = options.get_next_command(Operations::ALL + [:user])
|
|
467
469
|
case sh_command
|
|
468
|
-
when *
|
|
470
|
+
when *Operations::ALL
|
|
469
471
|
return entity_execute(
|
|
470
472
|
api: @api_v5,
|
|
471
473
|
entity: shfld_entity,
|
|
@@ -474,7 +476,7 @@ module Aspera
|
|
|
474
476
|
@api_v5.lookup_entity_by_field(entity: shfld_entity, field: field, value: value)['id']
|
|
475
477
|
end
|
|
476
478
|
when :user
|
|
477
|
-
sh_id = instance_identifier do |field, value|
|
|
479
|
+
sh_id = options.instance_identifier do |field, value|
|
|
478
480
|
@api_v5.lookup_entity_by_field(entity: shfld_entity, field: field, value: value)['id']
|
|
479
481
|
end
|
|
480
482
|
user_path = "#{shfld_entity}/#{sh_id}/custom_access_users"
|
|
@@ -485,15 +487,14 @@ module Aspera
|
|
|
485
487
|
end
|
|
486
488
|
when :browse
|
|
487
489
|
# nodes
|
|
488
|
-
node_id = instance_identifier do |field, value|
|
|
490
|
+
node_id = options.instance_identifier do |field, value|
|
|
489
491
|
@api_v5.lookup_entity_by_field(entity: 'nodes', value: value, field: field)['id']
|
|
490
492
|
end
|
|
491
493
|
return browse_folder("nodes/#{node_id}/browse")
|
|
492
494
|
when :invite_external_collaborator
|
|
493
495
|
# :shared_inboxes, :workgroups
|
|
494
|
-
shared_inbox_id = instance_identifier{ |field, value| @api_v5.lookup_entity_by_field(entity: res_sym.to_s, field: field, value: value, query: res_id_query)['id']}
|
|
495
|
-
creation_payload = value_create_modify(command: res_command
|
|
496
|
-
creation_payload = {'email_address' => creation_payload} if creation_payload.is_a?(String)
|
|
496
|
+
shared_inbox_id = options.instance_identifier{ |field, value| @api_v5.lookup_entity_by_field(entity: res_sym.to_s, field: field, value: value, query: res_id_query)['id']}
|
|
497
|
+
creation_payload = value_create_modify(command: res_command)
|
|
497
498
|
result = @api_v5.create("#{res_sym}/#{shared_inbox_id}/external_collaborator", creation_payload)
|
|
498
499
|
formatter.display_status(result['message'])
|
|
499
500
|
result = @api_v5.lookup_entity_by_field(
|
|
@@ -505,7 +506,7 @@ module Aspera
|
|
|
505
506
|
return Main.result_single_object(result)
|
|
506
507
|
when :members, :saml_groups
|
|
507
508
|
# res_command := :shared_inboxes, :workgroups
|
|
508
|
-
res_id = instance_identifier{ |field, value| @api_v5.lookup_entity_by_field(entity: res_sym.to_s, field: field, value: value, query: res_id_query)['id']}
|
|
509
|
+
res_id = options.instance_identifier{ |field, value| @api_v5.lookup_entity_by_field(entity: res_sym.to_s, field: field, value: value, query: res_id_query)['id']}
|
|
509
510
|
res_path = "#{res_sym}/#{res_id}/#{res_command}"
|
|
510
511
|
list_key = res_command.to_s
|
|
511
512
|
list_key = 'groups' if res_command.eql?(:saml_groups)
|
|
@@ -515,7 +516,7 @@ module Aspera
|
|
|
515
516
|
users = options.get_next_argument('user id, %name:, or Array')
|
|
516
517
|
users = [users] unless users.is_a?(Array)
|
|
517
518
|
users = users.map do |user|
|
|
518
|
-
if (m =
|
|
519
|
+
if (m = Manager.percent_selector(user))
|
|
519
520
|
@api_v5.lookup_entity_by_field(
|
|
520
521
|
entity: 'accounts',
|
|
521
522
|
field: m[:field],
|
|
@@ -546,7 +547,7 @@ module Aspera
|
|
|
546
547
|
end
|
|
547
548
|
when :reset_password
|
|
548
549
|
# :accounts
|
|
549
|
-
contact_id = instance_identifier{ |field, value| @api_v5.lookup_entity_by_field(entity: 'accounts', field: field, value: value, query: res_id_query)['id']}
|
|
550
|
+
contact_id = options.instance_identifier{ |field, value| @api_v5.lookup_entity_by_field(entity: 'accounts', field: field, value: value, query: res_id_query)['id']}
|
|
550
551
|
@api_v5.create("accounts/#{contact_id}/reset_password", {})
|
|
551
552
|
return Main.result_status('password reset, user shall check email')
|
|
552
553
|
end
|
|
@@ -617,7 +618,7 @@ module Aspera
|
|
|
617
618
|
command = options.get_next_command(ACTIONS)
|
|
618
619
|
unless %i{postprocessing health}.include?(command)
|
|
619
620
|
# create an API object with the same options, but with a different subpath
|
|
620
|
-
@api_v5 = Api::Faspex.new(**Oauth.
|
|
621
|
+
@api_v5 = Api::Faspex.new(**Oauth.kwargs_from_options(options))
|
|
621
622
|
# in case user wants to use HTTPGW tell transfer agent how to get address
|
|
622
623
|
transfer.httpgw_url_cb = lambda{@api_v5.read('account')['gateway_url']}
|
|
623
624
|
end
|
|
@@ -660,7 +661,7 @@ module Aspera
|
|
|
660
661
|
when :list
|
|
661
662
|
return Main.result_object_list(all_shared_folders)
|
|
662
663
|
when :browse
|
|
663
|
-
shared_folder_id = instance_identifier do |field, value|
|
|
664
|
+
shared_folder_id = options.instance_identifier do |field, value|
|
|
664
665
|
matches = all_shared_folders.select{ |i| i[field].eql?(value)}
|
|
665
666
|
raise "no match for #{field} = #{value}" if matches.empty?
|
|
666
667
|
raise "multiple matches for #{field} = #{value}" if matches.length > 1
|
|
@@ -674,7 +675,7 @@ module Aspera
|
|
|
674
675
|
return execute_admin
|
|
675
676
|
when :invitations
|
|
676
677
|
invitation_endpoint = 'invitations'
|
|
677
|
-
invitation_command = options.get_next_command(%i[resend].concat(
|
|
678
|
+
invitation_command = options.get_next_command(%i[resend].concat(Operations::ALL))
|
|
678
679
|
case invitation_command
|
|
679
680
|
when :create
|
|
680
681
|
return do_bulk_operation(command: invitation_command, descr: 'data') do |params|
|
|
@@ -682,7 +683,7 @@ module Aspera
|
|
|
682
683
|
@api_v5.create(invitation_endpoint, params)
|
|
683
684
|
end
|
|
684
685
|
when :resend
|
|
685
|
-
@api_v5.create("#{invitation_endpoint}/#{instance_identifier}/resend", nil)
|
|
686
|
+
@api_v5.create("#{invitation_endpoint}/#{options.instance_identifier}/resend", nil)
|
|
686
687
|
return Main.result_status('Invitation resent')
|
|
687
688
|
else
|
|
688
689
|
return entity_execute(
|