aspera-cli 4.13.0 → 4.15.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.
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