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