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
|
@@ -12,18 +12,6 @@ module Aspera
|
|
|
12
12
|
option :username, description: "User's identifier"
|
|
13
13
|
option :password, description: "User's password"
|
|
14
14
|
|
|
15
|
-
# Declare url/username/password on an arbitrary Options object.
|
|
16
|
-
# Still needed for ad-hoc callers that are not plugin instances
|
|
17
|
-
# (e.g. PresetActions#action_config_lookup).
|
|
18
|
-
class << self
|
|
19
|
-
def declare_options(options)
|
|
20
|
-
options.declare(:url, description: 'URL of application, e.g. https://app.example.com/aspera/app') unless options.option_declared?(:url)
|
|
21
|
-
options.declare(:username, description: "User's identifier") unless options.option_declared?(:username)
|
|
22
|
-
options.declare(:password, description: "User's password") unless options.option_declared?(:password)
|
|
23
|
-
options.parse_options!
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
15
|
def initialize(context:, basic_options: true)
|
|
28
16
|
super(context: context)
|
|
29
17
|
# DSL options (url, username, password) are auto-declared by Base#initialize
|
|
@@ -68,7 +68,7 @@ module Aspera
|
|
|
68
68
|
# @return [String] product family folder (~/.aspera)
|
|
69
69
|
def module_family_folder
|
|
70
70
|
user_home_folder = Dir.home
|
|
71
|
-
Aspera.assert(Dir.exist?(user_home_folder), type: Cli::Error){"Home folder does not exist: #{user_home_folder}. Check your user environment."}
|
|
71
|
+
Aspera.assert(Dir.exist?(user_home_folder), type: Cli::Error) { "Home folder does not exist: #{user_home_folder}. Check your user environment." }
|
|
72
72
|
return File.join(user_home_folder, ASPERA_HOME_FOLDER_NAME)
|
|
73
73
|
end
|
|
74
74
|
|
|
@@ -84,7 +84,7 @@ module Aspera
|
|
|
84
84
|
private_constant :DEFAULT_CHECK_NEW_VERSION_DAYS
|
|
85
85
|
|
|
86
86
|
option :preset, description: 'Load the named option preset from current config file', short: 'P', handler: :option_preset
|
|
87
|
-
option :version_check_days, description: 'Period in days to check new version (zero to disable)', allowed:
|
|
87
|
+
option :version_check_days, description: 'Period in days to check new version (zero to disable)', allowed: Type::INTEGER, default: DEFAULT_CHECK_NEW_VERSION_DAYS
|
|
88
88
|
option :plugin_folder, description: 'Folder where to find additional plugins', handler: :option_plugin_folder
|
|
89
89
|
option :sdk_url, description: 'Ascp: URL to get Aspera Transfer Executables', default: SpecialValues::DEF
|
|
90
90
|
option :locations_url, description: 'Ascp: URL to get download locations of Aspera Transfer Daemon', handler: {o: Ascp::Installation.instance, m: :transferd_urls}
|
|
@@ -92,7 +92,7 @@ module Aspera
|
|
|
92
92
|
option :smtp, schema: Schema::Registry::SMTP_OPTIONS
|
|
93
93
|
option :notify_to, description: 'Email: Recipient for notification of transfers'
|
|
94
94
|
option :notify_template, description: 'Email: ERB template for notification of transfers'
|
|
95
|
-
option :cache_tokens, description: 'Save and reuse OAuth tokens', allowed:
|
|
95
|
+
option :cache_tokens, description: 'Save and reuse OAuth tokens', allowed: Type::BOOLEAN, default: true, handler: :option_cache_tokens
|
|
96
96
|
|
|
97
97
|
def initialize(**_)
|
|
98
98
|
super
|
|
@@ -100,7 +100,7 @@ module Aspera
|
|
|
100
100
|
@sdk_default_location = false
|
|
101
101
|
@option_cache_tokens = true
|
|
102
102
|
# :no_default uses a &block callback - must stay imperative
|
|
103
|
-
options.declare(:no_default, description: 'Do not load default configuration for plugin', allowed:
|
|
103
|
+
options.declare(:no_default, description: 'Do not load default configuration for plugin', allowed: Type::NONE, short: 'N') { presets.use_plugin_defaults = false }
|
|
104
104
|
# Declare wizard options (Wizard#initialize calls options.declare internally)
|
|
105
105
|
@wizard = Wizard.new(self, context.main_folder)
|
|
106
106
|
options.parse_options!
|
|
@@ -113,7 +113,7 @@ module Aspera
|
|
|
113
113
|
|
|
114
114
|
# DSL command declarations - replaces ACTIONS + execute_action
|
|
115
115
|
command :preset, description: 'Manage configuration presets'
|
|
116
|
-
commands_under
|
|
116
|
+
commands_under :preset do
|
|
117
117
|
command :list, description: 'List all presets'
|
|
118
118
|
command :overview, description: 'Display all options from all presets'
|
|
119
119
|
command :lookup, description: 'Find preset matching URL and username'
|
|
@@ -127,11 +127,9 @@ module Aspera
|
|
|
127
127
|
arguments: [{name: :name, type: :identifier}, {name: :param_name, type: String}]
|
|
128
128
|
command :unset, description: 'Remove a parameter from a preset',
|
|
129
129
|
arguments: [{name: :name, type: :identifier}, {name: :param_name, type: String}]
|
|
130
|
-
command
|
|
131
|
-
:set, description: 'Set a parameter in a preset',
|
|
130
|
+
command :set, description: 'Set a parameter in a preset',
|
|
132
131
|
arguments: [{name: :name, type: :identifier}, {name: :param_name, type: String},
|
|
133
132
|
{name: :param_value, type: nil}]
|
|
134
|
-
)
|
|
135
133
|
command :initialize, description: 'Initialize a preset with a value',
|
|
136
134
|
arguments: [{name: :name, type: :identifier}, {name: :config_value, type: Hash}]
|
|
137
135
|
command :update, description: 'Update a preset with current option values',
|
|
@@ -159,11 +157,11 @@ module Aspera
|
|
|
159
157
|
]
|
|
160
158
|
command :pubkey, description: 'Display the public key of an RSA private key',
|
|
161
159
|
arguments: [{name: :private_key_pem, type: String}],
|
|
162
|
-
action: ->(private_key_pem:, **){Result::Text.new(OpenSSL::PKey::RSA.new(private_key_pem).public_key.to_s)}
|
|
160
|
+
action: ->(private_key_pem:, **) { Result::Text.new(OpenSSL::PKey::RSA.new(private_key_pem).public_key.to_s) }
|
|
163
161
|
command :remote_certificate, description: 'Retrieve the certificate chain of a remote HTTPS server'
|
|
164
162
|
command :echo, description: 'Display the value of a given argument',
|
|
165
163
|
arguments: [{name: :value, type: nil}],
|
|
166
|
-
action: ->(value:, **){Result.auto(value)}
|
|
164
|
+
action: ->(value:, **) { Result.auto(value) }
|
|
167
165
|
command :download, description: 'Download a file from a URL',
|
|
168
166
|
arguments: [
|
|
169
167
|
{name: :file_url, type: String},
|
|
@@ -176,14 +174,14 @@ module Aspera
|
|
|
176
174
|
command :wizard, description: 'Run the setup wizard for an Aspera product (interactive)',
|
|
177
175
|
arguments: [{name: :url, type: String}, {name: :plugin_name, mandatory: false, default: nil},
|
|
178
176
|
{name: :preset_name, mandatory: false, default: ''}]
|
|
179
|
-
command :coffee, description: 'Display a coffee image', action: ->{Result::Image.new(COFFEE_IMAGE_URL)}
|
|
177
|
+
command :coffee, description: 'Display a coffee image', action: -> { Result::Image.new(COFFEE_IMAGE_URL) }
|
|
180
178
|
command :image, description: 'Display an image',
|
|
181
179
|
arguments: [{name: :image_uri, type: nil}],
|
|
182
|
-
action: ->(image_uri:, **){Result::Image.new(image_uri)}
|
|
180
|
+
action: ->(image_uri:, **) { Result::Image.new(image_uri) }
|
|
183
181
|
command :sync, description: 'Manage Aspera Sync operations'
|
|
184
182
|
command :gem, description: 'Display gem information'
|
|
185
|
-
command :folder, description: 'Display the configuration folder path', action: ->{Result::Text.new(context.main_folder)}
|
|
186
|
-
command :file, description: 'Display the configuration file path', action: ->{Result::Text.new(context.presets.config_file)}
|
|
183
|
+
command :folder, description: 'Display the configuration folder path', action: -> { Result::Text.new(context.main_folder) }
|
|
184
|
+
command :file, description: 'Display the configuration file path', action: -> { Result::Text.new(context.presets.config_file) }
|
|
187
185
|
command(
|
|
188
186
|
:email_test, description: 'Send a test email',
|
|
189
187
|
action: lambda do
|
|
@@ -191,41 +189,45 @@ module Aspera
|
|
|
191
189
|
Result::Nothing.new
|
|
192
190
|
end
|
|
193
191
|
)
|
|
194
|
-
command :smtp_settings, description: 'Display the current SMTP settings', action: ->{Result::SingleObject.new(context.mailer.email_settings)}
|
|
192
|
+
command :smtp_settings, description: 'Display the current SMTP settings', action: -> { Result::SingleObject.new(context.mailer.email_settings) }
|
|
195
193
|
command(
|
|
196
194
|
:proxy_check, description: 'Check the proxy returned by the PAC script for a given URL',
|
|
197
195
|
arguments: [{name: :server_url, type: String}],
|
|
198
196
|
action: lambda do |server_url:, **|
|
|
199
|
-
Aspera.assert(!context.pac_executor.nil?, type: Cli::BadArgument){'No PAC script configured, use --fpac'}
|
|
197
|
+
Aspera.assert(!context.pac_executor.nil?, type: Cli::BadArgument) { 'No PAC script configured, use --fpac' }
|
|
200
198
|
Result::ValueList.new(context.pac_executor.get_proxies(server_url), name: 'proxy')
|
|
201
199
|
end
|
|
202
200
|
)
|
|
203
|
-
command :check_update, description: 'Check if a newer version of the gem is available', action: ->{Result::SingleObject.new(check_gem_version)}
|
|
201
|
+
command :check_update, description: 'Check if a newer version of the gem is available', action: -> { Result::SingleObject.new(check_gem_version) }
|
|
204
202
|
command :initdemo, description: 'Initialize the demo server preset'
|
|
205
203
|
command :vault, description: 'Manage secrets in the vault'
|
|
206
|
-
commands_under
|
|
204
|
+
commands_under :vault do
|
|
207
205
|
command :info, description: 'Display vault information',
|
|
208
|
-
action: ->(**){Result::SingleObject.new(
|
|
209
|
-
command :
|
|
210
|
-
action: ->(**){Result::ObjectList.new(
|
|
211
|
-
command :
|
|
212
|
-
|
|
206
|
+
action: ->(**) { Result::SingleObject.new(vault_required.info) }
|
|
207
|
+
command :ids, description: 'List secret labels in the vault',
|
|
208
|
+
action: ->(**) { Result::ObjectList.new(vault_required.ids) }
|
|
209
|
+
command :list, description: 'List all secrets with full details',
|
|
210
|
+
action: ->(**) { Result::ObjectList.new(vault_required.all) }
|
|
211
|
+
command :show, description: 'Show a secret by label (or id)',
|
|
212
|
+
arguments: [{name: :label, type: String}, {name: :id, type: String, mandatory: false, default: nil}]
|
|
213
213
|
command :create, description: 'Add a new secret to the vault',
|
|
214
|
-
arguments: [{name: :info, type: Hash}]
|
|
215
|
-
command :delete, description: 'Delete a secret by label',
|
|
216
|
-
arguments: [{name: :label, type: String}]
|
|
214
|
+
arguments: [{name: :info, type: Hash, schema: Schema::Registry::VAULT_SECRET}]
|
|
215
|
+
command :delete, description: 'Delete a secret by label (or id)',
|
|
216
|
+
arguments: [{name: :label, type: String}, {name: :id, type: String, mandatory: false, default: nil}]
|
|
217
217
|
command :password, description: 'Change the vault password',
|
|
218
218
|
arguments: [{name: :new_password, type: String}]
|
|
219
|
+
command :import, description: 'Import secrets from a JSON array (supports --bulk)',
|
|
220
|
+
arguments: [{name: :secrets, type: Array, schema: {type: 'array', items: {'$ref' => Schema::Registry::VAULT_SECRET}}}]
|
|
219
221
|
end
|
|
220
222
|
command :commands, description: 'List all available commands across all plugins'
|
|
221
223
|
command :options, description: 'List all options available for a plugin',
|
|
222
224
|
arguments: [{name: :plugin_name, type: String}]
|
|
223
225
|
command :test, description: 'Internal test commands'
|
|
224
|
-
command :platform, description: 'Display the current platform/architecture', action: ->{Result::Text.new(Environment.instance.architecture)}
|
|
226
|
+
command :platform, description: 'Display the current platform/architecture', action: -> { Result::Text.new(Environment.instance.architecture) }
|
|
225
227
|
command :completion, description: 'Generate shell completion scripts'
|
|
226
228
|
|
|
227
229
|
# remote_certificate sub-commands
|
|
228
|
-
commands_under
|
|
230
|
+
commands_under :remote_certificate do
|
|
229
231
|
command :chain, description: 'Display the full certificate chain as PEM',
|
|
230
232
|
arguments: [{name: :remote_url, type: String}]
|
|
231
233
|
command :only, description: 'Display only the server certificate as PEM',
|
|
@@ -235,7 +237,7 @@ module Aspera
|
|
|
235
237
|
end
|
|
236
238
|
|
|
237
239
|
# tokens sub-commands
|
|
238
|
-
commands_under
|
|
240
|
+
commands_under :tokens do
|
|
239
241
|
command(
|
|
240
242
|
:flush, description: 'Delete all cached OAuth tokens',
|
|
241
243
|
action: lambda do
|
|
@@ -255,7 +257,7 @@ module Aspera
|
|
|
255
257
|
end
|
|
256
258
|
|
|
257
259
|
# plugins sub-commands
|
|
258
|
-
commands_under
|
|
260
|
+
commands_under :plugins do
|
|
259
261
|
command :list, description: 'List all available plugins'
|
|
260
262
|
command :create, description: 'Create a new plugin skeleton file',
|
|
261
263
|
arguments: [
|
|
@@ -266,7 +268,7 @@ module Aspera
|
|
|
266
268
|
|
|
267
269
|
# ascp sub-commands
|
|
268
270
|
command :ascp, description: 'Manage FASP/ascp transfer engine'
|
|
269
|
-
commands_under
|
|
271
|
+
commands_under :ascp do
|
|
270
272
|
command :show, description: 'Display ascp binary path'
|
|
271
273
|
command :info, description: 'Display ascp and transfer spec information'
|
|
272
274
|
command :install, description: 'Install the transfer SDK',
|
|
@@ -276,14 +278,14 @@ module Aspera
|
|
|
276
278
|
arguments: [{name: :agent_name, mandatory: false, default: nil}]
|
|
277
279
|
command :errors, description: 'Display FASP error codes'
|
|
278
280
|
command :products, description: 'Manage installed Aspera products'
|
|
279
|
-
commands_under
|
|
281
|
+
commands_under :products do
|
|
280
282
|
command :list, description: 'List installed Aspera products'
|
|
281
283
|
end
|
|
282
284
|
end
|
|
283
285
|
|
|
284
286
|
# agents sub-commands
|
|
285
287
|
command :agents, description: 'Manage transfer agents'
|
|
286
|
-
commands_under
|
|
288
|
+
commands_under :agents do
|
|
287
289
|
command :list, description: 'List all transfer agents'
|
|
288
290
|
command :show, description: 'Show details for a transfer agent',
|
|
289
291
|
arguments: [{name: :agent_name, allowed: Agent::Factory::ALL.keys}]
|
|
@@ -293,7 +295,7 @@ module Aspera
|
|
|
293
295
|
|
|
294
296
|
# transfer async management sub-commands
|
|
295
297
|
command :transfer, description: 'Manage asynchronous transfers'
|
|
296
|
-
commands_under
|
|
298
|
+
commands_under :transfer do
|
|
297
299
|
command :list, description: 'List all async transfer jobs'
|
|
298
300
|
command :status, description: 'Show status of an async transfer job',
|
|
299
301
|
arguments: [{name: :job_id, type: String}]
|
|
@@ -302,13 +304,13 @@ module Aspera
|
|
|
302
304
|
|
|
303
305
|
# transferd sub-commands
|
|
304
306
|
command :transferd, description: 'Manage the transfer daemon (transferd)'
|
|
305
|
-
commands_under
|
|
307
|
+
commands_under :transferd do
|
|
306
308
|
command :install, description: 'Install the transfer daemon'
|
|
307
309
|
command :list, description: 'List available SDK locations'
|
|
308
310
|
end
|
|
309
311
|
|
|
310
312
|
# sync sub-commands
|
|
311
|
-
commands_under
|
|
313
|
+
commands_under :sync do
|
|
312
314
|
command(
|
|
313
315
|
:spec, description: 'Display the sync configuration schema',
|
|
314
316
|
action: lambda do
|
|
@@ -317,21 +319,21 @@ module Aspera
|
|
|
317
319
|
end
|
|
318
320
|
)
|
|
319
321
|
command :admin, description: 'Manage sync database (admin operations)'
|
|
320
|
-
SyncActions.register_sync_admin_commands(self,
|
|
322
|
+
SyncActions.register_sync_admin_commands(self, :admin)
|
|
321
323
|
command :translate, description: 'Translate async-style arguments to sync config format',
|
|
322
324
|
arguments: [{name: :async_arguments, type: String, multiple: true}],
|
|
323
|
-
action: ->(async_arguments:, **){Result::SingleObject.new(Sync::Operations.args_to_conf(async_arguments))}
|
|
325
|
+
action: ->(async_arguments:, **) { Result::SingleObject.new(Sync::Operations.args_to_conf(async_arguments)) }
|
|
324
326
|
end
|
|
325
327
|
|
|
326
328
|
# gem sub-commands
|
|
327
|
-
commands_under
|
|
328
|
-
command :path, description: 'Display the gem source root path', action: ->{Result::Text.new(self.class.gem_src_root)}
|
|
329
|
-
command :version, description: 'Display the gem version', action: ->{Result::Text.new(Cli::VERSION)}
|
|
330
|
-
command :name, description: 'Display the gem name', action: ->{Result::Text.new(Info::GEM_NAME)}
|
|
329
|
+
commands_under :gem do
|
|
330
|
+
command :path, description: 'Display the gem source root path', action: -> { Result::Text.new(self.class.gem_src_root) }
|
|
331
|
+
command :version, description: 'Display the gem version', action: -> { Result::Text.new(Cli::VERSION) }
|
|
332
|
+
command :name, description: 'Display the gem name', action: -> { Result::Text.new(Info::GEM_NAME) }
|
|
331
333
|
end
|
|
332
334
|
|
|
333
335
|
# test sub-commands
|
|
334
|
-
commands_under
|
|
336
|
+
commands_under :test do
|
|
335
337
|
command :throw, description: 'Raise an exception (for testing)',
|
|
336
338
|
arguments: [
|
|
337
339
|
{name: :exception_class_name, type: String},
|
|
@@ -341,7 +343,7 @@ module Aspera
|
|
|
341
343
|
end
|
|
342
344
|
|
|
343
345
|
# completion sub-commands
|
|
344
|
-
commands_under
|
|
346
|
+
commands_under :completion do
|
|
345
347
|
command :bash, description: 'Generate bash completion script',
|
|
346
348
|
arguments: [{name: :words, type: String, multiple: true, mandatory: false}]
|
|
347
349
|
end
|
|
@@ -352,8 +354,8 @@ module Aspera
|
|
|
352
354
|
|
|
353
355
|
def option_plugin_folder=(value)
|
|
354
356
|
value = [value] unless value.is_a?(Array)
|
|
355
|
-
Aspera.assert_array_all(value, String){'plugin folder(s)'}
|
|
356
|
-
value.each{ |f| Plugins::Factory.instance.add_lookup_folder(f)}
|
|
357
|
+
Aspera.assert_array_all(value, String) { 'plugin folder(s)' }
|
|
358
|
+
value.each { |f| Plugins::Factory.instance.add_lookup_folder(f) }
|
|
357
359
|
end
|
|
358
360
|
|
|
359
361
|
def option_plugin_folder
|
|
@@ -384,7 +386,7 @@ module Aspera
|
|
|
384
386
|
when :toc, :local
|
|
385
387
|
require 'aspera/markdown'
|
|
386
388
|
local_doc = File.join(self.class.gem_src_root, '..', 'docs', 'README.md')
|
|
387
|
-
Aspera.assert(File.exist?(local_doc), type: Cli::Error){"Local documentation not found: #{local_doc}"}
|
|
389
|
+
Aspera.assert(File.exist?(local_doc), type: Cli::Error) { "Local documentation not found: #{local_doc}" }
|
|
388
390
|
content = File.read(local_doc)
|
|
389
391
|
if location == :toc
|
|
390
392
|
entries = Markdown.toc(content)
|
|
@@ -393,7 +395,7 @@ module Aspera
|
|
|
393
395
|
# :local
|
|
394
396
|
if section
|
|
395
397
|
text = Markdown.extract_section(content, section)
|
|
396
|
-
Aspera.assert(!text.nil?, type: Cli::Error){"Section not found: #{section}"}
|
|
398
|
+
Aspera.assert(!text.nil?, type: Cli::Error) { "Section not found: #{section}" }
|
|
397
399
|
return Result::Text.new(text)
|
|
398
400
|
end
|
|
399
401
|
if Environment.instance.url_method.eql?(:graphical)
|
|
@@ -411,34 +413,34 @@ module Aspera
|
|
|
411
413
|
|
|
412
414
|
def action_remote_certificate_chain(remote_url:, **)
|
|
413
415
|
remote_chain = Rest.remote_certificate_chain(remote_url, as_string: false)
|
|
414
|
-
Aspera.assert(remote_chain&.first){"No certificate found for #{remote_url}"}
|
|
416
|
+
Aspera.assert(remote_chain&.first) { "No certificate found for #{remote_url}" }
|
|
415
417
|
Result::Text.new(remote_chain.map(&:to_pem).join("\n"))
|
|
416
418
|
end
|
|
417
419
|
|
|
418
420
|
def action_remote_certificate_only(remote_url:, **)
|
|
419
421
|
remote_chain = Rest.remote_certificate_chain(remote_url, as_string: false)
|
|
420
|
-
Aspera.assert(remote_chain&.first){"No certificate found for #{remote_url}"}
|
|
422
|
+
Aspera.assert(remote_chain&.first) { "No certificate found for #{remote_url}" }
|
|
421
423
|
Result::Text.new(remote_chain.first.to_pem)
|
|
422
424
|
end
|
|
423
425
|
|
|
424
426
|
def action_remote_certificate_name(remote_url:, **)
|
|
425
427
|
remote_chain = Rest.remote_certificate_chain(remote_url, as_string: false)
|
|
426
|
-
Aspera.assert(remote_chain&.first){"No certificate found for #{remote_url}"}
|
|
427
|
-
Result::Text.new(remote_chain.first.subject.to_a.find{ |name, _, _| name == 'CN'}[1])
|
|
428
|
+
Aspera.assert(remote_chain&.first) { "No certificate found for #{remote_url}" }
|
|
429
|
+
Result::Text.new(remote_chain.first.subject.to_a.find { |name, _, _| name == 'CN' }[1])
|
|
428
430
|
end
|
|
429
431
|
|
|
430
432
|
def action_download(file_url:, file_dest: nil, **)
|
|
431
433
|
file_url = file_url.chomp
|
|
432
434
|
file_dest = File.join(transfer.destination_folder(Transfer::Spec::DIRECTION_RECEIVE), file_url.gsub(%r{.*/}, '')) if file_dest.nil?
|
|
433
435
|
Log.log.info("Downloading: #{file_url}")
|
|
434
|
-
Rest.new(base_url: file_url).call(operation: 'GET',
|
|
436
|
+
Rest.new(base_url: file_url).call(operation: 'GET', save_to: file_dest)
|
|
435
437
|
Result::Status.new("Saved to: #{file_dest}")
|
|
436
438
|
end
|
|
437
439
|
|
|
438
440
|
def action_tokens_show(token_id:, **)
|
|
439
441
|
require 'aspera/api/node'
|
|
440
442
|
data = OAuth::Factory.instance.get_token_info(token_id)
|
|
441
|
-
Aspera.assert(!data.nil?, type: Cli::Error){'Unknown identifier'}
|
|
443
|
+
Aspera.assert(!data.nil?, type: Cli::Error) { 'Unknown identifier' }
|
|
442
444
|
Result::SingleObject.new(data)
|
|
443
445
|
end
|
|
444
446
|
|
|
@@ -493,9 +495,9 @@ module Aspera
|
|
|
493
495
|
def action_initdemo
|
|
494
496
|
cp = presets.config_presets
|
|
495
497
|
if cp.key?(DEMO_PRESET)
|
|
496
|
-
Log.log.warn{"Demo server preset already present: #{DEMO_PRESET}"}
|
|
498
|
+
Log.log.warn { "Demo server preset already present: #{DEMO_PRESET}" }
|
|
497
499
|
else
|
|
498
|
-
Log.log.info{"Creating Demo server preset: #{DEMO_PRESET}"}
|
|
500
|
+
Log.log.info { "Creating Demo server preset: #{DEMO_PRESET}" }
|
|
499
501
|
cp[DEMO_PRESET] = {
|
|
500
502
|
'url' => "ssh://#{DEMO_SERVER}.asperasoft.com:33001",
|
|
501
503
|
'username' => ASPERA,
|
|
@@ -504,12 +506,12 @@ module Aspera
|
|
|
504
506
|
end
|
|
505
507
|
cp[PresetManager::Key::DEFAULTS] ||= {}
|
|
506
508
|
if cp[PresetManager::Key::DEFAULTS].key?(SERVER_COMMAND)
|
|
507
|
-
Log.log.warn{"Server default preset already set to: #{cp[PresetManager::Key::DEFAULTS][SERVER_COMMAND]}"}
|
|
508
|
-
Log.log.warn{"Use #{DEMO_PRESET} for demo: -P#{DEMO_PRESET}"} unless
|
|
509
|
+
Log.log.warn { "Server default preset already set to: #{cp[PresetManager::Key::DEFAULTS][SERVER_COMMAND]}" }
|
|
510
|
+
Log.log.warn { "Use #{DEMO_PRESET} for demo: -P#{DEMO_PRESET}" } unless
|
|
509
511
|
DEMO_PRESET.eql?(cp[PresetManager::Key::DEFAULTS][SERVER_COMMAND])
|
|
510
512
|
else
|
|
511
513
|
cp[PresetManager::Key::DEFAULTS][SERVER_COMMAND] = DEMO_PRESET
|
|
512
|
-
Log.log.info{"Setting server default preset to : #{DEMO_PRESET}"}
|
|
514
|
+
Log.log.info { "Setting server default preset to : #{DEMO_PRESET}" }
|
|
513
515
|
end
|
|
514
516
|
Result::Status.new('Done')
|
|
515
517
|
end
|
|
@@ -518,19 +520,20 @@ module Aspera
|
|
|
518
520
|
commands = Plugins::Factory.instance.plugin_list.flat_map do |name|
|
|
519
521
|
plugin_class = Plugins::Factory.instance.plugin_class(name)
|
|
520
522
|
reg = plugin_class.command_registry
|
|
521
|
-
reg.all_paths.reject{ |path| reg.children_of(path).any?}.map do |path|
|
|
523
|
+
reg.all_paths.reject { |path| reg.children_of(path).any? }.map do |path|
|
|
522
524
|
spec = reg[path]
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
525
|
+
# Build syntax by interleaving each path segment with the arguments declared on that node
|
|
526
|
+
tokens = [name.to_s]
|
|
527
|
+
path.each_with_index do |seg, i|
|
|
528
|
+
tokens << seg.to_s
|
|
529
|
+
node_args = reg[path[0, i + 1]]&.arguments.to_a
|
|
530
|
+
node_args.each do |a|
|
|
531
|
+
token = a.allowed ? a.allowed.join('|') : a.name.to_s
|
|
532
|
+
token += '...' if a.multiple
|
|
533
|
+
tokens << (a.mandatory ? "<#{token}>" : "[<#{token}>]")
|
|
534
|
+
end
|
|
532
535
|
end
|
|
533
|
-
syntax =
|
|
536
|
+
syntax = tokens.join(' ')
|
|
534
537
|
{
|
|
535
538
|
syntax: syntax,
|
|
536
539
|
description: spec&.description.to_s
|
|
@@ -557,14 +560,14 @@ module Aspera
|
|
|
557
560
|
|
|
558
561
|
def action_test_throw(exception_class_name:, exception_text:, **)
|
|
559
562
|
type = Object.const_get(exception_class_name)
|
|
560
|
-
Aspera.assert(type <= Exception){"#{type} is not an exception: #{type.class}"}
|
|
563
|
+
Aspera.assert(type <= Exception) { "#{type} is not an exception: #{type.class}" }
|
|
561
564
|
raise type, exception_text
|
|
562
565
|
end
|
|
563
566
|
|
|
564
567
|
def action_completion_bash(words: nil, **)
|
|
565
568
|
if words.nil? || words.empty?
|
|
566
569
|
# Level 0: propose plugin names
|
|
567
|
-
Plugins::Factory.instance.plugin_list.each{ |p| puts p}
|
|
570
|
+
Plugins::Factory.instance.plugin_list.each { |p| puts p }
|
|
568
571
|
else
|
|
569
572
|
plugin_sym = words.first.to_sym
|
|
570
573
|
plugin_class = begin
|
|
@@ -574,7 +577,7 @@ module Aspera
|
|
|
574
577
|
end
|
|
575
578
|
# Navigate into the registry using remaining words as path
|
|
576
579
|
path = words[1..].map(&:to_sym)
|
|
577
|
-
plugin_class.command_registry.children_of(path).each_key{ |k| puts k}
|
|
580
|
+
plugin_class.command_registry.children_of(path).each_key { |k| puts k }
|
|
578
581
|
end
|
|
579
582
|
Process.exit(0)
|
|
580
583
|
end
|
|
@@ -42,7 +42,7 @@ module Aspera
|
|
|
42
42
|
}
|
|
43
43
|
rescue StandardError => e
|
|
44
44
|
error = e
|
|
45
|
-
Log.log.debug{"detect error: #{e}"}
|
|
45
|
+
Log.log.debug { "detect error: #{e}" }
|
|
46
46
|
end
|
|
47
47
|
raise error if error
|
|
48
48
|
return
|
|
@@ -76,16 +76,16 @@ module Aspera
|
|
|
76
76
|
command :health, description: 'Check Console API health', setup: :setup_api
|
|
77
77
|
command :transfer, description: 'Manage transfers', setup: :setup_api
|
|
78
78
|
|
|
79
|
-
commands_under
|
|
79
|
+
commands_under :transfer do
|
|
80
80
|
command :current, description: 'Manage current transfers'
|
|
81
81
|
command :smart, description: 'Manage smart transfers'
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
commands_under
|
|
84
|
+
commands_under %i[transfer current] do
|
|
85
85
|
command :list, description: 'List current transfers'
|
|
86
86
|
command :show, description: 'Show a transfer',
|
|
87
87
|
arguments: [{name: :transfer_id, type: :identifier}],
|
|
88
|
-
action: ->(api_console:, transfer_id:, **){Result::SingleObject.new(api_console.read("transfers/#{transfer_id}"))}
|
|
88
|
+
action: ->(api_console:, transfer_id:, **) { Result::SingleObject.new(api_console.read("transfers/#{transfer_id}")) }
|
|
89
89
|
command :files, description: 'List files in a transfer',
|
|
90
90
|
arguments: [{name: :transfer_id, type: :identifier}]
|
|
91
91
|
command :start, description: 'Start a transfer',
|
|
@@ -117,8 +117,8 @@ module Aspera
|
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
commands_under
|
|
121
|
-
command :list, description: 'List smart transfers', action: ->(api_console:){Result::ObjectList.new(api_console.read('smart_transfers'))}
|
|
120
|
+
commands_under %i[transfer smart] do
|
|
121
|
+
command :list, description: 'List smart transfers', action: ->(api_console:) { Result::ObjectList.new(api_console.read('smart_transfers')) }
|
|
122
122
|
command :submit, description: 'Submit a smart transfer',
|
|
123
123
|
arguments: [{name: :smart_id}, {name: :transfer_params, type: Hash}]
|
|
124
124
|
end
|
|
@@ -175,10 +175,10 @@ module Aspera
|
|
|
175
175
|
private
|
|
176
176
|
|
|
177
177
|
def parse_extended_filter(filter, query)
|
|
178
|
-
Aspera.assert(filter.start_with?('(') && filter.end_with?(')'), type: BadArgument){"Invalid filter syntax: #{filter}, shall be (field op val)and(field op val)..."}
|
|
178
|
+
Aspera.assert(filter.start_with?('(') && filter.end_with?(')'), type: BadArgument) { "Invalid filter syntax: #{filter}, shall be (field op val)and(field op val)..." }
|
|
179
179
|
filter[1..-2].split(')and(').each_with_index do |expr, i|
|
|
180
180
|
m = expr.match(EXPR_RE)
|
|
181
|
-
Aspera.assert(m, type: BadArgument){"Invalid expression: #{expr}, shall be: <field> <op> <val>"}
|
|
181
|
+
Aspera.assert(m, type: BadArgument) { "Invalid expression: #{expr}, shall be: <field> <op> <val>" }
|
|
182
182
|
t = m.captures
|
|
183
183
|
i += 1
|
|
184
184
|
query["filter#{i}"] = t[0]
|
|
@@ -13,9 +13,9 @@ module Aspera
|
|
|
13
13
|
|
|
14
14
|
command :node, description: 'Execute COS node commands', setup: :setup_cos_node
|
|
15
15
|
|
|
16
|
-
commands_under
|
|
16
|
+
commands_under :node do
|
|
17
17
|
Node::COMMANDS_COS.each do |cmd|
|
|
18
|
-
command
|
|
18
|
+
command cmd, description: "Node #{cmd} command"
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -27,10 +27,11 @@ module Aspera
|
|
|
27
27
|
option :region, description: 'Storage region'
|
|
28
28
|
option :identity, description: "Authentication URL (#{Api::CosNode::IBM_CLOUD_TOKEN_URL})", default: Api::CosNode::IBM_CLOUD_TOKEN_URL
|
|
29
29
|
|
|
30
|
+
use_options Node
|
|
31
|
+
|
|
30
32
|
def initialize(**_)
|
|
31
33
|
super
|
|
32
34
|
options.parse_options!
|
|
33
|
-
Node.declare_options(options)
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
# Build the COS Node API and plugin from CLI options.
|
|
@@ -53,13 +53,13 @@ module Aspera
|
|
|
53
53
|
|
|
54
54
|
# @return [String] path to source file of plugin
|
|
55
55
|
def plugin_source(plugin_name_sym)
|
|
56
|
-
Aspera.assert(@plugins.key?(plugin_name_sym), type: NoSuchElement){"plugin not found: #{plugin_name_sym}"}
|
|
56
|
+
Aspera.assert(@plugins.key?(plugin_name_sym), type: NoSuchElement) { "plugin not found: #{plugin_name_sym}" }
|
|
57
57
|
@plugins[plugin_name_sym][:source]
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
# @return [Class] class object for plugin
|
|
61
61
|
def plugin_class(plugin_name_sym)
|
|
62
|
-
Aspera.assert(@plugins.key?(plugin_name_sym), type: NoSuchElement){"plugin not found: #{plugin_name_sym}"}
|
|
62
|
+
Aspera.assert(@plugins.key?(plugin_name_sym), type: NoSuchElement) { "plugin not found: #{plugin_name_sym}" }
|
|
63
63
|
require @plugins[plugin_name_sym][:require_stanza]
|
|
64
64
|
# Module.nesting[1] is Aspera::Cli::Plugins
|
|
65
65
|
return Object.const_get("#{Module.nesting[1]}::#{plugin_name_sym.to_s.snake_to_capital}")
|