aspera-cli 4.7.0 → 4.8.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 (94) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -0
  3. data/README.md +844 -861
  4. data/bin/ascli +20 -1
  5. data/bin/asession +37 -34
  6. data/docs/test_env.conf +11 -3
  7. data/examples/aoc.rb +13 -12
  8. data/examples/dascli +26 -0
  9. data/examples/faspex4.rb +34 -29
  10. data/examples/transfer.rb +30 -29
  11. data/lib/aspera/aoc.rb +151 -143
  12. data/lib/aspera/ascmd.rb +56 -45
  13. data/lib/aspera/ats_api.rb +6 -5
  14. data/lib/aspera/cli/basic_auth_plugin.rb +18 -16
  15. data/lib/aspera/cli/extended_value.rb +32 -30
  16. data/lib/aspera/cli/formater.rb +103 -111
  17. data/lib/aspera/cli/info.rb +2 -1
  18. data/lib/aspera/cli/listener/line_dump.rb +1 -0
  19. data/lib/aspera/cli/listener/logger.rb +1 -0
  20. data/lib/aspera/cli/listener/progress.rb +13 -12
  21. data/lib/aspera/cli/listener/progress_multi.rb +21 -20
  22. data/lib/aspera/cli/main.rb +106 -89
  23. data/lib/aspera/cli/manager.rb +96 -85
  24. data/lib/aspera/cli/plugin.rb +50 -32
  25. data/lib/aspera/cli/plugins/alee.rb +6 -5
  26. data/lib/aspera/cli/plugins/aoc.rb +521 -426
  27. data/lib/aspera/cli/plugins/ats.rb +84 -83
  28. data/lib/aspera/cli/plugins/bss.rb +30 -27
  29. data/lib/aspera/cli/plugins/config.rb +483 -397
  30. data/lib/aspera/cli/plugins/console.rb +17 -15
  31. data/lib/aspera/cli/plugins/cos.rb +26 -35
  32. data/lib/aspera/cli/plugins/faspex.rb +201 -168
  33. data/lib/aspera/cli/plugins/faspex5.rb +109 -74
  34. data/lib/aspera/cli/plugins/node.rb +378 -189
  35. data/lib/aspera/cli/plugins/orchestrator.rb +71 -65
  36. data/lib/aspera/cli/plugins/preview.rb +131 -122
  37. data/lib/aspera/cli/plugins/server.rb +94 -93
  38. data/lib/aspera/cli/plugins/shares.rb +42 -28
  39. data/lib/aspera/cli/plugins/sync.rb +15 -14
  40. data/lib/aspera/cli/transfer_agent.rb +56 -52
  41. data/lib/aspera/cli/version.rb +2 -1
  42. data/lib/aspera/colors.rb +29 -28
  43. data/lib/aspera/command_line_builder.rb +50 -43
  44. data/lib/aspera/cos_node.rb +64 -38
  45. data/lib/aspera/data_repository.rb +1 -0
  46. data/lib/aspera/environment.rb +18 -8
  47. data/lib/aspera/fasp/agent_base.rb +26 -23
  48. data/lib/aspera/fasp/agent_connect.rb +35 -30
  49. data/lib/aspera/fasp/agent_direct.rb +68 -60
  50. data/lib/aspera/fasp/agent_httpgw.rb +71 -64
  51. data/lib/aspera/fasp/agent_node.rb +24 -23
  52. data/lib/aspera/fasp/agent_trsdk.rb +19 -20
  53. data/lib/aspera/fasp/error.rb +2 -1
  54. data/lib/aspera/fasp/error_info.rb +79 -68
  55. data/lib/aspera/fasp/installation.rb +122 -114
  56. data/lib/aspera/fasp/listener.rb +1 -0
  57. data/lib/aspera/fasp/parameters.rb +44 -41
  58. data/lib/aspera/fasp/resume_policy.rb +14 -11
  59. data/lib/aspera/fasp/transfer_spec.rb +6 -5
  60. data/lib/aspera/fasp/uri.rb +25 -24
  61. data/lib/aspera/faspex_gw.rb +83 -72
  62. data/lib/aspera/hash_ext.rb +10 -12
  63. data/lib/aspera/id_generator.rb +8 -7
  64. data/lib/aspera/keychain/encrypted_hash.rb +60 -45
  65. data/lib/aspera/keychain/macos_security.rb +26 -24
  66. data/lib/aspera/log.rb +34 -38
  67. data/lib/aspera/nagios.rb +14 -13
  68. data/lib/aspera/node.rb +19 -19
  69. data/lib/aspera/oauth.rb +121 -101
  70. data/lib/aspera/open_application.rb +6 -5
  71. data/lib/aspera/persistency_action_once.rb +9 -8
  72. data/lib/aspera/persistency_folder.rb +10 -9
  73. data/lib/aspera/preview/file_types.rb +261 -266
  74. data/lib/aspera/preview/generator.rb +74 -73
  75. data/lib/aspera/preview/image_error.png +0 -0
  76. data/lib/aspera/preview/options.rb +7 -6
  77. data/lib/aspera/preview/utils.rb +30 -33
  78. data/lib/aspera/preview/video_error.png +0 -0
  79. data/lib/aspera/proxy_auto_config.rb +25 -23
  80. data/lib/aspera/rest.rb +73 -74
  81. data/lib/aspera/rest_call_error.rb +1 -0
  82. data/lib/aspera/rest_error_analyzer.rb +11 -9
  83. data/lib/aspera/rest_errors_aspera.rb +5 -4
  84. data/lib/aspera/secret_hider.rb +68 -0
  85. data/lib/aspera/ssh.rb +12 -10
  86. data/lib/aspera/sync.rb +49 -47
  87. data/lib/aspera/temp_file_manager.rb +7 -5
  88. data/lib/aspera/timer_limiter.rb +9 -8
  89. data/lib/aspera/uri_reader.rb +11 -14
  90. data/lib/aspera/web_auth.rb +17 -15
  91. data.tar.gz.sig +0 -0
  92. metadata +117 -34
  93. metadata.gz.sig +2 -0
  94. data/bin/dascli +0 -13
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'aspera/cli/basic_auth_plugin'
3
4
  require 'aspera/cli/extended_value'
4
5
  require 'aspera/cli/version'
6
+ require 'aspera/cli/formater'
5
7
  require 'aspera/fasp/installation'
6
8
  require 'aspera/fasp/parameters'
7
9
  require 'aspera/fasp/transfer_spec'
@@ -27,37 +29,37 @@ module Aspera
27
29
  # manage the CLI config file
28
30
  class Config < Plugin
29
31
  # folder in $HOME for application files (config, cache)
30
- ASPERA_HOME_FOLDER_NAME='.aspera'
32
+ ASPERA_HOME_FOLDER_NAME = '.aspera'
31
33
  # default config file
32
34
  DEFAULT_CONFIG_FILENAME = 'config.yaml'
33
35
  # reserved preset names
34
- CONF_PRESET_CONFIG='config'
35
- CONF_PRESET_VERSION='version'
36
- CONF_PRESET_DEFAULT='default'
37
- CONF_PRESET_GLOBAL='global_common_defaults'
38
- CONF_PRESET_SECRETS='default_secrets' # pragma: allowlist secret
36
+ CONF_PRESET_CONFIG = 'config'
37
+ CONF_PRESET_VERSION = 'version'
38
+ CONF_PRESET_DEFAULT = 'default'
39
+ CONF_PRESET_GLOBAL = 'global_common_defaults'
40
+ CONF_PRESET_SECRETS = 'default_secrets' # pragma: allowlist secret
39
41
  CONF_PLUGIN_SYM = :config # Plugins::Config.name.split('::').last.downcase.to_sym
40
42
  CONF_GLOBAL_SYM = :config
41
43
  # old tool name
42
44
  PROGRAM_NAME_V1 = 'aslmcli'
43
45
  PROGRAM_NAME_V2 = 'mlia'
44
46
  # default redirect for AoC web auth
45
- DEFAULT_REDIRECT='http://localhost:12345'
47
+ DEFAULT_REDIRECT = 'http://localhost:12345'
46
48
  # folder containing custom plugins in user's config folder
47
- ASPERA_PLUGINS_FOLDERNAME='plugins'
48
- RUBY_FILE_EXT='.rb'
49
- AOC_COMMAND_V1='files'
50
- AOC_COMMAND_V2='aspera'
51
- AOC_COMMAND_V3='aoc'
52
- AOC_COMMAND_CURRENT=AOC_COMMAND_V3
53
- SERVER_COMMAND='server'
49
+ ASPERA_PLUGINS_FOLDERNAME = 'plugins'
50
+ RUBY_FILE_EXT = '.rb'
51
+ AOC_COMMAND_V1 = 'files'
52
+ AOC_COMMAND_V2 = 'aspera'
53
+ AOC_COMMAND_V3 = 'aoc'
54
+ AOC_COMMAND_CURRENT = AOC_COMMAND_V3
55
+ SERVER_COMMAND = 'server'
54
56
  CONNECT_WEB_URL = 'https://d3gcli72yxqn2z.cloudfront.net/connect'
55
57
  CONNECT_VERSIONS = 'connectversions.js'
56
58
  TRANSFER_SDK_ARCHIVE_URL = 'https://ibm.biz/aspera_transfer_sdk'
57
- DEMO='demo'
58
- DEMO_SERVER_PRESET='demoserver'
59
- AOC_PATH_API_CLIENTS='admin/api-clients'
60
- EMAIL_TEST_TEMPLATE=<<~END_OF_TEMPLATE
59
+ DEMO = 'demo'
60
+ DEMO_SERVER_PRESET = 'demoserver'
61
+ AOC_PATH_API_CLIENTS = 'admin/api-clients'
62
+ EMAIL_TEST_TEMPLATE = <<~END_OF_TEMPLATE
61
63
  From: <%=from_name%> <<%=from_email%>>
62
64
  To: <<%=to%>>
63
65
  Subject: Amelia email test
@@ -65,33 +67,33 @@ module Aspera
65
67
  It worked !
66
68
  END_OF_TEMPLATE
67
69
  # special extended values
68
- EXTV_INCLUDE_PRESETS=:incps
69
- EXTV_PRESET=:preset
70
- PRESET_DIG_SEPARATOR='.'
71
- DEFAULT_CHECK_NEW_VERSION_DAYS=7
72
- DEFAULT_PRIV_KEY_FILENAME='aspera_aoc_key' # pragma: allowlist secret
73
- DEFAULT_PRIVKEY_LENGTH=4096
70
+ EXTV_INCLUDE_PRESETS = :incps
71
+ EXTV_PRESET = :preset
72
+ PRESET_DIG_SEPARATOR = '.'
73
+ DEFAULT_CHECK_NEW_VERSION_DAYS = 7
74
+ DEFAULT_PRIV_KEY_FILENAME = 'aspera_aoc_key' # pragma: allowlist secret
75
+ DEFAULT_PRIVKEY_LENGTH = 4096
74
76
  private_constant :DEFAULT_CONFIG_FILENAME,:CONF_PRESET_CONFIG,:CONF_PRESET_VERSION,:CONF_PRESET_DEFAULT,
75
- :CONF_PRESET_GLOBAL,:PROGRAM_NAME_V1,:PROGRAM_NAME_V2,:DEFAULT_REDIRECT,:ASPERA_PLUGINS_FOLDERNAME,
76
- :RUBY_FILE_EXT,:AOC_COMMAND_V1,:AOC_COMMAND_V2,:AOC_COMMAND_V3,:AOC_COMMAND_CURRENT,:DEMO,
77
- :TRANSFER_SDK_ARCHIVE_URL,:AOC_PATH_API_CLIENTS,:DEMO_SERVER_PRESET,:EMAIL_TEST_TEMPLATE,:EXTV_INCLUDE_PRESETS,
78
- :EXTV_PRESET,:DEFAULT_CHECK_NEW_VERSION_DAYS,:DEFAULT_PRIV_KEY_FILENAME,:SERVER_COMMAND,:CONF_PRESET_SECRETS,
79
- :PRESET_DIG_SEPARATOR
77
+ :CONF_PRESET_GLOBAL,:PROGRAM_NAME_V1,:PROGRAM_NAME_V2,:DEFAULT_REDIRECT,:ASPERA_PLUGINS_FOLDERNAME,
78
+ :RUBY_FILE_EXT,:AOC_COMMAND_V1,:AOC_COMMAND_V2,:AOC_COMMAND_V3,:AOC_COMMAND_CURRENT,:DEMO,
79
+ :TRANSFER_SDK_ARCHIVE_URL,:AOC_PATH_API_CLIENTS,:DEMO_SERVER_PRESET,:EMAIL_TEST_TEMPLATE,:EXTV_INCLUDE_PRESETS,
80
+ :EXTV_PRESET,:DEFAULT_CHECK_NEW_VERSION_DAYS,:DEFAULT_PRIV_KEY_FILENAME,:SERVER_COMMAND,:CONF_PRESET_SECRETS,
81
+ :PRESET_DIG_SEPARATOR
80
82
  def initialize(env,params)
81
83
  raise 'env and params must be Hash' unless env.is_a?(Hash) && params.is_a?(Hash)
82
- raise 'missing param' unless [:name,:help,:version,:gem].sort.eql?(params.keys.sort)
84
+ raise 'missing param' unless %i[name help version gem].sort.eql?(params.keys.sort)
83
85
  super(env)
84
- @info=params
85
- @main_folder=default_app_main_folder
86
- @plugins={}
87
- @plugin_lookup_folders=[]
88
- @use_plugin_defaults=true
89
- @config_presets=nil
90
- @connect_versions=nil
91
- @vault=nil
92
- @conf_file_default=File.join(@main_folder,DEFAULT_CONFIG_FILENAME)
93
- @option_config_file=@conf_file_default
94
- @pac_exec=nil
86
+ @info = params
87
+ @main_folder = default_app_main_folder
88
+ @plugins = {}
89
+ @plugin_lookup_folders = []
90
+ @use_plugin_defaults = true
91
+ @config_presets = nil
92
+ @connect_versions = nil
93
+ @vault = nil
94
+ @conf_file_default = File.join(@main_folder,DEFAULT_CONFIG_FILENAME)
95
+ @option_config_file = @conf_file_default
96
+ @pac_exec = nil
95
97
  Log.log.debug("#{@info[:name]} folder: #{@main_folder}")
96
98
  # set folder for FASP SDK
97
99
  add_plugin_lookup_folder(self.class.gem_plugins_folder)
@@ -113,7 +115,7 @@ module Aspera
113
115
  options.set_obj_attr(:use_product,self,:option_use_product)
114
116
  options.set_obj_attr(:preset,self,:option_preset)
115
117
  options.set_obj_attr(:plugin_folder,self,:option_plugin_folder)
116
- options.add_opt_switch(:no_default,'-N','do not load default configuration for plugin') { @use_plugin_defaults=false }
118
+ options.add_opt_switch(:no_default,'-N','do not load default configuration for plugin') { @use_plugin_defaults = false }
117
119
  options.add_opt_boolean(:override,'Wizard: override existing value')
118
120
  options.add_opt_boolean(:use_generic_client,'Wizard: AoC: use global or org specific jwt client id')
119
121
  options.add_opt_boolean(:default,'Wizard: set as default configuration for specified plugin (also: update)')
@@ -140,9 +142,9 @@ module Aspera
140
142
  options.set_option(:sdk_folder,File.join(@main_folder,'sdk'))
141
143
  options.set_option(:override,:no)
142
144
  options.parse_options!
143
- pac_script=options.get_option(:fpac,:optional)
145
+ pac_script = options.get_option(:fpac)
144
146
  # create PAC executor
145
- @pac_exec=Aspera::ProxyAutoConfig.new(pac_script).register_uri_generic unless pac_script.nil?
147
+ @pac_exec = Aspera::ProxyAutoConfig.new(pac_script).register_uri_generic unless pac_script.nil?
146
148
  end
147
149
 
148
150
  # env var name to override the app's main folder
@@ -153,72 +155,81 @@ module Aspera
153
155
 
154
156
  def default_app_main_folder
155
157
  # find out application main folder
156
- app_folder=ENV[conf_dir_env_var]
158
+ app_folder = ENV[conf_dir_env_var]
157
159
  # if env var undefined or empty
158
160
  if app_folder.nil? || app_folder.empty?
159
- user_home_folder=Dir.home
161
+ user_home_folder = Dir.home
160
162
  raise CliError,"Home folder does not exist: #{user_home_folder}. Check your user environment or use #{conf_dir_env_var}." unless Dir.exist?(user_home_folder)
161
- app_folder=File.join(user_home_folder,ASPERA_HOME_FOLDER_NAME,@info[:name])
163
+ app_folder = File.join(user_home_folder,ASPERA_HOME_FOLDER_NAME,@info[:name])
162
164
  end
163
165
  return app_folder
164
166
  end
165
167
 
166
168
  def check_gem_version
167
- latest_version=begin
168
- Rest.new(base_url: 'https://rubygems.org/api/v1').read("versions/#{@info[:gem]}/latest.json")[:data]['version']
169
- rescue StandardError
170
- Log.log.warn('Could not retrieve latest gem version on rubygems.')
171
- '0'
172
- end
169
+ latest_version =
170
+ begin
171
+ Rest.new(base_url: 'https://rubygems.org/api/v1').read("versions/#{@info[:gem]}/latest.json")[:data]['version']
172
+ rescue StandardError
173
+ Log.log.warn('Could not retrieve latest gem version on rubygems.')
174
+ '0'
175
+ end
173
176
  if Gem::Version.new(Environment.ruby_version) < Gem::Version.new(RUBY_FUTURE_MINIMUM_VERSION)
174
- Log.log.warn("Note that a future version will require Ruby version #{RUBY_FUTURE_MINIMUM_VERSION} at minimum, you are using #{Environment.ruby_version}")
177
+ Log.log.warn("Note that a future version will require Ruby version #{RUBY_FUTURE_MINIMUM_VERSION} at minimum, "\
178
+ "you are using #{Environment.ruby_version}")
175
179
  end
176
- return {name: @info[:gem], current: Aspera::Cli::VERSION, latest: latest_version, need_update: Gem::Version.new(Aspera::Cli::VERSION) < Gem::Version.new(latest_version)}
180
+ return {
181
+ name: @info[:gem],
182
+ current: Aspera::Cli::VERSION,
183
+ latest: latest_version,
184
+ need_update: Gem::Version.new(Aspera::Cli::VERSION) < Gem::Version.new(latest_version)
185
+ }
177
186
  end
178
187
 
179
188
  def periodic_check_newer_gem_version
180
189
  # get verification period
181
- delay_days=options.get_option(:version_check_days,:mandatory)
190
+ delay_days = options.get_option(:version_check_days,is_type: :mandatory)
182
191
  Log.log.info("check days: #{delay_days}")
183
192
  # check only if not zero day
184
193
  return if delay_days.eql?(0)
185
194
  # get last date from persistency
186
- last_check_array=[]
187
- check_date_persist=PersistencyActionOnce.new(
188
- manager: persistency,
189
- data: last_check_array,
190
- id: 'version_last_check')
195
+ last_check_array = []
196
+ check_date_persist = PersistencyActionOnce.new(
197
+ manager: persistency,
198
+ data: last_check_array,
199
+ id: 'version_last_check')
191
200
  # get persisted date or nil
192
- current_date=Date.today
193
- last_check_days = begin
194
- current_date-Date.strptime(last_check_array.first, '%Y/%m/%d')
195
- rescue StandardError
196
- # negative value will force check
197
- -1
198
- end
201
+ current_date = Date.today
202
+ last_check_days =
203
+ begin
204
+ current_date - Date.strptime(last_check_array.first, '%Y/%m/%d')
205
+ rescue StandardError
206
+ # negative value will force check
207
+ -1
208
+ end
199
209
  Log.log.debug("days elapsed: #{last_check_days}")
200
210
  return if last_check_days < delay_days
201
211
  # generate timestamp
202
- last_check_array[0]=current_date.strftime('%Y/%m/%d')
212
+ last_check_array[0] = current_date.strftime('%Y/%m/%d')
203
213
  check_date_persist.save
204
214
  # compare this version and the one on internet
205
- check_data=check_gem_version
206
- Log.log.warn("A new version is available: #{check_data[:latest]}. You have #{check_data[:current]}. Upgrade with: gem update #{check_data[:name]}") if check_data[:need_update]
215
+ check_data = check_gem_version
216
+ Log.log.warn("A new version is available: #{check_data[:latest]}. "\
217
+ "You have #{check_data[:current]}. Upgrade with: gem update #{check_data[:name]}") if check_data[:need_update]
207
218
  end
208
219
 
209
220
  # retrieve structure from cloud (CDN) with all versions available
210
221
  def connect_versions
211
222
  if @connect_versions.nil?
212
- api_connect_cdn=Rest.new({base_url: CONNECT_WEB_URL})
213
- javascript=api_connect_cdn.call({operation: 'GET',subpath: CONNECT_VERSIONS})
223
+ api_connect_cdn = Rest.new({base_url: CONNECT_WEB_URL})
224
+ javascript = api_connect_cdn.call({operation: 'GET',subpath: CONNECT_VERSIONS})
214
225
  # get result on one line
215
- connect_versions_javascript=javascript[:http].body.gsub(/\r?\n\s*/,'')
226
+ connect_versions_javascript = javascript[:http].body.gsub(/\r?\n\s*/,'')
216
227
  Log.log.debug("javascript=[\n#{connect_versions_javascript}\n]")
217
228
  # get javascript object only
218
- found=connect_versions_javascript.match(/^.*? = (.*);/)
229
+ found = connect_versions_javascript.match(/^.*? = (.*);/)
219
230
  raise CliError,'Problen when getting connect versions from internet' if found.nil?
220
- alldata=JSON.parse(found[1])
221
- @connect_versions=alldata['entries']
231
+ alldata = JSON.parse(found[1])
232
+ @connect_versions = alldata['entries']
222
233
  end
223
234
  return @connect_versions
224
235
  end
@@ -228,9 +239,9 @@ module Aspera
228
239
  # try to find: conffile[conffile["default"][plugin_str]]
229
240
  # @param plugin_name_sym : symbol for plugin name
230
241
  def add_plugin_default_preset(plugin_name_sym)
231
- default_config_name=get_plugin_default_config_name(plugin_name_sym)
242
+ default_config_name = get_plugin_default_config_name(plugin_name_sym)
232
243
  Log.log.debug("add_plugin_default_preset:#{plugin_name_sym}:#{default_config_name}")
233
- options.add_option_preset(preset_by_name(default_config_name),:unshift) unless default_config_name.nil?
244
+ options.add_option_preset(preset_by_name(default_config_name),op: :unshift) unless default_config_name.nil?
234
245
  return nil
235
246
  end
236
247
 
@@ -240,7 +251,7 @@ module Aspera
240
251
  require 'openssl'
241
252
  priv_key = OpenSSL::PKey::RSA.new(length)
242
253
  File.write(private_key_path,priv_key.to_s)
243
- File.write(private_key_path+'.pub',priv_key.public_key.to_s)
254
+ File.write(private_key_path + '.pub',priv_key.public_key.to_s)
244
255
  nil
245
256
  end
246
257
 
@@ -268,16 +279,6 @@ module Aspera
268
279
  # Module.nesting[2] is Aspera::Cli::Plugins
269
280
  return Object.const_get("#{module_full_name}::#{plugin_name_sym.to_s.capitalize}")
270
281
  end
271
-
272
- def flatten_all_config(t)
273
- r=[]
274
- t.each do |k,v|
275
- v.each do |kk,vv|
276
- r.push({'config'=>k,'parameter'=>kk,'value'=>vv})
277
- end
278
- end
279
- return r
280
- end
281
282
  end
282
283
 
283
284
  # set parameter and value in global config
@@ -285,14 +286,14 @@ module Aspera
285
286
  # @return preset name that contains global default
286
287
  def set_global_default(key,value)
287
288
  # get default preset if it exists
288
- global_default_preset_name=get_plugin_default_config_name(CONF_GLOBAL_SYM)
289
+ global_default_preset_name = get_plugin_default_config_name(CONF_GLOBAL_SYM)
289
290
  if global_default_preset_name.nil?
290
- global_default_preset_name=CONF_PRESET_GLOBAL
291
- @config_presets[CONF_PRESET_DEFAULT]||={}
292
- @config_presets[CONF_PRESET_DEFAULT][CONF_GLOBAL_SYM.to_s]=global_default_preset_name
291
+ global_default_preset_name = CONF_PRESET_GLOBAL
292
+ @config_presets[CONF_PRESET_DEFAULT] ||= {}
293
+ @config_presets[CONF_PRESET_DEFAULT][CONF_GLOBAL_SYM.to_s] = global_default_preset_name
293
294
  end
294
- @config_presets[global_default_preset_name]||={}
295
- @config_presets[global_default_preset_name][key.to_s]=value
295
+ @config_presets[global_default_preset_name] ||= {}
296
+ @config_presets[global_default_preset_name][key.to_s] = value
296
297
  self.format.display_status("Updated: #{global_default_preset_name}: #{key} <- #{value}")
297
298
  save_presets_to_config_file
298
299
  return global_default_preset_name
@@ -310,12 +311,12 @@ module Aspera
310
311
  # @param include_path used to detect and avoid include loops
311
312
  def preset_by_name(config_name, include_path=[])
312
313
  raise CliError,'loop in include' if include_path.include?(config_name)
313
- include_path=include_path.clone # avoid messing up if there are multiple branches
314
- current=@config_presets
314
+ include_path = include_path.clone # avoid messing up if there are multiple branches
315
+ current = @config_presets
315
316
  config_name.split(PRESET_DIG_SEPARATOR).each do |name|
316
317
  raise CliError,"not a Hash: #{include_path} (#{current.class})" unless current.is_a?(Hash)
317
318
  include_path.push(name)
318
- current=current[name]
319
+ current = current[name]
319
320
  raise CliError,"no such config preset: #{include_path}" if nil?
320
321
  end
321
322
  case current
@@ -331,10 +332,10 @@ module Aspera
331
332
  def expanded_with_preset_includes(hash_val, include_path=[])
332
333
  raise CliError,"#{EXTV_INCLUDE_PRESETS} requires a Hash, have #{hash_val.class}" unless hash_val.is_a?(Hash)
333
334
  if hash_val.has_key?(EXTV_INCLUDE_PRESETS)
334
- memory=hash_val.clone
335
- includes=memory[EXTV_INCLUDE_PRESETS]
335
+ memory = hash_val.clone
336
+ includes = memory[EXTV_INCLUDE_PRESETS]
336
337
  memory.delete(EXTV_INCLUDE_PRESETS)
337
- hash_val={}
338
+ hash_val = {}
338
339
  raise "#{EXTV_INCLUDE_PRESETS} must be an Array" unless includes.is_a?(Array)
339
340
  raise "#{EXTV_INCLUDE_PRESETS} must contain names" unless includes.map(&:class).uniq.eql?([String])
340
341
  includes.each do |preset_name|
@@ -379,13 +380,13 @@ module Aspera
379
380
  end
380
381
 
381
382
  def convert_preset_path(old_name,new_name,files_to_copy)
382
- old_subpath=File.join('',ASPERA_HOME_FOLDER_NAME,old_name,'')
383
- new_subpath=File.join('',ASPERA_HOME_FOLDER_NAME,new_name,'')
383
+ old_subpath = File.join('',ASPERA_HOME_FOLDER_NAME,old_name,'')
384
+ new_subpath = File.join('',ASPERA_HOME_FOLDER_NAME,new_name,'')
384
385
  # convert possible keys located in config folder
385
386
  @config_presets.values.select{|p|p.is_a?(Hash)}.each do |preset|
386
- preset.values.select{|v|v.is_a?(String) and v.include?(old_subpath)}.each do |value|
387
- old_val=value.clone
388
- included_path=File.expand_path(old_val.gsub(/^@file:/,''))
387
+ preset.values.select{|v|v.is_a?(String) && v.include?(old_subpath)}.each do |value|
388
+ old_val = value.clone
389
+ included_path = File.expand_path(old_val.gsub(/^@file:/,''))
389
390
  files_to_copy.push(included_path) unless files_to_copy.include?(included_path) || !File.exist?(included_path)
390
391
  value.gsub!(old_subpath,new_subpath)
391
392
  Log.log.warn("Converted config value: #{old_val} -> #{value}")
@@ -394,9 +395,9 @@ module Aspera
394
395
  end
395
396
 
396
397
  def convert_preset_plugin_name(old_name,new_name)
397
- default_preset=@config_presets[CONF_PRESET_DEFAULT]
398
+ default_preset = @config_presets[CONF_PRESET_DEFAULT]
398
399
  return unless default_preset.is_a?(Hash) && default_preset.has_key?(old_name)
399
- default_preset[new_name]=default_preset[old_name]
400
+ default_preset[new_name] = default_preset[old_name]
400
401
  default_preset.delete(old_name)
401
402
  Log.log.warn("Converted plugin default: #{old_name} -> #{new_name}")
402
403
  end
@@ -406,65 +407,65 @@ module Aspera
406
407
  def read_config_file
407
408
  begin
408
409
  Log.log.debug("config file is: #{@option_config_file}".red)
409
- conf_file_v1=File.join(Dir.home,ASPERA_HOME_FOLDER_NAME,PROGRAM_NAME_V1,DEFAULT_CONFIG_FILENAME)
410
- conf_file_v2=File.join(Dir.home,ASPERA_HOME_FOLDER_NAME,PROGRAM_NAME_V2,DEFAULT_CONFIG_FILENAME)
410
+ conf_file_v1 = File.join(Dir.home,ASPERA_HOME_FOLDER_NAME,PROGRAM_NAME_V1,DEFAULT_CONFIG_FILENAME)
411
+ conf_file_v2 = File.join(Dir.home,ASPERA_HOME_FOLDER_NAME,PROGRAM_NAME_V2,DEFAULT_CONFIG_FILENAME)
411
412
  # files search for configuration, by default the one given by user
412
- search_files=[@option_config_file]
413
+ search_files = [@option_config_file]
413
414
  # if default file, then also look for older versions
414
415
  search_files.push(conf_file_v2,conf_file_v1) if @option_config_file.eql?(@conf_file_default)
415
416
  # find first existing file (or nil)
416
- conf_file_to_load=search_files.select{|f| File.exist?(f)}.first
417
+ conf_file_to_load = search_files.find{|f| File.exist?(f)}
417
418
  # require save if old version of file
418
- save_required= !@option_config_file.eql?(conf_file_to_load)
419
+ save_required = !@option_config_file.eql?(conf_file_to_load)
419
420
  # if no file found, create default config
420
421
  if conf_file_to_load.nil?
421
422
  Log.log.warn("No config file found. Creating empty configuration file: #{@option_config_file}")
422
- @config_presets={CONF_PRESET_CONFIG=>{CONF_PRESET_VERSION=>@info[:version]}}
423
+ @config_presets = {CONF_PRESET_CONFIG => {CONF_PRESET_VERSION => @info[:version]}}
423
424
  else
424
425
  Log.log.debug("loading #{@option_config_file}")
425
- @config_presets=YAML.load_file(conf_file_to_load)
426
+ @config_presets = YAML.load_file(conf_file_to_load)
426
427
  end
427
- files_to_copy=[]
428
+ files_to_copy = []
428
429
  Log.log.debug("Available_presets: #{@config_presets}")
429
430
  raise 'Expecting YAML Hash' unless @config_presets.is_a?(Hash)
430
431
  # check there is at least the config section
431
432
  if !@config_presets.has_key?(CONF_PRESET_CONFIG)
432
433
  raise "Cannot find key: #{CONF_PRESET_CONFIG}"
433
434
  end
434
- version=@config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]
435
+ version = @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]
435
436
  if version.nil?
436
437
  raise 'No version found in config section.'
437
438
  end
438
439
  # oldest compatible conf file format, update to latest version when an incompatible change is made
439
440
  # check compatibility of version of conf file
440
- config_tested_version='0.4.5'
441
+ config_tested_version = '0.4.5'
441
442
  if Gem::Version.new(version) < Gem::Version.new(config_tested_version)
442
443
  raise "Unsupported config file version #{version}. Expecting min version #{config_tested_version}"
443
444
  end
444
- config_tested_version='0.6.15'
445
+ config_tested_version = '0.6.15'
445
446
  if Gem::Version.new(version) < Gem::Version.new(config_tested_version)
446
447
  convert_preset_plugin_name(AOC_COMMAND_V1,AOC_COMMAND_V2)
447
- version=@config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]=config_tested_version
448
- save_required=true
448
+ version = @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = config_tested_version
449
+ save_required = true
449
450
  end
450
- config_tested_version='0.8.10'
451
+ config_tested_version = '0.8.10'
451
452
  if Gem::Version.new(version) <= Gem::Version.new(config_tested_version)
452
453
  convert_preset_path(PROGRAM_NAME_V1,PROGRAM_NAME_V2,files_to_copy)
453
- version=@config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]=config_tested_version
454
- save_required=true
454
+ version = @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = config_tested_version
455
+ save_required = true
455
456
  end
456
- config_tested_version='1.0'
457
+ config_tested_version = '1.0'
457
458
  if Gem::Version.new(version) <= Gem::Version.new(config_tested_version)
458
459
  convert_preset_plugin_name(AOC_COMMAND_V2,AOC_COMMAND_V3)
459
460
  convert_preset_path(PROGRAM_NAME_V2,@info[:name],files_to_copy)
460
- version=@config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]=config_tested_version
461
- save_required=true
461
+ version = @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = config_tested_version
462
+ save_required = true
462
463
  end
463
464
  Log.log.debug("conf version: #{version}")
464
465
  # Place new compatibility code here
465
466
  if save_required
466
467
  Log.log.warn('Saving automatic conversion.')
467
- @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]=@info[:version]
468
+ @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = @info[:version]
468
469
  save_presets_to_config_file
469
470
  Log.log.warn('Copying referenced files')
470
471
  files_to_copy.each do |file|
@@ -477,7 +478,7 @@ module Aspera
477
478
  raise e
478
479
  rescue StandardError => e
479
480
  Log.log.debug("-> #{e}")
480
- new_name="#{@option_config_file}.pre#{@info[:version]}.manual_conversion_needed"
481
+ new_name = "#{@option_config_file}.pre#{@info[:version]}.manual_conversion_needed"
481
482
  File.rename(@option_config_file,new_name)
482
483
  Log.log.warn("Renamed config file to #{new_name}.")
483
484
  Log.log.warn('Manual Conversion is required. Next time, a new empty file will be created.')
@@ -503,13 +504,13 @@ module Aspera
503
504
 
504
505
  def add_plugin_info(path)
505
506
  raise "ERROR: plugin path must end with #{RUBY_FILE_EXT}" if !path.end_with?(RUBY_FILE_EXT)
506
- plugin_symbol=File.basename(path,RUBY_FILE_EXT).to_sym
507
- req=path.gsub(/#{RUBY_FILE_EXT}$/,'')
507
+ plugin_symbol = File.basename(path,RUBY_FILE_EXT).to_sym
508
+ req = path.gsub(/#{RUBY_FILE_EXT}$/o,'')
508
509
  if @plugins.has_key?(plugin_symbol)
509
510
  Log.log.warn("skipping plugin already registered: #{plugin_symbol}")
510
511
  return
511
512
  end
512
- @plugins[plugin_symbol]={source: path,require_stanza: req}
513
+ @plugins[plugin_symbol] = {source: path,require_stanza: req}
513
514
  end
514
515
 
515
516
  def identify_plugin_for_url(url)
@@ -518,24 +519,27 @@ module Aspera
518
519
  next if plugin_name_sym.eql?(CONF_PLUGIN_SYM)
519
520
  # load plugin class
520
521
  require plugin_info[:require_stanza]
521
- c=self.class.plugin_class(plugin_name_sym)
522
+ c = self.class.plugin_class(plugin_name_sym)
522
523
  next unless c.respond_to?(:detect)
523
- current_url=url
524
- detection_info=nil
524
+ current_url = url
525
+ detection_info = nil
525
526
  # first try : direct
526
527
  begin
527
- detection_info=c.detect(current_url)
528
+ detection_info = c.detect(current_url)
529
+ rescue OpenSSL::SSL::SSLError => e
530
+ Log.log.warn(e.message)
531
+ Log.log.warn('Use option --insecure=yes to ignore certificate') if e.message.include?('cert')
528
532
  rescue StandardError => e
529
- Log.log.debug("Cannot detect #{plugin_name_sym} : #{e.message}")
533
+ Log.log.debug("Cannot detect #{plugin_name_sym} : #{e.class}/#{e.message}")
530
534
  end
531
535
  # second try : is there a redirect ?
532
536
  if detection_info.nil?
533
537
  begin
534
538
  # TODO: check if redirect ?
535
- new_url=Rest.new(base_url: url).call(operation: 'GET',subpath: '',redirect_max: 1)[:http].uri.to_s
539
+ new_url = Rest.new(base_url: url).call(operation: 'GET',subpath: '',redirect_max: 1)[:http].uri.to_s
536
540
  unless url.eql?(new_url)
537
- detection_info=c.detect(new_url)
538
- current_url=new_url
541
+ detection_info = c.detect(new_url)
542
+ current_url = new_url
539
543
  end
540
544
  rescue StandardError => e
541
545
  Log.log.debug("Cannot detect #{plugin_name_sym} : #{e.message}")
@@ -547,35 +551,35 @@ module Aspera
547
551
  end
548
552
 
549
553
  def execute_connect_action
550
- command=options.get_next_command([:list,:info,:version])
551
- if [:info,:version].include?(command)
552
- connect_id=options.get_next_argument('id or title')
553
- one_res=connect_versions.select{|i|i['id'].eql?(connect_id) || i['title'].eql?(connect_id)}.first
554
+ command = options.get_next_command(%i[list info version])
555
+ if %i[info version].include?(command)
556
+ connect_id = options.get_next_argument('id or title')
557
+ one_res = connect_versions.find{|i|i['id'].eql?(connect_id) || i['title'].eql?(connect_id)}
554
558
  raise CliNoSuchId.new(:connect,connect_id) if one_res.nil?
555
559
  end
556
560
  case command
557
561
  when :list
558
- return {type: :object_list, data: connect_versions, fields: ['id','title','version']}
562
+ return {type: :object_list, data: connect_versions, fields: %w[id title version]}
559
563
  when :info # shows files used
560
564
  one_res.delete('links')
561
565
  return {type: :single_object, data: one_res}
562
566
  when :version # shows files used
563
- all_links=one_res['links']
564
- command=options.get_next_command([:list,:download,:open])
565
- if [:download,:open].include?(command)
566
- link_title=options.get_next_argument('title or rel')
567
- one_link=all_links.select {|i| i['title'].eql?(link_title) or i['rel'].eql?(link_title)}.first
567
+ all_links = one_res['links']
568
+ command = options.get_next_command(%i[list download open])
569
+ if %i[download open].include?(command)
570
+ link_title = options.get_next_argument('title or rel')
571
+ one_link = all_links.find {|i| i['title'].eql?(link_title) || i['rel'].eql?(link_title)}
568
572
  raise 'no such value' if one_link.nil?
569
573
  end
570
574
  case command
571
575
  when :list # shows files used
572
576
  return {type: :object_list, data: all_links}
573
577
  when :download
574
- folder_dest=transfer.destination_folder(Fasp::TransferSpec::DIRECTION_RECEIVE)
578
+ folder_dest = transfer.destination_folder(Fasp::TransferSpec::DIRECTION_RECEIVE)
575
579
  #folder_dest=self.options.get_next_argument('destination folder')
576
- api_connect_cdn=Rest.new({base_url: CONNECT_WEB_URL})
580
+ api_connect_cdn = Rest.new({base_url: CONNECT_WEB_URL})
577
581
  fileurl = one_link['href']
578
- filename=fileurl.gsub(%r{.*/},'')
582
+ filename = fileurl.gsub(%r{.*/},'')
579
583
  api_connect_cdn.call({operation: 'GET',subpath: fileurl,save_to_file: File.join(folder_dest,filename)})
580
584
  return Main.result_status("Downloaded: #{filename}")
581
585
  when :open
@@ -586,60 +590,69 @@ module Aspera
586
590
  end
587
591
 
588
592
  def execute_action_ascp
589
- command=options.get_next_command([:connect,:use,:show,:products,:info,:install,:spec,:errors])
593
+ command = options.get_next_command(%i[connect use show products info install spec errors])
590
594
  case command
591
595
  when :connect
592
596
  return execute_connect_action
593
597
  when :use
594
- ascp_path=options.get_next_argument('path to ascp')
595
- ascp_version=Fasp::Installation.instance.get_ascp_version(ascp_path)
598
+ ascp_path = options.get_next_argument('path to ascp')
599
+ ascp_version = Fasp::Installation.instance.get_ascp_version(ascp_path)
596
600
  self.format.display_status("ascp version: #{ascp_version}")
597
- preset_name=set_global_default(:ascp_path,ascp_path)
601
+ preset_name = set_global_default(:ascp_path,ascp_path)
598
602
  return Main.result_status("Saved to default global preset #{preset_name}")
599
603
  when :show # shows files used
600
604
  return {type: :status, data: Fasp::Installation.instance.path(:ascp)}
601
605
  when :info # shows files used
602
- data=Fasp::Installation::FILES.each_with_object({}) do |v,m|
603
- m[v.to_s]=Fasp::Installation.instance.path(v) rescue 'Not Found'
606
+ data = Fasp::Installation::FILES.each_with_object({}) do |v,m|
607
+ m[v.to_s] =
608
+ begin
609
+ Fasp::Installation.instance.path(v)
610
+ rescue => e
611
+ e.message
612
+ end
604
613
  end
605
614
  # read PATHs from ascp directly, and pvcl modules as well
606
615
  Open3.popen3(Fasp::Installation.instance.path(:ascp),'-DDL-') do |_stdin, _stdout, stderr, thread|
607
- last_line=''
608
- while (line=stderr.gets)
616
+ last_line = ''
617
+ while (line = stderr.gets)
609
618
  line.chomp!
610
- last_line=line
619
+ last_line = line
611
620
  case line
612
- when %r{^DBG Path ([^ ]+) (dir|file) +: (.*)$} then data[Regexp.last_match(1)]=Regexp.last_match(3)
613
- when %r{^DBG Added module group:"([^"]+)" name:"([^"]+)", version:"([^"]+)" interface:"([^"]+)"$} then data[Regexp.last_match(2)]=Regexp.last_match(4)
614
- when %r{^DBG License result \(/license/(\S+)\): (.+)$} then data[Regexp.last_match(1)]=Regexp.last_match(2)
615
- when %r{^LOG (.+) version ([0-9.]+)$} then data['product_name']=Regexp.last_match(1);data['product_version']=Regexp.last_match(2)
616
- when %r{^LOG Initializing FASP version ([^,]+),} then data['ascp_version']=Regexp.last_match(1)
621
+ when %r{^DBG Path ([^ ]+) (dir|file) +: (.*)$} then data[Regexp.last_match(1)] = Regexp.last_match(3)
622
+ when %r{^DBG Added module group:"([^"]+)" name:"([^"]+)", version:"([^"]+)" interface:"([^"]+)"$} then data[Regexp.last_match(2)] = Regexp.last_match(4)
623
+ when %r{^DBG License result \(/license/(\S+)\): (.+)$} then data[Regexp.last_match(1)] = Regexp.last_match(2)
624
+ when %r{^LOG (.+) version ([0-9.]+)$} then data['product_name'] = Regexp.last_match(1);data['product_version'] = Regexp.last_match(2)
625
+ when %r{^LOG Initializing FASP version ([^,]+),} then data['ascp_version'] = Regexp.last_match(1)
617
626
  end
618
627
  end
619
628
  if !thread.value.exitstatus.eql?(1) && !data.has_key?('root')
620
629
  raise last_line
621
630
  end
622
631
  end
623
- data['keypass']=Fasp::Installation.instance.bypass_pass
632
+ data['keypass'] = Fasp::Installation.instance.bypass_pass
624
633
  return {type: :single_object, data: data}
625
634
  when :products
626
- command=options.get_next_command([:list,:use])
635
+ command = options.get_next_command(%i[list use])
627
636
  case command
628
637
  when :list
629
- return {type: :object_list, data: Fasp::Installation.instance.installed_products, fields: ['name','app_root']}
638
+ return {type: :object_list, data: Fasp::Installation.instance.installed_products, fields: %w[name app_root]}
630
639
  when :use
631
- default_product=options.get_next_argument('product name')
640
+ default_product = options.get_next_argument('product name')
632
641
  Fasp::Installation.instance.use_ascp_from_product(default_product)
633
- preset_name=set_global_default(:ascp_path,Fasp::Installation.instance.path(:ascp))
642
+ preset_name = set_global_default(:ascp_path,Fasp::Installation.instance.path(:ascp))
634
643
  return Main.result_status("Saved to default global preset #{preset_name}")
635
644
  end
636
645
  when :install
637
- v=Fasp::Installation.instance.install_sdk(options.get_option(:sdk_url,:mandatory))
646
+ v = Fasp::Installation.instance.install_sdk(options.get_option(:sdk_url,is_type: :mandatory))
638
647
  return Main.result_status("Installed version #{v}")
639
648
  when :spec
640
- return {type: :object_list, data: Fasp::Parameters.man_table, fields: ['name','type',Fasp::Parameters::SUPPORTED_AGENTS_SHORT.map(&:to_s),'description'].flatten}
649
+ return {
650
+ type: :object_list,
651
+ data: Fasp::Parameters.man_table,
652
+ fields: ['name','type',Fasp::Parameters::SUPPORTED_AGENTS_SHORT.map(&:to_s),'description'].flatten
653
+ }
641
654
  when :errors
642
- error_data=[]
655
+ error_data = []
643
656
  Fasp::ERROR_INFO.each_pair do |code,prop|
644
657
  error_data.push(code: code, mnemonic: prop[:c], retry: prop[:r], info: prop[:a])
645
658
  end
@@ -649,24 +662,24 @@ module Aspera
649
662
  end
650
663
 
651
664
  # legacy actions available globally
652
- PRESET_GBL_ACTIONS=[:list,:overview].freeze
665
+ PRESET_GBL_ACTIONS = %i[list overview].freeze
653
666
  # require existing preset
654
- PRESET_EXST_ACTIONS=[:show,:delete,:get,:unset].freeze
667
+ PRESET_EXST_ACTIONS = %i[show delete get unset].freeze
655
668
  # require id
656
- PRESET_INSTANCE_ACTIONS=[PRESET_EXST_ACTIONS,:initialize,:update,:ask,:set].flatten.freeze
657
- PRESET_ALL_ACTIONS=[PRESET_GBL_ACTIONS,PRESET_INSTANCE_ACTIONS].flatten.freeze
669
+ PRESET_INSTANCE_ACTIONS = [PRESET_EXST_ACTIONS,%i[initialize update ask set]].flatten.freeze
670
+ PRESET_ALL_ACTIONS = [PRESET_GBL_ACTIONS,PRESET_INSTANCE_ACTIONS].flatten.freeze
658
671
 
659
672
  def execute_file_action(action,config_name)
660
- action=options.get_next_command(PRESET_ALL_ACTIONS) if action.nil?
661
- config_name=instance_identifier() if config_name.nil? && PRESET_INSTANCE_ACTIONS.include?(action)
673
+ action = options.get_next_command(PRESET_ALL_ACTIONS) if action.nil?
674
+ config_name = instance_identifier if config_name.nil? && PRESET_INSTANCE_ACTIONS.include?(action)
662
675
  # those operations require existing option
663
676
  raise "no such preset: #{config_name}" if PRESET_EXST_ACTIONS.include?(action) && !@config_presets.has_key?(config_name)
664
- selected_preset=@config_presets[config_name]
677
+ selected_preset = @config_presets[config_name]
665
678
  case action
666
679
  when :list
667
680
  return {type: :value_list, data: @config_presets.keys, name: 'name'}
668
681
  when :overview
669
- return {type: :object_list, data: self.class.flatten_all_config(@config_presets)}
682
+ return {type: :object_list, data: Formater.flatten_config_overview(@config_presets)}
670
683
  when :show
671
684
  raise "no such config: #{config_name}" if selected_preset.nil?
672
685
  return {type: :single_object, data: selected_preset}
@@ -675,67 +688,67 @@ module Aspera
675
688
  save_presets_to_config_file
676
689
  return Main.result_status("Deleted: #{config_name}")
677
690
  when :get
678
- param_name=options.get_next_argument('parameter name')
679
- value=selected_preset[param_name]
691
+ param_name = options.get_next_argument('parameter name')
692
+ value = selected_preset[param_name]
680
693
  raise "no such option in preset #{config_name} : #{param_name}" if value.nil?
681
694
  case value
682
695
  when Numeric,String then return {type: :text, data: ExtendedValue.instance.evaluate(value.to_s)}
683
696
  end
684
697
  return {type: :single_object, data: value}
685
698
  when :unset
686
- param_name=options.get_next_argument('parameter name')
699
+ param_name = options.get_next_argument('parameter name')
687
700
  selected_preset.delete(param_name)
688
701
  save_presets_to_config_file
689
702
  return Main.result_status("Removed: #{config_name}: #{param_name}")
690
703
  when :set
691
- param_name=options.get_next_argument('parameter name')
692
- param_value=options.get_next_argument('parameter value')
704
+ param_name = options.get_next_argument('parameter name')
705
+ param_value = options.get_next_argument('parameter value')
693
706
  if !@config_presets.has_key?(config_name)
694
707
  Log.log.debug("no such config name: #{config_name}, initializing")
695
- selected_preset=@config_presets[config_name]={}
708
+ selected_preset = @config_presets[config_name] = {}
696
709
  end
697
710
  if selected_preset.has_key?(param_name)
698
711
  Log.log.warn("overwriting value: #{selected_preset[param_name]}")
699
712
  end
700
- selected_preset[param_name]=param_value
713
+ selected_preset[param_name] = param_value
701
714
  save_presets_to_config_file
702
715
  return Main.result_status("Updated: #{config_name}: #{param_name} <- #{param_value}")
703
716
  when :initialize
704
- config_value=options.get_next_argument('extended value (Hash)')
717
+ config_value = options.get_next_argument('extended value (Hash)')
705
718
  if @config_presets.has_key?(config_name)
706
719
  Log.log.warn("configuration already exists: #{config_name}, overwriting")
707
720
  end
708
- @config_presets[config_name]=config_value
721
+ @config_presets[config_name] = config_value
709
722
  save_presets_to_config_file
710
723
  return Main.result_status("Modified: #{@option_config_file}")
711
724
  when :update
712
725
  # get unprocessed options
713
- theopts=options.get_options_table
726
+ theopts = options.get_options_table
714
727
  Log.log.debug("opts=#{theopts}")
715
- @config_presets[config_name]||={}
728
+ @config_presets[config_name] ||= {}
716
729
  @config_presets[config_name].merge!(theopts)
717
730
  # fix bug in 4.4 (creating key "true" in "default" preset)
718
731
  @config_presets[CONF_PRESET_DEFAULT].delete(true) if @config_presets[CONF_PRESET_DEFAULT].is_a?(Hash)
719
732
  save_presets_to_config_file
720
733
  return Main.result_status("Updated: #{config_name}")
721
734
  when :ask
722
- options.ask_missing_mandatory=:yes
723
- @config_presets[config_name]||={}
724
- options.get_next_argument('option names',:multiple).each do |optionname|
725
- option_value=options.get_interactive(:option,optionname)
726
- @config_presets[config_name][optionname]=option_value
735
+ options.ask_missing_mandatory = :yes
736
+ @config_presets[config_name] ||= {}
737
+ options.get_next_argument('option names',expected: :multiple).each do |optionname|
738
+ option_value = options.get_interactive(:option,optionname)
739
+ @config_presets[config_name][optionname] = option_value
727
740
  end
728
741
  save_presets_to_config_file
729
742
  return Main.result_status("Updated: #{config_name}")
730
743
  end
731
744
  end
732
745
 
733
- ACTIONS=[PRESET_GBL_ACTIONS,:id,:preset,:open,:documentation,:genkey,:gem,:plugin,:flush_tokens,:echo,:wizard,:export_to_cli,:detect,:coffee,:ascp,:email_test,
734
- :smtp_settings,:proxy_check,:folder,:file,:check_update,:initdemo,:vault].flatten.freeze
746
+ ACTIONS = [PRESET_GBL_ACTIONS,%i[id preset open documentation genkey gem plugin flush_tokens echo wizard export_to_cli detect coffee
747
+ ascp email_test smtp_settings proxy_check folder file check_update initdemo vault]].flatten.freeze
735
748
 
736
749
  # "config" plugin
737
750
  def execute_action
738
- action=options.get_next_command(ACTIONS)
751
+ action = options.get_next_command(ACTIONS)
739
752
  case action
740
753
  when *PRESET_GBL_ACTIONS # older syntax
741
754
  return execute_file_action(action,nil)
@@ -747,31 +760,32 @@ module Aspera
747
760
  OpenApplication.instance.uri(@option_config_file.to_s) #file://
748
761
  return Main.result_nothing
749
762
  when :documentation
750
- section=options.get_next_argument('private key file path',:single,:optional)
751
- section='#'+section unless section.nil?
763
+ section = options.get_next_argument('private key file path',mandatory: false)
764
+ section = '#' + section unless section.nil?
752
765
  OpenApplication.instance.uri("#{@info[:help]}#{section}")
753
766
  return Main.result_nothing
754
767
  when :genkey # generate new rsa key
755
- private_key_path=options.get_next_argument('private key file path')
756
- generate_rsa_private_key(private_key_path,DEFAULT_PRIVKEY_LENGTH)
757
- return Main.result_status('Generated key: '+private_key_path)
768
+ private_key_path = options.get_next_argument('private key file path')
769
+ private_key_length = options.get_next_argument('size in bits',mandatory: false) || DEFAULT_PRIVKEY_LENGTH
770
+ generate_rsa_private_key(private_key_path,private_key_length)
771
+ return Main.result_status('Generated key: ' + private_key_path)
758
772
  when :echo # display the content of a value given on command line
759
- result={type: :other_struct, data: options.get_next_argument('value')}
773
+ result = {type: :other_struct, data: options.get_next_argument('value')}
760
774
  # special for csv
761
- result[:type]=:object_list if result[:data].is_a?(Array) && result[:data].first.is_a?(Hash)
775
+ result[:type] = :object_list if result[:data].is_a?(Array) && result[:data].first.is_a?(Hash)
762
776
  return result
763
777
  when :flush_tokens
764
- deleted_files=Oauth.flush_tokens
778
+ deleted_files = Oauth.flush_tokens
765
779
  return {type: :value_list, data: deleted_files, name: 'file'}
766
780
  when :plugin
767
- case options.get_next_command([:list,:create])
781
+ case options.get_next_command(%i[list create])
768
782
  when :list
769
- return {type: :object_list, data: @plugins.keys.map { |i| { 'plugin' => i.to_s, 'path' => @plugins[i][:source] } }, fields: ['plugin','path']}
783
+ return {type: :object_list, data: @plugins.keys.map { |i| { 'plugin' => i.to_s, 'path' => @plugins[i][:source] } }, fields: %w[plugin path]}
770
784
  when :create
771
- plugin_name=options.get_next_argument('name',:single,:mandatory).downcase
772
- plugin_folder=options.get_next_argument('folder',:single,:optional) || File.join(@main_folder,ASPERA_PLUGINS_FOLDERNAME)
773
- plugin_file=File.join(plugin_folder,"#{plugin_name}.rb")
774
- content=<<~END_OF_PLUGIN_CODE
785
+ plugin_name = options.get_next_argument('name',expected: :single).downcase
786
+ plugin_folder = options.get_next_argument('folder',expected: :single,mandatory: false) || File.join(@main_folder,ASPERA_PLUGINS_FOLDERNAME)
787
+ plugin_file = File.join(plugin_folder,"#{plugin_name}.rb")
788
+ content = <<~END_OF_PLUGIN_CODE
775
789
  require 'aspera/cli/plugin'
776
790
  module Aspera
777
791
  module Cli
@@ -789,159 +803,62 @@ module Aspera
789
803
  end
790
804
  when :wizard
791
805
  # interactive mode
792
- options.ask_missing_mandatory=true
806
+ options.ask_missing_mandatory = true
793
807
  # register url option
794
- BasicAuthPlugin.new(@agents.merge(skip_option_header: true))
808
+ BasicAuthPlugin.register_options(@agents)
809
+ params={}
795
810
  # get from option, or ask
796
- instance_url=options.get_option(:url,:mandatory)
811
+ params[:instance_url] = options.get_option(:url,is_type: :mandatory)
797
812
  # allow user to tell the preset name
798
- preset_name=options.get_option(:id,:optional)
813
+ params[:preset_name] = options.get_option(:id)
799
814
  # allow user to specify type of application
800
- application=options.get_option(:value,:optional)
801
- application=application.nil? ? identify_plugin_for_url(instance_url)[:product] : application.to_sym
802
- plugin_name='<replace per app>'
803
- test_args='<replace per app>'
804
- case application
815
+ params[:application] = options.get_option(:value)
816
+ params[:application] = params[:application].nil? ? identify_plugin_for_url(params[:instance_url])[:product] : params[:application].to_sym
817
+ params[:plugin_name]=params[:application]
818
+ params[:test_args] = '<replace per app>'
819
+ case params[:application]
820
+ when :faspex5
821
+ wizard_faspex5(params)
805
822
  when :aoc
806
- self.format.display_status('Detected: Aspera on Cloud'.bold)
807
- plugin_name=AOC_COMMAND_CURRENT
808
- organization=AoC.parse_url(instance_url).first
809
- # if not defined by user, generate name
810
- preset_name=[application,organization].join('_') if preset_name.nil?
811
- self.format.display_status("Preparing preset: #{preset_name}")
812
- # init defaults if necessary
813
- @config_presets[CONF_PRESET_DEFAULT]||={}
814
- option_override=options.get_option(:override,:mandatory)
815
- option_default=options.get_option(:default,:mandatory)
816
- Log.log.error("override=#{option_override} -> #{option_override.class}")
817
- raise CliError,"A default configuration already exists for plugin '#{plugin_name}' (use --override=yes or --default=no)" if !option_override && option_default && @config_presets[CONF_PRESET_DEFAULT].has_key?(plugin_name)
818
- raise CliError,"Preset already exists: #{preset_name} (use --override=yes or --id=<name>)" if !option_override && @config_presets.has_key?(preset_name)
819
- # lets see if path to priv key is provided
820
- private_key_path=options.get_option(:pkeypath,:optional)
821
- # give a chance to provide
822
- if private_key_path.nil?
823
- self.format.display_status('Please provide path to your private RSA key, or empty to generate one:')
824
- private_key_path=options.get_option(:pkeypath,:mandatory).to_s
825
- end
826
- # else generate path
827
- if private_key_path.empty?
828
- private_key_path=File.join(@main_folder,DEFAULT_PRIV_KEY_FILENAME)
829
- end
830
- if File.exist?(private_key_path)
831
- self.format.display_status('Using existing key:')
832
- else
833
- self.format.display_status("Generating #{DEFAULT_PRIVKEY_LENGTH} bit RSA key...")
834
- generate_rsa_private_key(private_key_path,DEFAULT_PRIVKEY_LENGTH)
835
- self.format.display_status('Created:')
836
- end
837
- self.format.display_status(private_key_path)
838
- pub_key_pem=OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
839
- # declare command line options for AoC
840
- require 'aspera/cli/plugins/aoc'
841
- # make username mandatory for jwt, this triggers interactive input
842
- options.get_option(:username,:mandatory)
843
- # instanciate AoC plugin, so that command line options are known
844
- aoc_api=self.class.plugin_class(plugin_name).new(@agents.merge({skip_basic_auth_options: true, private_key_path: private_key_path})).aoc_api
845
- auto_set_pub_key=false
846
- auto_set_jwt=false
847
- use_browser_authentication=false
848
- if options.get_option(:use_generic_client)
849
- self.format.display_status('Using global client_id.')
850
- self.format.display_status('Please Login to your Aspera on Cloud instance.'.red)
851
- self.format.display_status('Navigate to your "Account Settings"'.red)
852
- self.format.display_status('Check or update the value of "Public Key" to be:'.red.blink)
853
- self.format.display_status(pub_key_pem.to_s)
854
- if !options.get_option(:test_mode)
855
- self.format.display_status('Once updated or validated, press enter.')
856
- OpenApplication.instance.uri(instance_url)
857
- $stdin.gets
858
- end
859
- else
860
- self.format.display_status('Using organization specific client_id.')
861
- if options.get_option(:client_id,:optional).nil? || options.get_option(:client_secret,:optional).nil?
862
- self.format.display_status('Please login to your Aspera on Cloud instance.'.red)
863
- self.format.display_status('Go to: Apps->Admin->Organization->Integrations')
864
- self.format.display_status('Create or check if there is an existing integration named:')
865
- self.format.display_status("- name: #{@info[:name]}")
866
- self.format.display_status("- redirect uri: #{DEFAULT_REDIRECT}")
867
- self.format.display_status('- origin: localhost')
868
- self.format.display_status('Once created or identified,')
869
- self.format.display_status('Please enter:'.red)
870
- end
871
- OpenApplication.instance.uri("#{instance_url}/#{AOC_PATH_API_CLIENTS}")
872
- options.get_option(:client_id,:mandatory)
873
- options.get_option(:client_secret,:mandatory)
874
- use_browser_authentication=true
875
- end
876
- if use_browser_authentication
877
- self.format.display_status('We will use web authentication to bootstrap.')
878
- auto_set_pub_key=true
879
- auto_set_jwt=true
880
- aoc_api.oauth.params[:crtype]=:web
881
- aoc_api.oauth.params[:web][:redirect_uri]=DEFAULT_REDIRECT
882
- aoc_api.oauth.params[:scope]=AoC::SCOPE_FILES_ADMIN
883
- end
884
- myself=aoc_api.read('self')[:data]
885
- if auto_set_pub_key
886
- raise CliError,'Public key is already set in profile (use --override=yes)' unless myself['public_key'].empty? || option_override
887
- self.format.display_status('Updating profile with new key')
888
- aoc_api.update("users/#{myself['id']}",{'public_key'=>pub_key_pem})
889
- end
890
- if auto_set_jwt
891
- self.format.display_status('Enabling JWT for client')
892
- aoc_api.update("clients/#{options.get_option(:client_id)}",{'jwt_grant_enabled'=>true,'explicit_authorization_required'=>false})
893
- end
894
- self.format.display_status("Creating new config preset: #{preset_name}")
895
- @config_presets[preset_name]={
896
- :url.to_s =>options.get_option(:url),
897
- :username.to_s =>myself['email'],
898
- :auth.to_s =>:jwt.to_s,
899
- :private_key.to_s =>'@file:'+private_key_path
900
- }
901
- # set only if non nil
902
- [:client_id,:client_secret].each do |s|
903
- o=options.get_option(s)
904
- @config_presets[preset_name][s.to_s] = o unless o.nil?
905
- end
906
- test_args="#{plugin_name} user profile show"
823
+ wizard_aoc(params)
907
824
  else
908
- raise CliBadArgument,"Supports only: aoc. Detected: #{application}"
825
+ raise CliBadArgument,"Supports only: aoc. Detected: #{params[:application]}"
909
826
  end # product
910
- if option_default
911
- self.format.display_status("Setting config preset as default for #{plugin_name}")
912
- @config_presets[CONF_PRESET_DEFAULT][plugin_name]=preset_name
827
+ if params[:option_default]
828
+ self.format.display_status("Setting config preset as default for #{params[:plugin_name]}")
829
+ @config_presets[CONF_PRESET_DEFAULT][params[:plugin_name]] = params[:preset_name]
913
830
  else
914
- test_args="-P#{preset_name} #{test_args}"
831
+ params[:test_args] = "-P#{params[:preset_name]} #{params[:test_args]}"
915
832
  end
916
833
  self.format.display_status('Saving config file.')
917
834
  save_presets_to_config_file
918
- return Main.result_status("Done.\nYou can test with:\n#{@info[:name]} #{test_args}")
919
- when :export_to_cli
835
+ return Main.result_status("Done.\nYou can test with:\n#{@info[:name]} #{params[:test_args]}")
836
+ when :export_to_cli # this method shall be deprecated in the future: it was used to export configuration to "aspera.exe" CLI
920
837
  self.format.display_status('Exporting: Aspera on Cloud')
921
838
  require 'aspera/cli/plugins/aoc'
922
839
  # need url / username
923
840
  add_plugin_default_preset(AOC_COMMAND_V3.to_sym)
924
841
  # instanciate AoC plugin
925
842
  self.class.plugin_class(AOC_COMMAND_CURRENT).new(@agents) # TODO: is this line needed ? get options ?
926
- url=options.get_option(:url,:mandatory)
927
- cli_conf_file=Fasp::Installation.instance.cli_conf_file
928
- data=JSON.parse(File.read(cli_conf_file))
929
- organization,instance_domain=AoC.parse_url(url)
930
- key_basename='org_'+organization+'.pem'
931
- key_file=File.join(File.dirname(File.dirname(cli_conf_file)),'etc',key_basename)
932
- File.write(key_file,options.get_option(:private_key,:mandatory))
933
- new_conf={
843
+ url = options.get_option(:url,is_type: :mandatory)
844
+ cli_conf_file = Fasp::Installation.instance.cli_conf_file
845
+ data = JSON.parse(File.read(cli_conf_file))
846
+ organization,instance_domain = AoC.parse_url(url)
847
+ key_basename = 'org_' + organization + '.pem'
848
+ key_file = File.join(File.dirname(File.dirname(cli_conf_file)),'etc',key_basename)
849
+ File.write(key_file,options.get_option(:private_key,is_type: :mandatory))
850
+ new_conf = {
934
851
  'organization' => organization,
935
852
  'hostname' => [organization,instance_domain].join('.'),
936
853
  'privateKeyFilename' => key_basename,
937
- 'username' => options.get_option(:username,:mandatory)
854
+ 'username' => options.get_option(:username,is_type: :mandatory)
938
855
  }
939
- new_conf['clientId']=options.get_option(:client_id,:optional)
940
- new_conf['clientSecret']=options.get_option(:client_secret,:optional)
856
+ new_conf['clientId'] = options.get_option(:client_id)
857
+ new_conf['clientSecret'] = options.get_option(:client_secret)
941
858
  if new_conf['clientId'].nil?
942
- new_conf['clientId'],new_conf['clientSecret']=AoC.get_client_info()
859
+ new_conf['clientId'],new_conf['clientSecret'] = AoC.get_client_info
943
860
  end
944
- entry=data['AoCAccounts'].select{|i|i['organization'].eql?(organization)}.first
861
+ entry = data['AoCAccounts'].find{|i|i['organization'].eql?(organization)}
945
862
  if entry.nil?
946
863
  data['AoCAccounts'].push(new_conf)
947
864
  self.format.display_status("Creating new aoc entry: #{organization}")
@@ -953,15 +870,15 @@ module Aspera
953
870
  return Main.result_status("Updated: #{cli_conf_file}")
954
871
  when :detect
955
872
  # need url / username
956
- BasicAuthPlugin.new(@agents)
957
- return {type: :single_object, data: identify_plugin_for_url(options.get_option(:url,:mandatory))}
873
+ BasicAuthPlugin.register_options(@agents)
874
+ return {type: :single_object, data: identify_plugin_for_url(options.get_option(:url,is_type: :mandatory))}
958
875
  when :coffee
959
876
  OpenApplication.instance.uri('https://enjoyjava.com/wp-content/uploads/2018/01/How-to-make-strong-coffee.jpg')
960
877
  return Main.result_nothing
961
878
  when :ascp
962
879
  execute_action_ascp
963
880
  when :gem
964
- case options.get_next_command([:path,:version,:name])
881
+ case options.get_next_command(%i[path version name])
965
882
  when :path then return Main.result_status(self.class.gem_src_root)
966
883
  when :version then return Main.result_status(Aspera::Cli::VERSION)
967
884
  when :name then return Main.result_status(@info[:gem])
@@ -977,8 +894,8 @@ module Aspera
977
894
  return {type: :single_object, data: email_settings}
978
895
  when :proxy_check
979
896
  # ensure fpac was provided
980
- options.get_option(:fpac,:mandatory)
981
- server_url=options.get_next_argument('server url')
897
+ options.get_option(:fpac,is_type: :mandatory)
898
+ server_url = options.get_next_argument('server url')
982
899
  return Main.result_status(@pac_exec.find_proxy_for_url(server_url))
983
900
  when :check_update
984
901
  return {type: :single_object, data: check_gem_version}
@@ -987,28 +904,32 @@ module Aspera
987
904
  Log.log.warn("Demo server preset already present: #{DEMO_SERVER_PRESET}")
988
905
  else
989
906
  Log.log.info("Creating Demo server preset: #{DEMO_SERVER_PRESET}")
990
- @config_presets[DEMO_SERVER_PRESET]=
991
- {'url'=>'ssh://'+DEMO+'.asperasoft.com:33001','username'=>AOC_COMMAND_V2,'ssAP'.downcase.reverse+'drow'.reverse=>DEMO+AOC_COMMAND_V2}
907
+ @config_presets[DEMO_SERVER_PRESET] = {
908
+ 'url' => 'ssh://' + DEMO + '.asperasoft.com:33001',
909
+ 'username' => AOC_COMMAND_V2,
910
+ 'ssAP'.downcase.reverse + 'drow'.reverse => DEMO + AOC_COMMAND_V2
911
+ }
992
912
  end
993
- @config_presets[CONF_PRESET_DEFAULT]||={}
913
+ @config_presets[CONF_PRESET_DEFAULT] ||= {}
994
914
  if @config_presets[CONF_PRESET_DEFAULT].has_key?(SERVER_COMMAND)
995
915
  Log.log.warn("Server default preset already set to: #{@config_presets[CONF_PRESET_DEFAULT][SERVER_COMMAND]}")
996
- Log.log.warn("Use #{DEMO_SERVER_PRESET} for demo: -P#{DEMO_SERVER_PRESET}") unless DEMO_SERVER_PRESET.eql?(@config_presets[CONF_PRESET_DEFAULT][SERVER_COMMAND])
916
+ Log.log.warn("Use #{DEMO_SERVER_PRESET} for demo: -P#{DEMO_SERVER_PRESET}") unless
917
+ DEMO_SERVER_PRESET.eql?(@config_presets[CONF_PRESET_DEFAULT][SERVER_COMMAND])
997
918
  else
998
- @config_presets[CONF_PRESET_DEFAULT][SERVER_COMMAND]=DEMO_SERVER_PRESET
919
+ @config_presets[CONF_PRESET_DEFAULT][SERVER_COMMAND] = DEMO_SERVER_PRESET
999
920
  Log.log.info("Setting server default preset to : #{DEMO_SERVER_PRESET}")
1000
921
  end
1001
922
  save_presets_to_config_file
1002
923
  return Main.result_status('Done')
1003
924
  when :vault
1004
- command=options.get_next_command([:init,:list,:get,:set,:delete])
925
+ command = options.get_next_command(%i[init list get set delete])
1005
926
  case command
1006
927
  when :init
1007
- type=options.get_option(:value,:optional)
928
+ type = options.get_option(:value)
1008
929
  case type
1009
930
  when 'config',NilClass
1010
931
  raise 'default secrets already exists' if @config_presets.has_key?(CONF_PRESET_SECRETS)
1011
- @config_presets[CONF_PRESET_SECRETS]={}
932
+ @config_presets[CONF_PRESET_SECRETS] = {}
1012
933
  set_global_default(:secrets,"@preset:#{CONF_PRESET_SECRETS}")
1013
934
  else raise 'no such vault type'
1014
935
  end
@@ -1017,26 +938,26 @@ module Aspera
1017
938
  return {type: :object_list, data: vault.list}
1018
939
  when :set
1019
940
  # register url option
1020
- BasicAuthPlugin.new(@agents.merge(skip_option_header: true))
1021
- username=options.get_option(:username,:mandatory)
1022
- url=options.get_option(:url,:mandatory)
1023
- description=options.get_option(:value,:optional)
1024
- secret=options.get_next_argument('secret')
941
+ BasicAuthPlugin.register_options(@agents)
942
+ username = options.get_option(:username,is_type: :mandatory)
943
+ url = options.get_option(:url,is_type: :mandatory)
944
+ description = options.get_option(:value)
945
+ secret = options.get_next_argument('secret')
1025
946
  vault.set(username: username, url: url, description: description, secret: secret)
1026
947
  save_presets_to_config_file if vault.is_a?(Keychain::EncryptedHash)
1027
948
  return Main.result_status('Done')
1028
949
  when :get
1029
950
  # register url option
1030
- BasicAuthPlugin.new(@agents.merge(skip_option_header: true))
1031
- username=options.get_option(:username,:mandatory)
1032
- url=options.get_option(:url,:optional)
1033
- result=vault.get(username: username, url: url)
951
+ BasicAuthPlugin.register_options(@agents)
952
+ username = options.get_option(:username,is_type: :mandatory)
953
+ url = options.get_option(:url)
954
+ result = vault.get(username: username, url: url)
1034
955
  return {type: :single_object, data: result}
1035
956
  when :delete
1036
957
  # register url option
1037
- BasicAuthPlugin.new(@agents.merge(skip_option_header: true))
1038
- username=options.get_option(:username,:mandatory)
1039
- url=options.get_option(:url,:optional)
958
+ BasicAuthPlugin.register_options(@agents)
959
+ username = options.get_option(:username,is_type: :mandatory)
960
+ url = options.get_option(:url)
1040
961
  vault.delete(username: username, url: url)
1041
962
  return Main.result_status('Done')
1042
963
  end
@@ -1046,17 +967,17 @@ module Aspera
1046
967
 
1047
968
  # @return email server setting with defaults if not defined
1048
969
  def email_settings
1049
- smtp=options.get_option(:smtp,:mandatory)
970
+ smtp = options.get_option(:smtp,is_type: :mandatory)
1050
971
  # change string keys into symbol keys
1051
- smtp=smtp.keys.each_with_object({}){|v,m|m[v.to_sym]=smtp[v];}
972
+ smtp = smtp.keys.each_with_object({}){|v,m|m[v.to_sym] = smtp[v];}
1052
973
  # defaults
1053
- smtp[:tls]||=true
1054
- smtp[:port]||=smtp[:tls]?587:25
1055
- smtp[:from_email]||=smtp[:username] if smtp.has_key?(:username)
1056
- smtp[:from_name]||=smtp[:from_email].gsub(/@.*$/,'').gsub(/[^a-zA-Z]/,' ').capitalize if smtp.has_key?(:username)
1057
- smtp[:domain]||=smtp[:from_email].gsub(/^.*@/,'') if smtp.has_key?(:from_email)
974
+ smtp[:tls] ||= true
975
+ smtp[:port] ||= smtp[:tls] ? 587 : 25
976
+ smtp[:from_email] ||= smtp[:username] if smtp.has_key?(:username)
977
+ smtp[:from_name] ||= smtp[:from_email].gsub(/@.*$/,'').gsub(/[^a-zA-Z]/,' ').capitalize if smtp.has_key?(:username)
978
+ smtp[:domain] ||= smtp[:from_email].gsub(/^.*@/,'') if smtp.has_key?(:from_email)
1058
979
  # check minimum required
1059
- [:server,:port,:domain].each do |n|
980
+ %i[server port domain].each do |n|
1060
981
  raise "Missing smtp parameter: #{n}" unless smtp.has_key?(n)
1061
982
  end
1062
983
  Log.log.debug("smtp=#{smtp}")
@@ -1069,25 +990,25 @@ module Aspera
1069
990
  end
1070
991
 
1071
992
  def send_email_template(vars,email_template_default=nil)
1072
- vars[:to]||=options.get_option(:notif_to,:mandatory)
1073
- notif_template=options.get_option(:notif_template,email_template_default.nil? ? :mandatory : :optional) || email_template_default
1074
- mail_conf=email_settings
1075
- vars[:from_name]||=mail_conf[:from_name]
1076
- vars[:from_email]||=mail_conf[:from_email]
1077
- [:from_name,:from_email].each do |n|
993
+ vars[:to] ||= options.get_option(:notif_to,is_type: :mandatory)
994
+ notif_template = options.get_option(:notif_template,is_type: email_template_default.nil? ? :mandatory : :optional) || email_template_default
995
+ mail_conf = email_settings
996
+ vars[:from_name] ||= mail_conf[:from_name]
997
+ vars[:from_email] ||= mail_conf[:from_email]
998
+ %i[from_name from_email].each do |n|
1078
999
  raise "Missing email parameter: #{n}" unless vars.has_key?(n)
1079
1000
  end
1080
- start_options=[mail_conf[:domain]]
1001
+ start_options = [mail_conf[:domain]]
1081
1002
  start_options.push(mail_conf[:username],mail_conf[:password],:login) if mail_conf.has_key?(:username) && mail_conf.has_key?(:password)
1082
1003
  # create a binding with only variables defined in vars
1083
- template_binding=empty_binding
1004
+ template_binding = empty_binding
1084
1005
  # add variables to binding
1085
1006
  vars.each do |k,v|
1086
1007
  raise "key (#{k.class}) must be Symbol" unless k.is_a?(Symbol)
1087
1008
  template_binding.local_variable_set(k,v)
1088
1009
  end
1089
1010
  # execute template
1090
- msg_with_headers=ERB.new(notif_template).result(template_binding)
1011
+ msg_with_headers = ERB.new(notif_template).result(template_binding)
1091
1012
  Log.dump(:msg_with_headers,msg_with_headers)
1092
1013
  smtp = Net::SMTP.new(mail_conf[:server], mail_conf[:port])
1093
1014
  smtp.enable_starttls if mail_conf[:tls]
@@ -1113,9 +1034,11 @@ module Aspera
1113
1034
  end
1114
1035
  if @config_presets.has_key?(CONF_PRESET_DEFAULT) &&
1115
1036
  @config_presets[CONF_PRESET_DEFAULT].has_key?(plugin_sym.to_s)
1116
- default_config_name=@config_presets[CONF_PRESET_DEFAULT][plugin_sym.to_s]
1037
+ default_config_name = @config_presets[CONF_PRESET_DEFAULT][plugin_sym.to_s]
1117
1038
  if !@config_presets.has_key?(default_config_name)
1118
- Log.log.error("Default config name [#{default_config_name}] specified for plugin [#{plugin_sym}], but it does not exist in config file.\nPlease fix the issue: either create preset with one parameter (#{@info[:name]} config id #{default_config_name} init @json:'{}') or remove default (#{@info[:name]} config id default remove #{plugin_sym}).")
1039
+ Log.log.error("Default config name [#{default_config_name}] specified for plugin [#{plugin_sym}], but it does not exist in config file.\n"\
1040
+ 'Please fix the issue: either create preset with one parameter: '\
1041
+ "(#{@info[:name]} config id #{default_config_name} init @json:'{}') or remove default (#{@info[:name]} config id default remove #{plugin_sym}).")
1119
1042
  end
1120
1043
  raise CliError,"Config name [#{default_config_name}] must be a hash, check config file." if !@config_presets[default_config_name].is_a?(Hash)
1121
1044
  return default_config_name
@@ -1125,15 +1048,15 @@ module Aspera
1125
1048
 
1126
1049
  def vault
1127
1050
  if @vault.nil?
1128
- vault_info=options.get_option(:secrets,:optional)
1051
+ vault_info = options.get_option(:secrets)
1129
1052
  case vault_info
1130
1053
  when Hash
1131
- @vault=Keychain::EncryptedHash.new(vault_info)
1054
+ @vault = Keychain::EncryptedHash.new(vault_info)
1132
1055
  when /^system/
1133
- name=vault_info.start_with?('system:') ? vault_info[7..-1] : nil
1056
+ name = vault_info.start_with?('system:') ? vault_info[7..-1] : nil
1134
1057
  case Environment.os
1135
1058
  when Environment::OS_X
1136
- @vault=Keychain::MacosSecurity.new(name)
1059
+ @vault = Keychain::MacosSecurity.new(name)
1137
1060
  when Environment::OS_WINDOWS,Environment::OS_LINUX,Environment::OS_AIX
1138
1061
  raise 'not implemented'
1139
1062
  else raise 'Error'
@@ -1151,14 +1074,177 @@ module Aspera
1151
1074
  def get_secret(options)
1152
1075
  raise 'options shall be Hash' unless options.is_a?(Hash)
1153
1076
  raise 'options shall have username' unless options.has_key?(:username)
1154
- secret=self.options.get_option(:secret,:optional)
1077
+ secret = self.options.get_option(:secret)
1155
1078
  if secret.nil?
1156
- secret=vault.get(options) rescue nil
1079
+ secret = vault.get(options) rescue nil
1157
1080
  # mandatory by default
1158
1081
  raise "please provide secret for #{options[:username]}" if secret.nil? && (options[:mandatory].nil? || options[:mandatory])
1159
1082
  end
1160
1083
  return secret
1161
1084
  end
1085
+
1086
+ def wizard_aoc(params)
1087
+ self.format.display_status('Detected: Aspera on Cloud'.bold)
1088
+ params[:plugin_name] = AOC_COMMAND_CURRENT
1089
+ organization = AoC.parse_url(params[:instance_url]).first
1090
+ # if not defined by user, generate name
1091
+ params[:preset_name] = [params[:application],organization].join('_') if params[:preset_name].nil?
1092
+ self.format.display_status("Preparing preset: #{params[:preset_name]}")
1093
+ # init defaults if necessary
1094
+ @config_presets[CONF_PRESET_DEFAULT] ||= {}
1095
+ option_override = options.get_option(:override,is_type: :mandatory)
1096
+ params[:option_default] = options.get_option(:default,is_type: :mandatory)
1097
+ Log.log.error("override=#{option_override} -> #{option_override.class}")
1098
+ raise CliError,"A default configuration already exists for plugin '#{params[:plugin_name]}' (use --override=yes or --default=no)" \
1099
+ if !option_override && params[:option_default] && @config_presets[CONF_PRESET_DEFAULT].has_key?(params[:plugin_name])
1100
+ raise CliError,"Preset already exists: #{params[:preset_name]} (use --override=yes or --id=<name>)" \
1101
+ if !option_override && @config_presets.has_key?(params[:preset_name])
1102
+ # lets see if path to priv key is provided
1103
+ private_key_path = options.get_option(:pkeypath)
1104
+ # give a chance to provide
1105
+ if private_key_path.nil?
1106
+ self.format.display_status('Please provide path to your private RSA key, or empty to generate one:')
1107
+ private_key_path = options.get_option(:pkeypath,is_type: :mandatory).to_s
1108
+ end
1109
+ # else generate path
1110
+ if private_key_path.empty?
1111
+ private_key_path = File.join(@main_folder,DEFAULT_PRIV_KEY_FILENAME)
1112
+ end
1113
+ if File.exist?(private_key_path)
1114
+ self.format.display_status('Using existing key:')
1115
+ else
1116
+ self.format.display_status("Generating #{DEFAULT_PRIVKEY_LENGTH} bit RSA key...")
1117
+ generate_rsa_private_key(private_key_path,DEFAULT_PRIVKEY_LENGTH)
1118
+ self.format.display_status('Created:')
1119
+ end
1120
+ self.format.display_status(private_key_path)
1121
+ pub_key_pem = OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
1122
+ # declare command line options for AoC
1123
+ require 'aspera/cli/plugins/aoc'
1124
+ # make username mandatory for jwt, this triggers interactive input
1125
+ options.get_option(:username,is_type: :mandatory)
1126
+ # instanciate AoC plugin, so that command line options are known
1127
+ aoc_api = self.class.plugin_class(params[:plugin_name]).new(@agents.merge({skip_basic_auth_options: true, private_key_path: private_key_path})).aoc_api
1128
+ auto_set_pub_key = false
1129
+ auto_set_jwt = false
1130
+ use_browser_authentication = false
1131
+ if options.get_option(:use_generic_client)
1132
+ self.format.display_status('Using global client_id.')
1133
+ self.format.display_status('Please Login to your Aspera on Cloud instance.'.red)
1134
+ self.format.display_status('Navigate to your "Account Settings"'.red)
1135
+ self.format.display_status('Check or update the value of "Public Key" to be:'.red.blink)
1136
+ self.format.display_status(pub_key_pem.to_s)
1137
+ if !options.get_option(:test_mode)
1138
+ self.format.display_status('Once updated or validated, press enter.')
1139
+ OpenApplication.instance.uri(params[:instance_url])
1140
+ $stdin.gets
1141
+ end
1142
+ else
1143
+ self.format.display_status('Using organization specific client_id.')
1144
+ if options.get_option(:client_id).nil? || options.get_option(:client_secret,is_type: :optional).nil?
1145
+ self.format.display_status('Please login to your Aspera on Cloud instance.'.red)
1146
+ self.format.display_status('Go to: Apps->Admin->Organization->Integrations')
1147
+ self.format.display_status('Create or check if there is an existing integration named:')
1148
+ self.format.display_status("- name: #{@info[:name]}")
1149
+ self.format.display_status("- redirect uri: #{DEFAULT_REDIRECT}")
1150
+ self.format.display_status('- origin: localhost')
1151
+ self.format.display_status('Once created or identified,')
1152
+ self.format.display_status('Please enter:'.red)
1153
+ end
1154
+ OpenApplication.instance.uri("#{params[:instance_url]}/#{AOC_PATH_API_CLIENTS}")
1155
+ options.get_option(:client_id,is_type: :mandatory)
1156
+ options.get_option(:client_secret,is_type: :mandatory)
1157
+ use_browser_authentication = true
1158
+ end
1159
+ if use_browser_authentication
1160
+ self.format.display_status('We will use web authentication to bootstrap.')
1161
+ auto_set_pub_key = true
1162
+ auto_set_jwt = true
1163
+ aoc_api.oauth.gparams[:crtype] = :web
1164
+ aoc_api.oauth.gparams[:scope] = AoC::SCOPE_FILES_ADMIN
1165
+ aoc_api.oauth.sparams[:redirect_uri] = DEFAULT_REDIRECT
1166
+ end
1167
+ myself = aoc_api.read('self')[:data]
1168
+ if auto_set_pub_key
1169
+ raise CliError,'Public key is already set in profile (use --override=yes)' unless myself['public_key'].empty? || option_override
1170
+ self.format.display_status('Updating profile with new key')
1171
+ aoc_api.update("users/#{myself['id']}",{'public_key' => pub_key_pem})
1172
+ end
1173
+ if auto_set_jwt
1174
+ self.format.display_status('Enabling JWT for client')
1175
+ aoc_api.update("clients/#{options.get_option(:client_id)}",{'jwt_grant_enabled' => true,'explicit_authorization_required' => false})
1176
+ end
1177
+ self.format.display_status("Creating new config preset: #{params[:preset_name]}")
1178
+ @config_presets[params[:preset_name]] = {
1179
+ :url.to_s => options.get_option(:url),
1180
+ :username.to_s => myself['email'],
1181
+ :auth.to_s => :jwt.to_s,
1182
+ :private_key.to_s => '@file:' + private_key_path
1183
+ }
1184
+ # set only if non nil
1185
+ %i[client_id client_secret].each do |s|
1186
+ o = options.get_option(s)
1187
+ @config_presets[params[:preset_name]][s.to_s] = o unless o.nil?
1188
+ end
1189
+ params[:test_args] = "#{params[:plugin_name]} user profile show"
1190
+ end
1191
+
1192
+ def wizard_faspex5(params)
1193
+ self.format.display_status('Detected: Faspex v5'.bold)
1194
+ # if not defined by user, generate unique name
1195
+ params[:preset_name] = [params[:application],URI.parse(params[:instance_url]).host.gsub(/[^a-z0-9.]/,'').split('.')].flatten.join('_') \
1196
+ if params[:preset_name].nil?
1197
+ self.format.display_status("Preparing preset: #{params[:preset_name]}")
1198
+ # init defaults if necessary
1199
+ @config_presets[CONF_PRESET_DEFAULT] ||= {}
1200
+ option_override = options.get_option(:override,is_type: :mandatory)
1201
+ params[:option_default] = options.get_option(:default,is_type: :mandatory)
1202
+ Log.log.error("override=#{option_override} -> #{option_override.class}")
1203
+ raise CliError,"A default configuration already exists for plugin '#{params[:plugin_name]}' (use --override=yes or --default=no)" \
1204
+ if !option_override && params[:option_default] && @config_presets[CONF_PRESET_DEFAULT].has_key?(params[:plugin_name])
1205
+ raise CliError,"Preset already exists: #{params[:preset_name]} (use --override=yes or --id=<name>)" \
1206
+ if !option_override && @config_presets.has_key?(params[:preset_name])
1207
+ # lets see if path to priv key is provided
1208
+ private_key_path = options.get_option(:pkeypath)
1209
+ # give a chance to provide
1210
+ if private_key_path.nil?
1211
+ self.format.display_status('Please provide path to your private RSA key, or empty to generate one:')
1212
+ private_key_path = options.get_option(:pkeypath,is_type: :mandatory).to_s
1213
+ end
1214
+ # else generate path
1215
+ if private_key_path.empty?
1216
+ private_key_path = File.join(@main_folder,DEFAULT_PRIV_KEY_FILENAME)
1217
+ end
1218
+ if File.exist?(private_key_path)
1219
+ self.format.display_status('Using existing key:')
1220
+ else
1221
+ self.format.display_status("Generating #{DEFAULT_PRIVKEY_LENGTH} bit RSA key...")
1222
+ generate_rsa_private_key(private_key_path,DEFAULT_PRIVKEY_LENGTH)
1223
+ self.format.display_status('Created:')
1224
+ end
1225
+ self.format.display_status(private_key_path)
1226
+ pub_key_pem = OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
1227
+ # declare command line options for AoC
1228
+ require 'aspera/cli/plugins/faspex5'
1229
+ self.class.plugin_class(params[:plugin_name]).new(@agents.merge({skip_basic_auth_options: true}))
1230
+ self.format.display_status('Please login to Faspex 5.'.red)
1231
+ OpenApplication.instance.uri(params[:instance_url])
1232
+ self.format.display_status('Navigate to: 𓃑 → Admin → Configurations → API clients')
1233
+ self.format.display_status('Create a client with:')
1234
+ self.format.display_status('- JWT enabled')
1235
+ self.format.display_status('- The following public key:')
1236
+ self.format.display_status(pub_key_pem.to_s)
1237
+ self.format.display_status('Once created, copy the following parameters:')
1238
+ @config_presets[params[:preset_name]] = {
1239
+ :url.to_s => options.get_option(:url),
1240
+ :username.to_s => options.get_option(:username),
1241
+ :auth.to_s => :jwt.to_s,
1242
+ :private_key.to_s => '@file:' + private_key_path,
1243
+ :client_id.to_s => options.get_option(:client_id,is_type: :mandatory),
1244
+ :client_secret.to_s => options.get_option(:client_secret,is_type: :mandatory)
1245
+ }
1246
+ params[:test_args] = "#{params[:plugin_name]} user profile show"
1247
+ end
1162
1248
  end
1163
1249
  end
1164
1250
  end