aspera-cli 4.18.1 → 4.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +33 -0
- data/CONTRIBUTING.md +17 -12
- data/README.md +396 -185
- data/bin/asession +26 -19
- data/examples/build_exec +74 -0
- data/examples/{rubyc → build_exec_rubyc} +18 -2
- data/examples/get_proto_file.rb +7 -0
- data/lib/aspera/agent/alpha.rb +8 -8
- data/lib/aspera/agent/base.rb +4 -18
- data/lib/aspera/agent/connect.rb +14 -13
- data/lib/aspera/agent/direct.rb +123 -120
- data/lib/aspera/agent/httpgw.rb +2 -3
- data/lib/aspera/agent/node.rb +10 -10
- data/lib/aspera/agent/trsdk.rb +17 -20
- data/lib/aspera/api/alee.rb +15 -0
- data/lib/aspera/api/aoc.rb +128 -99
- data/lib/aspera/api/ats.rb +1 -1
- data/lib/aspera/api/cos_node.rb +1 -1
- data/lib/aspera/api/httpgw.rb +104 -64
- data/lib/aspera/api/node.rb +33 -12
- data/lib/aspera/ascmd.rb +56 -48
- data/lib/aspera/ascp/installation.rb +142 -70
- data/lib/aspera/ascp/management.rb +7 -3
- data/lib/aspera/ascp/products.rb +13 -7
- data/lib/aspera/assert.rb +10 -5
- data/lib/aspera/cli/formatter.rb +42 -26
- data/lib/aspera/cli/hints.rb +2 -1
- data/lib/aspera/cli/info.rb +12 -10
- data/lib/aspera/cli/main.rb +16 -13
- data/lib/aspera/cli/manager.rb +15 -10
- data/lib/aspera/cli/plugin.rb +17 -31
- data/lib/aspera/cli/plugin_factory.rb +10 -1
- data/lib/aspera/cli/plugins/alee.rb +3 -3
- data/lib/aspera/cli/plugins/aoc.rb +222 -194
- data/lib/aspera/cli/plugins/ats.rb +16 -14
- data/lib/aspera/cli/plugins/config.rb +66 -53
- data/lib/aspera/cli/plugins/console.rb +3 -3
- data/lib/aspera/cli/plugins/faspex.rb +11 -21
- data/lib/aspera/cli/plugins/faspex5.rb +44 -42
- data/lib/aspera/cli/plugins/faspio.rb +2 -2
- data/lib/aspera/cli/plugins/httpgw.rb +1 -1
- data/lib/aspera/cli/plugins/node.rb +155 -96
- data/lib/aspera/cli/plugins/orchestrator.rb +14 -13
- data/lib/aspera/cli/plugins/preview.rb +8 -9
- data/lib/aspera/cli/plugins/server.rb +6 -10
- data/lib/aspera/cli/plugins/shares.rb +13 -9
- data/lib/aspera/cli/sync_actions.rb +72 -31
- data/lib/aspera/cli/transfer_agent.rb +13 -14
- data/lib/aspera/cli/transfer_progress.rb +36 -18
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/command_line_builder.rb +3 -4
- data/lib/aspera/coverage.rb +13 -1
- data/lib/aspera/environment.rb +59 -10
- data/lib/aspera/faspex_gw.rb +3 -3
- data/lib/aspera/json_rpc.rb +1 -1
- data/lib/aspera/keychain/encrypted_hash.rb +2 -0
- data/lib/aspera/keychain/macos_security.rb +7 -12
- data/lib/aspera/log.rb +4 -4
- data/lib/aspera/node_simulator.rb +1 -1
- data/lib/aspera/oauth/base.rb +39 -45
- data/lib/aspera/oauth/factory.rb +11 -4
- data/lib/aspera/oauth/generic.rb +4 -8
- data/lib/aspera/oauth/jwt.rb +4 -4
- data/lib/aspera/oauth/url_json.rb +3 -2
- data/lib/aspera/oauth/web.rb +10 -6
- data/lib/aspera/persistency_action_once.rb +16 -8
- data/lib/aspera/preview/utils.rb +5 -16
- data/lib/aspera/rest.rb +100 -76
- data/lib/aspera/secret_hider.rb +3 -2
- data/lib/aspera/ssh.rb +1 -1
- data/lib/aspera/transfer/faux_file.rb +7 -5
- data/lib/aspera/transfer/parameters.rb +41 -35
- data/lib/aspera/transfer/spec.rb +16 -18
- data/lib/aspera/transfer/sync.rb +51 -50
- data/lib/aspera/transfer/uri.rb +1 -1
- data/lib/aspera/uri_reader.rb +1 -1
- data/lib/aspera/web_auth.rb +166 -18
- data/lib/aspera/web_server_simple.rb +27 -15
- data/lib/transfer_pb.rb +84 -0
- data/lib/transfer_services_pb.rb +82 -0
- data.tar.gz.sig +0 -0
- metadata +25 -6
- metadata.gz.sig +0 -0
@@ -5,6 +5,7 @@
|
|
5
5
|
require 'aspera/cli/plugins/node'
|
6
6
|
require 'aspera/api/ats'
|
7
7
|
require 'aspera/api/aoc'
|
8
|
+
require 'aspera/api/alee'
|
8
9
|
require 'aspera/assert'
|
9
10
|
|
10
11
|
module Aspera
|
@@ -24,13 +25,14 @@ module Aspera
|
|
24
25
|
options.declare(:cloud, 'Cloud provider')
|
25
26
|
options.declare(:region, 'Cloud region')
|
26
27
|
options.parse_options!
|
28
|
+
Node.declare_options(options)
|
27
29
|
end
|
28
30
|
|
29
31
|
def server_by_cloud_region
|
30
32
|
# TODO: provide list ?
|
31
33
|
cloud = options.get_option(:cloud, mandatory: true).upcase
|
32
34
|
region = options.get_option(:region, mandatory: true)
|
33
|
-
return @ats_api_pub.read("servers/#{cloud}/#{region}")
|
35
|
+
return @ats_api_pub.read("servers/#{cloud}/#{region}")
|
34
36
|
end
|
35
37
|
|
36
38
|
# require api key only if needed
|
@@ -84,29 +86,29 @@ module Aspera
|
|
84
86
|
end
|
85
87
|
end
|
86
88
|
res = ats_api_pub_v1.create('access_keys', params)
|
87
|
-
return {type: :single_object, data: res
|
89
|
+
return {type: :single_object, data: res}
|
88
90
|
# TODO : action : modify, with "PUT"
|
89
91
|
when :list
|
90
92
|
params = options.get_option(:params) || {'offset' => 0, 'max_results' => 1000}
|
91
93
|
res = ats_api_pub_v1.read('access_keys', params)
|
92
|
-
return {type: :object_list, data: res[
|
94
|
+
return {type: :object_list, data: res['data'], fields: ['name', 'id', 'created.at', 'modified.at']}
|
93
95
|
when :show
|
94
96
|
res = ats_api_pub_v1.read("access_keys/#{access_key_id}")
|
95
|
-
return {type: :single_object, data: res
|
97
|
+
return {type: :single_object, data: res}
|
96
98
|
when :modify
|
97
99
|
params = value_create_modify(command: command)
|
98
100
|
params['id'] = access_key_id
|
99
101
|
ats_api_pub_v1.update("access_keys/#{access_key_id}", params)
|
100
102
|
return Main.result_status('modified')
|
101
103
|
when :entitlement
|
102
|
-
ak = ats_api_pub_v1.read("access_keys/#{access_key_id}")
|
104
|
+
ak = ats_api_pub_v1.read("access_keys/#{access_key_id}")
|
103
105
|
api_bss = Api::Alee.new(ak['license']['entitlement_id'], ak['license']['customer_id'])
|
104
|
-
return {type: :single_object, data: api_bss.read('entitlement')
|
106
|
+
return {type: :single_object, data: api_bss.read('entitlement')}
|
105
107
|
when :delete
|
106
108
|
ats_api_pub_v1.delete("access_keys/#{access_key_id}")
|
107
109
|
return Main.result_status("deleted #{access_key_id}")
|
108
110
|
when :node
|
109
|
-
ak_data = ats_api_pub_v1.read("access_keys/#{access_key_id}")
|
111
|
+
ak_data = ats_api_pub_v1.read("access_keys/#{access_key_id}")
|
110
112
|
server_data = @ats_api_pub.all_servers.find {|i| i['id'].start_with?(ak_data['transfer_server_id'])}
|
111
113
|
raise Cli::Error, 'no such server found' if server_data.nil?
|
112
114
|
node_url = server_data['transfer_setup_url']
|
@@ -128,7 +130,7 @@ module Aspera
|
|
128
130
|
username: access_key_id,
|
129
131
|
password: config.lookup_secret(url: ats_url, username: access_key_id)
|
130
132
|
})
|
131
|
-
return {type: :single_object, data: api_ak_auth.read('servers')
|
133
|
+
return {type: :single_object, data: api_ak_auth.read('servers')}
|
132
134
|
else Aspera.error_unexpected_value(command)
|
133
135
|
end
|
134
136
|
end
|
@@ -177,7 +179,7 @@ module Aspera
|
|
177
179
|
instance = options.get_option(:instance)
|
178
180
|
if instance.nil?
|
179
181
|
# Take the first Aspera on Cloud transfer service instance ID if not provided by user
|
180
|
-
instance = ats_api_v2_auth_ibm.read('instances')[
|
182
|
+
instance = ats_api_v2_auth_ibm.read('instances')['data'].first
|
181
183
|
formatter.display_status("using first instance: #{instance}")
|
182
184
|
end
|
183
185
|
rest_add_header = {'X-ATS-Service-Instance-Id' => instance}
|
@@ -185,18 +187,18 @@ module Aspera
|
|
185
187
|
ats_ibm_api = ats_api_v2_auth_ibm(rest_add_header)
|
186
188
|
case command
|
187
189
|
when :instances
|
188
|
-
instances = ats_ibm_api.read('instances')
|
190
|
+
instances = ats_ibm_api.read('instances')
|
189
191
|
Log.log.warn{"more instances remaining: #{instances['remaining']}"} unless instances['remaining'].to_i.eql?(0)
|
190
192
|
return {type: :value_list, data: instances['data'], name: 'instance'}
|
191
193
|
when :create
|
192
|
-
created_key = ats_ibm_api.create('api_keys', value_create_modify(command: command, default: {}))
|
194
|
+
created_key = ats_ibm_api.create('api_keys', value_create_modify(command: command, default: {}))
|
193
195
|
return {type: :single_object, data: created_key}
|
194
196
|
when :list # list known api keys in ATS (this require an api_key ...)
|
195
197
|
res = ats_ibm_api.read('api_keys', {'offset' => 0, 'max_results' => 1000})
|
196
|
-
return {type: :value_list, data: res[
|
198
|
+
return {type: :value_list, data: res['data'], name: 'ats_id'}
|
197
199
|
when :show # show one of api_key in ATS
|
198
200
|
res = ats_ibm_api.read("api_keys/#{concerned_id}")
|
199
|
-
return {type: :single_object, data: res
|
201
|
+
return {type: :single_object, data: res}
|
200
202
|
when :delete
|
201
203
|
ats_ibm_api.delete("api_keys/#{concerned_id}")
|
202
204
|
return Main.result_status("deleted #{concerned_id}")
|
@@ -222,7 +224,7 @@ module Aspera
|
|
222
224
|
when :api_key # manage credential to access ATS API
|
223
225
|
return execute_action_api_key
|
224
226
|
when :aws_trust_policy
|
225
|
-
res = ats_api_pub_v1.read('aws/trustpolicy', {region: options.get_option(:region, mandatory: true)})
|
227
|
+
res = ats_api_pub_v1.read('aws/trustpolicy', {region: options.get_option(:region, mandatory: true)})
|
226
228
|
return {type: :single_object, data: res}
|
227
229
|
else Aspera.error_unexpected_value(command)
|
228
230
|
end
|
@@ -57,15 +57,14 @@ module Aspera
|
|
57
57
|
APP_NAME_SDK = 'sdk'
|
58
58
|
CONNECT_WEB_URL = 'https://d3gcli72yxqn2z.cloudfront.net/connect'
|
59
59
|
CONNECT_VERSIONS = 'connectversions.js' # cspell: disable-line
|
60
|
-
TRANSFER_SDK_ARCHIVE_URL = 'https://ibm.biz/aspera_transfer_sdk'
|
61
60
|
DEMO_SERVER = 'demo'
|
62
61
|
DEMO_PRESET = 'demoserver' # cspell: disable-line
|
63
62
|
EMAIL_TEST_TEMPLATE = <<~END_OF_TEMPLATE
|
64
63
|
From: <%=from_name%> <<%=from_email%>>
|
65
64
|
To: <<%=to%>>
|
66
|
-
Subject: #{GEM_NAME} email test
|
65
|
+
Subject: #{Info::GEM_NAME} email test
|
67
66
|
|
68
|
-
This email was sent to test #{
|
67
|
+
This email was sent to test #{Info::CMD_NAME}.
|
69
68
|
END_OF_TEMPLATE
|
70
69
|
# special extended values
|
71
70
|
EXTEND_PRESET = :preset
|
@@ -86,7 +85,6 @@ module Aspera
|
|
86
85
|
:CONF_PRESET_GLOBAL,
|
87
86
|
:ASPERA_PLUGINS_FOLDERNAME,
|
88
87
|
:ASPERA,
|
89
|
-
:TRANSFER_SDK_ARCHIVE_URL,
|
90
88
|
:DEMO_SERVER,
|
91
89
|
:DEMO_PRESET,
|
92
90
|
:EMAIL_TEST_TEMPLATE,
|
@@ -126,8 +124,8 @@ module Aspera
|
|
126
124
|
end
|
127
125
|
|
128
126
|
# deep clone hash so that it does not get modified in case of display and secret hide
|
129
|
-
def
|
130
|
-
return
|
127
|
+
def deep_clone(val)
|
128
|
+
return Marshal.load(Marshal.dump(val))
|
131
129
|
end
|
132
130
|
|
133
131
|
# return product family folder (~/.aspera)
|
@@ -145,13 +143,9 @@ module Aspera
|
|
145
143
|
end
|
146
144
|
end
|
147
145
|
|
148
|
-
def initialize(
|
146
|
+
def initialize(**env)
|
149
147
|
# we need to defer parsing of options until we have the config file, so we can use @extend with @preset
|
150
148
|
super(**env)
|
151
|
-
@gem = gem
|
152
|
-
@name = name
|
153
|
-
@help = help
|
154
|
-
@version = version
|
155
149
|
@use_plugin_defaults = true
|
156
150
|
@config_presets = nil
|
157
151
|
@config_checksum_on_disk = nil
|
@@ -177,9 +171,9 @@ module Aspera
|
|
177
171
|
:home, 'Home folder for tool',
|
178
172
|
handler: {o: self, m: :main_folder},
|
179
173
|
types: String,
|
180
|
-
default: self.class.default_app_main_folder(app_name:
|
174
|
+
default: self.class.default_app_main_folder(app_name: Info::CMD_NAME))
|
181
175
|
options.parse_options!
|
182
|
-
Log.log.debug{"#{
|
176
|
+
Log.log.debug{"#{Info::CMD_NAME} folder: #{@main_folder}"}
|
183
177
|
# data persistency manager, created by config plugin
|
184
178
|
@persistency = PersistencyFolder.new(File.join(@main_folder, PERSISTENCY_FOLDER))
|
185
179
|
# set folders for plugin lookup
|
@@ -218,7 +212,7 @@ module Aspera
|
|
218
212
|
# Transfer SDK options
|
219
213
|
options.declare(:ascp_path, 'Path to ascp', handler: {o: Ascp::Installation.instance, m: :ascp_path})
|
220
214
|
options.declare(:use_product, 'Use ascp from specified product', handler: {o: self, m: :option_use_product})
|
221
|
-
options.declare(:sdk_url, 'URL to get SDK', default:
|
215
|
+
options.declare(:sdk_url, 'URL to get SDK', default: SpecialValues::DEF)
|
222
216
|
options.declare(:sdk_folder, 'SDK folder path', handler: {o: Ascp::Installation.instance, m: :sdk_folder})
|
223
217
|
options.declare(:progress_bar, 'Display progress bar', values: :bool, default: Environment.terminal?)
|
224
218
|
# email options
|
@@ -234,7 +228,7 @@ module Aspera
|
|
234
228
|
options.declare(:http_proxy, 'URL for HTTP proxy with optional credentials', types: String, handler: {o: self, m: :option_http_proxy})
|
235
229
|
options.declare(:cache_tokens, 'Save and reuse OAuth tokens', values: :bool, handler: {o: self, m: :option_cache_tokens})
|
236
230
|
options.declare(:fpac, 'Proxy auto configuration script')
|
237
|
-
options.declare(:proxy_credentials, 'HTTP proxy credentials for fpac
|
231
|
+
options.declare(:proxy_credentials, 'HTTP proxy credentials for fpac: user, password', types: Array)
|
238
232
|
options.parse_options!
|
239
233
|
@progress_bar = TransferProgress.new if options.get_option(:progress_bar)
|
240
234
|
# Check SDK folder is set or not, for compatibility, we check in two places
|
@@ -248,7 +242,7 @@ module Aspera
|
|
248
242
|
if !Dir.exist?(sdk_folder)
|
249
243
|
Log.log.debug{"not exists: #{sdk_folder}"}
|
250
244
|
# former location
|
251
|
-
former_sdk_folder = File.join(self.class.default_app_main_folder(app_name:
|
245
|
+
former_sdk_folder = File.join(self.class.default_app_main_folder(app_name: Info::CMD_NAME), APP_NAME_SDK)
|
252
246
|
Log.log.debug{"checking: #{former_sdk_folder}"}
|
253
247
|
sdk_folder = former_sdk_folder if Dir.exist?(former_sdk_folder)
|
254
248
|
end
|
@@ -266,11 +260,16 @@ module Aspera
|
|
266
260
|
@pac_exec.proxy_pass = proxy_user_pass[1]
|
267
261
|
end
|
268
262
|
end
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
263
|
+
RestParameters.instance.user_agent = Info::CMD_NAME
|
264
|
+
RestParameters.instance.progress_bar = @progress_bar
|
265
|
+
RestParameters.instance.session_cb = lambda{|http_session|update_http_session(http_session)}
|
266
|
+
@option_http_options.keys.select{|i|RestParameters.instance.respond_to?(i)}.each do |k|
|
267
|
+
method = "#{k}=".to_sym
|
268
|
+
RestParameters.instance.send(method, @option_http_options[k])
|
269
|
+
@option_http_options.delete(k)
|
270
|
+
end
|
273
271
|
OAuth::Factory.instance.persist_mgr = persistency if @option_cache_tokens
|
272
|
+
OAuth::Web.additionnal_info = "#{Info::CMD_NAME} v#{Cli::VERSION}"
|
274
273
|
Transfer::Parameters.file_list_folder = File.join(@main_folder, 'filelists')
|
275
274
|
RestErrorAnalyzer.instance.log_file = File.join(@main_folder, 'rest_exceptions.log')
|
276
275
|
# register aspera REST call error handlers
|
@@ -281,6 +280,8 @@ module Aspera
|
|
281
280
|
attr_reader :option_ignore_cert_host_port, :progress_bar
|
282
281
|
|
283
282
|
# add files, folders or default locations to the certificate store
|
283
|
+
# @param path_list [Array<String>] list of paths to add
|
284
|
+
# @return the list of paths
|
284
285
|
def trusted_cert_locations=(path_list)
|
285
286
|
path_list = [path_list] unless path_list.is_a?(Array)
|
286
287
|
Aspera.assert_type(path_list, Array){'cert locations'}
|
@@ -296,10 +297,10 @@ module Aspera
|
|
296
297
|
Log.log.debug{"Adding cert location: #{path}"}
|
297
298
|
if path.eql?(SpecialValues::DEF)
|
298
299
|
@certificate_store.set_default_paths
|
299
|
-
paths_to_add = [
|
300
|
-
|
301
|
-
|
302
|
-
|
300
|
+
paths_to_add = [OpenSSL::X509::DEFAULT_CERT_DIR]
|
301
|
+
# JRuby cert file seems not to be PEM
|
302
|
+
paths_to_add.push(OpenSSL::X509::DEFAULT_CERT_FILE) unless defined?(JRUBY_VERSION)
|
303
|
+
paths_to_add.select!{|f|File.exist?(f)}
|
303
304
|
elsif File.file?(path)
|
304
305
|
@certificate_store.add_file(path)
|
305
306
|
elsif File.directory?(path)
|
@@ -392,19 +393,19 @@ module Aspera
|
|
392
393
|
def check_gem_version
|
393
394
|
latest_version =
|
394
395
|
begin
|
395
|
-
Rest.new(base_url: 'https://rubygems.org/api/v1').read("versions/#{
|
396
|
+
Rest.new(base_url: 'https://rubygems.org/api/v1').read("versions/#{Info::GEM_NAME}/latest.json")['version']
|
396
397
|
rescue StandardError
|
397
398
|
Log.log.warn('Could not retrieve latest gem version on rubygems.')
|
398
399
|
'0'
|
399
400
|
end
|
400
|
-
if Gem::Version.new(Environment.ruby_version) < Gem::Version.new(RUBY_FUTURE_MINIMUM_VERSION)
|
401
|
+
if Gem::Version.new(Environment.ruby_version) < Gem::Version.new(Info::RUBY_FUTURE_MINIMUM_VERSION)
|
401
402
|
Log.log.warn do
|
402
|
-
"Note that a future version will require Ruby version #{RUBY_FUTURE_MINIMUM_VERSION} at minimum, " \
|
403
|
+
"Note that a future version will require Ruby version #{Info::RUBY_FUTURE_MINIMUM_VERSION} at minimum, " \
|
403
404
|
"you are using #{Environment.ruby_version}"
|
404
405
|
end
|
405
406
|
end
|
406
407
|
return {
|
407
|
-
name:
|
408
|
+
name: Info::GEM_NAME,
|
408
409
|
current: Cli::VERSION,
|
409
410
|
latest: latest_version,
|
410
411
|
need_update: Gem::Version.new(Cli::VERSION) < Gem::Version.new(latest_version)
|
@@ -520,7 +521,7 @@ module Aspera
|
|
520
521
|
current = current[name]
|
521
522
|
raise Cli::Error, "No such config preset: #{include_path}" if current.nil?
|
522
523
|
end
|
523
|
-
current = self.class.
|
524
|
+
current = self.class.deep_clone(current) unless current.is_a?(String)
|
524
525
|
return ExtendedValue.instance.evaluate(current)
|
525
526
|
end
|
526
527
|
|
@@ -578,7 +579,7 @@ module Aspera
|
|
578
579
|
@config_checksum_on_disk = config_checksum
|
579
580
|
end
|
580
581
|
files_to_copy = []
|
581
|
-
Log.log.
|
582
|
+
Log.log.trace1{Log.dump('Available_presets', @config_presets)}
|
582
583
|
Aspera.assert_type(@config_presets, Hash){'config file YAML'}
|
583
584
|
# check there is at least the config section
|
584
585
|
Aspera.assert(@config_presets.key?(CONF_PRESET_CONFIG)){"Cannot find key: #{CONF_PRESET_CONFIG}"}
|
@@ -590,7 +591,7 @@ module Aspera
|
|
590
591
|
@config_presets[CONF_PRESET_DEFAULTS].delete(true) if @config_presets[CONF_PRESET_DEFAULTS].is_a?(Hash)
|
591
592
|
# ^^^ Place new compatibility code before this line
|
592
593
|
# set version to current
|
593
|
-
@config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] =
|
594
|
+
@config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = Cli::VERSION
|
594
595
|
unless files_to_copy.empty?
|
595
596
|
Log.log.warn('Copying referenced files')
|
596
597
|
files_to_copy.each do |file|
|
@@ -605,7 +606,7 @@ module Aspera
|
|
605
606
|
Log.log.debug{"-> #{e.class.name} : #{e}"}
|
606
607
|
if File.exist?(@option_config_file)
|
607
608
|
# then there is a problem with that file.
|
608
|
-
new_name = "#{@option_config_file}.pre#{
|
609
|
+
new_name = "#{@option_config_file}.pre#{Cli::VERSION}.manual_conversion_needed"
|
609
610
|
File.rename(@option_config_file, new_name)
|
610
611
|
Log.log.warn{"Renamed config file to #{new_name}."}
|
611
612
|
Log.log.warn('Manual Conversion is required. Next time, a new empty file will be created.')
|
@@ -699,8 +700,7 @@ module Aspera
|
|
699
700
|
return execute_connect_action
|
700
701
|
when :use
|
701
702
|
ascp_path = options.get_next_argument('path to ascp')
|
702
|
-
|
703
|
-
formatter.display_status("ascp version: #{ascp_version}")
|
703
|
+
formatter.display_status("ascp version: #{Ascp::Installation.instance.get_ascp_version(ascp_path)}")
|
704
704
|
set_global_default(:ascp_path, ascp_path)
|
705
705
|
return Main.result_nothing
|
706
706
|
when :show
|
@@ -729,8 +729,8 @@ module Aspera
|
|
729
729
|
when :install
|
730
730
|
# reset to default location, if older default was used
|
731
731
|
Ascp::Installation.instance.sdk_folder = self.class.default_app_main_folder(app_name: APP_NAME_SDK) if @sdk_default_location
|
732
|
-
v = Ascp::Installation.instance.install_sdk(options.get_option(:sdk_url, mandatory: true))
|
733
|
-
return Main.result_status("Installed version #{v}")
|
732
|
+
n, v = Ascp::Installation.instance.install_sdk(url: options.get_option(:sdk_url, mandatory: true))
|
733
|
+
return Main.result_status("Installed #{n} version #{v}")
|
734
734
|
when :spec
|
735
735
|
return {
|
736
736
|
type: :object_list,
|
@@ -766,9 +766,9 @@ module Aspera
|
|
766
766
|
return {type: :value_list, data: @config_presets.keys, name: 'name'}
|
767
767
|
when :overview
|
768
768
|
# display process modifies the value (hide secrets): we do not want to save removed secrets
|
769
|
-
return {type: :config_over, data: self.class.
|
769
|
+
return {type: :config_over, data: self.class.deep_clone(@config_presets)}
|
770
770
|
when :show
|
771
|
-
return {type: :single_object, data: self.class.
|
771
|
+
return {type: :single_object, data: self.class.deep_clone(@config_presets[name])}
|
772
772
|
when :delete
|
773
773
|
@config_presets.delete(name)
|
774
774
|
return Main.result_status("Deleted: #{name}")
|
@@ -871,7 +871,9 @@ module Aspera
|
|
871
871
|
check_update
|
872
872
|
initdemo
|
873
873
|
vault
|
874
|
-
|
874
|
+
test
|
875
|
+
platform
|
876
|
+
].freeze
|
875
877
|
|
876
878
|
# Main action procedure for plugin
|
877
879
|
def execute_action
|
@@ -885,7 +887,7 @@ module Aspera
|
|
885
887
|
when :documentation
|
886
888
|
section = options.get_next_argument('private key file path', mandatory: false)
|
887
889
|
section = "##{section}" unless section.nil?
|
888
|
-
Environment.instance.open_uri("#{
|
890
|
+
Environment.instance.open_uri("#{Info::DOC_URL}#{section}")
|
889
891
|
return Main.result_nothing
|
890
892
|
when :genkey # generate new rsa key
|
891
893
|
private_key_path = options.get_next_argument('private key file path')
|
@@ -967,7 +969,7 @@ module Aspera
|
|
967
969
|
case options.get_next_command(%i[path version name])
|
968
970
|
when :path then return Main.result_status(self.class.gem_src_root)
|
969
971
|
when :version then return Main.result_status(Cli::VERSION)
|
970
|
-
when :name then return Main.result_status(
|
972
|
+
when :name then return Main.result_status(Info::GEM_NAME)
|
971
973
|
end
|
972
974
|
when :folder
|
973
975
|
return Main.result_status(@main_folder)
|
@@ -1007,14 +1009,9 @@ module Aspera
|
|
1007
1009
|
end
|
1008
1010
|
return Main.result_status('Done')
|
1009
1011
|
when :vault then execute_vault
|
1010
|
-
when :
|
1011
|
-
|
1012
|
-
|
1013
|
-
exception_class_name = options.get_next_argument('exception class name', mandatory: true)
|
1014
|
-
exception_text = options.get_next_argument('exception text', mandatory: true)
|
1015
|
-
exception_class = Object.const_get(exception_class_name)
|
1016
|
-
Aspera.assert(exception_class <= Exception){"#{exception_class} is not an exception: #{exception_class.class}"}
|
1017
|
-
raise exception_class, exception_text
|
1012
|
+
when :test then return execute_test
|
1013
|
+
when :platform
|
1014
|
+
return Main.result_status(Environment.architecture)
|
1018
1015
|
else Aspera.error_unreachable_line
|
1019
1016
|
end
|
1020
1017
|
end
|
@@ -1107,7 +1104,7 @@ module Aspera
|
|
1107
1104
|
test_args = "-P#{wiz_preset_name} #{test_args}"
|
1108
1105
|
end
|
1109
1106
|
# TODO: actually test the command
|
1110
|
-
return Main.result_status("You can test with:\n#{
|
1107
|
+
return Main.result_status("You can test with:\n#{Info::CMD_NAME} #{identification[:product]} #{test_args}")
|
1111
1108
|
end
|
1112
1109
|
|
1113
1110
|
# @return [Hash] email server setting with defaults if not defined
|
@@ -1136,6 +1133,8 @@ module Aspera
|
|
1136
1133
|
end
|
1137
1134
|
|
1138
1135
|
# send email using ERB template
|
1136
|
+
# @param email_template_default [String] default template, can be overriden by option
|
1137
|
+
# @param values [Hash] values to be used in template, keys with default: to, from_name, from_email
|
1139
1138
|
def send_email_template(email_template_default: nil, values: {})
|
1140
1139
|
values[:to] ||= options.get_option(:notify_to, mandatory: true)
|
1141
1140
|
notify_template = options.get_option(:notify_template, mandatory: email_template_default.nil?) || email_template_default
|
@@ -1197,7 +1196,7 @@ module Aspera
|
|
1197
1196
|
Log.log.error do
|
1198
1197
|
"Default config name [#{default_config_name}] specified for plugin [#{plugin_name_sym}], but it does not exist in config file.\n" \
|
1199
1198
|
'Please fix the issue: either create preset with one parameter: ' \
|
1200
|
-
"(#{
|
1199
|
+
"(#{Info::CMD_NAME} config id #{default_config_name} init @json:'{}') or remove default (#{Info::CMD_NAME} config id default remove #{plugin_name_sym})."
|
1201
1200
|
end
|
1202
1201
|
end
|
1203
1202
|
raise Cli::Error, "Config name [#{default_config_name}] must be a hash, check config file." if !@config_presets[default_config_name].is_a?(Hash)
|
@@ -1252,7 +1251,7 @@ module Aspera
|
|
1252
1251
|
info = options.get_option(:vault) || {}
|
1253
1252
|
info = info.symbolize_keys
|
1254
1253
|
info[:type] ||= 'file'
|
1255
|
-
info[:name] ||= (info[:type].eql?('file') ? DEFAULT_VAULT_FILENAME :
|
1254
|
+
info[:name] ||= (info[:type].eql?('file') ? DEFAULT_VAULT_FILENAME : Info::CMD_NAME)
|
1256
1255
|
Aspera.assert(info.keys.sort == %i[name type]) {"vault info shall have exactly keys 'type' and 'name'"}
|
1257
1256
|
Aspera.assert(info.values.all?(String)){'vault info shall have only string values'}
|
1258
1257
|
info[:password] = options.get_option(:vault_password, mandatory: true)
|
@@ -1284,6 +1283,20 @@ module Aspera
|
|
1284
1283
|
@vault
|
1285
1284
|
end
|
1286
1285
|
|
1286
|
+
def execute_test
|
1287
|
+
case options.get_next_command(%i[throw web])
|
1288
|
+
when :throw
|
1289
|
+
# :type [String]
|
1290
|
+
# options
|
1291
|
+
exception_class_name = options.get_next_argument('exception class name', mandatory: true)
|
1292
|
+
exception_text = options.get_next_argument('exception text', mandatory: true)
|
1293
|
+
exception_class = Object.const_get(exception_class_name)
|
1294
|
+
Aspera.assert(exception_class <= Exception){"#{exception_class} is not an exception: #{exception_class.class}"}
|
1295
|
+
raise exception_class, exception_text
|
1296
|
+
when :web
|
1297
|
+
end
|
1298
|
+
end
|
1299
|
+
|
1287
1300
|
# version of URL without trailing "/" and removing default port
|
1288
1301
|
def canonical_url(url)
|
1289
1302
|
url.sub(%r{/+$}, '').sub(%r{^(https://[^/]+):443$}, '\1')
|
@@ -1296,7 +1309,7 @@ module Aspera
|
|
1296
1309
|
@config_presets.each_value do |v|
|
1297
1310
|
next unless v.is_a?(Hash)
|
1298
1311
|
conf_url = v['url'].is_a?(String) ? canonical_url(v['url']) : nil
|
1299
|
-
return self.class.
|
1312
|
+
return self.class.deep_clone(v) if conf_url.eql?(url) && v['username'].eql?(username)
|
1300
1313
|
end
|
1301
1314
|
nil
|
1302
1315
|
end
|
@@ -84,11 +84,11 @@ module Aspera
|
|
84
84
|
command = options.get_next_command(%i[list submit])
|
85
85
|
case command
|
86
86
|
when :list
|
87
|
-
return {type: :object_list, data: api_console.read('smart_transfers')
|
87
|
+
return {type: :object_list, data: api_console.read('smart_transfers')}
|
88
88
|
when :submit
|
89
89
|
smart_id = options.get_next_argument('smart_id')
|
90
90
|
params = options.get_next_argument('transfer parameters')
|
91
|
-
return {type: :object_list, data: api_console.create("smart_transfers/#{smart_id}", params)
|
91
|
+
return {type: :object_list, data: api_console.create("smart_transfers/#{smart_id}", params)}
|
92
92
|
end
|
93
93
|
when :current
|
94
94
|
command = options.get_next_command([:list])
|
@@ -99,7 +99,7 @@ module Aspera
|
|
99
99
|
data: api_console.read('transfers', {
|
100
100
|
'from' => options.get_option(:filter_from, mandatory: true),
|
101
101
|
'to' => options.get_option(:filter_to, mandatory: true)
|
102
|
-
})
|
102
|
+
}),
|
103
103
|
fields: %w[id contact name status]}
|
104
104
|
end
|
105
105
|
end
|
@@ -37,7 +37,8 @@ module Aspera
|
|
37
37
|
# sub path in url for public link delivery
|
38
38
|
PUB_LINK_EXTERNAL_MATCH = 'external_deliveries/'
|
39
39
|
STANDARD_PATH = '/aspera/faspex'
|
40
|
-
|
40
|
+
HEADER_FASPEX_VERSION = 'X-IBM-Aspera'
|
41
|
+
private_constant(*%i[KEY_NODE KEY_PATH PACKAGE_MATCH_FIELD ATOM_MAILBOXES ATOM_PARAMS ATOM_EXT_PARAMS PUB_LINK_EXTERNAL_MATCH HEADER_FASPEX_VERSION])
|
41
42
|
|
42
43
|
class << self
|
43
44
|
def detect(address_or_url)
|
@@ -58,7 +59,7 @@ module Aspera
|
|
58
59
|
# 4.x
|
59
60
|
next unless result[:http].body.start_with?('<?xml')
|
60
61
|
res_s = XmlSimple.xml_in(result[:http].body, {'ForceArray' => false})
|
61
|
-
Log.log.debug{"version: #{result[:http][
|
62
|
+
Log.log.debug{"version: #{result[:http][HEADER_FASPEX_VERSION]}"}
|
62
63
|
version = res_s['XRD']['application']['version']
|
63
64
|
# take redirect if any
|
64
65
|
return {
|
@@ -95,7 +96,7 @@ module Aspera
|
|
95
96
|
result = {
|
96
97
|
base_url: "#{public_uri.scheme}://#{public_uri.host}#{port_add}#{base}",
|
97
98
|
subpath: subpath,
|
98
|
-
query: Rest.
|
99
|
+
query: Rest.query_to_h(public_uri.query)
|
99
100
|
}
|
100
101
|
Log.log.debug{Log.dump('link data', result)}
|
101
102
|
return result
|
@@ -246,7 +247,7 @@ module Aspera
|
|
246
247
|
delivery_info[:source_paths_list] = transfer.source_list.join("\r\n")
|
247
248
|
api_public_link = Rest.new(base_url: link_data[:base_url])
|
248
249
|
# Hum, as this does not always work (only user, but not dropbox), we get the javascript and need hack
|
249
|
-
# pkg_created=api_public_link.create(create_path,package_create_params)
|
250
|
+
# pkg_created=api_public_link.create(create_path,package_create_params)
|
250
251
|
# so extract data from javascript
|
251
252
|
package_creation_data = api_public_link.call(
|
252
253
|
operation: 'POST',
|
@@ -307,17 +308,11 @@ module Aspera
|
|
307
308
|
first_source['paths'].push(*transfer.source_list)
|
308
309
|
source_id = instance_identifier(as_option: :remote_source) do |field, value|
|
309
310
|
Aspera.assert(field.eql?('name'), exception_class: Cli::BadArgument){'only name as selector, or give id'}
|
310
|
-
source_list = api_v3.
|
311
|
+
source_list = api_v3.read('source_shares')['items']
|
311
312
|
self.class.get_source_id_by_name(value, source_list)
|
312
313
|
end
|
313
314
|
first_source['id'] = source_id.to_i unless source_id.nil?
|
314
|
-
pkg_created = api_v3.
|
315
|
-
operation: 'POST',
|
316
|
-
subpath: 'send',
|
317
|
-
headers: {'Accept' => 'application/json'},
|
318
|
-
body: package_create_params,
|
319
|
-
body_type: :json
|
320
|
-
)[:data]
|
315
|
+
pkg_created = api_v3.create('send', package_create_params)
|
321
316
|
if first_source.key?('id')
|
322
317
|
# no transfer spec if remote source: handled by faspex
|
323
318
|
return {data: [pkg_created['links']['status']], type: :value_list, name: 'link'}
|
@@ -437,7 +432,7 @@ module Aspera
|
|
437
432
|
end
|
438
433
|
when :source
|
439
434
|
command_source = options.get_next_command(%i[list info node])
|
440
|
-
source_list = api_v3.
|
435
|
+
source_list = api_v3.read('source_shares')['items']
|
441
436
|
case command_source
|
442
437
|
when :list
|
443
438
|
return {type: :object_list, data: source_list}
|
@@ -479,13 +474,13 @@ module Aspera
|
|
479
474
|
end
|
480
475
|
end
|
481
476
|
when :me
|
482
|
-
my_info = api_v3.
|
477
|
+
my_info = api_v3.read('me')
|
483
478
|
return {data: my_info, type: :single_object}
|
484
479
|
when :dropbox
|
485
480
|
command_pkg = options.get_next_command([:list])
|
486
481
|
case command_pkg
|
487
482
|
when :list
|
488
|
-
dropbox_list = api_v3.
|
483
|
+
dropbox_list = api_v3.read('dropboxes')
|
489
484
|
return {type: :object_list, data: dropbox_list['items'], fields: %w[name id description can_read can_write]}
|
490
485
|
end
|
491
486
|
when :v4
|
@@ -509,12 +504,7 @@ module Aspera
|
|
509
504
|
return entity_action(api_v4, "#{pkg_box_type}/#{pkg_box_id}/packages")
|
510
505
|
end
|
511
506
|
when :address_book
|
512
|
-
result = api_v3.
|
513
|
-
operation: 'GET',
|
514
|
-
subpath: 'address-book',
|
515
|
-
headers: {'Accept' => 'application/json'},
|
516
|
-
query: {'format' => 'json', 'count' => 100_000}
|
517
|
-
)[:data]
|
507
|
+
result = api_v3.read('address-book', {'format' => 'json', 'count' => 100_000})
|
518
508
|
formatter.display_status("users: #{result['itemsPerPage']}/#{result['totalResults']}, start:#{result['startIndex']}")
|
519
509
|
users = result['entry']
|
520
510
|
# add missing entries
|