aspera-cli 4.12.0 → 4.14.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 +45 -5
- data/CONTRIBUTING.md +113 -22
- data/README.md +1289 -754
- data/bin/ascli +3 -3
- data/examples/dascli +1 -1
- data/examples/rubyc +24 -0
- data/lib/aspera/aoc.rb +63 -74
- data/lib/aspera/ascmd.rb +5 -3
- data/lib/aspera/cli/basic_auth_plugin.rb +6 -6
- data/lib/aspera/cli/extended_value.rb +24 -37
- data/lib/aspera/cli/formatter.rb +23 -25
- data/lib/aspera/cli/info.rb +2 -4
- data/lib/aspera/cli/main.rb +27 -27
- data/lib/aspera/cli/manager.rb +143 -120
- data/lib/aspera/cli/plugin.rb +88 -43
- data/lib/aspera/cli/plugins/alee.rb +2 -2
- data/lib/aspera/cli/plugins/aoc.rb +235 -104
- data/lib/aspera/cli/plugins/ats.rb +16 -18
- data/lib/aspera/cli/plugins/bss.rb +3 -3
- data/lib/aspera/cli/plugins/config.rb +190 -373
- data/lib/aspera/cli/plugins/console.rb +4 -6
- data/lib/aspera/cli/plugins/cos.rb +12 -13
- data/lib/aspera/cli/plugins/faspex.rb +21 -21
- data/lib/aspera/cli/plugins/faspex5.rb +399 -150
- data/lib/aspera/cli/plugins/node.rb +260 -174
- data/lib/aspera/cli/plugins/orchestrator.rb +15 -18
- data/lib/aspera/cli/plugins/preview.rb +40 -62
- data/lib/aspera/cli/plugins/server.rb +33 -16
- data/lib/aspera/cli/plugins/shares.rb +24 -33
- data/lib/aspera/cli/plugins/sync.rb +6 -6
- data/lib/aspera/cli/transfer_agent.rb +47 -30
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +9 -7
- data/lib/aspera/command_line_builder.rb +2 -1
- data/lib/aspera/cos_node.rb +1 -1
- data/lib/aspera/data/6 +0 -0
- data/lib/aspera/environment.rb +7 -3
- data/lib/aspera/fasp/agent_connect.rb +6 -1
- data/lib/aspera/fasp/agent_direct.rb +17 -17
- data/lib/aspera/fasp/agent_httpgw.rb +138 -60
- data/lib/aspera/fasp/agent_node.rb +14 -4
- data/lib/aspera/fasp/agent_trsdk.rb +2 -0
- data/lib/aspera/fasp/error_info.rb +2 -0
- data/lib/aspera/fasp/installation.rb +19 -19
- data/lib/aspera/fasp/parameters.rb +29 -20
- data/lib/aspera/fasp/parameters.yaml +5 -2
- data/lib/aspera/fasp/resume_policy.rb +3 -3
- data/lib/aspera/fasp/transfer_spec.rb +8 -5
- data/lib/aspera/fasp/uri.rb +23 -21
- data/lib/aspera/faspex_gw.rb +1 -0
- data/lib/aspera/faspex_postproc.rb +3 -3
- data/lib/aspera/hash_ext.rb +12 -2
- data/lib/aspera/keychain/macos_security.rb +13 -13
- data/lib/aspera/log.rb +1 -0
- data/lib/aspera/node.rb +73 -84
- data/lib/aspera/oauth.rb +4 -3
- data/lib/aspera/persistency_action_once.rb +1 -1
- data/lib/aspera/preview/file_types.rb +8 -6
- data/lib/aspera/preview/generator.rb +23 -11
- data/lib/aspera/preview/options.rb +3 -2
- data/lib/aspera/preview/terminal.rb +80 -0
- data/lib/aspera/preview/utils.rb +11 -11
- data/lib/aspera/proxy_auto_config.js +2 -2
- data/lib/aspera/rest.rb +42 -4
- data/lib/aspera/rest_call_error.rb +3 -1
- data/lib/aspera/secret_hider.rb +10 -5
- data/lib/aspera/ssh.rb +1 -1
- data/lib/aspera/sync.rb +41 -33
- data/lib/aspera/web_server_simple.rb +22 -18
- data.tar.gz.sig +0 -0
- metadata +40 -48
- metadata.gz.sig +0 -0
- data/docs/test_env.conf +0 -179
- data/examples/aoc.rb +0 -30
- data/examples/faspex4.rb +0 -94
- data/examples/node.rb +0 -96
- data/examples/server.rb +0 -93
- data/lib/aspera/data/7 +0 -0
@@ -40,19 +40,15 @@ module Aspera
|
|
40
40
|
CONF_PRESET_GLOBAL = 'global_common_defaults'
|
41
41
|
CONF_PLUGIN_SYM = :config # Plugins::Config.name.split('::').last.downcase.to_sym
|
42
42
|
CONF_GLOBAL_SYM = :config
|
43
|
-
# old tool name
|
44
|
-
PROGRAM_NAME_V1 = 'aslmcli'
|
45
|
-
PROGRAM_NAME_V2 = 'mlia'
|
46
43
|
# default redirect for AoC web auth
|
47
44
|
DEFAULT_REDIRECT = 'http://localhost:12345'
|
48
45
|
# folder containing custom plugins in user's config folder
|
49
46
|
ASPERA_PLUGINS_FOLDERNAME = 'plugins'
|
50
47
|
RUBY_FILE_EXT = '.rb'
|
51
|
-
|
52
|
-
|
53
|
-
AOC_COMMAND_V3 = 'aoc'
|
54
|
-
AOC_COMMAND_CURRENT = AOC_COMMAND_V3
|
48
|
+
ASPERA = 'aspera'
|
49
|
+
AOC_COMMAND = 'aoc'
|
55
50
|
SERVER_COMMAND = 'server'
|
51
|
+
APP_NAME_SDK = 'sdk'
|
56
52
|
CONNECT_WEB_URL = 'https://d3gcli72yxqn2z.cloudfront.net/connect'
|
57
53
|
CONNECT_VERSIONS = 'connectversions.js'
|
58
54
|
TRANSFER_SDK_ARCHIVE_URL = 'https://ibm.biz/aspera_transfer_sdk'
|
@@ -74,20 +70,17 @@ module Aspera
|
|
74
70
|
DEFAULT_CHECK_NEW_VERSION_DAYS = 7
|
75
71
|
DEFAULT_PRIV_KEY_FILENAME = 'aspera_aoc_key' # pragma: allowlist secret
|
76
72
|
DEFAULT_PRIVKEY_LENGTH = 4096
|
73
|
+
COFFEE_IMAGE = 'https://enjoyjava.com/wp-content/uploads/2018/01/How-to-make-strong-coffee.jpg'
|
77
74
|
private_constant :DEFAULT_CONFIG_FILENAME,
|
78
75
|
:CONF_PRESET_CONFIG,
|
79
76
|
:CONF_PRESET_VERSION,
|
80
77
|
:CONF_PRESET_DEFAULT,
|
81
78
|
:CONF_PRESET_GLOBAL,
|
82
|
-
:PROGRAM_NAME_V1,
|
83
|
-
:PROGRAM_NAME_V2,
|
84
79
|
:DEFAULT_REDIRECT,
|
85
80
|
:ASPERA_PLUGINS_FOLDERNAME,
|
86
81
|
:RUBY_FILE_EXT,
|
87
|
-
:
|
88
|
-
:
|
89
|
-
:AOC_COMMAND_V3,
|
90
|
-
:AOC_COMMAND_CURRENT,
|
82
|
+
:ASPERA,
|
83
|
+
:AOC_COMMAND,
|
91
84
|
:DEMO,
|
92
85
|
:TRANSFER_SDK_ARCHIVE_URL,
|
93
86
|
:AOC_PATH_API_CLIENTS,
|
@@ -99,7 +92,8 @@ module Aspera
|
|
99
92
|
:DEFAULT_CHECK_NEW_VERSION_DAYS,
|
100
93
|
:DEFAULT_PRIV_KEY_FILENAME,
|
101
94
|
:SERVER_COMMAND,
|
102
|
-
:PRESET_DIG_SEPARATOR
|
95
|
+
:PRESET_DIG_SEPARATOR,
|
96
|
+
:COFFEE_IMAGE
|
103
97
|
def initialize(env, params)
|
104
98
|
raise 'env and params must be Hash' unless env.is_a?(Hash) && params.is_a?(Hash)
|
105
99
|
raise 'missing param' unless %i[name help version gem].sort.eql?(params.keys.sort)
|
@@ -115,57 +109,63 @@ module Aspera
|
|
115
109
|
@conf_file_default = File.join(@main_folder, DEFAULT_CONFIG_FILENAME)
|
116
110
|
@option_config_file = @conf_file_default
|
117
111
|
@pac_exec = nil
|
112
|
+
@sdk_default_location = false
|
118
113
|
Log.log.debug{"#{@info[:name]} folder: #{@main_folder}"}
|
119
114
|
# set folder for FASP SDK
|
120
115
|
add_plugin_lookup_folder(self.class.gem_plugins_folder)
|
121
116
|
add_plugin_lookup_folder(File.join(@main_folder, ASPERA_PLUGINS_FOLDERNAME))
|
122
117
|
# do file parameter first
|
123
|
-
options.
|
124
|
-
options.add_opt_simple(:config_file, "read parameters from file in YAML format, current=#{@option_config_file}")
|
118
|
+
options.declare(:config_file, "Read parameters from file in YAML format, current=#{@option_config_file}", handler: {o: self, m: :option_config_file})
|
125
119
|
options.parse_options!
|
126
120
|
# read correct file (set @config_presets)
|
127
121
|
read_config_file
|
128
122
|
# add preset handler (needed for smtp)
|
129
|
-
ExtendedValue.instance.set_handler(EXTV_PRESET,
|
130
|
-
ExtendedValue.instance.set_handler(EXTV_INCLUDE_PRESETS,
|
131
|
-
ExtendedValue.instance.set_handler(EXTV_VAULT,
|
123
|
+
ExtendedValue.instance.set_handler(EXTV_PRESET, lambda{|v|preset_by_name(v)})
|
124
|
+
ExtendedValue.instance.set_handler(EXTV_INCLUDE_PRESETS, lambda{|v|expanded_with_preset_includes(v)})
|
125
|
+
ExtendedValue.instance.set_handler(EXTV_VAULT, lambda{|v|vault_value(v)})
|
132
126
|
# load defaults before it can be overridden
|
133
127
|
add_plugin_default_preset(CONF_GLOBAL_SYM)
|
134
128
|
options.parse_options!
|
135
|
-
options.
|
136
|
-
options.
|
137
|
-
options.
|
138
|
-
options.
|
139
|
-
options.
|
140
|
-
options.
|
141
|
-
options.
|
142
|
-
options.
|
143
|
-
options.
|
144
|
-
options.
|
145
|
-
options.
|
146
|
-
options.
|
147
|
-
options.
|
148
|
-
options.
|
149
|
-
options.
|
150
|
-
options.
|
151
|
-
options.
|
152
|
-
options.
|
153
|
-
options.
|
154
|
-
options.
|
155
|
-
options.
|
156
|
-
options.add_opt_simple(:sdk_folder, 'SDK folder path')
|
157
|
-
options.add_opt_simple(:notif_to, 'Email recipient for notification of transfers')
|
158
|
-
options.add_opt_simple(:notif_template, 'Email ERB template for notification of transfers')
|
159
|
-
options.add_opt_simple(:version_check_days, Integer, 'Period in days to check new version (zero to disable)')
|
160
|
-
options.add_opt_simple(:plugin_folder, 'Folder where to find additional plugins')
|
161
|
-
options.set_option(:use_generic_client, true)
|
162
|
-
options.set_option(:test_mode, false)
|
163
|
-
options.set_option(:default, true)
|
164
|
-
options.set_option(:version_check_days, DEFAULT_CHECK_NEW_VERSION_DAYS)
|
165
|
-
options.set_option(:sdk_url, TRANSFER_SDK_ARCHIVE_URL)
|
166
|
-
options.set_option(:sdk_folder, File.join(@main_folder, 'sdk'))
|
167
|
-
options.set_option(:override, :no)
|
129
|
+
options.declare(:no_default, 'Do not load default configuration for plugin', values: :none, short: 'N') { @use_plugin_defaults = false }
|
130
|
+
options.declare(:override, 'Wizard: override existing value', values: :bool, default: :no)
|
131
|
+
options.declare(:use_generic_client, 'Wizard: AoC: use global or org specific jwt client id', values: :bool, default: true)
|
132
|
+
options.declare(:default, 'Wizard: set as default configuration for specified plugin (also: update)', values: :bool, default: true)
|
133
|
+
options.declare(:test_mode, 'Wizard: skip private key check step', values: :bool, default: false)
|
134
|
+
options.declare(:preset, 'Load the named option preset from current config file', short: 'P', handler: {o: self, m: :option_preset})
|
135
|
+
options.declare(:pkeypath, 'Wizard: path to private key for JWT')
|
136
|
+
options.declare(:ascp_path, 'Path to ascp', handler: {o: Fasp::Installation.instance, m: :ascp_path})
|
137
|
+
options.declare(:use_product, 'Use ascp from specified product', handler: {o: self, m: :option_use_product})
|
138
|
+
options.declare(:smtp, 'SMTP configuration', types: Hash)
|
139
|
+
options.declare(:fpac, 'Proxy auto configuration script')
|
140
|
+
options.declare(:proxy_credentials, 'HTTP proxy credentials (Array with user and password)')
|
141
|
+
options.declare(:secret, 'Secret for access keys')
|
142
|
+
options.declare(:vault, 'Vault for secrets')
|
143
|
+
options.declare(:vault_password, 'Vault password')
|
144
|
+
options.declare(:sdk_url, 'URL to get SDK', default: TRANSFER_SDK_ARCHIVE_URL)
|
145
|
+
options.declare(:sdk_folder, 'SDK folder path', handler: {o: Fasp::Installation.instance, m: :sdk_folder})
|
146
|
+
options.declare(:notif_to, 'Email recipient for notification of transfers')
|
147
|
+
options.declare(:notif_template, 'Email ERB template for notification of transfers')
|
148
|
+
options.declare(:version_check_days, 'Period in days to check new version (zero to disable)', coerce: Integer, default: DEFAULT_CHECK_NEW_VERSION_DAYS)
|
149
|
+
options.declare(:plugin_folder, 'Folder where to find additional plugins', handler: {o: self, m: :option_plugin_folder})
|
168
150
|
options.parse_options!
|
151
|
+
# Check SDK folder is set or not, for compatibility, we check in two places
|
152
|
+
sdk_folder = Fasp::Installation.instance.sdk_folder rescue nil
|
153
|
+
if sdk_folder.nil?
|
154
|
+
@sdk_default_location = true
|
155
|
+
Log.log.debug('SDK folder is not set, checking default')
|
156
|
+
# new location
|
157
|
+
sdk_folder = default_app_main_folder(app_name: APP_NAME_SDK)
|
158
|
+
Log.log.debug{"checking: #{sdk_folder}"}
|
159
|
+
if !Dir.exist?(sdk_folder)
|
160
|
+
Log.log.debug{"not exists: #{sdk_folder}"}
|
161
|
+
# former location
|
162
|
+
former_sdk_folder = File.join(default_app_main_folder, APP_NAME_SDK)
|
163
|
+
Log.log.debug{"checking: #{former_sdk_folder}"}
|
164
|
+
sdk_folder = former_sdk_folder if Dir.exist?(former_sdk_folder)
|
165
|
+
end
|
166
|
+
Log.log.debug{"using: #{sdk_folder}"}
|
167
|
+
Fasp::Installation.instance.sdk_folder = sdk_folder
|
168
|
+
end
|
169
169
|
pac_script = options.get_option(:fpac)
|
170
170
|
# create PAC executor
|
171
171
|
@pac_exec = Aspera::ProxyAutoConfig.new(pac_script).register_uri_generic unless pac_script.nil?
|
@@ -184,15 +184,20 @@ module Aspera
|
|
184
184
|
return "#{@info[:name]}_home".upcase
|
185
185
|
end
|
186
186
|
|
187
|
-
|
187
|
+
# return product family folder (~/.aspera)
|
188
|
+
def module_family_folder
|
189
|
+
user_home_folder = Dir.home
|
190
|
+
raise CliError, "Home folder does not exist: #{user_home_folder}. Check your user environment." unless Dir.exist?(user_home_folder)
|
191
|
+
return File.join(user_home_folder, ASPERA_HOME_FOLDER_NAME)
|
192
|
+
end
|
193
|
+
|
194
|
+
# return product config folder (~/.aspera/<name>)
|
195
|
+
def default_app_main_folder(app_name: nil)
|
196
|
+
app_name = @info[:name] if app_name.nil?
|
188
197
|
# find out application main folder
|
189
198
|
app_folder = ENV[conf_dir_env_var]
|
190
199
|
# if env var undefined or empty
|
191
|
-
if app_folder.nil? || app_folder.empty?
|
192
|
-
user_home_folder = Dir.home
|
193
|
-
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)
|
194
|
-
app_folder = File.join(user_home_folder, ASPERA_HOME_FOLDER_NAME, @info[:name])
|
195
|
-
end
|
200
|
+
app_folder = File.join(module_family_folder, app_name) if app_folder.nil? || app_folder.empty?
|
196
201
|
return app_folder
|
197
202
|
end
|
198
203
|
|
@@ -220,7 +225,7 @@ module Aspera
|
|
220
225
|
|
221
226
|
def periodic_check_newer_gem_version
|
222
227
|
# get verification period
|
223
|
-
delay_days = options.get_option(:version_check_days,
|
228
|
+
delay_days = options.get_option(:version_check_days, mandatory: true)
|
224
229
|
Log.log.info{"check days: #{delay_days}"}
|
225
230
|
# check only if not zero day
|
226
231
|
return if delay_days.eql?(0)
|
@@ -281,17 +286,17 @@ module Aspera
|
|
281
286
|
|
282
287
|
private
|
283
288
|
|
284
|
-
def generate_rsa_private_key(private_key_path, length)
|
285
|
-
require 'openssl'
|
286
|
-
priv_key = OpenSSL::PKey::RSA.new(length)
|
287
|
-
File.write(private_key_path, priv_key.to_s)
|
288
|
-
File.write(private_key_path + '.pub', priv_key.public_key.to_s)
|
289
|
-
Environment.restrict_file_access(private_key_path)
|
290
|
-
Environment.restrict_file_access(private_key_path + '.pub')
|
291
|
-
nil
|
292
|
-
end
|
293
|
-
|
294
289
|
class << self
|
290
|
+
def generate_rsa_private_key(path:, length: DEFAULT_PRIVKEY_LENGTH)
|
291
|
+
require 'openssl'
|
292
|
+
priv_key = OpenSSL::PKey::RSA.new(length)
|
293
|
+
File.write(path, priv_key.to_s)
|
294
|
+
File.write(path + '.pub', priv_key.public_key.to_s)
|
295
|
+
Environment.restrict_file_access(path)
|
296
|
+
Environment.restrict_file_access(path + '.pub')
|
297
|
+
nil
|
298
|
+
end
|
299
|
+
|
295
300
|
# folder containing plugins in the gem's main folder
|
296
301
|
def gem_plugins_folder
|
297
302
|
File.dirname(File.expand_path(__FILE__))
|
@@ -350,7 +355,7 @@ module Aspera
|
|
350
355
|
include_path = include_path.clone # avoid messing up if there are multiple branches
|
351
356
|
current = @config_presets
|
352
357
|
config_name.split(PRESET_DIG_SEPARATOR).each do |name|
|
353
|
-
raise CliError, "Expecting Hash for
|
358
|
+
raise CliError, "Expecting Hash for sub key: #{include_path} (#{current.class})" unless current.is_a?(Hash)
|
354
359
|
include_path.push(name)
|
355
360
|
current = current[name]
|
356
361
|
raise CliError, "No such config preset: #{include_path}" if current.nil?
|
@@ -415,43 +420,15 @@ module Aspera
|
|
415
420
|
end
|
416
421
|
end
|
417
422
|
|
418
|
-
def convert_preset_path(old_name, new_name, files_to_copy)
|
419
|
-
old_subpath = File.join('', ASPERA_HOME_FOLDER_NAME, old_name, '')
|
420
|
-
new_subpath = File.join('', ASPERA_HOME_FOLDER_NAME, new_name, '')
|
421
|
-
# convert possible keys located in config folder
|
422
|
-
@config_presets.values.select{|p|p.is_a?(Hash)}.each do |preset|
|
423
|
-
preset.values.select{|v|v.is_a?(String) && v.include?(old_subpath)}.each do |value|
|
424
|
-
old_val = value.clone
|
425
|
-
included_path = File.expand_path(old_val.gsub(/^@file:/, ''))
|
426
|
-
files_to_copy.push(included_path) unless files_to_copy.include?(included_path) || !File.exist?(included_path)
|
427
|
-
value.gsub!(old_subpath, new_subpath)
|
428
|
-
Log.log.warn{"Converted config value: #{old_val} -> #{value}"}
|
429
|
-
end
|
430
|
-
end
|
431
|
-
end
|
432
|
-
|
433
|
-
def convert_preset_plugin_name(old_name, new_name)
|
434
|
-
default_preset = @config_presets[CONF_PRESET_DEFAULT]
|
435
|
-
return unless default_preset.is_a?(Hash) && default_preset.key?(old_name)
|
436
|
-
default_preset[new_name] = default_preset[old_name]
|
437
|
-
default_preset.delete(old_name)
|
438
|
-
Log.log.warn{"Converted plugin default: #{old_name} -> #{new_name}"}
|
439
|
-
end
|
440
|
-
|
441
423
|
# read config file and validate format
|
442
|
-
# tries to convert from older version if possible and required
|
443
424
|
def read_config_file
|
444
425
|
Log.log.debug{"config file is: #{@option_config_file}".red}
|
445
|
-
conf_file_v1 = File.join(Dir.home, ASPERA_HOME_FOLDER_NAME, PROGRAM_NAME_V1, DEFAULT_CONFIG_FILENAME)
|
446
|
-
conf_file_v2 = File.join(Dir.home, ASPERA_HOME_FOLDER_NAME, PROGRAM_NAME_V2, DEFAULT_CONFIG_FILENAME)
|
447
426
|
# files search for configuration, by default the one given by user
|
448
427
|
search_files = [@option_config_file]
|
449
|
-
# if default file, then also look for older versions
|
450
|
-
search_files.push(conf_file_v2, conf_file_v1) if @option_config_file.eql?(@conf_file_default)
|
451
428
|
# find first existing file (or nil)
|
452
429
|
conf_file_to_load = search_files.find{|f| File.exist?(f)}
|
453
430
|
# require save if old version of file
|
454
|
-
save_required =
|
431
|
+
save_required = false
|
455
432
|
# if no file found, create default config
|
456
433
|
if conf_file_to_load.nil?
|
457
434
|
Log.log.warn{"No config file found. Creating empty configuration file: #{@option_config_file}"}
|
@@ -471,32 +448,8 @@ module Aspera
|
|
471
448
|
if version.nil?
|
472
449
|
raise 'No version found in config section.'
|
473
450
|
end
|
474
|
-
# oldest compatible conf file format, update to latest version when an incompatible change is made
|
475
|
-
# check compatibility of version of conf file
|
476
|
-
config_tested_version = '0.4.5'
|
477
|
-
if Gem::Version.new(version) < Gem::Version.new(config_tested_version)
|
478
|
-
raise "Unsupported config file version #{version}. Expecting min version #{config_tested_version}"
|
479
|
-
end
|
480
|
-
config_tested_version = '0.6.15'
|
481
|
-
if Gem::Version.new(version) < Gem::Version.new(config_tested_version)
|
482
|
-
convert_preset_plugin_name(AOC_COMMAND_V1, AOC_COMMAND_V2)
|
483
|
-
version = @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = config_tested_version
|
484
|
-
save_required = true
|
485
|
-
end
|
486
|
-
config_tested_version = '0.8.10'
|
487
|
-
if Gem::Version.new(version) <= Gem::Version.new(config_tested_version)
|
488
|
-
convert_preset_path(PROGRAM_NAME_V1, PROGRAM_NAME_V2, files_to_copy)
|
489
|
-
version = @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = config_tested_version
|
490
|
-
save_required = true
|
491
|
-
end
|
492
|
-
config_tested_version = '1.0'
|
493
|
-
if Gem::Version.new(version) <= Gem::Version.new(config_tested_version)
|
494
|
-
convert_preset_plugin_name(AOC_COMMAND_V2, AOC_COMMAND_V3)
|
495
|
-
convert_preset_path(PROGRAM_NAME_V2, @info[:name], files_to_copy)
|
496
|
-
version = @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = config_tested_version
|
497
|
-
save_required = true
|
498
|
-
end
|
499
451
|
Log.log.debug{"conf version: #{version}"}
|
452
|
+
# if there are any conversion needed, those happen here.
|
500
453
|
# Place new compatibility code here
|
501
454
|
if save_required
|
502
455
|
Log.log.warn('Saving automatic conversion.')
|
@@ -550,13 +503,18 @@ module Aspera
|
|
550
503
|
@plugins[plugin_symbol] = {source: path, require_stanza: req}
|
551
504
|
end
|
552
505
|
|
553
|
-
|
506
|
+
# Find a plugin, and issue the "require"
|
507
|
+
# @return [Hash] plugin info: { product: , url:, version: }
|
508
|
+
def identify_plugin_for_url(url, check_only: nil)
|
509
|
+
check_only = check_only.to_sym unless check_only.nil?
|
554
510
|
plugins.each do |plugin_name_sym, plugin_info|
|
555
511
|
# no detection for internal plugin
|
556
512
|
next if plugin_name_sym.eql?(CONF_PLUGIN_SYM)
|
513
|
+
next if check_only && !check_only.eql?(plugin_name_sym)
|
557
514
|
# load plugin class
|
558
515
|
require plugin_info[:require_stanza]
|
559
516
|
c = self.class.plugin_class(plugin_name_sym)
|
517
|
+
# requires detection method
|
560
518
|
next unless c.respond_to?(:detect)
|
561
519
|
current_url = url
|
562
520
|
detection_info = nil
|
@@ -565,7 +523,7 @@ module Aspera
|
|
565
523
|
detection_info = c.detect(current_url)
|
566
524
|
rescue OpenSSL::SSL::SSLError => e
|
567
525
|
Log.log.warn(e.message)
|
568
|
-
Log.log.warn('Use option --insecure=yes to
|
526
|
+
Log.log.warn('Use option --insecure=yes to allow unchecked certificate') if e.message.include?('cert')
|
569
527
|
rescue StandardError => e
|
570
528
|
Log.log.debug{"Cannot detect #{plugin_name_sym} : #{e.class}/#{e.message}"}
|
571
529
|
end
|
@@ -674,6 +632,10 @@ module Aspera
|
|
674
632
|
end
|
675
633
|
end
|
676
634
|
data['keypass'] = Fasp::Installation.instance.bypass_pass
|
635
|
+
# log is "-" no need to display
|
636
|
+
data.delete('log')
|
637
|
+
# show command line transfer spec
|
638
|
+
data['ts'] = transfer.updated_ts
|
677
639
|
return {type: :single_object, data: data}
|
678
640
|
when :products
|
679
641
|
command = options.get_next_command(%i[list use])
|
@@ -687,7 +649,9 @@ module Aspera
|
|
687
649
|
return Main.result_status("Saved to default global preset #{preset_name}")
|
688
650
|
end
|
689
651
|
when :install
|
690
|
-
|
652
|
+
# reset to default location, if older default was used
|
653
|
+
Fasp::Installation.instance.sdk_folder = default_app_main_folder(app_name: APP_NAME_SDK) if @sdk_default_location
|
654
|
+
v = Fasp::Installation.instance.install_sdk(options.get_option(:sdk_url, mandatory: true))
|
691
655
|
return Main.result_status("Installed version #{v}")
|
692
656
|
when :spec
|
693
657
|
return {
|
@@ -747,6 +711,7 @@ module Aspera
|
|
747
711
|
when :set
|
748
712
|
param_name = options.get_next_argument('parameter name')
|
749
713
|
param_value = options.get_next_argument('parameter value')
|
714
|
+
param_name = Manager.option_line_to_name(param_name)
|
750
715
|
if !@config_presets.key?(name)
|
751
716
|
Log.log.debug{"no such config name: #{name}, initializing"}
|
752
717
|
selected_preset = @config_presets[name] = {}
|
@@ -786,8 +751,8 @@ module Aspera
|
|
786
751
|
return Main.result_status("Updated: #{name}")
|
787
752
|
when :lookup
|
788
753
|
BasicAuthPlugin.register_options(@agents)
|
789
|
-
url = options.get_option(:url,
|
790
|
-
user = options.get_option(:username,
|
754
|
+
url = options.get_option(:url, mandatory: true)
|
755
|
+
user = options.get_option(:username, mandatory: true)
|
791
756
|
result = lookup_preset(url: url, username: user)
|
792
757
|
raise 'no such config found' if result.nil?
|
793
758
|
return {type: :single_object, data: result}
|
@@ -820,7 +785,6 @@ module Aspera
|
|
820
785
|
end
|
821
786
|
|
822
787
|
ACTIONS = %i[
|
823
|
-
id
|
824
788
|
preset
|
825
789
|
open
|
826
790
|
documentation
|
@@ -830,7 +794,6 @@ module Aspera
|
|
830
794
|
flush_tokens
|
831
795
|
echo
|
832
796
|
wizard
|
833
|
-
export_to_cli
|
834
797
|
detect
|
835
798
|
coffee
|
836
799
|
ascp
|
@@ -841,19 +804,12 @@ module Aspera
|
|
841
804
|
file
|
842
805
|
check_update
|
843
806
|
initdemo
|
844
|
-
vault].
|
807
|
+
vault].freeze
|
845
808
|
|
846
809
|
# "config" plugin
|
847
810
|
def execute_action
|
848
811
|
action = options.get_next_command(ACTIONS)
|
849
812
|
case action
|
850
|
-
when *PRESET_GBL_ACTIONS # older syntax
|
851
|
-
Log.log.warn{"This syntax is deprecated, use command: preset #{action}"}
|
852
|
-
return execute_preset(action: action)
|
853
|
-
when :id # older syntax
|
854
|
-
identifier = options.get_next_argument('config name')
|
855
|
-
Log.log.warn{"This syntax is deprecated, use command: preset <verb> #{identifier}"}
|
856
|
-
return execute_preset(name: identifier)
|
857
813
|
when :preset # newer syntax
|
858
814
|
return execute_preset
|
859
815
|
when :open
|
@@ -867,7 +823,7 @@ module Aspera
|
|
867
823
|
when :genkey # generate new rsa key
|
868
824
|
private_key_path = options.get_next_argument('private key file path')
|
869
825
|
private_key_length = options.get_next_argument('size in bits', mandatory: false) || DEFAULT_PRIVKEY_LENGTH
|
870
|
-
generate_rsa_private_key(private_key_path, private_key_length)
|
826
|
+
self.class.generate_rsa_private_key(path: private_key_path, length: private_key_length)
|
871
827
|
return Main.result_status('Generated key: ' + private_key_path)
|
872
828
|
when :echo # display the content of a value given on command line
|
873
829
|
result = {type: :other_struct, data: options.get_next_argument('value')}
|
@@ -909,72 +865,89 @@ module Aspera
|
|
909
865
|
BasicAuthPlugin.register_options(@agents)
|
910
866
|
params = {}
|
911
867
|
# get from option, or ask
|
912
|
-
params[:instance_url] = options.get_option(:url,
|
868
|
+
params[:instance_url] = options.get_option(:url, mandatory: true)
|
869
|
+
# check it is a well formatted url: starts with scheme
|
870
|
+
if !params[:instance_url].match?(%r{^[a-z]{1,6}://})
|
871
|
+
new_url = "https://#{params[:instance_url]}"
|
872
|
+
Log.log.warn("URL #{params[:instance_url]} does not start with a scheme, using #{new_url}")
|
873
|
+
params[:instance_url] = new_url
|
874
|
+
end
|
913
875
|
# allow user to tell the preset name
|
914
876
|
params[:preset_name] = options.get_option(:id)
|
915
|
-
# allow user to specify type of application
|
916
|
-
params[:
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
877
|
+
# allow user to specify type of application (symbol)
|
878
|
+
identification = identify_plugin_for_url(params[:instance_url], check_only: value_or_query(allowed_types: String))
|
879
|
+
Log.log.debug{"Detected: #{identification}"}
|
880
|
+
formatter.display_status("Detected: #{identification[:name]} at #{identification[:url]}".bold)
|
881
|
+
# we detected application (not set by user)
|
882
|
+
params[:plugin_sym] = identification[:product]
|
883
|
+
# update the url option
|
884
|
+
params[:instance_url] = identification[:url]
|
885
|
+
options.set_option(:url, params[:instance_url])
|
886
|
+
# instantiate plugin: command line options are known and wizard can be called
|
887
|
+
plugin_instance = self.class.plugin_class(params[:plugin_sym]).new(@agents.merge({skip_basic_auth_options: true}))
|
888
|
+
raise CliBadArgument, "Detected: #{params[:plugin_sym]}, no wizard available for this application" unless plugin_instance.respond_to?(:wizard)
|
889
|
+
# get default preset name if not set by user
|
890
|
+
params[:prepare] = true
|
891
|
+
plugin_instance.send(:wizard, params)
|
892
|
+
params[:prepare] = false
|
893
|
+
|
894
|
+
if params[:need_private_key]
|
895
|
+
# lets see if path to priv key is provided
|
896
|
+
private_key_path = options.get_option(:pkeypath)
|
897
|
+
# give a chance to provide
|
898
|
+
if private_key_path.nil?
|
899
|
+
formatter.display_status('Please provide path to your private RSA key, or empty to generate one:')
|
900
|
+
private_key_path = options.get_option(:pkeypath, mandatory: true).to_s
|
901
|
+
# private_key_path = File.expand_path(private_key_path)
|
902
|
+
end
|
903
|
+
# else generate path
|
904
|
+
if private_key_path.empty?
|
905
|
+
private_key_path = File.join(@main_folder, DEFAULT_PRIV_KEY_FILENAME)
|
906
|
+
end
|
907
|
+
if File.exist?(private_key_path)
|
908
|
+
formatter.display_status('Using existing key:')
|
909
|
+
else
|
910
|
+
formatter.display_status("Generating #{DEFAULT_PRIVKEY_LENGTH} bit RSA key...")
|
911
|
+
Config.generate_rsa_private_key(path: private_key_path)
|
912
|
+
formatter.display_status('Created key:')
|
913
|
+
end
|
914
|
+
formatter.display_status(private_key_path)
|
915
|
+
params[:pub_key_pem] = OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
|
916
|
+
params[:private_key_path] = private_key_path
|
917
|
+
end
|
918
|
+
|
919
|
+
formatter.display_status("Preparing preset: #{params[:preset_name]}")
|
920
|
+
# init defaults if necessary
|
921
|
+
@config_presets[CONF_PRESET_DEFAULT] ||= {}
|
922
|
+
option_override = options.get_option(:override, mandatory: true)
|
923
|
+
raise CliError, "A default configuration already exists for plugin '#{params[:plugin_sym]}' (use --override=yes or --default=no)" \
|
924
|
+
if !option_override && options.get_option(:default, mandatory: true) && @config_presets[CONF_PRESET_DEFAULT].key?(params[:plugin_sym])
|
925
|
+
raise CliError, "Preset already exists: #{params[:preset_name]} (use --override=yes or --id=<name>)" \
|
926
|
+
if !option_override && @config_presets.key?(params[:preset_name])
|
927
|
+
wizard_result = plugin_instance.send(:wizard, params)
|
928
|
+
Log.log.debug{"wizard result: #{wizard_result}"}
|
929
|
+
raise "Internal error: missing keys in wizard result: #{wizard_result.keys}" unless %i[preset_value test_args].eql?(wizard_result.keys.sort)
|
930
|
+
@config_presets[params[:preset_name]] = wizard_result[:preset_value].stringify_keys
|
931
|
+
params[:test_args] = wizard_result[:test_args]
|
932
|
+
if options.get_option(:default, mandatory: true)
|
933
|
+
formatter.display_status("Setting config preset as default for #{params[:plugin_sym]}")
|
934
|
+
@config_presets[CONF_PRESET_DEFAULT][params[:plugin_sym].to_s] = params[:preset_name]
|
931
935
|
else
|
932
936
|
params[:test_args] = "-P#{params[:preset_name]} #{params[:test_args]}"
|
933
937
|
end
|
934
938
|
formatter.display_status('Saving config file.')
|
935
939
|
save_presets_to_config_file
|
936
940
|
return Main.result_status("Done.\nYou can test with:\n#{@info[:name]} #{params[:test_args]}")
|
937
|
-
when :export_to_cli # this method shall be deprecated in the future: it was used to export configuration to "aspera.exe" CLI
|
938
|
-
formatter.display_status('Exporting: Aspera on Cloud')
|
939
|
-
require 'aspera/cli/plugins/aoc'
|
940
|
-
# need url / username
|
941
|
-
add_plugin_default_preset(AOC_COMMAND_V3.to_sym)
|
942
|
-
# instantiate AoC plugin
|
943
|
-
self.class.plugin_class(AOC_COMMAND_CURRENT).new(@agents) # TODO: is this line needed ? get options ?
|
944
|
-
url = options.get_option(:url, is_type: :mandatory)
|
945
|
-
cli_conf_file = Fasp::Installation.instance.cli_conf_file
|
946
|
-
data = JSON.parse(File.read(cli_conf_file))
|
947
|
-
organization, instance_domain = AoC.parse_url(url)
|
948
|
-
key_basename = 'org_' + organization + '.pem'
|
949
|
-
key_file = File.join(File.dirname(File.dirname(cli_conf_file)), 'etc', key_basename)
|
950
|
-
File.write(key_file, options.get_option(:private_key, is_type: :mandatory))
|
951
|
-
new_conf = {
|
952
|
-
'organization' => organization,
|
953
|
-
'hostname' => [organization, instance_domain].join('.'),
|
954
|
-
'privateKeyFilename' => key_basename,
|
955
|
-
'username' => options.get_option(:username, is_type: :mandatory)
|
956
|
-
}
|
957
|
-
new_conf['clientId'] = options.get_option(:client_id)
|
958
|
-
new_conf['clientSecret'] = options.get_option(:client_secret)
|
959
|
-
if new_conf['clientId'].nil?
|
960
|
-
new_conf['clientId'], new_conf['clientSecret'] = AoC.get_client_info
|
961
|
-
end
|
962
|
-
entry = data['AoCAccounts'].find{|i|i['organization'].eql?(organization)}
|
963
|
-
if entry.nil?
|
964
|
-
data['AoCAccounts'].push(new_conf)
|
965
|
-
formatter.display_status("Creating new aoc entry: #{organization}")
|
966
|
-
else
|
967
|
-
formatter.display_status("Updating existing aoc entry: #{organization}")
|
968
|
-
entry.merge!(new_conf)
|
969
|
-
end
|
970
|
-
File.write(cli_conf_file, JSON.pretty_generate(data))
|
971
|
-
return Main.result_status("Updated: #{cli_conf_file}")
|
972
941
|
when :detect
|
973
942
|
# need url / username
|
974
943
|
BasicAuthPlugin.register_options(@agents)
|
975
|
-
return {type: :single_object, data: identify_plugin_for_url(options.get_option(:url,
|
944
|
+
return {type: :single_object, data: identify_plugin_for_url(options.get_option(:url, mandatory: true))}
|
976
945
|
when :coffee
|
977
|
-
OpenApplication.instance.
|
946
|
+
if OpenApplication.instance.url_method.eql?(:text)
|
947
|
+
require 'aspera/preview/terminal'
|
948
|
+
return Main.result_status(Preview::Terminal.build(Rest.new(base_url: COFFEE_IMAGE).read('')[:http].body, reserved_lines: 3))
|
949
|
+
end
|
950
|
+
OpenApplication.instance.uri(COFFEE_IMAGE)
|
978
951
|
return Main.result_nothing
|
979
952
|
when :ascp
|
980
953
|
execute_action_ascp
|
@@ -995,7 +968,7 @@ module Aspera
|
|
995
968
|
return {type: :single_object, data: email_settings}
|
996
969
|
when :proxy_check
|
997
970
|
# ensure fpac was provided
|
998
|
-
options.get_option(:fpac,
|
971
|
+
options.get_option(:fpac, mandatory: true)
|
999
972
|
server_url = options.get_next_argument('server url')
|
1000
973
|
return Main.result_status(@pac_exec.find_proxy_for_url(server_url))
|
1001
974
|
when :check_update
|
@@ -1007,8 +980,8 @@ module Aspera
|
|
1007
980
|
Log.log.info{"Creating Demo server preset: #{DEMO_SERVER_PRESET}"}
|
1008
981
|
@config_presets[DEMO_SERVER_PRESET] = {
|
1009
982
|
'url' => 'ssh://' + DEMO + '.asperasoft.com:33001',
|
1010
|
-
'username' =>
|
1011
|
-
'ssAP'.downcase.reverse + 'drow'.reverse => DEMO +
|
983
|
+
'username' => ASPERA,
|
984
|
+
'ssAP'.downcase.reverse + 'drow'.reverse => DEMO + ASPERA # cspell:disable-line
|
1012
985
|
}
|
1013
986
|
end
|
1014
987
|
@config_presets[CONF_PRESET_DEFAULT] ||= {}
|
@@ -1029,18 +1002,24 @@ module Aspera
|
|
1029
1002
|
|
1030
1003
|
# @return email server setting with defaults if not defined
|
1031
1004
|
def email_settings
|
1032
|
-
smtp = options.get_option(:smtp,
|
1005
|
+
smtp = options.get_option(:smtp, mandatory: true, allowed_types: [Hash])
|
1033
1006
|
# change string keys into symbol keys
|
1034
|
-
smtp = smtp.
|
1007
|
+
smtp = smtp.symbolize_keys
|
1035
1008
|
# defaults
|
1036
|
-
smtp[:tls]
|
1037
|
-
smtp[:port] ||= smtp[:tls]
|
1009
|
+
smtp[:tls] = !smtp[:ssl] unless smtp.key?(:tls)
|
1010
|
+
smtp[:port] ||= if smtp[:tls]
|
1011
|
+
587
|
1012
|
+
elsif smtp[:ssl]
|
1013
|
+
465
|
1014
|
+
else
|
1015
|
+
25
|
1016
|
+
end
|
1038
1017
|
smtp[:from_email] ||= smtp[:username] if smtp.key?(:username)
|
1039
1018
|
smtp[:from_name] ||= smtp[:from_email].gsub(/@.*$/, '').gsub(/[^a-zA-Z]/, ' ').capitalize if smtp.key?(:username)
|
1040
1019
|
smtp[:domain] ||= smtp[:from_email].gsub(/^.*@/, '') if smtp.key?(:from_email)
|
1041
1020
|
# check minimum required
|
1042
1021
|
%i[server port domain].each do |n|
|
1043
|
-
raise "Missing smtp parameter: #{n}" unless smtp.key?(n)
|
1022
|
+
raise "Missing mandatory smtp parameter: #{n}" unless smtp.key?(n)
|
1044
1023
|
end
|
1045
1024
|
Log.log.debug{"smtp=#{smtp}"}
|
1046
1025
|
return smtp
|
@@ -1052,8 +1031,8 @@ module Aspera
|
|
1052
1031
|
end
|
1053
1032
|
|
1054
1033
|
def send_email_template(email_template_default: nil, values: {})
|
1055
|
-
values[:to] ||= options.get_option(:notif_to,
|
1056
|
-
notif_template = options.get_option(:notif_template,
|
1034
|
+
values[:to] ||= options.get_option(:notif_to, mandatory: true)
|
1035
|
+
notif_template = options.get_option(:notif_template, mandatory: email_template_default.nil?) || email_template_default
|
1057
1036
|
mail_conf = email_settings
|
1058
1037
|
values[:from_name] ||= mail_conf[:from_name]
|
1059
1038
|
values[:from_email] ||= mail_conf[:from_email]
|
@@ -1074,6 +1053,7 @@ module Aspera
|
|
1074
1053
|
Log.dump(:msg_with_headers, msg_with_headers)
|
1075
1054
|
smtp = Net::SMTP.new(mail_conf[:server], mail_conf[:port])
|
1076
1055
|
smtp.enable_starttls if mail_conf[:tls]
|
1056
|
+
smtp.enable_tls if mail_conf[:ssl]
|
1077
1057
|
smtp.start(*start_options) do |smtp_session|
|
1078
1058
|
smtp_session.send_message(msg_with_headers, values[:from_email], values[:to])
|
1079
1059
|
end
|
@@ -1090,20 +1070,20 @@ module Aspera
|
|
1090
1070
|
|
1091
1071
|
# returns [String] name if config_presets has default
|
1092
1072
|
# returns nil if there is no config or bypass default params
|
1093
|
-
def get_plugin_default_config_name(
|
1073
|
+
def get_plugin_default_config_name(plugin_name_sym)
|
1094
1074
|
raise 'internal error: config_presets shall be defined' if @config_presets.nil?
|
1095
1075
|
if !@use_plugin_defaults
|
1096
1076
|
Log.log.debug('skip default config')
|
1097
1077
|
return nil
|
1098
1078
|
end
|
1099
1079
|
if @config_presets.key?(CONF_PRESET_DEFAULT) &&
|
1100
|
-
@config_presets[CONF_PRESET_DEFAULT].key?(
|
1101
|
-
default_config_name = @config_presets[CONF_PRESET_DEFAULT][
|
1080
|
+
@config_presets[CONF_PRESET_DEFAULT].key?(plugin_name_sym.to_s)
|
1081
|
+
default_config_name = @config_presets[CONF_PRESET_DEFAULT][plugin_name_sym.to_s]
|
1102
1082
|
if !@config_presets.key?(default_config_name)
|
1103
1083
|
Log.log.error do
|
1104
|
-
"Default config name [#{default_config_name}] specified for plugin [#{
|
1084
|
+
"Default config name [#{default_config_name}] specified for plugin [#{plugin_name_sym}], but it does not exist in config file.\n"\
|
1105
1085
|
'Please fix the issue: either create preset with one parameter: '\
|
1106
|
-
"(#{@info[:name]} config id #{default_config_name} init @json:'{}') or remove default (#{@info[:name]} config id default remove #{
|
1086
|
+
"(#{@info[:name]} config id #{default_config_name} init @json:'{}') or remove default (#{@info[:name]} config id default remove #{plugin_name_sym})."
|
1107
1087
|
end
|
1108
1088
|
end
|
1109
1089
|
raise CliError, "Config name [#{default_config_name}] must be a hash, check config file." if !@config_presets[default_config_name].is_a?(Hash)
|
@@ -1153,7 +1133,7 @@ module Aspera
|
|
1153
1133
|
def vault
|
1154
1134
|
if @vault.nil?
|
1155
1135
|
vault_info = options.get_option(:vault) || {'type' => 'file', 'name' => 'vault.bin'}
|
1156
|
-
vault_password = options.get_option(:vault_password,
|
1136
|
+
vault_password = options.get_option(:vault_password, mandatory: true)
|
1157
1137
|
raise 'vault must be Hash' unless vault_info.is_a?(Hash)
|
1158
1138
|
vault_type = vault_info['type'] || 'file'
|
1159
1139
|
vault_name = vault_info['name'] || (vault_type.eql?('file') ? 'vault.bin' : PROGRAM_NAME)
|
@@ -1207,169 +1187,6 @@ module Aspera
|
|
1207
1187
|
end
|
1208
1188
|
return secret
|
1209
1189
|
end
|
1210
|
-
|
1211
|
-
def wizard_aoc(params)
|
1212
|
-
formatter.display_status('Detected: Aspera on Cloud'.bold)
|
1213
|
-
params[:plugin_name] = AOC_COMMAND_CURRENT
|
1214
|
-
organization = AoC.parse_url(params[:instance_url]).first
|
1215
|
-
# if not defined by user, generate name
|
1216
|
-
params[:preset_name] = [params[:application], organization].join('_') if params[:preset_name].nil?
|
1217
|
-
formatter.display_status("Preparing preset: #{params[:preset_name]}")
|
1218
|
-
# init defaults if necessary
|
1219
|
-
@config_presets[CONF_PRESET_DEFAULT] ||= {}
|
1220
|
-
option_override = options.get_option(:override, is_type: :mandatory)
|
1221
|
-
params[:option_default] = options.get_option(:default, is_type: :mandatory)
|
1222
|
-
Log.log.error{"override=#{option_override} -> #{option_override.class}"}
|
1223
|
-
raise CliError, "A default configuration already exists for plugin '#{params[:plugin_name]}' (use --override=yes or --default=no)" \
|
1224
|
-
if !option_override && params[:option_default] && @config_presets[CONF_PRESET_DEFAULT].key?(params[:plugin_name])
|
1225
|
-
raise CliError, "Preset already exists: #{params[:preset_name]} (use --override=yes or --id=<name>)" \
|
1226
|
-
if !option_override && @config_presets.key?(params[:preset_name])
|
1227
|
-
# lets see if path to priv key is provided
|
1228
|
-
private_key_path = options.get_option(:pkeypath)
|
1229
|
-
# give a chance to provide
|
1230
|
-
if private_key_path.nil?
|
1231
|
-
formatter.display_status('Please provide path to your private RSA key, or empty to generate one:')
|
1232
|
-
private_key_path = options.get_option(:pkeypath, is_type: :mandatory).to_s
|
1233
|
-
end
|
1234
|
-
# else generate path
|
1235
|
-
if private_key_path.empty?
|
1236
|
-
private_key_path = File.join(@main_folder, DEFAULT_PRIV_KEY_FILENAME)
|
1237
|
-
end
|
1238
|
-
if File.exist?(private_key_path)
|
1239
|
-
formatter.display_status('Using existing key:')
|
1240
|
-
else
|
1241
|
-
formatter.display_status("Generating #{DEFAULT_PRIVKEY_LENGTH} bit RSA key...")
|
1242
|
-
generate_rsa_private_key(private_key_path, DEFAULT_PRIVKEY_LENGTH)
|
1243
|
-
formatter.display_status('Created:')
|
1244
|
-
end
|
1245
|
-
formatter.display_status(private_key_path)
|
1246
|
-
pub_key_pem = OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
|
1247
|
-
# declare command line options for AoC
|
1248
|
-
require 'aspera/cli/plugins/aoc'
|
1249
|
-
# make username mandatory for jwt, this triggers interactive input
|
1250
|
-
options.get_option(:username, is_type: :mandatory)
|
1251
|
-
# instantiate AoC plugin, so that command line options are known
|
1252
|
-
aoc_api = self.class.plugin_class(params[:plugin_name]).new(@agents.merge({skip_basic_auth_options: true, private_key_path: private_key_path})).aoc_api
|
1253
|
-
auto_set_pub_key = false
|
1254
|
-
auto_set_jwt = false
|
1255
|
-
use_browser_authentication = false
|
1256
|
-
if options.get_option(:use_generic_client)
|
1257
|
-
formatter.display_status('Using global client_id.')
|
1258
|
-
formatter.display_status('Please Login to your Aspera on Cloud instance.'.red)
|
1259
|
-
formatter.display_status('Navigate to your "Account Settings"'.red)
|
1260
|
-
formatter.display_status('Check or update the value of "Public Key" to be:'.red.blink)
|
1261
|
-
formatter.display_status(pub_key_pem.to_s)
|
1262
|
-
if !options.get_option(:test_mode)
|
1263
|
-
formatter.display_status('Once updated or validated, press enter.')
|
1264
|
-
OpenApplication.instance.uri(params[:instance_url])
|
1265
|
-
$stdin.gets
|
1266
|
-
end
|
1267
|
-
else
|
1268
|
-
formatter.display_status('Using organization specific client_id.')
|
1269
|
-
if options.get_option(:client_id).nil? || options.get_option(:client_secret, is_type: :optional).nil?
|
1270
|
-
formatter.display_status('Please login to your Aspera on Cloud instance.'.red)
|
1271
|
-
formatter.display_status('Go to: Apps->Admin->Organization->Integrations')
|
1272
|
-
formatter.display_status('Create or check if there is an existing integration named:')
|
1273
|
-
formatter.display_status("- name: #{@info[:name]}")
|
1274
|
-
formatter.display_status("- redirect uri: #{DEFAULT_REDIRECT}")
|
1275
|
-
formatter.display_status('- origin: localhost')
|
1276
|
-
formatter.display_status('Once created or identified,')
|
1277
|
-
formatter.display_status('Please enter:'.red)
|
1278
|
-
end
|
1279
|
-
OpenApplication.instance.uri("#{params[:instance_url]}/#{AOC_PATH_API_CLIENTS}")
|
1280
|
-
options.get_option(:client_id, is_type: :mandatory)
|
1281
|
-
options.get_option(:client_secret, is_type: :mandatory)
|
1282
|
-
use_browser_authentication = true
|
1283
|
-
end
|
1284
|
-
if use_browser_authentication
|
1285
|
-
formatter.display_status('We will use web authentication to bootstrap.')
|
1286
|
-
auto_set_pub_key = true
|
1287
|
-
auto_set_jwt = true
|
1288
|
-
aoc_api.oauth.generic_parameters[:grant_method] = :web
|
1289
|
-
aoc_api.oauth.generic_parameters[:scope] = AoC::SCOPE_FILES_ADMIN
|
1290
|
-
aoc_api.oauth.specific_parameters[:redirect_uri] = DEFAULT_REDIRECT
|
1291
|
-
end
|
1292
|
-
myself = aoc_api.read('self')[:data]
|
1293
|
-
if auto_set_pub_key
|
1294
|
-
raise CliError, 'Public key is already set in profile (use --override=yes)' unless myself['public_key'].empty? || option_override
|
1295
|
-
formatter.display_status('Updating profile with new key')
|
1296
|
-
aoc_api.update("users/#{myself['id']}", {'public_key' => pub_key_pem})
|
1297
|
-
end
|
1298
|
-
if auto_set_jwt
|
1299
|
-
formatter.display_status('Enabling JWT for client')
|
1300
|
-
aoc_api.update("clients/#{options.get_option(:client_id)}", {'jwt_grant_enabled' => true, 'explicit_authorization_required' => false})
|
1301
|
-
end
|
1302
|
-
formatter.display_status("Creating new config preset: #{params[:preset_name]}")
|
1303
|
-
@config_presets[params[:preset_name]] = {
|
1304
|
-
:url.to_s => options.get_option(:url),
|
1305
|
-
:username.to_s => myself['email'],
|
1306
|
-
:auth.to_s => :jwt.to_s,
|
1307
|
-
:private_key.to_s => '@file:' + private_key_path
|
1308
|
-
}
|
1309
|
-
# set only if non nil
|
1310
|
-
%i[client_id client_secret].each do |s|
|
1311
|
-
o = options.get_option(s)
|
1312
|
-
@config_presets[params[:preset_name]][s.to_s] = o unless o.nil?
|
1313
|
-
end
|
1314
|
-
params[:test_args] = "#{params[:plugin_name]} user profile show"
|
1315
|
-
end
|
1316
|
-
|
1317
|
-
def wizard_faspex5(params)
|
1318
|
-
formatter.display_status('Detected: Faspex v5'.bold)
|
1319
|
-
# if not defined by user, generate unique name
|
1320
|
-
params[:preset_name] = [params[:application]].concat(URI.parse(params[:instance_url]).host.gsub(/[^a-z0-9.]/, '').split('.')).join('_') \
|
1321
|
-
if params[:preset_name].nil?
|
1322
|
-
formatter.display_status("Preparing preset: #{params[:preset_name]}")
|
1323
|
-
# init defaults if necessary
|
1324
|
-
@config_presets[CONF_PRESET_DEFAULT] ||= {}
|
1325
|
-
option_override = options.get_option(:override, is_type: :mandatory)
|
1326
|
-
params[:option_default] = options.get_option(:default, is_type: :mandatory)
|
1327
|
-
Log.log.error{"override=#{option_override} -> #{option_override.class}"}
|
1328
|
-
raise CliError, "A default configuration already exists for plugin '#{params[:plugin_name]}' (use --override=yes or --default=no)" \
|
1329
|
-
if !option_override && params[:option_default] && @config_presets[CONF_PRESET_DEFAULT].key?(params[:plugin_name])
|
1330
|
-
raise CliError, "Preset already exists: #{params[:preset_name]} (use --override=yes or --id=<name>)" \
|
1331
|
-
if !option_override && @config_presets.key?(params[:preset_name])
|
1332
|
-
# lets see if path to priv key is provided
|
1333
|
-
private_key_path = options.get_option(:pkeypath)
|
1334
|
-
# give a chance to provide
|
1335
|
-
if private_key_path.nil?
|
1336
|
-
formatter.display_status('Please provide path to your private RSA key, or empty to generate one:')
|
1337
|
-
private_key_path = options.get_option(:pkeypath, is_type: :mandatory).to_s
|
1338
|
-
end
|
1339
|
-
# else generate path
|
1340
|
-
if private_key_path.empty?
|
1341
|
-
private_key_path = File.join(@main_folder, DEFAULT_PRIV_KEY_FILENAME)
|
1342
|
-
end
|
1343
|
-
if File.exist?(private_key_path)
|
1344
|
-
formatter.display_status('Using existing key:')
|
1345
|
-
else
|
1346
|
-
formatter.display_status("Generating #{DEFAULT_PRIVKEY_LENGTH} bit RSA key...")
|
1347
|
-
generate_rsa_private_key(private_key_path, DEFAULT_PRIVKEY_LENGTH)
|
1348
|
-
formatter.display_status('Created:')
|
1349
|
-
end
|
1350
|
-
formatter.display_status(private_key_path)
|
1351
|
-
pub_key_pem = OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
|
1352
|
-
# declare command line options for AoC
|
1353
|
-
require 'aspera/cli/plugins/faspex5'
|
1354
|
-
self.class.plugin_class(params[:plugin_name]).new(@agents.merge({skip_basic_auth_options: true}))
|
1355
|
-
formatter.display_status('Please login to Faspex 5.'.red)
|
1356
|
-
OpenApplication.instance.uri(params[:instance_url])
|
1357
|
-
formatter.display_status('Navigate to: 𓃑 → Admin → Configurations → API clients')
|
1358
|
-
formatter.display_status('Create a client with:')
|
1359
|
-
formatter.display_status('- JWT enabled')
|
1360
|
-
formatter.display_status('- The following public key:')
|
1361
|
-
formatter.display_status(pub_key_pem.to_s)
|
1362
|
-
formatter.display_status('Once created, copy the following parameters:')
|
1363
|
-
@config_presets[params[:preset_name]] = {
|
1364
|
-
:url.to_s => options.get_option(:url),
|
1365
|
-
:username.to_s => options.get_option(:username),
|
1366
|
-
:auth.to_s => :jwt.to_s,
|
1367
|
-
:private_key.to_s => '@file:' + private_key_path,
|
1368
|
-
:client_id.to_s => options.get_option(:client_id, is_type: :mandatory),
|
1369
|
-
:client_secret.to_s => options.get_option(:client_secret, is_type: :mandatory)
|
1370
|
-
}
|
1371
|
-
params[:test_args] = "#{params[:plugin_name]} user profile show"
|
1372
|
-
end
|
1373
1190
|
end
|
1374
1191
|
end
|
1375
1192
|
end
|