aspera-cli 4.4.0 → 4.7.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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2095 -1503
  3. data/bin/ascli +2 -1
  4. data/bin/asession +4 -5
  5. data/docs/test_env.conf +3 -0
  6. data/examples/aoc.rb +4 -3
  7. data/examples/faspex4.rb +25 -25
  8. data/examples/proxy.pac +1 -1
  9. data/examples/transfer.rb +17 -17
  10. data/lib/aspera/aoc.rb +238 -185
  11. data/lib/aspera/ascmd.rb +93 -83
  12. data/lib/aspera/ats_api.rb +11 -10
  13. data/lib/aspera/cli/basic_auth_plugin.rb +13 -14
  14. data/lib/aspera/cli/extended_value.rb +42 -33
  15. data/lib/aspera/cli/formater.rb +142 -108
  16. data/lib/aspera/cli/info.rb +17 -0
  17. data/lib/aspera/cli/listener/line_dump.rb +3 -2
  18. data/lib/aspera/cli/listener/logger.rb +2 -1
  19. data/lib/aspera/cli/listener/progress.rb +16 -18
  20. data/lib/aspera/cli/listener/progress_multi.rb +18 -21
  21. data/lib/aspera/cli/main.rb +173 -149
  22. data/lib/aspera/cli/manager.rb +163 -168
  23. data/lib/aspera/cli/plugin.rb +43 -31
  24. data/lib/aspera/cli/plugins/alee.rb +6 -6
  25. data/lib/aspera/cli/plugins/aoc.rb +405 -370
  26. data/lib/aspera/cli/plugins/ats.rb +86 -79
  27. data/lib/aspera/cli/plugins/bss.rb +14 -16
  28. data/lib/aspera/cli/plugins/config.rb +580 -362
  29. data/lib/aspera/cli/plugins/console.rb +23 -19
  30. data/lib/aspera/cli/plugins/cos.rb +18 -18
  31. data/lib/aspera/cli/plugins/faspex.rb +201 -158
  32. data/lib/aspera/cli/plugins/faspex5.rb +80 -57
  33. data/lib/aspera/cli/plugins/node.rb +183 -166
  34. data/lib/aspera/cli/plugins/orchestrator.rb +71 -67
  35. data/lib/aspera/cli/plugins/preview.rb +92 -96
  36. data/lib/aspera/cli/plugins/server.rb +79 -75
  37. data/lib/aspera/cli/plugins/shares.rb +35 -19
  38. data/lib/aspera/cli/plugins/sync.rb +20 -22
  39. data/lib/aspera/cli/transfer_agent.rb +76 -113
  40. data/lib/aspera/cli/version.rb +2 -1
  41. data/lib/aspera/colors.rb +35 -27
  42. data/lib/aspera/command_line_builder.rb +48 -34
  43. data/lib/aspera/cos_node.rb +29 -21
  44. data/lib/aspera/data_repository.rb +3 -2
  45. data/lib/aspera/environment.rb +50 -45
  46. data/lib/aspera/fasp/{manager.rb → agent_base.rb} +28 -25
  47. data/lib/aspera/fasp/{connect.rb → agent_connect.rb} +52 -43
  48. data/lib/aspera/fasp/{local.rb → agent_direct.rb} +58 -72
  49. data/lib/aspera/fasp/{http_gw.rb → agent_httpgw.rb} +37 -43
  50. data/lib/aspera/fasp/{node.rb → agent_node.rb} +35 -16
  51. data/lib/aspera/fasp/agent_trsdk.rb +104 -0
  52. data/lib/aspera/fasp/error.rb +2 -1
  53. data/lib/aspera/fasp/error_info.rb +68 -52
  54. data/lib/aspera/fasp/installation.rb +152 -124
  55. data/lib/aspera/fasp/listener.rb +1 -0
  56. data/lib/aspera/fasp/parameters.rb +87 -92
  57. data/lib/aspera/fasp/parameters.yaml +305 -249
  58. data/lib/aspera/fasp/resume_policy.rb +11 -14
  59. data/lib/aspera/fasp/transfer_spec.rb +26 -0
  60. data/lib/aspera/fasp/uri.rb +22 -21
  61. data/lib/aspera/faspex_gw.rb +55 -89
  62. data/lib/aspera/hash_ext.rb +4 -3
  63. data/lib/aspera/id_generator.rb +8 -7
  64. data/lib/aspera/keychain/encrypted_hash.rb +121 -0
  65. data/lib/aspera/keychain/macos_security.rb +90 -0
  66. data/lib/aspera/log.rb +55 -37
  67. data/lib/aspera/nagios.rb +13 -12
  68. data/lib/aspera/node.rb +30 -25
  69. data/lib/aspera/oauth.rb +175 -226
  70. data/lib/aspera/open_application.rb +4 -3
  71. data/lib/aspera/persistency_action_once.rb +6 -6
  72. data/lib/aspera/persistency_folder.rb +5 -9
  73. data/lib/aspera/preview/file_types.rb +6 -5
  74. data/lib/aspera/preview/generator.rb +25 -24
  75. data/lib/aspera/preview/options.rb +16 -14
  76. data/lib/aspera/preview/utils.rb +98 -98
  77. data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
  78. data/lib/aspera/proxy_auto_config.rb +111 -20
  79. data/lib/aspera/rest.rb +154 -135
  80. data/lib/aspera/rest_call_error.rb +2 -2
  81. data/lib/aspera/rest_error_analyzer.rb +23 -25
  82. data/lib/aspera/rest_errors_aspera.rb +15 -14
  83. data/lib/aspera/ssh.rb +12 -10
  84. data/lib/aspera/sync.rb +42 -41
  85. data/lib/aspera/temp_file_manager.rb +18 -14
  86. data/lib/aspera/timer_limiter.rb +2 -1
  87. data/lib/aspera/uri_reader.rb +7 -5
  88. data/lib/aspera/web_auth.rb +79 -76
  89. metadata +116 -29
  90. data/docs/Makefile +0 -66
  91. data/docs/README.erb.md +0 -3973
  92. data/docs/README.md +0 -13
  93. data/docs/diagrams.txt +0 -49
  94. data/docs/doc_tools.rb +0 -58
  95. data/lib/aspera/api_detector.rb +0 -60
  96. data/lib/aspera/cli/plugins/shares2.rb +0 -114
  97. data/lib/aspera/secrets.rb +0 -20
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'aspera/log'
2
3
  require 'aspera/command_line_builder'
3
4
  require 'aspera/temp_file_manager'
@@ -5,75 +6,86 @@ require 'securerandom'
5
6
  require 'base64'
6
7
  require 'json'
7
8
  require 'yaml'
8
- require 'securerandom'
9
9
  require 'fileutils'
10
+ require 'openssl'
10
11
 
11
12
  module Aspera
12
13
  module Fasp
13
14
  # translate transfer specification to ascp parameter list
14
15
  class Parameters
15
- private
16
- # Temp folder for file lists, must contain only file lists
17
- # because of garbage collection takes any file there
18
- # this could be refined, as , for instance, on macos, temp folder is already user specific
19
- @@file_list_folder=TempFileManager.instance.new_file_path_global('asession_filelists')
20
- @@param_description_cache=nil
21
- # @return normaiwed description of transfer spec parameters
22
- def self.description
23
- return @@param_description_cache unless @@param_description_cache.nil?
24
- # config file in same folder with same name as this source
25
- @@param_description_cache=YAML.load_file("#{__FILE__[0..-3]}yaml")
26
- Aspera::CommandLineBuilder.normalize_description(@@param_description_cache)
27
- end
28
-
29
- # Agents shown in manual
16
+ # Agents shown in manual for parameters (sub list)
30
17
  SUPPORTED_AGENTS=[:direct,:node,:connect]
31
18
  # Short names of columns in manual
32
19
  SUPPORTED_AGENTS_SHORT=SUPPORTED_AGENTS.map{|a|a.to_s[0].to_sym}
33
20
 
34
- # @return a table suitable to display a manual
35
- def self.man_table
36
- result=[]
37
- description.keys.map do |k|
38
- i=description[k]
39
- param={name: k, type: [i[:accepted_types]].flatten.join(','),description: i[:desc]}
40
- SUPPORTED_AGENTS.each do |a|
41
- param[a.to_s[0].to_sym]=i[:context].nil? || i[:context].include?(a) ? 'Y' : ''
42
- end
43
- # only keep lines that are usable in supported agents
44
- next if SUPPORTED_AGENTS_SHORT.inject(true){|m,i|m and param[i].empty?}
45
- param[:cli]=case i[:cltype]
46
- when :envvar; 'env:'+i[:clvarname]
47
- when :opt_without_arg,:opt_with_arg; i[:option_switch]
48
- else ''
49
- end
50
- if i.has_key?(:enum)
51
- param[:description] << "\nAllowed values: #{i[:enum].join(', ')}"
21
+ class << self
22
+ # Temp folder for file lists, must contain only file lists
23
+ # because of garbage collection takes any file there
24
+ # this could be refined, as , for instance, on macos, temp folder is already user specific
25
+ @file_list_folder=TempFileManager.instance.new_file_path_global('asession_filelists')
26
+ @param_description_cache=nil
27
+ # @return normalized description of transfer spec parameters, direct from yaml
28
+ def description
29
+ return @param_description_cache unless @param_description_cache.nil?
30
+ # config file in same folder with same name as this source
31
+ @param_description_cache=YAML.load_file("#{__FILE__[0..-3]}yaml")
32
+ Aspera::CommandLineBuilder.normalize_description(@param_description_cache)
33
+ end
34
+
35
+ # @return a table suitable to display in manual
36
+ def man_table
37
+ result=[]
38
+ description.each do |k,i|
39
+ param={name: k, type: [i[:accepted_types]].flatten.join(','),description: i[:desc]}
40
+ SUPPORTED_AGENTS.each do |a|
41
+ param[a.to_s[0].to_sym]=i[:tragents].nil? || i[:tragents].include?(a) ? 'Y' : ''
42
+ end
43
+ # only keep lines that are usable in supported agents
44
+ next if SUPPORTED_AGENTS_SHORT.inject(true){|m,j|m && param[j].empty?}
45
+ param[:cli]=
46
+ case i[:cltype]
47
+ when :envvar then 'env:'+i[:clvarname]
48
+ when :opt_without_arg,:opt_with_arg then i[:clswitch]
49
+ else ''
50
+ end
51
+ if i.has_key?(:enum)
52
+ param[:description] += "\nAllowed values: #{i[:enum].join(', ')}"
53
+ end
54
+ result.push(param)
52
55
  end
53
- result.push(param)
56
+ return result
54
57
  end
55
- return result
56
- end
57
58
 
58
- # special encoding methods used in YAML (key: :encode)
59
- def self.encode_cipher(v)
60
- v.tr('-','')
61
- end
59
+ # special encoding methods used in YAML (key: :clconvert)
60
+ def clconv_remove_hyphen(v); v.tr('-',''); end
62
61
 
63
- # special encoding methods used in YAML (key: :encode)
64
- def self.encode_source_root(v)
65
- Base64.strict_encode64(v)
66
- end
62
+ # special encoding methods used in YAML (key: :clconvert)
63
+ def clconv_json64(v); Base64.strict_encode64(JSON.generate(v)); end
67
64
 
68
- # special encoding methods used in YAML (key: :encode)
69
- def self.encode_tags(v)
70
- Base64.strict_encode64(JSON.generate(v))
71
- end
65
+ # special encoding methods used in YAML (key: :clconvert)
66
+ def clconv_base64(v); Base64.strict_encode64(v); end
72
67
 
73
- def self.ts_has_file_list(ts)
74
- ts.has_key?('EX_ascp_args') and ts['EX_ascp_args'].is_a?(Array) and ['--file-list','--file-pair-list'].any?{|i|ts['EX_ascp_args'].include?(i)}
75
- end
68
+ def ts_has_file_list(ts)
69
+ ts.has_key?('EX_ascp_args') and ts['EX_ascp_args'].is_a?(Array) and ['--file-list','--file-pair-list'].any?{|i|ts['EX_ascp_args'].include?(i)}
70
+ end
76
71
 
72
+ def ts_to_env_args(transfer_spec,options)
73
+ return Parameters.new(transfer_spec,options).ascp_args()
74
+ end
75
+
76
+ # temp file list files are created here
77
+ def file_list_folder=(v)
78
+ @file_list_folder=v
79
+ return if @file_list_folder.nil?
80
+ FileUtils.mkdir_p(@file_list_folder)
81
+ TempFileManager.instance.cleanup_expired(@file_list_folder)
82
+ end
83
+
84
+ # static methods
85
+ attr_reader :file_list_folder
86
+ end # self
87
+
88
+ # @param options [Hash] key: :wss: bool
77
89
  def initialize(job_spec,options)
78
90
  @job_spec=job_spec
79
91
  @options=options
@@ -81,28 +93,26 @@ module Aspera
81
93
  Log.log.debug("agent options: #{@options}")
82
94
  end
83
95
 
84
- public
85
-
86
96
  # translate transfer spec to env vars and command line arguments for ascp
87
97
  # NOTE: parameters starting with "EX_" (extended) are not standard
88
- def ascp_args()
98
+ def ascp_args
89
99
  env_args={
90
- :args=>[],
91
- :env=>{},
92
- :ascp_version=>:ascp
100
+ args: [],
101
+ env: {},
102
+ ascp_version: :ascp
93
103
  }
94
104
  # some ssh credentials are required to avoid interactive password input
95
- if !@job_spec.has_key?('remote_password') and
96
- !@job_spec.has_key?('ssh_private_key') and
97
- !@job_spec.has_key?('EX_ssh_key_paths') then
98
- raise Fasp::Error.new('required: password or ssh key (value or path)')
105
+ if !@job_spec.has_key?('remote_password') &&
106
+ !@job_spec.has_key?('ssh_private_key') &&
107
+ !@job_spec.has_key?('EX_ssh_key_paths')
108
+ raise Fasp::Error, 'required: password or ssh key (value or path)'
99
109
  end
100
110
 
101
111
  # special cases
102
- @job_spec.delete('source_root') if @job_spec.has_key?('source_root') and @job_spec['source_root'].empty?
112
+ @job_spec.delete('source_root') if @job_spec.has_key?('source_root') && @job_spec['source_root'].empty?
103
113
 
104
114
  # use web socket session initiation ?
105
- if @builder.process_param('wss_enabled',:get_value) and ( @options[:wss] or !@job_spec.has_key?('fasp_port') )
115
+ if @builder.process_param('wss_enabled',:get_value) && (@options[:wss] || !@job_spec.has_key?('fasp_port'))
106
116
  # by default use web socket session if available, unless removed by user
107
117
  @builder.add_command_line_options(['--ws-connect'])
108
118
  # TODO: option to give order ssh,ws (legacy http is implied bu ssh)
@@ -111,6 +121,9 @@ module Aspera
111
121
  @job_spec.delete('fasp_port')
112
122
  @job_spec.delete('EX_ssh_key_paths')
113
123
  @job_spec.delete('sshfp')
124
+ # set location for CA bundle to be the one of Ruby, see env var SSL_CERT_FILE / SSL_CERT_DIR
125
+ @job_spec['EX_ssh_key_paths']=[OpenSSL::X509::DEFAULT_CERT_FILE]
126
+ Log.log.debug('CA certs: EX_ssh_key_paths <- DEFAULT_CERT_FILE from openssl')
114
127
  else
115
128
  # remove unused parameter (avoid warning)
116
129
  @job_spec.delete('wss_port')
@@ -131,17 +144,17 @@ module Aspera
131
144
  file_list_provided=self.class.ts_has_file_list(@job_spec)
132
145
  @builder.params_definition['paths'][:mandatory]=!@job_spec.has_key?('keepalive') and !file_list_provided
133
146
  paths_array=@builder.process_param('paths',:get_value)
134
- if file_list_provided and ! paths_array.nil?
135
- Log.log.warn("file list provided both in transfer spec and ascp file list. Keeping file list only.")
147
+ if file_list_provided && !paths_array.nil?
148
+ Log.log.warn('file list provided both in transfer spec and ascp file list. Keeping file list only.')
136
149
  paths_array=nil
137
150
  end
138
- if ! paths_array.nil?
151
+ if !paths_array.nil?
139
152
  # it's an array
140
- raise "paths is empty in transfer spec" if paths_array.empty?
153
+ raise 'paths is empty in transfer spec' if paths_array.empty?
141
154
  # use file list if there is storage defined for it.
142
- if @@file_list_folder.nil?
155
+ if self.class.file_list_folder.nil?
143
156
  # not safe for special characters ? (maybe not, depends on OS)
144
- Log.log.debug("placing source file list on command line (no file list file)")
157
+ Log.log.debug('placing source file list on command line (no file list file)')
145
158
  @builder.add_command_line_options(paths_array.map{|i|i['source']})
146
159
  else
147
160
  file_list_file=@builder.process_param('EX_file_list',:get_value)
@@ -157,14 +170,14 @@ module Aspera
157
170
  # TODO: well, we test only the first one, but anyway it shall be consistent
158
171
  if paths_array.first.has_key?('destination')
159
172
  option='--file-pair-list'
160
- lines=paths_array.inject([]){|m,e|m.push(e['source'],e['destination']);m}
173
+ lines=paths_array.each_with_object([]){|e,m|m.push(e['source'],e['destination']);}
161
174
  else
162
175
  option='--file-list'
163
176
  lines=paths_array.map{|i|i['source']}
164
177
  end
165
- file_list_file=Aspera::TempFileManager.instance.new_file_path_in_folder(@@file_list_folder)
166
- File.open(file_list_file, 'w+'){|f|f.puts(lines)}
167
- Log.log.debug("#{option}=\n#{File.read(file_list_file)}".red)
178
+ file_list_file=Aspera::TempFileManager.instance.new_file_path_in_folder(self.class.file_list_folder)
179
+ File.write(file_list_file, lines.join("\n"))
180
+ Log.log.debug{"#{option}=\n#{File.read(file_list_file)}".red}
168
181
  end
169
182
  end
170
183
  @builder.add_command_line_options(["#{option}=#{file_list_file}"])
@@ -183,24 +196,6 @@ module Aspera
183
196
 
184
197
  return env_args
185
198
  end
186
-
187
- # temp file list files are created here
188
- def self.file_list_folder=(v)
189
- @@file_list_folder=v
190
- if !@@file_list_folder.nil?
191
- FileUtils.mkdir_p(@@file_list_folder)
192
- TempFileManager.instance.cleanup_expired(@@file_list_folder)
193
- end
194
- end
195
-
196
- # static methods
197
- class << self
198
- def file_list_folder; @@file_list_folder;end
199
-
200
- def ts_to_env_args(transfer_spec,options)
201
- return Parameters.new(transfer_spec,options).ascp_args()
202
- end
203
- end
204
199
  end # Parameters
205
200
  end
206
201
  end