aspera-cli 4.20.0 → 4.21.2
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 +41 -3
- data/CONTRIBUTING.md +69 -142
- data/README.md +687 -461
- data/bin/ascli +5 -14
- data/bin/asession +3 -5
- data/examples/get_proto_file.rb +4 -3
- data/examples/proxy.pac +20 -20
- data/lib/aspera/agent/base.rb +2 -0
- data/lib/aspera/agent/connect.rb +20 -2
- data/lib/aspera/agent/{alpha.rb → desktop.rb} +12 -18
- data/lib/aspera/agent/direct.rb +30 -31
- data/lib/aspera/agent/node.rb +1 -11
- data/lib/aspera/agent/{trsdk.rb → transferd.rb} +37 -51
- data/lib/aspera/api/alee.rb +1 -1
- data/lib/aspera/api/aoc.rb +13 -8
- data/lib/aspera/api/cos_node.rb +1 -1
- data/lib/aspera/api/node.rb +49 -32
- data/lib/aspera/ascp/installation.rb +98 -77
- data/lib/aspera/ascp/management.rb +27 -6
- data/lib/aspera/cli/extended_value.rb +9 -3
- data/lib/aspera/cli/formatter.rb +155 -154
- data/lib/aspera/cli/info.rb +2 -1
- data/lib/aspera/cli/main.rb +12 -0
- data/lib/aspera/cli/manager.rb +4 -4
- data/lib/aspera/cli/plugin.rb +2 -2
- data/lib/aspera/cli/plugins/aoc.rb +134 -73
- data/lib/aspera/cli/plugins/config.rb +114 -83
- data/lib/aspera/cli/plugins/cos.rb +1 -0
- data/lib/aspera/cli/plugins/faspex.rb +4 -2
- data/lib/aspera/cli/plugins/faspex5.rb +29 -14
- data/lib/aspera/cli/plugins/node.rb +51 -41
- data/lib/aspera/cli/transfer_progress.rb +2 -0
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/command_line_builder.rb +1 -1
- data/lib/aspera/coverage.rb +5 -3
- data/lib/aspera/environment.rb +59 -16
- data/lib/aspera/faspex_postproc.rb +3 -5
- data/lib/aspera/hash_ext.rb +2 -12
- data/lib/aspera/node_simulator.rb +230 -112
- data/lib/aspera/oauth/base.rb +40 -48
- data/lib/aspera/oauth/factory.rb +41 -2
- data/lib/aspera/oauth/jwt.rb +4 -1
- data/lib/aspera/persistency_action_once.rb +1 -1
- data/lib/aspera/persistency_folder.rb +20 -2
- data/lib/aspera/preview/generator.rb +13 -10
- data/lib/aspera/preview/options.rb +2 -2
- data/lib/aspera/preview/terminal.rb +1 -1
- data/lib/aspera/preview/utils.rb +11 -6
- data/lib/aspera/products/connect.rb +82 -0
- data/lib/aspera/products/desktop.rb +30 -0
- data/lib/aspera/products/other.rb +82 -0
- data/lib/aspera/products/transferd.rb +61 -0
- data/lib/aspera/rest.rb +22 -17
- data/lib/aspera/secret_hider.rb +9 -2
- data/lib/aspera/ssh.rb +31 -24
- data/lib/aspera/temp_file_manager.rb +5 -4
- data/lib/aspera/transfer/parameters.rb +2 -1
- data/lib/aspera/transfer/spec.yaml +22 -20
- data/lib/aspera/transfer/sync.rb +1 -5
- data/lib/aspera/transfer/uri.rb +2 -2
- data/lib/aspera/uri_reader.rb +18 -1
- data/lib/transferd_pb.rb +86 -0
- data/lib/transferd_services_pb.rb +84 -0
- data.tar.gz.sig +0 -0
- metadata +13 -166
- metadata.gz.sig +0 -0
- data/examples/build_exec +0 -74
- data/examples/build_exec_rubyc +0 -40
- data/lib/aspera/ascp/products.rb +0 -168
- data/lib/transfer_pb.rb +0 -84
- data/lib/transfer_services_pb.rb +0 -82
@@ -9,11 +9,10 @@ require 'aspera/cli/formatter'
|
|
9
9
|
require 'aspera/cli/info'
|
10
10
|
require 'aspera/cli/transfer_progress'
|
11
11
|
require 'aspera/ascp/installation'
|
12
|
-
require 'aspera/
|
12
|
+
require 'aspera/products/transferd'
|
13
13
|
require 'aspera/transfer/error_info'
|
14
14
|
require 'aspera/transfer/parameters'
|
15
15
|
require 'aspera/transfer/spec'
|
16
|
-
require 'aspera/keychain/encrypted_hash'
|
17
16
|
require 'aspera/keychain/macos_security'
|
18
17
|
require 'aspera/proxy_auto_config'
|
19
18
|
require 'aspera/environment'
|
@@ -54,9 +53,7 @@ module Aspera
|
|
54
53
|
PERSISTENCY_FOLDER = 'persist_store'
|
55
54
|
ASPERA = 'aspera'
|
56
55
|
SERVER_COMMAND = 'server'
|
57
|
-
|
58
|
-
CONNECT_WEB_URL = 'https://d3gcli72yxqn2z.cloudfront.net/connect'
|
59
|
-
CONNECT_VERSIONS = 'connectversions.js' # cspell: disable-line
|
56
|
+
DIR_SDK = 'sdk'
|
60
57
|
DEMO_SERVER = 'demo'
|
61
58
|
DEMO_PRESET = 'demoserver' # cspell: disable-line
|
62
59
|
EMAIL_TEST_TEMPLATE = <<~END_OF_TEMPLATE
|
@@ -78,6 +75,7 @@ module Aspera
|
|
78
75
|
GEM_CHECK_DATE_FMT = '%Y/%m/%d'
|
79
76
|
# for testing only
|
80
77
|
SELF_SIGNED_CERT = OpenSSL::SSL.const_get(:enon_yfirev.to_s.upcase.reverse) # cspell: disable-line
|
78
|
+
CONF_OVERVIEW_KEYS = %w[preset parameter value].freeze
|
81
79
|
private_constant :DEFAULT_CONFIG_FILENAME,
|
82
80
|
:CONF_PRESET_CONFIG,
|
83
81
|
:CONF_PRESET_VERSION,
|
@@ -98,7 +96,8 @@ module Aspera
|
|
98
96
|
:WIZARD_RESULT_KEYS,
|
99
97
|
:SELF_SIGNED_CERT,
|
100
98
|
:PERSISTENCY_FOLDER,
|
101
|
-
:DEFAULT_PRIV_KEY_LENGTH
|
99
|
+
:DEFAULT_PRIV_KEY_LENGTH,
|
100
|
+
:CONF_OVERVIEW_KEYS
|
102
101
|
|
103
102
|
class << self
|
104
103
|
def generate_rsa_private_key(path:, length: DEFAULT_PRIV_KEY_LENGTH)
|
@@ -145,11 +144,10 @@ module Aspera
|
|
145
144
|
|
146
145
|
def initialize(**env)
|
147
146
|
# we need to defer parsing of options until we have the config file, so we can use @extend with @preset
|
148
|
-
super
|
147
|
+
super
|
149
148
|
@use_plugin_defaults = true
|
150
149
|
@config_presets = nil
|
151
150
|
@config_checksum_on_disk = nil
|
152
|
-
@connect_versions = nil
|
153
151
|
@vault = nil
|
154
152
|
@pac_exec = nil
|
155
153
|
@sdk_default_location = false
|
@@ -212,8 +210,9 @@ module Aspera
|
|
212
210
|
# Transfer SDK options
|
213
211
|
options.declare(:ascp_path, 'Path to ascp', handler: {o: Ascp::Installation.instance, m: :ascp_path})
|
214
212
|
options.declare(:use_product, 'Use ascp from specified product', handler: {o: self, m: :option_use_product})
|
215
|
-
options.declare(:sdk_url, 'URL to get
|
216
|
-
options.declare(:
|
213
|
+
options.declare(:sdk_url, 'URL to get Aspera Transfer Daemon', default: SpecialValues::DEF)
|
214
|
+
options.declare(:locations_url, 'URL to get locations of Aspera Transfer Daemon', handler: {o: Ascp::Installation.instance, m: :transferd_urls})
|
215
|
+
options.declare(:sdk_folder, 'SDK folder path', handler: {o: Products::Transferd, m: :sdk_directory})
|
217
216
|
options.declare(:progress_bar, 'Display progress bar', values: :bool, default: Environment.terminal?)
|
218
217
|
# email options
|
219
218
|
options.declare(:smtp, 'SMTP configuration', types: Hash)
|
@@ -232,22 +231,22 @@ module Aspera
|
|
232
231
|
options.parse_options!
|
233
232
|
@progress_bar = TransferProgress.new if options.get_option(:progress_bar)
|
234
233
|
# Check SDK folder is set or not, for compatibility, we check in two places
|
235
|
-
|
236
|
-
if
|
234
|
+
sdk_dir = Products::Transferd.sdk_directory rescue nil
|
235
|
+
if sdk_dir.nil?
|
237
236
|
@sdk_default_location = true
|
238
237
|
Log.log.debug('SDK folder is not set, checking default')
|
239
238
|
# new location
|
240
|
-
|
241
|
-
Log.log.debug{"checking: #{
|
242
|
-
if !Dir.exist?(
|
243
|
-
Log.log.debug{"not exists: #{
|
239
|
+
sdk_dir = self.class.default_app_main_folder(app_name: DIR_SDK)
|
240
|
+
Log.log.debug{"checking: #{sdk_dir}"}
|
241
|
+
if !Dir.exist?(sdk_dir)
|
242
|
+
Log.log.debug{"not exists: #{sdk_dir}"}
|
244
243
|
# former location
|
245
|
-
former_sdk_folder = File.join(self.class.default_app_main_folder(app_name: Info::CMD_NAME),
|
244
|
+
former_sdk_folder = File.join(self.class.default_app_main_folder(app_name: Info::CMD_NAME), DIR_SDK)
|
246
245
|
Log.log.debug{"checking: #{former_sdk_folder}"}
|
247
|
-
|
246
|
+
sdk_dir = former_sdk_folder if Dir.exist?(former_sdk_folder)
|
248
247
|
end
|
249
|
-
Log.log.debug{"using: #{
|
250
|
-
|
248
|
+
Log.log.debug{"using: #{sdk_dir}"}
|
249
|
+
Products::Transferd.sdk_directory = sdk_dir
|
251
250
|
end
|
252
251
|
pac_script = options.get_option(:fpac)
|
253
252
|
# create PAC executor
|
@@ -414,7 +413,7 @@ module Aspera
|
|
414
413
|
|
415
414
|
def periodic_check_newer_gem_version
|
416
415
|
# get verification period
|
417
|
-
delay_days = options.get_option(:version_check_days, mandatory: true)
|
416
|
+
delay_days = options.get_option(:version_check_days, mandatory: true).to_i
|
418
417
|
# check only if not zero day
|
419
418
|
return if delay_days.eql?(0)
|
420
419
|
# get last date from persistency
|
@@ -438,23 +437,6 @@ module Aspera
|
|
438
437
|
end if check_data[:need_update]
|
439
438
|
end
|
440
439
|
|
441
|
-
# retrieve structure from cloud (CDN) with all versions available
|
442
|
-
def connect_versions
|
443
|
-
if @connect_versions.nil?
|
444
|
-
api_connect_cdn = Rest.new(base_url: CONNECT_WEB_URL)
|
445
|
-
javascript = api_connect_cdn.call(operation: 'GET', subpath: CONNECT_VERSIONS)
|
446
|
-
# get result on one line
|
447
|
-
connect_versions_javascript = javascript[:http].body.gsub(/\r?\n\s*/, '')
|
448
|
-
Log.log.debug{"javascript=[\n#{connect_versions_javascript}\n]"}
|
449
|
-
# get javascript object only
|
450
|
-
found = connect_versions_javascript.match(/^.*? = (.*);/)
|
451
|
-
raise Cli::Error, 'Problem when getting connect versions from internet' if found.nil?
|
452
|
-
all_data = JSON.parse(found[1])
|
453
|
-
@connect_versions = all_data['entries']
|
454
|
-
end
|
455
|
-
return @connect_versions
|
456
|
-
end
|
457
|
-
|
458
440
|
# loads default parameters of plugin if no -P parameter
|
459
441
|
# and if there is a section defined for the plugin in the "default" section
|
460
442
|
# try to find: conf[conf["default"][plugin_str]]
|
@@ -658,34 +640,31 @@ module Aspera
|
|
658
640
|
command = options.get_next_command(%i[list info version])
|
659
641
|
if %i[info version].include?(command)
|
660
642
|
connect_id = options.get_next_argument('id or title')
|
661
|
-
one_res =
|
643
|
+
one_res = Products::Connect.instance.versions.find{|i|i['id'].eql?(connect_id) || i['title'].eql?(connect_id)}
|
662
644
|
raise Cli::NoSuchIdentifier.new(:connect, connect_id) if one_res.nil?
|
663
645
|
end
|
664
646
|
case command
|
665
647
|
when :list
|
666
|
-
return
|
648
|
+
return Main.result_object_list(Products::Connect.instance.versions, fields: %w[id title version])
|
667
649
|
when :info
|
668
650
|
one_res.delete('links')
|
669
|
-
return
|
651
|
+
return Main.result_single_object(one_res)
|
670
652
|
when :version
|
671
653
|
all_links = one_res['links']
|
672
654
|
command = options.get_next_command(%i[list download open])
|
673
655
|
if %i[download open].include?(command)
|
674
656
|
link_title = options.get_next_argument('title or rel')
|
675
657
|
one_link = all_links.find {|i| i['title'].eql?(link_title) || i['rel'].eql?(link_title)}
|
676
|
-
raise
|
658
|
+
raise "no such value: #{link_title}" if one_link.nil?
|
677
659
|
end
|
678
660
|
case command
|
679
661
|
when :list
|
680
|
-
return
|
662
|
+
return Main.result_object_list(all_links)
|
681
663
|
when :download
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
filename = file_url.gsub(%r{.*/}, '')
|
687
|
-
api_connect_cdn.call(operation: 'GET', subpath: file_url, save_to_file: File.join(folder_dest, filename))
|
688
|
-
return Main.result_status("Downloaded: #{filename}")
|
664
|
+
archive_path = one_link['href']
|
665
|
+
save_to_path = File.join(transfer.destination_folder(Transfer::Spec::DIRECTION_RECEIVE), archive_path.gsub(%r{.*/}, ''))
|
666
|
+
Products::Connect.instance.cdn_api.call(operation: 'GET', subpath: archive_path, save_to_file: save_to_path)
|
667
|
+
return Main.result_status("Downloaded: #{save_to_path}")
|
689
668
|
when :open
|
690
669
|
Environment.instance.open_uri(one_link['href'])
|
691
670
|
return Main.result_status("Opened: #{one_link['href']}")
|
@@ -700,11 +679,12 @@ module Aspera
|
|
700
679
|
return execute_connect_action
|
701
680
|
when :use
|
702
681
|
ascp_path = options.get_next_argument('path to ascp')
|
682
|
+
Ascp::Installation.instance.ascp_path = ascp_path
|
703
683
|
formatter.display_status("ascp version: #{Ascp::Installation.instance.get_ascp_version(ascp_path)}")
|
704
684
|
set_global_default(:ascp_path, ascp_path)
|
705
685
|
return Main.result_nothing
|
706
686
|
when :show
|
707
|
-
return
|
687
|
+
return Main.result_status(Ascp::Installation.instance.path(:ascp))
|
708
688
|
when :info
|
709
689
|
# collect info from ascp executable
|
710
690
|
data = Ascp::Installation.instance.ascp_info
|
@@ -713,13 +693,13 @@ module Aspera
|
|
713
693
|
# add keys
|
714
694
|
DataRepository::ELEMENTS.each_with_object(data){|i, h|h[i.to_s] = DataRepository.instance.item(i)}
|
715
695
|
# declare those as secrets
|
716
|
-
SecretHider::ADDITIONAL_KEYS_TO_HIDE.
|
717
|
-
return
|
696
|
+
SecretHider::ADDITIONAL_KEYS_TO_HIDE.concat(DataRepository::ELEMENTS.map(&:to_s))
|
697
|
+
return Main.result_single_object(data)
|
718
698
|
when :products
|
719
699
|
command = options.get_next_command(%i[list use])
|
720
700
|
case command
|
721
701
|
when :list
|
722
|
-
return
|
702
|
+
return Main.result_object_list(Ascp::Installation.instance.installed_products, fields: %w[name app_root])
|
723
703
|
when :use
|
724
704
|
default_product = options.get_next_argument('product name')
|
725
705
|
Ascp::Installation.instance.use_ascp_from_product(default_product)
|
@@ -728,23 +708,44 @@ module Aspera
|
|
728
708
|
end
|
729
709
|
when :install
|
730
710
|
# reset to default location, if older default was used
|
731
|
-
|
732
|
-
|
711
|
+
Products::Transferd.sdk_directory = self.class.default_app_main_folder(app_name: DIR_SDK) if @sdk_default_location
|
712
|
+
version = options.get_next_argument('transferd version', mandatory: false)
|
713
|
+
n, v = Ascp::Installation.instance.install_sdk(url: options.get_option(:sdk_url, mandatory: true), version: version)
|
733
714
|
return Main.result_status("Installed #{n} version #{v}")
|
734
715
|
when :spec
|
735
|
-
return
|
736
|
-
|
737
|
-
data: Transfer::Parameters.man_table(formatter),
|
716
|
+
return Main.result_object_list(
|
717
|
+
Transfer::Parameters.man_table(formatter),
|
738
718
|
fields: [%w[name type], Transfer::Parameters::SUPPORTED_AGENTS_SHORT.map(&:to_s), %w[description]].flatten.freeze
|
739
|
-
|
719
|
+
)
|
740
720
|
when :errors
|
741
721
|
error_data = []
|
742
722
|
Transfer::ERROR_INFO.each_pair do |code, prop|
|
743
723
|
error_data.push(code: code, mnemonic: prop[:c], retry: prop[:r], info: prop[:a])
|
744
724
|
end
|
745
|
-
return
|
725
|
+
return Main.result_object_list(error_data)
|
726
|
+
else Aspera.error_unexpected_value(command)
|
727
|
+
end
|
728
|
+
Aspera.error_unreachable_line
|
729
|
+
end
|
730
|
+
|
731
|
+
def execute_action_transferd
|
732
|
+
command = options.get_next_command(%i[list install])
|
733
|
+
case command
|
734
|
+
when :install
|
735
|
+
# reset to default location, if older default was used
|
736
|
+
Products::Transferd.sdk_directory = self.class.default_app_main_folder(app_name: DIR_SDK) if @sdk_default_location
|
737
|
+
version = options.get_next_argument('transferd version', mandatory: false)
|
738
|
+
n, v = Ascp::Installation.instance.install_sdk(url: options.get_option(:sdk_url, mandatory: true), version: version)
|
739
|
+
return Main.result_status("Installed #{n} version #{v}")
|
740
|
+
when :list
|
741
|
+
sdk_list = Ascp::Installation.instance.sdk_locations
|
742
|
+
return Main.result_object_list(
|
743
|
+
sdk_list,
|
744
|
+
fields: sdk_list.first.keys - ['url']
|
745
|
+
)
|
746
|
+
else Aspera.error_unexpected_value(command)
|
746
747
|
end
|
747
|
-
|
748
|
+
Aspera.error_unreachable_line
|
748
749
|
end
|
749
750
|
|
750
751
|
# legacy actions available globally
|
@@ -763,12 +764,20 @@ module Aspera
|
|
763
764
|
raise "no such preset: #{name}" if PRESET_EXIST_ACTIONS.include?(action) && !@config_presets.key?(name)
|
764
765
|
case action
|
765
766
|
when :list
|
766
|
-
return
|
767
|
+
return Main.result_value_list(@config_presets.keys, 'name')
|
767
768
|
when :overview
|
768
769
|
# display process modifies the value (hide secrets): we do not want to save removed secrets
|
769
|
-
|
770
|
+
data = self.class.deep_clone(@config_presets)
|
771
|
+
formatter.hide_secrets(data)
|
772
|
+
result = []
|
773
|
+
data.each do |config, preset|
|
774
|
+
preset.each do |parameter, value|
|
775
|
+
result.push(CONF_OVERVIEW_KEYS.zip([config, parameter, value]).to_h)
|
776
|
+
end
|
777
|
+
end
|
778
|
+
return Main.result_object_list(result, fields: CONF_OVERVIEW_KEYS)
|
770
779
|
when :show
|
771
|
-
return
|
780
|
+
return Main.result_single_object(self.class.deep_clone(@config_presets[name]))
|
772
781
|
when :delete
|
773
782
|
@config_presets.delete(name)
|
774
783
|
return Main.result_status("Deleted: #{name}")
|
@@ -779,7 +788,7 @@ module Aspera
|
|
779
788
|
case value
|
780
789
|
when Numeric, String then return {type: :text, data: ExtendedValue.instance.evaluate(value.to_s)}
|
781
790
|
end
|
782
|
-
return
|
791
|
+
return Main.result_single_object(value)
|
783
792
|
when :unset
|
784
793
|
param_name = options.get_next_argument('parameter name')
|
785
794
|
@config_presets[name].delete(param_name)
|
@@ -818,7 +827,7 @@ module Aspera
|
|
818
827
|
user = options.get_option(:username, mandatory: true)
|
819
828
|
result = lookup_preset(url: url, username: user)
|
820
829
|
raise 'no such config found' if result.nil?
|
821
|
-
return
|
830
|
+
return Main.result_single_object(result)
|
822
831
|
when :secure
|
823
832
|
identifier = options.get_next_argument('config name', mandatory: false)
|
824
833
|
preset_names = identifier.nil? ? @config_presets.keys : [identifier]
|
@@ -856,13 +865,15 @@ module Aspera
|
|
856
865
|
remote_certificate
|
857
866
|
gem
|
858
867
|
plugins
|
859
|
-
|
868
|
+
tokens
|
860
869
|
echo
|
870
|
+
download
|
861
871
|
wizard
|
862
872
|
detect
|
863
873
|
coffee
|
864
874
|
image
|
865
875
|
ascp
|
876
|
+
transferd
|
866
877
|
email_test
|
867
878
|
smtp_settings
|
868
879
|
proxy_check
|
@@ -912,9 +923,27 @@ module Aspera
|
|
912
923
|
end
|
913
924
|
when :echo # display the content of a value given on command line
|
914
925
|
return Formatter.auto_type(options.get_next_argument('value', validation: nil))
|
915
|
-
when :
|
916
|
-
|
917
|
-
|
926
|
+
when :download
|
927
|
+
file_url = options.get_next_argument('source URL').chomp
|
928
|
+
file_dest = options.get_next_argument('file path', mandatory: false)
|
929
|
+
if file_dest.nil?
|
930
|
+
file_dest = File.join(transfer.destination_folder(Transfer::Spec::DIRECTION_RECEIVE), file_url.gsub(%r{.*/}, ''))
|
931
|
+
end
|
932
|
+
formatter.display_status("Downloading: #{file_url}")
|
933
|
+
Rest.new(base_url: file_url).call(operation: 'GET', save_to_file: file_dest)
|
934
|
+
return Main.result_status("Saved to: #{file_dest}")
|
935
|
+
when :tokens
|
936
|
+
require 'aspera/api/node'
|
937
|
+
case options.get_next_command(%i{flush list show})
|
938
|
+
when :flush
|
939
|
+
return Main.result_value_list(OAuth::Factory.instance.flush_tokens, name: 'file')
|
940
|
+
when :list
|
941
|
+
return Main.result_object_list(OAuth::Factory.instance.persisted_tokens)
|
942
|
+
when :show
|
943
|
+
data = OAuth::Factory.instance.get_token_info(instance_identifier)
|
944
|
+
raise Cli::Error, 'No such identifier' if data.nil?
|
945
|
+
return Main.result_single_object(data)
|
946
|
+
end
|
918
947
|
when :plugins
|
919
948
|
case options.get_next_command(%i[list create])
|
920
949
|
when :list
|
@@ -928,7 +957,7 @@ module Aspera
|
|
928
957
|
path: PluginFactory.instance.plugin_source(name)
|
929
958
|
})
|
930
959
|
end
|
931
|
-
return
|
960
|
+
return Main.result_object_list(result, fields: %w[plugin detect wizard path])
|
932
961
|
when :create
|
933
962
|
plugin_name = options.get_next_argument('name').downcase
|
934
963
|
destination_folder = options.get_next_argument('folder', mandatory: false) || File.join(@main_folder, ASPERA_PLUGINS_FOLDERNAME)
|
@@ -954,10 +983,7 @@ module Aspera
|
|
954
983
|
options.ask_missing_mandatory = true
|
955
984
|
# detect plugins by url and optional query
|
956
985
|
apps = identify_plugins_for_url.freeze
|
957
|
-
return
|
958
|
-
type: :object_list,
|
959
|
-
data: apps
|
960
|
-
} if action.eql?(:detect)
|
986
|
+
return Main.result_object_list(apps) if action.eql?(:detect)
|
961
987
|
return wizard_find(apps)
|
962
988
|
when :coffee
|
963
989
|
return Main.result_image(COFFEE_IMAGE, formatter: formatter)
|
@@ -965,6 +991,8 @@ module Aspera
|
|
965
991
|
return Main.result_image(options.get_next_argument('image uri or blob'), formatter: formatter)
|
966
992
|
when :ascp
|
967
993
|
execute_action_ascp
|
994
|
+
when :transferd
|
995
|
+
execute_action_transferd
|
968
996
|
when :gem
|
969
997
|
case options.get_next_command(%i[path version name])
|
970
998
|
when :path then return Main.result_status(self.class.gem_src_root)
|
@@ -979,14 +1007,14 @@ module Aspera
|
|
979
1007
|
send_email_template(email_template_default: EMAIL_TEST_TEMPLATE)
|
980
1008
|
return Main.result_nothing
|
981
1009
|
when :smtp_settings
|
982
|
-
return
|
1010
|
+
return Main.result_single_object(email_settings)
|
983
1011
|
when :proxy_check
|
984
1012
|
# ensure fpac was provided
|
985
1013
|
options.get_option(:fpac, mandatory: true)
|
986
1014
|
server_url = options.get_next_argument('server url')
|
987
1015
|
return Main.result_status(@pac_exec.find_proxy_for_url(server_url))
|
988
1016
|
when :check_update
|
989
|
-
return
|
1017
|
+
return Main.result_single_object(check_gem_version)
|
990
1018
|
when :initdemo
|
991
1019
|
if @config_presets.key?(DEMO_PRESET)
|
992
1020
|
Log.log.warn{"Demo server preset already present: #{DEMO_PRESET}"}
|
@@ -1085,7 +1113,7 @@ module Aspera
|
|
1085
1113
|
wiz_preset_name = elements.join('_').strip.downcase.gsub(/[^a-z0-9]/, '_').squeeze('_')
|
1086
1114
|
end
|
1087
1115
|
# test mode does not change conf file
|
1088
|
-
return
|
1116
|
+
return Main.result_single_object(wizard_result) if options.get_option(:test_mode)
|
1089
1117
|
# Write configuration file
|
1090
1118
|
formatter.display_status("Preparing preset: #{wiz_preset_name}")
|
1091
1119
|
# init defaults if necessary
|
@@ -1196,7 +1224,8 @@ module Aspera
|
|
1196
1224
|
Log.log.error do
|
1197
1225
|
"Default config name [#{default_config_name}] specified for plugin [#{plugin_name_sym}], but it does not exist in config file.\n" \
|
1198
1226
|
'Please fix the issue: either create preset with one parameter: ' \
|
1199
|
-
"(#{Info::CMD_NAME} config id #{default_config_name} init @json:'{}')
|
1227
|
+
"(#{Info::CMD_NAME} config id #{default_config_name} init @json:'{}') " \
|
1228
|
+
"or remove default (#{Info::CMD_NAME} config id default remove #{plugin_name_sym})."
|
1200
1229
|
end
|
1201
1230
|
end
|
1202
1231
|
raise Cli::Error, "Config name [#{default_config_name}] must be a hash, check config file." if !@config_presets[default_config_name].is_a?(Hash)
|
@@ -1211,11 +1240,11 @@ module Aspera
|
|
1211
1240
|
command = options.get_next_command(%i[info list show create delete password])
|
1212
1241
|
case command
|
1213
1242
|
when :info
|
1214
|
-
return
|
1243
|
+
return Main.result_single_object(vault_info)
|
1215
1244
|
when :list
|
1216
|
-
return
|
1245
|
+
return Main.result_object_list(vault.list, fields: %w(label url username password description))
|
1217
1246
|
when :show
|
1218
|
-
return
|
1247
|
+
return Main.result_single_object(vault.get(label: options.get_next_argument('label')))
|
1219
1248
|
when :create
|
1220
1249
|
label = options.get_next_argument('label', validation: String)
|
1221
1250
|
info = options.get_next_argument('info', validation: Hash)
|
@@ -1264,6 +1293,8 @@ module Aspera
|
|
1264
1293
|
info = vault_info
|
1265
1294
|
case info[:type]
|
1266
1295
|
when 'file'
|
1296
|
+
# this module requires comilation, so it is optinal
|
1297
|
+
require 'aspera/keychain/encrypted_hash'
|
1267
1298
|
# absolute_path? introduced in ruby 2.7
|
1268
1299
|
@vault = Keychain::EncryptedHash.new(
|
1269
1300
|
info[:name].eql?(File.absolute_path(info[:name])) ? info[:name] : File.join(@main_folder, info[:name]),
|
@@ -19,6 +19,7 @@ module Aspera
|
|
19
19
|
options.declare(:region, 'Storage region')
|
20
20
|
options.declare(:identity, "Authentication URL (#{Api::CosNode::IBM_CLOUD_TOKEN_URL})", default: Api::CosNode::IBM_CLOUD_TOKEN_URL)
|
21
21
|
options.parse_options!
|
22
|
+
Node.declare_options(options)
|
22
23
|
end
|
23
24
|
|
24
25
|
ACTIONS = %i[node].freeze
|
@@ -305,7 +305,7 @@ module Aspera
|
|
305
305
|
# authenticated user
|
306
306
|
delivery_info['sources'] ||= [{'paths' => []}]
|
307
307
|
first_source = delivery_info['sources'].first
|
308
|
-
first_source['paths'].
|
308
|
+
first_source['paths'].concat(transfer.source_list)
|
309
309
|
source_id = instance_identifier(as_option: :remote_source) do |field, value|
|
310
310
|
Aspera.assert(field.eql?('name'), exception_class: Cli::BadArgument){'only name as selector, or give id'}
|
311
311
|
source_list = api_v3.read('source_shares')['items']
|
@@ -441,7 +441,9 @@ module Aspera
|
|
441
441
|
Aspera.assert(field.eql?('name'), exception_class: Cli::BadArgument){'only name as selector, or give id'}
|
442
442
|
self.class.get_source_id_by_name(value, source_list)
|
443
443
|
end.to_i
|
444
|
-
|
444
|
+
selected_source = source_list.find{|i|i['id'].eql?(source_id)}
|
445
|
+
raise 'No such source' if selected_source.nil?
|
446
|
+
source_name = selected_source['name']
|
445
447
|
source_hash = options.get_option(:storage, mandatory: true)
|
446
448
|
# check value of option
|
447
449
|
Aspera.assert_type(source_hash, Hash, exception_class: Cli::Error){'storage option'}
|
@@ -228,24 +228,25 @@ module Aspera
|
|
228
228
|
config.progress_bar&.event(:transfer, session_id: id, info: status['bytes_written'].to_i)
|
229
229
|
end
|
230
230
|
if status_list.include?(status['upload_status'])
|
231
|
-
# if status['upload_status'].eql?('completed')
|
232
231
|
config.progress_bar&.event(:end, session_id: id)
|
233
232
|
return status
|
234
|
-
# end
|
235
233
|
end
|
236
234
|
sleep(1.0)
|
237
235
|
end
|
238
236
|
end
|
239
237
|
|
238
|
+
# @param [Srting] job identifier
|
239
|
+
# @return [Hash] result of API call for job status
|
240
240
|
def wait_for_job(job_id)
|
241
|
+
result = nil
|
241
242
|
loop do
|
242
|
-
|
243
|
-
|
244
|
-
formatter.long_operation_running(
|
243
|
+
result = @api_v5.read("jobs/#{job_id}", {type: :formatted})
|
244
|
+
break unless JOB_RUNNING.include?(result['status'])
|
245
|
+
formatter.long_operation_running(result['status'])
|
245
246
|
sleep(0.5)
|
246
247
|
end
|
247
248
|
formatter.long_operation_terminated
|
248
|
-
|
249
|
+
return result
|
249
250
|
end
|
250
251
|
|
251
252
|
# Get a (full or partial) list of all entities of a given type with query: offset/limit
|
@@ -253,9 +254,10 @@ module Aspera
|
|
253
254
|
# @param query [Hash,nil] additional query parameters
|
254
255
|
# @param real_path [String] real path if it's n ot just the type
|
255
256
|
# @param item_list_key [String] key in the result to get the list of items
|
256
|
-
def list_entities(type:, real_path: nil, item_list_key: nil, query:
|
257
|
+
def list_entities(type:, real_path: nil, item_list_key: nil, query: nil)
|
257
258
|
Log.log.trace1{"list_entities t=#{type} p=#{real_path} k=#{item_list_key} q=#{query}"}
|
258
259
|
type = type.to_s if type.is_a?(Symbol)
|
260
|
+
query = {} if query.nil?
|
259
261
|
Aspera.assert_type(type, String)
|
260
262
|
Aspera.assert_type(query, Hash)
|
261
263
|
item_list_key = type if item_list_key.nil?
|
@@ -463,7 +465,8 @@ module Aspera
|
|
463
465
|
end
|
464
466
|
return browse_folder("packages/#{package_id}/files/#{location}")
|
465
467
|
when :status
|
466
|
-
|
468
|
+
status_list = options.get_next_argument('list of states, or nothing', mandatory: false, validation: Array)
|
469
|
+
status = wait_package_status(package_id, status_list: status_list)
|
467
470
|
return {type: :single_object, data: status}
|
468
471
|
when :delete
|
469
472
|
ids = package_id
|
@@ -555,9 +558,10 @@ module Aspera
|
|
555
558
|
id_as_arg = 'type'
|
556
559
|
when :accounts
|
557
560
|
display_fields = Formatter.all_but('user_profile_data_attributes')
|
561
|
+
available_commands.push(:reset_password)
|
558
562
|
when :oauth_clients
|
559
563
|
display_fields = Formatter.all_but('public_key')
|
560
|
-
adm_api = Rest.new(**@api_v5.params
|
564
|
+
adm_api = Rest.new(**@api_v5.params, base_url: "#{@faspex5_api_base_url}/#{PATH_AUTH}")
|
561
565
|
when :shared_inboxes, :workgroups
|
562
566
|
available_commands.push(:members, :saml_groups, :invite_external_collaborator)
|
563
567
|
res_id_query = {'all': true}
|
@@ -595,7 +599,11 @@ module Aspera
|
|
595
599
|
|
596
600
|
end
|
597
601
|
when :browse
|
598
|
-
|
602
|
+
node_id = instance_identifier do |field, value|
|
603
|
+
lookup_entity_by_field(
|
604
|
+
type: res_type, value: value, field: field, real_path: res_path, item_list_key: list_key, query: res_id_query)['id']
|
605
|
+
end
|
606
|
+
return browse_folder("#{res_path}/#{node_id}/browse")
|
599
607
|
when :invite_external_collaborator
|
600
608
|
shared_inbox_id = instance_identifier { |field, value| lookup_entity_by_field(type: res_type.to_s, field: field, value: value, query: res_id_query)['id']}
|
601
609
|
creation_payload = value_create_modify(command: res_command, type: [Hash, String])
|
@@ -642,7 +650,12 @@ module Aspera
|
|
642
650
|
value: value,
|
643
651
|
query: {type: Rest.array_params(%w{local_user saml_user self_registered_user external_user})})['id']
|
644
652
|
end
|
653
|
+
when :reset_password
|
654
|
+
contact_id = instance_identifier { |field, value| lookup_entity_by_field(type: res_type.to_s, field: field, value: value, query: res_id_query)['id']}
|
655
|
+
adm_api.create("#{res_type}/#{contact_id}/reset_password", {})
|
656
|
+
return Main.result_status('password reset, user shall check email')
|
645
657
|
end
|
658
|
+
Aspera.error_unreachable_line
|
646
659
|
end
|
647
660
|
|
648
661
|
def execute_admin
|
@@ -655,16 +668,18 @@ module Aspera
|
|
655
668
|
when *ADMIN_RESOURCES
|
656
669
|
return execute_resource(command)
|
657
670
|
when :clean_deleted
|
658
|
-
delete_data = value_create_modify(command: command, default: {
|
671
|
+
delete_data = value_create_modify(command: command, default: {})
|
672
|
+
delete_data = @api_v5.read('configuration').slice('days_before_deleting_package_records') if delete_data.empty?
|
659
673
|
res = @api_v5.create('internal/packages/clean_deleted', delete_data)
|
660
674
|
return {type: :single_object, data: res}
|
661
675
|
when :events
|
662
676
|
event_type = options.get_next_command(%i[application webhook])
|
663
677
|
case event_type
|
664
678
|
when :application
|
665
|
-
return {type: :object_list, data: list_entities(type: 'application_events'
|
679
|
+
return {type: :object_list, data: list_entities(type: 'application_events', query: query_read_delete),
|
680
|
+
fields: %w[event_type created_at application user.name]}
|
666
681
|
when :webhook
|
667
|
-
return {type: :object_list, data: list_entities(type: 'all_webhooks_events', item_list_key: 'events')}
|
682
|
+
return {type: :object_list, data: list_entities(type: 'all_webhooks_events', query: query_read_delete, item_list_key: 'events')}
|
668
683
|
end
|
669
684
|
when :configuration
|
670
685
|
conf_path = 'configuration'
|
@@ -732,7 +747,7 @@ module Aspera
|
|
732
747
|
end
|
733
748
|
end
|
734
749
|
when :bearer_token
|
735
|
-
return {type: :text, data: @api_v5.oauth.
|
750
|
+
return {type: :text, data: @api_v5.oauth.authorization}
|
736
751
|
when :packages
|
737
752
|
return package_action
|
738
753
|
when :shared_folders
|