aspera-cli 4.10.0 → 4.12.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/BUGS.md +19 -0
- data/CHANGELOG.md +528 -0
- data/CONTRIBUTING.md +143 -0
- data/README.md +977 -589
- data/bin/ascli +4 -4
- data/bin/asession +12 -12
- data/docs/test_env.conf +29 -19
- data/examples/aoc.rb +6 -6
- data/examples/dascli +18 -16
- data/examples/faspex4.rb +15 -15
- data/examples/node.rb +12 -12
- data/examples/proxy.pac +2 -2
- data/examples/server.rb +12 -12
- data/lib/aspera/aoc.rb +344 -272
- data/lib/aspera/ascmd.rb +56 -54
- data/lib/aspera/ats_api.rb +4 -4
- data/lib/aspera/cli/basic_auth_plugin.rb +15 -12
- data/lib/aspera/cli/extended_value.rb +9 -9
- data/lib/aspera/cli/{formater.rb → formatter.rb} +69 -69
- data/lib/aspera/cli/listener/line_dump.rb +1 -1
- data/lib/aspera/cli/listener/logger.rb +1 -1
- data/lib/aspera/cli/listener/progress.rb +5 -6
- data/lib/aspera/cli/listener/progress_multi.rb +16 -21
- data/lib/aspera/cli/main.rb +72 -73
- data/lib/aspera/cli/manager.rb +112 -112
- data/lib/aspera/cli/plugin.rb +68 -48
- data/lib/aspera/cli/plugins/alee.rb +4 -4
- data/lib/aspera/cli/plugins/aoc.rb +322 -720
- data/lib/aspera/cli/plugins/ats.rb +50 -52
- data/lib/aspera/cli/plugins/bss.rb +10 -10
- data/lib/aspera/cli/plugins/config.rb +514 -410
- data/lib/aspera/cli/plugins/console.rb +12 -12
- data/lib/aspera/cli/plugins/cos.rb +18 -20
- data/lib/aspera/cli/plugins/faspex.rb +134 -136
- data/lib/aspera/cli/plugins/faspex5.rb +235 -70
- data/lib/aspera/cli/plugins/node.rb +378 -309
- data/lib/aspera/cli/plugins/orchestrator.rb +52 -49
- data/lib/aspera/cli/plugins/preview.rb +129 -120
- data/lib/aspera/cli/plugins/server.rb +137 -83
- data/lib/aspera/cli/plugins/shares.rb +77 -52
- data/lib/aspera/cli/plugins/sync.rb +13 -33
- data/lib/aspera/cli/transfer_agent.rb +61 -61
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +3 -3
- data/lib/aspera/command_line_builder.rb +78 -74
- data/lib/aspera/cos_node.rb +31 -29
- data/lib/aspera/data_repository.rb +1 -1
- data/lib/aspera/environment.rb +30 -28
- data/lib/aspera/fasp/agent_base.rb +17 -15
- data/lib/aspera/fasp/agent_connect.rb +34 -32
- data/lib/aspera/fasp/agent_direct.rb +70 -73
- data/lib/aspera/fasp/agent_httpgw.rb +79 -74
- data/lib/aspera/fasp/agent_node.rb +26 -26
- data/lib/aspera/fasp/agent_trsdk.rb +20 -20
- data/lib/aspera/fasp/error.rb +3 -2
- data/lib/aspera/fasp/error_info.rb +11 -8
- data/lib/aspera/fasp/installation.rb +80 -80
- data/lib/aspera/fasp/listener.rb +2 -2
- data/lib/aspera/fasp/parameters.rb +103 -92
- data/lib/aspera/fasp/parameters.yaml +313 -214
- data/lib/aspera/fasp/resume_policy.rb +10 -10
- data/lib/aspera/fasp/transfer_spec.rb +22 -2
- data/lib/aspera/fasp/uri.rb +7 -7
- data/lib/aspera/faspex_gw.rb +80 -159
- data/lib/aspera/faspex_postproc.rb +77 -0
- data/lib/aspera/hash_ext.rb +3 -3
- data/lib/aspera/id_generator.rb +5 -5
- data/lib/aspera/keychain/encrypted_hash.rb +23 -28
- data/lib/aspera/keychain/macos_security.rb +21 -20
- data/lib/aspera/log.rb +13 -13
- data/lib/aspera/nagios.rb +24 -23
- data/lib/aspera/node.rb +217 -38
- data/lib/aspera/oauth.rb +78 -74
- data/lib/aspera/open_application.rb +19 -11
- data/lib/aspera/persistency_action_once.rb +4 -4
- data/lib/aspera/persistency_folder.rb +13 -13
- data/lib/aspera/preview/file_types.rb +8 -8
- data/lib/aspera/preview/generator.rb +67 -67
- data/lib/aspera/preview/utils.rb +27 -27
- data/lib/aspera/proxy_auto_config.js +63 -63
- data/lib/aspera/proxy_auto_config.rb +19 -19
- data/lib/aspera/rest.rb +65 -67
- data/lib/aspera/rest_call_error.rb +2 -1
- data/lib/aspera/rest_error_analyzer.rb +22 -21
- data/lib/aspera/rest_errors_aspera.rb +16 -16
- data/lib/aspera/secret_hider.rb +17 -14
- data/lib/aspera/ssh.rb +15 -14
- data/lib/aspera/sync.rb +177 -62
- data/lib/aspera/temp_file_manager.rb +2 -2
- data/lib/aspera/uri_reader.rb +4 -4
- data/lib/aspera/web_auth.rb +13 -64
- data/lib/aspera/web_server_simple.rb +76 -0
- data.tar.gz.sig +0 -0
- metadata +11 -6
- metadata.gz.sig +0 -0
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'aspera/cli/basic_auth_plugin'
|
4
4
|
require 'aspera/cli/extended_value'
|
5
5
|
require 'aspera/cli/version'
|
6
|
-
require 'aspera/cli/
|
6
|
+
require 'aspera/cli/formatter'
|
7
7
|
require 'aspera/cli/info'
|
8
8
|
require 'aspera/fasp/installation'
|
9
9
|
require 'aspera/fasp/parameters'
|
@@ -28,7 +28,7 @@ module Aspera
|
|
28
28
|
module Cli
|
29
29
|
module Plugins
|
30
30
|
# manage the CLI config file
|
31
|
-
class Config < Plugin
|
31
|
+
class Config < Aspera::Cli::Plugin
|
32
32
|
# folder in $HOME for application files (config, cache)
|
33
33
|
ASPERA_HOME_FOLDER_NAME = '.aspera'
|
34
34
|
# default config file
|
@@ -74,13 +74,33 @@ module Aspera
|
|
74
74
|
DEFAULT_CHECK_NEW_VERSION_DAYS = 7
|
75
75
|
DEFAULT_PRIV_KEY_FILENAME = 'aspera_aoc_key' # pragma: allowlist secret
|
76
76
|
DEFAULT_PRIVKEY_LENGTH = 4096
|
77
|
-
private_constant :DEFAULT_CONFIG_FILENAME
|
78
|
-
:
|
79
|
-
:
|
80
|
-
:
|
81
|
-
:
|
77
|
+
private_constant :DEFAULT_CONFIG_FILENAME,
|
78
|
+
:CONF_PRESET_CONFIG,
|
79
|
+
:CONF_PRESET_VERSION,
|
80
|
+
:CONF_PRESET_DEFAULT,
|
81
|
+
:CONF_PRESET_GLOBAL,
|
82
|
+
:PROGRAM_NAME_V1,
|
83
|
+
:PROGRAM_NAME_V2,
|
84
|
+
:DEFAULT_REDIRECT,
|
85
|
+
:ASPERA_PLUGINS_FOLDERNAME,
|
86
|
+
:RUBY_FILE_EXT,
|
87
|
+
:AOC_COMMAND_V1,
|
88
|
+
:AOC_COMMAND_V2,
|
89
|
+
:AOC_COMMAND_V3,
|
90
|
+
:AOC_COMMAND_CURRENT,
|
91
|
+
:DEMO,
|
92
|
+
:TRANSFER_SDK_ARCHIVE_URL,
|
93
|
+
:AOC_PATH_API_CLIENTS,
|
94
|
+
:DEMO_SERVER_PRESET,
|
95
|
+
:EMAIL_TEST_TEMPLATE,
|
96
|
+
:EXTV_INCLUDE_PRESETS,
|
97
|
+
:EXTV_PRESET,
|
98
|
+
:EXTV_VAULT,
|
99
|
+
:DEFAULT_CHECK_NEW_VERSION_DAYS,
|
100
|
+
:DEFAULT_PRIV_KEY_FILENAME,
|
101
|
+
:SERVER_COMMAND,
|
82
102
|
:PRESET_DIG_SEPARATOR
|
83
|
-
def initialize(env,params)
|
103
|
+
def initialize(env, params)
|
84
104
|
raise 'env and params must be Hash' unless env.is_a?(Hash) && params.is_a?(Hash)
|
85
105
|
raise 'missing param' unless %i[name help version gem].sort.eql?(params.keys.sort)
|
86
106
|
super(env)
|
@@ -92,69 +112,69 @@ module Aspera
|
|
92
112
|
@config_presets = nil
|
93
113
|
@connect_versions = nil
|
94
114
|
@vault = nil
|
95
|
-
@conf_file_default = File.join(@main_folder,DEFAULT_CONFIG_FILENAME)
|
115
|
+
@conf_file_default = File.join(@main_folder, DEFAULT_CONFIG_FILENAME)
|
96
116
|
@option_config_file = @conf_file_default
|
97
117
|
@pac_exec = nil
|
98
|
-
Log.log.debug
|
118
|
+
Log.log.debug{"#{@info[:name]} folder: #{@main_folder}"}
|
99
119
|
# set folder for FASP SDK
|
100
120
|
add_plugin_lookup_folder(self.class.gem_plugins_folder)
|
101
|
-
add_plugin_lookup_folder(File.join(@main_folder,ASPERA_PLUGINS_FOLDERNAME))
|
121
|
+
add_plugin_lookup_folder(File.join(@main_folder, ASPERA_PLUGINS_FOLDERNAME))
|
102
122
|
# do file parameter first
|
103
|
-
options.set_obj_attr(:config_file,self
|
104
|
-
options.add_opt_simple(:config_file,"read parameters from file in YAML format, current=#{@option_config_file}")
|
123
|
+
options.set_obj_attr(:config_file, self, :option_config_file)
|
124
|
+
options.add_opt_simple(:config_file, "read parameters from file in YAML format, current=#{@option_config_file}")
|
105
125
|
options.parse_options!
|
106
|
-
# read correct file
|
126
|
+
# read correct file (set @config_presets)
|
107
127
|
read_config_file
|
108
128
|
# add preset handler (needed for smtp)
|
109
|
-
ExtendedValue.instance.set_handler(EXTV_PRESET
|
110
|
-
ExtendedValue.instance.set_handler(EXTV_INCLUDE_PRESETS
|
111
|
-
ExtendedValue.instance.set_handler(EXTV_VAULT
|
112
|
-
# load defaults before it can be
|
129
|
+
ExtendedValue.instance.set_handler(EXTV_PRESET, :reader, lambda{|v|preset_by_name(v)})
|
130
|
+
ExtendedValue.instance.set_handler(EXTV_INCLUDE_PRESETS, :decoder, lambda{|v|expanded_with_preset_includes(v)})
|
131
|
+
ExtendedValue.instance.set_handler(EXTV_VAULT, :decoder, lambda{|v|vault_value(v)})
|
132
|
+
# load defaults before it can be overridden
|
113
133
|
add_plugin_default_preset(CONF_GLOBAL_SYM)
|
114
134
|
options.parse_options!
|
115
|
-
options.set_obj_attr(:ascp_path,Fasp::Installation.instance
|
116
|
-
options.set_obj_attr(:sdk_folder,Fasp::Installation.instance
|
117
|
-
options.set_obj_attr(:use_product,self
|
118
|
-
options.set_obj_attr(:preset,self
|
119
|
-
options.set_obj_attr(:plugin_folder,self
|
120
|
-
options.add_opt_switch(:no_default,'-N','do not load default configuration for plugin') { @use_plugin_defaults = false }
|
121
|
-
options.add_opt_boolean(:override,'Wizard: override existing value')
|
122
|
-
options.add_opt_boolean(:use_generic_client,'Wizard: AoC: use global or org specific jwt client id')
|
123
|
-
options.add_opt_boolean(:default,'Wizard: set as default configuration for specified plugin (also: update)')
|
124
|
-
options.add_opt_boolean(:test_mode,'Wizard: skip private key check step')
|
125
|
-
options.add_opt_simple(:preset,'-PVALUE','load the named option preset from current config file')
|
126
|
-
options.add_opt_simple(:pkeypath,'Wizard: path to private key for JWT')
|
127
|
-
options.add_opt_simple(:ascp_path,'Path to ascp')
|
128
|
-
options.add_opt_simple(:use_product,'Use ascp from specified product')
|
129
|
-
options.add_opt_simple(:smtp,'SMTP configuration (extended value: hash)')
|
130
|
-
options.add_opt_simple(:fpac,'Proxy auto configuration script')
|
131
|
-
options.add_opt_simple(:proxy_credentials,'HTTP proxy credentials (Array with user and password)')
|
132
|
-
options.add_opt_simple(:secret,'Secret for access keys')
|
133
|
-
options.add_opt_simple(:vault,'Vault for secrets')
|
134
|
-
options.add_opt_simple(:vault_password,'Vault password')
|
135
|
-
options.add_opt_simple(:sdk_url,'URL to get SDK')
|
136
|
-
options.add_opt_simple(:sdk_folder,'SDK folder path')
|
137
|
-
options.add_opt_simple(:notif_to,'Email recipient for notification of transfers')
|
138
|
-
options.add_opt_simple(:notif_template,'Email ERB template for notification of transfers')
|
139
|
-
options.add_opt_simple(:version_check_days,Integer,'Period in days to check new version (zero to disable)')
|
140
|
-
options.add_opt_simple(:plugin_folder,'Folder where to find additional plugins')
|
141
|
-
options.set_option(:use_generic_client,true)
|
142
|
-
options.set_option(:test_mode,false)
|
143
|
-
options.set_option(:default,true)
|
144
|
-
options.set_option(:version_check_days,DEFAULT_CHECK_NEW_VERSION_DAYS)
|
145
|
-
options.set_option(:sdk_url,TRANSFER_SDK_ARCHIVE_URL)
|
146
|
-
options.set_option(:sdk_folder,File.join(@main_folder,'sdk'))
|
147
|
-
options.set_option(:override
|
135
|
+
options.set_obj_attr(:ascp_path, Fasp::Installation.instance, :ascp_path)
|
136
|
+
options.set_obj_attr(:sdk_folder, Fasp::Installation.instance, :sdk_folder)
|
137
|
+
options.set_obj_attr(:use_product, self, :option_use_product)
|
138
|
+
options.set_obj_attr(:preset, self, :option_preset)
|
139
|
+
options.set_obj_attr(:plugin_folder, self, :option_plugin_folder)
|
140
|
+
options.add_opt_switch(:no_default, '-N', 'do not load default configuration for plugin') { @use_plugin_defaults = false }
|
141
|
+
options.add_opt_boolean(:override, 'Wizard: override existing value')
|
142
|
+
options.add_opt_boolean(:use_generic_client, 'Wizard: AoC: use global or org specific jwt client id')
|
143
|
+
options.add_opt_boolean(:default, 'Wizard: set as default configuration for specified plugin (also: update)')
|
144
|
+
options.add_opt_boolean(:test_mode, 'Wizard: skip private key check step')
|
145
|
+
options.add_opt_simple(:preset, '-PVALUE', 'load the named option preset from current config file')
|
146
|
+
options.add_opt_simple(:pkeypath, 'Wizard: path to private key for JWT')
|
147
|
+
options.add_opt_simple(:ascp_path, 'Path to ascp')
|
148
|
+
options.add_opt_simple(:use_product, 'Use ascp from specified product')
|
149
|
+
options.add_opt_simple(:smtp, 'SMTP configuration (extended value: hash)')
|
150
|
+
options.add_opt_simple(:fpac, 'Proxy auto configuration script')
|
151
|
+
options.add_opt_simple(:proxy_credentials, 'HTTP proxy credentials (Array with user and password)')
|
152
|
+
options.add_opt_simple(:secret, 'Secret for access keys')
|
153
|
+
options.add_opt_simple(:vault, 'Vault for secrets')
|
154
|
+
options.add_opt_simple(:vault_password, 'Vault password')
|
155
|
+
options.add_opt_simple(:sdk_url, 'URL to get SDK')
|
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)
|
148
168
|
options.parse_options!
|
149
169
|
pac_script = options.get_option(:fpac)
|
150
170
|
# create PAC executor
|
151
171
|
@pac_exec = Aspera::ProxyAutoConfig.new(pac_script).register_uri_generic unless pac_script.nil?
|
152
|
-
proxy_creds=options.get_option(:proxy_credentials)
|
172
|
+
proxy_creds = options.get_option(:proxy_credentials)
|
153
173
|
if !proxy_creds.nil?
|
154
|
-
raise CliBadArgument,'proxy credentials shall be an array (#{proxy_creds.class})' unless proxy_creds.is_a?(Array)
|
155
|
-
raise CliBadArgument,'proxy credentials shall have two elements (#{proxy_creds.length})' unless proxy_creds.length.eql?(2)
|
156
|
-
@pac_exec.proxy_user=Rest.proxy_user=proxy_creds[0]
|
157
|
-
@pac_exec.proxy_pass=Rest.proxy_pass=proxy_creds[1]
|
174
|
+
raise CliBadArgument, 'proxy credentials shall be an array (#{proxy_creds.class})' unless proxy_creds.is_a?(Array)
|
175
|
+
raise CliBadArgument, 'proxy credentials shall have two elements (#{proxy_creds.length})' unless proxy_creds.length.eql?(2)
|
176
|
+
@pac_exec.proxy_user = Rest.proxy_user = proxy_creds[0]
|
177
|
+
@pac_exec.proxy_pass = Rest.proxy_pass = proxy_creds[1]
|
158
178
|
end
|
159
179
|
end
|
160
180
|
|
@@ -170,8 +190,8 @@ module Aspera
|
|
170
190
|
# if env var undefined or empty
|
171
191
|
if app_folder.nil? || app_folder.empty?
|
172
192
|
user_home_folder = Dir.home
|
173
|
-
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)
|
174
|
-
app_folder = File.join(user_home_folder,ASPERA_HOME_FOLDER_NAME
|
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])
|
175
195
|
end
|
176
196
|
return app_folder
|
177
197
|
end
|
@@ -185,8 +205,10 @@ module Aspera
|
|
185
205
|
'0'
|
186
206
|
end
|
187
207
|
if Gem::Version.new(Environment.ruby_version) < Gem::Version.new(RUBY_FUTURE_MINIMUM_VERSION)
|
188
|
-
Log.log.warn
|
189
|
-
"
|
208
|
+
Log.log.warn do
|
209
|
+
"Note that a future version will require Ruby version #{RUBY_FUTURE_MINIMUM_VERSION} at minimum, "\
|
210
|
+
"you are using #{Environment.ruby_version}"
|
211
|
+
end
|
190
212
|
end
|
191
213
|
return {
|
192
214
|
name: @info[:gem],
|
@@ -198,8 +220,8 @@ module Aspera
|
|
198
220
|
|
199
221
|
def periodic_check_newer_gem_version
|
200
222
|
# get verification period
|
201
|
-
delay_days = options.get_option(:version_check_days,is_type: :mandatory)
|
202
|
-
Log.log.info
|
223
|
+
delay_days = options.get_option(:version_check_days, is_type: :mandatory)
|
224
|
+
Log.log.info{"check days: #{delay_days}"}
|
203
225
|
# check only if not zero day
|
204
226
|
return if delay_days.eql?(0)
|
205
227
|
# get last date from persistency
|
@@ -217,52 +239,53 @@ module Aspera
|
|
217
239
|
# negative value will force check
|
218
240
|
-1
|
219
241
|
end
|
220
|
-
Log.log.debug
|
242
|
+
Log.log.debug{"days elapsed: #{last_check_days}"}
|
221
243
|
return if last_check_days < delay_days
|
222
244
|
# generate timestamp
|
223
245
|
last_check_array[0] = current_date.strftime('%Y/%m/%d')
|
224
246
|
check_date_persist.save
|
225
247
|
# compare this version and the one on internet
|
226
248
|
check_data = check_gem_version
|
227
|
-
Log.log.warn
|
228
|
-
"You have #{check_data[:current]}. Upgrade with: gem update #{check_data[:name]}"
|
249
|
+
Log.log.warn do
|
250
|
+
"A new version is available: #{check_data[:latest]}. You have #{check_data[:current]}. Upgrade with: gem update #{check_data[:name]}"
|
251
|
+
end if check_data[:need_update]
|
229
252
|
end
|
230
253
|
|
231
254
|
# retrieve structure from cloud (CDN) with all versions available
|
232
255
|
def connect_versions
|
233
256
|
if @connect_versions.nil?
|
234
257
|
api_connect_cdn = Rest.new({base_url: CONNECT_WEB_URL})
|
235
|
-
javascript = api_connect_cdn.call({operation: 'GET',subpath: CONNECT_VERSIONS})
|
258
|
+
javascript = api_connect_cdn.call({operation: 'GET', subpath: CONNECT_VERSIONS})
|
236
259
|
# get result on one line
|
237
|
-
connect_versions_javascript = javascript[:http].body.gsub(/\r?\n\s*/,'')
|
238
|
-
Log.log.debug
|
260
|
+
connect_versions_javascript = javascript[:http].body.gsub(/\r?\n\s*/, '')
|
261
|
+
Log.log.debug{"javascript=[\n#{connect_versions_javascript}\n]"}
|
239
262
|
# get javascript object only
|
240
263
|
found = connect_versions_javascript.match(/^.*? = (.*);/)
|
241
|
-
raise CliError,'
|
242
|
-
|
243
|
-
@connect_versions =
|
264
|
+
raise CliError, 'Problem when getting connect versions from internet' if found.nil?
|
265
|
+
all_data = JSON.parse(found[1])
|
266
|
+
@connect_versions = all_data['entries']
|
244
267
|
end
|
245
268
|
return @connect_versions
|
246
269
|
end
|
247
270
|
|
248
271
|
# loads default parameters of plugin if no -P parameter
|
249
272
|
# and if there is a section defined for the plugin in the "default" section
|
250
|
-
# try to find:
|
273
|
+
# try to find: conf[conf["default"][plugin_str]]
|
251
274
|
# @param plugin_name_sym : symbol for plugin name
|
252
275
|
def add_plugin_default_preset(plugin_name_sym)
|
253
276
|
default_config_name = get_plugin_default_config_name(plugin_name_sym)
|
254
|
-
Log.log.debug
|
255
|
-
options.add_option_preset(preset_by_name(default_config_name),op: :unshift) unless default_config_name.nil?
|
277
|
+
Log.log.debug{"add_plugin_default_preset:#{plugin_name_sym}:#{default_config_name}"}
|
278
|
+
options.add_option_preset(preset_by_name(default_config_name), op: :unshift) unless default_config_name.nil?
|
256
279
|
return nil
|
257
280
|
end
|
258
281
|
|
259
282
|
private
|
260
283
|
|
261
|
-
def generate_rsa_private_key(private_key_path,length)
|
284
|
+
def generate_rsa_private_key(private_key_path, length)
|
262
285
|
require 'openssl'
|
263
286
|
priv_key = OpenSSL::PKey::RSA.new(length)
|
264
|
-
File.write(private_key_path,priv_key.to_s)
|
265
|
-
File.write(private_key_path + '.pub',priv_key.public_key.to_s)
|
287
|
+
File.write(private_key_path, priv_key.to_s)
|
288
|
+
File.write(private_key_path + '.pub', priv_key.public_key.to_s)
|
266
289
|
Environment.restrict_file_access(private_key_path)
|
267
290
|
Environment.restrict_file_access(private_key_path + '.pub')
|
268
291
|
nil
|
@@ -274,7 +297,7 @@ module Aspera
|
|
274
297
|
File.dirname(File.expand_path(__FILE__))
|
275
298
|
end
|
276
299
|
|
277
|
-
# name of
|
300
|
+
# name of englobing module
|
278
301
|
# @return "Aspera::Cli::Plugins"
|
279
302
|
def module_full_name
|
280
303
|
return Module.nesting[2].to_s
|
@@ -283,10 +306,10 @@ module Aspera
|
|
283
306
|
# @return main folder where code is, i.e. .../lib
|
284
307
|
# go up as many times as englobing modules (not counting class, as it is a file)
|
285
308
|
def gem_src_root
|
286
|
-
File.expand_path(module_full_name.gsub('::','/').gsub(%r{[^/]+},'..'),gem_plugins_folder)
|
309
|
+
File.expand_path(module_full_name.gsub('::', '/').gsub(%r{[^/]+}, '..'), gem_plugins_folder)
|
287
310
|
end
|
288
311
|
|
289
|
-
#
|
312
|
+
# instantiate a plugin
|
290
313
|
# plugins must be Capitalized
|
291
314
|
def plugin_class(plugin_name_sym)
|
292
315
|
# Module.nesting[2] is Aspera::Cli::Plugins
|
@@ -297,7 +320,7 @@ module Aspera
|
|
297
320
|
# set parameter and value in global config
|
298
321
|
# creates one if none already created
|
299
322
|
# @return preset name that contains global default
|
300
|
-
def set_global_default(key,value)
|
323
|
+
def set_global_default(key, value)
|
301
324
|
# get default preset if it exists
|
302
325
|
global_default_preset_name = get_plugin_default_config_name(CONF_GLOBAL_SYM)
|
303
326
|
if global_default_preset_name.nil?
|
@@ -307,7 +330,7 @@ module Aspera
|
|
307
330
|
end
|
308
331
|
@config_presets[global_default_preset_name] ||= {}
|
309
332
|
@config_presets[global_default_preset_name][key.to_s] = value
|
310
|
-
|
333
|
+
formatter.display_status("Updated: #{global_default_preset_name}: #{key} <- #{value}")
|
311
334
|
save_presets_to_config_file
|
312
335
|
return global_default_preset_name
|
313
336
|
end
|
@@ -323,28 +346,28 @@ module Aspera
|
|
323
346
|
# @param config_name name of the preset in config file
|
324
347
|
# @param include_path used to detect and avoid include loops
|
325
348
|
def preset_by_name(config_name, include_path=[])
|
326
|
-
raise CliError,'loop in include' if include_path.include?(config_name)
|
349
|
+
raise CliError, 'loop in include' if include_path.include?(config_name)
|
327
350
|
include_path = include_path.clone # avoid messing up if there are multiple branches
|
328
351
|
current = @config_presets
|
329
352
|
config_name.split(PRESET_DIG_SEPARATOR).each do |name|
|
330
|
-
raise CliError,"
|
353
|
+
raise CliError, "Expecting Hash for subkey: #{include_path} (#{current.class})" unless current.is_a?(Hash)
|
331
354
|
include_path.push(name)
|
332
355
|
current = current[name]
|
333
|
-
raise CliError,"
|
356
|
+
raise CliError, "No such config preset: #{include_path}" if current.nil?
|
334
357
|
end
|
335
358
|
case current
|
336
|
-
when Hash then return expanded_with_preset_includes(current,include_path)
|
359
|
+
when Hash then return expanded_with_preset_includes(current, include_path)
|
337
360
|
when String then return ExtendedValue.instance.evaluate(current)
|
338
361
|
else return current
|
339
362
|
end
|
340
363
|
end
|
341
364
|
|
342
|
-
# @return the hash value with 'incps' keys
|
365
|
+
# @return the hash value with 'incps' keys expanded to include other presets
|
343
366
|
# @param hash_val
|
344
367
|
# @param include_path to avoid inclusion loop
|
345
368
|
def expanded_with_preset_includes(hash_val, include_path=[])
|
346
|
-
raise CliError,"#{EXTV_INCLUDE_PRESETS} requires a Hash, have #{hash_val.class}" unless hash_val.is_a?(Hash)
|
347
|
-
if hash_val.
|
369
|
+
raise CliError, "#{EXTV_INCLUDE_PRESETS} requires a Hash, have #{hash_val.class}" unless hash_val.is_a?(Hash)
|
370
|
+
if hash_val.key?(EXTV_INCLUDE_PRESETS)
|
348
371
|
memory = hash_val.clone
|
349
372
|
includes = memory[EXTV_INCLUDE_PRESETS]
|
350
373
|
memory.delete(EXTV_INCLUDE_PRESETS)
|
@@ -352,7 +375,7 @@ module Aspera
|
|
352
375
|
raise "#{EXTV_INCLUDE_PRESETS} must be an Array" unless includes.is_a?(Array)
|
353
376
|
raise "#{EXTV_INCLUDE_PRESETS} must contain names" unless includes.map(&:class).uniq.eql?([String])
|
354
377
|
includes.each do |preset_name|
|
355
|
-
hash_val.merge!(preset_by_name(preset_name,include_path))
|
378
|
+
hash_val.merge!(preset_by_name(preset_name, include_path))
|
356
379
|
end
|
357
380
|
hash_val.merge!(memory)
|
358
381
|
end
|
@@ -392,124 +415,122 @@ module Aspera
|
|
392
415
|
end
|
393
416
|
end
|
394
417
|
|
395
|
-
def convert_preset_path(old_name,new_name,files_to_copy)
|
396
|
-
old_subpath = File.join('',ASPERA_HOME_FOLDER_NAME,old_name,'')
|
397
|
-
new_subpath = File.join('',ASPERA_HOME_FOLDER_NAME,new_name,'')
|
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, '')
|
398
421
|
# convert possible keys located in config folder
|
399
422
|
@config_presets.values.select{|p|p.is_a?(Hash)}.each do |preset|
|
400
423
|
preset.values.select{|v|v.is_a?(String) && v.include?(old_subpath)}.each do |value|
|
401
424
|
old_val = value.clone
|
402
|
-
included_path = File.expand_path(old_val.gsub(/^@file:/,''))
|
425
|
+
included_path = File.expand_path(old_val.gsub(/^@file:/, ''))
|
403
426
|
files_to_copy.push(included_path) unless files_to_copy.include?(included_path) || !File.exist?(included_path)
|
404
|
-
value.gsub!(old_subpath,new_subpath)
|
405
|
-
Log.log.warn
|
427
|
+
value.gsub!(old_subpath, new_subpath)
|
428
|
+
Log.log.warn{"Converted config value: #{old_val} -> #{value}"}
|
406
429
|
end
|
407
430
|
end
|
408
431
|
end
|
409
432
|
|
410
|
-
def convert_preset_plugin_name(old_name,new_name)
|
433
|
+
def convert_preset_plugin_name(old_name, new_name)
|
411
434
|
default_preset = @config_presets[CONF_PRESET_DEFAULT]
|
412
|
-
return unless default_preset.is_a?(Hash) && default_preset.
|
435
|
+
return unless default_preset.is_a?(Hash) && default_preset.key?(old_name)
|
413
436
|
default_preset[new_name] = default_preset[old_name]
|
414
437
|
default_preset.delete(old_name)
|
415
|
-
Log.log.warn
|
438
|
+
Log.log.warn{"Converted plugin default: #{old_name} -> #{new_name}"}
|
416
439
|
end
|
417
440
|
|
418
441
|
# read config file and validate format
|
419
442
|
# tries to convert from older version if possible and required
|
420
443
|
def read_config_file
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
Log.log.warn("..#{file} -> #{@main_folder}")
|
487
|
-
end
|
488
|
-
end
|
489
|
-
rescue Psych::SyntaxError => e
|
490
|
-
Log.log.error('YAML error in config file')
|
491
|
-
raise e
|
492
|
-
rescue StandardError => e
|
493
|
-
Log.log.debug("-> #{e.class.name} : #{e}")
|
494
|
-
if File.exist?(@option_config_file)
|
495
|
-
# then there is a problem with that file.
|
496
|
-
new_name = "#{@option_config_file}.pre#{@info[:version]}.manual_conversion_needed"
|
497
|
-
File.rename(@option_config_file,new_name)
|
498
|
-
Log.log.warn("Renamed config file to #{new_name}.")
|
499
|
-
Log.log.warn('Manual Conversion is required. Next time, a new empty file will be created.')
|
444
|
+
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
|
+
# files search for configuration, by default the one given by user
|
448
|
+
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
|
+
# find first existing file (or nil)
|
452
|
+
conf_file_to_load = search_files.find{|f| File.exist?(f)}
|
453
|
+
# require save if old version of file
|
454
|
+
save_required = !@option_config_file.eql?(conf_file_to_load)
|
455
|
+
# if no file found, create default config
|
456
|
+
if conf_file_to_load.nil?
|
457
|
+
Log.log.warn{"No config file found. Creating empty configuration file: #{@option_config_file}"}
|
458
|
+
@config_presets = {CONF_PRESET_CONFIG => {CONF_PRESET_VERSION => @info[:version]}}
|
459
|
+
else
|
460
|
+
Log.log.debug{"loading #{@option_config_file}"}
|
461
|
+
@config_presets = YAML.load_file(conf_file_to_load)
|
462
|
+
end
|
463
|
+
files_to_copy = []
|
464
|
+
Log.log.debug{"Available_presets: #{@config_presets}"}
|
465
|
+
raise 'Expecting YAML Hash' unless @config_presets.is_a?(Hash)
|
466
|
+
# check there is at least the config section
|
467
|
+
if !@config_presets.key?(CONF_PRESET_CONFIG)
|
468
|
+
raise "Cannot find key: #{CONF_PRESET_CONFIG}"
|
469
|
+
end
|
470
|
+
version = @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]
|
471
|
+
if version.nil?
|
472
|
+
raise 'No version found in config section.'
|
473
|
+
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
|
+
Log.log.debug{"conf version: #{version}"}
|
500
|
+
# Place new compatibility code here
|
501
|
+
if save_required
|
502
|
+
Log.log.warn('Saving automatic conversion.')
|
503
|
+
@config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = @info[:version]
|
504
|
+
save_presets_to_config_file
|
505
|
+
Log.log.warn('Copying referenced files')
|
506
|
+
files_to_copy.each do |file|
|
507
|
+
FileUtils.cp(file, @main_folder)
|
508
|
+
Log.log.warn{"..#{file} -> #{@main_folder}"}
|
500
509
|
end
|
501
|
-
raise CliError,e.to_s
|
502
510
|
end
|
511
|
+
rescue Psych::SyntaxError => e
|
512
|
+
Log.log.error('YAML error in config file')
|
513
|
+
raise e
|
514
|
+
rescue StandardError => e
|
515
|
+
Log.log.debug{"-> #{e.class.name} : #{e}"}
|
516
|
+
if File.exist?(@option_config_file)
|
517
|
+
# then there is a problem with that file.
|
518
|
+
new_name = "#{@option_config_file}.pre#{@info[:version]}.manual_conversion_needed"
|
519
|
+
File.rename(@option_config_file, new_name)
|
520
|
+
Log.log.warn{"Renamed config file to #{new_name}."}
|
521
|
+
Log.log.warn('Manual Conversion is required. Next time, a new empty file will be created.')
|
522
|
+
end
|
523
|
+
raise CliError, e.to_s
|
503
524
|
end
|
504
525
|
|
505
526
|
# find plugins in defined paths
|
506
527
|
def add_plugins_from_lookup_folders
|
507
528
|
@plugin_lookup_folders.each do |folder|
|
508
529
|
next unless File.directory?(folder)
|
509
|
-
#TODO: add gem root to load path ? and require short folder ?
|
510
|
-
|
530
|
+
# TODO: add gem root to load path ? and require short folder ?
|
531
|
+
# $LOAD_PATH.push(folder) if i[:add_path]
|
511
532
|
Dir.entries(folder).select{|file|file.end_with?(RUBY_FILE_EXT)}.each do |source|
|
512
|
-
add_plugin_info(File.join(folder,source))
|
533
|
+
add_plugin_info(File.join(folder, source))
|
513
534
|
end
|
514
535
|
end
|
515
536
|
end
|
@@ -520,17 +541,17 @@ module Aspera
|
|
520
541
|
|
521
542
|
def add_plugin_info(path)
|
522
543
|
raise "ERROR: plugin path must end with #{RUBY_FILE_EXT}" if !path.end_with?(RUBY_FILE_EXT)
|
523
|
-
plugin_symbol = File.basename(path,RUBY_FILE_EXT).to_sym
|
524
|
-
req = path.gsub(/#{RUBY_FILE_EXT}$/o,'')
|
525
|
-
if @plugins.
|
526
|
-
Log.log.warn
|
544
|
+
plugin_symbol = File.basename(path, RUBY_FILE_EXT).to_sym
|
545
|
+
req = path.gsub(/#{RUBY_FILE_EXT}$/o, '')
|
546
|
+
if @plugins.key?(plugin_symbol)
|
547
|
+
Log.log.warn{"skipping plugin already registered: #{plugin_symbol}"}
|
527
548
|
return
|
528
549
|
end
|
529
|
-
@plugins[plugin_symbol] = {source: path,require_stanza: req}
|
550
|
+
@plugins[plugin_symbol] = {source: path, require_stanza: req}
|
530
551
|
end
|
531
552
|
|
532
553
|
def identify_plugin_for_url(url)
|
533
|
-
plugins.each do |plugin_name_sym,plugin_info|
|
554
|
+
plugins.each do |plugin_name_sym, plugin_info|
|
534
555
|
# no detection for internal plugin
|
535
556
|
next if plugin_name_sym.eql?(CONF_PLUGIN_SYM)
|
536
557
|
# load plugin class
|
@@ -546,22 +567,23 @@ module Aspera
|
|
546
567
|
Log.log.warn(e.message)
|
547
568
|
Log.log.warn('Use option --insecure=yes to ignore certificate') if e.message.include?('cert')
|
548
569
|
rescue StandardError => e
|
549
|
-
Log.log.debug
|
570
|
+
Log.log.debug{"Cannot detect #{plugin_name_sym} : #{e.class}/#{e.message}"}
|
550
571
|
end
|
551
572
|
# second try : is there a redirect ?
|
552
573
|
if detection_info.nil?
|
553
574
|
begin
|
554
575
|
# TODO: check if redirect ?
|
555
|
-
new_url = Rest.new(base_url: url).call(operation: 'GET',subpath: '',redirect_max: 1)[:http].uri.to_s
|
576
|
+
new_url = Rest.new(base_url: url).call(operation: 'GET', subpath: '', redirect_max: 1)[:http].uri.to_s
|
556
577
|
unless url.eql?(new_url)
|
557
578
|
detection_info = c.detect(new_url)
|
558
579
|
current_url = new_url
|
559
580
|
end
|
560
581
|
rescue StandardError => e
|
561
|
-
Log.log.debug
|
582
|
+
Log.log.debug{"Cannot detect #{plugin_name_sym} : #{e.message}"}
|
562
583
|
end
|
563
584
|
end
|
564
|
-
|
585
|
+
# if there is a redirect, then the detector can override the url.
|
586
|
+
return {product: plugin_name_sym, url: current_url}.merge(detection_info) unless detection_info.nil?
|
565
587
|
end # loop
|
566
588
|
raise "No known application found at #{url}"
|
567
589
|
end
|
@@ -571,7 +593,7 @@ module Aspera
|
|
571
593
|
if %i[info version].include?(command)
|
572
594
|
connect_id = options.get_next_argument('id or title')
|
573
595
|
one_res = connect_versions.find{|i|i['id'].eql?(connect_id) || i['title'].eql?(connect_id)}
|
574
|
-
raise CliNoSuchId.new(:connect,connect_id) if one_res.nil?
|
596
|
+
raise CliNoSuchId.new(:connect, connect_id) if one_res.nil?
|
575
597
|
end
|
576
598
|
case command
|
577
599
|
when :list
|
@@ -592,11 +614,11 @@ module Aspera
|
|
592
614
|
return {type: :object_list, data: all_links}
|
593
615
|
when :download
|
594
616
|
folder_dest = transfer.destination_folder(Fasp::TransferSpec::DIRECTION_RECEIVE)
|
595
|
-
#folder_dest=self.options.get_next_argument('destination folder')
|
617
|
+
# folder_dest=self.options.get_next_argument('destination folder')
|
596
618
|
api_connect_cdn = Rest.new({base_url: CONNECT_WEB_URL})
|
597
|
-
|
598
|
-
filename =
|
599
|
-
api_connect_cdn.call({operation: 'GET',subpath:
|
619
|
+
file_url = one_link['href']
|
620
|
+
filename = file_url.gsub(%r{.*/}, '')
|
621
|
+
api_connect_cdn.call({operation: 'GET', subpath: file_url, save_to_file: File.join(folder_dest, filename)})
|
600
622
|
return Main.result_status("Downloaded: #{filename}")
|
601
623
|
when :open
|
602
624
|
OpenApplication.instance.uri(one_link['href'])
|
@@ -613,13 +635,13 @@ module Aspera
|
|
613
635
|
when :use
|
614
636
|
ascp_path = options.get_next_argument('path to ascp')
|
615
637
|
ascp_version = Fasp::Installation.instance.get_ascp_version(ascp_path)
|
616
|
-
|
617
|
-
preset_name = set_global_default(:ascp_path,ascp_path)
|
638
|
+
formatter.display_status("ascp version: #{ascp_version}")
|
639
|
+
preset_name = set_global_default(:ascp_path, ascp_path)
|
618
640
|
return Main.result_status("Saved to default global preset #{preset_name}")
|
619
641
|
when :show # shows files used
|
620
642
|
return {type: :status, data: Fasp::Installation.instance.path(:ascp)}
|
621
643
|
when :info # shows files used
|
622
|
-
data = Fasp::Installation::FILES.each_with_object({}) do |v,m|
|
644
|
+
data = Fasp::Installation::FILES.each_with_object({}) do |v, m|
|
623
645
|
m[v.to_s] =
|
624
646
|
begin
|
625
647
|
Fasp::Installation.instance.path(v)
|
@@ -628,21 +650,26 @@ module Aspera
|
|
628
650
|
end
|
629
651
|
end
|
630
652
|
# read PATHs from ascp directly, and pvcl modules as well
|
631
|
-
Open3.popen3(Fasp::Installation.instance.path(:ascp),'-DDL-') do |_stdin, _stdout, stderr, thread|
|
653
|
+
Open3.popen3(Fasp::Installation.instance.path(:ascp), '-DDL-') do |_stdin, _stdout, stderr, thread|
|
632
654
|
last_line = ''
|
633
655
|
while (line = stderr.gets)
|
634
656
|
line.chomp!
|
635
657
|
last_line = line
|
636
658
|
case line
|
637
|
-
when
|
638
|
-
|
659
|
+
when /^DBG Path ([^ ]+) (dir|file) +: (.*)$/
|
660
|
+
data[Regexp.last_match(1)] = Regexp.last_match(3)
|
661
|
+
when /^DBG Added module group:"([^"]+)" name:"([^"]+)", version:"([^"]+)" interface:"([^"]+)"$/
|
639
662
|
data[Regexp.last_match(2)] = "#{Regexp.last_match(4)} #{Regexp.last_match(1)} v#{Regexp.last_match(3)}"
|
640
|
-
when %r{^DBG License result \(/license/(\S+)\): (.+)$}
|
641
|
-
|
642
|
-
when
|
663
|
+
when %r{^DBG License result \(/license/(\S+)\): (.+)$}
|
664
|
+
data[Regexp.last_match(1)] = Regexp.last_match(2)
|
665
|
+
when /^LOG (.+) version ([0-9.]+)$/
|
666
|
+
data['product_name'] = Regexp.last_match(1)
|
667
|
+
data['product_version'] = Regexp.last_match(2)
|
668
|
+
when /^LOG Initializing FASP version ([^,]+),/
|
669
|
+
data['ascp_version'] = Regexp.last_match(1)
|
643
670
|
end
|
644
671
|
end
|
645
|
-
if !thread.value.exitstatus.eql?(1) && !data.
|
672
|
+
if !thread.value.exitstatus.eql?(1) && !data.key?('root')
|
646
673
|
raise last_line
|
647
674
|
end
|
648
675
|
end
|
@@ -656,21 +683,21 @@ module Aspera
|
|
656
683
|
when :use
|
657
684
|
default_product = options.get_next_argument('product name')
|
658
685
|
Fasp::Installation.instance.use_ascp_from_product(default_product)
|
659
|
-
preset_name = set_global_default(:ascp_path,Fasp::Installation.instance.path(:ascp))
|
686
|
+
preset_name = set_global_default(:ascp_path, Fasp::Installation.instance.path(:ascp))
|
660
687
|
return Main.result_status("Saved to default global preset #{preset_name}")
|
661
688
|
end
|
662
689
|
when :install
|
663
|
-
v = Fasp::Installation.instance.install_sdk(options.get_option(:sdk_url,is_type: :mandatory))
|
690
|
+
v = Fasp::Installation.instance.install_sdk(options.get_option(:sdk_url, is_type: :mandatory))
|
664
691
|
return Main.result_status("Installed version #{v}")
|
665
692
|
when :spec
|
666
693
|
return {
|
667
694
|
type: :object_list,
|
668
695
|
data: Fasp::Parameters.man_table,
|
669
|
-
fields: [
|
696
|
+
fields: [%w[name type], Fasp::Parameters::SUPPORTED_AGENTS_SHORT.map(&:to_s), %w[description]].flatten.freeze
|
670
697
|
}
|
671
698
|
when :errors
|
672
699
|
error_data = []
|
673
|
-
Fasp::ERROR_INFO.each_pair do |code,prop|
|
700
|
+
Fasp::ERROR_INFO.each_pair do |code, prop|
|
674
701
|
error_data.push(code: code, mnemonic: prop[:c], retry: prop[:r], info: prop[:a])
|
675
702
|
end
|
676
703
|
return {type: :object_list, data: error_data}
|
@@ -679,112 +706,168 @@ module Aspera
|
|
679
706
|
end
|
680
707
|
|
681
708
|
# legacy actions available globally
|
682
|
-
PRESET_GBL_ACTIONS = %i[list overview].freeze
|
683
|
-
#
|
684
|
-
|
709
|
+
PRESET_GBL_ACTIONS = %i[list overview lookup secure].freeze
|
710
|
+
# operations requiring that preset exists
|
711
|
+
PRESET_EXIST_ACTIONS = %i[show delete get unset].freeze
|
685
712
|
# require id
|
686
|
-
PRESET_INSTANCE_ACTIONS =
|
687
|
-
PRESET_ALL_ACTIONS = [PRESET_GBL_ACTIONS,PRESET_INSTANCE_ACTIONS].flatten.freeze
|
713
|
+
PRESET_INSTANCE_ACTIONS = %i[initialize update ask set].concat(PRESET_EXIST_ACTIONS).freeze
|
714
|
+
PRESET_ALL_ACTIONS = [PRESET_GBL_ACTIONS, PRESET_INSTANCE_ACTIONS].flatten.freeze
|
688
715
|
|
689
|
-
def
|
716
|
+
def execute_preset(action: nil, name: nil)
|
690
717
|
action = options.get_next_command(PRESET_ALL_ACTIONS) if action.nil?
|
691
|
-
|
718
|
+
name = instance_identifier if name.nil? && PRESET_INSTANCE_ACTIONS.include?(action)
|
692
719
|
# those operations require existing option
|
693
|
-
raise "no such preset: #{
|
694
|
-
selected_preset = @config_presets[
|
720
|
+
raise "no such preset: #{name}" if PRESET_EXIST_ACTIONS.include?(action) && !@config_presets.key?(name)
|
721
|
+
selected_preset = @config_presets[name]
|
695
722
|
case action
|
696
723
|
when :list
|
697
724
|
return {type: :value_list, data: @config_presets.keys, name: 'name'}
|
698
725
|
when :overview
|
699
|
-
return {type: :object_list, data:
|
726
|
+
return {type: :object_list, data: Formatter.flatten_config_overview(@config_presets)}
|
700
727
|
when :show
|
701
|
-
raise "no such config: #{
|
728
|
+
raise "no such config: #{name}" if selected_preset.nil?
|
702
729
|
return {type: :single_object, data: selected_preset}
|
703
730
|
when :delete
|
704
|
-
@config_presets.delete(
|
731
|
+
@config_presets.delete(name)
|
705
732
|
save_presets_to_config_file
|
706
|
-
return Main.result_status("Deleted: #{
|
733
|
+
return Main.result_status("Deleted: #{name}")
|
707
734
|
when :get
|
708
735
|
param_name = options.get_next_argument('parameter name')
|
709
736
|
value = selected_preset[param_name]
|
710
|
-
raise "no such option in preset #{
|
737
|
+
raise "no such option in preset #{name} : #{param_name}" if value.nil?
|
711
738
|
case value
|
712
|
-
when Numeric,String then return {type: :text, data: ExtendedValue.instance.evaluate(value.to_s)}
|
739
|
+
when Numeric, String then return {type: :text, data: ExtendedValue.instance.evaluate(value.to_s)}
|
713
740
|
end
|
714
741
|
return {type: :single_object, data: value}
|
715
742
|
when :unset
|
716
743
|
param_name = options.get_next_argument('parameter name')
|
717
744
|
selected_preset.delete(param_name)
|
718
745
|
save_presets_to_config_file
|
719
|
-
return Main.result_status("Removed: #{
|
746
|
+
return Main.result_status("Removed: #{name}: #{param_name}")
|
720
747
|
when :set
|
721
748
|
param_name = options.get_next_argument('parameter name')
|
722
749
|
param_value = options.get_next_argument('parameter value')
|
723
|
-
if !@config_presets.
|
724
|
-
Log.log.debug
|
725
|
-
selected_preset = @config_presets[
|
750
|
+
if !@config_presets.key?(name)
|
751
|
+
Log.log.debug{"no such config name: #{name}, initializing"}
|
752
|
+
selected_preset = @config_presets[name] = {}
|
726
753
|
end
|
727
|
-
if selected_preset.
|
728
|
-
Log.log.warn
|
754
|
+
if selected_preset.key?(param_name)
|
755
|
+
Log.log.warn{"overwriting value: #{selected_preset[param_name]}"}
|
729
756
|
end
|
730
757
|
selected_preset[param_name] = param_value
|
731
758
|
save_presets_to_config_file
|
732
|
-
return Main.result_status("Updated: #{
|
759
|
+
return Main.result_status("Updated: #{name}: #{param_name} <- #{param_value}")
|
733
760
|
when :initialize
|
734
|
-
config_value = options.get_next_argument('extended value
|
735
|
-
if @config_presets.
|
736
|
-
Log.log.warn
|
761
|
+
config_value = options.get_next_argument('extended value', type: Hash)
|
762
|
+
if @config_presets.key?(name)
|
763
|
+
Log.log.warn{"configuration already exists: #{name}, overwriting"}
|
737
764
|
end
|
738
|
-
@config_presets[
|
765
|
+
@config_presets[name] = config_value
|
739
766
|
save_presets_to_config_file
|
740
767
|
return Main.result_status("Modified: #{@option_config_file}")
|
741
768
|
when :update
|
742
769
|
# get unprocessed options
|
743
|
-
|
744
|
-
Log.log.debug
|
745
|
-
@config_presets[
|
746
|
-
@config_presets[
|
770
|
+
unprocessed_options = options.get_options_table
|
771
|
+
Log.log.debug{"opts=#{unprocessed_options}"}
|
772
|
+
@config_presets[name] ||= {}
|
773
|
+
@config_presets[name].merge!(unprocessed_options)
|
747
774
|
# fix bug in 4.4 (creating key "true" in "default" preset)
|
748
775
|
@config_presets[CONF_PRESET_DEFAULT].delete(true) if @config_presets[CONF_PRESET_DEFAULT].is_a?(Hash)
|
749
776
|
save_presets_to_config_file
|
750
|
-
return Main.result_status("Updated: #{
|
777
|
+
return Main.result_status("Updated: #{name}")
|
751
778
|
when :ask
|
752
779
|
options.ask_missing_mandatory = :yes
|
753
|
-
@config_presets[
|
754
|
-
options.get_next_argument('option names',expected: :multiple).each do |
|
755
|
-
option_value = options.get_interactive(:option,
|
756
|
-
@config_presets[
|
780
|
+
@config_presets[name] ||= {}
|
781
|
+
options.get_next_argument('option names', expected: :multiple).each do |option_name|
|
782
|
+
option_value = options.get_interactive(:option, option_name)
|
783
|
+
@config_presets[name][option_name] = option_value
|
757
784
|
end
|
758
785
|
save_presets_to_config_file
|
759
|
-
return Main.result_status("Updated: #{
|
786
|
+
return Main.result_status("Updated: #{name}")
|
787
|
+
when :lookup
|
788
|
+
BasicAuthPlugin.register_options(@agents)
|
789
|
+
url = options.get_option(:url, is_type: :mandatory)
|
790
|
+
user = options.get_option(:username, is_type: :mandatory)
|
791
|
+
result = lookup_preset(url: url, username: user)
|
792
|
+
raise 'no such config found' if result.nil?
|
793
|
+
return {type: :single_object, data: result}
|
794
|
+
when :secure
|
795
|
+
identifier = options.get_next_argument('config name', mandatory: false)
|
796
|
+
preset_names = identifier.nil? ? @config_presets.keys : [identifier]
|
797
|
+
secret_keywords = %w[password secret].freeze
|
798
|
+
preset_names.each do |preset_name|
|
799
|
+
preset = @config_presets[preset_name]
|
800
|
+
next unless preset.is_a?(Hash)
|
801
|
+
preset.each_key do |option_name|
|
802
|
+
secret_keywords.each do |keyword|
|
803
|
+
next unless option_name.end_with?(keyword)
|
804
|
+
vault_label = preset_name
|
805
|
+
incr = 0
|
806
|
+
until vault.get(label: vault_label, exception: false).nil?
|
807
|
+
vault_label = "#{preset_name}#{incr}"
|
808
|
+
incr += 1
|
809
|
+
end
|
810
|
+
to_set = {label: vault_label, password: preset[option_name]}
|
811
|
+
puts "need to encode #{preset_name}.#{option_name} -> #{vault_label} -> #{to_set}"
|
812
|
+
# to_copy=%i[]
|
813
|
+
vault.set(to_set)
|
814
|
+
preset[option_name] = "@vault:#{vault_label}.password"
|
815
|
+
end
|
816
|
+
end
|
817
|
+
end
|
818
|
+
return Main.result_status('Secrets secured in vault: Make sure to save the vault password securely.')
|
760
819
|
end
|
761
820
|
end
|
762
821
|
|
763
|
-
ACTIONS =
|
764
|
-
|
822
|
+
ACTIONS = %i[
|
823
|
+
id
|
824
|
+
preset
|
825
|
+
open
|
826
|
+
documentation
|
827
|
+
genkey
|
828
|
+
gem
|
829
|
+
plugin
|
830
|
+
flush_tokens
|
831
|
+
echo
|
832
|
+
wizard
|
833
|
+
export_to_cli
|
834
|
+
detect
|
835
|
+
coffee
|
836
|
+
ascp
|
837
|
+
email_test
|
838
|
+
smtp_settings
|
839
|
+
proxy_check
|
840
|
+
folder
|
841
|
+
file
|
842
|
+
check_update
|
843
|
+
initdemo
|
844
|
+
vault].concat(PRESET_GBL_ACTIONS).freeze
|
765
845
|
|
766
846
|
# "config" plugin
|
767
847
|
def execute_action
|
768
848
|
action = options.get_next_command(ACTIONS)
|
769
849
|
case action
|
770
850
|
when *PRESET_GBL_ACTIONS # older syntax
|
771
|
-
|
851
|
+
Log.log.warn{"This syntax is deprecated, use command: preset #{action}"}
|
852
|
+
return execute_preset(action: action)
|
772
853
|
when :id # older syntax
|
773
|
-
|
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)
|
774
857
|
when :preset # newer syntax
|
775
|
-
return
|
858
|
+
return execute_preset
|
776
859
|
when :open
|
777
|
-
OpenApplication.
|
860
|
+
OpenApplication.editor(@option_config_file.to_s)
|
778
861
|
return Main.result_nothing
|
779
862
|
when :documentation
|
780
|
-
section = options.get_next_argument('private key file path',mandatory: false)
|
863
|
+
section = options.get_next_argument('private key file path', mandatory: false)
|
781
864
|
section = '#' + section unless section.nil?
|
782
865
|
OpenApplication.instance.uri("#{@info[:help]}#{section}")
|
783
866
|
return Main.result_nothing
|
784
867
|
when :genkey # generate new rsa key
|
785
868
|
private_key_path = options.get_next_argument('private key file path')
|
786
|
-
private_key_length = options.get_next_argument('size in bits',mandatory: false) || DEFAULT_PRIVKEY_LENGTH
|
787
|
-
generate_rsa_private_key(private_key_path,private_key_length)
|
869
|
+
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)
|
788
871
|
return Main.result_status('Generated key: ' + private_key_path)
|
789
872
|
when :echo # display the content of a value given on command line
|
790
873
|
result = {type: :other_struct, data: options.get_next_argument('value')}
|
@@ -800,9 +883,9 @@ module Aspera
|
|
800
883
|
when :list
|
801
884
|
return {type: :object_list, data: @plugins.keys.map { |i| { 'plugin' => i.to_s, 'path' => @plugins[i][:source] } }, fields: %w[plugin path]}
|
802
885
|
when :create
|
803
|
-
plugin_name = options.get_next_argument('name',expected: :single).downcase
|
804
|
-
plugin_folder = options.get_next_argument('folder',expected: :single,mandatory: false) || File.join(@main_folder,ASPERA_PLUGINS_FOLDERNAME)
|
805
|
-
plugin_file = File.join(plugin_folder,"#{plugin_name}.rb")
|
886
|
+
plugin_name = options.get_next_argument('name', expected: :single).downcase
|
887
|
+
plugin_folder = options.get_next_argument('folder', expected: :single, mandatory: false) || File.join(@main_folder, ASPERA_PLUGINS_FOLDERNAME)
|
888
|
+
plugin_file = File.join(plugin_folder, "#{plugin_name}.rb")
|
806
889
|
content = <<~END_OF_PLUGIN_CODE
|
807
890
|
require 'aspera/cli/plugin'
|
808
891
|
module Aspera
|
@@ -816,7 +899,7 @@ module Aspera
|
|
816
899
|
end # Cli
|
817
900
|
end # Aspera
|
818
901
|
END_OF_PLUGIN_CODE
|
819
|
-
File.write(plugin_file,content)
|
902
|
+
File.write(plugin_file, content)
|
820
903
|
return Main.result_status("Created #{plugin_file}")
|
821
904
|
end
|
822
905
|
when :wizard
|
@@ -824,15 +907,15 @@ module Aspera
|
|
824
907
|
options.ask_missing_mandatory = true
|
825
908
|
# register url option
|
826
909
|
BasicAuthPlugin.register_options(@agents)
|
827
|
-
params={}
|
910
|
+
params = {}
|
828
911
|
# get from option, or ask
|
829
|
-
params[:instance_url] = options.get_option(:url,is_type: :mandatory)
|
912
|
+
params[:instance_url] = options.get_option(:url, is_type: :mandatory)
|
830
913
|
# allow user to tell the preset name
|
831
914
|
params[:preset_name] = options.get_option(:id)
|
832
915
|
# allow user to specify type of application
|
833
916
|
params[:application] = options.get_option(:value)
|
834
917
|
params[:application] = params[:application].nil? ? identify_plugin_for_url(params[:instance_url])[:product] : params[:application].to_sym
|
835
|
-
params[:plugin_name]=params[:application]
|
918
|
+
params[:plugin_name] = params[:application]
|
836
919
|
params[:test_args] = '<replace per app>'
|
837
920
|
case params[:application]
|
838
921
|
when :faspex5
|
@@ -840,56 +923,56 @@ module Aspera
|
|
840
923
|
when :aoc
|
841
924
|
wizard_aoc(params)
|
842
925
|
else
|
843
|
-
raise CliBadArgument,"Supports only: aoc. Detected: #{params[:application]}"
|
926
|
+
raise CliBadArgument, "Supports only: aoc. Detected: #{params[:application]}"
|
844
927
|
end # product
|
845
928
|
if params[:option_default]
|
846
|
-
|
929
|
+
formatter.display_status("Setting config preset as default for #{params[:plugin_name]}")
|
847
930
|
@config_presets[CONF_PRESET_DEFAULT][params[:plugin_name]] = params[:preset_name]
|
848
931
|
else
|
849
932
|
params[:test_args] = "-P#{params[:preset_name]} #{params[:test_args]}"
|
850
933
|
end
|
851
|
-
|
934
|
+
formatter.display_status('Saving config file.')
|
852
935
|
save_presets_to_config_file
|
853
936
|
return Main.result_status("Done.\nYou can test with:\n#{@info[:name]} #{params[:test_args]}")
|
854
937
|
when :export_to_cli # this method shall be deprecated in the future: it was used to export configuration to "aspera.exe" CLI
|
855
|
-
|
938
|
+
formatter.display_status('Exporting: Aspera on Cloud')
|
856
939
|
require 'aspera/cli/plugins/aoc'
|
857
940
|
# need url / username
|
858
941
|
add_plugin_default_preset(AOC_COMMAND_V3.to_sym)
|
859
|
-
#
|
942
|
+
# instantiate AoC plugin
|
860
943
|
self.class.plugin_class(AOC_COMMAND_CURRENT).new(@agents) # TODO: is this line needed ? get options ?
|
861
|
-
url = options.get_option(:url,is_type: :mandatory)
|
944
|
+
url = options.get_option(:url, is_type: :mandatory)
|
862
945
|
cli_conf_file = Fasp::Installation.instance.cli_conf_file
|
863
946
|
data = JSON.parse(File.read(cli_conf_file))
|
864
|
-
organization,instance_domain = AoC.parse_url(url)
|
947
|
+
organization, instance_domain = AoC.parse_url(url)
|
865
948
|
key_basename = 'org_' + organization + '.pem'
|
866
|
-
key_file = File.join(File.dirname(File.dirname(cli_conf_file)),'etc',key_basename)
|
867
|
-
File.write(key_file,options.get_option(:private_key,is_type: :mandatory))
|
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))
|
868
951
|
new_conf = {
|
869
952
|
'organization' => organization,
|
870
|
-
'hostname' => [organization,instance_domain].join('.'),
|
953
|
+
'hostname' => [organization, instance_domain].join('.'),
|
871
954
|
'privateKeyFilename' => key_basename,
|
872
|
-
'username' => options.get_option(:username,is_type: :mandatory)
|
955
|
+
'username' => options.get_option(:username, is_type: :mandatory)
|
873
956
|
}
|
874
957
|
new_conf['clientId'] = options.get_option(:client_id)
|
875
958
|
new_conf['clientSecret'] = options.get_option(:client_secret)
|
876
959
|
if new_conf['clientId'].nil?
|
877
|
-
new_conf['clientId'],new_conf['clientSecret'] = AoC.get_client_info
|
960
|
+
new_conf['clientId'], new_conf['clientSecret'] = AoC.get_client_info
|
878
961
|
end
|
879
962
|
entry = data['AoCAccounts'].find{|i|i['organization'].eql?(organization)}
|
880
963
|
if entry.nil?
|
881
964
|
data['AoCAccounts'].push(new_conf)
|
882
|
-
|
965
|
+
formatter.display_status("Creating new aoc entry: #{organization}")
|
883
966
|
else
|
884
|
-
|
967
|
+
formatter.display_status("Updating existing aoc entry: #{organization}")
|
885
968
|
entry.merge!(new_conf)
|
886
969
|
end
|
887
|
-
File.write(cli_conf_file,JSON.pretty_generate(data))
|
970
|
+
File.write(cli_conf_file, JSON.pretty_generate(data))
|
888
971
|
return Main.result_status("Updated: #{cli_conf_file}")
|
889
972
|
when :detect
|
890
973
|
# need url / username
|
891
974
|
BasicAuthPlugin.register_options(@agents)
|
892
|
-
return {type: :single_object, data: identify_plugin_for_url(options.get_option(:url,is_type: :mandatory))}
|
975
|
+
return {type: :single_object, data: identify_plugin_for_url(options.get_option(:url, is_type: :mandatory))}
|
893
976
|
when :coffee
|
894
977
|
OpenApplication.instance.uri('https://enjoyjava.com/wp-content/uploads/2018/01/How-to-make-strong-coffee.jpg')
|
895
978
|
return Main.result_nothing
|
@@ -912,16 +995,16 @@ module Aspera
|
|
912
995
|
return {type: :single_object, data: email_settings}
|
913
996
|
when :proxy_check
|
914
997
|
# ensure fpac was provided
|
915
|
-
options.get_option(:fpac,is_type: :mandatory)
|
998
|
+
options.get_option(:fpac, is_type: :mandatory)
|
916
999
|
server_url = options.get_next_argument('server url')
|
917
1000
|
return Main.result_status(@pac_exec.find_proxy_for_url(server_url))
|
918
1001
|
when :check_update
|
919
1002
|
return {type: :single_object, data: check_gem_version}
|
920
1003
|
when :initdemo
|
921
|
-
if @config_presets.
|
922
|
-
Log.log.warn
|
1004
|
+
if @config_presets.key?(DEMO_SERVER_PRESET)
|
1005
|
+
Log.log.warn{"Demo server preset already present: #{DEMO_SERVER_PRESET}"}
|
923
1006
|
else
|
924
|
-
Log.log.info
|
1007
|
+
Log.log.info{"Creating Demo server preset: #{DEMO_SERVER_PRESET}"}
|
925
1008
|
@config_presets[DEMO_SERVER_PRESET] = {
|
926
1009
|
'url' => 'ssh://' + DEMO + '.asperasoft.com:33001',
|
927
1010
|
'username' => AOC_COMMAND_V2,
|
@@ -929,13 +1012,13 @@ module Aspera
|
|
929
1012
|
}
|
930
1013
|
end
|
931
1014
|
@config_presets[CONF_PRESET_DEFAULT] ||= {}
|
932
|
-
if @config_presets[CONF_PRESET_DEFAULT].
|
933
|
-
Log.log.warn
|
934
|
-
Log.log.warn
|
1015
|
+
if @config_presets[CONF_PRESET_DEFAULT].key?(SERVER_COMMAND)
|
1016
|
+
Log.log.warn{"Server default preset already set to: #{@config_presets[CONF_PRESET_DEFAULT][SERVER_COMMAND]}"}
|
1017
|
+
Log.log.warn{"Use #{DEMO_SERVER_PRESET} for demo: -P#{DEMO_SERVER_PRESET}"} unless
|
935
1018
|
DEMO_SERVER_PRESET.eql?(@config_presets[CONF_PRESET_DEFAULT][SERVER_COMMAND])
|
936
1019
|
else
|
937
1020
|
@config_presets[CONF_PRESET_DEFAULT][SERVER_COMMAND] = DEMO_SERVER_PRESET
|
938
|
-
Log.log.info
|
1021
|
+
Log.log.info{"Setting server default preset to : #{DEMO_SERVER_PRESET}"}
|
939
1022
|
end
|
940
1023
|
save_presets_to_config_file
|
941
1024
|
return Main.result_status('Done')
|
@@ -946,20 +1029,20 @@ module Aspera
|
|
946
1029
|
|
947
1030
|
# @return email server setting with defaults if not defined
|
948
1031
|
def email_settings
|
949
|
-
smtp = options.get_option(:smtp,is_type: :mandatory)
|
1032
|
+
smtp = options.get_option(:smtp, is_type: :mandatory)
|
950
1033
|
# change string keys into symbol keys
|
951
|
-
smtp = smtp.keys.each_with_object({}){|v,m|m[v.to_sym] = smtp[v];}
|
1034
|
+
smtp = smtp.keys.each_with_object({}){|v, m|m[v.to_sym] = smtp[v]; }
|
952
1035
|
# defaults
|
953
1036
|
smtp[:tls] ||= true
|
954
1037
|
smtp[:port] ||= smtp[:tls] ? 587 : 25
|
955
|
-
smtp[:from_email] ||= smtp[:username] if smtp.
|
956
|
-
smtp[:from_name] ||= smtp[:from_email].gsub(/@.*$/,'').gsub(/[^a-zA-Z]/,' ').capitalize if smtp.
|
957
|
-
smtp[:domain] ||= smtp[:from_email].gsub(/^.*@/,'') if smtp.
|
1038
|
+
smtp[:from_email] ||= smtp[:username] if smtp.key?(:username)
|
1039
|
+
smtp[:from_name] ||= smtp[:from_email].gsub(/@.*$/, '').gsub(/[^a-zA-Z]/, ' ').capitalize if smtp.key?(:username)
|
1040
|
+
smtp[:domain] ||= smtp[:from_email].gsub(/^.*@/, '') if smtp.key?(:from_email)
|
958
1041
|
# check minimum required
|
959
1042
|
%i[server port domain].each do |n|
|
960
|
-
raise "Missing smtp parameter: #{n}" unless smtp.
|
1043
|
+
raise "Missing smtp parameter: #{n}" unless smtp.key?(n)
|
961
1044
|
end
|
962
|
-
Log.log.debug
|
1045
|
+
Log.log.debug{"smtp=#{smtp}"}
|
963
1046
|
return smtp
|
964
1047
|
end
|
965
1048
|
|
@@ -969,26 +1052,26 @@ module Aspera
|
|
969
1052
|
end
|
970
1053
|
|
971
1054
|
def send_email_template(email_template_default: nil, values: {})
|
972
|
-
values[:to] ||= options.get_option(:notif_to,is_type: :mandatory)
|
973
|
-
notif_template = options.get_option(:notif_template,is_type: email_template_default.nil? ? :mandatory : :optional) || email_template_default
|
1055
|
+
values[:to] ||= options.get_option(:notif_to, is_type: :mandatory)
|
1056
|
+
notif_template = options.get_option(:notif_template, is_type: email_template_default.nil? ? :mandatory : :optional) || email_template_default
|
974
1057
|
mail_conf = email_settings
|
975
1058
|
values[:from_name] ||= mail_conf[:from_name]
|
976
1059
|
values[:from_email] ||= mail_conf[:from_email]
|
977
1060
|
%i[from_name from_email].each do |n|
|
978
|
-
raise "Missing email parameter: #{n}" unless values.
|
1061
|
+
raise "Missing email parameter: #{n}" unless values.key?(n)
|
979
1062
|
end
|
980
1063
|
start_options = [mail_conf[:domain]]
|
981
|
-
start_options.push(mail_conf[:username],mail_conf[:password]
|
1064
|
+
start_options.push(mail_conf[:username], mail_conf[:password], :login) if mail_conf.key?(:username) && mail_conf.key?(:password)
|
982
1065
|
# create a binding with only variables defined in values
|
983
1066
|
template_binding = empty_binding
|
984
1067
|
# add variables to binding
|
985
|
-
values.each do |k,v|
|
1068
|
+
values.each do |k, v|
|
986
1069
|
raise "key (#{k.class}) must be Symbol" unless k.is_a?(Symbol)
|
987
|
-
template_binding.local_variable_set(k,v)
|
1070
|
+
template_binding.local_variable_set(k, v)
|
988
1071
|
end
|
989
1072
|
# execute template
|
990
1073
|
msg_with_headers = ERB.new(notif_template).result(template_binding)
|
991
|
-
Log.dump(:msg_with_headers,msg_with_headers)
|
1074
|
+
Log.dump(:msg_with_headers, msg_with_headers)
|
992
1075
|
smtp = Net::SMTP.new(mail_conf[:server], mail_conf[:port])
|
993
1076
|
smtp.enable_starttls if mail_conf[:tls]
|
994
1077
|
smtp.start(*start_options) do |smtp_session|
|
@@ -999,8 +1082,8 @@ module Aspera
|
|
999
1082
|
def save_presets_to_config_file
|
1000
1083
|
raise 'no configuration loaded' if @config_presets.nil?
|
1001
1084
|
FileUtils.mkdir_p(@main_folder) unless Dir.exist?(@main_folder)
|
1002
|
-
Log.log.debug
|
1003
|
-
File.write(@option_config_file
|
1085
|
+
Log.log.debug{"Writing #{@option_config_file}"}
|
1086
|
+
File.write(@option_config_file, @config_presets.to_yaml)
|
1004
1087
|
Environment.restrict_file_access(@main_folder)
|
1005
1088
|
Environment.restrict_file_access(@option_config_file)
|
1006
1089
|
end
|
@@ -1013,21 +1096,23 @@ module Aspera
|
|
1013
1096
|
Log.log.debug('skip default config')
|
1014
1097
|
return nil
|
1015
1098
|
end
|
1016
|
-
if @config_presets.
|
1017
|
-
|
1099
|
+
if @config_presets.key?(CONF_PRESET_DEFAULT) &&
|
1100
|
+
@config_presets[CONF_PRESET_DEFAULT].key?(plugin_sym.to_s)
|
1018
1101
|
default_config_name = @config_presets[CONF_PRESET_DEFAULT][plugin_sym.to_s]
|
1019
|
-
if !@config_presets.
|
1020
|
-
Log.log.error
|
1021
|
-
|
1022
|
-
|
1102
|
+
if !@config_presets.key?(default_config_name)
|
1103
|
+
Log.log.error do
|
1104
|
+
"Default config name [#{default_config_name}] specified for plugin [#{plugin_sym}], but it does not exist in config file.\n"\
|
1105
|
+
'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 #{plugin_sym})."
|
1107
|
+
end
|
1023
1108
|
end
|
1024
|
-
raise CliError,"Config name [#{default_config_name}] must be a hash, check config file." if !@config_presets[default_config_name].is_a?(Hash)
|
1109
|
+
raise CliError, "Config name [#{default_config_name}] must be a hash, check config file." if !@config_presets[default_config_name].is_a?(Hash)
|
1025
1110
|
return default_config_name
|
1026
1111
|
end
|
1027
1112
|
return nil
|
1028
1113
|
end # get_plugin_default_config_name
|
1029
1114
|
|
1030
|
-
ALLOWED_KEYS
|
1115
|
+
ALLOWED_KEYS = %i[password username description].freeze
|
1031
1116
|
def execute_vault
|
1032
1117
|
command = options.get_next_command(%i[list show create delete password])
|
1033
1118
|
case command
|
@@ -1036,11 +1121,11 @@ module Aspera
|
|
1036
1121
|
when :show
|
1037
1122
|
return {type: :single_object, data: vault.get(label: options.get_next_argument('label'))}
|
1038
1123
|
when :create
|
1039
|
-
label=options.get_next_argument('label')
|
1040
|
-
info=options.get_next_argument('info Hash')
|
1124
|
+
label = options.get_next_argument('label')
|
1125
|
+
info = options.get_next_argument('info Hash')
|
1041
1126
|
raise 'info must be Hash' unless info.is_a?(Hash)
|
1042
|
-
info=info.symbolize_keys
|
1043
|
-
info[:label]=label
|
1127
|
+
info = info.symbolize_keys
|
1128
|
+
info[:label] = label
|
1044
1129
|
vault.set(info)
|
1045
1130
|
return Main.result_status('Password added')
|
1046
1131
|
when :delete
|
@@ -1048,154 +1133,173 @@ module Aspera
|
|
1048
1133
|
return Main.result_status('Password deleted')
|
1049
1134
|
when :password
|
1050
1135
|
raise 'Vault does not support password change' unless vault.respond_to?(:password=)
|
1051
|
-
new_password=options.get_next_argument('new_password')
|
1052
|
-
vault.password=new_password
|
1136
|
+
new_password = options.get_next_argument('new_password')
|
1137
|
+
vault.password = new_password
|
1053
1138
|
vault.save
|
1054
1139
|
return Main.result_status('Password updated')
|
1055
1140
|
end
|
1056
1141
|
end
|
1057
1142
|
|
1058
1143
|
def vault_value(name)
|
1059
|
-
m=name.match(/^(.+)\.(.+)$/)
|
1144
|
+
m = name.match(/^(.+)\.(.+)$/)
|
1060
1145
|
raise 'vault name shall match <name>.<param>' if m.nil?
|
1061
|
-
info=vault.get(label: m[1])
|
1062
|
-
#raise "no such vault entry: #{m[1]}" if info.nil?
|
1063
|
-
value=info[m[2].to_sym]
|
1146
|
+
info = vault.get(label: m[1])
|
1147
|
+
# raise "no such vault entry: #{m[1]}" if info.nil?
|
1148
|
+
value = info[m[2].to_sym]
|
1064
1149
|
raise "no such entry value: #{m[2]}" if value.nil?
|
1065
1150
|
return value
|
1066
1151
|
end
|
1067
1152
|
|
1068
1153
|
def vault
|
1069
1154
|
if @vault.nil?
|
1070
|
-
vault_info = options.get_option(:vault) || {'type'=>'file','name'=>'vault.bin'}
|
1071
|
-
vault_password = options.get_option(:vault_password,is_type: :mandatory)
|
1155
|
+
vault_info = options.get_option(:vault) || {'type' => 'file', 'name' => 'vault.bin'}
|
1156
|
+
vault_password = options.get_option(:vault_password, is_type: :mandatory)
|
1072
1157
|
raise 'vault must be Hash' unless vault_info.is_a?(Hash)
|
1073
1158
|
vault_type = vault_info['type'] || 'file'
|
1074
1159
|
vault_name = vault_info['name'] || (vault_type.eql?('file') ? 'vault.bin' : PROGRAM_NAME)
|
1075
1160
|
case vault_type
|
1076
1161
|
when 'file'
|
1077
|
-
|
1078
|
-
|
1162
|
+
# absolute_path? introduced in ruby 2.7
|
1163
|
+
vault_path = vault_name.eql?(File.absolute_path(vault_name)) ? vault_name : File.join(@main_folder, vault_name)
|
1164
|
+
@vault = Keychain::EncryptedHash.new(vault_path, vault_password)
|
1079
1165
|
when 'system'
|
1080
1166
|
case Environment.os
|
1081
1167
|
when Environment::OS_X
|
1082
|
-
@vault = Keychain::MacosSystem.new(vault_name,vault_password)
|
1083
|
-
when Environment::OS_WINDOWS,Environment::OS_LINUX,Environment::OS_AIX
|
1168
|
+
@vault = Keychain::MacosSystem.new(vault_name, vault_password)
|
1169
|
+
when Environment::OS_WINDOWS, Environment::OS_LINUX, Environment::OS_AIX
|
1084
1170
|
raise 'not implemented'
|
1085
1171
|
else raise 'Error, OS not supported'
|
1086
1172
|
end
|
1087
1173
|
else
|
1088
|
-
raise CliBadArgument,"Unknown vault type: #{vault_type}"
|
1174
|
+
raise CliBadArgument, "Unknown vault type: #{vault_type}"
|
1089
1175
|
end
|
1090
1176
|
end
|
1091
1177
|
raise 'No vault defined' if @vault.nil?
|
1092
1178
|
@vault
|
1093
1179
|
end
|
1094
1180
|
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1181
|
+
# version of URL without trailing "/" and removing default port
|
1182
|
+
def canonical_url(url)
|
1183
|
+
url.gsub(%r{/+$}, '').gsub(%r{^(https://[^/]+):443$}, '\1')
|
1184
|
+
end
|
1185
|
+
|
1186
|
+
def lookup_preset(url:, username:)
|
1187
|
+
# remove extra info to maximize match
|
1188
|
+
url = canonical_url(url)
|
1189
|
+
Log.log.debug{"Lookup preset for #{username}@#{url}"}
|
1190
|
+
@config_presets.each do |_k, v|
|
1191
|
+
next unless v.is_a?(Hash)
|
1192
|
+
conf_url = v['url'].is_a?(String) ? canonical_url(v['url']) : nil
|
1193
|
+
return v if conf_url.eql?(url) && v['username'].eql?(username)
|
1194
|
+
end
|
1195
|
+
nil
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
def lookup_secret(url:, username:, mandatory: false)
|
1199
|
+
secret = options.get_option(:secret)
|
1099
1200
|
if secret.nil?
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1201
|
+
conf = lookup_preset(url: url, username: username)
|
1202
|
+
if conf.is_a?(Hash)
|
1203
|
+
Log.log.debug{"Found preset #{conf} with URL and username"}
|
1204
|
+
secret = conf['password']
|
1205
|
+
end
|
1206
|
+
raise "Please provide secret for #{username} using option: secret or by setting a preset for #{username}@#{url}." if secret.nil? && mandatory
|
1103
1207
|
end
|
1104
1208
|
return secret
|
1105
1209
|
end
|
1106
1210
|
|
1107
1211
|
def wizard_aoc(params)
|
1108
|
-
|
1212
|
+
formatter.display_status('Detected: Aspera on Cloud'.bold)
|
1109
1213
|
params[:plugin_name] = AOC_COMMAND_CURRENT
|
1110
1214
|
organization = AoC.parse_url(params[:instance_url]).first
|
1111
1215
|
# if not defined by user, generate name
|
1112
|
-
params[:preset_name] = [params[:application],organization].join('_') if params[:preset_name].nil?
|
1113
|
-
|
1216
|
+
params[:preset_name] = [params[:application], organization].join('_') if params[:preset_name].nil?
|
1217
|
+
formatter.display_status("Preparing preset: #{params[:preset_name]}")
|
1114
1218
|
# init defaults if necessary
|
1115
1219
|
@config_presets[CONF_PRESET_DEFAULT] ||= {}
|
1116
|
-
option_override = options.get_option(:override,is_type: :mandatory)
|
1117
|
-
params[:option_default] = options.get_option(:default,is_type: :mandatory)
|
1118
|
-
Log.log.error
|
1119
|
-
raise CliError,"A default configuration already exists for plugin '#{params[:plugin_name]}' (use --override=yes or --default=no)" \
|
1120
|
-
if !option_override && params[:option_default] && @config_presets[CONF_PRESET_DEFAULT].
|
1121
|
-
raise CliError,"Preset already exists: #{params[:preset_name]} (use --override=yes or --id=<name>)" \
|
1122
|
-
if !option_override && @config_presets.
|
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])
|
1123
1227
|
# lets see if path to priv key is provided
|
1124
1228
|
private_key_path = options.get_option(:pkeypath)
|
1125
1229
|
# give a chance to provide
|
1126
1230
|
if private_key_path.nil?
|
1127
|
-
|
1128
|
-
private_key_path = options.get_option(:pkeypath,is_type: :mandatory).to_s
|
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
|
1129
1233
|
end
|
1130
1234
|
# else generate path
|
1131
1235
|
if private_key_path.empty?
|
1132
|
-
private_key_path = File.join(@main_folder,DEFAULT_PRIV_KEY_FILENAME)
|
1236
|
+
private_key_path = File.join(@main_folder, DEFAULT_PRIV_KEY_FILENAME)
|
1133
1237
|
end
|
1134
1238
|
if File.exist?(private_key_path)
|
1135
|
-
|
1239
|
+
formatter.display_status('Using existing key:')
|
1136
1240
|
else
|
1137
|
-
|
1138
|
-
generate_rsa_private_key(private_key_path,DEFAULT_PRIVKEY_LENGTH)
|
1139
|
-
|
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:')
|
1140
1244
|
end
|
1141
|
-
|
1245
|
+
formatter.display_status(private_key_path)
|
1142
1246
|
pub_key_pem = OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
|
1143
1247
|
# declare command line options for AoC
|
1144
1248
|
require 'aspera/cli/plugins/aoc'
|
1145
1249
|
# make username mandatory for jwt, this triggers interactive input
|
1146
|
-
options.get_option(:username,is_type: :mandatory)
|
1147
|
-
#
|
1250
|
+
options.get_option(:username, is_type: :mandatory)
|
1251
|
+
# instantiate AoC plugin, so that command line options are known
|
1148
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
|
1149
1253
|
auto_set_pub_key = false
|
1150
1254
|
auto_set_jwt = false
|
1151
1255
|
use_browser_authentication = false
|
1152
1256
|
if options.get_option(:use_generic_client)
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
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)
|
1158
1262
|
if !options.get_option(:test_mode)
|
1159
|
-
|
1263
|
+
formatter.display_status('Once updated or validated, press enter.')
|
1160
1264
|
OpenApplication.instance.uri(params[:instance_url])
|
1161
1265
|
$stdin.gets
|
1162
1266
|
end
|
1163
1267
|
else
|
1164
|
-
|
1165
|
-
if options.get_option(:client_id).nil? || options.get_option(:client_secret,is_type: :optional).nil?
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
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)
|
1174
1278
|
end
|
1175
1279
|
OpenApplication.instance.uri("#{params[:instance_url]}/#{AOC_PATH_API_CLIENTS}")
|
1176
|
-
options.get_option(:client_id,is_type: :mandatory)
|
1177
|
-
options.get_option(:client_secret,is_type: :mandatory)
|
1280
|
+
options.get_option(:client_id, is_type: :mandatory)
|
1281
|
+
options.get_option(:client_secret, is_type: :mandatory)
|
1178
1282
|
use_browser_authentication = true
|
1179
1283
|
end
|
1180
1284
|
if use_browser_authentication
|
1181
|
-
|
1285
|
+
formatter.display_status('We will use web authentication to bootstrap.')
|
1182
1286
|
auto_set_pub_key = true
|
1183
1287
|
auto_set_jwt = true
|
1184
|
-
aoc_api.oauth.
|
1185
|
-
aoc_api.oauth.
|
1186
|
-
aoc_api.oauth.
|
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
|
1187
1291
|
end
|
1188
1292
|
myself = aoc_api.read('self')[:data]
|
1189
1293
|
if auto_set_pub_key
|
1190
|
-
raise CliError,'Public key is already set in profile (use --override=yes)' unless myself['public_key'].empty? || option_override
|
1191
|
-
|
1192
|
-
aoc_api.update("users/#{myself['id']}",{'public_key' => pub_key_pem})
|
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})
|
1193
1297
|
end
|
1194
1298
|
if auto_set_jwt
|
1195
|
-
|
1196
|
-
aoc_api.update("clients/#{options.get_option(:client_id)}",{'jwt_grant_enabled' => true,'explicit_authorization_required' => false})
|
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})
|
1197
1301
|
end
|
1198
|
-
|
1302
|
+
formatter.display_status("Creating new config preset: #{params[:preset_name]}")
|
1199
1303
|
@config_presets[params[:preset_name]] = {
|
1200
1304
|
:url.to_s => options.get_option(:url),
|
1201
1305
|
:username.to_s => myself['email'],
|
@@ -1211,58 +1315,58 @@ module Aspera
|
|
1211
1315
|
end
|
1212
1316
|
|
1213
1317
|
def wizard_faspex5(params)
|
1214
|
-
|
1318
|
+
formatter.display_status('Detected: Faspex v5'.bold)
|
1215
1319
|
# if not defined by user, generate unique name
|
1216
|
-
params[:preset_name] = [params[:application]
|
1320
|
+
params[:preset_name] = [params[:application]].concat(URI.parse(params[:instance_url]).host.gsub(/[^a-z0-9.]/, '').split('.')).join('_') \
|
1217
1321
|
if params[:preset_name].nil?
|
1218
|
-
|
1322
|
+
formatter.display_status("Preparing preset: #{params[:preset_name]}")
|
1219
1323
|
# init defaults if necessary
|
1220
1324
|
@config_presets[CONF_PRESET_DEFAULT] ||= {}
|
1221
|
-
option_override = options.get_option(:override,is_type: :mandatory)
|
1222
|
-
params[:option_default] = options.get_option(:default,is_type: :mandatory)
|
1223
|
-
Log.log.error
|
1224
|
-
raise CliError,"A default configuration already exists for plugin '#{params[:plugin_name]}' (use --override=yes or --default=no)" \
|
1225
|
-
if !option_override && params[:option_default] && @config_presets[CONF_PRESET_DEFAULT].
|
1226
|
-
raise CliError,"Preset already exists: #{params[:preset_name]} (use --override=yes or --id=<name>)" \
|
1227
|
-
if !option_override && @config_presets.
|
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])
|
1228
1332
|
# lets see if path to priv key is provided
|
1229
1333
|
private_key_path = options.get_option(:pkeypath)
|
1230
1334
|
# give a chance to provide
|
1231
1335
|
if private_key_path.nil?
|
1232
|
-
|
1233
|
-
private_key_path = options.get_option(:pkeypath,is_type: :mandatory).to_s
|
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
|
1234
1338
|
end
|
1235
1339
|
# else generate path
|
1236
1340
|
if private_key_path.empty?
|
1237
|
-
private_key_path = File.join(@main_folder,DEFAULT_PRIV_KEY_FILENAME)
|
1341
|
+
private_key_path = File.join(@main_folder, DEFAULT_PRIV_KEY_FILENAME)
|
1238
1342
|
end
|
1239
1343
|
if File.exist?(private_key_path)
|
1240
|
-
|
1344
|
+
formatter.display_status('Using existing key:')
|
1241
1345
|
else
|
1242
|
-
|
1243
|
-
generate_rsa_private_key(private_key_path,DEFAULT_PRIVKEY_LENGTH)
|
1244
|
-
|
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:')
|
1245
1349
|
end
|
1246
|
-
|
1350
|
+
formatter.display_status(private_key_path)
|
1247
1351
|
pub_key_pem = OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
|
1248
1352
|
# declare command line options for AoC
|
1249
1353
|
require 'aspera/cli/plugins/faspex5'
|
1250
1354
|
self.class.plugin_class(params[:plugin_name]).new(@agents.merge({skip_basic_auth_options: true}))
|
1251
|
-
|
1355
|
+
formatter.display_status('Please login to Faspex 5.'.red)
|
1252
1356
|
OpenApplication.instance.uri(params[:instance_url])
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
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:')
|
1259
1363
|
@config_presets[params[:preset_name]] = {
|
1260
1364
|
:url.to_s => options.get_option(:url),
|
1261
1365
|
:username.to_s => options.get_option(:username),
|
1262
1366
|
:auth.to_s => :jwt.to_s,
|
1263
1367
|
:private_key.to_s => '@file:' + private_key_path,
|
1264
|
-
:client_id.to_s => options.get_option(:client_id,is_type: :mandatory),
|
1265
|
-
:client_secret.to_s => options.get_option(:client_secret,is_type: :mandatory)
|
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)
|
1266
1370
|
}
|
1267
1371
|
params[:test_args] = "#{params[:plugin_name]} user profile show"
|
1268
1372
|
end
|