aspera-cli 4.16.0 → 4.17.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 (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)