aspera-cli 4.13.0 → 4.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +81 -7
  4. data/CONTRIBUTING.md +22 -6
  5. data/README.md +2038 -1080
  6. data/bin/ascli +18 -9
  7. data/bin/asession +12 -14
  8. data/examples/dascli +1 -1
  9. data/examples/proxy.pac +1 -1
  10. data/examples/rubyc +24 -0
  11. data/lib/aspera/aoc.rb +219 -159
  12. data/lib/aspera/ascmd.rb +25 -14
  13. data/lib/aspera/cli/basic_auth_plugin.rb +12 -9
  14. data/lib/aspera/cli/error.rb +17 -0
  15. data/lib/aspera/cli/extended_value.rb +47 -12
  16. data/lib/aspera/cli/formatter.rb +260 -179
  17. data/lib/aspera/cli/hints.rb +80 -0
  18. data/lib/aspera/cli/main.rb +104 -156
  19. data/lib/aspera/cli/manager.rb +259 -209
  20. data/lib/aspera/cli/plugin.rb +123 -63
  21. data/lib/aspera/cli/plugins/alee.rb +2 -3
  22. data/lib/aspera/cli/plugins/aoc.rb +341 -261
  23. data/lib/aspera/cli/plugins/ats.rb +22 -21
  24. data/lib/aspera/cli/plugins/bss.rb +5 -5
  25. data/lib/aspera/cli/plugins/config.rb +578 -627
  26. data/lib/aspera/cli/plugins/console.rb +44 -6
  27. data/lib/aspera/cli/plugins/cos.rb +15 -17
  28. data/lib/aspera/cli/plugins/faspex.rb +114 -100
  29. data/lib/aspera/cli/plugins/faspex5.rb +411 -264
  30. data/lib/aspera/cli/plugins/node.rb +354 -259
  31. data/lib/aspera/cli/plugins/orchestrator.rb +61 -29
  32. data/lib/aspera/cli/plugins/preview.rb +82 -90
  33. data/lib/aspera/cli/plugins/server.rb +79 -32
  34. data/lib/aspera/cli/plugins/shares.rb +55 -42
  35. data/lib/aspera/cli/sync_actions.rb +68 -0
  36. data/lib/aspera/cli/transfer_agent.rb +66 -73
  37. data/lib/aspera/cli/transfer_progress.rb +74 -0
  38. data/lib/aspera/cli/version.rb +1 -1
  39. data/lib/aspera/colors.rb +12 -8
  40. data/lib/aspera/command_line_builder.rb +14 -11
  41. data/lib/aspera/cos_node.rb +3 -2
  42. data/lib/aspera/data/6 +0 -0
  43. data/lib/aspera/environment.rb +24 -9
  44. data/lib/aspera/fasp/agent_aspera.rb +126 -0
  45. data/lib/aspera/fasp/agent_base.rb +31 -77
  46. data/lib/aspera/fasp/agent_connect.rb +25 -21
  47. data/lib/aspera/fasp/agent_direct.rb +89 -103
  48. data/lib/aspera/fasp/agent_httpgw.rb +231 -149
  49. data/lib/aspera/fasp/agent_node.rb +41 -34
  50. data/lib/aspera/fasp/agent_trsdk.rb +75 -32
  51. data/lib/aspera/fasp/error_info.rb +4 -2
  52. data/lib/aspera/fasp/faux_file.rb +52 -0
  53. data/lib/aspera/fasp/installation.rb +53 -195
  54. data/lib/aspera/fasp/management.rb +244 -0
  55. data/lib/aspera/fasp/parameters.rb +71 -37
  56. data/lib/aspera/fasp/parameters.yaml +76 -8
  57. data/lib/aspera/fasp/products.rb +162 -0
  58. data/lib/aspera/fasp/resume_policy.rb +3 -3
  59. data/lib/aspera/fasp/transfer_spec.rb +7 -6
  60. data/lib/aspera/fasp/uri.rb +26 -24
  61. data/lib/aspera/faspex_gw.rb +2 -2
  62. data/lib/aspera/faspex_postproc.rb +2 -2
  63. data/lib/aspera/hash_ext.rb +14 -4
  64. data/lib/aspera/json_rpc.rb +49 -0
  65. data/lib/aspera/keychain/macos_security.rb +13 -13
  66. data/lib/aspera/line_logger.rb +23 -0
  67. data/lib/aspera/log.rb +58 -16
  68. data/lib/aspera/node.rb +157 -92
  69. data/lib/aspera/oauth.rb +37 -19
  70. data/lib/aspera/open_application.rb +4 -4
  71. data/lib/aspera/persistency_action_once.rb +1 -1
  72. data/lib/aspera/persistency_folder.rb +2 -2
  73. data/lib/aspera/preview/file_types.rb +4 -2
  74. data/lib/aspera/preview/generator.rb +22 -35
  75. data/lib/aspera/preview/options.rb +2 -0
  76. data/lib/aspera/preview/terminal.rb +73 -16
  77. data/lib/aspera/preview/utils.rb +21 -28
  78. data/lib/aspera/proxy_auto_config.js +2 -2
  79. data/lib/aspera/rest.rb +136 -68
  80. data/lib/aspera/rest_call_error.rb +1 -1
  81. data/lib/aspera/rest_error_analyzer.rb +15 -14
  82. data/lib/aspera/rest_errors_aspera.rb +37 -34
  83. data/lib/aspera/secret_hider.rb +18 -15
  84. data/lib/aspera/ssh.rb +5 -2
  85. data/lib/aspera/sync.rb +127 -119
  86. data/lib/aspera/temp_file_manager.rb +10 -3
  87. data/lib/aspera/web_auth.rb +10 -7
  88. data/lib/aspera/web_server_simple.rb +9 -4
  89. data.tar.gz.sig +0 -0
  90. metadata +34 -17
  91. metadata.gz.sig +0 -0
  92. data/docs/test_env.conf +0 -186
  93. data/lib/aspera/cli/listener/line_dump.rb +0 -19
  94. data/lib/aspera/cli/listener/logger.rb +0 -22
  95. data/lib/aspera/cli/listener/progress.rb +0 -50
  96. data/lib/aspera/cli/listener/progress_multi.rb +0 -84
  97. data/lib/aspera/cli/plugins/sync.rb +0 -44
  98. data/lib/aspera/data/7 +0 -0
  99. data/lib/aspera/fasp/listener.rb +0 -13
@@ -0,0 +1,244 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aspera
4
+ module Fasp
5
+ # executes a local "ascp", connects mgt port, equivalent of "Fasp Manager"
6
+ class Management
7
+ # cspell: disable
8
+ OPERATIONS = %w[
9
+ NOP
10
+ START
11
+ QUERY
12
+ QUERYRSP
13
+ STATS
14
+ STOP
15
+ ERROR
16
+ CANCEL
17
+ DONE
18
+ RATE
19
+ FILEERROR
20
+ SESSION
21
+ NOTIFICATION
22
+ INIT
23
+ VLINK
24
+ NOTIFICATION
25
+ PUT
26
+ WRITE
27
+ CLOSE
28
+ SKIP
29
+ ARGSTOP
30
+ ]
31
+
32
+ PARAMETERS = %w[
33
+ Type
34
+ File
35
+ Size
36
+ Written
37
+ Bytescont
38
+ Rate
39
+ Loss
40
+ Query
41
+ Code
42
+ Password
43
+ Progress
44
+ Remaining
45
+ Elapsed
46
+ RexInfo
47
+ BlockInfo
48
+ DiskInfo
49
+ RateInfo
50
+ MinRate
51
+ Description
52
+ Elapsedusec
53
+ ServiceLevel
54
+ SessionId
55
+ User
56
+ Host
57
+ Encryption
58
+ Adaptive
59
+ Direction
60
+ Remote
61
+ Port
62
+ UserStr
63
+ CommandId
64
+ StartByte
65
+ EndByte
66
+ Token
67
+ Cookie
68
+ QueryResponse
69
+ Source
70
+ Destination
71
+ BWMeasurement
72
+ BWInfo
73
+ PMTU
74
+ TransferBytes
75
+ FileBytes
76
+ Operation
77
+ Delay
78
+ PreTransferFiles
79
+ PreTransferDirs
80
+ PreTransferSpecial
81
+ PreTransferFailed
82
+ PartialPreTransferBytes
83
+ PreTransferBytes
84
+ Priority
85
+ Transport
86
+ VlinkID
87
+ VlinkOn
88
+ VlinkCapIn
89
+ VlinkCapOut
90
+ ManifestFile
91
+ ArgScansAttempted
92
+ ArgScansCompleted
93
+ PathScansAttempted
94
+ PathScansFailed
95
+ PathScansIrregular
96
+ PathScansExcluded
97
+ DirScansCompleted
98
+ FileScansCompleted
99
+ DirCreatesAttempted
100
+ DirCreatesFailed
101
+ DirCreatesPassed
102
+ TransfersAttempted
103
+ TransfersFailed
104
+ TransfersPassed
105
+ TransfersSkipped
106
+ FallbackProtocol
107
+ RetryTimeout
108
+ PreTransferExcluded
109
+ XferId
110
+ XferRetry
111
+ Tags
112
+ FaspFileArgIndex
113
+ ArgTransfersStatus
114
+ ArgTransfersAttempted
115
+ ArgTransfersFailed
116
+ ArgTransfersPassed
117
+ ArgTransfersSkipped
118
+ FaspFileID
119
+ RateCap
120
+ MinRateCap
121
+ PolicyCap
122
+ PriorityCap
123
+ RateLock
124
+ MinRateLock
125
+ PolicyLock
126
+ FileChecksum
127
+ ServerHostname
128
+ ServerNodeId
129
+ ClientNodeId
130
+ ServerClusterId
131
+ ClientClusterId
132
+ FileChecksumType
133
+ ServerDocroot
134
+ ClientDocroot
135
+ NodeUser
136
+ ClientUser
137
+ SourcePrefix
138
+ RemoteAddress
139
+ TCPPort
140
+ Cipher
141
+ ResumePolicy
142
+ CreatePolicy
143
+ ManifestPolicy
144
+ Precalc
145
+ OverwritePolicy
146
+ RTTAutocorrect
147
+ TimePolicy
148
+ ManifestPath
149
+ ManifestInprogress
150
+ PartialFiles
151
+ FilesEncrypt
152
+ FilesDecrypt
153
+ DatagramSize
154
+ PrepostCommand
155
+ XoptFlags
156
+ VLinkVersion
157
+ PeerVLinkVersion
158
+ VLinkLocalEnabled
159
+ VLinkLocalId
160
+ VLinkLocalCL
161
+ VLinkRemoteEnabled
162
+ VLinkRemoteId
163
+ VLRemoteCL
164
+ DSPipelineDepth
165
+ PeerDSPipelineDepth
166
+ LocalIP
167
+ SourceBase
168
+ ReadBlockSize
169
+ WriteBlockSize
170
+ ClusterNumNodes
171
+ ClusterNodeId
172
+ MoveRange
173
+ MoveRangeLow
174
+ MoveRangeHigh
175
+ Keepalive
176
+ TestLogin
177
+ UseProxy
178
+ ProxyIP
179
+ RateControlAlgorithm
180
+ ClientMacAddress
181
+ Offset
182
+ ChunkSize
183
+ PostTransferValidation
184
+ OverwritePolicyCap
185
+ ExtraCreatePolicy]
186
+ # Management port start message
187
+ MGT_HEADER = 'FASPMGR 2'
188
+ # fields description for JSON generation
189
+ # spellchecker: disable
190
+ INTEGER_FIELDS = %w[Bytescont FaspFileArgIndex StartByte Rate MinRate Port Priority RateCap MinRateCap TCPPort CreatePolicy TimePolicy
191
+ DatagramSize XoptFlags VLinkVersion PeerVLinkVersion DSPipelineDepth PeerDSPipelineDepth ReadBlockSize WriteBlockSize
192
+ ClusterNumNodes ClusterNodeId Size Written Loss FileBytes PreTransferBytes TransferBytes PMTU Elapsedusec ArgScansAttempted
193
+ ArgScansCompleted PathScansAttempted FileScansCompleted TransfersAttempted TransfersPassed Delay].freeze
194
+ BOOLEAN_FIELDS = %w[Encryption Remote RateLock MinRateLock PolicyLock FilesEncrypt FilesDecrypt VLinkLocalEnabled VLinkRemoteEnabled
195
+ MoveRange Keepalive TestLogin UseProxy Precalc RTTAutocorrect].freeze
196
+ # cspell: enable
197
+
198
+ class << self
199
+ # translates legacy event into enhanced (JSON) event
200
+ def enhanced_event_format(event)
201
+ return event.keys.each_with_object({}) do |e, h|
202
+ # capital_to_snake_case
203
+ new_name = e
204
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
205
+ .gsub(/([a-z\d])(usec)$/, '\1_\2')
206
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
207
+ .downcase
208
+ value = event[e]
209
+ value = value.to_i if INTEGER_FIELDS.include?(e)
210
+ value = value.eql?('Yes') if BOOLEAN_FIELDS.include?(e)
211
+ h[new_name] = value
212
+ end
213
+ end
214
+ end # class << self
215
+
216
+ def initialize
217
+ @event_build = nil
218
+ @last_event = nil
219
+ end
220
+ attr_reader :last_event
221
+
222
+ def process_line(line)
223
+ # Log.log.debug{"line=[#{line}]"}
224
+ case line
225
+ when MGT_HEADER
226
+ # begin event
227
+ @event_build = {}
228
+ when /^([^:]+): (.*)$/
229
+ # event field
230
+ @event_build[Regexp.last_match(1)] = Regexp.last_match(2)
231
+ when ''
232
+ # empty line is separator to end event information
233
+ raise 'unexpected empty line' if @event_build.nil?
234
+ @last_event = @event_build
235
+ @event_build = nil
236
+ return @last_event
237
+ else
238
+ raise "unexpected line:[#{line}]"
239
+ end # case
240
+ return nil
241
+ end
242
+ end
243
+ end
244
+ end
@@ -3,6 +3,10 @@
3
3
  require 'aspera/log'
4
4
  require 'aspera/command_line_builder'
5
5
  require 'aspera/temp_file_manager'
6
+ require 'aspera/fasp/error'
7
+ require 'aspera/fasp/installation'
8
+ require 'aspera/cli/formatter'
9
+ require 'aspera/rest'
6
10
  require 'securerandom'
7
11
  require 'base64'
8
12
  require 'json'
@@ -15,10 +19,11 @@ module Aspera
15
19
  # translate transfer specification to ascp parameter list
16
20
  class Parameters
17
21
  # Agents shown in manual for parameters (sub list)
18
- SUPPORTED_AGENTS = %i[direct node connect].freeze
22
+ SUPPORTED_AGENTS = %i[direct node connect trsdk httpgw].freeze
19
23
  # Short names of columns in manual
20
24
  SUPPORTED_AGENTS_SHORT = SUPPORTED_AGENTS.map{|a|a.to_s[0].to_sym}
21
25
  FILE_LIST_OPTIONS = ['--file-list', '--file-pair-list'].freeze
26
+ SUPPORTED_OPTIONS = %i[ascp_args wss check_ignore quiet].freeze
22
27
 
23
28
  private_constant :SUPPORTED_AGENTS, :FILE_LIST_OPTIONS
24
29
 
@@ -26,7 +31,7 @@ module Aspera
26
31
  # Temp folder for file lists, must contain only file lists
27
32
  # because of garbage collection takes any file there
28
33
  # this could be refined, as , for instance, on macos, temp folder is already user specific
29
- @file_list_folder = TempFileManager.instance.new_file_path_global('asession_filelists')
34
+ @file_list_folder = TempFileManager.instance.new_file_path_global('asession_filelists') # cspell:disable-line
30
35
  @param_description_cache = nil
31
36
  # @return normalized description of transfer spec parameters, direct from yaml
32
37
  def description
@@ -46,7 +51,7 @@ module Aspera
46
51
  param = {name: name, type: [options[:accepted_types]].flatten.join(','), description: options[:desc]}
47
52
  # add flags for supported agents in doc
48
53
  SUPPORTED_AGENTS.each do |a|
49
- param[a.to_s[0].to_sym] = options[:agents].nil? || options[:agents].include?(a) ? 'Y' : ''
54
+ param[a.to_s[0].to_sym] = Cli::Formatter.tick(options[:agents].nil? || options[:agents].include?(a))
50
55
  end
51
56
  # only keep lines that are usable in supported agents
52
57
  next if SUPPORTED_AGENTS_SHORT.inject(true){|m, j|m && param[j].empty?}
@@ -64,9 +69,12 @@ module Aspera
64
69
  else
65
70
  raise "error: #{param}"
66
71
  end.map{|n|"{#{n}}"}.join('|')
67
- conv = options[:cli].key?(:convert) ? '(conversion)' : ''
68
- "#{options[:cli][:switch]} #{conv}#{values}"
69
- else ''
72
+ conversion_tag = options[:cli].key?(:convert) ? '(conversion)' : ''
73
+ "#{options[:cli][:switch]} #{conversion_tag}#{values}"
74
+ when :special then Cli::Formatter.special('special')
75
+ when :ignore then Cli::Formatter.special('ignored')
76
+ else
77
+ param[:d].eql?(tick_yes) ? '' : 'n/a'
70
78
  end
71
79
  if options.key?(:enum)
72
80
  param[:description] += "\nAllowed values: #{options[:enum].join(', ')}"
@@ -103,10 +111,6 @@ module Aspera
103
111
  ts.key?('EX_file_pair_list')
104
112
  end
105
113
 
106
- def ts_to_env_args(transfer_spec, wss:, ascp_args:)
107
- return Parameters.new(transfer_spec, wss: wss, ascp_args: ascp_args).ascp_args
108
- end
109
-
110
114
  # temp file list files are created here
111
115
  def file_list_folder=(v)
112
116
  @file_list_folder = v
@@ -120,21 +124,23 @@ module Aspera
120
124
  end # self
121
125
 
122
126
  # @param options [Hash] key: :wss: bool, :ascp_args: array of strings
123
- def initialize(job_spec, wss:, ascp_args:)
127
+ def initialize(job_spec, options)
124
128
  @job_spec = job_spec
125
- @opt_wss = wss
126
- @opt_args = ascp_args
127
- Log.log.debug{"agent options: #{@opt_wss} #{@opt_args}"}
128
- raise 'ascp args must be an Array' unless @opt_args.is_a?(Array)
129
- raise 'ascp args must be an Array of String' if @opt_args.any?{|i|!i.is_a?(String)}
129
+ # check necessary options
130
+ missing_options = SUPPORTED_OPTIONS - options.keys
131
+ raise "Internal: missing options: #{missing_options.join(', ')}" unless missing_options.empty?
132
+ @options = SUPPORTED_OPTIONS.each_with_object({}){|o, h| h[o] = options[o]}
133
+ Log.log.debug{Log.dump(:parameters_options, @options)}
134
+ raise 'ascp arguments must be an Array' unless @options[:ascp_args].is_a?(Array)
135
+ raise 'ascp arguments must be an Array of String' if @options[:ascp_args].any?{|i|!i.is_a?(String)}
130
136
  @builder = Aspera::CommandLineBuilder.new(@job_spec, self.class.description)
131
137
  end
132
138
 
133
139
  def process_file_list
134
140
  # is the file list provided through EX_ parameters?
135
- ascp_file_list_provided = self.class.ts_has_ascp_file_list(@job_spec, @opt_args)
141
+ ascp_file_list_provided = self.class.ts_has_ascp_file_list(@job_spec, @options[:ascp_args])
136
142
  # set if paths is mandatory in ts
137
- @builder.params_definition['paths'][:mandatory] = !@job_spec.key?('keepalive') && !ascp_file_list_provided
143
+ @builder.params_definition['paths'][:mandatory] = !@job_spec.key?('keepalive') && !ascp_file_list_provided # cspell:words keepalive
138
144
  # get paths in transfer spec (after setting if it is mandatory)
139
145
  ts_paths_array = @builder.read_param('paths')
140
146
  if ascp_file_list_provided && !ts_paths_array.nil?
@@ -154,18 +160,21 @@ module Aspera
154
160
  Log.log.debug('placing source file list on command line (no file list file)')
155
161
  @builder.add_command_line_options(ts_paths_array.map{|i|i['source']})
156
162
  else
163
+ raise "All elements of paths must have a 'source' key" unless ts_paths_array.all?{|i|i.key?('source')}
164
+ is_pair_list = ts_paths_array.any?{|i|i.key?('destination')}
165
+ raise "All elements of paths must be consistent with 'destination' key" if is_pair_list && !ts_paths_array.all?{|i|i.key?('destination')}
157
166
  # safer option: generate a file list file if there is storage defined for it
158
- # if there is destination in paths, then use file-pair-list
159
- # TODO: well, we test only the first one, but anyway it shall be consistent
160
- if ts_paths_array.first.key?('destination')
167
+ # if there is one destination in paths, then use file-pair-list
168
+ if is_pair_list
161
169
  option = '--file-pair-list'
162
- lines = ts_paths_array.each_with_object([]){|e, m|m.push(e['source'], e['destination']); }
170
+ lines = ts_paths_array.each_with_object([]){|e, m|m.push(e['source'], e['destination'] || e['source']) }
163
171
  else
164
172
  option = '--file-list'
165
173
  lines = ts_paths_array.map{|i|i['source']}
166
174
  end
167
175
  file_list_file = Aspera::TempFileManager.instance.new_file_path_in_folder(self.class.file_list_folder)
168
- File.write(file_list_file, lines.join("\n"))
176
+ Log.log.debug{Log.dump(:file_list, lines)}
177
+ File.write(file_list_file, lines.join("\n"), encoding: 'UTF-8')
169
178
  Log.log.debug{"#{option}=\n#{File.read(file_list_file)}".red}
170
179
  end
171
180
  end
@@ -183,18 +192,15 @@ module Aspera
183
192
  env: {},
184
193
  ascp_version: :ascp
185
194
  }
186
- # some ssh credentials are required to avoid interactive password input
187
- if !@job_spec.key?('remote_password') &&
188
- !@job_spec.key?('ssh_private_key') &&
189
- !@job_spec.key?('EX_ssh_key_paths')
190
- raise Fasp::Error, 'required: password or ssh key (value or path)'
191
- end
192
195
 
193
196
  # special cases
194
197
  @job_spec.delete('source_root') if @job_spec.key?('source_root') && @job_spec['source_root'].empty?
195
198
 
196
- # use web socket session initiation ?
197
- if @builder.read_param('wss_enabled') && (@opt_wss || !@job_spec.key?('fasp_port'))
199
+ # notify multi-session was already used, anyway it was deleted by agent direct
200
+ raise 'internal error' if @builder.read_param('multi_session')
201
+
202
+ # use web socket secure for session ?
203
+ if @builder.read_param('wss_enabled') && (@options[:wss] || !@job_spec.key?('fasp_port'))
198
204
  # by default use web socket session if available, unless removed by user
199
205
  @builder.add_command_line_options(['--ws-connect'])
200
206
  # TODO: option to give order ssh,ws (legacy http is implied bu ssh)
@@ -203,12 +209,30 @@ module Aspera
203
209
  @job_spec.delete('fasp_port')
204
210
  @job_spec.delete('EX_ssh_key_paths')
205
211
  @job_spec.delete('sshfp')
206
- # set location for CA bundle to be the one of Ruby, see env var SSL_CERT_FILE / SSL_CERT_DIR
207
- @job_spec['EX_ssh_key_paths'] = [OpenSSL::X509::DEFAULT_CERT_FILE]
208
- Log.log.debug('CA certs: EX_ssh_key_paths <- DEFAULT_CERT_FILE from openssl')
212
+ if @options[:check_ignore]&.call(@job_spec['remote_host'], @job_spec['wss_port'])
213
+ http_session = Rest.start_http_session("https://#{@job_spec['remote_host']}:#{@job_spec['wss_port']}")
214
+ # wss_api = Rest.new(base_url: "/v1/transfer")
215
+ # wss_api.read('start') rescue nil
216
+ wss_cert_file = TempFileManager.instance.new_file_path_global('wss_cert')
217
+ File.write(wss_cert_file, http_session.peer_cert.to_pem)
218
+ http_session.finish
219
+ env_args[:args].unshift('-i', wss_cert_file)
220
+ Log.log.debug{"CA certs for wss: remote cert: #{wss_cert_file}"}
221
+ else
222
+ # set location for CA bundle to be the one of Ruby, see env var SSL_CERT_FILE / SSL_CERT_DIR
223
+ @options[:trusted_certs].each do |file|
224
+ env_args[:args].unshift('-i', file)
225
+ Log.log.debug{"trusted certs for wss: #{file}"}
226
+ end
227
+ end
209
228
  else
210
229
  # remove unused parameter (avoid warning)
211
230
  @job_spec.delete('wss_port')
231
+ # add SSH bypass keys when authentication is token and no auth is provided
232
+ if @job_spec.key?('token') && !@job_spec.key?('remote_password')
233
+ # @job_spec['remote_password'] = Installation.instance.ssh_cert_uuid # not used: no passphrase
234
+ Installation.instance.aspera_token_ssh_key_paths.each { |key| env_args[:args].unshift('-i', key) }
235
+ end
212
236
  end
213
237
 
214
238
  # process parameters as specified in table
@@ -224,9 +248,9 @@ module Aspera
224
248
  end
225
249
  # get list of files to transfer and build arg for ascp
226
250
  process_file_list
227
- # optional args, at the end to override previous ones (to allow override)
251
+ # optional arguments, at the end to override previous ones (to allow override)
228
252
  @builder.add_command_line_options(@builder.read_param('EX_ascp_args'))
229
- @builder.add_command_line_options(@opt_args)
253
+ @builder.add_command_line_options(@options[:ascp_args])
230
254
  # process destination folder
231
255
  destination_folder = @builder.read_param('destination_root') || '/'
232
256
  # ascp4 does not support base64 encoding of destination
@@ -234,7 +258,17 @@ module Aspera
234
258
  # destination MUST be last command line argument to ascp
235
259
  @builder.add_command_line_options([destination_folder])
236
260
 
237
- @builder.add_env_args(env_args[:env], env_args[:args])
261
+ Log.log.debug{"ascp args: #{env_args}"}
262
+
263
+ @builder.add_env_args(env_args)
264
+
265
+ env_args[:args].unshift('-q') if @options[:quiet]
266
+
267
+ # add fallback cert and key as arguments if needed
268
+ if ['1', 1, true, 'force'].include?(@job_spec['http_fallback'])
269
+ env_args[:args].unshift('-Y', Installation.instance.path(:fallback_private_key))
270
+ env_args[:args].unshift('-I', Installation.instance.path(:fallback_certificate))
271
+ end
238
272
 
239
273
  return env_args
240
274
  end