aspera-cli 4.19.0 → 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 +20 -0
- data/CONTRIBUTING.md +16 -4
- data/README.md +344 -164
- data/bin/asession +26 -19
- data/examples/build_exec +65 -76
- data/examples/build_exec_rubyc +40 -0
- data/examples/get_proto_file.rb +7 -0
- data/lib/aspera/agent/alpha.rb +8 -8
- data/lib/aspera/agent/base.rb +2 -18
- data/lib/aspera/agent/connect.rb +14 -13
- data/lib/aspera/agent/direct.rb +23 -24
- 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 +126 -97
- data/lib/aspera/api/ats.rb +1 -1
- data/lib/aspera/api/cos_node.rb +1 -1
- data/lib/aspera/api/httpgw.rb +15 -10
- data/lib/aspera/api/node.rb +33 -12
- data/lib/aspera/ascmd.rb +56 -48
- data/lib/aspera/ascp/installation.rb +99 -42
- data/lib/aspera/ascp/management.rb +3 -2
- data/lib/aspera/ascp/products.rb +12 -0
- data/lib/aspera/assert.rb +10 -5
- data/lib/aspera/cli/formatter.rb +27 -17
- 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 +5 -0
- data/lib/aspera/cli/plugin.rb +15 -29
- 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 +53 -45
- 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 +153 -95
- 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 +5 -9
- data/lib/aspera/cli/plugins/shares.rb +2 -2
- data/lib/aspera/cli/sync_actions.rb +2 -2
- data/lib/aspera/cli/transfer_agent.rb +12 -14
- data/lib/aspera/cli/transfer_progress.rb +35 -17
- 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 +34 -18
- data/lib/aspera/faspex_gw.rb +2 -2
- data/lib/aspera/json_rpc.rb +1 -1
- data/lib/aspera/keychain/macos_security.rb +7 -12
- data/lib/aspera/log.rb +3 -4
- 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 +3 -3
- data/lib/aspera/oauth/url_json.rb +1 -2
- data/lib/aspera/oauth/web.rb +5 -2
- 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/transfer/faux_file.rb +4 -4
- data/lib/aspera/transfer/parameters.rb +14 -16
- data/lib/aspera/transfer/spec.rb +12 -12
- data/lib/aspera/transfer/sync.rb +1 -5
- data/lib/aspera/transfer/uri.rb +1 -1
- data/lib/aspera/uri_reader.rb +1 -1
- data/lib/aspera/web_auth.rb +166 -17
- data/lib/aspera/web_server_simple.rb +4 -3
- data/lib/transfer_pb.rb +84 -0
- data/lib/transfer_services_pb.rb +82 -0
- data.tar.gz.sig +0 -0
- metadata +24 -5
- 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
|
@@ -394,19 +393,19 @@ module Aspera
|
|
394
393
|
def check_gem_version
|
395
394
|
latest_version =
|
396
395
|
begin
|
397
|
-
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']
|
398
397
|
rescue StandardError
|
399
398
|
Log.log.warn('Could not retrieve latest gem version on rubygems.')
|
400
399
|
'0'
|
401
400
|
end
|
402
|
-
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)
|
403
402
|
Log.log.warn do
|
404
|
-
"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, " \
|
405
404
|
"you are using #{Environment.ruby_version}"
|
406
405
|
end
|
407
406
|
end
|
408
407
|
return {
|
409
|
-
name:
|
408
|
+
name: Info::GEM_NAME,
|
410
409
|
current: Cli::VERSION,
|
411
410
|
latest: latest_version,
|
412
411
|
need_update: Gem::Version.new(Cli::VERSION) < Gem::Version.new(latest_version)
|
@@ -522,7 +521,7 @@ module Aspera
|
|
522
521
|
current = current[name]
|
523
522
|
raise Cli::Error, "No such config preset: #{include_path}" if current.nil?
|
524
523
|
end
|
525
|
-
current = self.class.
|
524
|
+
current = self.class.deep_clone(current) unless current.is_a?(String)
|
526
525
|
return ExtendedValue.instance.evaluate(current)
|
527
526
|
end
|
528
527
|
|
@@ -592,7 +591,7 @@ module Aspera
|
|
592
591
|
@config_presets[CONF_PRESET_DEFAULTS].delete(true) if @config_presets[CONF_PRESET_DEFAULTS].is_a?(Hash)
|
593
592
|
# ^^^ Place new compatibility code before this line
|
594
593
|
# set version to current
|
595
|
-
@config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] =
|
594
|
+
@config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = Cli::VERSION
|
596
595
|
unless files_to_copy.empty?
|
597
596
|
Log.log.warn('Copying referenced files')
|
598
597
|
files_to_copy.each do |file|
|
@@ -607,7 +606,7 @@ module Aspera
|
|
607
606
|
Log.log.debug{"-> #{e.class.name} : #{e}"}
|
608
607
|
if File.exist?(@option_config_file)
|
609
608
|
# then there is a problem with that file.
|
610
|
-
new_name = "#{@option_config_file}.pre#{
|
609
|
+
new_name = "#{@option_config_file}.pre#{Cli::VERSION}.manual_conversion_needed"
|
611
610
|
File.rename(@option_config_file, new_name)
|
612
611
|
Log.log.warn{"Renamed config file to #{new_name}."}
|
613
612
|
Log.log.warn('Manual Conversion is required. Next time, a new empty file will be created.')
|
@@ -730,7 +729,7 @@ module Aspera
|
|
730
729
|
when :install
|
731
730
|
# reset to default location, if older default was used
|
732
731
|
Ascp::Installation.instance.sdk_folder = self.class.default_app_main_folder(app_name: APP_NAME_SDK) if @sdk_default_location
|
733
|
-
n, v = Ascp::Installation.instance.install_sdk(options.get_option(:sdk_url, mandatory: true))
|
732
|
+
n, v = Ascp::Installation.instance.install_sdk(url: options.get_option(:sdk_url, mandatory: true))
|
734
733
|
return Main.result_status("Installed #{n} version #{v}")
|
735
734
|
when :spec
|
736
735
|
return {
|
@@ -767,9 +766,9 @@ module Aspera
|
|
767
766
|
return {type: :value_list, data: @config_presets.keys, name: 'name'}
|
768
767
|
when :overview
|
769
768
|
# display process modifies the value (hide secrets): we do not want to save removed secrets
|
770
|
-
return {type: :config_over, data: self.class.
|
769
|
+
return {type: :config_over, data: self.class.deep_clone(@config_presets)}
|
771
770
|
when :show
|
772
|
-
return {type: :single_object, data: self.class.
|
771
|
+
return {type: :single_object, data: self.class.deep_clone(@config_presets[name])}
|
773
772
|
when :delete
|
774
773
|
@config_presets.delete(name)
|
775
774
|
return Main.result_status("Deleted: #{name}")
|
@@ -872,7 +871,7 @@ module Aspera
|
|
872
871
|
check_update
|
873
872
|
initdemo
|
874
873
|
vault
|
875
|
-
|
874
|
+
test
|
876
875
|
platform
|
877
876
|
].freeze
|
878
877
|
|
@@ -888,7 +887,7 @@ module Aspera
|
|
888
887
|
when :documentation
|
889
888
|
section = options.get_next_argument('private key file path', mandatory: false)
|
890
889
|
section = "##{section}" unless section.nil?
|
891
|
-
Environment.instance.open_uri("#{
|
890
|
+
Environment.instance.open_uri("#{Info::DOC_URL}#{section}")
|
892
891
|
return Main.result_nothing
|
893
892
|
when :genkey # generate new rsa key
|
894
893
|
private_key_path = options.get_next_argument('private key file path')
|
@@ -970,7 +969,7 @@ module Aspera
|
|
970
969
|
case options.get_next_command(%i[path version name])
|
971
970
|
when :path then return Main.result_status(self.class.gem_src_root)
|
972
971
|
when :version then return Main.result_status(Cli::VERSION)
|
973
|
-
when :name then return Main.result_status(
|
972
|
+
when :name then return Main.result_status(Info::GEM_NAME)
|
974
973
|
end
|
975
974
|
when :folder
|
976
975
|
return Main.result_status(@main_folder)
|
@@ -1010,14 +1009,7 @@ module Aspera
|
|
1010
1009
|
end
|
1011
1010
|
return Main.result_status('Done')
|
1012
1011
|
when :vault then execute_vault
|
1013
|
-
when :
|
1014
|
-
# :type [String]
|
1015
|
-
options
|
1016
|
-
exception_class_name = options.get_next_argument('exception class name', mandatory: true)
|
1017
|
-
exception_text = options.get_next_argument('exception text', mandatory: true)
|
1018
|
-
exception_class = Object.const_get(exception_class_name)
|
1019
|
-
Aspera.assert(exception_class <= Exception){"#{exception_class} is not an exception: #{exception_class.class}"}
|
1020
|
-
raise exception_class, exception_text
|
1012
|
+
when :test then return execute_test
|
1021
1013
|
when :platform
|
1022
1014
|
return Main.result_status(Environment.architecture)
|
1023
1015
|
else Aspera.error_unreachable_line
|
@@ -1112,7 +1104,7 @@ module Aspera
|
|
1112
1104
|
test_args = "-P#{wiz_preset_name} #{test_args}"
|
1113
1105
|
end
|
1114
1106
|
# TODO: actually test the command
|
1115
|
-
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}")
|
1116
1108
|
end
|
1117
1109
|
|
1118
1110
|
# @return [Hash] email server setting with defaults if not defined
|
@@ -1141,6 +1133,8 @@ module Aspera
|
|
1141
1133
|
end
|
1142
1134
|
|
1143
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
|
1144
1138
|
def send_email_template(email_template_default: nil, values: {})
|
1145
1139
|
values[:to] ||= options.get_option(:notify_to, mandatory: true)
|
1146
1140
|
notify_template = options.get_option(:notify_template, mandatory: email_template_default.nil?) || email_template_default
|
@@ -1202,7 +1196,7 @@ module Aspera
|
|
1202
1196
|
Log.log.error do
|
1203
1197
|
"Default config name [#{default_config_name}] specified for plugin [#{plugin_name_sym}], but it does not exist in config file.\n" \
|
1204
1198
|
'Please fix the issue: either create preset with one parameter: ' \
|
1205
|
-
"(#{
|
1199
|
+
"(#{Info::CMD_NAME} config id #{default_config_name} init @json:'{}') or remove default (#{Info::CMD_NAME} config id default remove #{plugin_name_sym})."
|
1206
1200
|
end
|
1207
1201
|
end
|
1208
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)
|
@@ -1257,7 +1251,7 @@ module Aspera
|
|
1257
1251
|
info = options.get_option(:vault) || {}
|
1258
1252
|
info = info.symbolize_keys
|
1259
1253
|
info[:type] ||= 'file'
|
1260
|
-
info[:name] ||= (info[:type].eql?('file') ? DEFAULT_VAULT_FILENAME :
|
1254
|
+
info[:name] ||= (info[:type].eql?('file') ? DEFAULT_VAULT_FILENAME : Info::CMD_NAME)
|
1261
1255
|
Aspera.assert(info.keys.sort == %i[name type]) {"vault info shall have exactly keys 'type' and 'name'"}
|
1262
1256
|
Aspera.assert(info.values.all?(String)){'vault info shall have only string values'}
|
1263
1257
|
info[:password] = options.get_option(:vault_password, mandatory: true)
|
@@ -1289,6 +1283,20 @@ module Aspera
|
|
1289
1283
|
@vault
|
1290
1284
|
end
|
1291
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
|
+
|
1292
1300
|
# version of URL without trailing "/" and removing default port
|
1293
1301
|
def canonical_url(url)
|
1294
1302
|
url.sub(%r{/+$}, '').sub(%r{^(https://[^/]+):443$}, '\1')
|
@@ -1301,7 +1309,7 @@ module Aspera
|
|
1301
1309
|
@config_presets.each_value do |v|
|
1302
1310
|
next unless v.is_a?(Hash)
|
1303
1311
|
conf_url = v['url'].is_a?(String) ? canonical_url(v['url']) : nil
|
1304
|
-
return self.class.
|
1312
|
+
return self.class.deep_clone(v) if conf_url.eql?(url) && v['username'].eql?(username)
|
1305
1313
|
end
|
1306
1314
|
nil
|
1307
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
|