aspera-cli 4.10.0 → 4.12.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/BUGS.md +19 -0
- data/CHANGELOG.md +528 -0
- data/CONTRIBUTING.md +143 -0
- data/README.md +977 -589
- data/bin/ascli +4 -4
- data/bin/asession +12 -12
- data/docs/test_env.conf +29 -19
- data/examples/aoc.rb +6 -6
- data/examples/dascli +18 -16
- data/examples/faspex4.rb +15 -15
- data/examples/node.rb +12 -12
- data/examples/proxy.pac +2 -2
- data/examples/server.rb +12 -12
- data/lib/aspera/aoc.rb +344 -272
- data/lib/aspera/ascmd.rb +56 -54
- data/lib/aspera/ats_api.rb +4 -4
- data/lib/aspera/cli/basic_auth_plugin.rb +15 -12
- data/lib/aspera/cli/extended_value.rb +9 -9
- data/lib/aspera/cli/{formater.rb → formatter.rb} +69 -69
- data/lib/aspera/cli/listener/line_dump.rb +1 -1
- data/lib/aspera/cli/listener/logger.rb +1 -1
- data/lib/aspera/cli/listener/progress.rb +5 -6
- data/lib/aspera/cli/listener/progress_multi.rb +16 -21
- data/lib/aspera/cli/main.rb +72 -73
- data/lib/aspera/cli/manager.rb +112 -112
- data/lib/aspera/cli/plugin.rb +68 -48
- data/lib/aspera/cli/plugins/alee.rb +4 -4
- data/lib/aspera/cli/plugins/aoc.rb +322 -720
- data/lib/aspera/cli/plugins/ats.rb +50 -52
- data/lib/aspera/cli/plugins/bss.rb +10 -10
- data/lib/aspera/cli/plugins/config.rb +514 -410
- data/lib/aspera/cli/plugins/console.rb +12 -12
- data/lib/aspera/cli/plugins/cos.rb +18 -20
- data/lib/aspera/cli/plugins/faspex.rb +134 -136
- data/lib/aspera/cli/plugins/faspex5.rb +235 -70
- data/lib/aspera/cli/plugins/node.rb +378 -309
- data/lib/aspera/cli/plugins/orchestrator.rb +52 -49
- data/lib/aspera/cli/plugins/preview.rb +129 -120
- data/lib/aspera/cli/plugins/server.rb +137 -83
- data/lib/aspera/cli/plugins/shares.rb +77 -52
- data/lib/aspera/cli/plugins/sync.rb +13 -33
- data/lib/aspera/cli/transfer_agent.rb +61 -61
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +3 -3
- data/lib/aspera/command_line_builder.rb +78 -74
- data/lib/aspera/cos_node.rb +31 -29
- data/lib/aspera/data_repository.rb +1 -1
- data/lib/aspera/environment.rb +30 -28
- data/lib/aspera/fasp/agent_base.rb +17 -15
- data/lib/aspera/fasp/agent_connect.rb +34 -32
- data/lib/aspera/fasp/agent_direct.rb +70 -73
- data/lib/aspera/fasp/agent_httpgw.rb +79 -74
- data/lib/aspera/fasp/agent_node.rb +26 -26
- data/lib/aspera/fasp/agent_trsdk.rb +20 -20
- data/lib/aspera/fasp/error.rb +3 -2
- data/lib/aspera/fasp/error_info.rb +11 -8
- data/lib/aspera/fasp/installation.rb +80 -80
- data/lib/aspera/fasp/listener.rb +2 -2
- data/lib/aspera/fasp/parameters.rb +103 -92
- data/lib/aspera/fasp/parameters.yaml +313 -214
- data/lib/aspera/fasp/resume_policy.rb +10 -10
- data/lib/aspera/fasp/transfer_spec.rb +22 -2
- data/lib/aspera/fasp/uri.rb +7 -7
- data/lib/aspera/faspex_gw.rb +80 -159
- data/lib/aspera/faspex_postproc.rb +77 -0
- data/lib/aspera/hash_ext.rb +3 -3
- data/lib/aspera/id_generator.rb +5 -5
- data/lib/aspera/keychain/encrypted_hash.rb +23 -28
- data/lib/aspera/keychain/macos_security.rb +21 -20
- data/lib/aspera/log.rb +13 -13
- data/lib/aspera/nagios.rb +24 -23
- data/lib/aspera/node.rb +217 -38
- data/lib/aspera/oauth.rb +78 -74
- data/lib/aspera/open_application.rb +19 -11
- data/lib/aspera/persistency_action_once.rb +4 -4
- data/lib/aspera/persistency_folder.rb +13 -13
- data/lib/aspera/preview/file_types.rb +8 -8
- data/lib/aspera/preview/generator.rb +67 -67
- data/lib/aspera/preview/utils.rb +27 -27
- data/lib/aspera/proxy_auto_config.js +63 -63
- data/lib/aspera/proxy_auto_config.rb +19 -19
- data/lib/aspera/rest.rb +65 -67
- data/lib/aspera/rest_call_error.rb +2 -1
- data/lib/aspera/rest_error_analyzer.rb +22 -21
- data/lib/aspera/rest_errors_aspera.rb +16 -16
- data/lib/aspera/secret_hider.rb +17 -14
- data/lib/aspera/ssh.rb +15 -14
- data/lib/aspera/sync.rb +177 -62
- data/lib/aspera/temp_file_manager.rb +2 -2
- data/lib/aspera/uri_reader.rb +4 -4
- data/lib/aspera/web_auth.rb +13 -64
- data/lib/aspera/web_server_simple.rb +76 -0
- data.tar.gz.sig +0 -0
- metadata +11 -6
- metadata.gz.sig +0 -0
data/lib/aspera/fasp/listener.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Aspera
|
4
4
|
module Fasp
|
5
|
-
#
|
6
|
-
class Listener
|
5
|
+
# implement this class to get transfer events
|
6
|
+
class Listener # rubocop:disable Lint/EmptyClass
|
7
7
|
# define one of the following methods:
|
8
8
|
# event_text(text_data)
|
9
9
|
# event_struct(legacy_names)
|
@@ -18,8 +18,9 @@ module Aspera
|
|
18
18
|
SUPPORTED_AGENTS = %i[direct node connect].freeze
|
19
19
|
# Short names of columns in manual
|
20
20
|
SUPPORTED_AGENTS_SHORT = SUPPORTED_AGENTS.map{|a|a.to_s[0].to_sym}
|
21
|
+
FILE_LIST_OPTIONS = ['--file-list', '--file-pair-list'].freeze
|
21
22
|
|
22
|
-
private_constant :SUPPORTED_AGENTS
|
23
|
+
private_constant :SUPPORTED_AGENTS, :FILE_LIST_OPTIONS
|
23
24
|
|
24
25
|
class << self
|
25
26
|
# Temp folder for file lists, must contain only file lists
|
@@ -31,67 +32,71 @@ module Aspera
|
|
31
32
|
def description
|
32
33
|
if @param_description_cache.nil?
|
33
34
|
# config file in same folder with same name as this source
|
34
|
-
description_from_yaml=YAML.load_file("#{__FILE__[0..-3]}yaml")
|
35
|
+
description_from_yaml = YAML.load_file("#{__FILE__[0..-3]}yaml")
|
35
36
|
@param_description_cache = Aspera::CommandLineBuilder.normalize_description(description_from_yaml)
|
36
37
|
end
|
37
38
|
return @param_description_cache
|
38
39
|
end
|
39
40
|
|
40
41
|
# @return a table suitable to display in manual
|
41
|
-
def man_table
|
42
|
+
def man_table(to_text: true)
|
42
43
|
result = []
|
43
|
-
description.each do |
|
44
|
-
param = {name:
|
44
|
+
description.each do |name, options|
|
45
|
+
param = {name: name, type: [options[:accepted_types]].flatten.join(','), description: options[:desc]}
|
45
46
|
# add flags for supported agents in doc
|
46
47
|
SUPPORTED_AGENTS.each do |a|
|
47
|
-
param[a.to_s[0].to_sym] =
|
48
|
+
param[a.to_s[0].to_sym] = options[:agents].nil? || options[:agents].include?(a) ? 'Y' : ''
|
48
49
|
end
|
49
50
|
# only keep lines that are usable in supported agents
|
50
|
-
next if SUPPORTED_AGENTS_SHORT.inject(true){|m,j|m && param[j].empty?}
|
51
|
+
next if SUPPORTED_AGENTS_SHORT.inject(true){|m, j|m && param[j].empty?}
|
51
52
|
param[:cli] =
|
52
|
-
case
|
53
|
-
when :envvar then 'env:' +
|
54
|
-
when :opt_without_arg then
|
53
|
+
case options[:cli][:type]
|
54
|
+
when :envvar then 'env:' + options[:cli][:variable]
|
55
|
+
when :opt_without_arg then options[:cli][:switch]
|
55
56
|
when :opt_with_arg
|
56
|
-
values=if
|
57
|
+
values = if options.key?(:enum)
|
57
58
|
['enum']
|
58
|
-
elsif
|
59
|
-
|
60
|
-
elsif !
|
61
|
-
[
|
59
|
+
elsif options[:accepted_types].is_a?(Array)
|
60
|
+
options[:accepted_types]
|
61
|
+
elsif !options[:accepted_types].nil?
|
62
|
+
[options[:accepted_types]]
|
62
63
|
else
|
63
64
|
raise "error: #{param}"
|
64
65
|
end.map{|n|"{#{n}}"}.join('|')
|
65
|
-
conv=
|
66
|
-
"#{
|
66
|
+
conv = options[:cli].key?(:convert) ? '(conversion)' : ''
|
67
|
+
"#{options[:cli][:switch]} #{conv}#{values}"
|
67
68
|
else ''
|
68
69
|
end
|
69
|
-
if
|
70
|
-
param[:description] += "\nAllowed values: #{
|
70
|
+
if options.key?(:enum)
|
71
|
+
param[:description] += "\nAllowed values: #{options[:enum].join(', ')}"
|
71
72
|
end
|
73
|
+
param[:description] = param[:description].gsub('/', '/') if to_text
|
72
74
|
result.push(param)
|
73
75
|
end
|
74
76
|
return result
|
75
77
|
end
|
76
78
|
|
77
|
-
# special encoding methods used in YAML (key: :
|
78
|
-
def
|
79
|
+
# special encoding methods used in YAML (key: :convert)
|
80
|
+
def convert_remove_hyphen(v); v.tr('-', ''); end
|
79
81
|
|
80
|
-
# special encoding methods used in YAML (key: :
|
81
|
-
def
|
82
|
+
# special encoding methods used in YAML (key: :convert)
|
83
|
+
def convert_json64(v); Base64.strict_encode64(JSON.generate(v)); end
|
82
84
|
|
83
|
-
# special encoding methods used in YAML (key: :
|
84
|
-
def
|
85
|
+
# special encoding methods used in YAML (key: :convert)
|
86
|
+
def convert_base64(v); Base64.strict_encode64(v); end
|
85
87
|
|
86
88
|
# file list is provided directly with ascp arguments
|
87
|
-
def ts_has_ascp_file_list(ts)
|
88
|
-
|
89
|
-
|
90
|
-
ts.
|
89
|
+
def ts_has_ascp_file_list(ts, ascp_args)
|
90
|
+
# it can also be option transfer_info
|
91
|
+
ascp_args = ascp_args['ascp_args'] if ascp_args.is_a?(Hash)
|
92
|
+
(ts['EX_ascp_args'].is_a?(Array) && ts['EX_ascp_args'].any?{|i|FILE_LIST_OPTIONS.include?(i)}) ||
|
93
|
+
(ascp_args.is_a?(Array) && ascp_args.any?{|i|FILE_LIST_OPTIONS.include?(i)}) ||
|
94
|
+
ts.key?('EX_file_list') ||
|
95
|
+
ts.key?('EX_file_pair_list')
|
91
96
|
end
|
92
97
|
|
93
|
-
def ts_to_env_args(transfer_spec,
|
94
|
-
return Parameters.new(transfer_spec,
|
98
|
+
def ts_to_env_args(transfer_spec, wss:, ascp_args:)
|
99
|
+
return Parameters.new(transfer_spec, wss: wss, ascp_args: ascp_args).ascp_args
|
95
100
|
end
|
96
101
|
|
97
102
|
# temp file list files are created here
|
@@ -106,12 +111,60 @@ module Aspera
|
|
106
111
|
attr_reader :file_list_folder
|
107
112
|
end # self
|
108
113
|
|
109
|
-
# @param options [Hash] key: :wss: bool
|
110
|
-
def initialize(job_spec,
|
114
|
+
# @param options [Hash] key: :wss: bool, :ascp_args: array of strings
|
115
|
+
def initialize(job_spec, wss:, ascp_args:)
|
111
116
|
@job_spec = job_spec
|
112
|
-
@
|
113
|
-
@
|
114
|
-
Log.log.debug
|
117
|
+
@opt_wss = wss
|
118
|
+
@opt_args = ascp_args
|
119
|
+
Log.log.debug{"agent options: #{@opt_wss} #{@opt_args}"}
|
120
|
+
raise 'ascp args must be an Array' unless @opt_args.is_a?(Array)
|
121
|
+
raise 'ascp args must be an Array of String' if @opt_args.any?{|i|!i.is_a?(String)}
|
122
|
+
@builder = Aspera::CommandLineBuilder.new(@job_spec, self.class.description)
|
123
|
+
end
|
124
|
+
|
125
|
+
def process_file_list
|
126
|
+
# is the file list provided through EX_ parameters?
|
127
|
+
ascp_file_list_provided = self.class.ts_has_ascp_file_list(@job_spec, @opt_args)
|
128
|
+
# set if paths is mandatory in ts
|
129
|
+
@builder.params_definition['paths'][:mandatory] = !@job_spec.key?('keepalive') && !ascp_file_list_provided
|
130
|
+
# get paths in transfer spec (after setting if it is mandatory)
|
131
|
+
ts_paths_array = @builder.read_param('paths')
|
132
|
+
if ascp_file_list_provided && !ts_paths_array.nil?
|
133
|
+
raise 'file list provided both in transfer spec and ascp file list. Remove one of them.'
|
134
|
+
end
|
135
|
+
# option 1: EX_file_list
|
136
|
+
file_list_file = @builder.read_param('EX_file_list')
|
137
|
+
if file_list_file.nil?
|
138
|
+
# option 2: EX_file_pair_list
|
139
|
+
file_list_file = @builder.read_param('EX_file_pair_list')
|
140
|
+
if !file_list_file.nil?
|
141
|
+
option = '--file-pair-list'
|
142
|
+
elsif !ts_paths_array.nil?
|
143
|
+
# option 3: in TS, it is an array
|
144
|
+
if self.class.file_list_folder.nil?
|
145
|
+
# not safe for special characters ? (maybe not, depends on OS)
|
146
|
+
Log.log.debug('placing source file list on command line (no file list file)')
|
147
|
+
@builder.add_command_line_options(ts_paths_array.map{|i|i['source']})
|
148
|
+
else
|
149
|
+
# safer option: generate a file list file if there is storage defined for it
|
150
|
+
# if there is destination in paths, then use file-pair-list
|
151
|
+
# TODO: well, we test only the first one, but anyway it shall be consistent
|
152
|
+
if ts_paths_array.first.key?('destination')
|
153
|
+
option = '--file-pair-list'
|
154
|
+
lines = ts_paths_array.each_with_object([]){|e, m|m.push(e['source'], e['destination']); }
|
155
|
+
else
|
156
|
+
option = '--file-list'
|
157
|
+
lines = ts_paths_array.map{|i|i['source']}
|
158
|
+
end
|
159
|
+
file_list_file = Aspera::TempFileManager.instance.new_file_path_in_folder(self.class.file_list_folder)
|
160
|
+
File.write(file_list_file, lines.join("\n"))
|
161
|
+
Log.log.debug{"#{option}=\n#{File.read(file_list_file)}".red}
|
162
|
+
end
|
163
|
+
end
|
164
|
+
else
|
165
|
+
option = '--file-list'
|
166
|
+
end
|
167
|
+
@builder.add_command_line_options(["#{option}=#{file_list_file}"]) unless option.nil?
|
115
168
|
end
|
116
169
|
|
117
170
|
# translate transfer spec to env vars and command line arguments for ascp
|
@@ -123,22 +176,22 @@ module Aspera
|
|
123
176
|
ascp_version: :ascp
|
124
177
|
}
|
125
178
|
# some ssh credentials are required to avoid interactive password input
|
126
|
-
if !@job_spec.
|
127
|
-
|
128
|
-
|
179
|
+
if !@job_spec.key?('remote_password') &&
|
180
|
+
!@job_spec.key?('ssh_private_key') &&
|
181
|
+
!@job_spec.key?('EX_ssh_key_paths')
|
129
182
|
raise Fasp::Error, 'required: password or ssh key (value or path)'
|
130
183
|
end
|
131
184
|
|
132
185
|
# special cases
|
133
|
-
@job_spec.delete('source_root') if @job_spec.
|
186
|
+
@job_spec.delete('source_root') if @job_spec.key?('source_root') && @job_spec['source_root'].empty?
|
134
187
|
|
135
188
|
# use web socket session initiation ?
|
136
|
-
if @builder.
|
189
|
+
if @builder.read_param('wss_enabled') && (@opt_wss || !@job_spec.key?('fasp_port'))
|
137
190
|
# by default use web socket session if available, unless removed by user
|
138
191
|
@builder.add_command_line_options(['--ws-connect'])
|
139
192
|
# TODO: option to give order ssh,ws (legacy http is implied bu ssh)
|
140
|
-
#
|
141
|
-
@job_spec['ssh_port'] = @builder.
|
193
|
+
# This will need to be cleaned up in aspera core
|
194
|
+
@job_spec['ssh_port'] = @builder.read_param('wss_port')
|
142
195
|
@job_spec.delete('fasp_port')
|
143
196
|
@job_spec.delete('EX_ssh_key_paths')
|
144
197
|
@job_spec.delete('sshfp')
|
@@ -154,68 +207,26 @@ module Aspera
|
|
154
207
|
@builder.process_params
|
155
208
|
|
156
209
|
# symbol must be index of Installation.paths
|
157
|
-
if @builder.
|
210
|
+
if @builder.read_param('use_ascp4')
|
158
211
|
env_args[:ascp_version] = :ascp4
|
159
212
|
else
|
160
213
|
env_args[:ascp_version] = :ascp
|
161
214
|
# destination will be base64 encoded, put before path arguments
|
162
215
|
@builder.add_command_line_options(['--dest64'])
|
163
216
|
end
|
164
|
-
#
|
165
|
-
|
166
|
-
# is the file list provided through EX_ parameters?
|
167
|
-
ascp_file_list_provided = self.class.ts_has_ascp_file_list(@job_spec)
|
168
|
-
# set if paths is mandatory in ts
|
169
|
-
@builder.params_definition['paths'][:mandatory] = !@job_spec.has_key?('keepalive') && !ascp_file_list_provided
|
170
|
-
# get paths in transfer spec (after setting if it is mandatory)
|
171
|
-
ts_paths_array = @builder.process_param('paths',:get_value)
|
172
|
-
if ascp_file_list_provided && !ts_paths_array.nil?
|
173
|
-
raise 'file list provided both in transfer spec and ascp file list. Remove one of them.'
|
174
|
-
end
|
175
|
-
# option 1: EX_file_list
|
176
|
-
file_list_file = @builder.process_param('EX_file_list',:get_value)
|
177
|
-
if !file_list_file.nil?
|
178
|
-
option = '--file-list'
|
179
|
-
else
|
180
|
-
# option 2: EX_file_pair_list
|
181
|
-
file_list_file = @builder.process_param('EX_file_pair_list',:get_value)
|
182
|
-
if !file_list_file.nil?
|
183
|
-
option = '--file-pair-list'
|
184
|
-
elsif !ts_paths_array.nil?
|
185
|
-
# option 3: in TS, it is an array
|
186
|
-
if !self.class.file_list_folder.nil?
|
187
|
-
# safer option: generate a file list file if there is storage defined for it
|
188
|
-
# if there is destination in paths, then use filepairlist
|
189
|
-
# TODO: well, we test only the first one, but anyway it shall be consistent
|
190
|
-
if ts_paths_array.first.has_key?('destination')
|
191
|
-
option = '--file-pair-list'
|
192
|
-
lines = ts_paths_array.each_with_object([]){|e,m|m.push(e['source'],e['destination']);}
|
193
|
-
else
|
194
|
-
option = '--file-list'
|
195
|
-
lines = ts_paths_array.map{|i|i['source']}
|
196
|
-
end
|
197
|
-
file_list_file = Aspera::TempFileManager.instance.new_file_path_in_folder(self.class.file_list_folder)
|
198
|
-
File.write(file_list_file, lines.join("\n"))
|
199
|
-
Log.log.debug{"#{option}=\n#{File.read(file_list_file)}".red}
|
200
|
-
else
|
201
|
-
# not safe for special characters ? (maybe not, depends on OS)
|
202
|
-
Log.log.debug('placing source file list on command line (no file list file)')
|
203
|
-
@builder.add_command_line_options(ts_paths_array.map{|i|i['source']})
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
@builder.add_command_line_options(["#{option}=#{file_list_file}"]) unless option.nil?
|
208
|
-
end
|
217
|
+
# get list of files to transfer and build arg for ascp
|
218
|
+
process_file_list
|
209
219
|
# optional args, at the end to override previous ones (to allow override)
|
210
|
-
@builder.add_command_line_options(@builder.
|
220
|
+
@builder.add_command_line_options(@builder.read_param('EX_ascp_args'))
|
221
|
+
@builder.add_command_line_options(@opt_args)
|
211
222
|
# process destination folder
|
212
|
-
destination_folder = @builder.
|
223
|
+
destination_folder = @builder.read_param('destination_root') || '/'
|
213
224
|
# ascp4 does not support base64 encoding of destination
|
214
225
|
destination_folder = Base64.strict_encode64(destination_folder) unless env_args[:ascp_version].eql?(:ascp4)
|
215
226
|
# destination MUST be last command line argument to ascp
|
216
227
|
@builder.add_command_line_options([destination_folder])
|
217
228
|
|
218
|
-
@builder.add_env_args(env_args[:env],env_args[:args])
|
229
|
+
@builder.add_env_args(env_args[:env], env_args[:args])
|
219
230
|
|
220
231
|
return env_args
|
221
232
|
end
|