haveapi-client 0.20.0 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/Rakefile +0 -1
  4. data/haveapi-client.gemspec +7 -10
  5. data/lib/haveapi/cli/action_state.rb +50 -51
  6. data/lib/haveapi/cli/authentication/base.rb +4 -9
  7. data/lib/haveapi/cli/authentication/basic.rb +3 -1
  8. data/lib/haveapi/cli/authentication/token.rb +7 -8
  9. data/lib/haveapi/cli/cli.rb +115 -127
  10. data/lib/haveapi/cli/command.rb +2 -4
  11. data/lib/haveapi/cli/commands/action_state_wait.rb +9 -9
  12. data/lib/haveapi/cli/example_formatter.rb +8 -8
  13. data/lib/haveapi/cli/output_formatter.rb +39 -36
  14. data/lib/haveapi/cli/utils.rb +5 -5
  15. data/lib/haveapi/cli.rb +1 -1
  16. data/lib/haveapi/client/action.rb +17 -20
  17. data/lib/haveapi/client/action_state.rb +3 -7
  18. data/lib/haveapi/client/authentication/base.rb +4 -7
  19. data/lib/haveapi/client/authentication/basic.rb +2 -2
  20. data/lib/haveapi/client/authentication/noauth.rb +0 -1
  21. data/lib/haveapi/client/authentication/token.rb +28 -27
  22. data/lib/haveapi/client/client.rb +12 -6
  23. data/lib/haveapi/client/communicator.rb +33 -35
  24. data/lib/haveapi/client/exceptions.rb +5 -9
  25. data/lib/haveapi/client/parameters/resource.rb +1 -0
  26. data/lib/haveapi/client/parameters/typed.rb +3 -5
  27. data/lib/haveapi/client/params.rb +8 -8
  28. data/lib/haveapi/client/resource.rb +12 -13
  29. data/lib/haveapi/client/resource_instance.rb +71 -72
  30. data/lib/haveapi/client/resource_instance_list.rb +2 -1
  31. data/lib/haveapi/client/response.rb +8 -8
  32. data/lib/haveapi/client/validator.rb +7 -8
  33. data/lib/haveapi/client/validators/confirmation.rb +1 -0
  34. data/lib/haveapi/client/validators/length.rb +1 -0
  35. data/lib/haveapi/client/validators/numericality.rb +2 -1
  36. data/lib/haveapi/client/validators/presence.rb +1 -0
  37. data/lib/haveapi/client/version.rb +2 -2
  38. data/lib/haveapi/client.rb +2 -2
  39. data/lib/restclient_ext/resource.rb +5 -5
  40. data/shell.nix +1 -1
  41. metadata +15 -43
@@ -12,9 +12,8 @@ module HaveAPI::CLI
12
12
 
13
13
  def run
14
14
  c = new
15
-
16
15
  rescue Interrupt
17
- warn "Interrupted"
16
+ warn 'Interrupted'
18
17
  exit(false)
19
18
  end
20
19
 
@@ -38,7 +37,7 @@ module HaveAPI::CLI
38
37
  connect_api unless @api
39
38
 
40
39
  if @action
41
- method(@action.first).call( * @action[1..-1] )
40
+ method(@action.first).call(* @action[1..])
42
41
  exit
43
42
  end
44
43
 
@@ -51,7 +50,7 @@ module HaveAPI::CLI
51
50
 
52
51
  resources = args[0].split('.')
53
52
 
54
- if cmd = find_command(resources, args[1])
53
+ if (cmd = find_command(resources, args[1]))
55
54
  authenticate if @auth
56
55
  c = cmd.new(@opts, HaveAPI::Client::Client.new(nil, communicator: @api))
57
56
 
@@ -72,21 +71,21 @@ module HaveAPI::CLI
72
71
  end
73
72
  end
74
73
 
75
- if sep = ARGV.index('--')
76
- cmd_opt.parse!(ARGV[sep+1..-1])
74
+ if (sep = ARGV.index('--'))
75
+ cmd_opt.parse!(ARGV[sep + 1..])
77
76
  end
78
77
 
79
- c.exec(args[2..-1] || [])
78
+ c.exec(args[2..] || [])
80
79
 
81
80
  exit
82
81
  end
83
82
 
84
83
  if args.count == 1
85
84
  describe_resource(resources)
86
- exit(true)
85
+ exit
87
86
  end
88
87
 
89
- action = @api.get_action(resources, args[1].to_sym, args[2..-1])
88
+ action = @api.get_action(resources, args[1].to_sym, args[2..])
90
89
 
91
90
  unless action
92
91
  warn "Resource or action '#{args[0]} #{args[1]}' not found"
@@ -97,24 +96,23 @@ module HaveAPI::CLI
97
96
  if authenticate(action) && !action.unresolved_args?
98
97
  begin
99
98
  action.update_description(@api.describe_action(action))
100
-
101
99
  rescue RestClient::ResourceNotFound => e
102
100
  format_errors(action, 'Object not found', {})
103
101
  exit(false)
104
102
  end
105
103
  end
106
104
 
107
- @selected_params = @opts[:output] ? @opts[:output].split(',').uniq
108
- : nil
105
+ @selected_params = if @opts[:output]
106
+ @opts[:output].split(',').uniq
107
+ end
109
108
 
110
109
  @input_params = parameters(action)
111
110
 
112
111
  includes = build_includes(action) if @selected_params
113
- @input_params[:meta] = { includes: includes } if includes
112
+ @input_params[:meta] = { includes: } if includes
114
113
 
115
114
  begin
116
115
  ret = action.execute(@input_params, raw: @opts[:raw])
117
-
118
116
  rescue HaveAPI::Client::ValidationError => e
119
117
  format_errors(action, 'input parameters not valid', e.errors)
120
118
  exit(false)
@@ -128,30 +126,30 @@ module HaveAPI::CLI
128
126
  exit(false)
129
127
  end
130
128
 
131
- if action.blocking?
132
- res = HaveAPI::Client::Response.new(action, ret)
129
+ return unless action.blocking?
133
130
 
134
- if res.meta[:action_state_id]
135
- state = ActionState.new(
136
- @opts,
137
- HaveAPI::Client::Client.new(@api.url, communicator: @api, block: false),
138
- res.meta[:action_state_id]
139
- )
131
+ res = HaveAPI::Client::Response.new(action, ret)
140
132
 
141
- if @opts[:block]
142
- puts
143
- action_ret = state.wait_for_completion(timeout: @opts[:timeout])
133
+ return unless res.meta[:action_state_id]
144
134
 
145
- if action_ret.nil?
146
- warn "Timeout"
147
- exit(false)
148
- end
135
+ state = ActionState.new(
136
+ @opts,
137
+ HaveAPI::Client::Client.new(@api.url, communicator: @api, block: false),
138
+ res.meta[:action_state_id]
139
+ )
149
140
 
150
- else
151
- puts
152
- state.print_help
153
- end
141
+ puts
142
+
143
+ if @opts[:block]
144
+ action_ret = state.wait_for_completion(timeout: @opts[:timeout])
145
+
146
+ if action_ret.nil?
147
+ warn 'Timeout'
148
+ exit(false)
154
149
  end
150
+
151
+ else
152
+ state.print_help
155
153
  end
156
154
  end
157
155
 
@@ -163,7 +161,7 @@ module HaveAPI::CLI
163
161
  options = {
164
162
  client: default_url,
165
163
  block: true,
166
- verbose: false,
164
+ verbose: false
167
165
  }
168
166
 
169
167
  @global_opt = OptionParser.new do |opts|
@@ -211,11 +209,11 @@ module HaveAPI::CLI
211
209
  options[:layout] = :columns
212
210
  end
213
211
 
214
- opts.on('-H', '--no-header', 'Hide header row') do |h|
212
+ opts.on('-H', '--no-header', 'Hide header row') do |_h|
215
213
  options[:header] = false
216
214
  end
217
215
 
218
- opts.on('-L', '--list-parameters', 'List output parameters') do |l|
216
+ opts.on('-L', '--list-parameters', 'List output parameters') do |_l|
219
217
  options[:list_output] = true
220
218
  end
221
219
 
@@ -260,9 +258,9 @@ module HaveAPI::CLI
260
258
  end
261
259
 
262
260
  opts.on(
263
- '--timeout SEC',
264
- Float,
265
- 'Fail when the action does not finish within the timeout'
261
+ '--timeout SEC',
262
+ Float,
263
+ 'Fail when the action does not finish within the timeout'
266
264
  ) do |v|
267
265
  options[:timeout] = v.to_f
268
266
  end
@@ -291,11 +289,9 @@ module HaveAPI::CLI
291
289
  args = []
292
290
 
293
291
  ARGV.each do |arg|
294
- if arg == '--'
295
- break
296
- else
297
- args << arg
298
- end
292
+ break if arg == '--'
293
+
294
+ args << arg
299
295
  end
300
296
 
301
297
  @global_opt.parse!(args)
@@ -304,11 +300,11 @@ module HaveAPI::CLI
304
300
  cfg = server_config(options[:client])
305
301
  connect_api(url: options[:client], version: options[:version]) unless @api
306
302
 
307
- if m = cfg[:last_auth]
303
+ if (m = cfg[:last_auth])
308
304
  @auth = Cli.auth_methods[m].new(
309
305
  @api,
310
306
  @api.describe_api(options[:version])[:authentication][m],
311
- cfg[:auth][m],
307
+ cfg[:auth][m]
312
308
  )
313
309
  end
314
310
  end
@@ -328,12 +324,12 @@ module HaveAPI::CLI
328
324
  opts.on(param_option(name, p), p[:description] || p[:label] || ' ') do |*args|
329
325
  arg = args.first
330
326
 
331
- if arg.nil?
332
- options[name] = read_param(name, p)
327
+ options[name] = if arg.nil?
328
+ read_param(name, p)
333
329
 
334
- else
335
- options[name] = args.first
336
- end
330
+ else
331
+ args.first
332
+ end
337
333
  end
338
334
  end
339
335
  end
@@ -353,7 +349,7 @@ module HaveAPI::CLI
353
349
  puts 'Output parameters:'
354
350
 
355
351
  action.params.each do |name, param|
356
- puts sprintf(" %-32s %s", name, param[:description])
352
+ puts format(' %-32s %s', name, param[:description])
357
353
  end
358
354
 
359
355
  print_examples(action)
@@ -367,7 +363,7 @@ module HaveAPI::CLI
367
363
 
368
364
  return {} unless sep
369
365
 
370
- @action_opt.parse!(ARGV[sep+1..-1])
366
+ @action_opt.parse!(ARGV[sep + 1..])
371
367
 
372
368
  options
373
369
  end
@@ -375,7 +371,7 @@ module HaveAPI::CLI
375
371
  def list_versions
376
372
  desc = @api.available_versions
377
373
 
378
- desc[:versions].each do |v, _|
374
+ desc[:versions].each_key do |v|
379
375
  next if v == :default
380
376
 
381
377
  v_int = v.to_s.to_i
@@ -384,7 +380,7 @@ module HaveAPI::CLI
384
380
  end
385
381
  end
386
382
 
387
- def list_auth(v=nil)
383
+ def list_auth(v = nil)
388
384
  desc = @api.describe_api(v)
389
385
 
390
386
  desc[:authentication].each_key do |auth|
@@ -392,7 +388,7 @@ module HaveAPI::CLI
392
388
  end
393
389
  end
394
390
 
395
- def list_resources(v=nil)
391
+ def list_resources(v = nil)
396
392
  desc = @api.describe_api(v)
397
393
 
398
394
  sort_by_key(desc[:resources]).each do |resource, children|
@@ -400,7 +396,7 @@ module HaveAPI::CLI
400
396
  end
401
397
  end
402
398
 
403
- def list_actions(v=nil)
399
+ def list_actions(v = nil)
404
400
  desc = @api.describe_api(v)
405
401
 
406
402
  sort_by_key(desc[:resources]).each do |resource, children|
@@ -450,16 +446,16 @@ module HaveAPI::CLI
450
446
 
451
447
  puts '' if !desc[:resources].empty? && !desc[:actions].empty?
452
448
 
453
- unless desc[:actions].empty?
454
- puts 'Actions:'
449
+ return if desc[:actions].empty?
455
450
 
456
- desc[:actions].keys.sort.each do |a|
457
- puts " #{a}"
458
- end
451
+ puts 'Actions:'
452
+
453
+ desc[:actions].keys.sort.each do |a|
454
+ puts " #{a}"
459
455
  end
460
456
  end
461
457
 
462
- def nested_resource(prefix, children, actions=false)
458
+ def nested_resource(prefix, children, actions = false)
463
459
  if actions
464
460
  children[:actions].keys.sort.each do |action|
465
461
  puts "#{prefix}##{action}"
@@ -468,8 +464,8 @@ module HaveAPI::CLI
468
464
  puts prefix
469
465
  end
470
466
 
471
- sort_by_key(children[:resources]).each do |resource, children|
472
- nested_resource("#{prefix}.#{resource}", children, actions)
467
+ sort_by_key(children[:resources]).each do |resource, grandchildren|
468
+ nested_resource("#{prefix}.#{resource}", grandchildren, actions)
473
469
  end
474
470
  end
475
471
 
@@ -480,10 +476,10 @@ module HaveAPI::CLI
480
476
  puts
481
477
  puts 'Commands:'
482
478
  Cli.commands.each do |cmd|
483
- puts sprintf(
484
- '%-36s %s',
485
- "#{cmd.resource.join('.')} #{cmd.action} #{cmd.args}",
486
- cmd.desc
479
+ puts format(
480
+ '%-36s %s',
481
+ "#{cmd.resource.join('.')} #{cmd.action} #{cmd.args}",
482
+ cmd.desc
487
483
  )
488
484
  end
489
485
  end
@@ -493,10 +489,10 @@ module HaveAPI::CLI
493
489
  end
494
490
 
495
491
  def print_examples(action)
496
- unless action.examples.empty?
497
- puts "\nExamples:\n"
498
- ExampleFormatter.format_examples(self, action)
499
- end
492
+ return if action.examples.empty?
493
+
494
+ puts "\nExamples:\n"
495
+ ExampleFormatter.format_examples(self, action)
500
496
  end
501
497
 
502
498
  def format_output(action, response, out = $>)
@@ -510,7 +506,7 @@ module HaveAPI::CLI
510
506
  namespace = action.namespace(:output).to_sym
511
507
 
512
508
  if action.output_layout.to_sym == :custom
513
- return PP.pp(response[namespace], out)
509
+ return PP.pp(response[namespace], out)
514
510
  end
515
511
 
516
512
  cols = []
@@ -522,37 +518,35 @@ module HaveAPI::CLI
522
518
 
523
519
  # Fetching an associated attribute
524
520
  if raw_name.to_s.index('.')
525
- parts = raw_name.to_s.split('.').map! { |v| v.to_sym }
521
+ parts = raw_name.to_s.split('.').map!(&:to_sym)
526
522
  name = parts.first.to_sym
527
523
 
528
524
  top = action.params
529
525
 
530
526
  parts.each do |part|
531
- fail "'#{part}' not found" unless top.has_key?(part)
527
+ raise "'#{part}' not found" unless top.has_key?(part)
532
528
 
533
- if top[part][:type] == 'Resource'
534
- param = top[part]
535
- top = @api.get_action(top[part][:resource], :show, []).params
529
+ param = top[part]
536
530
 
537
- else
538
- param = top[part]
539
- break
540
- end
531
+ break if param[:type] != 'Resource'
532
+
533
+ top = @api.get_action(param[:resource], :show, []).params
541
534
  end
542
535
 
543
- col[:display] = Proc.new do |r|
536
+ col[:display] = proc do |r|
544
537
  next '' unless r
545
538
 
546
539
  top = r
547
- parts[1..-1].each do |part|
548
- fail "'#{part}' not found" unless top.has_key?(part)
540
+ parts[1..].each do |part|
541
+ raise "'#{part}' not found" unless top.has_key?(part)
549
542
  break if top[part].nil?
543
+
550
544
  top = top[part]
551
545
  end
552
546
 
553
547
  case param[:type]
554
548
  when 'Resource'
555
- "#{top[ param[:value_label].to_sym ]} (##{top[ param[:value_id].to_sym ]})"
549
+ "#{top[param[:value_label].to_sym]} (##{top[param[:value_id].to_sym]})"
556
550
 
557
551
  when 'Datetime'
558
552
  format_date(top)
@@ -567,12 +561,13 @@ module HaveAPI::CLI
567
561
  else # directly accessible parameter
568
562
  name = raw_name.to_sym
569
563
  param = action.params[name]
570
- fail "parameter '#{name}' does not exist" if param.nil?
564
+ raise "parameter '#{name}' does not exist" if param.nil?
571
565
 
572
566
  if param[:type] == 'Resource'
573
- col[:display] = Proc.new do |r|
567
+ col[:display] = proc do |r|
574
568
  next '' unless r
575
- "#{r[ param[:value_label].to_sym ]} (##{r[ param[:value_id].to_sym ]})"
569
+
570
+ "#{r[param[:value_label].to_sym]} (##{r[param[:value_id].to_sym]})"
576
571
  end
577
572
 
578
573
  elsif param[:type] == 'Datetime'
@@ -581,8 +576,8 @@ module HaveAPI::CLI
581
576
  end
582
577
 
583
578
  col.update({
584
- name: name,
585
- align: %w(Integer Float).include?(param[:type]) ? 'right' : 'left',
579
+ name:,
580
+ align: %w[Integer Float].include?(param[:type]) ? 'right' : 'left'
586
581
  })
587
582
 
588
583
  col[:label] ||= param[:label] && !param[:label].empty? ? param[:label] : name.upcase
@@ -591,11 +586,11 @@ module HaveAPI::CLI
591
586
  end
592
587
 
593
588
  OutputFormatter.print(
594
- response[namespace],
595
- cols,
596
- header: @opts[:header].nil?,
597
- sort: @opts[:sort] && @opts[:sort].to_sym,
598
- layout: @opts[:layout]
589
+ response[namespace],
590
+ cols,
591
+ header: @opts[:header].nil?,
592
+ sort: @opts[:sort] && @opts[:sort].to_sym,
593
+ layout: @opts[:layout]
599
594
  )
600
595
  end
601
596
 
@@ -610,25 +605,23 @@ module HaveAPI::CLI
610
605
  end
611
606
 
612
607
  def authenticate(action = nil)
613
- if @auth
614
- @auth.validate
615
- @auth.authenticate
608
+ raise 'auth is needed and has not been selected' unless @auth
616
609
 
617
- if @opts[:save]
618
- cfg = server_config(api_url)
619
- cfg[:auth][@opts[:auth]] = @auth.save
620
- cfg[:last_auth] = @opts[:auth]
621
- write_config
622
- end
610
+ @auth.validate
611
+ @auth.authenticate
623
612
 
624
- else
625
- # FIXME: exit as auth is needed and has not been selected
613
+ if @opts[:save]
614
+ cfg = server_config(api_url)
615
+ cfg[:auth][@opts[:auth]] = @auth.save
616
+ cfg[:last_auth] = @opts[:auth]
617
+ write_config
626
618
  end
627
619
 
628
- return true
620
+ true
629
621
  end
630
622
 
631
623
  protected
624
+
632
625
  def default_url
633
626
  'http://localhost:4567'
634
627
  end
@@ -638,18 +631,16 @@ module HaveAPI::CLI
638
631
  end
639
632
 
640
633
  def write_config
641
- File.open(config_path, 'w') do |f|
642
- f.write(YAML.dump(@config))
643
- end
634
+ File.write(config_path, YAML.dump(@config))
644
635
  end
645
636
 
646
637
  def read_config
647
- @config = YAML.load_file(config_path) if File.exists?(config_path)
638
+ @config = YAML.load_file(config_path) if File.exist?(config_path)
648
639
  end
649
640
 
650
641
  def server_config(url)
651
642
  unless @config[:servers]
652
- @config[:servers] = [{url: url, auth: {}}]
643
+ @config[:servers] = [{ url:, auth: {} }]
653
644
  return @config[:servers].first
654
645
  end
655
646
 
@@ -657,7 +648,7 @@ module HaveAPI::CLI
657
648
  return s if s[:url] == url
658
649
  end
659
650
 
660
- @config[:servers] << {url: url, auth: {}}
651
+ @config[:servers] << { url:, auth: {} }
661
652
  @config[:servers].last
662
653
  end
663
654
 
@@ -708,7 +699,7 @@ module HaveAPI::CLI
708
699
  includes = []
709
700
  top = action.params
710
701
 
711
- param.split('.').map! { |v| v.to_sym }.each do |part|
702
+ param.split('.').map!(&:to_sym).each do |part|
712
703
  next unless top.has_key?(part)
713
704
  next if top[part][:type] != 'Resource'
714
705
 
@@ -728,25 +719,22 @@ module HaveAPI::CLI
728
719
 
729
720
  t = DateTime.iso8601(date).to_time
730
721
  ret = case @opts[:datetime]
731
- when :timestamp
732
- t.to_i
733
-
734
- when :utc
735
- t.utc
722
+ when :timestamp
723
+ t.to_i
736
724
 
737
- when :local
738
- t.localtime
725
+ when :utc
726
+ t.utc
739
727
 
740
- else
741
- t.localtime
742
- end
728
+ else
729
+ t.localtime
730
+ end
743
731
 
744
732
  @opts[:date_format] ? ret.strftime(@opts[:date_format]) : ret
745
733
  end
746
734
 
747
735
  def sort_by_key(hash)
748
736
  hash.sort do |a, b|
749
- a[0]<=> b[0]
737
+ a[0] <=> b[0]
750
738
  end
751
739
  end
752
740
  end
@@ -5,7 +5,7 @@ module HaveAPI::CLI
5
5
 
6
6
  def cmd(resource, action = nil)
7
7
  @resource = resource.is_a?(::Array) ? resource : [resource]
8
- @resource.map! { |v| v.to_s }
8
+ @resource.map!(&:to_s)
9
9
  @action = action && action.to_s
10
10
 
11
11
  Cli.register_command(self)
@@ -41,9 +41,7 @@ module HaveAPI::CLI
41
41
  @api = client
42
42
  end
43
43
 
44
- def options(opts)
45
-
46
- end
44
+ def options(opts); end
47
45
 
48
46
  def exec(args)
49
47
  raise NotImplementedError
@@ -7,24 +7,24 @@ module HaveAPI::CLI::Commands
7
7
  desc 'Block until the action is finished'
8
8
 
9
9
  def exec(args)
10
- if args.size < 1
11
- warn "Provide argument STATE ID"
10
+ if args.empty?
11
+ warn 'Provide argument STATE ID'
12
12
  exit(false)
13
13
  end
14
14
 
15
15
  @api.set_opts(block: false)
16
16
 
17
17
  state = HaveAPI::CLI::ActionState.new(
18
- @global_opts,
19
- @api,
20
- args.first.to_i
18
+ @global_opts,
19
+ @api,
20
+ args.first.to_i
21
21
  )
22
22
  ret = state.wait_for_completion(timeout: @global_opts[:timeout])
23
23
 
24
- if ret.nil?
25
- warn "Timeout"
26
- exit(false)
27
- end
24
+ return unless ret.nil?
25
+
26
+ warn 'Timeout'
27
+ exit(false)
28
28
  end
29
29
  end
30
30
  end
@@ -24,9 +24,9 @@ module HaveAPI::CLI
24
24
 
25
25
  # response
26
26
  cli.format_output(
27
- action,
28
- {action.namespace(:output).to_sym => example[:response]},
29
- out
27
+ action,
28
+ { action.namespace(:output).to_sym => example[:response] },
29
+ out
30
30
  )
31
31
  end
32
32
  end
@@ -35,16 +35,16 @@ module HaveAPI::CLI
35
35
  option = name.to_s.dasherize
36
36
 
37
37
  case desc[:type]
38
- when 'Boolean'
39
- value ? "--#{option}" : "--no-#{option}"
38
+ when 'Boolean'
39
+ value ? "--#{option}" : "--no-#{option}"
40
40
 
41
- else
42
- "--#{option} #{example_value(value)}"
41
+ else
42
+ "--#{option} #{example_value(value)}"
43
43
  end
44
44
  end
45
45
 
46
46
  def self.example_value(v)
47
- (v.is_a?(String) && (v.empty? || v.index(' '))) ? "\"#{v}\"" : v
47
+ v.is_a?(String) && (v.empty? || v.index(' ')) ? "\"#{v}\"" : v
48
48
  end
49
49
  end
50
50
  end