aspera-cli 4.23.0 → 4.24.1

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 (110) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +37 -1
  4. data/CONTRIBUTING.md +86 -29
  5. data/README.md +2109 -1300
  6. data/bin/ascli +2 -1
  7. data/bin/asession +4 -4
  8. data/lib/aspera/agent/base.rb +4 -0
  9. data/lib/aspera/agent/connect.rb +20 -18
  10. data/lib/aspera/agent/desktop.rb +14 -11
  11. data/lib/aspera/agent/direct.rb +39 -31
  12. data/lib/aspera/agent/httpgw.rb +2 -2
  13. data/lib/aspera/agent/node.rb +9 -11
  14. data/lib/aspera/agent/transferd.rb +18 -11
  15. data/lib/aspera/api/aoc.rb +44 -31
  16. data/lib/aspera/api/cos_node.rb +7 -5
  17. data/lib/aspera/api/httpgw.rb +15 -18
  18. data/lib/aspera/api/node.rb +104 -22
  19. data/lib/aspera/ascmd.rb +22 -16
  20. data/lib/aspera/ascp/installation.rb +37 -40
  21. data/lib/aspera/ascp/management.rb +5 -4
  22. data/lib/aspera/assert.rb +54 -23
  23. data/lib/aspera/cli/basic_auth_plugin.rb +8 -7
  24. data/lib/aspera/cli/error.rb +1 -1
  25. data/lib/aspera/cli/extended_value.rb +28 -29
  26. data/lib/aspera/cli/formatter.rb +191 -168
  27. data/lib/aspera/cli/hints.rb +29 -3
  28. data/lib/aspera/cli/main.rb +138 -107
  29. data/lib/aspera/cli/manager.rb +50 -30
  30. data/lib/aspera/cli/plugin.rb +148 -77
  31. data/lib/aspera/cli/plugin_factory.rb +2 -2
  32. data/lib/aspera/cli/plugins/aoc.rb +189 -70
  33. data/lib/aspera/cli/plugins/ats.rb +15 -13
  34. data/lib/aspera/cli/plugins/config.rb +100 -214
  35. data/lib/aspera/cli/plugins/console.rb +49 -18
  36. data/lib/aspera/cli/plugins/cos.rb +4 -4
  37. data/lib/aspera/cli/plugins/faspex.rb +45 -51
  38. data/lib/aspera/cli/plugins/faspex5.rb +164 -165
  39. data/lib/aspera/cli/plugins/faspio.rb +6 -5
  40. data/lib/aspera/cli/plugins/httpgw.rb +2 -2
  41. data/lib/aspera/cli/plugins/node.rb +144 -162
  42. data/lib/aspera/cli/plugins/orchestrator.rb +10 -14
  43. data/lib/aspera/cli/plugins/preview.rb +26 -29
  44. data/lib/aspera/cli/plugins/server.rb +28 -28
  45. data/lib/aspera/cli/plugins/shares.rb +40 -28
  46. data/lib/aspera/cli/sync_actions.rb +101 -80
  47. data/lib/aspera/cli/transfer_agent.rb +51 -50
  48. data/lib/aspera/cli/transfer_progress.rb +29 -20
  49. data/lib/aspera/cli/version.rb +1 -1
  50. data/lib/aspera/cli/wizard.rb +157 -0
  51. data/lib/aspera/colors.rb +13 -8
  52. data/lib/aspera/command_line_builder.rb +28 -22
  53. data/lib/aspera/command_line_converter.rb +31 -0
  54. data/lib/aspera/environment.rb +145 -101
  55. data/lib/aspera/faspex_gw.rb +1 -1
  56. data/lib/aspera/faspex_postproc.rb +3 -2
  57. data/lib/aspera/hash_ext.rb +1 -1
  58. data/lib/aspera/id_generator.rb +10 -10
  59. data/lib/aspera/keychain/base.rb +18 -0
  60. data/lib/aspera/keychain/encrypted_hash.rb +6 -12
  61. data/lib/aspera/keychain/factory.rb +9 -3
  62. data/lib/aspera/keychain/hashicorp_vault.rb +9 -6
  63. data/lib/aspera/keychain/macos_security.rb +13 -13
  64. data/lib/aspera/log.rb +91 -19
  65. data/lib/aspera/nagios.rb +5 -6
  66. data/lib/aspera/node_simulator.rb +12 -7
  67. data/lib/aspera/oauth/base.rb +5 -3
  68. data/lib/aspera/oauth/factory.rb +24 -18
  69. data/lib/aspera/oauth/jwt.rb +13 -1
  70. data/lib/aspera/oauth/url_json.rb +3 -3
  71. data/lib/aspera/oauth/web.rb +5 -3
  72. data/lib/aspera/persistency_folder.rb +2 -2
  73. data/lib/aspera/preview/file_types.rb +4 -3
  74. data/lib/aspera/preview/generator.rb +25 -12
  75. data/lib/aspera/preview/terminal.rb +10 -7
  76. data/lib/aspera/preview/utils.rb +11 -9
  77. data/lib/aspera/products/connect.rb +1 -1
  78. data/lib/aspera/products/desktop.rb +1 -1
  79. data/lib/aspera/products/other.rb +2 -2
  80. data/lib/aspera/products/transferd.rb +8 -6
  81. data/lib/aspera/proxy_auto_config.rb +1 -1
  82. data/lib/aspera/rest.rb +29 -22
  83. data/lib/aspera/rest_call_error.rb +1 -1
  84. data/lib/aspera/resumer.rb +1 -1
  85. data/lib/aspera/secret_hider.rb +46 -40
  86. data/lib/aspera/ssh.rb +13 -3
  87. data/lib/aspera/sync/args.schema.yaml +102 -0
  88. data/lib/aspera/sync/conf.schema.yaml +701 -0
  89. data/lib/aspera/sync/database.rb +83 -0
  90. data/lib/aspera/sync/operations.rb +296 -0
  91. data/lib/aspera/temp_file_manager.rb +3 -2
  92. data/lib/aspera/transfer/error.rb +1 -1
  93. data/lib/aspera/transfer/error_info.rb +1 -2
  94. data/lib/aspera/transfer/faux_file.rb +11 -10
  95. data/lib/aspera/transfer/parameters.rb +6 -5
  96. data/lib/aspera/transfer/spec.rb +15 -1
  97. data/lib/aspera/transfer/spec.schema.yaml +316 -293
  98. data/lib/aspera/transfer/spec_doc.rb +34 -16
  99. data/lib/aspera/transfer/uri.rb +5 -5
  100. data/lib/aspera/uri_reader.rb +14 -10
  101. data/lib/aspera/web_auth.rb +2 -2
  102. data/lib/aspera/web_server_simple.rb +2 -2
  103. data.tar.gz.sig +0 -0
  104. metadata +15 -13
  105. metadata.gz.sig +0 -0
  106. data/lib/aspera/transfer/async_conf.schema.yaml +0 -716
  107. data/lib/aspera/transfer/convert.rb +0 -29
  108. data/lib/aspera/transfer/sync.rb +0 -232
  109. data/lib/aspera/transfer/sync_instance.schema.yaml +0 -20
  110. data/lib/aspera/transfer/sync_session.schema.yaml +0 -86
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'aspera/assert'
4
- module Aspera
5
- module Transfer
6
- # concertion class for transfert spec values to CLI values (ascp)
7
- class Convert
8
- class << self
9
- # special encoding methods used in YAML (key: convert)
10
- def remove_hyphen(value); value.tr('-', ''); end
11
-
12
- # special encoding methods used in YAML (key: convert)
13
- def json64(value); Base64.strict_encode64(JSON.generate(value)); end
14
-
15
- # special encoding methods used in YAML (key: convert)
16
- def base64(value); Base64.strict_encode64(value); end
17
-
18
- # transform yes/no to true/false
19
- def yes_to_true(value)
20
- case value
21
- when 'yes' then return true
22
- when 'no' then return false
23
- else Aspera.error_unexpected_value(value){'only: yes or no: '}
24
- end
25
- end
26
- end
27
- end
28
- end
29
- end
@@ -1,232 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # cspell:words logdir bidi watchd cooloff asyncadmin
4
-
5
- require 'aspera/command_line_builder'
6
- require 'aspera/ascp/installation'
7
- require 'aspera/agent/direct'
8
- require 'aspera/transfer/convert'
9
- require 'aspera/log'
10
- require 'aspera/assert'
11
- require 'json'
12
- require 'base64'
13
- require 'open3'
14
- require 'English'
15
-
16
- module Aspera
17
- module Transfer
18
- # builds command line arg for async and execute it
19
- module Sync
20
- # sync direction
21
- DIRECTIONS = %i[push pull bidi].freeze
22
- # default direction for sync
23
- DEFAULT_DIRECTION = :push
24
- # JSON for async instance command line options
25
- INSTANCE_SCHEMA = CommandLineBuilder.read_schema(__FILE__, 'instance')
26
- SESSION_SCHEMA = CommandLineBuilder.read_schema(__FILE__, 'session')
27
-
28
- CMDLINE_PARAMS_KEYS = %w[instance sessions].freeze
29
-
30
- # Translation of transfer spec parameters to async v2 API (asyncs)
31
- # TODO: complete this list with all transfer spec parameters or include in async json schema with x- parameters
32
- TSPEC_TO_ASYNC_CONF = {
33
- 'remote_host' => 'remote.host',
34
- 'remote_user' => 'remote.user',
35
- 'remote_password' => 'remote.pass',
36
- 'sshfp' => 'remote.fingerprint',
37
- 'ssh_port' => 'remote.port',
38
- 'wss_port' => 'remote.ws_port',
39
- 'proxy' => 'remote.proxy',
40
- 'token' => 'remote.token',
41
- 'tags' => 'tags'
42
- }.freeze
43
-
44
- ASYNC_ADMIN_EXECUTABLE = 'asyncadmin'
45
-
46
- private_constant :INSTANCE_SCHEMA, :SESSION_SCHEMA, :CMDLINE_PARAMS_KEYS, :TSPEC_TO_ASYNC_CONF, :ASYNC_ADMIN_EXECUTABLE
47
-
48
- class << self
49
- # Set `remote_dir` in sync parameters based on transfer spec
50
- # @param params [Hash] sync parameters, old or new format
51
- # @param remote_dir_key [String] key to update in above hash
52
- # @param transfer_spec [Hash] transfer spec
53
- def update_remote_dir(sync_params, remote_dir_key, transfer_spec)
54
- if transfer_spec.dig(*%w[tags aspera node file_id])
55
- # in AoC, use gen4
56
- sync_params[remote_dir_key] = '/'
57
- elsif transfer_spec['cookie']&.start_with?('aspera.shares2')
58
- # TODO : something more generic, independent of Shares
59
- # in Shares, the actual folder on remote end is not always the same as the name of the share
60
- remote_key = transfer_spec['direction'].eql?('send') ? 'destination' : 'source'
61
- actual_remote = transfer_spec['paths']&.first&.[](remote_key)
62
- sync_params[remote_dir_key] = actual_remote if actual_remote
63
- end
64
- nil
65
- end
66
-
67
- def remote_certificates(remote)
68
- certificates_to_use = []
69
- # use web socket secure for session ?
70
- if remote['connect_mode']&.eql?('ws')
71
- remote.delete('port')
72
- remote.delete('fingerprint')
73
- # ignore cert for wss ?
74
- # if @options[:check_ignore_cb]&.call(remote['host'], remote['ws_port'])
75
- # wss_cert_file = TempFileManager.instance.new_file_path_global('wss_cert')
76
- # wss_url = "https://#{remote['host']}:#{remote['ws_port']}"
77
- # File.write(wss_cert_file, Rest.remote_certificate_chain(wss_url))
78
- # certificates_to_use.push(wss_cert_file)
79
- # end
80
- # set location for CA bundle to be the one of Ruby, see env var SSL_CERT_FILE / SSL_CERT_DIR
81
- # certificates_to_use.concat(@options[:trusted_certs]) if @options[:trusted_certs]
82
- else
83
- # remove unused parameter (avoid warning)
84
- remote.delete('ws_port')
85
- # add SSH bypass keys when authentication is token and no auth is provided
86
- if remote.key?('token') && !remote.key?('pass')
87
- certificates_to_use.concat(Ascp::Installation.instance.aspera_token_ssh_key_paths(:rsa))
88
- end
89
- end
90
- return certificates_to_use
91
- end
92
-
93
- # Get symbol of sync direction, defaulting to :push
94
- # @param params [Hash] sync parameters, old or new format
95
- # @return [Symbol] direction symbol, one of :push, :pull, :bidi
96
- def direction_sym(params)
97
- (params['direction'] || DEFAULT_DIRECTION).to_sym
98
- end
99
-
100
- # @param sync_params [Hash] sync parameters, old or new format
101
- # @param &block [nil, Proc] block to generate transfer spec, takes: direction (one of DIRECTIONS), local_dir, remote_dir
102
- def start(sync_params)
103
- Log.log.debug{Log.dump(:sync_params_initial, sync_params)}
104
- Aspera.assert_type(sync_params, Hash)
105
- Aspera.assert(%w[local sessions].any?{ |k| sync_params.key?(k)}){'At least one of `local` or `sessions` must be present in async parameters'}
106
- env_args = {
107
- args: [],
108
- env: {}
109
- }
110
- if sync_params.key?('local')
111
- # async native JSON format (conf option)
112
- Aspera.assert_type(sync_params['local'], Hash){'local'}
113
- remote = sync_params['remote']
114
- Aspera.assert_type(remote, Hash){'remote'}
115
- Aspera.assert_type(remote['path'], String){'remote path'}
116
- # get transfer spec if possible, and feed back to new structure
117
- if block_given?
118
- transfer_spec = yield(direction_sym(sync_params), sync_params['local']['path'], remote['path'])
119
- # translate transfer spec to async parameters
120
- TSPEC_TO_ASYNC_CONF.each do |ts_param, sy_path|
121
- next unless transfer_spec.key?(ts_param)
122
- sy_dig = sy_path.split('.')
123
- param = sy_dig.pop
124
- hash = sy_dig.empty? ? sync_params : sync_params[sy_dig.first]
125
- hash = sync_params[sy_dig.first] = {} if hash.nil?
126
- hash[param] = transfer_spec[ts_param]
127
- end
128
- update_remote_dir(remote, 'path', transfer_spec)
129
- end
130
- remote['connect_mode'] ||= transfer_spec['wss_enabled'] ? 'ws' : 'ssh'
131
- add_certificates = remote_certificates(remote)
132
- if !add_certificates.empty?
133
- remote['private_key_paths'] ||= []
134
- remote['private_key_paths'].concat(add_certificates)
135
- end
136
- # '--exclusive-mgmt-port=12345', '--arg-err-path=-',
137
- env_args[:args] = ["--conf64=#{Base64.strict_encode64(JSON.generate(sync_params))}"]
138
- Log.log.debug{Log.dump(:sync_conf, sync_params)}
139
- agent = Agent::Direct.new
140
- agent.start_and_monitor_process(session: {}, name: :async, **env_args)
141
- else
142
- # key 'sessions' is present
143
- # ascli JSON format (cmdline)
144
- raise StandardError, "Only 'sessions', and optionally 'instance' keys are allowed" unless
145
- sync_params.keys.push('instance').uniq.sort.eql?(CMDLINE_PARAMS_KEYS)
146
- Aspera.assert_type(sync_params['sessions'], Array)
147
- Aspera.assert_type(sync_params['sessions'].first, Hash)
148
- if block_given?
149
- sync_params['sessions'].each do |session|
150
- Aspera.assert_type(session['local_dir'], String){'local_dir'}
151
- Aspera.assert_type(session['remote_dir'], String){'remote_dir'}
152
- transfer_spec = yield(direction_sym(session), session['local_dir'], session['remote_dir'])
153
- SESSION_SCHEMA['properties'].each do |name, properties|
154
- if properties.key?('x-tspec')
155
- tspec_param = properties['x-tspec'].is_a?(TrueClass) ? name : properties['x-tspec'].to_s
156
- session[name] ||= transfer_spec[tspec_param] if transfer_spec.key?(tspec_param)
157
- end
158
- end
159
- session['private_key_paths'] = Ascp::Installation.instance.aspera_token_ssh_key_paths(:rsa) if transfer_spec.key?('token')
160
- update_remote_dir(session, 'remote_dir', transfer_spec)
161
- end
162
- end
163
- if sync_params.key?('instance')
164
- Aspera.assert_type(sync_params['instance'], Hash)
165
- instance_builder = CommandLineBuilder.new(sync_params['instance'], INSTANCE_SCHEMA, Convert)
166
- instance_builder.process_params
167
- instance_builder.add_env_args(env_args)
168
- end
169
- sync_params['sessions'].each do |session_params|
170
- Aspera.assert_type(session_params, Hash)
171
- Aspera.assert(session_params.key?('name')){'session must contain at least: name'}
172
- session_builder = CommandLineBuilder.new(session_params, SESSION_SCHEMA, Convert)
173
- session_builder.process_params
174
- session_builder.add_env_args(env_args)
175
- end
176
- Environment.secure_execute(exec: Ascp::Installation.instance.path(:async), **env_args)
177
- end
178
- return nil
179
- end
180
-
181
- def parse_status(stdout)
182
- Log.log.trace1{"stdout=#{stdout}"}
183
- result = {}
184
- ids = nil
185
- stdout.split("\n").each do |line|
186
- info = line.split(':', 2).map(&:lstrip)
187
- if info[1].eql?('')
188
- info[1] = ids = []
189
- elsif info[1].nil?
190
- ids.push(info[0])
191
- next
192
- end
193
- result[info[0]] = info[1]
194
- end
195
- return result
196
- end
197
-
198
- def admin_status(sync_params, session_name)
199
- arguments = ['--quiet']
200
- if sync_params.key?('local')
201
- Aspera.assert(!sync_params['name'].nil?){'Missing session name'}
202
- Aspera.assert(session_name.nil? || session_name.eql?(sync_params['name'])){'Session not found'}
203
- arguments.push("--name=#{sync_params['name']}")
204
- if sync_params.key?('local_db_dir')
205
- arguments.push("--local-db-dir=#{sync_params['local_db_dir']}")
206
- elsif sync_params.dig('local', 'path')
207
- arguments.push("--local-dir=#{sync_params.dig('local', 'path')}")
208
- else
209
- raise 'Missing either local_db_dir or local.path'
210
- end
211
- elsif sync_params.key?('sessions')
212
- session = session_name.nil? ? sync_params['sessions'].first : sync_params['sessions'].find{ |s| s['name'].eql?(session_name)}
213
- raise "Session #{session_name} not found in #{sync_params['sessions'].map{ |s| s['name']}.join(',')}" if session.nil?
214
- raise 'Missing session name' if session['name'].nil?
215
- arguments.push("--name=#{session['name']}")
216
- if session.key?('local_db_dir')
217
- arguments.push("--local-db-dir=#{session['local_db_dir']}")
218
- elsif session.key?('local_dir')
219
- arguments.push("--local-dir=#{session['local_dir']}")
220
- else
221
- raise 'Missing either local_db_dir or local_dir'
222
- end
223
- else
224
- raise 'At least one of `local` or `sessions` must be present in async parameters'
225
- end
226
- stdout = Environment.secure_capture(exec: ASYNC_ADMIN_EXECUTABLE, args: arguments)
227
- return parse_status(stdout)
228
- end
229
- end
230
- end
231
- end
232
- end
@@ -1,20 +0,0 @@
1
- $schema: https://json-schema.org/draft/2020-12/schema
2
- $id: https://github.com/IBM/aspera-cli/tree/main/lib/aspera/transfer/sync_instance.schema.yaml
3
- $comment: >-
4
- `x-` fields documented in command_line_builder.rb
5
- This spec is specific to ascli.
6
- The native async conf format is now preferred.
7
- title: SyncInstanceSpec
8
- description: Global parameters for async.
9
- type: object
10
- properties:
11
- alt_logdir:
12
- type: string
13
- watchd:
14
- type: string
15
- apply_local_docroot:
16
- x-cli-switch: true
17
- quiet:
18
- x-cli-switch: true
19
- ws_connect:
20
- x-cli-switch: true
@@ -1,86 +0,0 @@
1
- $schema: https://json-schema.org/draft/2020-12/schema
2
- $id: https://github.com/IBM/aspera-cli/tree/main/lib/aspera/transfer/sync_instance.schema.yaml
3
- $comment: >-
4
- `x-` fields documented in command_line_builder.rb
5
- This spec is specific to ascli.
6
- The native async conf format is now preferred.
7
- title: SyncSessionSpec
8
- description: Sync session parameters for async.
9
- type: object
10
- properties:
11
- name:
12
- type: string
13
- local_dir:
14
- type: string
15
- remote_dir:
16
- type: string
17
- local_db_dir:
18
- type: string
19
- remote_db_dir:
20
- type: string
21
- host:
22
- type: string
23
- x-tspec: remote_host
24
- user:
25
- type: string
26
- x-tspec: remote_user
27
- private_key_paths:
28
- type: array
29
- x-cli-option: "--private-key-path"
30
- direction:
31
- type: string
32
- checksum:
33
- type: string
34
- tags:
35
- type: object
36
- x-cli-option: "--tags64"
37
- x-cli-convert: json64
38
- x-tspec: true
39
- tcp_port:
40
- type: integer
41
- x-tspec: ssh_port
42
- rate_policy:
43
- type: string
44
- target_rate:
45
- type: string
46
- cooloff:
47
- type: integer
48
- pending_max:
49
- type: integer
50
- scan_intensity:
51
- type: string
52
- cipher:
53
- type: string
54
- x-cli-convert: remove_hyphen
55
- x-tspec: true
56
- transfer_threads:
57
- type: integer
58
- preserve_time:
59
- x-cli-switch: true
60
- x-tspec: preserve_times
61
- preserve_access_time:
62
- x-cli-switch: true
63
- preserve_modification_time:
64
- x-cli-switch: true
65
- preserve_uid:
66
- x-cli-switch: true
67
- x-tspec: preserve_file_owner_uid
68
- preserve_gid:
69
- x-cli-switch: true
70
- x-tspec: preserve_file_owner_gid
71
- create_dir:
72
- x-cli-switch: true
73
- x-tspec: true
74
- reset:
75
- x-cli-switch: true
76
- remote_password:
77
- x-cli-envvar: ASPERA_SCP_PASS
78
- x-tspec: true
79
- cookie:
80
- x-cli-envvar: ASPERA_SCP_COOKIE
81
- x-tspec: true
82
- token:
83
- x-cli-envvar: ASPERA_SCP_TOKEN
84
- x-tspec: true
85
- license:
86
- x-cli-envvar: ASPERA_SCP_LICENSE