aspera-cli 4.16.0 → 4.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +50 -19
  4. data/CONTRIBUTING.md +3 -1
  5. data/README.md +965 -793
  6. data/bin/asession +29 -21
  7. data/lib/aspera/{fasp/agent_alpha.rb → agent/alpha.rb} +26 -25
  8. data/lib/aspera/{fasp/agent_base.rb → agent/base.rb} +15 -12
  9. data/lib/aspera/{fasp/agent_connect.rb → agent/connect.rb} +13 -11
  10. data/lib/aspera/{fasp/agent_direct.rb → agent/direct.rb} +49 -53
  11. data/lib/aspera/{fasp/agent_httpgw.rb → agent/httpgw.rb} +20 -19
  12. data/lib/aspera/{fasp/agent_node.rb → agent/node.rb} +20 -33
  13. data/lib/aspera/{fasp/agent_trsdk.rb → agent/trsdk.rb} +11 -11
  14. data/lib/aspera/api/aoc.rb +586 -0
  15. data/lib/aspera/api/ats.rb +46 -0
  16. data/lib/aspera/api/cos_node.rb +95 -0
  17. data/lib/aspera/api/node.rb +344 -0
  18. data/lib/aspera/ascmd.rb +46 -10
  19. data/lib/aspera/{fasp → ascp}/installation.rb +5 -5
  20. data/lib/aspera/{fasp → ascp}/management.rb +3 -8
  21. data/lib/aspera/{fasp → ascp}/products.rb +1 -1
  22. data/lib/aspera/assert.rb +30 -30
  23. data/lib/aspera/cli/basic_auth_plugin.rb +11 -10
  24. data/lib/aspera/cli/extended_value.rb +1 -1
  25. data/lib/aspera/cli/formatter.rb +13 -13
  26. data/lib/aspera/cli/hints.rb +5 -5
  27. data/lib/aspera/cli/main.rb +35 -28
  28. data/lib/aspera/cli/manager.rb +25 -24
  29. data/lib/aspera/cli/plugin.rb +22 -15
  30. data/lib/aspera/cli/plugin_factory.rb +61 -0
  31. data/lib/aspera/cli/plugins/alee.rb +7 -7
  32. data/lib/aspera/cli/plugins/aoc.rb +83 -77
  33. data/lib/aspera/cli/plugins/ats.rb +32 -33
  34. data/lib/aspera/cli/plugins/bss.rb +3 -4
  35. data/lib/aspera/cli/plugins/config.rb +169 -186
  36. data/lib/aspera/cli/plugins/console.rb +8 -6
  37. data/lib/aspera/cli/plugins/cos.rb +19 -18
  38. data/lib/aspera/cli/plugins/faspex.rb +61 -54
  39. data/lib/aspera/cli/plugins/faspex5.rb +150 -103
  40. data/lib/aspera/cli/plugins/node.rb +68 -73
  41. data/lib/aspera/cli/plugins/orchestrator.rb +34 -44
  42. data/lib/aspera/cli/plugins/preview.rb +31 -31
  43. data/lib/aspera/cli/plugins/server.rb +31 -33
  44. data/lib/aspera/cli/plugins/shares.rb +13 -11
  45. data/lib/aspera/cli/sync_actions.rb +8 -8
  46. data/lib/aspera/cli/transfer_agent.rb +32 -19
  47. data/lib/aspera/cli/transfer_progress.rb +1 -1
  48. data/lib/aspera/cli/version.rb +1 -1
  49. data/lib/aspera/colors.rb +5 -0
  50. data/lib/aspera/command_line_builder.rb +14 -14
  51. data/lib/aspera/coverage.rb +1 -2
  52. data/lib/aspera/data_repository.rb +1 -1
  53. data/lib/aspera/environment.rb +2 -3
  54. data/lib/aspera/faspex_gw.rb +5 -6
  55. data/lib/aspera/faspex_postproc.rb +1 -1
  56. data/lib/aspera/id_generator.rb +2 -2
  57. data/lib/aspera/json_rpc.rb +5 -5
  58. data/lib/aspera/keychain/encrypted_hash.rb +6 -6
  59. data/lib/aspera/keychain/macos_security.rb +27 -22
  60. data/lib/aspera/log.rb +2 -2
  61. data/lib/aspera/nagios.rb +3 -3
  62. data/lib/aspera/node_simulator.rb +5 -6
  63. data/lib/aspera/oauth/base.rb +143 -0
  64. data/lib/aspera/oauth/factory.rb +124 -0
  65. data/lib/aspera/oauth/generic.rb +34 -0
  66. data/lib/aspera/oauth/jwt.rb +51 -0
  67. data/lib/aspera/oauth/url_json.rb +31 -0
  68. data/lib/aspera/oauth/web.rb +50 -0
  69. data/lib/aspera/oauth.rb +5 -331
  70. data/lib/aspera/open_application.rb +7 -7
  71. data/lib/aspera/persistency_action_once.rb +4 -4
  72. data/lib/aspera/persistency_folder.rb +2 -2
  73. data/lib/aspera/preview/generator.rb +5 -5
  74. data/lib/aspera/preview/terminal.rb +3 -2
  75. data/lib/aspera/preview/utils.rb +3 -3
  76. data/lib/aspera/proxy_auto_config.rb +4 -4
  77. data/lib/aspera/rest.rb +175 -144
  78. data/lib/aspera/rest_errors_aspera.rb +3 -3
  79. data/lib/aspera/resumer.rb +77 -0
  80. data/lib/aspera/ssh.rb +6 -1
  81. data/lib/aspera/{fasp → transfer}/error.rb +3 -3
  82. data/lib/aspera/{fasp → transfer}/error_info.rb +1 -1
  83. data/lib/aspera/{fasp → transfer}/faux_file.rb +1 -1
  84. data/lib/aspera/{fasp → transfer}/parameters.rb +58 -89
  85. data/lib/aspera/{fasp/transfer_spec.rb → transfer/spec.rb} +18 -16
  86. data/lib/aspera/{fasp/parameters.yaml → transfer/spec.yaml} +4 -99
  87. data/lib/aspera/{fasp → transfer}/sync.rb +32 -32
  88. data/lib/aspera/{fasp → transfer}/uri.rb +9 -8
  89. data/lib/aspera/web_server_simple.rb +11 -3
  90. data.tar.gz.sig +0 -0
  91. metadata +36 -63
  92. metadata.gz.sig +0 -0
  93. data/lib/aspera/aoc.rb +0 -601
  94. data/lib/aspera/ats_api.rb +0 -47
  95. data/lib/aspera/cos_node.rb +0 -94
  96. data/lib/aspera/fasp/resume_policy.rb +0 -79
  97. data/lib/aspera/node.rb +0 -339
@@ -7,11 +7,11 @@ require 'aspera/cli/version'
7
7
  require 'aspera/cli/formatter'
8
8
  require 'aspera/cli/info'
9
9
  require 'aspera/cli/transfer_progress'
10
- require 'aspera/fasp/installation'
11
- require 'aspera/fasp/products'
12
- require 'aspera/fasp/parameters'
13
- require 'aspera/fasp/transfer_spec'
14
- require 'aspera/fasp/error_info'
10
+ require 'aspera/ascp/installation'
11
+ require 'aspera/ascp/products'
12
+ require 'aspera/transfer/error_info'
13
+ require 'aspera/transfer/parameters'
14
+ require 'aspera/transfer/spec'
15
15
  require 'aspera/keychain/encrypted_hash'
16
16
  require 'aspera/keychain/macos_security'
17
17
  require 'aspera/proxy_auto_config'
@@ -24,6 +24,7 @@ require 'aspera/line_logger'
24
24
  require 'aspera/rest'
25
25
  require 'aspera/log'
26
26
  require 'aspera/assert'
27
+ require 'aspera/oauth'
27
28
  require 'open3'
28
29
  require 'date'
29
30
  require 'erb'
@@ -32,7 +33,7 @@ module Aspera
32
33
  module Cli
33
34
  module Plugins
34
35
  # manage the CLI config file
35
- class Config < Aspera::Cli::Plugin
36
+ class Config < Cli::Plugin
36
37
  # folder in $HOME for application files (config, cache)
37
38
  ASPERA_HOME_FOLDER_NAME = '.aspera'
38
39
  # default config file
@@ -45,20 +46,18 @@ module Aspera
45
46
  CONF_PRESET_GLOBAL = 'global_common_defaults'
46
47
  # special name to identify value of default
47
48
  GLOBAL_DEFAULT_KEYWORD = 'GLOBAL'
48
- CONF_PLUGIN_SYM = :config # Plugins::Config.name.split('::').last.downcase.to_sym
49
49
  CONF_GLOBAL_SYM = :config
50
50
  # folder containing custom plugins in user's config folder
51
51
  ASPERA_PLUGINS_FOLDERNAME = 'plugins'
52
52
  PERSISTENCY_FOLDER = 'persist_store'
53
- RUBY_FILE_EXT = '.rb'
54
53
  ASPERA = 'aspera'
55
54
  SERVER_COMMAND = 'server'
56
55
  APP_NAME_SDK = 'sdk'
57
56
  CONNECT_WEB_URL = 'https://d3gcli72yxqn2z.cloudfront.net/connect'
58
57
  CONNECT_VERSIONS = 'connectversions.js' # cspell: disable-line
59
58
  TRANSFER_SDK_ARCHIVE_URL = 'https://ibm.biz/aspera_transfer_sdk'
60
- DEMO = 'demo'
61
- DEMO_SERVER_PRESET = 'demoserver' # cspell: disable-line
59
+ DEMO_SERVER = 'demo'
60
+ DEMO_PRESET = 'demoserver' # cspell: disable-line
62
61
  EMAIL_TEST_TEMPLATE = <<~END_OF_TEMPLATE
63
62
  From: <%=from_name%> <<%=from_email%>>
64
63
  To: <<%=to%>>
@@ -84,11 +83,10 @@ module Aspera
84
83
  :CONF_PRESET_DEFAULTS,
85
84
  :CONF_PRESET_GLOBAL,
86
85
  :ASPERA_PLUGINS_FOLDERNAME,
87
- :RUBY_FILE_EXT,
88
86
  :ASPERA,
89
- :DEMO,
90
87
  :TRANSFER_SDK_ARCHIVE_URL,
91
- :DEMO_SERVER_PRESET,
88
+ :DEMO_SERVER,
89
+ :DEMO_PRESET,
92
90
  :EMAIL_TEST_TEMPLATE,
93
91
  :EXTEND_PRESET,
94
92
  :EXTEND_VAULT,
@@ -118,23 +116,11 @@ module Aspera
118
116
  File.dirname(File.expand_path(__FILE__))
119
117
  end
120
118
 
121
- # name of englobing module
122
- # @return "Aspera::Cli::Plugins"
123
- def module_full_name
124
- return Module.nesting[2].to_s
125
- end
126
-
127
119
  # @return main folder where code is, i.e. .../lib
128
120
  # go up as many times as englobing modules (not counting class, as it is a file)
129
121
  def gem_src_root
130
- File.expand_path(module_full_name.gsub('::', '/').gsub(%r{[^/]+}, '..'), gem_plugins_folder)
131
- end
132
-
133
- # instantiate a plugin
134
- # plugins must be Capitalized
135
- def plugin_class(plugin_name_sym)
136
- # Module.nesting[2] is Aspera::Cli::Plugins
137
- return Object.const_get("#{module_full_name}::#{plugin_name_sym.to_s.capitalize}")
122
+ # Module.nesting[2] is Cli::Plugins
123
+ File.expand_path(Module.nesting[2].to_s.gsub('::', '/').gsub(%r{[^/]+}, '..'), gem_plugins_folder)
138
124
  end
139
125
 
140
126
  # deep clone hash so that it does not get modified in case of display and secret hide
@@ -145,27 +131,25 @@ module Aspera
145
131
  # return product family folder (~/.aspera)
146
132
  def module_family_folder
147
133
  user_home_folder = Dir.home
148
- assert(Dir.exist?(user_home_folder), exception_class: Cli::Error){"Home folder does not exist: #{user_home_folder}. Check your user environment."}
134
+ Aspera.assert(Dir.exist?(user_home_folder), exception_class: Cli::Error){"Home folder does not exist: #{user_home_folder}. Check your user environment."}
149
135
  return File.join(user_home_folder, ASPERA_HOME_FOLDER_NAME)
150
136
  end
151
137
 
152
138
  # return product config folder (~/.aspera/<name>)
153
139
  def default_app_main_folder(app_name:)
154
- assert_type(app_name, String)
155
- assert(!app_name.empty?)
140
+ Aspera.assert_type(app_name, String)
141
+ Aspera.assert(!app_name.empty?)
156
142
  return File.join(module_family_folder, app_name)
157
143
  end
158
144
  end # self
159
145
 
160
- def initialize(env, params)
161
- assert_type(env, Hash)
162
- assert_type(params, Hash)
163
- assert(%i[gem help name version].eql?(params.keys.sort)){'missing param'}
146
+ def initialize(gem:, name:, help:, version:, **env)
164
147
  # we need to defer parsing of options until we have the config file, so we can use @extend with @preset
165
- super(env)
166
- @info = params
167
- @plugins = {}
168
- @plugin_lookup_folders = []
148
+ super(**env)
149
+ @gem = gem
150
+ @name = name
151
+ @help = help
152
+ @version = version
169
153
  @use_plugin_defaults = true
170
154
  @config_presets = nil
171
155
  @config_checksum_on_disk = nil
@@ -182,7 +166,9 @@ module Aspera
182
166
  @proxy_credentials = nil
183
167
  @main_folder = nil
184
168
  @option_config_file = nil
169
+ # store is used for ruby https
185
170
  @certificate_store = nil
171
+ # paths are used for ascp
186
172
  @certificate_paths = nil
187
173
  @progress_bar = nil
188
174
  # option to set main folder
@@ -190,14 +176,14 @@ module Aspera
190
176
  :home, 'Home folder for tool',
191
177
  handler: {o: self, m: :main_folder},
192
178
  types: String,
193
- default: self.class.default_app_main_folder(app_name: @info[:name]))
179
+ default: self.class.default_app_main_folder(app_name: @name))
194
180
  options.parse_options!
195
- Log.log.debug{"#{@info[:name]} folder: #{@main_folder}"}
196
- # data persistency manager
197
- env[:persistency] = PersistencyFolder.new(File.join(@main_folder, PERSISTENCY_FOLDER))
181
+ Log.log.debug{"#{@name} folder: #{@main_folder}"}
182
+ # data persistency manager, created by config plugin
183
+ @persistency = PersistencyFolder.new(File.join(@main_folder, PERSISTENCY_FOLDER))
198
184
  # set folders for plugin lookup
199
- add_plugin_lookup_folder(self.class.gem_plugins_folder)
200
- add_plugin_lookup_folder(File.join(@main_folder, ASPERA_PLUGINS_FOLDERNAME))
185
+ PluginFactory.instance.add_lookup_folder(self.class.gem_plugins_folder)
186
+ PluginFactory.instance.add_lookup_folder(File.join(@main_folder, ASPERA_PLUGINS_FOLDERNAME))
201
187
  # option to set config file
202
188
  options.declare(
203
189
  :config_file, 'Path to YAML file with preset configuration',
@@ -229,10 +215,10 @@ module Aspera
229
215
  options.declare(:test_mode, 'Wizard: skip private key check step', values: :bool, default: false)
230
216
  options.declare(:key_path, 'Wizard: path to private key for JWT')
231
217
  # Transfer SDK options
232
- options.declare(:ascp_path, 'Path to ascp', handler: {o: Fasp::Installation.instance, m: :ascp_path})
218
+ options.declare(:ascp_path, 'Path to ascp', handler: {o: Ascp::Installation.instance, m: :ascp_path})
233
219
  options.declare(:use_product, 'Use ascp from specified product', handler: {o: self, m: :option_use_product})
234
220
  options.declare(:sdk_url, 'URL to get SDK', default: TRANSFER_SDK_ARCHIVE_URL)
235
- options.declare(:sdk_folder, 'SDK folder path', handler: {o: Fasp::Installation.instance, m: :sdk_folder})
221
+ options.declare(:sdk_folder, 'SDK folder path', handler: {o: Ascp::Installation.instance, m: :sdk_folder})
236
222
  options.declare(:progress_bar, 'Display progress bar', values: :bool, default: Environment.terminal?)
237
223
  # email options
238
224
  options.declare(:smtp, 'SMTP configuration', types: Hash)
@@ -244,13 +230,13 @@ module Aspera
244
230
  options.declare(:silent_insecure, 'Issue a warning if certificate is ignored', values: :bool, handler: {o: self, m: :option_warn_insecure_cert}, default: :yes)
245
231
  options.declare(:cert_stores, 'List of folder with trusted certificates', types: [Array, String], handler: {o: self, m: :trusted_cert_locations})
246
232
  options.declare(:http_options, 'Options for HTTP/S socket', types: Hash, handler: {o: self, m: :option_http_options}, default: {})
247
- options.declare(:cache_tokens, 'Save and reuse Oauth tokens', values: :bool, handler: {o: self, m: :option_cache_tokens})
233
+ options.declare(:cache_tokens, 'Save and reuse OAuth tokens', values: :bool, handler: {o: self, m: :option_cache_tokens})
248
234
  options.declare(:fpac, 'Proxy auto configuration script')
249
235
  options.declare(:proxy_credentials, 'HTTP proxy credentials (user and password)', types: Array)
250
236
  options.parse_options!
251
237
  @progress_bar = TransferProgress.new if options.get_option(:progress_bar)
252
238
  # Check SDK folder is set or not, for compatibility, we check in two places
253
- sdk_folder = Fasp::Installation.instance.sdk_folder rescue nil
239
+ sdk_folder = Ascp::Installation.instance.sdk_folder rescue nil
254
240
  if sdk_folder.nil?
255
241
  @sdk_default_location = true
256
242
  Log.log.debug('SDK folder is not set, checking default')
@@ -260,19 +246,19 @@ module Aspera
260
246
  if !Dir.exist?(sdk_folder)
261
247
  Log.log.debug{"not exists: #{sdk_folder}"}
262
248
  # former location
263
- former_sdk_folder = File.join(self.class.default_app_main_folder(app_name: @info[:name]), APP_NAME_SDK)
249
+ former_sdk_folder = File.join(self.class.default_app_main_folder(app_name: @name), APP_NAME_SDK)
264
250
  Log.log.debug{"checking: #{former_sdk_folder}"}
265
251
  sdk_folder = former_sdk_folder if Dir.exist?(former_sdk_folder)
266
252
  end
267
253
  Log.log.debug{"using: #{sdk_folder}"}
268
- Fasp::Installation.instance.sdk_folder = sdk_folder
254
+ Ascp::Installation.instance.sdk_folder = sdk_folder
269
255
  end
270
256
  pac_script = options.get_option(:fpac)
271
257
  # create PAC executor
272
- @pac_exec = Aspera::ProxyAutoConfig.new(pac_script).register_uri_generic unless pac_script.nil?
258
+ @pac_exec = ProxyAutoConfig.new(pac_script).register_uri_generic unless pac_script.nil?
273
259
  proxy_user_pass = options.get_option(:proxy_credentials)
274
260
  if !proxy_user_pass.nil?
275
- assert(proxy_user_pass.length.eql?(2), exception_class: Cli::BadArgument){"proxy_credentials shall have two elements (#{proxy_user_pass.length})"}
261
+ Aspera.assert(proxy_user_pass.length.eql?(2), exception_class: Cli::BadArgument){"proxy_credentials shall have two elements (#{proxy_user_pass.length})"}
276
262
  @proxy_credentials = {user: proxy_user_pass[0], pass: proxy_user_pass[1]}
277
263
  @pac_exec.proxy_user = @proxy_credentials[:user]
278
264
  @pac_exec.proxy_pass = @proxy_credentials[:pass]
@@ -281,34 +267,36 @@ module Aspera
281
267
  user_agent: PROGRAM_NAME,
282
268
  session_cb: lambda{|http_session|update_http_session(http_session)},
283
269
  progress_bar: @progress_bar)
284
- Oauth.persist_mgr = persistency if @option_cache_tokens
285
- Fasp::Parameters.file_list_folder = File.join(@main_folder, 'filelists') # cspell: disable-line
286
- Aspera::RestErrorAnalyzer.instance.log_file = File.join(@main_folder, 'rest_exceptions.log')
270
+ OAuth::Factory.instance.persist_mgr = persistency if @option_cache_tokens
271
+ Transfer::Parameters.file_list_folder = File.join(@main_folder, 'filelists') # cspell: disable-line
272
+ RestErrorAnalyzer.instance.log_file = File.join(@main_folder, 'rest_exceptions.log')
287
273
  # register aspera REST call error handlers
288
- Aspera::RestErrorsAspera.register_handlers
274
+ RestErrorsAspera.register_handlers
289
275
  end
290
276
 
291
277
  attr_accessor :main_folder, :option_cache_tokens, :option_insecure, :option_warn_insecure_cert, :option_http_options
292
278
  attr_reader :option_ignore_cert_host_port, :progress_bar
293
279
 
280
+ # add files, folders or default locations to the certificate store
294
281
  def trusted_cert_locations=(path_list)
295
282
  path_list = [path_list] unless path_list.is_a?(Array)
283
+ Aspera.assert_type(path_list, Array){'cert locations'}
296
284
  if @certificate_store.nil?
297
285
  Log.log.debug('Creating SSL Cert store')
298
286
  @certificate_store = OpenSSL::X509::Store.new
299
- @certificate_store.set_default_paths
300
287
  @certificate_paths = []
301
288
  end
302
289
 
303
290
  path_list.each do |path|
304
- assert_type(path, String){'Expecting a String for cert location'}
305
- Log.log.debug("Adding cert location: #{path}")
291
+ Aspera.assert_type(path, String){'Expecting a String for certificate location'}
292
+ paths_to_add = [path]
293
+ Log.log.debug{"Adding cert location: #{path}"}
306
294
  if path.eql?(ExtendedValue::DEF)
307
- path = OpenSSL::X509::DEFAULT_CERT_DIR
308
- @certificate_store.add_path(path)
309
- @certificate_paths.push(path)
310
- path = OpenSSL::X509::DEFAULT_CERT_FILE
311
- @certificate_store.add_file(path)
295
+ @certificate_store.set_default_paths
296
+ paths_to_add = [
297
+ OpenSSL::X509::DEFAULT_CERT_DIR,
298
+ OpenSSL::X509::DEFAULT_CERT_FILE
299
+ ].select{|f|File.exist?(f)}
312
300
  elsif File.file?(path)
313
301
  @certificate_store.add_file(path)
314
302
  elsif File.directory?(path)
@@ -316,17 +304,29 @@ module Aspera
316
304
  else
317
305
  raise "No such file or folder: #{path}"
318
306
  end
319
- @certificate_paths.push(path)
307
+ paths_to_add.each do |p|
308
+ pp = [File.realpath(p)]
309
+ if File.directory?(p)
310
+ pp = Dir.entries(p)
311
+ .map{|e|File.realpath(File.join(p, e))}
312
+ .select{|entry|File.file?(entry)}
313
+ end
314
+ @certificate_paths.concat(pp)
315
+ end
320
316
  end
317
+ @certificate_paths.uniq!
321
318
  end
322
319
 
323
- def trusted_cert_locations(files_only: false)
324
- locations = if @certificate_paths.nil?
325
- [OpenSSL::X509::DEFAULT_CERT_DIR, OpenSSL::X509::DEFAULT_CERT_FILE]
326
- else
327
- @certificate_paths
320
+ # returns only files
321
+ def trusted_cert_locations
322
+ locations = @certificate_paths
323
+ if locations.nil?
324
+ # compute default locations
325
+ self.trusted_cert_locations = ExtendedValue::DEF
326
+ locations = @certificate_paths
327
+ # restore defaults
328
+ @certificate_paths = @certificate_store = nil
328
329
  end
329
- locations = locations.select{|f|File.file?(f)} if files_only
330
330
  return locations
331
331
  end
332
332
 
@@ -384,7 +384,7 @@ module Aspera
384
384
  def check_gem_version
385
385
  latest_version =
386
386
  begin
387
- Rest.new(base_url: 'https://rubygems.org/api/v1').read("versions/#{@info[:gem]}/latest.json")[:data]['version']
387
+ Rest.new(base_url: 'https://rubygems.org/api/v1').read("versions/#{@gem}/latest.json")[:data]['version']
388
388
  rescue StandardError
389
389
  Log.log.warn('Could not retrieve latest gem version on rubygems.')
390
390
  '0'
@@ -396,10 +396,10 @@ module Aspera
396
396
  end
397
397
  end
398
398
  return {
399
- name: @info[:gem],
400
- current: Aspera::Cli::VERSION,
399
+ name: @gem,
400
+ current: Cli::VERSION,
401
401
  latest: latest_version,
402
- need_update: Gem::Version.new(Aspera::Cli::VERSION) < Gem::Version.new(latest_version)
402
+ need_update: Gem::Version.new(Cli::VERSION) < Gem::Version.new(latest_version)
403
403
  }
404
404
  end
405
405
 
@@ -432,8 +432,8 @@ module Aspera
432
432
  # retrieve structure from cloud (CDN) with all versions available
433
433
  def connect_versions
434
434
  if @connect_versions.nil?
435
- api_connect_cdn = Rest.new({base_url: CONNECT_WEB_URL})
436
- javascript = api_connect_cdn.call({operation: 'GET', subpath: CONNECT_VERSIONS})
435
+ api_connect_cdn = Rest.new(base_url: CONNECT_WEB_URL)
436
+ javascript = api_connect_cdn.call(operation: 'GET', subpath: CONNECT_VERSIONS)
437
437
  # get result on one line
438
438
  connect_versions_javascript = javascript[:http].body.gsub(/\r?\n\s*/, '')
439
439
  Log.log.debug{"javascript=[\n#{connect_versions_javascript}\n]"}
@@ -468,14 +468,14 @@ module Aspera
468
468
  end
469
469
 
470
470
  def set_preset_key(preset, param_name, param_value)
471
- assert_values(param_name.class, [String, Symbol]){'parameter'}
471
+ Aspera.assert_values(param_name.class, [String, Symbol]){'parameter'}
472
472
  param_name = param_name.to_s
473
473
  selected_preset = @config_presets[preset]
474
474
  if selected_preset.nil?
475
475
  Log.log.debug{"No such preset name: #{preset}, initializing"}
476
476
  selected_preset = @config_presets[preset] = {}
477
477
  end
478
- assert_type(selected_preset, Hash){"#{preset}.#{param_name}"}
478
+ Aspera.assert_type(selected_preset, Hash){"#{preset}.#{param_name}"}
479
479
  if selected_preset.key?(param_name)
480
480
  if selected_preset[param_name].eql?(param_value)
481
481
  Log.log.warn{"keeping same value for #{preset}: #{param_name}: #{param_value}"}
@@ -496,7 +496,7 @@ module Aspera
496
496
  end
497
497
 
498
498
  # $HOME/.aspera/`program_name`
499
- attr_reader :gem_url, :plugins
499
+ attr_reader :gem_url
500
500
  attr_accessor :option_config_file
501
501
 
502
502
  # @return the hash from name (also expands possible includes)
@@ -507,7 +507,7 @@ module Aspera
507
507
  include_path = include_path.clone # avoid messing up if there are multiple branches
508
508
  current = @config_presets
509
509
  config_name.split(PRESET_DIG_SEPARATOR).each do |name|
510
- assert_type(current, Hash, exception_class: Cli::Error){"sub key: #{include_path}"}
510
+ Aspera.assert_type(current, Hash, exception_class: Cli::Error){"sub key: #{include_path}"}
511
511
  include_path.push(name)
512
512
  current = current[name]
513
513
  raise Cli::Error, "No such config preset: #{include_path}" if current.nil?
@@ -517,7 +517,7 @@ module Aspera
517
517
  end
518
518
 
519
519
  def option_use_product=(value)
520
- Fasp::Installation.instance.use_ascp_from_product(value)
520
+ Ascp::Installation.instance.use_ascp_from_product(value)
521
521
  end
522
522
 
523
523
  def option_use_product
@@ -525,14 +525,14 @@ module Aspera
525
525
  end
526
526
 
527
527
  def option_plugin_folder=(value)
528
- assert_values(value.class, [String, Array]){'plugin folder'}
528
+ Aspera.assert_values(value.class, [String, Array]){'plugin folder'}
529
529
  value = [value] if value.is_a?(String)
530
- assert(value.all?(String)){'plugin folder'}
531
- value.each{|f|add_plugin_lookup_folder(f)}
530
+ Aspera.assert(value.all?(String)){'plugin folder'}
531
+ value.each{|f|PluginFactory.instance.add_lookup_folder(f)}
532
532
  end
533
533
 
534
534
  def option_plugin_folder
535
- return @plugin_lookup_folders
535
+ return PluginFactory.instance.lookup_folders
536
536
  end
537
537
 
538
538
  def option_preset; 'write-only option'; end
@@ -571,9 +571,9 @@ module Aspera
571
571
  end
572
572
  files_to_copy = []
573
573
  Log.log.debug{Log.dump('Available_presets', @config_presets)}
574
- assert_type(@config_presets, Hash){'config file YAML'}
574
+ Aspera.assert_type(@config_presets, Hash){'config file YAML'}
575
575
  # check there is at least the config section
576
- assert(@config_presets.key?(CONF_PRESET_CONFIG)){"Cannot find key: #{CONF_PRESET_CONFIG}"}
576
+ Aspera.assert(@config_presets.key?(CONF_PRESET_CONFIG)){"Cannot find key: #{CONF_PRESET_CONFIG}"}
577
577
  version = @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]
578
578
  raise 'No version found in config section.' if version.nil?
579
579
  Log.log.debug{"conf version: #{version}"}
@@ -582,7 +582,7 @@ module Aspera
582
582
  @config_presets[CONF_PRESET_DEFAULTS].delete(true) if @config_presets[CONF_PRESET_DEFAULTS].is_a?(Hash)
583
583
  # ^^^ Place new compatibility code before this line
584
584
  # set version to current
585
- @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = @info[:version]
585
+ @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = @version
586
586
  unless files_to_copy.empty?
587
587
  Log.log.warn('Copying referenced files')
588
588
  files_to_copy.each do |file|
@@ -597,7 +597,7 @@ module Aspera
597
597
  Log.log.debug{"-> #{e.class.name} : #{e}"}
598
598
  if File.exist?(@option_config_file)
599
599
  # then there is a problem with that file.
600
- new_name = "#{@option_config_file}.pre#{@info[:version]}.manual_conversion_needed"
600
+ new_name = "#{@option_config_file}.pre#{@version}.manual_conversion_needed"
601
601
  File.rename(@option_config_file, new_name)
602
602
  Log.log.warn{"Renamed config file to #{new_name}."}
603
603
  Log.log.warn('Manual Conversion is required. Next time, a new empty file will be created.')
@@ -605,33 +605,6 @@ module Aspera
605
605
  raise Cli::Error, e.to_s
606
606
  end
607
607
 
608
- # find plugins in defined paths
609
- def add_plugins_from_lookup_folders
610
- @plugin_lookup_folders.each do |folder|
611
- next unless File.directory?(folder)
612
- # TODO: add gem root to load path ? and require short folder ?
613
- # $LOAD_PATH.push(folder) if i[:add_path]
614
- Dir.entries(folder).select{|file|file.end_with?(RUBY_FILE_EXT)}.each do |source|
615
- add_plugin_info(File.join(folder, source))
616
- end
617
- end
618
- end
619
-
620
- def add_plugin_lookup_folder(folder)
621
- @plugin_lookup_folders.unshift(folder)
622
- end
623
-
624
- def add_plugin_info(path)
625
- raise "ERROR: plugin path must end with #{RUBY_FILE_EXT}" if !path.end_with?(RUBY_FILE_EXT)
626
- plugin_symbol = File.basename(path, RUBY_FILE_EXT).to_sym
627
- req = path.gsub(/#{RUBY_FILE_EXT}$/o, '')
628
- if @plugins.key?(plugin_symbol)
629
- Log.log.warn{"skipping plugin already registered: #{plugin_symbol}"}
630
- return
631
- end
632
- @plugins[plugin_symbol] = {source: path, require_stanza: req}
633
- end
634
-
635
608
  # Find a plugin, and issue the "require"
636
609
  # @return [Hash] plugin info: { product: , url:, version: }
637
610
  def identify_plugins_for_url
@@ -639,34 +612,36 @@ module Aspera
639
612
  check_only = options.get_next_argument('plugin name', mandatory: false)
640
613
  check_only = check_only.to_sym unless check_only.nil?
641
614
  found_apps = []
642
- plugins.each do |plugin_name_sym, plugin_info|
615
+ my_self_plugin_sym = self.class.name.split('::').last.downcase.to_sym
616
+ PluginFactory.instance.plugins.each do |plugin_name_sym, plugin_info|
643
617
  # no detection for internal plugin
644
- next if plugin_name_sym.eql?(CONF_PLUGIN_SYM)
618
+ next if plugin_name_sym.eql?(my_self_plugin_sym)
645
619
  next if check_only && !check_only.eql?(plugin_name_sym)
646
620
  # load plugin class
647
621
  require plugin_info[:require_stanza]
648
- detect_plugin_class = self.class.plugin_class(plugin_name_sym)
622
+ detect_plugin_class = PluginFactory.plugin_class(plugin_name_sym)
649
623
  # requires detection method
650
624
  next unless detect_plugin_class.respond_to?(:detect)
651
625
  detection_info = nil
652
626
  begin
627
+ Log.log.debug{"detecting #{plugin_name_sym} at #{app_url}"}
653
628
  detection_info = detect_plugin_class.detect(app_url)
654
629
  rescue OpenSSL::SSL::SSLError => e
655
630
  Log.log.warn(e.message)
656
631
  Log.log.warn('Use option --insecure=yes to allow unchecked certificate') if e.message.include?('cert')
657
632
  rescue StandardError => e
658
- Log.log.debug{"detect error: #{e}"}
633
+ Log.log.debug{"detect error: [#{e.class}] #{e}"}
659
634
  next
660
635
  end
661
636
  next if detection_info.nil?
662
- assert_type(detection_info, Hash)
663
- assert_type(detection_info[:url], String) if detection_info.key?(:url)
637
+ Aspera.assert_type(detection_info, Hash)
638
+ Aspera.assert_type(detection_info[:url], String) if detection_info.key?(:url)
664
639
  app_name = detect_plugin_class.respond_to?(:application_name) ? detect_plugin_class.application_name : detect_plugin_class.name.split('::').last
665
640
  # if there is a redirect, then the detector can override the url.
666
641
  found_apps.push({product: plugin_name_sym, name: app_name, url: app_url, version: 'unknown'}.merge(detection_info))
667
642
  end # loop
668
643
  raise "No known application found at #{app_url}" if found_apps.empty?
669
- assert(found_apps.all?{|a|a.keys.all?(Symbol)})
644
+ Aspera.assert(found_apps.all?{|a|a.keys.all?(Symbol)})
670
645
  return found_apps
671
646
  end
672
647
 
@@ -695,12 +670,12 @@ module Aspera
695
670
  when :list
696
671
  return {type: :object_list, data: all_links}
697
672
  when :download
698
- folder_dest = transfer.destination_folder(Fasp::TransferSpec::DIRECTION_RECEIVE)
673
+ folder_dest = transfer.destination_folder(Transfer::Spec::DIRECTION_RECEIVE)
699
674
  # folder_dest=self.options.get_next_argument('destination folder')
700
- api_connect_cdn = Rest.new({base_url: CONNECT_WEB_URL})
675
+ api_connect_cdn = Rest.new(base_url: CONNECT_WEB_URL)
701
676
  file_url = one_link['href']
702
677
  filename = file_url.gsub(%r{.*/}, '')
703
- api_connect_cdn.call({operation: 'GET', subpath: file_url, save_to_file: File.join(folder_dest, filename)})
678
+ api_connect_cdn.call(operation: 'GET', subpath: file_url, save_to_file: File.join(folder_dest, filename))
704
679
  return Main.result_status("Downloaded: #{filename}")
705
680
  when :open
706
681
  OpenApplication.instance.uri(one_link['href'])
@@ -716,15 +691,15 @@ module Aspera
716
691
  return execute_connect_action
717
692
  when :use
718
693
  ascp_path = options.get_next_argument('path to ascp')
719
- ascp_version = Fasp::Installation.instance.get_ascp_version(ascp_path)
694
+ ascp_version = Ascp::Installation.instance.get_ascp_version(ascp_path)
720
695
  formatter.display_status("ascp version: #{ascp_version}")
721
696
  set_global_default(:ascp_path, ascp_path)
722
697
  return Main.result_nothing
723
698
  when :show
724
- return {type: :status, data: Fasp::Installation.instance.path(:ascp)}
699
+ return {type: :status, data: Ascp::Installation.instance.path(:ascp)}
725
700
  when :info
726
701
  # collect info from ascp executable
727
- data = Fasp::Installation.instance.ascp_info
702
+ data = Ascp::Installation.instance.ascp_info
728
703
  # add command line transfer spec
729
704
  data['ts'] = transfer.updated_ts
730
705
  # add keys
@@ -736,27 +711,27 @@ module Aspera
736
711
  command = options.get_next_command(%i[list use])
737
712
  case command
738
713
  when :list
739
- return {type: :object_list, data: Fasp::Products.installed_products, fields: %w[name app_root]}
714
+ return {type: :object_list, data: Ascp::Products.installed_products, fields: %w[name app_root]}
740
715
  when :use
741
716
  default_product = options.get_next_argument('product name')
742
- Fasp::Installation.instance.use_ascp_from_product(default_product)
743
- set_global_default(:ascp_path, Fasp::Installation.instance.path(:ascp))
717
+ Ascp::Installation.instance.use_ascp_from_product(default_product)
718
+ set_global_default(:ascp_path, Ascp::Installation.instance.path(:ascp))
744
719
  return Main.result_nothing
745
720
  end
746
721
  when :install
747
722
  # reset to default location, if older default was used
748
- Fasp::Installation.instance.sdk_folder = self.class.default_app_main_folder(app_name: APP_NAME_SDK) if @sdk_default_location
749
- v = Fasp::Installation.instance.install_sdk(options.get_option(:sdk_url, mandatory: true))
723
+ Ascp::Installation.instance.sdk_folder = self.class.default_app_main_folder(app_name: APP_NAME_SDK) if @sdk_default_location
724
+ v = Ascp::Installation.instance.install_sdk(options.get_option(:sdk_url, mandatory: true))
750
725
  return Main.result_status("Installed version #{v}")
751
726
  when :spec
752
727
  return {
753
728
  type: :object_list,
754
- data: Fasp::Parameters.man_table,
755
- fields: [%w[name type], Fasp::Parameters::SUPPORTED_AGENTS_SHORT.map(&:to_s), %w[description]].flatten.freeze
729
+ data: Transfer::Parameters.man_table,
730
+ fields: [%w[name type], Transfer::Parameters::SUPPORTED_AGENTS_SHORT.map(&:to_s), %w[description]].flatten.freeze
756
731
  }
757
732
  when :errors
758
733
  error_data = []
759
- Fasp::ERROR_INFO.each_pair do |code, prop|
734
+ Transfer::ERROR_INFO.each_pair do |code, prop|
760
735
  error_data.push(code: code, mnemonic: prop[:c], retry: prop[:r], info: prop[:a])
761
736
  end
762
737
  return {type: :object_list, data: error_data}
@@ -901,7 +876,7 @@ module Aspera
901
876
  when :documentation
902
877
  section = options.get_next_argument('private key file path', mandatory: false)
903
878
  section = "##{section}" unless section.nil?
904
- OpenApplication.instance.uri("#{@info[:help]}#{section}")
879
+ OpenApplication.instance.uri("#{@help}#{section}")
905
880
  return Main.result_nothing
906
881
  when :genkey # generate new rsa key
907
882
  private_key_path = options.get_next_argument('private key file path')
@@ -912,28 +887,34 @@ module Aspera
912
887
  private_key_pem = options.get_next_argument('private key PEM value')
913
888
  return Main.result_status(OpenSSL::PKey::RSA.new(private_key_pem).public_key.to_s)
914
889
  when :remote_certificate
890
+ cert_action = options.get_next_command(%i[chain only name])
915
891
  remote_url = options.get_next_argument('remote URL')
916
- @option_insecure = true
917
- remote_certificate = Rest.start_http_session(remote_url).peer_cert
918
- remote_certificate.subject.to_a.find { |name, _, _| name == 'CN' }[1]
919
- formatter.display_status("CN=#{remote_certificate.subject.to_a.find { |name, _, _| name == 'CN' }[1] rescue ''}")
920
- return Main.result_status(remote_certificate.to_pem)
892
+ remote_chain = Rest.remote_certificate_chain(remote_url, as_string: false)
893
+ raise "No certificate found for #{remote_url}" unless remote_chain&.first
894
+ case cert_action
895
+ when :chain
896
+ return Main.result_status(remote_chain.map(&:to_pem).join("\n"))
897
+ when :only
898
+ return Main.result_status(remote_chain.first.to_pem)
899
+ when :name
900
+ return Main.result_status(remote_chain.first.subject.to_a.find { |name, _, _| name == 'CN' }[1])
901
+ end
921
902
  when :echo # display the content of a value given on command line
922
903
  return Formatter.auto_type(options.get_next_argument('value'))
923
904
  when :flush_tokens
924
- deleted_files = Oauth.flush_tokens
905
+ deleted_files = OAuth::Factory.instance.flush_tokens
925
906
  return {type: :value_list, data: deleted_files, name: 'file'}
926
907
  when :plugins
927
908
  case options.get_next_command(%i[list create])
928
909
  when :list
929
910
  result = []
930
- @plugins.each do |name, info|
911
+ PluginFactory.instance.plugins.each do |name, info|
931
912
  require info[:require_stanza]
932
- plugin_class = self.class.plugin_class(name)
913
+ plugin_klass = PluginFactory.plugin_class(name)
933
914
  result.push({
934
915
  plugin: name,
935
- detect: Formatter.tick(plugin_class.respond_to?(:detect)),
936
- wizard: Formatter.tick(plugin_class.respond_to?(:wizard)),
916
+ detect: Formatter.tick(plugin_klass.respond_to?(:detect)),
917
+ wizard: Formatter.tick(plugin_klass.respond_to?(:wizard)),
937
918
  path: info[:source]
938
919
  })
939
920
  end
@@ -979,8 +960,8 @@ module Aspera
979
960
  when :gem
980
961
  case options.get_next_command(%i[path version name])
981
962
  when :path then return Main.result_status(self.class.gem_src_root)
982
- when :version then return Main.result_status(Aspera::Cli::VERSION)
983
- when :name then return Main.result_status(@info[:gem])
963
+ when :version then return Main.result_status(Cli::VERSION)
964
+ when :name then return Main.result_status(@gem)
984
965
  end
985
966
  when :folder
986
967
  return Main.result_status(@main_folder)
@@ -999,24 +980,24 @@ module Aspera
999
980
  when :check_update
1000
981
  return {type: :single_object, data: check_gem_version}
1001
982
  when :initdemo
1002
- if @config_presets.key?(DEMO_SERVER_PRESET)
1003
- Log.log.warn{"Demo server preset already present: #{DEMO_SERVER_PRESET}"}
983
+ if @config_presets.key?(DEMO_PRESET)
984
+ Log.log.warn{"Demo server preset already present: #{DEMO_PRESET}"}
1004
985
  else
1005
- Log.log.info{"Creating Demo server preset: #{DEMO_SERVER_PRESET}"}
1006
- @config_presets[DEMO_SERVER_PRESET] = {
1007
- 'url' => "ssh://#{DEMO}.asperasoft.com:33001",
986
+ Log.log.info{"Creating Demo server preset: #{DEMO_PRESET}"}
987
+ @config_presets[DEMO_PRESET] = {
988
+ 'url' => "ssh://#{DEMO_SERVER}.asperasoft.com:33001",
1008
989
  'username' => ASPERA,
1009
- 'ssAP'.downcase.reverse + 'drow'.reverse => DEMO + ASPERA # cspell:disable-line
990
+ 'ssAP'.downcase.reverse + 'drow'.reverse => DEMO_SERVER + ASPERA # cspell:disable-line
1010
991
  }
1011
992
  end
1012
993
  @config_presets[CONF_PRESET_DEFAULTS] ||= {}
1013
994
  if @config_presets[CONF_PRESET_DEFAULTS].key?(SERVER_COMMAND)
1014
995
  Log.log.warn{"Server default preset already set to: #{@config_presets[CONF_PRESET_DEFAULTS][SERVER_COMMAND]}"}
1015
- Log.log.warn{"Use #{DEMO_SERVER_PRESET} for demo: -P#{DEMO_SERVER_PRESET}"} unless
1016
- DEMO_SERVER_PRESET.eql?(@config_presets[CONF_PRESET_DEFAULTS][SERVER_COMMAND])
996
+ Log.log.warn{"Use #{DEMO_PRESET} for demo: -P#{DEMO_PRESET}"} unless
997
+ DEMO_PRESET.eql?(@config_presets[CONF_PRESET_DEFAULTS][SERVER_COMMAND])
1017
998
  else
1018
- @config_presets[CONF_PRESET_DEFAULTS][SERVER_COMMAND] = DEMO_SERVER_PRESET
1019
- Log.log.info{"Setting server default preset to : #{DEMO_SERVER_PRESET}"}
999
+ @config_presets[CONF_PRESET_DEFAULTS][SERVER_COMMAND] = DEMO_PRESET
1000
+ Log.log.info{"Setting server default preset to : #{DEMO_PRESET}"}
1020
1001
  end
1021
1002
  return Main.result_status('Done')
1022
1003
  when :vault then execute_vault
@@ -1026,9 +1007,9 @@ module Aspera
1026
1007
  exception_class_name = options.get_next_argument('exception class name', mandatory: true)
1027
1008
  exception_text = options.get_next_argument('exception text', mandatory: true)
1028
1009
  exception_class = Object.const_get(exception_class_name)
1029
- assert(exception_class <= Exception){"#{exception_class} is not an exception: #{exception_class.class}"}
1010
+ Aspera.assert(exception_class <= Exception){"#{exception_class} is not an exception: #{exception_class.class}"}
1030
1011
  raise exception_class, exception_text
1031
- else error_unreachable_line
1012
+ else Aspera.error_unreachable_line
1032
1013
  end
1033
1014
  end
1034
1015
 
@@ -1043,15 +1024,17 @@ module Aspera
1043
1024
  apps.find{|a|a[:product].eql?(answer)}
1044
1025
  end
1045
1026
  wiz_url = identification[:url]
1046
- Log.log.debug{Log.dump(:identification, identification, :ruby)}
1027
+ Log.log.debug{Log.dump(:identification, identification)}
1047
1028
  formatter.display_status("Using: #{identification[:name]} at #{wiz_url}".bold)
1048
1029
  # set url for instantiation of plugin
1049
1030
  options.add_option_preset({url: wiz_url})
1050
1031
  # instantiate plugin: command line options will be known and wizard can be called
1051
- wiz_plugin_class = self.class.plugin_class(identification[:product])
1052
- assert(wiz_plugin_class.respond_to?(:wizard), exception_class: Cli::BadArgument){"Detected: #{identification[:product]}, but this application has no wizard"}
1032
+ wiz_plugin_class = PluginFactory.plugin_class(identification[:product])
1033
+ Aspera.assert(wiz_plugin_class.respond_to?(:wizard), exception_class: Cli::BadArgument) do
1034
+ "Detected: #{identification[:product]}, but this application has no wizard"
1035
+ end
1053
1036
  # instantiate plugin: command line options will be known, e.g. private_key
1054
- plugin_instance = wiz_plugin_class.new(@agents)
1037
+ plugin_instance = wiz_plugin_class.new(**init_params)
1055
1038
  wiz_params = {
1056
1039
  object: plugin_instance
1057
1040
  }
@@ -1087,7 +1070,7 @@ module Aspera
1087
1070
  # finally, call the wizard
1088
1071
  wizard_result = wiz_plugin_class.wizard(**wiz_params)
1089
1072
  Log.log.debug{"wizard result: #{wizard_result}"}
1090
- assert(WIZARD_RESULT_KEYS.eql?(wizard_result.keys.sort)){"missing or extra keys in wizard result: #{wizard_result.keys}"}
1073
+ Aspera.assert(WIZARD_RESULT_KEYS.eql?(wizard_result.keys.sort)){"missing or extra keys in wizard result: #{wizard_result.keys}"}
1091
1074
  # get preset name from user or default
1092
1075
  wiz_preset_name = options.get_option(:id)
1093
1076
  if wiz_preset_name.nil?
@@ -1118,7 +1101,7 @@ module Aspera
1118
1101
  test_args = "-P#{wiz_preset_name} #{test_args}"
1119
1102
  end
1120
1103
  # TODO: actually test the command
1121
- return Main.result_status("You can test with:\n#{@info[:name]} #{identification[:product]} #{test_args}")
1104
+ return Main.result_status("You can test with:\n#{@name} #{identification[:product]} #{test_args}")
1122
1105
  end
1123
1106
 
1124
1107
  # @return [Hash] email server setting with defaults if not defined
@@ -1136,11 +1119,11 @@ module Aspera
1136
1119
  25
1137
1120
  end
1138
1121
  smtp[:from_email] ||= smtp[:username] if smtp.key?(:username)
1139
- smtp[:from_name] ||= smtp[:from_email].gsub(/@.*$/, '').gsub(/[^a-zA-Z]/, ' ').capitalize if smtp.key?(:username)
1140
- smtp[:domain] ||= smtp[:from_email].gsub(/^.*@/, '') if smtp.key?(:from_email)
1122
+ smtp[:from_name] ||= smtp[:from_email].sub(/@.*$/, '').gsub(/[^a-zA-Z]/, ' ').capitalize if smtp.key?(:username)
1123
+ smtp[:domain] ||= smtp[:from_email].sub(/^.*@/, '') if smtp.key?(:from_email)
1141
1124
  # check minimum required
1142
1125
  %i[server port domain].each do |n|
1143
- assert(smtp.key?(n)){"Missing mandatory smtp parameter: #{n}"}
1126
+ Aspera.assert(smtp.key?(n)){"Missing mandatory smtp parameter: #{n}"}
1144
1127
  end
1145
1128
  Log.log.debug{"smtp=#{smtp}"}
1146
1129
  return smtp
@@ -1154,7 +1137,7 @@ module Aspera
1154
1137
  values[:from_name] ||= mail_conf[:from_name]
1155
1138
  values[:from_email] ||= mail_conf[:from_email]
1156
1139
  %i[from_name from_email].each do |n|
1157
- assert(values.key?(n)){"Missing email parameter: #{n}"}
1140
+ Aspera.assert(values.key?(n)){"Missing email parameter: #{n}"}
1158
1141
  end
1159
1142
  start_options = [mail_conf[:domain]]
1160
1143
  start_options.push(mail_conf[:username], mail_conf[:password], :login) if mail_conf.key?(:username) && mail_conf.key?(:password)
@@ -1162,7 +1145,7 @@ module Aspera
1162
1145
  template_binding = Environment.empty_binding
1163
1146
  # add variables to binding
1164
1147
  values.each do |k, v|
1165
- assert_type(k, Symbol)
1148
+ Aspera.assert_type(k, Symbol)
1166
1149
  template_binding.local_variable_set(k, v)
1167
1150
  end
1168
1151
  # execute template
@@ -1196,7 +1179,7 @@ module Aspera
1196
1179
  # returns [String] name if config_presets has default
1197
1180
  # returns nil if there is no config or bypass default params
1198
1181
  def get_plugin_default_config_name(plugin_name_sym)
1199
- assert(!@config_presets.nil?){'config_presets shall be defined'}
1182
+ Aspera.assert(!@config_presets.nil?){'config_presets shall be defined'}
1200
1183
  if !@use_plugin_defaults
1201
1184
  Log.log.debug('skip default config')
1202
1185
  return nil
@@ -1208,7 +1191,7 @@ module Aspera
1208
1191
  Log.log.error do
1209
1192
  "Default config name [#{default_config_name}] specified for plugin [#{plugin_name_sym}], but it does not exist in config file.\n" \
1210
1193
  'Please fix the issue: either create preset with one parameter: ' \
1211
- "(#{@info[:name]} config id #{default_config_name} init @json:'{}') or remove default (#{@info[:name]} config id default remove #{plugin_name_sym})."
1194
+ "(#{@name} config id #{default_config_name} init @json:'{}') or remove default (#{@name} config id default remove #{plugin_name_sym})."
1212
1195
  end
1213
1196
  end
1214
1197
  raise Cli::Error, "Config name [#{default_config_name}] must be a hash, check config file." if !@config_presets[default_config_name].is_a?(Hash)
@@ -1239,7 +1222,7 @@ module Aspera
1239
1222
  vault.delete(label: options.get_next_argument('label'))
1240
1223
  return Main.result_status('Password deleted')
1241
1224
  when :password
1242
- assert(vault.respond_to?(:password=)){'Vault does not support password change'}
1225
+ Aspera.assert(vault.respond_to?(:password=)){'Vault does not support password change'}
1243
1226
  new_password = options.get_next_argument('new_password')
1244
1227
  vault.password = new_password
1245
1228
  vault.save
@@ -1249,12 +1232,12 @@ module Aspera
1249
1232
 
1250
1233
  # @return [String] value from vault matching <name>.<param>
1251
1234
  def vault_value(name)
1252
- m = name.match(/^(.+)\.(.+)$/)
1253
- raise 'vault name shall match <name>.<param>' if m.nil?
1235
+ m = name.split('.')
1236
+ raise 'vault name shall match <name>.<param>' unless m.length.eql?(2)
1254
1237
  # this raise exception if label not found:
1255
- info = vault.get(label: m[1])
1256
- value = info[m[2].to_sym]
1257
- raise "no such entry value: #{m[2]}" if value.nil?
1238
+ info = vault.get(label: m[0])
1239
+ value = info[m[1].to_sym]
1240
+ raise "no such entry value: #{m[1]}" if value.nil?
1258
1241
  return value
1259
1242
  end
1260
1243
 
@@ -1263,8 +1246,8 @@ module Aspera
1263
1246
  info = info.symbolize_keys
1264
1247
  info[:type] ||= 'file'
1265
1248
  info[:name] ||= (info[:type].eql?('file') ? DEFAULT_VAULT_FILENAME : PROGRAM_NAME)
1266
- assert(info.keys.sort == %i[name type]) {"vault info shall have exactly keys 'type' and 'name'"}
1267
- assert(info.values.all?(String)){'vault info shall have only string values'}
1249
+ Aspera.assert(info.keys.sort == %i[name type]) {"vault info shall have exactly keys 'type' and 'name'"}
1250
+ Aspera.assert(info.values.all?(String)){'vault info shall have only string values'}
1268
1251
  info[:password] = options.get_option(:vault_password, mandatory: true)
1269
1252
  return info
1270
1253
  end
@@ -1296,14 +1279,14 @@ module Aspera
1296
1279
 
1297
1280
  # version of URL without trailing "/" and removing default port
1298
1281
  def canonical_url(url)
1299
- url.gsub(%r{/+$}, '').gsub(%r{^(https://[^/]+):443$}, '\1')
1282
+ url.sub(%r{/+$}, '').sub(%r{^(https://[^/]+):443$}, '\1')
1300
1283
  end
1301
1284
 
1302
1285
  def lookup_preset(url:, username:)
1303
1286
  # remove extra info to maximize match
1304
1287
  url = canonical_url(url)
1305
1288
  Log.log.debug{"Lookup preset for #{username}@#{url}"}
1306
- @config_presets.each do |_k, v|
1289
+ @config_presets.each_value do |v|
1307
1290
  next unless v.is_a?(Hash)
1308
1291
  conf_url = v['url'].is_a?(String) ? canonical_url(v['url']) : nil
1309
1292
  return self.class.protect_presets(v) if conf_url.eql?(url) && v['username'].eql?(username)