aspera-cli 4.20.0 → 4.21.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +20 -2
  4. data/README.md +281 -156
  5. data/bin/asession +2 -2
  6. data/lib/aspera/agent/alpha.rb +7 -12
  7. data/lib/aspera/agent/connect.rb +19 -1
  8. data/lib/aspera/agent/direct.rb +20 -29
  9. data/lib/aspera/agent/node.rb +1 -11
  10. data/lib/aspera/agent/trsdk.rb +4 -25
  11. data/lib/aspera/api/aoc.rb +5 -0
  12. data/lib/aspera/api/node.rb +45 -28
  13. data/lib/aspera/ascp/installation.rb +69 -38
  14. data/lib/aspera/ascp/management.rb +27 -6
  15. data/lib/aspera/cli/formatter.rb +149 -141
  16. data/lib/aspera/cli/info.rb +1 -1
  17. data/lib/aspera/cli/manager.rb +1 -0
  18. data/lib/aspera/cli/plugin.rb +2 -2
  19. data/lib/aspera/cli/plugins/aoc.rb +27 -17
  20. data/lib/aspera/cli/plugins/config.rb +31 -21
  21. data/lib/aspera/cli/plugins/faspex.rb +1 -1
  22. data/lib/aspera/cli/plugins/faspex5.rb +11 -3
  23. data/lib/aspera/cli/plugins/node.rb +44 -38
  24. data/lib/aspera/cli/version.rb +1 -1
  25. data/lib/aspera/command_line_builder.rb +1 -1
  26. data/lib/aspera/environment.rb +5 -6
  27. data/lib/aspera/node_simulator.rb +228 -112
  28. data/lib/aspera/oauth/base.rb +31 -42
  29. data/lib/aspera/oauth/factory.rb +41 -2
  30. data/lib/aspera/persistency_folder.rb +20 -2
  31. data/lib/aspera/preview/generator.rb +1 -1
  32. data/lib/aspera/preview/utils.rb +1 -1
  33. data/lib/aspera/products/alpha.rb +30 -0
  34. data/lib/aspera/products/connect.rb +48 -0
  35. data/lib/aspera/products/other.rb +82 -0
  36. data/lib/aspera/products/trsdk.rb +54 -0
  37. data/lib/aspera/rest.rb +18 -13
  38. data/lib/aspera/ssh.rb +28 -24
  39. data/lib/aspera/transfer/spec.yaml +22 -20
  40. data.tar.gz.sig +0 -0
  41. metadata +21 -4
  42. metadata.gz.sig +0 -0
  43. data/lib/aspera/ascp/products.rb +0 -168
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aspera/environment'
4
+
5
+ module Aspera
6
+ module Products
7
+ class Connect
8
+ APP_NAME = 'IBM Aspera Connect'
9
+ class << self
10
+ # standard folder locations
11
+ def locations
12
+ case Aspera::Environment.os
13
+ when Aspera::Environment::OS_WINDOWS then [{
14
+ app_root: File.join(ENV.fetch('LOCALAPPDATA', nil), 'Programs', 'Aspera', 'Aspera Connect'),
15
+ log_root: File.join(ENV.fetch('LOCALAPPDATA', nil), 'Aspera', 'Aspera Connect', 'var', 'log'),
16
+ run_root: File.join(ENV.fetch('LOCALAPPDATA', nil), 'Aspera', 'Aspera Connect')
17
+ }]
18
+ when Aspera::Environment::OS_MACOS then [{
19
+ app_root: File.join(Dir.home, 'Applications', 'Aspera Connect.app'),
20
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Connect'),
21
+ run_root: File.join(Dir.home, 'Library', 'Application Support', 'Aspera', 'Aspera Connect'),
22
+ sub_bin: File.join('Contents', 'Resources')
23
+ }, {
24
+ app_root: File.join('', 'Applications', 'Aspera Connect.app'),
25
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Connect'),
26
+ run_root: File.join(Dir.home, 'Library', 'Application Support', 'Aspera', 'Aspera Connect'),
27
+ sub_bin: File.join('Contents', 'Resources')
28
+ }, {
29
+ app_root: File.join(Dir.home, 'Applications', 'IBM Aspera Connect.app'),
30
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Connect'),
31
+ run_root: File.join(Dir.home, 'Library', 'Application Support', 'Aspera', 'Aspera Connect'),
32
+ sub_bin: File.join('Contents', 'Resources')
33
+ }, {
34
+ app_root: File.join('', 'Applications', 'IBM Aspera Connect.app'),
35
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Connect'),
36
+ run_root: File.join(Dir.home, 'Library', 'Application Support', 'Aspera', 'Aspera Connect'),
37
+ sub_bin: File.join('Contents', 'Resources')
38
+ }]
39
+ else [{ # other: Linux and Unix family
40
+ app_root: File.join(Dir.home, '.aspera', 'connect'),
41
+ run_root: File.join(Dir.home, '.aspera', 'connect')
42
+ }]
43
+ end.map { |i| i.merge({ expected: APP_NAME }) }
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ # cspell:ignore LOCALAPPDATA
4
+ require 'aspera/environment'
5
+
6
+ module Aspera
7
+ # Location of Aspera products, for which an Agent is not proposed
8
+ module Products
9
+ # other Aspera products with ascp
10
+ class Other
11
+ CLI_V3 = 'Aspera CLI (deprecated)'
12
+ DRIVE = 'Aspera Drive (deprecated)'
13
+ HSTS = 'IBM Aspera High-Speed Transfer Server'
14
+
15
+ private_constant :CLI_V3, :DRIVE, :HSTS
16
+ # product information manifest: XML (part of aspera product)
17
+ INFO_META_FILE = 'product-info.mf'
18
+
19
+ # :expected M app name is taken from the manifest if present, else defaults to this value
20
+ # :app_root M main folder for the application
21
+ # :log_root O location of log files (Linux uses syslog)
22
+ # :run_root O only for Connect Client, location of http port file
23
+ # :sub_bin O subfolder with executables, default : bin
24
+ LOCATION_ON_THIS_OS = case Aspera::Environment.os
25
+ when Aspera::Environment::OS_WINDOWS then [{
26
+ expected: CLI_V3,
27
+ app_root: File.join('C:', 'Program Files', 'Aspera', 'cli'),
28
+ log_root: File.join('C:', 'Program Files', 'Aspera', 'cli', 'var', 'log')
29
+ }, {
30
+ expected: HSTS,
31
+ app_root: File.join('C:', 'Program Files', 'Aspera', 'Enterprise Server'),
32
+ log_root: File.join('C:', 'Program Files', 'Aspera', 'Enterprise Server', 'var', 'log')
33
+ }]
34
+ when Aspera::Environment::OS_MACOS then [{
35
+ expected: CLI_V3,
36
+ app_root: File.join(Dir.home, 'Applications', 'Aspera CLI'),
37
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera')
38
+ }, {
39
+ expected: HSTS,
40
+ app_root: File.join('', 'Library', 'Aspera'),
41
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera')
42
+ }, {
43
+ expected: DRIVE,
44
+ app_root: File.join('', 'Applications', 'Aspera Drive.app'),
45
+ log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Drive'),
46
+ sub_bin: File.join('Contents', 'Resources')
47
+ }]
48
+ else [{ # other: Linux and Unix family
49
+ expected: CLI_V3,
50
+ app_root: File.join(Dir.home, '.aspera', 'cli')
51
+ }, {
52
+ expected: HSTS,
53
+ app_root: File.join('', 'opt', 'aspera')
54
+ }]
55
+ end
56
+ class << self
57
+ def find(scan_locations)
58
+ scan_locations.select do |item|
59
+ # skip if not main folder
60
+ Log.log.trace1{"Checking #{item[:app_root]}"}
61
+ next false unless Dir.exist?(item[:app_root])
62
+ Log.log.debug{"Found #{item[:expected]}"}
63
+ sub_bin = item[:sub_bin] || 'bin'
64
+ item[:ascp_path] = File.join(item[:app_root], sub_bin, Environment.exe_file('ascp'))
65
+ # skip if no ascp
66
+ next false unless File.exist?(item[:ascp_path])
67
+ # read info from product info file if present
68
+ product_info_file = "#{item[:app_root]}/#{INFO_META_FILE}"
69
+ if File.exist?(product_info_file)
70
+ res_s = XmlSimple.xml_in(File.read(product_info_file), {'ForceArray' => false})
71
+ item[:name] = res_s['name']
72
+ item[:version] = res_s['version']
73
+ else
74
+ item[:name] = item[:expected]
75
+ end
76
+ true # select this version
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aspera
4
+ module Products
5
+ class Trsdk
6
+ APP_NAME = 'IBM Aspera Transfer Daemon'
7
+ class << self
8
+ # standard folder locations
9
+ def locations
10
+ [{
11
+ app_root: sdk_directory,
12
+ sub_bin: ''
13
+ }].map { |i| i.merge({ expected: APP_NAME }) }
14
+ end
15
+
16
+ # location of SDK files
17
+ def sdk_directory=(v)
18
+ Log.log.debug{"sdk_directory=#{v}"}
19
+ @sdk_dir = v
20
+ sdk_directory
21
+ end
22
+
23
+ # @return the path to folder where SDK is installed
24
+ def sdk_directory
25
+ Aspera.assert(!@sdk_dir.nil?){'SDK path was not initialized'}
26
+ FileUtils.mkdir_p(@sdk_dir)
27
+ @sdk_dir
28
+ end
29
+
30
+ def transferd_path
31
+ return File.join(sdk_directory, Environment.exe_file('asperatransferd')) # cspell:disable-line
32
+ end
33
+
34
+ # Well, the port number is only in log file
35
+ def daemon_port_from_log(log_file)
36
+ result = nil
37
+ # if port is zero, a dynamic port was created, get it
38
+ File.open(log_file, 'r') do |file|
39
+ file.each_line do |line|
40
+ # Well, it's tricky to depend on log
41
+ if (m = line.match(/Info: API Server: Listening on ([^:]+):(\d+) /))
42
+ result = m[2].to_i
43
+ # no "break" , need to read last matching log line
44
+ end
45
+ end
46
+ end
47
+ raise 'Port not found in daemon logs' if result.nil?
48
+ Log.log.debug{"Got port #{result} from log"}
49
+ return result
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
data/lib/aspera/rest.rb CHANGED
@@ -10,7 +10,6 @@ require 'net/http'
10
10
  require 'net/https'
11
11
  require 'json'
12
12
  require 'base64'
13
- require 'cgi'
14
13
  require 'singleton'
15
14
  require 'securerandom'
16
15
 
@@ -22,11 +21,13 @@ class Net::HTTP::Cancel < Net::HTTPRequest # rubocop:disable Style/ClassAndModul
22
21
  end
23
22
 
24
23
  module Aspera
25
- # Global settings
24
+ # Global settings for Rest object
25
+ # For example to remove certificate verification globally:
26
+ # `RestParameters.instance.session_cb = lambda{|http|http.verify_mode=OpenSSL::SSL::VERIFY_NONE}`
26
27
  # @param user_agent [String] HTTP request header: 'User-Agent'
27
28
  # @param download_partial_suffix [String] suffix for partial download
28
29
  # @param session_cb [lambda] lambda called on new HTTP session. Takes the Net::HTTP as arg. Used to change parameters on creation.
29
- # @param progress_bar [Object] progress bar object
30
+ # @param progress_bar [Object] progress bar object called for file transfer
30
31
  class RestParameters
31
32
  include Singleton
32
33
 
@@ -200,6 +201,9 @@ module Aspera
200
201
  }
201
202
  end
202
203
 
204
+ # Create a REST object for API calls
205
+ # HTTP sessions parameters can be modified using global parameters in RestParameters
206
+ # For example, TLS verification can be skipped.
203
207
  # @param base_url [String] base URL of REST API
204
208
  # @param auth [Hash] authentication parameters:
205
209
  # :type (:none, :basic, :url, :oauth2)
@@ -207,14 +211,15 @@ module Aspera
207
211
  # :password [:basic]
208
212
  # :url_query [:url] a hash
209
213
  # :* [:oauth2] see OAuth::Factory class
210
- # @param not_auth_codes [Array] codes that trigger a refresh/regeneration of bearer token
211
- # @param redirect_max [int] max redirection allowed
214
+ # @param not_auth_codes [Array] codes that trigger a refresh/regeneration of bearer token
215
+ # @param redirect_max [Integer] max redirection allowed
216
+ # @param headers [Hash] default headers to include in all calls
212
217
  def initialize(
213
218
  base_url:,
214
- auth: nil,
215
- not_auth_codes: nil,
219
+ auth: {type: :none},
220
+ not_auth_codes: ['401'],
216
221
  redirect_max: 0,
217
- headers: nil
222
+ headers: {}
218
223
  )
219
224
  Aspera.assert_type(base_url, String)
220
225
  # base url with no trailing slashes (note: string may be frozen)
@@ -224,20 +229,20 @@ module Aspera
224
229
  @base_url = @base_url.gsub(/:80$/, '') if @base_url.start_with?('http://')
225
230
  Log.log.debug{"Rest.new(#{@base_url})"}
226
231
  # default is no auth
227
- @auth_params = auth.nil? ? {type: :none} : auth
232
+ @auth_params = auth
228
233
  Aspera.assert_type(@auth_params, Hash)
229
234
  Aspera.assert(@auth_params.key?(:type)){'no auth type defined'}
230
- @not_auth_codes = not_auth_codes.nil? ? ['401'] : not_auth_codes
235
+ @not_auth_codes = not_auth_codes
231
236
  Aspera.assert_type(@not_auth_codes, Array)
232
237
  # persistent session
233
238
  @http_session = nil
234
- # OAuth object (created on demand)
235
- @oauth = nil
236
239
  @redirect_max = redirect_max
237
240
  Aspera.assert_type(@redirect_max, Integer)
238
- @headers = headers.nil? ? {} : headers
241
+ @headers = headers
239
242
  Aspera.assert_type(@headers, Hash)
240
243
  @headers['User-Agent'] ||= RestParameters.instance.user_agent
244
+ # OAuth object (created on demand)
245
+ @oauth = nil
241
246
  end
242
247
 
243
248
  # @return the OAuth object (create, or cached if already created)
data/lib/aspera/ssh.rb CHANGED
@@ -1,33 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'net/ssh'
4
-
5
- if ENV.fetch('ASCLI_ENABLE_ED25519', 'false').eql?('false')
6
- # HACK: deactivate ed25519 and ecdsa private keys from SSH identities, as it usually causes problems
7
- old_verbose = $VERBOSE
8
- $VERBOSE = nil
9
- begin
10
- module Net; module SSH; module Authentication; class Session; private; def default_keys; %w[~/.ssh/id_dsa ~/.ssh/id_rsa ~/.ssh2/id_dsa ~/.ssh2/id_rsa]; end; end; end; end; end # rubocop:disable Layout/AccessModifierIndentation, Layout/EmptyLinesAroundAccessModifier, Layout/LineLength, Style/Semicolon
11
- rescue StandardError
12
- # ignore errors
13
- end
14
- $VERBOSE = old_verbose
15
- end
16
-
17
- if defined?(JRUBY_VERSION) && ENV.fetch('ASCLI_ENABLE_ECDSHA2', 'false').eql?('false')
18
- Net::SSH::Transport::Algorithms::ALGORITHMS.each_value { |a| a.reject! { |a| a =~ /^ecd(sa|h)-sha2/ } }
19
- Net::SSH::KnownHosts::SUPPORTED_TYPE.reject! { |t| t =~ /^ecd(sa|h)-sha2/ }
20
- end
4
+ require 'aspera/assert'
21
5
 
22
6
  module Aspera
23
7
  # A simple wrapper around Net::SSH
24
8
  # executes one command and get its result from stdout
25
9
  class Ssh
10
+ class << self
11
+ def disable_ed25519_keys
12
+ old_verbose = $VERBOSE
13
+ $VERBOSE = nil
14
+ Net::SSH::Authentication::Session.class_eval do
15
+ define_method(:default_keys) do
16
+ %w[~/.ssh/id_dsa ~/.ssh/id_rsa ~/.ssh2/id_dsa ~/.ssh2/id_rsa].freeze
17
+ end
18
+ private(:default_keys)
19
+ end rescue nil
20
+ $VERBOSE = old_verbose
21
+ end
22
+
23
+ def disable_ecd_sha2_algorithms
24
+ Net::SSH::Transport::Algorithms::ALGORITHMS.each_value { |a| a.reject! { |a| a =~ /^ecd(sa|h)-sha2/ } }
25
+ Net::SSH::KnownHosts::SUPPORTED_TYPE.reject! { |t| t =~ /^ecd(sa|h)-sha2/ }
26
+ end
27
+ end
26
28
  # ssh_options: same as Net::SSH.start
27
29
  # see: https://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
28
30
  def initialize(host, username, ssh_options)
29
31
  Log.log.debug{"ssh:#{username}@#{host}"}
30
32
  Log.log.debug{"ssh_options:#{ssh_options}"}
33
+ Aspera.assert_type(host, String)
34
+ Aspera.assert_type(username, String)
35
+ Aspera.assert_type(ssh_options, Hash)
31
36
  @host = host
32
37
  @username = username
33
38
  @ssh_options = ssh_options
@@ -35,10 +40,7 @@ module Aspera
35
40
  end
36
41
 
37
42
  def execute(cmd, input=nil)
38
- if cmd.is_a?(Array)
39
- # concatenate arguments, enclose in double quotes
40
- cmd = cmd.map{|v|%Q("#{v}")}.join(' ')
41
- end
43
+ Aspera.assert_type(cmd, String)
42
44
  Log.log.debug{"cmd=#{cmd}"}
43
45
  response = []
44
46
  Net::SSH.start(@host, @username, @ssh_options) do |session|
@@ -49,9 +51,7 @@ module Aspera
49
51
  channel.on_extended_data do |_chan, _type, data|
50
52
  error_message = "#{cmd}: [#{data.chomp}]"
51
53
  # Happens when windows user hasn't logged in and created home account.
52
- if data.include?('Could not chdir to home directory')
53
- error_message += "\nHint: home not created in Windows?"
54
- end
54
+ error_message += "\nHint: home not created in Windows?" if data.include?('Could not chdir to home directory')
55
55
  raise error_message
56
56
  end
57
57
  # send command to SSH channel (execute) cspell: disable-next-line
@@ -67,3 +67,7 @@ module Aspera
67
67
  end
68
68
  end
69
69
  end
70
+
71
+ # HACK: deactivate ed25519 and ecdsa private keys from SSH identities, as it usually causes problems
72
+ Aspera::Ssh.disable_ed25519_keys if ENV.fetch('ASCLI_ENABLE_ED25519', 'false').eql?('false')
73
+ Aspera::Ssh.disable_ecd_sha2_algorithms if defined?(JRUBY_VERSION) && ENV.fetch('ASCLI_ENABLE_ECDSHA2', 'false').eql?('false')
@@ -1,13 +1,13 @@
1
- # desc : description
2
- # accepted_types : accepted types for non-enum
3
- # default : default value if not specified
4
- # enum : set with list of values for enum types accepted in transfer spec
5
- # agents : supported agents (for doc only), if not specified: all
6
- # required : optional, default: false
7
- # cli.type : ascp: type of parameter, one of CLI_OPTION_TYPES
8
- # cli.switch : ascp: switch for ascp command line
9
- # cli.convert : ascp: transform value: either a Hash with conversion values, or name of class
10
- # cli.variable : ascp: name of env var
1
+ # desc [String] description
2
+ # accepted_types [Symbol, Array(Symbol)] accepted types for non-enum
3
+ # default [String] default value if not specified
4
+ # enum [Array] set with list of values for enum types accepted in transfer spec
5
+ # agents [Array] supported agents (for doc only), if not specified: all
6
+ # required [bool] optional, default: false
7
+ # cli.type [Symbol] ascp: type of parameter, one of CLI_OPTION_TYPES (opt_without_arg opt_with_arg special ignore envvar)
8
+ # cli.switch [String] ascp: switch for ascp command line
9
+ # cli.convert [String] ascp: transform value: either a Hash with conversion values, or name of class
10
+ # cli.variable [String] ascp: name of env var
11
11
  # cspell:words dgram dnat dnats faspmgr asperanoded xattrs keepalive datagram
12
12
  ---
13
13
  cipher:
@@ -102,17 +102,13 @@ direction:
102
102
  receive: recv
103
103
  send: send
104
104
  exclude_newer_than:
105
- :desc: skip src files with mtime > arg
106
- :accepted_types: :int
107
- :agents:
108
- - :direct
105
+ :desc: Exclude files, but not directories, from the transfer if they are newer than the specified number of seconds added to the source computer's epoch. e.g. "-86400" for newer than a day back.
106
+ :accepted_types: :string
109
107
  :cli:
110
108
  :type: :opt_with_arg
111
109
  exclude_older_than:
112
- :desc: skip src files with mtime < arg
113
- :accepted_types: :int
114
- :agents:
115
- - :direct
110
+ :desc: Exclude files, but not directories, from the transfer if they are older than the specified number of seconds added to the source computer's epoch. e.g. "-86400" for older than a day back.
111
+ :accepted_types: :string
116
112
  :cli:
117
113
  :type: :opt_with_arg
118
114
  fasp_port:
@@ -213,7 +209,6 @@ password:
213
209
  Windows only, node api only.
214
210
 
215
211
 
216
- :required: false
217
212
  :accepted_types: :string
218
213
  :agents:
219
214
  - :node
@@ -419,7 +414,7 @@ symlink_policy:
419
414
  :type: :opt_with_arg
420
415
  :switch: "--symbolic-links"
421
416
  tags:
422
- :desc: Metadata for transfer as JSON
417
+ :desc: Metadata for transfer as JSON. Key `aspera` is reserved. Key `aspera.xfer_retry` specified a retry timeout for node api initiated transfers.
423
418
  :accepted_types: :hash
424
419
  :cli:
425
420
  :type: :opt_with_arg
@@ -714,3 +709,10 @@ write_threads:
714
709
  - :unknown
715
710
  :cli:
716
711
  :type: :ignore
712
+ xfer_max_retries:
713
+ :desc: maximum number of retries, for node API initiated transfers. Shall not exceed aspera.conf `transfer_manager_max_retries` (default 5).
714
+ :accepted_types: :int
715
+ :agents:
716
+ - :node
717
+ :cli:
718
+ :type: :ignore
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aspera-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.20.0
4
+ version: 4.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Laurent Martin
@@ -37,7 +37,7 @@ cert_chain:
37
37
  eTf9kxhVM40wGQOECVNA8UsEEZHD48eF+csUYZtAJOF5oxTI8UyV9T/o6CgO0c9/
38
38
  Gzz+Qm5ULOUcPiJLjSpaiTrkiIVYiDGnqNSr6R1Hb1c=
39
39
  -----END CERTIFICATE-----
40
- date: 2025-01-21 00:00:00.000000000 Z
40
+ date: 2025-02-26 00:00:00.000000000 Z
41
41
  dependencies:
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: blankslate
@@ -123,6 +123,20 @@ dependencies:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
125
  version: '7.0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: openssl
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: 3.3.0
133
+ type: :runtime
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: 3.3.0
126
140
  - !ruby/object:Gem::Dependency
127
141
  name: rainbow
128
142
  requirement: !ruby/object:Gem::Requirement
@@ -426,7 +440,6 @@ files:
426
440
  - lib/aspera/ascmd.rb
427
441
  - lib/aspera/ascp/installation.rb
428
442
  - lib/aspera/ascp/management.rb
429
- - lib/aspera/ascp/products.rb
430
443
  - lib/aspera/assert.rb
431
444
  - lib/aspera/cli/basic_auth_plugin.rb
432
445
  - lib/aspera/cli/error.rb
@@ -496,6 +509,10 @@ files:
496
509
  - lib/aspera/preview/terminal.rb
497
510
  - lib/aspera/preview/utils.rb
498
511
  - lib/aspera/preview/video_error.png
512
+ - lib/aspera/products/alpha.rb
513
+ - lib/aspera/products/connect.rb
514
+ - lib/aspera/products/other.rb
515
+ - lib/aspera/products/trsdk.rb
499
516
  - lib/aspera/proxy_auto_config.js
500
517
  - lib/aspera/proxy_auto_config.rb
501
518
  - lib/aspera/rest.rb
@@ -538,7 +555,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
538
555
  requirements:
539
556
  - - ">="
540
557
  - !ruby/object:Gem::Version
541
- version: '2.6'
558
+ version: '2.7'
542
559
  required_rubygems_version: !ruby/object:Gem::Requirement
543
560
  requirements:
544
561
  - - ">="
metadata.gz.sig CHANGED
Binary file
@@ -1,168 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # cspell:ignore LOCALAPPDATA
4
- require 'aspera/environment'
5
-
6
- module Aspera
7
- module Ascp
8
- # find Aspera standard products installation in standard paths
9
- class Products
10
- # known product names
11
- CONNECT = 'IBM Aspera Connect'
12
- ASPERA = 'IBM Aspera (Client)'
13
- CLI_V1 = 'Aspera CLI (deprecated)'
14
- DRIVE = 'Aspera Drive (deprecated)'
15
- HSTS = 'IBM Aspera High-Speed Transfer Server'
16
- # product information manifest: XML (part of aspera product)
17
- INFO_META_FILE = 'product-info.mf'
18
- BIN_SUBFOLDER = 'bin'
19
- ETC_SUBFOLDER = 'etc'
20
- VAR_RUN_SUBFOLDER = File.join('var', 'run')
21
-
22
- @@found_products = nil # rubocop:disable Style/ClassVars
23
- class << self
24
- # @return product folders depending on OS fields
25
- # :expected M app name is taken from the manifest if present, else defaults to this value
26
- # :app_root M main folder for the application
27
- # :log_root O location of log files (Linux uses syslog)
28
- # :run_root O only for Connect Client, location of http port file
29
- # :sub_bin O subfolder with executables, default : bin
30
- def product_locations_on_current_os
31
- result =
32
- case Aspera::Environment.os
33
- when Aspera::Environment::OS_WINDOWS then [{
34
- expected: CONNECT,
35
- app_root: File.join(ENV.fetch('LOCALAPPDATA', nil), 'Programs', 'Aspera', 'Aspera Connect'),
36
- log_root: File.join(ENV.fetch('LOCALAPPDATA', nil), 'Aspera', 'Aspera Connect', 'var', 'log'),
37
- run_root: File.join(ENV.fetch('LOCALAPPDATA', nil), 'Aspera', 'Aspera Connect')
38
- }, {
39
- expected: CLI_V1,
40
- app_root: File.join('C:', 'Program Files', 'Aspera', 'cli'),
41
- log_root: File.join('C:', 'Program Files', 'Aspera', 'cli', 'var', 'log')
42
- }, {
43
- expected: HSTS,
44
- app_root: File.join('C:', 'Program Files', 'Aspera', 'Enterprise Server'),
45
- log_root: File.join('C:', 'Program Files', 'Aspera', 'Enterprise Server', 'var', 'log')
46
- }]
47
- when Aspera::Environment::OS_MACOS then [{
48
- expected: CONNECT,
49
- app_root: File.join(Dir.home, 'Applications', 'Aspera Connect.app'),
50
- log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Connect'),
51
- run_root: File.join(Dir.home, 'Library', 'Application Support', 'Aspera', 'Aspera Connect'),
52
- sub_bin: File.join('Contents', 'Resources')
53
- }, {
54
- expected: CONNECT,
55
- app_root: File.join('', 'Applications', 'Aspera Connect.app'),
56
- log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Connect'),
57
- run_root: File.join(Dir.home, 'Library', 'Application Support', 'Aspera', 'Aspera Connect'),
58
- sub_bin: File.join('Contents', 'Resources')
59
- }, {
60
- expected: CONNECT,
61
- app_root: File.join(Dir.home, 'Applications', 'IBM Aspera Connect.app'),
62
- log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Connect'),
63
- run_root: File.join(Dir.home, 'Library', 'Application Support', 'Aspera', 'Aspera Connect'),
64
- sub_bin: File.join('Contents', 'Resources')
65
- }, {
66
- expected: CONNECT,
67
- app_root: File.join('', 'Applications', 'IBM Aspera Connect.app'),
68
- log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Connect'),
69
- run_root: File.join(Dir.home, 'Library', 'Application Support', 'Aspera', 'Aspera Connect'),
70
- sub_bin: File.join('Contents', 'Resources')
71
- }, {
72
- expected: CLI_V1,
73
- app_root: File.join(Dir.home, 'Applications', 'Aspera CLI'),
74
- log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera')
75
- }, {
76
- expected: HSTS,
77
- app_root: File.join('', 'Library', 'Aspera'),
78
- log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera')
79
- }, {
80
- expected: DRIVE,
81
- app_root: File.join('', 'Applications', 'Aspera Drive.app'),
82
- log_root: File.join(Dir.home, 'Library', 'Logs', 'Aspera_Drive'),
83
- sub_bin: File.join('Contents', 'Resources')
84
- }, {
85
- expected: ASPERA,
86
- app_root: File.join('', 'Applications', 'IBM Aspera.app'),
87
- log_root: File.join(Dir.home, 'Library', 'Logs', 'IBM Aspera'),
88
- sub_bin: File.join('Contents', 'Resources', 'sdk', 'aspera', 'bin')
89
- }]
90
- else [{ # other: Linux and Unix family
91
- expected: CONNECT,
92
- app_root: File.join(Dir.home, '.aspera', 'connect'),
93
- run_root: File.join(Dir.home, '.aspera', 'connect')
94
- }, {
95
- expected: CLI_V1,
96
- app_root: File.join(Dir.home, '.aspera', 'cli')
97
- }, {
98
- expected: HSTS,
99
- app_root: File.join('', 'opt', 'aspera')
100
- }]
101
- end
102
- result # .each {|item| item.deep_do {|h, _k, _v, _m|h.freeze}}.freeze
103
- end
104
-
105
- # @return the list of installed products in format of product_locations_on_current_os
106
- def installed_products
107
- if @@found_products.nil?
108
- scan_locations = product_locations_on_current_os.clone
109
- # add SDK as first search path
110
- scan_locations.unshift({
111
- expected: 'SDK',
112
- app_root: Installation.instance.sdk_folder,
113
- sub_bin: ''
114
- })
115
- # search installed products: with ascp
116
- @@found_products = scan_locations.select! do |item| # rubocop:disable Style/ClassVars
117
- # skip if not main folder
118
- next false unless Dir.exist?(item[:app_root])
119
- Log.log.debug{"Found #{item[:app_root]}"}
120
- sub_bin = item[:sub_bin] || BIN_SUBFOLDER
121
- item[:ascp_path] = File.join(item[:app_root], sub_bin, ascp_filename)
122
- # skip if no ascp
123
- next false unless File.exist?(item[:ascp_path])
124
- # read info from product info file if present
125
- product_info_file = "#{item[:app_root]}/#{INFO_META_FILE}"
126
- if File.exist?(product_info_file)
127
- res_s = XmlSimple.xml_in(File.read(product_info_file), {'ForceArray' => false})
128
- item[:name] = res_s['name']
129
- item[:version] = res_s['version']
130
- else
131
- item[:name] = item[:expected]
132
- end
133
- true # select this version
134
- end
135
- end
136
- return @@found_products
137
- end
138
-
139
- # filename for ascp with optional extension (Windows)
140
- def ascp_filename
141
- return "ascp#{Environment.exe_extension}"
142
- end
143
-
144
- # @return folder paths for specified applications
145
- # @param name Connect or CLI
146
- def folders(name)
147
- found = Products.installed_products.select{|i|i[:expected].eql?(name) || i[:name].eql?(name)}
148
- raise "Product: #{name} not found, please install." if found.empty?
149
- return found.first
150
- end
151
-
152
- # @return the file path of local connect where API's URI can be read
153
- def connect_uri
154
- connect = folders(CONNECT)
155
- folder = File.join(connect[:run_root], VAR_RUN_SUBFOLDER)
156
- ['', 's'].each do |ext|
157
- uri_file = File.join(folder, "http#{ext}.uri")
158
- Log.log.debug{"checking connect port file: #{uri_file}"}
159
- if File.exist?(uri_file)
160
- return File.open(uri_file, &:gets).strip
161
- end
162
- end
163
- raise "no connect uri file found in #{folder}"
164
- end
165
- end
166
- end
167
- end
168
- end