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