aspera-cli 4.26.1 → 4.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +300 -22
- data/CONTRIBUTING.md +100 -12
- data/bin/ascli +5 -5
- data/docs/README.md +10757 -0
- data/docs/test-mcp-with-ai.md +202 -0
- data/lib/aspera/agent/base.rb +20 -6
- data/lib/aspera/agent/connect.rb +53 -16
- data/lib/aspera/agent/desktop.rb +52 -17
- data/lib/aspera/agent/direct.rb +27 -25
- data/lib/aspera/agent/factory.rb +4 -0
- data/lib/aspera/agent/httpgw.rb +2 -2
- data/lib/aspera/agent/node.rb +34 -2
- data/lib/aspera/agent/transferd.rb +39 -3
- data/lib/aspera/api/alee.rb +1 -1
- data/lib/aspera/api/aoc.rb +56 -51
- data/lib/aspera/api/cos_node.rb +2 -2
- data/lib/aspera/api/faspex.rb +22 -20
- data/lib/aspera/api/httpgw.rb +4 -4
- data/lib/aspera/api/node.rb +33 -30
- data/lib/aspera/api/queries/bss_subscription_account.graphql +18 -0
- data/lib/aspera/api/queries/bss_subscription_usage.graphql +18 -0
- data/lib/aspera/ascmd.rb +25 -23
- data/lib/aspera/ascp/installation.rb +43 -40
- data/lib/aspera/ascp/management.rb +2 -3
- data/lib/aspera/cli/ascp_actions.rb +155 -0
- data/lib/aspera/cli/async_transfer_store.rb +81 -0
- data/lib/aspera/cli/bootstrapper.rb +197 -0
- data/lib/aspera/cli/command_registry.rb +145 -0
- data/lib/aspera/cli/command_spec.rb +138 -0
- data/lib/aspera/cli/context.rb +71 -0
- data/lib/aspera/cli/error.rb +16 -0
- data/lib/aspera/cli/extended_value.rb +5 -3
- data/lib/aspera/cli/formatter.rb +122 -209
- data/lib/aspera/cli/gem_checker.rb +65 -0
- data/lib/aspera/cli/hints.rb +2 -2
- data/lib/aspera/cli/http.rb +218 -0
- data/lib/aspera/cli/info.rb +2 -0
- data/lib/aspera/cli/mailer.rb +97 -0
- data/lib/aspera/cli/mcp_tool.rb +198 -0
- data/lib/aspera/cli/options.schema.yaml +364 -7
- data/lib/aspera/cli/{manager.rb → parser.rb} +337 -144
- data/lib/aspera/cli/plugins/alee.rb +20 -22
- data/lib/aspera/cli/plugins/aoc.rb +1173 -849
- data/lib/aspera/cli/plugins/ats.rb +200 -161
- data/lib/aspera/cli/plugins/base.rb +470 -107
- data/lib/aspera/cli/plugins/basic_auth.rb +14 -4
- data/lib/aspera/cli/plugins/config.rb +434 -1032
- data/lib/aspera/cli/plugins/console.rb +106 -64
- data/lib/aspera/cli/plugins/cos.rb +44 -32
- data/lib/aspera/cli/plugins/factory.rb +7 -4
- data/lib/aspera/cli/plugins/faspex.rb +296 -259
- data/lib/aspera/cli/plugins/faspex5.rb +592 -344
- data/lib/aspera/cli/plugins/faspio.rb +49 -51
- data/lib/aspera/cli/plugins/httpgw.rb +18 -25
- data/lib/aspera/cli/plugins/mcp.rb +279 -0
- data/lib/aspera/cli/plugins/node.rb +1001 -797
- data/lib/aspera/cli/plugins/oauth.rb +7 -10
- data/lib/aspera/cli/plugins/orchestrator.rb +111 -139
- data/lib/aspera/cli/plugins/preview.rb +183 -142
- data/lib/aspera/cli/plugins/server.rb +125 -80
- data/lib/aspera/cli/plugins/shares.rb +301 -107
- data/lib/aspera/cli/preset_actions.rb +139 -0
- data/lib/aspera/cli/preset_manager.rb +236 -0
- data/lib/aspera/cli/result.rb +360 -0
- data/lib/aspera/cli/runner.rb +473 -0
- data/lib/aspera/cli/secret_finder.rb +40 -0
- data/lib/aspera/cli/special_values.rb +1 -0
- data/lib/aspera/cli/sync_actions.rb +84 -56
- data/lib/aspera/cli/terminal_formatter.rb +65 -0
- data/lib/aspera/cli/transfer_actions.rb +83 -0
- data/lib/aspera/cli/transfer_agent.rb +116 -51
- data/lib/aspera/cli/transfer_progress.rb +9 -9
- data/lib/aspera/cli/vault_manager.rb +57 -0
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/cli/wizard.rb +26 -26
- data/lib/aspera/command_line_builder.rb +23 -23
- data/lib/aspera/data_repository.rb +6 -1
- data/lib/aspera/dot_container.rb +5 -5
- data/lib/aspera/environment.rb +39 -13
- data/lib/aspera/exec_spec.rb +13 -0
- data/lib/aspera/faspex_gw.rb +2 -2
- data/lib/aspera/faspex_postproc.rb +4 -3
- data/lib/aspera/graphql.rb +35 -0
- data/lib/aspera/hash_ext.rb +6 -0
- data/lib/aspera/json_rpc/client.rb +62 -0
- data/lib/aspera/json_rpc/version.rb +7 -0
- data/lib/aspera/keychain/base.rb +1 -1
- data/lib/aspera/keychain/encrypted_hash.rb +2 -2
- data/lib/aspera/keychain/factory.rb +4 -4
- data/lib/aspera/keychain/macos_security.rb +4 -4
- data/lib/aspera/link_header.rb +82 -0
- data/lib/aspera/log.rb +23 -5
- data/lib/aspera/markdown.rb +85 -2
- data/lib/aspera/nagios.rb +2 -2
- data/lib/aspera/node_simulator.rb +3 -1
- data/lib/aspera/oauth/base.rb +10 -10
- data/lib/aspera/oauth/boot.rb +43 -0
- data/lib/aspera/oauth/factory.rb +41 -15
- data/lib/aspera/oauth/jwt.rb +4 -4
- data/lib/aspera/oauth/web.rb +4 -4
- data/lib/aspera/oauth.rb +1 -0
- data/lib/aspera/persistency_action_once.rb +10 -10
- data/lib/aspera/persistency_folder.rb +10 -3
- data/lib/aspera/preview/file_types.rb +7 -3
- data/lib/aspera/preview/generator.rb +3 -3
- data/lib/aspera/preview/utils.rb +1 -1
- data/lib/aspera/products/connect.rb +4 -1
- data/lib/aspera/products/other.rb +1 -1
- data/lib/aspera/products/transferd.rb +3 -3
- data/lib/aspera/proxy_auto_config.rb +10 -9
- data/lib/aspera/rest.rb +18 -40
- data/lib/aspera/rest_error_analyzer.rb +7 -3
- data/lib/aspera/rest_errors_aspera.rb +0 -10
- data/lib/aspera/rest_list.rb +13 -6
- data/lib/aspera/schema/IBM Aspera Faspex API-5.0-enhanced.yaml +14 -4
- data/lib/aspera/schema/IBM Aspera on Cloud API-0.2.6-enhanced.yaml +2730 -648
- data/lib/aspera/schema/async_tables.yaml +361 -0
- data/lib/aspera/schema/documentation.rb +57 -26
- data/lib/aspera/schema/reader.rb +60 -11
- data/lib/aspera/schema/registry.rb +50 -10
- data/lib/aspera/secret_hider.rb +11 -2
- data/lib/aspera/ssl.rb +4 -4
- data/lib/aspera/sync/conf.schema.yaml +2 -2
- data/lib/aspera/sync/database.rb +14 -10
- data/lib/aspera/sync/operations.rb +15 -18
- data/lib/aspera/temp_file_manager.rb +5 -1
- data/lib/aspera/timer_limiter.rb +1 -1
- data/lib/aspera/transfer/faux_file.rb +24 -11
- data/lib/aspera/transfer/parameters.rb +27 -25
- data/lib/aspera/transfer/result.rb +74 -0
- data/lib/aspera/transfer/resumer.rb +7 -7
- data/lib/aspera/transfer/spec.rb +18 -1
- data/lib/aspera/transfer/spec.schema.yaml +26 -8
- data/lib/aspera/transfer/uri.rb +1 -1
- data/lib/aspera/uri_reader.rb +2 -2
- data/lib/aspera/web_auth.rb +2 -2
- data/lib/aspera/web_server_simple.rb +8 -5
- data/lib/aspera/yaml.rb +2 -1
- data.tar.gz.sig +0 -0
- metadata +45 -16
- metadata.gz.sig +0 -0
- data/lib/aspera/cli/main.rb +0 -480
- data/lib/aspera/json_rpc.rb +0 -51
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# cspell:ignore ascmd zmode zuid zgid fasping
|
|
4
4
|
require 'aspera/cli/plugins/basic_auth'
|
|
5
5
|
require 'aspera/cli/sync_actions'
|
|
6
|
+
require 'aspera/transfer/result'
|
|
6
7
|
require 'aspera/transfer/spec'
|
|
7
8
|
require 'aspera/ascmd'
|
|
8
9
|
require 'aspera/ssh'
|
|
@@ -21,26 +22,17 @@ module Aspera
|
|
|
21
22
|
LOCAL_SCHEME = 'local'
|
|
22
23
|
HTTPS_SCHEME = 'https'
|
|
23
24
|
URI_SCHEMES = [SSH_SCHEME, LOCAL_SCHEME, HTTPS_SCHEME].freeze
|
|
24
|
-
ASCMD_ALIASES = {
|
|
25
|
-
browse: :ls,
|
|
26
|
-
delete: :rm,
|
|
27
|
-
rename: :mv
|
|
28
|
-
}.freeze
|
|
29
|
-
TRANSFER_COMMANDS = %i[sync upload download].freeze
|
|
30
25
|
|
|
31
|
-
private_constant :SSH_SCHEME, :URI_SCHEMES
|
|
26
|
+
private_constant :SSH_SCHEME, :URI_SCHEMES
|
|
32
27
|
|
|
33
28
|
class LocalExecutor
|
|
34
29
|
def execute(ascmd_path, input:)
|
|
35
30
|
Environment.secure_execute(ascmd_path, mode: :capture, stdin_data: input, binmode: true, exception: false).first
|
|
36
31
|
end
|
|
37
32
|
end
|
|
33
|
+
application_name 'HSTS Fasp/SSH'
|
|
38
34
|
|
|
39
35
|
class << self
|
|
40
|
-
def application_name
|
|
41
|
-
'HSTS Fasp/SSH'
|
|
42
|
-
end
|
|
43
|
-
|
|
44
36
|
# @return [Hash,NilClass]
|
|
45
37
|
def detect(address_or_url)
|
|
46
38
|
urls = if address_or_url.match?(%r{^[a-z]{1,6}://})
|
|
@@ -87,10 +79,8 @@ module Aspera
|
|
|
87
79
|
def initialize(**_)
|
|
88
80
|
super
|
|
89
81
|
@connection_type = :ssh
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
options.declare(:ssh_options, 'SSH options', allowed: Hash, default: {})
|
|
93
|
-
SyncActions.declare_options(options)
|
|
82
|
+
@ascmd_executor = nil
|
|
83
|
+
@server_transfer_spec = nil
|
|
94
84
|
options.parse_options!
|
|
95
85
|
@ssh_opts = options.get_option(:ssh_options).symbolize_keys
|
|
96
86
|
end
|
|
@@ -165,81 +155,136 @@ module Aspera
|
|
|
165
155
|
end
|
|
166
156
|
# if user provided transfer spec has a token, we will use bypass keys
|
|
167
157
|
cred_set = true if transfer.user_transfer_spec['token'].is_a?(String)
|
|
168
|
-
Aspera.assert(cred_set,
|
|
158
|
+
Aspera.assert(cred_set, 'Either password, key , or transfer spec token must be provided', type: BadArgument)
|
|
169
159
|
return server_transfer_spec
|
|
170
160
|
end
|
|
171
161
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
162
|
+
Sync::Operations::DIRECTIONS.each do |dir|
|
|
163
|
+
define_method(:"action_sync_#{dir}"){ |**| run_sync_transfer(dir){@server_transfer_spec}}
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# --- DSL ---
|
|
167
|
+
|
|
168
|
+
option :ssh_keys, description: 'SSH key path list', allowed: Allowed::TYPES_STRING_ARRAY
|
|
169
|
+
option :passphrase, description: 'SSH private key passphrase'
|
|
170
|
+
option :ssh_options, description: 'SSH options', allowed: Hash
|
|
171
|
+
|
|
172
|
+
# root_setup runs once before any command argument is consumed, populating
|
|
173
|
+
# @server_transfer_spec and @ascmd_executor so that condition methods work.
|
|
174
|
+
root_setup :setup_server
|
|
175
|
+
|
|
176
|
+
command :health, description: 'Check transfer health'
|
|
177
|
+
command(:upload, description: 'Upload files to server', transfer_paths: :send, action: lambda do
|
|
178
|
+
@server_transfer_spec['direction'] = Transfer::Spec.transfer_type_to_direction(:upload)
|
|
179
|
+
Runner.result_transfer(transfer.start(@server_transfer_spec))
|
|
180
|
+
end)
|
|
181
|
+
command(:download, description: 'Download files from server', transfer_paths: :receive, action: lambda do
|
|
182
|
+
@server_transfer_spec['direction'] = Transfer::Spec.transfer_type_to_direction(:download)
|
|
183
|
+
Runner.result_transfer(transfer.start(@server_transfer_spec))
|
|
184
|
+
end)
|
|
185
|
+
command :sync, description: 'Synchronize files with server'
|
|
186
|
+
commands_under(:sync) do
|
|
187
|
+
Sync::Operations::DIRECTIONS.each do |dir|
|
|
188
|
+
command(dir, description: "#{dir.capitalize}-sync with server", transfer_paths: :send)
|
|
189
|
+
end
|
|
190
|
+
command :admin, description: 'Manage sync database (admin operations)'
|
|
191
|
+
SyncActions.register_sync_admin_commands(self, %i[sync admin])
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
commands_under(:health) do
|
|
195
|
+
command :transfer, description: 'Check FASP transfer health'
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# AsCmd operations (available only when SSH/local - not WSS)
|
|
199
|
+
ASCMD_ARGS = [{name: :command_arguments, multiple: true, mandatory: false, default: nil}].freeze
|
|
200
|
+
private_constant :ASCMD_ARGS
|
|
201
|
+
|
|
202
|
+
command :ls, description: 'List files on server', condition: :ascmd_available?, aliases: [:browse], arguments: ASCMD_ARGS
|
|
203
|
+
command :rm, description: 'Delete file(s) on server', condition: :ascmd_available?, aliases: [:delete], arguments: ASCMD_ARGS
|
|
204
|
+
command :mv, description: 'Rename/move file(s) on server', condition: :ascmd_available?, aliases: [:rename], arguments: ASCMD_ARGS
|
|
205
|
+
command :cp, description: 'Copy file(s) on server', condition: :ascmd_available?, arguments: ASCMD_ARGS
|
|
206
|
+
command :mkdir, description: 'Create directory on server', condition: :ascmd_available?, arguments: ASCMD_ARGS
|
|
207
|
+
command :df, description: 'Show disk usage on server', condition: :ascmd_available?, arguments: ASCMD_ARGS
|
|
208
|
+
command :du, description: 'Show file sizes on server', condition: :ascmd_available?, arguments: ASCMD_ARGS
|
|
209
|
+
command :md5sum, description: 'Compute MD5 checksums on server', condition: :ascmd_available?, arguments: ASCMD_ARGS
|
|
210
|
+
command :info, description: 'Show server system information', condition: :ascmd_available?, arguments: ASCMD_ARGS
|
|
211
|
+
|
|
212
|
+
# Generate ascmd handlers - convention: action_<op>
|
|
213
|
+
%i[rm mv cp mkdir].each do |op|
|
|
214
|
+
define_action_method([op]) do |command_arguments:, **|
|
|
215
|
+
execute_ascmd(op, command_arguments){Result::Success.new}
|
|
180
216
|
end
|
|
181
217
|
end
|
|
182
218
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
219
|
+
%i[du md5sum info].each do |op|
|
|
220
|
+
define_action_method([op]) do |command_arguments:, **|
|
|
221
|
+
execute_ascmd(op, command_arguments){ |r| Result::SingleObject.new(r.stringify_keys)}
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# --- conditions ---
|
|
226
|
+
|
|
227
|
+
def ascmd_available?
|
|
228
|
+
!@ascmd_executor.nil?
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# --- setup ---
|
|
187
232
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
233
|
+
# Build the transfer spec and ascmd executor from CLI options.
|
|
234
|
+
# Stores results in instance variables; returns empty context hash.
|
|
235
|
+
def setup_server(**)
|
|
236
|
+
@server_transfer_spec = options_to_base_transfer_spec
|
|
237
|
+
@ascmd_executor = case @connection_type
|
|
191
238
|
when :local then LocalExecutor.new
|
|
192
|
-
when :wss
|
|
193
|
-
when :ssh
|
|
239
|
+
when :wss then nil
|
|
240
|
+
when :ssh then Ssh.new(@server_transfer_spec['remote_host'], @server_transfer_spec['remote_user'], @ssh_opts)
|
|
194
241
|
else Aspera.error_unexpected_value(@connection_type){'connection type'}
|
|
195
242
|
end
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
end
|
|
242
|
-
else Aspera.error_unreachable_line
|
|
243
|
+
{}
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# --- health ---
|
|
247
|
+
|
|
248
|
+
def action_health_transfer
|
|
249
|
+
nagios = Nagios.new
|
|
250
|
+
probe_ts = @server_transfer_spec.merge({
|
|
251
|
+
'direction' => 'send',
|
|
252
|
+
'cookie' => 'aspera.sync', # hide in console
|
|
253
|
+
'resume_policy' => 'none',
|
|
254
|
+
'paths' => [{'source' => 'faux:///pingfile?1k', 'destination' => '.fasping'}]
|
|
255
|
+
})
|
|
256
|
+
statuses = transfer.start(probe_ts)
|
|
257
|
+
if statuses.is_a?(Transfer::Result::Success)
|
|
258
|
+
nagios.add_ok('transfer', 'ok')
|
|
259
|
+
else
|
|
260
|
+
nagios.add_critical('transfer', statuses.is_a?(Transfer::Result::Error) ? statuses.exception.message : statuses.to_s)
|
|
261
|
+
end
|
|
262
|
+
Result::ObjectList.new(nagios.status_list)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# --- ascmd handlers ---
|
|
266
|
+
|
|
267
|
+
def action_ls(command_arguments:, **)
|
|
268
|
+
execute_ascmd(:ls, command_arguments) do |result|
|
|
269
|
+
Result::ObjectList.new(result.map(&:stringify_keys), fields: %w[zmode zuid zgid size mtime name])
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def action_df(command_arguments:, **)
|
|
274
|
+
execute_ascmd(:df, command_arguments) do |result|
|
|
275
|
+
Result::ObjectList.new(result.map(&:stringify_keys))
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
private
|
|
280
|
+
|
|
281
|
+
def execute_ascmd(op, command_arguments)
|
|
282
|
+
ascmd = AsCmd.new(@ascmd_executor)
|
|
283
|
+
begin
|
|
284
|
+
result = ascmd.execute_single(op, command_arguments)
|
|
285
|
+
yield(result)
|
|
286
|
+
rescue AsCmd::Error => e
|
|
287
|
+
raise Cli::BadArgument, e.extended_message
|
|
243
288
|
end
|
|
244
289
|
end
|
|
245
290
|
end
|