aspera-cli 4.22.0 → 4.24.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 (114) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +405 -364
  4. data/CONTRIBUTING.md +86 -29
  5. data/README.md +1856 -961
  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 +53 -43
  16. data/lib/aspera/api/cos_node.rb +7 -5
  17. data/lib/aspera/api/httpgw.rb +23 -22
  18. data/lib/aspera/api/node.rb +104 -22
  19. data/lib/aspera/ascmd.rb +35 -21
  20. data/lib/aspera/ascp/installation.rb +43 -43
  21. data/lib/aspera/ascp/management.rb +5 -4
  22. data/lib/aspera/assert.rb +55 -24
  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 +38 -4
  28. data/lib/aspera/cli/main.rb +139 -108
  29. data/lib/aspera/cli/manager.rb +51 -31
  30. data/lib/aspera/cli/plugin.rb +149 -78
  31. data/lib/aspera/cli/plugin_factory.rb +2 -2
  32. data/lib/aspera/cli/plugins/aoc.rb +217 -88
  33. data/lib/aspera/cli/plugins/ats.rb +15 -13
  34. data/lib/aspera/cli/plugins/config.rb +105 -227
  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 +162 -163
  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 +233 -247
  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 +29 -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 +55 -58
  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 +160 -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/data_repository.rb +1 -0
  55. data/lib/aspera/environment.rb +144 -100
  56. data/lib/aspera/faspex_gw.rb +1 -1
  57. data/lib/aspera/faspex_postproc.rb +3 -2
  58. data/lib/aspera/hash_ext.rb +1 -1
  59. data/lib/aspera/id_generator.rb +10 -10
  60. data/lib/aspera/keychain/base.rb +18 -0
  61. data/lib/aspera/keychain/encrypted_hash.rb +6 -12
  62. data/lib/aspera/keychain/factory.rb +9 -3
  63. data/lib/aspera/keychain/hashicorp_vault.rb +9 -6
  64. data/lib/aspera/keychain/macos_security.rb +13 -13
  65. data/lib/aspera/log.rb +70 -20
  66. data/lib/aspera/nagios.rb +5 -6
  67. data/lib/aspera/node_simulator.rb +12 -7
  68. data/lib/aspera/oauth/base.rb +6 -2
  69. data/lib/aspera/oauth/factory.rb +25 -18
  70. data/lib/aspera/oauth/jwt.rb +13 -1
  71. data/lib/aspera/oauth/url_json.rb +3 -3
  72. data/lib/aspera/oauth/web.rb +5 -3
  73. data/lib/aspera/persistency_folder.rb +2 -2
  74. data/lib/aspera/preview/file_types.rb +43 -35
  75. data/lib/aspera/preview/generator.rb +26 -13
  76. data/lib/aspera/preview/terminal.rb +10 -7
  77. data/lib/aspera/preview/utils.rb +11 -9
  78. data/lib/aspera/products/connect.rb +2 -1
  79. data/lib/aspera/products/desktop.rb +1 -1
  80. data/lib/aspera/products/other.rb +2 -2
  81. data/lib/aspera/products/transferd.rb +8 -6
  82. data/lib/aspera/proxy_auto_config.rb +1 -1
  83. data/lib/aspera/rest.rb +46 -28
  84. data/lib/aspera/rest_call_error.rb +1 -1
  85. data/lib/aspera/rest_error_analyzer.rb +1 -0
  86. data/lib/aspera/resumer.rb +1 -1
  87. data/lib/aspera/secret_hider.rb +46 -40
  88. data/lib/aspera/ssh.rb +14 -4
  89. data/lib/aspera/sync/args.schema.yaml +102 -0
  90. data/lib/aspera/sync/conf.schema.yaml +701 -0
  91. data/lib/aspera/sync/database.rb +83 -0
  92. data/lib/aspera/{transfer/sync.rb → sync/operations.rb} +145 -68
  93. data/lib/aspera/temp_file_manager.rb +4 -2
  94. data/lib/aspera/timer_limiter.rb +7 -5
  95. data/lib/aspera/transfer/error.rb +1 -1
  96. data/lib/aspera/transfer/error_info.rb +1 -2
  97. data/lib/aspera/transfer/faux_file.rb +11 -10
  98. data/lib/aspera/transfer/parameters.rb +6 -5
  99. data/lib/aspera/transfer/spec.rb +15 -1
  100. data/lib/aspera/transfer/spec.schema.yaml +316 -293
  101. data/lib/aspera/transfer/spec_doc.rb +34 -16
  102. data/lib/aspera/transfer/uri.rb +5 -5
  103. data/lib/aspera/uri_reader.rb +14 -10
  104. data/lib/aspera/web_auth.rb +2 -2
  105. data/lib/aspera/web_server_simple.rb +2 -2
  106. data.tar.gz.sig +0 -0
  107. metadata +15 -15
  108. metadata.gz.sig +0 -0
  109. data/examples/dascli +0 -30
  110. data/examples/get_proto_file.rb +0 -8
  111. data/examples/proxy.pac +0 -60
  112. data/lib/aspera/transfer/convert.rb +0 -29
  113. data/lib/aspera/transfer/sync_instance.schema.yaml +0 -13
  114. data/lib/aspera/transfer/sync_session.schema.yaml +0 -79
data/lib/aspera/assert.rb CHANGED
@@ -1,55 +1,86 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Aspera
4
- class InternalError < StandardError
4
+ # Generic error in gem
5
+ class Error < StandardError
5
6
  end
6
7
 
7
- class AssertError < StandardError
8
+ # Error that shall not happen, else it's a bug
9
+ class InternalError < Error
10
+ end
11
+
12
+ # An expected condition was not met
13
+ class AssertError < Error
8
14
  end
9
15
  class << self
10
- # the block is executed in the context of the Aspera module
11
- def assert(assertion, info = nil, exception_class: AssertError)
16
+ # Replace `raise`, allows sending exception, or just error log, when type is `:error`
17
+ # @param type [Exception,Symbol] Send to log if symbol, else raise exception
18
+ # @param message [String] Message for error.
19
+ def report_error(type, message)
20
+ if type.is_a?(Symbol)
21
+ Log.log.send(type, message)
22
+ else
23
+ raise type, message
24
+ end
25
+ end
26
+
27
+ # Assert that a condition is true, else raise exception
28
+ # @param assertion [Bool] Must be true
29
+ # @param info [String,nil] Fixed message in case assert fails, else use `block`
30
+ # @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
31
+ # @param block [Proc] Produces a string that desribes the problem for complex messages
32
+ # The block is executed in the context of the Aspera module
33
+ def assert(assertion, info = nil, type: AssertError)
12
34
  raise InternalError, 'bad assert: both info and block given' unless info.nil? || !block_given?
13
35
  return if assertion
14
36
  message = 'assertion failed'
15
37
  info = yield if block_given?
16
38
  message = "#{message}: #{info}" if info
17
39
  message = "#{message}: #{caller.find{ |call| !call.start_with?(__FILE__)}}"
18
- raise exception_class, message
40
+ report_error(type, message)
19
41
  end
20
42
 
21
- # assert that value has the given type
22
- # @param value [Object] the value to check
23
- # @param type [Class] the expected type
24
- def assert_type(value, type, exception_class: AssertError)
25
- assert(value.is_a?(type), exception_class: exception_class){"#{block_given? ? "#{yield}: " : nil}expecting #{type}, but have #{value.inspect}"}
43
+ # Assert that value has the given type
44
+ # @param value [Object] The value to check
45
+ # @param classes [Class, Array] The expected type(s)
46
+ # @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
47
+ # @param block [Proc] Additional description in front of message
48
+ def assert_type(value, *classes, type: AssertError)
49
+ assert(classes.any?{ |k| value.is_a?(k)}, type: type){"#{"#{yield}: " if block_given?}expecting #{classes.join(', ')}, but have #{value.inspect}"}
26
50
  end
27
51
 
28
- # assert that value is one of the given values
29
- # @param value value to check
30
- # @param values accepted values
31
- # @param exception_class exception in case of no match
32
- def assert_values(value, values, exception_class: AssertError)
33
- assert(values.include?(value), exception_class: exception_class) do
52
+ # Assert that value is one of the given values
53
+ # @param value [any] value to check
54
+ # @param values [Array] accepted values
55
+ # @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
56
+ # @param block [Proc] Additional description in front of message
57
+ def assert_values(value, values, type: AssertError)
58
+ assert(values.include?(value), type: type) do
34
59
  val_list = values.inspect
35
60
  val_list = "one of #{val_list}" if values.is_a?(Array)
36
- "#{block_given? ? "#{yield}: " : nil}expecting #{val_list}, but have #{value.inspect}"
61
+ "#{"#{yield}: " if block_given?}expecting #{val_list}, but have #{value.inspect}"
37
62
  end
38
63
  end
39
64
 
40
- # the line with this shall never be reached
65
+ # The value is not one of the expected values
66
+ # @param value [any] The wrong value
67
+ # @param type [Exception,Symbol] Exception to raise, or Symbol for Log.log
68
+ # @param block [Proc] Additional description in front of message
69
+ def error_unexpected_value(value, type: InternalError)
70
+ report_error(type, "#{"#{yield}: " if block_given?}unexpected value: #{value.inspect}")
71
+ end
72
+
73
+ # The line with this shall never be reached
41
74
  def error_unreachable_line
42
75
  raise InternalError, "unreachable line reached: #{caller(2..2).first}"
43
76
  end
44
77
 
45
- # The value is not one of the expected values
46
- # @param value the wrong value
47
- # @param exception_class exception to raise
48
- # @param block additional description in front
49
- def error_unexpected_value(value, exception_class: InternalError)
50
- raise exception_class, "#{block_given? ? "#{yield}: " : nil}unexpected value: #{value.inspect}"
78
+ # Not implemented error
79
+ def error_not_implemented
80
+ raise Error, 'Feature not yet implemented'
51
81
  end
52
82
 
83
+ # Use in superclass to require the given method in subclass.
53
84
  def require_method!(name)
54
85
  define_method(name) do |*_args|
55
86
  raise NotImplementedError, "#{self.class} must implement the #{name} method"
@@ -9,20 +9,20 @@ module Aspera
9
9
  class BasicAuthPlugin < Cli::Plugin
10
10
  class << self
11
11
  def declare_options(options)
12
- options.declare(:url, 'URL of application, e.g. https://faspex.example.com/aspera/faspex')
13
- options.declare(:username, "User's name to log in")
12
+ options.declare(:url, 'URL of application, e.g. https://app.example.com/aspera/app')
13
+ options.declare(:username, "User's identifier")
14
14
  options.declare(:password, "User's password")
15
15
  options.parse_options!
16
16
  end
17
17
  end
18
18
 
19
- def initialize(basic_options: true, **env)
20
- super(**env)
19
+ def initialize(context:, basic_options: true)
20
+ super(context: context)
21
21
  BasicAuthPlugin.declare_options(options) if basic_options
22
22
  end
23
23
 
24
24
  # returns a Rest object with basic auth
25
- def basic_auth_params(subpath=nil)
25
+ def basic_auth_params(subpath = nil)
26
26
  api_url = options.get_option(:url, mandatory: true)
27
27
  api_url = "#{api_url}/#{subpath}" unless subpath.nil?
28
28
  return {
@@ -31,10 +31,11 @@ module Aspera
31
31
  type: :basic,
32
32
  username: options.get_option(:username, mandatory: true),
33
33
  password: options.get_option(:password, mandatory: true)
34
- }}
34
+ }
35
+ }
35
36
  end
36
37
 
37
- def basic_auth_api(subpath=nil)
38
+ def basic_auth_api(subpath = nil)
38
39
  return Rest.new(**basic_auth_params(subpath))
39
40
  end
40
41
  end
@@ -4,7 +4,7 @@ module Aspera
4
4
  module Cli
5
5
  # CLI base exception
6
6
  class Error < StandardError; end
7
- # raised when an unexpected argument is provided
7
+ # Raised when an unexpected argument is provided.
8
8
  class BadArgument < Error; end
9
9
  class NoSuchElement < Error; end
10
10
 
@@ -41,12 +41,12 @@ module Aspera
41
41
  hash_array.push(col_titles.zip(values).to_h)
42
42
  end
43
43
  end
44
- Log.log.warn('Titled CSV file without any line') if hash_array.empty?
44
+ Log.log.warn('Titled CSV file without any row') if hash_array.empty?
45
45
  return hash_array
46
46
  end
47
47
 
48
- def assert_no_value(v, what)
49
- raise "no value allowed for extended value type: #{what}" unless v.empty?
48
+ def assert_no_value(value, what)
49
+ raise "no value allowed for extended value type: #{what}" unless value.empty?
50
50
  end
51
51
  end
52
52
 
@@ -56,25 +56,25 @@ module Aspera
56
56
  # base handlers
57
57
  # other handlers can be set using set_handler, e.g. `preset` is reader in config plugin
58
58
  @handlers = {
59
- val: lambda{ |v| v},
60
- base64: lambda{ |v| Base64.decode64(v)},
61
- csvt: lambda{ |v| ExtendedValue.decode_csvt(v)},
62
- env: lambda{ |v| ENV.fetch(v, nil)},
63
- file: lambda{ |v| File.read(File.expand_path(v))},
64
- uri: lambda{ |v| UriReader.read(v)},
65
- json: lambda{ |v| JSON_parse(v)},
66
- lines: lambda{ |v| v.split("\n")},
67
- list: lambda{ |v| v[1..-1].split(v[0])},
68
- none: lambda{ |v| ExtendedValue.assert_no_value(v, :none); nil}, # rubocop:disable Style/Semicolon
69
- path: lambda{ |v| File.expand_path(v)},
70
- re: lambda{ |v| Regexp.new(v, Regexp::MULTILINE)},
71
- ruby: lambda{ |v| Environment.secure_eval(v, __FILE__, __LINE__)},
72
- secret: lambda{ |v| prompt = v.empty? ? 'secret' : v; $stdin.getpass("#{prompt}> ")}, # rubocop:disable Style/Semicolon
73
- stdin: lambda{ |v| ExtendedValue.assert_no_value(v, :stdin); $stdin.read}, # rubocop:disable Style/Semicolon
74
- stdbin: lambda{ |v| ExtendedValue.assert_no_value(v, :stdbin); $stdin.binmode.read}, # rubocop:disable Style/Semicolon
75
- yaml: lambda{ |v| YAML.load(v)},
76
- zlib: lambda{ |v| Zlib::Inflate.inflate(v)},
77
- extend: lambda{ |v| ExtendedValue.instance.evaluate_all(v)}
59
+ val: lambda{ |i| i},
60
+ base64: lambda{ |i| Base64.decode64(i)},
61
+ csvt: lambda{ |i| ExtendedValue.decode_csvt(i)},
62
+ env: lambda{ |i| ENV.fetch(i, nil)},
63
+ file: lambda{ |i| File.read(File.expand_path(i))},
64
+ uri: lambda{ |i| UriReader.read(i)},
65
+ json: lambda{ |i| JSON_parse(i)},
66
+ lines: lambda{ |i| i.split("\n")},
67
+ list: lambda{ |i| i[1..-1].split(i[0])},
68
+ none: lambda{ |i| ExtendedValue.assert_no_value(i, :none); nil}, # rubocop:disable Style/Semicolon
69
+ path: lambda{ |i| File.expand_path(i)},
70
+ re: lambda{ |i| Regexp.new(i, Regexp::MULTILINE)},
71
+ ruby: lambda{ |i| Environment.secure_eval(i, __FILE__, __LINE__)},
72
+ secret: lambda{ |i| prompt = i.empty? ? 'secret' : i; $stdin.getpass("#{prompt}> ")}, # rubocop:disable Style/Semicolon
73
+ stdin: lambda{ |i| ExtendedValue.assert_no_value(i, :stdin); $stdin.read}, # rubocop:disable Style/Semicolon
74
+ stdbin: lambda{ |i| ExtendedValue.assert_no_value(i, :stdbin); $stdin.binmode.read}, # rubocop:disable Style/Semicolon
75
+ yaml: lambda{ |i| YAML.load(i)},
76
+ zlib: lambda{ |i| Zlib::Inflate.inflate(i)},
77
+ extend: lambda{ |i| ExtendedValue.instance.evaluate_all(i)}
78
78
  }
79
79
  @default_decoder = nil
80
80
  end
@@ -85,14 +85,15 @@ module Aspera
85
85
  end
86
86
 
87
87
  # JSON Parser, with more information on error location
88
- def JSON_parse(v)
89
- JSON.parse(v)
88
+ # :reek:UncommunicativeMethodName
89
+ def JSON_parse(value) # rubocop:disable Naming/MethodName
90
+ JSON.parse(value)
90
91
  rescue JSON::ParserError => e
91
92
  m = /at line (\d+) column (\d+)/.match(e.message)
92
93
  raise if m.nil?
93
94
  line = m[1].to_i - 1
94
95
  column = m[2].to_i - 1
95
- lines = v.lines
96
+ lines = value.lines
96
97
  raise if line >= lines.size
97
98
  error_line = lines[line].chomp
98
99
  context_col_beg = [column - 10, 0].max
@@ -145,9 +146,7 @@ module Aspera
145
146
  # parse string value as extended value
146
147
  # use default decoder if none is specified
147
148
  def evaluate_with_default(value)
148
- if value.is_a?(String) && value.match(/^#{handler_regex_string}.*$/).nil? && !@default_decoder.nil?
149
- value = [MARKER_START, @default_decoder, MARKER_END, value].join
150
- end
149
+ value = [MARKER_START, @default_decoder, MARKER_END, value].join if value.is_a?(String) && value.match(/^#{handler_regex_string}.*$/).nil? && !@default_decoder.nil?
151
150
  return evaluate(value)
152
151
  end
153
152
 
@@ -157,7 +156,7 @@ module Aspera
157
156
  while (m = value.match(regex))
158
157
  sub_value = "@#{m[2]}:#{m[3]}"
159
158
  Log.log.debug{"evaluating #{sub_value}"}
160
- value = m[1] + evaluate(sub_value) + m[4]
159
+ value = "#{m[1]}#{evaluate(sub_value)}#{m[4]}"
161
160
  end
162
161
  return value
163
162
  end