aspera-cli 4.7.0 → 4.8.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 (94) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -0
  3. data/README.md +844 -861
  4. data/bin/ascli +20 -1
  5. data/bin/asession +37 -34
  6. data/docs/test_env.conf +11 -3
  7. data/examples/aoc.rb +13 -12
  8. data/examples/dascli +26 -0
  9. data/examples/faspex4.rb +34 -29
  10. data/examples/transfer.rb +30 -29
  11. data/lib/aspera/aoc.rb +151 -143
  12. data/lib/aspera/ascmd.rb +56 -45
  13. data/lib/aspera/ats_api.rb +6 -5
  14. data/lib/aspera/cli/basic_auth_plugin.rb +18 -16
  15. data/lib/aspera/cli/extended_value.rb +32 -30
  16. data/lib/aspera/cli/formater.rb +103 -111
  17. data/lib/aspera/cli/info.rb +2 -1
  18. data/lib/aspera/cli/listener/line_dump.rb +1 -0
  19. data/lib/aspera/cli/listener/logger.rb +1 -0
  20. data/lib/aspera/cli/listener/progress.rb +13 -12
  21. data/lib/aspera/cli/listener/progress_multi.rb +21 -20
  22. data/lib/aspera/cli/main.rb +106 -89
  23. data/lib/aspera/cli/manager.rb +96 -85
  24. data/lib/aspera/cli/plugin.rb +50 -32
  25. data/lib/aspera/cli/plugins/alee.rb +6 -5
  26. data/lib/aspera/cli/plugins/aoc.rb +521 -426
  27. data/lib/aspera/cli/plugins/ats.rb +84 -83
  28. data/lib/aspera/cli/plugins/bss.rb +30 -27
  29. data/lib/aspera/cli/plugins/config.rb +483 -397
  30. data/lib/aspera/cli/plugins/console.rb +17 -15
  31. data/lib/aspera/cli/plugins/cos.rb +26 -35
  32. data/lib/aspera/cli/plugins/faspex.rb +201 -168
  33. data/lib/aspera/cli/plugins/faspex5.rb +109 -74
  34. data/lib/aspera/cli/plugins/node.rb +378 -189
  35. data/lib/aspera/cli/plugins/orchestrator.rb +71 -65
  36. data/lib/aspera/cli/plugins/preview.rb +131 -122
  37. data/lib/aspera/cli/plugins/server.rb +94 -93
  38. data/lib/aspera/cli/plugins/shares.rb +42 -28
  39. data/lib/aspera/cli/plugins/sync.rb +15 -14
  40. data/lib/aspera/cli/transfer_agent.rb +56 -52
  41. data/lib/aspera/cli/version.rb +2 -1
  42. data/lib/aspera/colors.rb +29 -28
  43. data/lib/aspera/command_line_builder.rb +50 -43
  44. data/lib/aspera/cos_node.rb +64 -38
  45. data/lib/aspera/data_repository.rb +1 -0
  46. data/lib/aspera/environment.rb +18 -8
  47. data/lib/aspera/fasp/agent_base.rb +26 -23
  48. data/lib/aspera/fasp/agent_connect.rb +35 -30
  49. data/lib/aspera/fasp/agent_direct.rb +68 -60
  50. data/lib/aspera/fasp/agent_httpgw.rb +71 -64
  51. data/lib/aspera/fasp/agent_node.rb +24 -23
  52. data/lib/aspera/fasp/agent_trsdk.rb +19 -20
  53. data/lib/aspera/fasp/error.rb +2 -1
  54. data/lib/aspera/fasp/error_info.rb +79 -68
  55. data/lib/aspera/fasp/installation.rb +122 -114
  56. data/lib/aspera/fasp/listener.rb +1 -0
  57. data/lib/aspera/fasp/parameters.rb +44 -41
  58. data/lib/aspera/fasp/resume_policy.rb +14 -11
  59. data/lib/aspera/fasp/transfer_spec.rb +6 -5
  60. data/lib/aspera/fasp/uri.rb +25 -24
  61. data/lib/aspera/faspex_gw.rb +83 -72
  62. data/lib/aspera/hash_ext.rb +10 -12
  63. data/lib/aspera/id_generator.rb +8 -7
  64. data/lib/aspera/keychain/encrypted_hash.rb +60 -45
  65. data/lib/aspera/keychain/macos_security.rb +26 -24
  66. data/lib/aspera/log.rb +34 -38
  67. data/lib/aspera/nagios.rb +14 -13
  68. data/lib/aspera/node.rb +19 -19
  69. data/lib/aspera/oauth.rb +121 -101
  70. data/lib/aspera/open_application.rb +6 -5
  71. data/lib/aspera/persistency_action_once.rb +9 -8
  72. data/lib/aspera/persistency_folder.rb +10 -9
  73. data/lib/aspera/preview/file_types.rb +261 -266
  74. data/lib/aspera/preview/generator.rb +74 -73
  75. data/lib/aspera/preview/image_error.png +0 -0
  76. data/lib/aspera/preview/options.rb +7 -6
  77. data/lib/aspera/preview/utils.rb +30 -33
  78. data/lib/aspera/preview/video_error.png +0 -0
  79. data/lib/aspera/proxy_auto_config.rb +25 -23
  80. data/lib/aspera/rest.rb +73 -74
  81. data/lib/aspera/rest_call_error.rb +1 -0
  82. data/lib/aspera/rest_error_analyzer.rb +11 -9
  83. data/lib/aspera/rest_errors_aspera.rb +5 -4
  84. data/lib/aspera/secret_hider.rb +68 -0
  85. data/lib/aspera/ssh.rb +12 -10
  86. data/lib/aspera/sync.rb +49 -47
  87. data/lib/aspera/temp_file_manager.rb +7 -5
  88. data/lib/aspera/timer_limiter.rb +9 -8
  89. data/lib/aspera/uri_reader.rb +11 -14
  90. data/lib/aspera/web_auth.rb +17 -15
  91. data.tar.gz.sig +0 -0
  92. metadata +117 -34
  93. metadata.gz.sig +2 -0
  94. data/bin/dascli +0 -13
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'aspera/colors'
3
4
  require 'aspera/log'
4
5
  require 'aspera/cli/extended_value'
@@ -15,7 +16,7 @@ module Aspera
15
16
 
16
17
  class CliNoSuchId < CliError
17
18
  def initialize(res_type,res_id)
18
- msg="No such #{res_type} identifier: #{res_id}"
19
+ msg = "No such #{res_type} identifier: #{res_id}"
19
20
  super(msg)
20
21
  end
21
22
  end
@@ -25,8 +26,8 @@ module Aspera
25
26
  #attr_accessor :object
26
27
  #attr_accessor :attr_symb
27
28
  def initialize(object,attr_symb)
28
- @object=object
29
- @attr_symb=attr_symb
29
+ @object = object
30
+ @attr_symb = attr_symb
30
31
  end
31
32
 
32
33
  def value
@@ -43,15 +44,15 @@ module Aspera
43
44
  # resolves on extended value syntax
44
45
  class Manager
45
46
  # boolean options are set to true/false from the following values
46
- TRUE_VALUES=[:yes,true].freeze
47
- BOOLEAN_VALUES=[TRUE_VALUES,:no,false].flatten.freeze
48
- BOOLEAN_SIMPLE=[:yes,:no].freeze
47
+ TRUE_VALUES = [:yes,true].freeze
48
+ BOOLEAN_VALUES = [TRUE_VALUES,:no,false].flatten.freeze
49
+ BOOLEAN_SIMPLE = %i[yes no].freeze
49
50
  # option name separator on command line
50
- OPTION_SEP_LINE='-'
51
+ OPTION_SEP_LINE = '-'
51
52
  # option name separator in code (symbol)
52
- OPTION_SEP_NAME='_'
53
+ OPTION_SEP_NAME = '_'
53
54
 
54
- private_constant :TRUE_VALUES,:BOOLEAN_VALUES,:BOOLEAN_SIMPLE,:OPTION_SEP_LINE,:OPTION_SEP_NAME
55
+ private_constant :TRUE_VALUES,:BOOLEAN_VALUES,:OPTION_SEP_LINE,:OPTION_SEP_NAME
55
56
 
56
57
  class << self
57
58
  def enum_to_bool(enum)
@@ -66,9 +67,9 @@ module Aspera
66
67
  # find shortened string value in allowed symbol list
67
68
  def get_from_list(shortval,descr,allowed_values)
68
69
  # we accept shortcuts
69
- matching_exact=allowed_values.select{|i| i.to_s.eql?(shortval)}
70
+ matching_exact = allowed_values.select{|i| i.to_s.eql?(shortval)}
70
71
  return matching_exact.first if matching_exact.length == 1
71
- matching=allowed_values.select{|i| i.to_s.start_with?(shortval)}
72
+ matching = allowed_values.select{|i| i.to_s.start_with?(shortval)}
72
73
  raise CliBadArgument,bad_arg_message_multi("unknown value for #{descr}: #{shortval}",allowed_values) if matching.empty?
73
74
  raise CliBadArgument,bad_arg_message_multi("ambigous shortcut for #{descr}: #{shortval}",matching) unless matching.length.eql?(1)
74
75
  return enum_to_bool(matching.first) if allowed_values.eql?(BOOLEAN_VALUES)
@@ -84,36 +85,36 @@ module Aspera
84
85
  attr_accessor :ask_missing_mandatory, :ask_missing_optional
85
86
  attr_writer :fail_on_missing_mandatory
86
87
 
87
- def initialize(program_name,argv=nil)
88
+ def initialize(program_name,argv: nil)
88
89
  # command line values not starting with '-'
89
- @unprocessed_cmd_line_arguments=[]
90
+ @unprocessed_cmd_line_arguments = []
90
91
  # command line values starting with '-'
91
- @unprocessed_cmd_line_options=[]
92
+ @unprocessed_cmd_line_options = []
92
93
  # a copy of all initial options
93
- @initial_cli_options=[]
94
+ @initial_cli_options = []
94
95
  # option description: key = option symbol, value=hash, :type, :accessor, :value, :accepted
95
- @declared_options={}
96
+ @declared_options = {}
96
97
  # do we ask missing options and arguments to user ?
97
- @ask_missing_mandatory=false # STDIN.isatty
98
+ @ask_missing_mandatory = false # STDIN.isatty
98
99
  # ask optional options if not provided and in interactive
99
- @ask_missing_optional=false
100
- @fail_on_missing_mandatory=true
100
+ @ask_missing_optional = false
101
+ @fail_on_missing_mandatory = true
101
102
  # those must be set before parse, parse consumes those defined only
102
- @unprocessed_defaults=[]
103
- @unprocessed_env=[]
103
+ @unprocessed_defaults = []
104
+ @unprocessed_env = []
104
105
  # Note: was initially inherited but it is prefered to have specific methods
105
- @parser=OptionParser.new
106
- @parser.program_name=program_name
106
+ @parser = OptionParser.new
107
+ @parser.program_name = program_name
107
108
  # options can also be provided by env vars : --param-name -> ASLMCLI_PARAM_NAME
108
- env_prefix=program_name.upcase+OPTION_SEP_NAME
109
+ env_prefix = program_name.upcase + OPTION_SEP_NAME
109
110
  ENV.each do |k,v|
110
111
  if k.start_with?(env_prefix)
111
112
  @unprocessed_env.push([k[env_prefix.length..-1].downcase.to_sym,v])
112
113
  end
113
114
  end
114
115
  Log.log.debug("env=#{@unprocessed_env}".red)
115
- @unprocessed_cmd_line_options=[]
116
- @unprocessed_cmd_line_arguments=[]
116
+ @unprocessed_cmd_line_options = []
117
+ @unprocessed_cmd_line_arguments = []
117
118
  # argv is nil when help is generated for every plugin
118
119
  unless argv.nil?
119
120
  @parser.separator('')
@@ -123,12 +124,12 @@ module Aspera
123
124
  add_opt_boolean(:interactive,'use interactive input of missing params')
124
125
  add_opt_boolean(:ask_options,'ask even optional options')
125
126
  parse_options!
126
- process_options=true
127
+ process_options = true
127
128
  while !argv.empty?
128
- value=argv.shift
129
+ value = argv.shift
129
130
  if process_options && value.start_with?('-')
130
131
  if value.eql?('--')
131
- process_options=false
132
+ process_options = false
132
133
  else
133
134
  @unprocessed_cmd_line_options.push(value)
134
135
  end
@@ -137,39 +138,45 @@ module Aspera
137
138
  end
138
139
  end
139
140
  end
140
- @initial_cli_options=@unprocessed_cmd_line_options.dup
141
+ @initial_cli_options = @unprocessed_cmd_line_options.dup
141
142
  Log.log.debug("add_cmd_line_options:commands/args=#{@unprocessed_cmd_line_arguments},options=#{@unprocessed_cmd_line_options}".red)
142
143
  end
143
144
 
144
- def get_next_command(command_list); return get_next_argument('command',command_list); end
145
+ def get_next_command(command_list); return get_next_argument('command',expected: command_list); end
145
146
 
146
147
  # @param expected is
147
148
  # - Array of allowed value (single value)
148
149
  # - :multiple for remaining values
149
150
  # - :single for a single unconstrained value
150
- # @param is_type : :mandatory or :optional
151
+ # @param mandatory true/false
152
+ # @param type expected class for result
151
153
  # @return value, list or nil
152
- def get_next_argument(descr,expected=:single,is_type=:mandatory)
153
- result=nil
154
+ def get_next_argument(descr,expected: :single,mandatory: true, type: nil)
155
+ unless type.nil?
156
+ raise 'internal: type must be a Class' unless type.is_a?(Class)
157
+ descr="#{descr} (#{type})"
158
+ end
159
+ result = nil
154
160
  if !@unprocessed_cmd_line_arguments.empty?
155
161
  # there are values
156
162
  case expected
157
163
  when :single
158
- result=ExtendedValue.instance.evaluate(@unprocessed_cmd_line_arguments.shift)
164
+ result = ExtendedValue.instance.evaluate(@unprocessed_cmd_line_arguments.shift)
159
165
  when :multiple
160
166
  result = @unprocessed_cmd_line_arguments.shift(@unprocessed_cmd_line_arguments.length).map{|v|ExtendedValue.instance.evaluate(v)}
161
167
  # if expecting list and only one arg of type array : it is the list
162
168
  if result.length.eql?(1) && result.first.is_a?(Array)
163
- result=result.first
169
+ result = result.first
164
170
  end
165
171
  else
166
- result=self.class.get_from_list(@unprocessed_cmd_line_arguments.shift,descr,expected)
172
+ result = self.class.get_from_list(@unprocessed_cmd_line_arguments.shift,descr,expected)
167
173
  end
168
- elsif is_type.eql?(:mandatory)
174
+ elsif mandatory
169
175
  # no value provided
170
- result=get_interactive(:argument,descr,expected)
176
+ result = get_interactive(:argument,descr,expected: expected)
171
177
  end
172
178
  Log.log.debug("#{descr}=#{result}")
179
+ raise "argument shall be #{type.name}" unless type.nil? || result.is_a?(type)
173
180
  return result
174
181
  end
175
182
 
@@ -177,19 +184,20 @@ module Aspera
177
184
  def declare_option(option_symbol,type)
178
185
  Log.log.debug("declare_option: #{option_symbol}: #{type}: skip=#{@declared_options.has_key?(option_symbol)}".green)
179
186
  if @declared_options.has_key?(option_symbol)
180
- raise "INTERNAL ERROR: option #{option_symbol} already declared. only accessor can be redeclared and ignored" unless @declared_options[option_symbol][:type].eql?(:accessor)
187
+ raise "INTERNAL ERROR: option #{option_symbol} already declared. only accessor can be redeclared and ignored" \
188
+ unless @declared_options[option_symbol][:type].eql?(:accessor)
181
189
  return
182
190
  end
183
- @declared_options[option_symbol]={type: type}
191
+ @declared_options[option_symbol] = {type: type}
184
192
  # by default passwords and secrets are sensitive, else specify when declaring the option
185
- @declared_options[option_symbol][:sensitive]=true if !%w[password secret key].select{|i| option_symbol.to_s.end_with?(i)}.empty?
193
+ @declared_options[option_symbol][:sensitive] = true if !%w[password secret key].select{|i| option_symbol.to_s.end_with?(i)}.empty?
186
194
  end
187
195
 
188
196
  # define option with handler
189
197
  def set_obj_attr(option_symbol,object,attr_symb,default_value=nil)
190
198
  Log.log.debug("set attr obj #{option_symbol} (#{object},#{attr_symb})")
191
199
  declare_option(option_symbol,:accessor)
192
- @declared_options[option_symbol][:accessor]=AttrAccessor.new(object,attr_symb)
200
+ @declared_options[option_symbol][:accessor] = AttrAccessor.new(object,attr_symb)
193
201
  set_option(option_symbol,default_value,'default obj attr') if !default_value.nil?
194
202
  end
195
203
 
@@ -200,14 +208,14 @@ module Aspera
200
208
  raise 'ERROR: cannot set undeclared option'
201
209
  #declare_option(option_symbol)
202
210
  end
203
- value=ExtendedValue.instance.evaluate(value)
204
- value=Manager.enum_to_bool(value) if @declared_options[option_symbol][:values].eql?(BOOLEAN_VALUES)
211
+ value = ExtendedValue.instance.evaluate(value)
212
+ value = Manager.enum_to_bool(value) if @declared_options[option_symbol][:values].eql?(BOOLEAN_VALUES)
205
213
  Log.log.debug("set #{option_symbol}=#{value} (#{@declared_options[option_symbol][:type]}) : #{where}")
206
214
  case @declared_options[option_symbol][:type]
207
215
  when :accessor
208
- @declared_options[option_symbol][:accessor].value=value
216
+ @declared_options[option_symbol][:accessor].value = value
209
217
  when :value
210
- @declared_options[option_symbol][:value]=value
218
+ @declared_options[option_symbol][:value] = value
211
219
  else # nil or other
212
220
  raise 'error'
213
221
  end
@@ -216,33 +224,33 @@ module Aspera
216
224
  # get an option value by name
217
225
  # either return value or call handler, can return nil
218
226
  # ask interactively if requested/required
219
- def get_option(option_symbol,is_type=:optional)
220
- result=nil
227
+ def get_option(option_symbol,is_type: :optional)
228
+ result = nil
221
229
  if @declared_options.has_key?(option_symbol)
222
230
  case @declared_options[option_symbol][:type]
223
231
  when :accessor
224
- result=@declared_options[option_symbol][:accessor].value
232
+ result = @declared_options[option_symbol][:accessor].value
225
233
  when :value
226
- result=@declared_options[option_symbol][:value]
234
+ result = @declared_options[option_symbol][:value]
227
235
  else
228
236
  raise 'unknown type'
229
237
  end
230
238
  Log.log.debug("get #{option_symbol} (#{@declared_options[option_symbol][:type]}) : #{result}")
231
239
  end
232
240
  # do not fail for manual generation if option mandatory but not set
233
- result='' if result.nil? && !@fail_on_missing_mandatory
241
+ result = '' if result.nil? && !@fail_on_missing_mandatory
234
242
  #Log.log.debug("interactive=#{@ask_missing_mandatory}")
235
243
  if result.nil?
236
244
  if !@ask_missing_mandatory
237
245
  raise CliBadArgument,"Missing mandatory option: #{option_symbol}" if is_type.eql?(:mandatory)
238
246
  elsif @ask_missing_optional || is_type.eql?(:mandatory)
239
247
  # ask_missing_mandatory
240
- expected=:single
248
+ expected = :single
241
249
  #print "please enter: #{option_symbol.to_s}"
242
250
  if @declared_options.has_key?(option_symbol) && @declared_options[option_symbol].has_key?(:values)
243
- expected=@declared_options[option_symbol][:values]
251
+ expected = @declared_options[option_symbol][:values]
244
252
  end
245
- result=get_interactive(:option,option_symbol.to_s,expected)
253
+ result = get_interactive(:option,option_symbol.to_s,expected: expected)
246
254
  set_option(option_symbol,result,'interactive')
247
255
  end
248
256
  end
@@ -250,7 +258,7 @@ module Aspera
250
258
  end
251
259
 
252
260
  # param must be hash
253
- def add_option_preset(preset_hash,op=:push)
261
+ def add_option_preset(preset_hash,op: :push)
254
262
  Log.log.debug("add_option_preset=#{preset_hash}")
255
263
  raise "internal error: setting default with no hash: #{preset_hash.class}" if !preset_hash.is_a?(Hash)
256
264
  # incremental override
@@ -263,11 +271,11 @@ module Aspera
263
271
  Log.log.debug("add_opt_list #{option_symbol}")
264
272
  on_args.unshift(symbol_to_option(option_symbol,'ENUM'))
265
273
  # this option value must be a symbol
266
- @declared_options[option_symbol][:values]=values
267
- value=get_option(option_symbol)
268
- help_values=values.map{|i|i.eql?(value)?highlight_current(i):i}.join(', ')
274
+ @declared_options[option_symbol][:values] = values
275
+ value = get_option(option_symbol)
276
+ help_values = values.map{|i|i.eql?(value) ? highlight_current(i) : i}.join(', ')
269
277
  if values.eql?(BOOLEAN_VALUES)
270
- help_values=BOOLEAN_SIMPLE.map{|i|(i.eql?(:yes) && value) || (i.eql?(:no) && !value) ? highlight_current(i) : i}.join(', ')
278
+ help_values = BOOLEAN_SIMPLE.map{|i|(i.eql?(:yes) && value) || (i.eql?(:no) && !value) ? highlight_current(i) : i}.join(', ')
271
279
  end
272
280
  on_args.push(values)
273
281
  on_args.push("#{help}: #{help_values}")
@@ -277,6 +285,9 @@ module Aspera
277
285
 
278
286
  def add_opt_boolean(option_symbol,help,*on_args)
279
287
  add_opt_list(option_symbol,BOOLEAN_VALUES,help,*on_args)
288
+ # if default was defined for obj, it may still be enum (yes/no) instead of boolean
289
+ default_value=get_option(option_symbol)
290
+ set_option(option_symbol,default_value,'opt boolean') unless default_value.nil?
280
291
  end
281
292
 
282
293
  # define an option with open values
@@ -297,7 +308,7 @@ module Aspera
297
308
  @parser.on(*on_args) do |v|
298
309
  case v
299
310
  when 'now' then set_option(option_symbol,Manager.time_to_string(Time.now),'cmdline')
300
- when /^-([0-9]+)h/ then set_option(option_symbol,Manager.time_to_string(Time.now-(3600*Regexp.last_match(1).to_i)),'cmdline')
311
+ when /^-([0-9]+)h/ then set_option(option_symbol,Manager.time_to_string(Time.now - (3600 * Regexp.last_match(1).to_i)),'cmdline')
301
312
  else set_option(option_symbol,v,'cmdline')
302
313
  end
303
314
  end
@@ -318,7 +329,7 @@ module Aspera
318
329
 
319
330
  # unprocessed options or arguments ?
320
331
  def final_errors
321
- result=[]
332
+ result = []
322
333
  result.push("unprocessed options: #{@unprocessed_cmd_line_options}") unless @unprocessed_cmd_line_options.empty?
323
334
  result.push("unprocessed values: #{@unprocessed_cmd_line_arguments}") unless @unprocessed_cmd_line_arguments.empty?
324
335
  return result
@@ -326,18 +337,18 @@ module Aspera
326
337
 
327
338
  # get all original options on command line used to generate a config in config file
328
339
  def get_options_table(remove_from_remaining: true)
329
- result={}
340
+ result = {}
330
341
  @initial_cli_options.each do |optionval|
331
342
  case optionval
332
343
  when /^--([^=]+)$/
333
344
  # ignore
334
345
  when /^--([^=]+)=(.*)$/
335
- name=Regexp.last_match(1)
336
- value=Regexp.last_match(2)
346
+ name = Regexp.last_match(1)
347
+ value = Regexp.last_match(2)
337
348
  name.gsub!(OPTION_SEP_LINE,OPTION_SEP_NAME)
338
- value=ExtendedValue.instance.evaluate(value)
349
+ value = ExtendedValue.instance.evaluate(value)
339
350
  Log.log.debug("option #{name}=#{value}")
340
- result[name]=value
351
+ result[name] = value
341
352
  @unprocessed_cmd_line_options.delete(optionval) if remove_from_remaining
342
353
  else
343
354
  raise CliBadArgument,"wrong option format: #{optionval}"
@@ -348,10 +359,10 @@ module Aspera
348
359
 
349
360
  # return options as taken from config file and command line just before command execution
350
361
  def declared_options(only_defined: false)
351
- result={}
362
+ result = {}
352
363
  @declared_options.keys.each do |option_symb|
353
- v=get_option(option_symb)
354
- result[option_symb.to_s]=v unless only_defined && v.nil?
364
+ v = get_option(option_symb)
365
+ result[option_symb.to_s] = v unless only_defined && v.nil?
355
366
  end
356
367
  return result
357
368
  end
@@ -363,7 +374,7 @@ module Aspera
363
374
  apply_options_preset(@unprocessed_defaults,'file')
364
375
  apply_options_preset(@unprocessed_env,'env')
365
376
  # command line override
366
- unknown_options=[]
377
+ unknown_options = []
367
378
  begin
368
379
  # remove known options one by one, exception if unknown
369
380
  Log.log.debug('before parse'.red)
@@ -377,47 +388,47 @@ module Aspera
377
388
  end
378
389
  Log.log.debug("remains: #{unknown_options}")
379
390
  # set unprocessed options for next time
380
- @unprocessed_cmd_line_options=unknown_options
391
+ @unprocessed_cmd_line_options = unknown_options
381
392
  end
382
393
 
383
394
  private
384
395
 
385
396
  def prompt_user_input(prompt,sensitive)
386
397
  return $stdin.getpass("#{prompt}> ") if sensitive
387
- print "#{prompt}> "
398
+ print("#{prompt}> ")
388
399
  return $stdin.gets.chomp
389
400
  end
390
401
 
391
- def get_interactive(type,descr,expected=:single)
402
+ def get_interactive(type,descr,expected: :single)
392
403
  if !@ask_missing_mandatory
393
404
  raise CliBadArgument,self.class.bad_arg_message_multi("missing: #{descr}",expected) if expected.is_a?(Array)
394
405
  raise CliBadArgument,"missing argument (#{expected}): #{descr}"
395
406
  end
396
- result=nil
407
+ result = nil
397
408
  sensitive = type.eql?(:option) && @declared_options[descr.to_sym][:sensitive]
398
- default_prompt="#{type}: #{descr}"
409
+ default_prompt = "#{type}: #{descr}"
399
410
  # ask interactively
400
411
  case expected
401
412
  when :multiple
402
- result=[]
413
+ result = []
403
414
  puts(' (one per line, end with empty line)')
404
415
  loop do
405
- entry=prompt_user_input(default_prompt,sensitive)
416
+ entry = prompt_user_input(default_prompt,sensitive)
406
417
  break if entry.empty?
407
418
  result.push(ExtendedValue.instance.evaluate(entry))
408
419
  end
409
420
  when :single
410
- result=ExtendedValue.instance.evaluate(prompt_user_input(default_prompt,sensitive))
421
+ result = ExtendedValue.instance.evaluate(prompt_user_input(default_prompt,sensitive))
411
422
  else # one fixed
412
- result=self.class.get_from_list(prompt_user_input("#{expected.join(' ')}\n#{default_prompt}",sensitive),descr,expected)
423
+ result = self.class.get_from_list(prompt_user_input("#{expected.join(' ')}\n#{default_prompt}",sensitive),descr,expected)
413
424
  end
414
425
  return result
415
426
  end
416
427
 
417
428
  # generate command line option from option symbol
418
429
  def symbol_to_option(symbol,opt_val)
419
- result='--'+symbol.to_s.gsub(OPTION_SEP_NAME,OPTION_SEP_LINE)
420
- result=result+'='+opt_val unless opt_val.nil?
430
+ result = '--' + symbol.to_s.gsub(OPTION_SEP_NAME,OPTION_SEP_LINE)
431
+ result = result + '=' + opt_val unless opt_val.nil?
421
432
  return result
422
433
  end
423
434
 
@@ -426,13 +437,13 @@ module Aspera
426
437
  end
427
438
 
428
439
  def apply_options_preset(preset,where)
429
- unprocessed=[]
440
+ unprocessed = []
430
441
  preset.each do |pair|
431
- k,v=*pair
442
+ k,v = *pair
432
443
  if @declared_options.has_key?(k)
433
444
  # constrained parameters as string are revert to symbol
434
445
  if @declared_options[k].has_key?(:values) && v.is_a?(String)
435
- v=self.class.get_from_list(v,k.to_s+" in #{where}",@declared_options[k][:values])
446
+ v = self.class.get_from_list(v,k.to_s + " in #{where}",@declared_options[k][:values])
436
447
  end
437
448
  set_option(k,v,where)
438
449
  else
@@ -1,69 +1,78 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Aspera
3
4
  module Cli
4
5
  # base class for plugins modules
5
6
  class Plugin
6
7
  # operation without id
7
- GLOBAL_OPS=[:create,:list].freeze
8
+ GLOBAL_OPS = %i[create list].freeze
8
9
  # operation on specific instance
9
- INSTANCE_OPS=[:modify,:delete,:show].freeze
10
- ALL_OPS=[GLOBAL_OPS,INSTANCE_OPS].flatten.freeze
10
+ INSTANCE_OPS = %i[modify delete show].freeze
11
+ ALL_OPS = [GLOBAL_OPS,INSTANCE_OPS].flatten.freeze
11
12
  # max number of items for list command
12
- MAX_ITEMS='max'
13
+ MAX_ITEMS = 'max'
13
14
  # max number of pages for list command
14
- MAX_PAGES='pmax'
15
+ MAX_PAGES = 'pmax'
16
+
17
+ #AGENTS=%i[options transfer config formater persistency].freeze
15
18
 
16
19
  # global for inherited classes
17
- @@options_created=false # rubocop:disable Style/ClassVars
20
+ @@options_created = false # rubocop:disable Style/ClassVars
18
21
 
19
22
  def initialize(env)
20
- @agents=env
21
- raise StandardError,"execute_action shall be redefined by subclass #{self.class}" unless respond_to?(:execute_action)
23
+ raise 'must be Hash' unless env.is_a?(Hash)
24
+ #env.each_key {|k| raise "wrong agent key #{k}" unless AGENTS.include?(k)}
25
+ @agents = env
26
+ # check presence in descendant of mandatory method and constant
27
+ raise StandardError,"missing method 'execute_action' in #{self.class}" unless respond_to?(:execute_action)
22
28
  raise StandardError,'ACTIONS shall be redefined by subclass' unless self.class.constants.include?(:ACTIONS)
23
- unless env[:skip_option_header]
24
- options.parser.separator ''
25
- options.parser.separator "COMMAND: #{self.class.name.split('::').last.downcase}"
26
- options.parser.separator "SUBCOMMANDS: #{self.class.const_get(:ACTIONS).map(&:to_s).join(' ')}"
27
- options.parser.separator 'OPTIONS:'
28
- end
29
+ options.parser.separator('')
30
+ options.parser.separator("COMMAND: #{self.class.name.split('::').last.downcase}")
31
+ options.parser.separator("SUBCOMMANDS: #{self.class.const_get(:ACTIONS).map(&:to_s).join(' ')}")
32
+ options.parser.separator('OPTIONS:')
29
33
  return if @@options_created
30
34
  options.add_opt_simple(:value,'extended value for create, update, list filter')
31
35
  options.add_opt_simple(:property,'name of property to set')
32
36
  options.add_opt_simple(:id,"resource identifier (#{INSTANCE_OPS.join(',')})")
33
37
  options.parse_options!
34
- @@options_created=true # rubocop:disable Style/ClassVars
38
+ @@options_created = true # rubocop:disable Style/ClassVars
35
39
  end
36
40
 
37
41
  # must be called AFTER the instance action
38
42
  def instance_identifier
39
- res_id=options.get_option(:id)
40
- res_id=options.get_next_argument('identifier') if res_id.nil?
43
+ res_id = options.get_option(:id)
44
+ res_id = options.get_next_argument('identifier') if res_id.nil?
41
45
  return res_id
42
46
  end
43
47
 
48
+ # TODO
49
+ def get_next_id_command(instance_ops: INSTANCE_OPS,global_ops: GLOBAL_OPS)
50
+ return get_next_argument('command',expected: command_list)
51
+ end
52
+
44
53
  # @param command [Symbol] command to execute: create show list modify delete
45
54
  # @param rest_api [Rest] api to use
46
55
  # @param res_class_path [String] sub path in URL to resource relative to base url
47
56
  # @param display_fields [Array] fields to display by default
48
57
  # @param id_default [String] default identifier to use for existing entity commands (show, modify)
49
- # @param use_subkey [bool] true if the result is in a subkey of the json
50
- def entity_command(command,rest_api,res_class_path,display_fields: nil,id_default: nil,use_subkey: false)
58
+ # @param item_list_key [String] result is in a subkey of the json
59
+ def entity_command(command,rest_api,res_class_path,display_fields: nil,id_default: nil,item_list_key: false)
51
60
  if INSTANCE_OPS.include?(command)
52
61
  begin
53
- one_res_id=instance_identifier()
62
+ one_res_id = instance_identifier
54
63
  rescue StandardError => e
55
64
  raise e if id_default.nil?
56
- one_res_id=id_default
65
+ one_res_id = id_default
57
66
  end
58
- one_res_path="#{res_class_path}/#{one_res_id}"
67
+ one_res_path = "#{res_class_path}/#{one_res_id}"
59
68
  end
60
69
  # parameters mandatory for create/modify
61
- if [:create,:modify].include?(command)
62
- parameters=options.get_option(:value,:mandatory)
70
+ if %i[create modify].include?(command)
71
+ parameters = options.get_option(:value,is_type: :mandatory)
63
72
  end
64
73
  # parameters optional for list
65
74
  if [:list].include?(command)
66
- parameters=options.get_option(:value,:optional)
75
+ parameters = options.get_option(:value)
67
76
  end
68
77
  case command
69
78
  when :create
@@ -71,17 +80,26 @@ module Aspera
71
80
  when :show
72
81
  return {type: :single_object, data: rest_api.read(one_res_path)[:data], fields: display_fields}
73
82
  when :list
74
- resp=rest_api.read(res_class_path,parameters)
75
- data=resp[:data]
83
+ resp = rest_api.read(res_class_path,parameters)
84
+ data = resp[:data]
76
85
  # TODO: not generic : which application is this for ?
77
86
  if resp[:http]['Content-Type'].start_with?('application/vnd.api+json')
78
- data=data[res_class_path]
87
+ data = data[res_class_path]
88
+ end
89
+ if item_list_key
90
+ item_list=data[item_list_key]
91
+ total_count=data['total_count']
92
+ if !total_count.nil?
93
+ count_msg = "Items: #{item_list.length}/#{total_count}"
94
+ count_msg = count_msg.bg_red unless item_list.length.eql?(total_count.to_i)
95
+ self.format.display_status(count_msg)
96
+ end
97
+ data = item_list
79
98
  end
80
- data=data[res_class_path] if use_subkey
81
99
  return {type: :object_list, data: data, fields: display_fields}
82
100
  when :modify
83
- property=options.get_option(:property,:optional)
84
- parameters={property => parameters} unless property.nil?
101
+ property = options.get_option(:property)
102
+ parameters = {property => parameters} unless property.nil?
85
103
  rest_api.update(one_res_path,parameters)
86
104
  return Main.result_status('modified')
87
105
  when :delete
@@ -95,7 +113,7 @@ module Aspera
95
113
  # implement generic rest operations on given resource path
96
114
  def entity_action(rest_api,res_class_path,**opts)
97
115
  #res_name=res_class_path.gsub(%r{^.*/},'').gsub(%r{s$},'').gsub('_',' ')
98
- command=options.get_next_command(ALL_OPS)
116
+ command = options.get_next_command(ALL_OPS)
99
117
  return entity_command(command,rest_api,res_class_path,**opts)
100
118
  end
101
119
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'aspera/rest'
3
4
  require 'aspera/aoc'
4
5
 
@@ -6,15 +7,15 @@ module Aspera
6
7
  module Cli
7
8
  module Plugins
8
9
  class Alee < BasicAuthPlugin
9
- ACTIONS=[:entitlement]
10
+ ACTIONS = %i[entitlement].freeze
10
11
 
11
12
  def execute_action
12
- command=options.get_next_command(ACTIONS)
13
+ command = options.get_next_command(ACTIONS)
13
14
  case command
14
15
  when :entitlement
15
- entitlement_id = options.get_option(:username,:mandatory)
16
- customer_id = options.get_option(:password,:mandatory)
17
- api_metering=AoC.metering_api(entitlement_id,customer_id)
16
+ entitlement_id = options.get_option(:username,is_type: :mandatory)
17
+ customer_id = options.get_option(:password,is_type: :mandatory)
18
+ api_metering = AoC.metering_api(entitlement_id,customer_id)
18
19
  return {type: :single_object, data: api_metering.read('entitlement')[:data]}
19
20
  end
20
21
  end