aspera-cli 4.6.0 → 4.7.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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +427 -300
  3. data/bin/ascli +2 -1
  4. data/bin/asession +1 -0
  5. data/docs/test_env.conf +2 -0
  6. data/examples/aoc.rb +4 -3
  7. data/examples/faspex4.rb +21 -19
  8. data/examples/proxy.pac +1 -1
  9. data/examples/transfer.rb +15 -15
  10. data/lib/aspera/aoc.rb +135 -124
  11. data/lib/aspera/ascmd.rb +85 -75
  12. data/lib/aspera/ats_api.rb +11 -10
  13. data/lib/aspera/cli/basic_auth_plugin.rb +13 -14
  14. data/lib/aspera/cli/extended_value.rb +42 -33
  15. data/lib/aspera/cli/formater.rb +138 -111
  16. data/lib/aspera/cli/info.rb +17 -0
  17. data/lib/aspera/cli/listener/line_dump.rb +3 -2
  18. data/lib/aspera/cli/listener/logger.rb +2 -1
  19. data/lib/aspera/cli/listener/progress.rb +16 -18
  20. data/lib/aspera/cli/listener/progress_multi.rb +13 -16
  21. data/lib/aspera/cli/main.rb +122 -130
  22. data/lib/aspera/cli/manager.rb +146 -154
  23. data/lib/aspera/cli/plugin.rb +38 -34
  24. data/lib/aspera/cli/plugins/alee.rb +6 -6
  25. data/lib/aspera/cli/plugins/aoc.rb +273 -276
  26. data/lib/aspera/cli/plugins/ats.rb +82 -76
  27. data/lib/aspera/cli/plugins/bss.rb +14 -16
  28. data/lib/aspera/cli/plugins/config.rb +350 -306
  29. data/lib/aspera/cli/plugins/console.rb +23 -19
  30. data/lib/aspera/cli/plugins/cos.rb +18 -18
  31. data/lib/aspera/cli/plugins/faspex.rb +180 -159
  32. data/lib/aspera/cli/plugins/faspex5.rb +64 -54
  33. data/lib/aspera/cli/plugins/node.rb +147 -140
  34. data/lib/aspera/cli/plugins/orchestrator.rb +68 -66
  35. data/lib/aspera/cli/plugins/preview.rb +92 -96
  36. data/lib/aspera/cli/plugins/server.rb +79 -75
  37. data/lib/aspera/cli/plugins/shares.rb +23 -24
  38. data/lib/aspera/cli/plugins/sync.rb +20 -22
  39. data/lib/aspera/cli/transfer_agent.rb +40 -39
  40. data/lib/aspera/cli/version.rb +2 -1
  41. data/lib/aspera/colors.rb +35 -27
  42. data/lib/aspera/command_line_builder.rb +48 -34
  43. data/lib/aspera/cos_node.rb +29 -21
  44. data/lib/aspera/data_repository.rb +3 -2
  45. data/lib/aspera/environment.rb +50 -45
  46. data/lib/aspera/fasp/agent_base.rb +22 -20
  47. data/lib/aspera/fasp/agent_connect.rb +13 -11
  48. data/lib/aspera/fasp/agent_direct.rb +48 -59
  49. data/lib/aspera/fasp/agent_httpgw.rb +33 -39
  50. data/lib/aspera/fasp/agent_node.rb +15 -13
  51. data/lib/aspera/fasp/agent_trsdk.rb +12 -14
  52. data/lib/aspera/fasp/error.rb +2 -1
  53. data/lib/aspera/fasp/error_info.rb +68 -52
  54. data/lib/aspera/fasp/installation.rb +106 -94
  55. data/lib/aspera/fasp/listener.rb +1 -0
  56. data/lib/aspera/fasp/parameters.rb +83 -92
  57. data/lib/aspera/fasp/parameters.yaml +305 -249
  58. data/lib/aspera/fasp/resume_policy.rb +11 -14
  59. data/lib/aspera/fasp/transfer_spec.rb +26 -0
  60. data/lib/aspera/fasp/uri.rb +22 -21
  61. data/lib/aspera/faspex_gw.rb +55 -90
  62. data/lib/aspera/hash_ext.rb +4 -3
  63. data/lib/aspera/id_generator.rb +8 -7
  64. data/lib/aspera/keychain/encrypted_hash.rb +17 -16
  65. data/lib/aspera/keychain/macos_security.rb +6 -10
  66. data/lib/aspera/log.rb +25 -20
  67. data/lib/aspera/nagios.rb +13 -12
  68. data/lib/aspera/node.rb +30 -22
  69. data/lib/aspera/oauth.rb +175 -226
  70. data/lib/aspera/open_application.rb +4 -3
  71. data/lib/aspera/persistency_action_once.rb +6 -6
  72. data/lib/aspera/persistency_folder.rb +5 -9
  73. data/lib/aspera/preview/file_types.rb +6 -5
  74. data/lib/aspera/preview/generator.rb +25 -24
  75. data/lib/aspera/preview/options.rb +16 -14
  76. data/lib/aspera/preview/utils.rb +98 -98
  77. data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
  78. data/lib/aspera/proxy_auto_config.rb +111 -20
  79. data/lib/aspera/rest.rb +115 -113
  80. data/lib/aspera/rest_call_error.rb +2 -2
  81. data/lib/aspera/rest_error_analyzer.rb +23 -25
  82. data/lib/aspera/rest_errors_aspera.rb +15 -14
  83. data/lib/aspera/ssh.rb +12 -10
  84. data/lib/aspera/sync.rb +42 -41
  85. data/lib/aspera/temp_file_manager.rb +18 -14
  86. data/lib/aspera/timer_limiter.rb +2 -1
  87. data/lib/aspera/uri_reader.rb +7 -5
  88. data/lib/aspera/web_auth.rb +79 -76
  89. metadata +64 -21
  90. data/docs/Makefile +0 -65
  91. data/docs/README.erb.md +0 -4424
  92. data/docs/README.md +0 -13
  93. data/docs/diagrams.txt +0 -49
  94. data/docs/doc_tools.rb +0 -58
  95. data/lib/aspera/cli/plugins/shares2.rb +0 -114
  96. data/lib/aspera/fasp/default.rb +0 -17
@@ -1,16 +1,19 @@
1
+ # frozen_string_literal: true
1
2
  require 'aspera/cli/basic_auth_plugin'
2
3
  require 'aspera/cli/extended_value'
4
+ require 'aspera/cli/version'
3
5
  require 'aspera/fasp/installation'
4
6
  require 'aspera/fasp/parameters'
5
- require 'aspera/open_application'
6
- require 'aspera/aoc'
7
+ require 'aspera/fasp/transfer_spec'
8
+ require 'aspera/fasp/error_info'
7
9
  require 'aspera/proxy_auto_config'
8
- require 'aspera/uri_reader'
9
- require 'aspera/rest'
10
+ require 'aspera/open_application'
10
11
  require 'aspera/persistency_action_once'
11
12
  require 'aspera/id_generator'
12
13
  require 'aspera/keychain/encrypted_hash'
13
14
  require 'aspera/keychain/macos_security'
15
+ require 'aspera/aoc'
16
+ require 'aspera/rest'
14
17
  require 'xmlsimple'
15
18
  require 'base64'
16
19
  require 'net/smtp'
@@ -32,7 +35,7 @@ module Aspera
32
35
  CONF_PRESET_VERSION='version'
33
36
  CONF_PRESET_DEFAULT='default'
34
37
  CONF_PRESET_GLOBAL='global_common_defaults'
35
- CONF_PRESET_SECRETS='default_secrets'
38
+ CONF_PRESET_SECRETS='default_secrets' # pragma: allowlist secret
36
39
  CONF_PLUGIN_SYM = :config # Plugins::Config.name.split('::').last.downcase.to_sym
37
40
  CONF_GLOBAL_SYM = :config
38
41
  # old tool name
@@ -54,19 +57,19 @@ module Aspera
54
57
  DEMO='demo'
55
58
  DEMO_SERVER_PRESET='demoserver'
56
59
  AOC_PATH_API_CLIENTS='admin/api-clients'
57
- EMAIL_TEST_TEMPLATE=<<END_OF_TEMPLATE
58
- From: <%=from_name%> <<%=from_email%>>
59
- To: <<%=to%>>
60
- Subject: Amelia email test
60
+ EMAIL_TEST_TEMPLATE=<<~END_OF_TEMPLATE
61
+ From: <%=from_name%> <<%=from_email%>>
62
+ To: <<%=to%>>
63
+ Subject: Amelia email test
61
64
 
62
- It worked !
63
- END_OF_TEMPLATE
65
+ It worked !
66
+ END_OF_TEMPLATE
64
67
  # special extended values
65
- EXTV_INCLUDE_PRESETS='incps'
66
- EXTV_PRESET='preset'
68
+ EXTV_INCLUDE_PRESETS=:incps
69
+ EXTV_PRESET=:preset
67
70
  PRESET_DIG_SEPARATOR='.'
68
71
  DEFAULT_CHECK_NEW_VERSION_DAYS=7
69
- DEFAULT_PRIV_KEY_FILENAME='aspera_aoc_key'
72
+ DEFAULT_PRIV_KEY_FILENAME='aspera_aoc_key' # pragma: allowlist secret
70
73
  DEFAULT_PRIVKEY_LENGTH=4096
71
74
  private_constant :DEFAULT_CONFIG_FILENAME,:CONF_PRESET_CONFIG,:CONF_PRESET_VERSION,:CONF_PRESET_DEFAULT,
72
75
  :CONF_PRESET_GLOBAL,:PROGRAM_NAME_V1,:PROGRAM_NAME_V2,:DEFAULT_REDIRECT,:ASPERA_PLUGINS_FOLDERNAME,
@@ -74,93 +77,103 @@ END_OF_TEMPLATE
74
77
  :TRANSFER_SDK_ARCHIVE_URL,:AOC_PATH_API_CLIENTS,:DEMO_SERVER_PRESET,:EMAIL_TEST_TEMPLATE,:EXTV_INCLUDE_PRESETS,
75
78
  :EXTV_PRESET,:DEFAULT_CHECK_NEW_VERSION_DAYS,:DEFAULT_PRIV_KEY_FILENAME,:SERVER_COMMAND,:CONF_PRESET_SECRETS,
76
79
  :PRESET_DIG_SEPARATOR
77
- def option_preset; nil; end
78
-
79
- def option_preset=(value)
80
- case value
81
- when String
82
- self.options.add_option_preset(preset_by_name(value))
83
- when Hash
84
- self.options.add_option_preset(value)
85
- else
86
- raise 'Preset definition must be a String for name, or Hash for value'
87
- end
88
- nil
89
- end
90
-
91
- def initialize(env,tool_name,help_url,version,main_folder)
80
+ def initialize(env,params)
81
+ 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)
92
83
  super(env)
84
+ @info=params
85
+ @main_folder=default_app_main_folder
93
86
  @plugins={}
94
87
  @plugin_lookup_folders=[]
95
88
  @use_plugin_defaults=true
96
89
  @config_presets=nil
97
90
  @connect_versions=nil
98
91
  @vault=nil
99
- @program_version=version
100
- @tool_name=tool_name
101
- @help_url=help_url
102
- @main_folder=main_folder
103
92
  @conf_file_default=File.join(@main_folder,DEFAULT_CONFIG_FILENAME)
104
93
  @option_config_file=@conf_file_default
105
- Log.log.debug("#{tool_name} folder: #{@main_folder}")
94
+ @pac_exec=nil
95
+ Log.log.debug("#{@info[:name]} folder: #{@main_folder}")
106
96
  # set folder for FASP SDK
107
97
  add_plugin_lookup_folder(self.class.gem_plugins_folder)
108
98
  add_plugin_lookup_folder(File.join(@main_folder,ASPERA_PLUGINS_FOLDERNAME))
109
99
  # do file parameter first
110
- self.options.set_obj_attr(:config_file,self,:option_config_file)
111
- self.options.add_opt_simple(:config_file,"read parameters from file in YAML format, current=#{@option_config_file}")
112
- self.options.parse_options!
100
+ options.set_obj_attr(:config_file,self,:option_config_file)
101
+ options.add_opt_simple(:config_file,"read parameters from file in YAML format, current=#{@option_config_file}")
102
+ options.parse_options!
113
103
  # read correct file
114
104
  read_config_file
115
105
  # add preset handler (needed for smtp)
116
106
  ExtendedValue.instance.set_handler(EXTV_PRESET,:reader,lambda{|v|preset_by_name(v)})
117
107
  ExtendedValue.instance.set_handler(EXTV_INCLUDE_PRESETS,:decoder,lambda{|v|expanded_with_preset_includes(v)})
118
108
  # load defaults before it can be overriden
119
- self.add_plugin_default_preset(CONF_GLOBAL_SYM)
120
- self.options.parse_options!
121
- self.options.set_obj_attr(:ascp_path,self,:option_ascp_path)
122
- self.options.set_obj_attr(:use_product,self,:option_use_product)
123
- self.options.set_obj_attr(:preset,self,:option_preset)
124
- self.options.set_obj_attr(:plugin_folder,self,:option_plugin_folder)
125
- self.options.add_opt_switch(:no_default,'-N','do not load default configuration for plugin') { @use_plugin_defaults=false }
126
- self.options.add_opt_boolean(:override,'Wizard: override existing value')
127
- self.options.add_opt_boolean(:use_generic_client,'Wizard: AoC: use global or org specific jwt client id')
128
- self.options.add_opt_boolean(:default,'Wizard: set as default configuration for specified plugin (also: update)')
129
- self.options.add_opt_boolean(:test_mode,'Wizard: skip private key check step')
130
- self.options.add_opt_simple(:preset,'-PVALUE','load the named option preset from current config file')
131
- self.options.add_opt_simple(:pkeypath,'Wizard: path to private key for JWT')
132
- self.options.add_opt_simple(:ascp_path,'path to ascp')
133
- self.options.add_opt_simple(:use_product,'use ascp from specified product')
134
- self.options.add_opt_simple(:smtp,'smtp configuration (extended value: hash)')
135
- self.options.add_opt_simple(:fpac,'proxy auto configuration URL')
136
- self.options.add_opt_simple(:secret,'default secret')
137
- self.options.add_opt_simple(:secrets,'secret vault')
138
- self.options.add_opt_simple(:sdk_url,'URL to get SDK')
139
- self.options.add_opt_simple(:sdk_folder,'SDK folder path')
140
- self.options.add_opt_simple(:notif_to,'email recipient for notification of transfers')
141
- self.options.add_opt_simple(:notif_template,'email ERB template for notification of transfers')
142
- self.options.add_opt_simple(:version_check_days,Integer,'period in days to check new version (zero to disable)')
143
- self.options.add_opt_simple(:plugin_folder,'folder where to find additional plugins')
144
- self.options.set_option(:use_generic_client,true)
145
- self.options.set_option(:test_mode,false)
146
- self.options.set_option(:default,true)
147
- self.options.set_option(:version_check_days,DEFAULT_CHECK_NEW_VERSION_DAYS)
148
- self.options.set_option(:sdk_url,TRANSFER_SDK_ARCHIVE_URL)
149
- self.options.set_option(:sdk_folder,File.join(@main_folder,'sdk'))
150
- self.options.set_option(:override,:no)
151
- self.options.parse_options!
152
- Fasp::Installation.instance.folder=self.options.get_option(:sdk_folder,:mandatory)
109
+ add_plugin_default_preset(CONF_GLOBAL_SYM)
110
+ options.parse_options!
111
+ options.set_obj_attr(:ascp_path,Fasp::Installation.instance,:ascp_path)
112
+ options.set_obj_attr(:sdk_folder,Fasp::Installation.instance,:sdk_folder)
113
+ options.set_obj_attr(:use_product,self,:option_use_product)
114
+ options.set_obj_attr(:preset,self,:option_preset)
115
+ 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 }
117
+ options.add_opt_boolean(:override,'Wizard: override existing value')
118
+ options.add_opt_boolean(:use_generic_client,'Wizard: AoC: use global or org specific jwt client id')
119
+ options.add_opt_boolean(:default,'Wizard: set as default configuration for specified plugin (also: update)')
120
+ options.add_opt_boolean(:test_mode,'Wizard: skip private key check step')
121
+ options.add_opt_simple(:preset,'-PVALUE','load the named option preset from current config file')
122
+ options.add_opt_simple(:pkeypath,'Wizard: path to private key for JWT')
123
+ options.add_opt_simple(:ascp_path,'path to ascp')
124
+ options.add_opt_simple(:use_product,'use ascp from specified product')
125
+ options.add_opt_simple(:smtp,'smtp configuration (extended value: hash)')
126
+ options.add_opt_simple(:fpac,'proxy auto configuration script')
127
+ options.add_opt_simple(:secret,'default secret')
128
+ options.add_opt_simple(:secrets,'secret vault')
129
+ options.add_opt_simple(:sdk_url,'URL to get SDK')
130
+ options.add_opt_simple(:sdk_folder,'SDK folder path')
131
+ options.add_opt_simple(:notif_to,'email recipient for notification of transfers')
132
+ options.add_opt_simple(:notif_template,'email ERB template for notification of transfers')
133
+ options.add_opt_simple(:version_check_days,Integer,'period in days to check new version (zero to disable)')
134
+ options.add_opt_simple(:plugin_folder,'folder where to find additional plugins')
135
+ options.set_option(:use_generic_client,true)
136
+ options.set_option(:test_mode,false)
137
+ options.set_option(:default,true)
138
+ options.set_option(:version_check_days,DEFAULT_CHECK_NEW_VERSION_DAYS)
139
+ options.set_option(:sdk_url,TRANSFER_SDK_ARCHIVE_URL)
140
+ options.set_option(:sdk_folder,File.join(@main_folder,'sdk'))
141
+ options.set_option(:override,:no)
142
+ options.parse_options!
143
+ pac_script=options.get_option(:fpac,:optional)
144
+ # create PAC executor
145
+ @pac_exec=Aspera::ProxyAutoConfig.new(pac_script).register_uri_generic unless pac_script.nil?
146
+ end
147
+
148
+ # env var name to override the app's main folder
149
+ # default main folder is $HOME/<vendor main app folder>/<program name>
150
+ def conf_dir_env_var
151
+ return "#{@info[:name]}_home".upcase
152
+ end
153
+
154
+ def default_app_main_folder
155
+ # find out application main folder
156
+ app_folder=ENV[conf_dir_env_var]
157
+ # if env var undefined or empty
158
+ if app_folder.nil? || app_folder.empty?
159
+ user_home_folder=Dir.home
160
+ 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])
162
+ end
163
+ return app_folder
153
164
  end
154
165
 
155
166
  def check_gem_version
156
- this_gem_name=File.basename(File.dirname(self.class.gem_root)).gsub(/-[0-9].*$/,'')
157
167
  latest_version=begin
158
- Rest.new(base_url: 'https://rubygems.org/api/v1').read("versions/#{this_gem_name}/latest.json")[:data]['version']
159
- rescue
168
+ Rest.new(base_url: 'https://rubygems.org/api/v1').read("versions/#{@info[:gem]}/latest.json")[:data]['version']
169
+ rescue StandardError
160
170
  Log.log.warn('Could not retrieve latest gem version on rubygems.')
161
171
  '0'
162
172
  end
163
- return {name: this_gem_name, current: Aspera::Cli::VERSION, latest: latest_version, need_update: Gem::Version.new(Aspera::Cli::VERSION) < Gem::Version.new(latest_version)}
173
+ 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}")
175
+ 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)}
164
177
  end
165
178
 
166
179
  def periodic_check_newer_gem_version
@@ -168,30 +181,29 @@ END_OF_TEMPLATE
168
181
  delay_days=options.get_option(:version_check_days,:mandatory)
169
182
  Log.log.info("check days: #{delay_days}")
170
183
  # check only if not zero day
171
- if !delay_days.eql?(0)
172
- # get last date from persistency
173
- last_check_array=[]
174
- check_date_persist=PersistencyActionOnce.new(
175
- manager: persistency,
176
- data: last_check_array,
177
- id: 'version_last_check')
178
- # get persisted date or nil
179
- last_check_date = begin
180
- Date.strptime(last_check_array.first, '%Y/%m/%d')
181
- rescue
182
- nil
183
- end
184
- current_date=Date.today
185
- Log.log.debug("days elapsed: #{last_check_date.is_a?(Date) ? current_date - last_check_date : last_check_date.class.name}")
186
- if last_check_date.nil? or (current_date - last_check_date) > delay_days
187
- last_check_array[0]=current_date.strftime('%Y/%m/%d')
188
- check_date_persist.save
189
- check_data=check_gem_version
190
- if check_data[:need_update]
191
- Log.log.warn("A new version is available: #{check_data[:latest]}. You have #{check_data[:current]}. Upgrade with: gem update #{check_data[:name]}")
192
- end
193
- end
184
+ return if delay_days.eql?(0)
185
+ # 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')
191
+ # 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
194
198
  end
199
+ Log.log.debug("days elapsed: #{last_check_days}")
200
+ return if last_check_days < delay_days
201
+ # generate timestamp
202
+ last_check_array[0]=current_date.strftime('%Y/%m/%d')
203
+ check_date_persist.save
204
+ # 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]
195
207
  end
196
208
 
197
209
  # retrieve structure from cloud (CDN) with all versions available
@@ -218,9 +230,10 @@ END_OF_TEMPLATE
218
230
  def add_plugin_default_preset(plugin_name_sym)
219
231
  default_config_name=get_plugin_default_config_name(plugin_name_sym)
220
232
  Log.log.debug("add_plugin_default_preset:#{plugin_name_sym}:#{default_config_name}")
221
- self.options.add_option_preset(preset_by_name(default_config_name),:unshift) unless default_config_name.nil?
233
+ options.add_option_preset(preset_by_name(default_config_name),:unshift) unless default_config_name.nil?
222
234
  return nil
223
235
  end
236
+
224
237
  private
225
238
 
226
239
  def generate_rsa_private_key(private_key_path,length)
@@ -231,32 +244,40 @@ END_OF_TEMPLATE
231
244
  nil
232
245
  end
233
246
 
234
- # folder containing plugins in the gem's main folder
235
- def self.gem_plugins_folder
236
- File.dirname(File.expand_path(__FILE__))
237
- end
247
+ class << self
248
+ # folder containing plugins in the gem's main folder
249
+ def gem_plugins_folder
250
+ File.dirname(File.expand_path(__FILE__))
251
+ end
238
252
 
239
- # find the root folder of gem where this class is
240
- # go up as many times as englobing modules (not counting class, as it is a file)
241
- def self.gem_root
242
- File.expand_path(Module.nesting[1].to_s.gsub('::','/').gsub(%r([^/]+),'..'),File.dirname(__FILE__))
243
- end
253
+ # name of englobin module
254
+ # @return "Aspera::Cli::Plugins"
255
+ def module_full_name
256
+ return Module.nesting[2].to_s
257
+ end
244
258
 
245
- # instanciate a plugin
246
- # plugins must be Capitalized
247
- def self.plugin_class(plugin_name_sym)
248
- # Module.nesting[2] is Aspera::Cli
249
- return Object::const_get("#{Module.nesting[2].to_s}::Plugins::#{plugin_name_sym.to_s.capitalize}")
250
- end
259
+ # @return main folder where code is, i.e. .../lib
260
+ # go up as many times as englobing modules (not counting class, as it is a file)
261
+ def gem_src_root
262
+ File.expand_path(module_full_name.gsub('::','/').gsub(%r{[^/]+},'..'),gem_plugins_folder)
263
+ end
264
+
265
+ # instanciate a plugin
266
+ # plugins must be Capitalized
267
+ def plugin_class(plugin_name_sym)
268
+ # Module.nesting[2] is Aspera::Cli::Plugins
269
+ return Object.const_get("#{module_full_name}::#{plugin_name_sym.to_s.capitalize}")
270
+ end
251
271
 
252
- def self.flatten_all_config(t)
253
- r=[]
254
- t.each do |k,v|
255
- v.each do |kk,vv|
256
- r.push({'config'=>k,'parameter'=>kk,'value'=>vv})
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
257
278
  end
279
+ return r
258
280
  end
259
- return r
260
281
  end
261
282
 
262
283
  # set parameter and value in global config
@@ -281,8 +302,7 @@ END_OF_TEMPLATE
281
302
 
282
303
  # $HOME/.aspera/`program_name`
283
304
  attr_reader :main_folder
284
- attr_reader :gem_url
285
- attr_reader :plugins
305
+ attr_reader :gem_url, :plugins
286
306
  attr_accessor :option_config_file
287
307
 
288
308
  # @return the hash from name (also expands possible includes)
@@ -299,8 +319,8 @@ END_OF_TEMPLATE
299
319
  raise CliError,"no such config preset: #{include_path}" if nil?
300
320
  end
301
321
  case current
302
- when Hash;return expanded_with_preset_includes(current,include_path)
303
- when String; return ExtendedValue.instance.evaluate(current)
322
+ when Hash then return expanded_with_preset_includes(current,include_path)
323
+ when String then return ExtendedValue.instance.evaluate(current)
304
324
  else return current
305
325
  end
306
326
  end
@@ -316,7 +336,7 @@ END_OF_TEMPLATE
316
336
  memory.delete(EXTV_INCLUDE_PRESETS)
317
337
  hash_val={}
318
338
  raise "#{EXTV_INCLUDE_PRESETS} must be an Array" unless includes.is_a?(Array)
319
- raise "#{EXTV_INCLUDE_PRESETS} must contain names" unless includes.map{|i|i.class}.uniq.eql?([String])
339
+ raise "#{EXTV_INCLUDE_PRESETS} must contain names" unless includes.map(&:class).uniq.eql?([String])
320
340
  includes.each do |preset_name|
321
341
  hash_val.merge!(preset_by_name(preset_name,include_path))
322
342
  end
@@ -325,26 +345,18 @@ END_OF_TEMPLATE
325
345
  return hash_val
326
346
  end
327
347
 
328
- def option_ascp_path=(new_value)
329
- Fasp::Installation.instance.ascp_path=new_value
330
- end
331
-
332
- def option_ascp_path
333
- Fasp::Installation.instance.path(:ascp)
334
- end
335
-
336
348
  def option_use_product=(value)
337
349
  Fasp::Installation.instance.use_ascp_from_product(value)
338
350
  end
339
351
 
340
352
  def option_use_product
341
- 'write-only value'
353
+ 'write-only option, see value of ascp_path'
342
354
  end
343
355
 
344
356
  def option_plugin_folder=(value)
345
357
  case value
346
- when String; add_plugin_lookup_folder(value)
347
- when Array; value.each{|f|add_plugin_lookup_folder(f)}
358
+ when String then add_plugin_lookup_folder(value)
359
+ when Array then value.each{|f|add_plugin_lookup_folder(f)}
348
360
  else raise "folder shall be Array or String, not #{value.class}"
349
361
  end
350
362
  end
@@ -353,6 +365,19 @@ END_OF_TEMPLATE
353
365
  return @plugin_lookup_folders
354
366
  end
355
367
 
368
+ def option_preset; 'write-only option'; end
369
+
370
+ def option_preset=(value)
371
+ case value
372
+ when String
373
+ options.add_option_preset(preset_by_name(value))
374
+ when Hash
375
+ options.add_option_preset(value)
376
+ else
377
+ raise 'Preset definition must be a String for name, or Hash for value'
378
+ end
379
+ end
380
+
356
381
  def convert_preset_path(old_name,new_name,files_to_copy)
357
382
  old_subpath=File.join('',ASPERA_HOME_FOLDER_NAME,old_name,'')
358
383
  new_subpath=File.join('',ASPERA_HOME_FOLDER_NAME,new_name,'')
@@ -361,7 +386,7 @@ END_OF_TEMPLATE
361
386
  preset.values.select{|v|v.is_a?(String) and v.include?(old_subpath)}.each do |value|
362
387
  old_val=value.clone
363
388
  included_path=File.expand_path(old_val.gsub(/^@file:/,''))
364
- files_to_copy.push(included_path) unless files_to_copy.include?(included_path) or !File.exist?(included_path)
389
+ files_to_copy.push(included_path) unless files_to_copy.include?(included_path) || !File.exist?(included_path)
365
390
  value.gsub!(old_subpath,new_subpath)
366
391
  Log.log.warn("Converted config value: #{old_val} -> #{value}")
367
392
  end
@@ -369,11 +394,11 @@ END_OF_TEMPLATE
369
394
  end
370
395
 
371
396
  def convert_preset_plugin_name(old_name,new_name)
372
- if @config_presets[CONF_PRESET_DEFAULT].is_a?(Hash) and @config_presets[CONF_PRESET_DEFAULT].has_key?(old_name)
373
- @config_presets[CONF_PRESET_DEFAULT][new_name]=@config_presets[CONF_PRESET_DEFAULT][old_name]
374
- @config_presets[CONF_PRESET_DEFAULT].delete(old_name)
375
- Log.log.warn("Converted plugin default: #{old_name} -> #{new_name}")
376
- end
397
+ default_preset=@config_presets[CONF_PRESET_DEFAULT]
398
+ 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.delete(old_name)
401
+ Log.log.warn("Converted plugin default: #{old_name} -> #{new_name}")
377
402
  end
378
403
 
379
404
  # read config file and validate format
@@ -390,11 +415,11 @@ END_OF_TEMPLATE
390
415
  # find first existing file (or nil)
391
416
  conf_file_to_load=search_files.select{|f| File.exist?(f)}.first
392
417
  # require save if old version of file
393
- save_required=!@option_config_file.eql?(conf_file_to_load)
418
+ save_required= !@option_config_file.eql?(conf_file_to_load)
394
419
  # if no file found, create default config
395
420
  if conf_file_to_load.nil?
396
421
  Log.log.warn("No config file found. Creating empty configuration file: #{@option_config_file}")
397
- @config_presets={CONF_PRESET_CONFIG=>{CONF_PRESET_VERSION=>@program_version}}
422
+ @config_presets={CONF_PRESET_CONFIG=>{CONF_PRESET_VERSION=>@info[:version]}}
398
423
  else
399
424
  Log.log.debug("loading #{@option_config_file}")
400
425
  @config_presets=YAML.load_file(conf_file_to_load)
@@ -431,14 +456,15 @@ END_OF_TEMPLATE
431
456
  config_tested_version='1.0'
432
457
  if Gem::Version.new(version) <= Gem::Version.new(config_tested_version)
433
458
  convert_preset_plugin_name(AOC_COMMAND_V2,AOC_COMMAND_V3)
434
- convert_preset_path(PROGRAM_NAME_V2,@tool_name,files_to_copy)
459
+ convert_preset_path(PROGRAM_NAME_V2,@info[:name],files_to_copy)
435
460
  version=@config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]=config_tested_version
436
461
  save_required=true
437
462
  end
463
+ Log.log.debug("conf version: #{version}")
438
464
  # Place new compatibility code here
439
465
  if save_required
440
466
  Log.log.warn('Saving automatic conversion.')
441
- @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]=@program_version
467
+ @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]=@info[:version]
442
468
  save_presets_to_config_file
443
469
  Log.log.warn('Copying referenced files')
444
470
  files_to_copy.each do |file|
@@ -449,9 +475,9 @@ END_OF_TEMPLATE
449
475
  rescue Psych::SyntaxError => e
450
476
  Log.log.error('YAML error in config file')
451
477
  raise e
452
- rescue => e
478
+ rescue StandardError => e
453
479
  Log.log.debug("-> #{e}")
454
- new_name="#{@option_config_file}.pre#{@program_version}.manual_conversion_needed"
480
+ new_name="#{@option_config_file}.pre#{@info[:version]}.manual_conversion_needed"
455
481
  File.rename(@option_config_file,new_name)
456
482
  Log.log.warn("Renamed config file to #{new_name}.")
457
483
  Log.log.warn('Manual Conversion is required. Next time, a new empty file will be created.')
@@ -462,12 +488,11 @@ END_OF_TEMPLATE
462
488
  # find plugins in defined paths
463
489
  def add_plugins_from_lookup_folders
464
490
  @plugin_lookup_folders.each do |folder|
465
- if File.directory?(folder)
466
- #TODO: add gem root to load path ? and require short folder ?
467
- #$LOAD_PATH.push(folder) if i[:add_path]
468
- Dir.entries(folder).select{|file|file.end_with?(RUBY_FILE_EXT)}.each do |source|
469
- add_plugin_info(File.join(folder,source))
470
- end
491
+ next unless File.directory?(folder)
492
+ #TODO: add gem root to load path ? and require short folder ?
493
+ #$LOAD_PATH.push(folder) if i[:add_path]
494
+ Dir.entries(folder).select{|file|file.end_with?(RUBY_FILE_EXT)}.each do |source|
495
+ add_plugin_info(File.join(folder,source))
471
496
  end
472
497
  end
473
498
  end
@@ -489,36 +514,42 @@ END_OF_TEMPLATE
489
514
 
490
515
  def identify_plugin_for_url(url)
491
516
  plugins.each do |plugin_name_sym,plugin_info|
517
+ # no detection for internal plugin
492
518
  next if plugin_name_sym.eql?(CONF_PLUGIN_SYM)
519
+ # load plugin class
493
520
  require plugin_info[:require_stanza]
494
521
  c=self.class.plugin_class(plugin_name_sym)
495
- if c.respond_to?(:detect)
496
- current_url=url
497
- begin
498
- res=c.send(:detect,current_url)
499
- return res.merge(product: plugin_name_sym, url: current_url) unless res.nil?
500
- rescue
501
- end
522
+ next unless c.respond_to?(:detect)
523
+ current_url=url
524
+ detection_info=nil
525
+ # first try : direct
526
+ begin
527
+ detection_info=c.detect(current_url)
528
+ rescue StandardError => e
529
+ Log.log.debug("Cannot detect #{plugin_name_sym} : #{e.message}")
530
+ end
531
+ # second try : is there a redirect ?
532
+ if detection_info.nil?
502
533
  begin
503
- # is there a redirect ?
504
- result=Rest.new({:base_url=>url}).call({operation: 'GET',subpath: '',redirect_max: 1})
505
- current_url=result[:http].uri.to_s
506
- # check if redirect
507
- if ! url.eql?(current_url)
508
- res=c.send(:detect,current_url)
509
- return res.merge(product: plugin_name_sym, url: current_url) unless res.nil?
534
+ # TODO: check if redirect ?
535
+ new_url=Rest.new(base_url: url).call(operation: 'GET',subpath: '',redirect_max: 1)[:http].uri.to_s
536
+ unless url.eql?(new_url)
537
+ detection_info=c.detect(new_url)
538
+ current_url=new_url
510
539
  end
511
- rescue
540
+ rescue StandardError => e
541
+ Log.log.debug("Cannot detect #{plugin_name_sym} : #{e.message}")
512
542
  end
513
543
  end
514
- end
544
+ return detection_info.merge(product: plugin_name_sym, url: current_url) unless detection_info.nil?
545
+ end # loop
515
546
  raise "No known application found at #{url}"
516
547
  end
517
548
 
518
549
  def execute_connect_action
519
- command=self.options.get_next_command([:list,:info,:version])
550
+ command=options.get_next_command([:list,:info,:version])
520
551
  if [:info,:version].include?(command)
521
- connect_id=self.options.get_next_argument('id or title')
552
+ connect_id=options.get_next_argument('id or title')
522
553
  one_res=connect_versions.select{|i|i['id'].eql?(connect_id) || i['title'].eql?(connect_id)}.first
523
554
  raise CliNoSuchId.new(:connect,connect_id) if one_res.nil?
524
555
  end
@@ -530,24 +561,24 @@ END_OF_TEMPLATE
530
561
  return {type: :single_object, data: one_res}
531
562
  when :version # shows files used
532
563
  all_links=one_res['links']
533
- command=self.options.get_next_command([:list,:download,:open])
564
+ command=options.get_next_command([:list,:download,:open])
534
565
  if [:download,:open].include?(command)
535
- link_title=self.options.get_next_argument('title or rel')
566
+ link_title=options.get_next_argument('title or rel')
536
567
  one_link=all_links.select {|i| i['title'].eql?(link_title) or i['rel'].eql?(link_title)}.first
537
- raise "no such value" if one_link.nil?
568
+ raise 'no such value' if one_link.nil?
538
569
  end
539
570
  case command
540
571
  when :list # shows files used
541
572
  return {type: :object_list, data: all_links}
542
- when :download #
543
- folder_dest=self.transfer.destination_folder('receive')
573
+ when :download
574
+ folder_dest=transfer.destination_folder(Fasp::TransferSpec::DIRECTION_RECEIVE)
544
575
  #folder_dest=self.options.get_next_argument('destination folder')
545
576
  api_connect_cdn=Rest.new({base_url: CONNECT_WEB_URL})
546
577
  fileurl = one_link['href']
547
578
  filename=fileurl.gsub(%r{.*/},'')
548
579
  api_connect_cdn.call({operation: 'GET',subpath: fileurl,save_to_file: File.join(folder_dest,filename)})
549
580
  return Main.result_status("Downloaded: #{filename}")
550
- when :open #
581
+ when :open
551
582
  OpenApplication.instance.uri(one_link['href'])
552
583
  return Main.result_status("Opened: #{one_link['href']}")
553
584
  end
@@ -555,12 +586,12 @@ END_OF_TEMPLATE
555
586
  end
556
587
 
557
588
  def execute_action_ascp
558
- command=self.options.get_next_command([:connect,:use,:show,:products,:info,:install,:spec])
589
+ command=options.get_next_command([:connect,:use,:show,:products,:info,:install,:spec,:errors])
559
590
  case command
560
591
  when :connect
561
592
  return execute_connect_action
562
593
  when :use
563
- ascp_path=self.options.get_next_argument('path to ascp')
594
+ ascp_path=options.get_next_argument('path to ascp')
564
595
  ascp_version=Fasp::Installation.instance.get_ascp_version(ascp_path)
565
596
  self.format.display_status("ascp version: #{ascp_version}")
566
597
  preset_name=set_global_default(:ascp_path,ascp_path)
@@ -568,46 +599,51 @@ END_OF_TEMPLATE
568
599
  when :show # shows files used
569
600
  return {type: :status, data: Fasp::Installation.instance.path(:ascp)}
570
601
  when :info # shows files used
571
- data=Fasp::Installation::FILES.inject({}) do |m,v|
602
+ data=Fasp::Installation::FILES.each_with_object({}) do |v,m|
572
603
  m[v.to_s]=Fasp::Installation.instance.path(v) rescue 'Not Found'
573
- m
574
604
  end
575
605
  # read PATHs from ascp directly, and pvcl modules as well
576
- Open3.popen3(Fasp::Installation.instance.path(:ascp),'-DDL-') do |stdin, stdout, stderr, thread|
606
+ Open3.popen3(Fasp::Installation.instance.path(:ascp),'-DDL-') do |_stdin, _stdout, stderr, thread|
577
607
  last_line=''
578
- while line=stderr.gets do
608
+ while (line=stderr.gets)
579
609
  line.chomp!
580
610
  last_line=line
581
611
  case line
582
- when %r{^DBG Path ([^ ]+) (dir|file) +: (.*)$};data[$1]=$3
583
- when %r{^DBG Added module group:"([^"]+)" name:"([^"]+)", version:"([^"]+)" interface:"([^"]+)"$};data[$2]=$4
584
- when %r{^DBG License result \(/license/(\S+)\): (.+)$};data[$1]=$2
585
- when %r{^LOG (.+) version ([0-9.]+)$};data['product_name']=$1;data['product_version']=$2
586
- when %r{^LOG Initializing FASP version ([^,]+),};data['ascp_version']=$1
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)
587
617
  end
588
618
  end
589
- if !thread.value.exitstatus.eql?(1) and !data.has_key?('root')
619
+ if !thread.value.exitstatus.eql?(1) && !data.has_key?('root')
590
620
  raise last_line
591
621
  end
592
622
  end
593
623
  data['keypass']=Fasp::Installation.instance.bypass_pass
594
624
  return {type: :single_object, data: data}
595
625
  when :products
596
- command=self.options.get_next_command([:list,:use])
626
+ command=options.get_next_command([:list,:use])
597
627
  case command
598
628
  when :list
599
629
  return {type: :object_list, data: Fasp::Installation.instance.installed_products, fields: ['name','app_root']}
600
630
  when :use
601
- default_product=self.options.get_next_argument('product name')
631
+ default_product=options.get_next_argument('product name')
602
632
  Fasp::Installation.instance.use_ascp_from_product(default_product)
603
633
  preset_name=set_global_default(:ascp_path,Fasp::Installation.instance.path(:ascp))
604
634
  return Main.result_status("Saved to default global preset #{preset_name}")
605
635
  end
606
636
  when :install
607
- v=Fasp::Installation.instance.install_sdk(self.options.get_option(:sdk_url,:mandatory))
637
+ v=Fasp::Installation.instance.install_sdk(options.get_option(:sdk_url,:mandatory))
608
638
  return Main.result_status("Installed version #{v}")
609
639
  when :spec
610
- return {type: :object_list, data: Fasp::Parameters.man_table, fields: ['name','type',Fasp::Parameters::SUPPORTED_AGENTS_SHORT.map{|i|i.to_s},'description'].flatten}
640
+ return {type: :object_list, data: Fasp::Parameters.man_table, fields: ['name','type',Fasp::Parameters::SUPPORTED_AGENTS_SHORT.map(&:to_s),'description'].flatten}
641
+ when :errors
642
+ error_data=[]
643
+ Fasp::ERROR_INFO.each_pair do |code,prop|
644
+ error_data.push(code: code, mnemonic: prop[:c], retry: prop[:r], info: prop[:a])
645
+ end
646
+ return {type: :object_list, data: error_data}
611
647
  end
612
648
  raise "unexpected case: #{command}"
613
649
  end
@@ -621,10 +657,10 @@ END_OF_TEMPLATE
621
657
  PRESET_ALL_ACTIONS=[PRESET_GBL_ACTIONS,PRESET_INSTANCE_ACTIONS].flatten.freeze
622
658
 
623
659
  def execute_file_action(action,config_name)
624
- action=self.options.get_next_command(PRESET_ALL_ACTIONS) if action.nil?
625
- config_name=instance_identifier() if config_name.nil? and PRESET_INSTANCE_ACTIONS.include?(action)
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)
626
662
  # those operations require existing option
627
- raise "no such preset: #{config_name}" if PRESET_EXST_ACTIONS.include?(action) and !@config_presets.has_key?(config_name)
663
+ raise "no such preset: #{config_name}" if PRESET_EXST_ACTIONS.include?(action) && !@config_presets.has_key?(config_name)
628
664
  selected_preset=@config_presets[config_name]
629
665
  case action
630
666
  when :list
@@ -639,21 +675,21 @@ END_OF_TEMPLATE
639
675
  save_presets_to_config_file
640
676
  return Main.result_status("Deleted: #{config_name}")
641
677
  when :get
642
- param_name=self.options.get_next_argument('parameter name')
678
+ param_name=options.get_next_argument('parameter name')
643
679
  value=selected_preset[param_name]
644
680
  raise "no such option in preset #{config_name} : #{param_name}" if value.nil?
645
681
  case value
646
- when Numeric,String; return {type: :text, data: ExtendedValue.instance.evaluate(value.to_s)}
682
+ when Numeric,String then return {type: :text, data: ExtendedValue.instance.evaluate(value.to_s)}
647
683
  end
648
684
  return {type: :single_object, data: value}
649
685
  when :unset
650
- param_name=self.options.get_next_argument('parameter name')
686
+ param_name=options.get_next_argument('parameter name')
651
687
  selected_preset.delete(param_name)
652
688
  save_presets_to_config_file
653
689
  return Main.result_status("Removed: #{config_name}: #{param_name}")
654
690
  when :set
655
- param_name=self.options.get_next_argument('parameter name')
656
- param_value=self.options.get_next_argument('parameter value')
691
+ param_name=options.get_next_argument('parameter name')
692
+ param_value=options.get_next_argument('parameter value')
657
693
  if !@config_presets.has_key?(config_name)
658
694
  Log.log.debug("no such config name: #{config_name}, initializing")
659
695
  selected_preset=@config_presets[config_name]={}
@@ -665,7 +701,7 @@ END_OF_TEMPLATE
665
701
  save_presets_to_config_file
666
702
  return Main.result_status("Updated: #{config_name}: #{param_name} <- #{param_value}")
667
703
  when :initialize
668
- config_value=self.options.get_next_argument('extended value (Hash)')
704
+ config_value=options.get_next_argument('extended value (Hash)')
669
705
  if @config_presets.has_key?(config_name)
670
706
  Log.log.warn("configuration already exists: #{config_name}, overwriting")
671
707
  end
@@ -674,7 +710,7 @@ END_OF_TEMPLATE
674
710
  return Main.result_status("Modified: #{@option_config_file}")
675
711
  when :update
676
712
  # get unprocessed options
677
- theopts=self.options.get_options_table
713
+ theopts=options.get_options_table
678
714
  Log.log.debug("opts=#{theopts}")
679
715
  @config_presets[config_name]||={}
680
716
  @config_presets[config_name].merge!(theopts)
@@ -683,10 +719,10 @@ END_OF_TEMPLATE
683
719
  save_presets_to_config_file
684
720
  return Main.result_status("Updated: #{config_name}")
685
721
  when :ask
686
- self.options.ask_missing_mandatory=:yes
722
+ options.ask_missing_mandatory=:yes
687
723
  @config_presets[config_name]||={}
688
- self.options.get_next_argument('option names',:multiple).each do |optionname|
689
- option_value=self.options.get_interactive(:option,optionname)
724
+ options.get_next_argument('option names',:multiple).each do |optionname|
725
+ option_value=options.get_interactive(:option,optionname)
690
726
  @config_presets[config_name][optionname]=option_value
691
727
  end
692
728
  save_presets_to_config_file
@@ -694,95 +730,98 @@ END_OF_TEMPLATE
694
730
  end
695
731
  end
696
732
 
697
- ACTIONS=[PRESET_GBL_ACTIONS,:id,:preset,:open,:documentation,:genkey,:gem_path,:plugin,:flush_tokens,:echo,:wizard,:export_to_cli,:detect,:coffee,:ascp,:email_test,:smtp_settings,:proxy_check,:folder,:file,:check_update,:initdemo,:vault].flatten.freeze
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
698
735
 
699
736
  # "config" plugin
700
737
  def execute_action
701
- action=self.options.get_next_command(ACTIONS)
738
+ action=options.get_next_command(ACTIONS)
702
739
  case action
703
740
  when *PRESET_GBL_ACTIONS # older syntax
704
741
  return execute_file_action(action,nil)
705
742
  when :id # older syntax
706
- return execute_file_action(nil,self.options.get_next_argument('config name'))
743
+ return execute_file_action(nil,options.get_next_argument('config name'))
707
744
  when :preset # newer syntax
708
745
  return execute_file_action(nil,nil)
709
746
  when :open
710
- OpenApplication.instance.uri("#{@option_config_file}") #file://
747
+ OpenApplication.instance.uri(@option_config_file.to_s) #file://
711
748
  return Main.result_nothing
712
749
  when :documentation
713
750
  section=options.get_next_argument('private key file path',:single,:optional)
714
751
  section='#'+section unless section.nil?
715
- OpenApplication.instance.uri("#{@help_url}#{section}")
752
+ OpenApplication.instance.uri("#{@info[:help]}#{section}")
716
753
  return Main.result_nothing
717
754
  when :genkey # generate new rsa key
718
- private_key_path=self.options.get_next_argument('private key file path')
755
+ private_key_path=options.get_next_argument('private key file path')
719
756
  generate_rsa_private_key(private_key_path,DEFAULT_PRIVKEY_LENGTH)
720
757
  return Main.result_status('Generated key: '+private_key_path)
721
758
  when :echo # display the content of a value given on command line
722
- result={type: :other_struct, data: self.options.get_next_argument('value')}
759
+ result={type: :other_struct, data: options.get_next_argument('value')}
723
760
  # special for csv
724
- result[:type]=:object_list if result[:data].is_a?(Array) and result[:data].first.is_a?(Hash)
761
+ result[:type]=:object_list if result[:data].is_a?(Array) && result[:data].first.is_a?(Hash)
725
762
  return result
726
763
  when :flush_tokens
727
764
  deleted_files=Oauth.flush_tokens
728
765
  return {type: :value_list, data: deleted_files, name: 'file'}
729
766
  when :plugin
730
- case self.options.get_next_command([:list,:create])
767
+ case options.get_next_command([:list,:create])
731
768
  when :list
732
- return {type: :object_list, data: @plugins.keys.map { |i| { 'plugin' => i.to_s, 'path' => @plugins[i][:source] } } , fields: ['plugin','path']}
769
+ return {type: :object_list, data: @plugins.keys.map { |i| { 'plugin' => i.to_s, 'path' => @plugins[i][:source] } }, fields: ['plugin','path']}
733
770
  when :create
734
771
  plugin_name=options.get_next_argument('name',:single,:mandatory).downcase
735
772
  plugin_folder=options.get_next_argument('folder',:single,:optional) || File.join(@main_folder,ASPERA_PLUGINS_FOLDERNAME)
736
773
  plugin_file=File.join(plugin_folder,"#{plugin_name}.rb")
737
- content=<<_EOF_
738
- require 'aspera/cli/plugin'
739
- module Aspera
740
- module Cli
741
- module Plugins
742
- class #{plugin_name.capitalize} < Plugin
743
- ACTIONS=[]
744
- def execute_action; return Main.result_status("You called plugin #{plugin_name}"); end
745
- end # #{plugin_name.capitalize}
746
- end # Plugins
747
- end # Cli
748
- end # Aspera
749
- _EOF_
774
+ content=<<~END_OF_PLUGIN_CODE
775
+ require 'aspera/cli/plugin'
776
+ module Aspera
777
+ module Cli
778
+ module Plugins
779
+ class #{plugin_name.capitalize} < Plugin
780
+ ACTIONS=[]
781
+ def execute_action; return Main.result_status('You called plugin #{plugin_name}'); end
782
+ end # #{plugin_name.capitalize}
783
+ end # Plugins
784
+ end # Cli
785
+ end # Aspera
786
+ END_OF_PLUGIN_CODE
750
787
  File.write(plugin_file,content)
751
788
  return Main.result_status("Created #{plugin_file}")
752
789
  end
753
790
  when :wizard
754
791
  # interactive mode
755
- self.options.ask_missing_mandatory=true
792
+ options.ask_missing_mandatory=true
756
793
  # register url option
757
794
  BasicAuthPlugin.new(@agents.merge(skip_option_header: true))
758
795
  # get from option, or ask
759
- instance_url=self.options.get_option(:url,:mandatory)
796
+ instance_url=options.get_option(:url,:mandatory)
760
797
  # allow user to tell the preset name
761
- preset_name=self.options.get_option(:id,:optional)
762
- appli=identify_plugin_for_url(instance_url)
763
- plugin_name="<replace per app>"
764
- test_args="<replace per app>"
765
- case appli[:product]
798
+ preset_name=options.get_option(:id,:optional)
799
+ # 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
766
805
  when :aoc
767
806
  self.format.display_status('Detected: Aspera on Cloud'.bold)
768
807
  plugin_name=AOC_COMMAND_CURRENT
769
- organization,instance_domain=AoC.parse_url(instance_url)
808
+ organization=AoC.parse_url(instance_url).first
770
809
  # if not defined by user, generate name
771
- preset_name=[appli[:product],organization].join('_') if preset_name.nil?
810
+ preset_name=[application,organization].join('_') if preset_name.nil?
772
811
  self.format.display_status("Preparing preset: #{preset_name}")
773
812
  # init defaults if necessary
774
813
  @config_presets[CONF_PRESET_DEFAULT]||={}
775
- option_override=self.options.get_option(:override,:mandatory)
776
- option_default=self.options.get_option(:default,:mandatory)
814
+ option_override=options.get_option(:override,:mandatory)
815
+ option_default=options.get_option(:default,:mandatory)
777
816
  Log.log.error("override=#{option_override} -> #{option_override.class}")
778
- raise CliError,"A default configuration already exists for plugin '#{plugin_name}' (use --override=yes or --default=no)" if !option_override and option_default and @config_presets[CONF_PRESET_DEFAULT].has_key?(plugin_name)
779
- raise CliError,"Preset already exists: #{preset_name} (use --override=yes or --id=<name>)" if !option_override and @config_presets.has_key?(preset_name)
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)
780
819
  # lets see if path to priv key is provided
781
- private_key_path=self.options.get_option(:pkeypath,:optional)
820
+ private_key_path=options.get_option(:pkeypath,:optional)
782
821
  # give a chance to provide
783
822
  if private_key_path.nil?
784
823
  self.format.display_status('Please provide path to your private RSA key, or empty to generate one:')
785
- private_key_path=self.options.get_option(:pkeypath,:mandatory).to_s
824
+ private_key_path=options.get_option(:pkeypath,:mandatory).to_s
786
825
  end
787
826
  # else generate path
788
827
  if private_key_path.empty?
@@ -800,74 +839,73 @@ _EOF_
800
839
  # declare command line options for AoC
801
840
  require 'aspera/cli/plugins/aoc'
802
841
  # make username mandatory for jwt, this triggers interactive input
803
- self.options.get_option(:username,:mandatory)
842
+ options.get_option(:username,:mandatory)
804
843
  # instanciate AoC plugin, so that command line options are known
805
- files_plugin=self.class.plugin_class(plugin_name).new(@agents.merge({skip_basic_auth_options: true, private_key_path: private_key_path}))
806
- aoc_api=files_plugin.get_api
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
807
845
  auto_set_pub_key=false
808
846
  auto_set_jwt=false
809
847
  use_browser_authentication=false
810
- if self.options.get_option(:use_generic_client)
848
+ if options.get_option(:use_generic_client)
811
849
  self.format.display_status('Using global client_id.')
812
850
  self.format.display_status('Please Login to your Aspera on Cloud instance.'.red)
813
851
  self.format.display_status('Navigate to your "Account Settings"'.red)
814
852
  self.format.display_status('Check or update the value of "Public Key" to be:'.red.blink)
815
- self.format.display_status("#{pub_key_pem}")
816
- if ! self.options.get_option(:test_mode)
853
+ self.format.display_status(pub_key_pem.to_s)
854
+ if !options.get_option(:test_mode)
817
855
  self.format.display_status('Once updated or validated, press enter.')
818
856
  OpenApplication.instance.uri(instance_url)
819
- STDIN.gets
857
+ $stdin.gets
820
858
  end
821
859
  else
822
860
  self.format.display_status('Using organization specific client_id.')
823
- if self.options.get_option(:client_id,:optional).nil? or self.options.get_option(:client_secret,:optional).nil?
861
+ if options.get_option(:client_id,:optional).nil? || options.get_option(:client_secret,:optional).nil?
824
862
  self.format.display_status('Please login to your Aspera on Cloud instance.'.red)
825
863
  self.format.display_status('Go to: Apps->Admin->Organization->Integrations')
826
864
  self.format.display_status('Create or check if there is an existing integration named:')
827
- self.format.display_status("- name: #{@tool_name}")
865
+ self.format.display_status("- name: #{@info[:name]}")
828
866
  self.format.display_status("- redirect uri: #{DEFAULT_REDIRECT}")
829
867
  self.format.display_status('- origin: localhost')
830
868
  self.format.display_status('Once created or identified,')
831
869
  self.format.display_status('Please enter:'.red)
832
870
  end
833
871
  OpenApplication.instance.uri("#{instance_url}/#{AOC_PATH_API_CLIENTS}")
834
- self.options.get_option(:client_id,:mandatory)
835
- self.options.get_option(:client_secret,:mandatory)
872
+ options.get_option(:client_id,:mandatory)
873
+ options.get_option(:client_secret,:mandatory)
836
874
  use_browser_authentication=true
837
875
  end
838
876
  if use_browser_authentication
839
877
  self.format.display_status('We will use web authentication to bootstrap.')
840
878
  auto_set_pub_key=true
841
879
  auto_set_jwt=true
842
- @api_aoc.oauth.params[:auth]=:web
843
- @api_aoc.oauth.params[:redirect_uri]=DEFAULT_REDIRECT
844
- @api_aoc.oauth.params[:scope]=AoC::SCOPE_FILES_ADMIN
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
845
883
  end
846
884
  myself=aoc_api.read('self')[:data]
847
885
  if auto_set_pub_key
848
- raise CliError,'Public key is already set in profile (use --override=yes)' unless myself['public_key'].empty? or option_override
886
+ raise CliError,'Public key is already set in profile (use --override=yes)' unless myself['public_key'].empty? || option_override
849
887
  self.format.display_status('Updating profile with new key')
850
888
  aoc_api.update("users/#{myself['id']}",{'public_key'=>pub_key_pem})
851
889
  end
852
890
  if auto_set_jwt
853
891
  self.format.display_status('Enabling JWT for client')
854
- aoc_api.update("clients/#{self.options.get_option(:client_id)}",{'jwt_grant_enabled'=>true,'explicit_authorization_required'=>false})
892
+ aoc_api.update("clients/#{options.get_option(:client_id)}",{'jwt_grant_enabled'=>true,'explicit_authorization_required'=>false})
855
893
  end
856
894
  self.format.display_status("Creating new config preset: #{preset_name}")
857
895
  @config_presets[preset_name]={
858
- :url.to_s =>self.options.get_option(:url),
896
+ :url.to_s =>options.get_option(:url),
859
897
  :username.to_s =>myself['email'],
860
898
  :auth.to_s =>:jwt.to_s,
861
- :private_key.to_s =>'@file:'+private_key_path,
899
+ :private_key.to_s =>'@file:'+private_key_path
862
900
  }
863
901
  # set only if non nil
864
902
  [:client_id,:client_secret].each do |s|
865
- o=self.options.get_option(s)
903
+ o=options.get_option(s)
866
904
  @config_presets[preset_name][s.to_s] = o unless o.nil?
867
905
  end
868
906
  test_args="#{plugin_name} user profile show"
869
907
  else
870
- raise CliBadArgument,"Supports only: aoc. Detected: #{appli}"
908
+ raise CliBadArgument,"Supports only: aoc. Detected: #{application}"
871
909
  end # product
872
910
  if option_default
873
911
  self.format.display_status("Setting config preset as default for #{plugin_name}")
@@ -877,29 +915,29 @@ _EOF_
877
915
  end
878
916
  self.format.display_status('Saving config file.')
879
917
  save_presets_to_config_file
880
- return Main.result_status("Done.\nYou can test with:\n#{@tool_name} #{test_args}")
918
+ return Main.result_status("Done.\nYou can test with:\n#{@info[:name]} #{test_args}")
881
919
  when :export_to_cli
882
920
  self.format.display_status('Exporting: Aspera on Cloud')
883
921
  require 'aspera/cli/plugins/aoc'
884
922
  # need url / username
885
923
  add_plugin_default_preset(AOC_COMMAND_V3.to_sym)
886
924
  # instanciate AoC plugin
887
- files_plugin=self.class.plugin_class(AOC_COMMAND_CURRENT).new(@agents) # TODO: is this line needed ?
888
- url=self.options.get_option(:url,:mandatory)
925
+ self.class.plugin_class(AOC_COMMAND_CURRENT).new(@agents) # TODO: is this line needed ? get options ?
926
+ url=options.get_option(:url,:mandatory)
889
927
  cli_conf_file=Fasp::Installation.instance.cli_conf_file
890
928
  data=JSON.parse(File.read(cli_conf_file))
891
929
  organization,instance_domain=AoC.parse_url(url)
892
930
  key_basename='org_'+organization+'.pem'
893
931
  key_file=File.join(File.dirname(File.dirname(cli_conf_file)),'etc',key_basename)
894
- File.write(key_file,self.options.get_option(:private_key,:mandatory))
932
+ File.write(key_file,options.get_option(:private_key,:mandatory))
895
933
  new_conf={
896
934
  'organization' => organization,
897
935
  'hostname' => [organization,instance_domain].join('.'),
898
936
  'privateKeyFilename' => key_basename,
899
- 'username' => self.options.get_option(:username,:mandatory)
937
+ 'username' => options.get_option(:username,:mandatory)
900
938
  }
901
- new_conf['clientId']=self.options.get_option(:client_id,:optional)
902
- new_conf['clientSecret']=self.options.get_option(:client_secret,:optional)
939
+ new_conf['clientId']=options.get_option(:client_id,:optional)
940
+ new_conf['clientSecret']=options.get_option(:client_secret,:optional)
903
941
  if new_conf['clientId'].nil?
904
942
  new_conf['clientId'],new_conf['clientSecret']=AoC.get_client_info()
905
943
  end
@@ -916,14 +954,18 @@ _EOF_
916
954
  when :detect
917
955
  # need url / username
918
956
  BasicAuthPlugin.new(@agents)
919
- return Main.result_status("Found: #{identify_plugin_for_url(self.options.get_option(:url,:mandatory))}")
957
+ return {type: :single_object, data: identify_plugin_for_url(options.get_option(:url,:mandatory))}
920
958
  when :coffee
921
959
  OpenApplication.instance.uri('https://enjoyjava.com/wp-content/uploads/2018/01/How-to-make-strong-coffee.jpg')
922
960
  return Main.result_nothing
923
961
  when :ascp
924
962
  execute_action_ascp
925
- when :gem_path
926
- return Main.result_status(self.class.gem_root)
963
+ when :gem
964
+ case options.get_next_command([:path,:version,:name])
965
+ when :path then return Main.result_status(self.class.gem_src_root)
966
+ when :version then return Main.result_status(Aspera::Cli::VERSION)
967
+ when :name then return Main.result_status(@info[:gem])
968
+ end
927
969
  when :folder
928
970
  return Main.result_status(@main_folder)
929
971
  when :file
@@ -934,9 +976,10 @@ _EOF_
934
976
  when :smtp_settings
935
977
  return {type: :single_object, data: email_settings}
936
978
  when :proxy_check
937
- pac_url=self.options.get_option(:fpac,:mandatory)
938
- server_url=self.options.get_next_argument('server url')
939
- return Main.result_status(Aspera::ProxyAutoConfig.new(UriReader.read(pac_url)).get_proxy(server_url))
979
+ # ensure fpac was provided
980
+ options.get_option(:fpac,:mandatory)
981
+ server_url=options.get_next_argument('server url')
982
+ return Main.result_status(@pac_exec.find_proxy_for_url(server_url))
940
983
  when :check_update
941
984
  return {type: :single_object, data: check_gem_version}
942
985
  when :initdemo
@@ -944,7 +987,8 @@ _EOF_
944
987
  Log.log.warn("Demo server preset already present: #{DEMO_SERVER_PRESET}")
945
988
  else
946
989
  Log.log.info("Creating Demo server preset: #{DEMO_SERVER_PRESET}")
947
- @config_presets[DEMO_SERVER_PRESET]={'url'=>'ssh://'+DEMO+'.asperasoft.com:33001','username'=>AOC_COMMAND_V2,'ssAP'.downcase.reverse+'drow'.reverse=>DEMO+AOC_COMMAND_V2}
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}
948
992
  end
949
993
  @config_presets[CONF_PRESET_DEFAULT]||={}
950
994
  if @config_presets[CONF_PRESET_DEFAULT].has_key?(SERVER_COMMAND)
@@ -957,13 +1001,13 @@ _EOF_
957
1001
  save_presets_to_config_file
958
1002
  return Main.result_status('Done')
959
1003
  when :vault
960
- command=self.options.get_next_command([:init,:list,:get,:set,:delete])
1004
+ command=options.get_next_command([:init,:list,:get,:set,:delete])
961
1005
  case command
962
1006
  when :init
963
- type=self.options.get_option(:value,:optional)
1007
+ type=options.get_option(:value,:optional)
964
1008
  case type
965
1009
  when 'config',NilClass
966
- raise "default secrets already exists" if @config_presets.has_key?(CONF_PRESET_SECRETS)
1010
+ raise 'default secrets already exists' if @config_presets.has_key?(CONF_PRESET_SECRETS)
967
1011
  @config_presets[CONF_PRESET_SECRETS]={}
968
1012
  set_global_default(:secrets,"@preset:#{CONF_PRESET_SECRETS}")
969
1013
  else raise 'no such vault type'
@@ -974,26 +1018,26 @@ _EOF_
974
1018
  when :set
975
1019
  # register url option
976
1020
  BasicAuthPlugin.new(@agents.merge(skip_option_header: true))
977
- username=self.options.get_option(:username,:mandatory)
978
- url=self.options.get_option(:url,:mandatory)
979
- description=self.options.get_option(:value,:optional)
980
- secret=self.options.get_next_argument('secret')
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')
981
1025
  vault.set(username: username, url: url, description: description, secret: secret)
982
1026
  save_presets_to_config_file if vault.is_a?(Keychain::EncryptedHash)
983
1027
  return Main.result_status('Done')
984
1028
  when :get
985
1029
  # register url option
986
1030
  BasicAuthPlugin.new(@agents.merge(skip_option_header: true))
987
- username=self.options.get_option(:username,:mandatory)
988
- url=self.options.get_option(:url,:optional)
1031
+ username=options.get_option(:username,:mandatory)
1032
+ url=options.get_option(:url,:optional)
989
1033
  result=vault.get(username: username, url: url)
990
1034
  return {type: :single_object, data: result}
991
1035
  when :delete
992
1036
  # register url option
993
1037
  BasicAuthPlugin.new(@agents.merge(skip_option_header: true))
994
- username=self.options.get_option(:username,:mandatory)
995
- url=self.options.get_option(:url,:optional)
996
- result=vault.delete(username: username, url: url)
1038
+ username=options.get_option(:username,:mandatory)
1039
+ url=options.get_option(:url,:optional)
1040
+ vault.delete(username: username, url: url)
997
1041
  return Main.result_status('Done')
998
1042
  end
999
1043
  else raise 'INTERNAL ERROR: wrong case'
@@ -1002,9 +1046,9 @@ _EOF_
1002
1046
 
1003
1047
  # @return email server setting with defaults if not defined
1004
1048
  def email_settings
1005
- smtp=self.options.get_option(:smtp,:mandatory)
1049
+ smtp=options.get_option(:smtp,:mandatory)
1006
1050
  # change string keys into symbol keys
1007
- smtp=smtp.keys.inject({}){|m,v|m[v.to_sym]=smtp[v];m}
1051
+ smtp=smtp.keys.each_with_object({}){|v,m|m[v.to_sym]=smtp[v];}
1008
1052
  # defaults
1009
1053
  smtp[:tls]||=true
1010
1054
  smtp[:port]||=smtp[:tls]?587:25
@@ -1034,7 +1078,7 @@ _EOF_
1034
1078
  raise "Missing email parameter: #{n}" unless vars.has_key?(n)
1035
1079
  end
1036
1080
  start_options=[mail_conf[:domain]]
1037
- start_options.push(mail_conf[:username],mail_conf[:password],:login) if mail_conf.has_key?(:username) and mail_conf.has_key?(:password)
1081
+ start_options.push(mail_conf[:username],mail_conf[:password],:login) if mail_conf.has_key?(:username) && mail_conf.has_key?(:password)
1038
1082
  # create a binding with only variables defined in vars
1039
1083
  template_binding=empty_binding
1040
1084
  # add variables to binding
@@ -1047,8 +1091,8 @@ _EOF_
1047
1091
  Log.dump(:msg_with_headers,msg_with_headers)
1048
1092
  smtp = Net::SMTP.new(mail_conf[:server], mail_conf[:port])
1049
1093
  smtp.enable_starttls if mail_conf[:tls]
1050
- smtp.start(*start_options) do |smtp|
1051
- smtp.send_message(msg_with_headers, vars[:from_email], vars[:to])
1094
+ smtp.start(*start_options) do |smtp_session|
1095
+ smtp_session.send_message(msg_with_headers, vars[:from_email], vars[:to])
1052
1096
  end
1053
1097
  end
1054
1098
 
@@ -1062,16 +1106,16 @@ _EOF_
1062
1106
  # returns [String] name if config_presets has default
1063
1107
  # returns nil if there is no config or bypass default params
1064
1108
  def get_plugin_default_config_name(plugin_sym)
1065
- raise "internal error: config_presets shall be defined" if @config_presets.nil?
1109
+ raise 'internal error: config_presets shall be defined' if @config_presets.nil?
1066
1110
  if !@use_plugin_defaults
1067
1111
  Log.log.debug('skip default config')
1068
1112
  return nil
1069
1113
  end
1070
- if @config_presets.has_key?(CONF_PRESET_DEFAULT) and
1114
+ if @config_presets.has_key?(CONF_PRESET_DEFAULT) &&
1071
1115
  @config_presets[CONF_PRESET_DEFAULT].has_key?(plugin_sym.to_s)
1072
1116
  default_config_name=@config_presets[CONF_PRESET_DEFAULT][plugin_sym.to_s]
1073
1117
  if !@config_presets.has_key?(default_config_name)
1074
- Log.log.error("Default config name [#{default_config_name}] specified for plugin [#{plugin_sym.to_s}], but it does not exist in config file.\nPlease fix the issue: either create preset with one parameter (#{@tool_name} config id #{default_config_name} init @json:'{}') or remove default (#{@tool_name} config id default remove #{plugin_sym.to_s}).")
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}).")
1075
1119
  end
1076
1120
  raise CliError,"Config name [#{default_config_name}] must be a hash, check config file." if !@config_presets[default_config_name].is_a?(Hash)
1077
1121
  return default_config_name
@@ -1081,7 +1125,7 @@ _EOF_
1081
1125
 
1082
1126
  def vault
1083
1127
  if @vault.nil?
1084
- vault_info=self.options.get_option(:secrets,:optional)
1128
+ vault_info=options.get_option(:secrets,:optional)
1085
1129
  case vault_info
1086
1130
  when Hash
1087
1131
  @vault=Keychain::EncryptedHash.new(vault_info)
@@ -1091,8 +1135,8 @@ _EOF_
1091
1135
  when Environment::OS_X
1092
1136
  @vault=Keychain::MacosSecurity.new(name)
1093
1137
  when Environment::OS_WINDOWS,Environment::OS_LINUX,Environment::OS_AIX
1094
- raise "not implemented"
1095
- else raise "Error"
1138
+ raise 'not implemented'
1139
+ else raise 'Error'
1096
1140
  end
1097
1141
  when NilClass
1098
1142
  # keep nil
@@ -1100,18 +1144,18 @@ _EOF_
1100
1144
  raise CliBadArgument,'secrets shall be Hash'
1101
1145
  end
1102
1146
  end
1103
- raise "No vault defined" if @vault.nil?
1147
+ raise 'No vault defined' if @vault.nil?
1104
1148
  @vault
1105
1149
  end
1106
1150
 
1107
1151
  def get_secret(options)
1108
- raise "options shall be Hash" unless options.is_a?(Hash)
1109
- raise "options shall have username" unless options.has_key?(:username)
1152
+ raise 'options shall be Hash' unless options.is_a?(Hash)
1153
+ raise 'options shall have username' unless options.has_key?(:username)
1110
1154
  secret=self.options.get_option(:secret,:optional)
1111
1155
  if secret.nil?
1112
1156
  secret=vault.get(options) rescue nil
1113
1157
  # mandatory by default
1114
- raise "please provide secret for #{options[:username]}" if secret.nil? and ( options[:mandatory].nil? or options[:mandatory] )
1158
+ raise "please provide secret for #{options[:username]}" if secret.nil? && (options[:mandatory].nil? || options[:mandatory])
1115
1159
  end
1116
1160
  return secret
1117
1161
  end