wavefront-cli 5.1.0 → 5.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HISTORY.md +3 -0
- data/lib/wavefront-cli/base.rb +13 -119
- data/lib/wavefront-cli/helpers/load_file.rb +80 -0
- data/lib/wavefront-cli/subcommands/import.rb +78 -0
- data/lib/wavefront-cli/version.rb +1 -1
- data/spec/test_mixins/import.rb +9 -3
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44f481275247e98780e57065df2166e93158382c03dea0d9dbc627b2d1756777
|
4
|
+
data.tar.gz: b225b2ba3668cc00c6e3e873064bcf54b79c1dbc6638009cba09cfb6de7874c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42c775a15f3a74a7ffbaa45ebff0d38755996c64afeca494496c4707a26734733e6f18f7469be9ac3b82786697e1d773748057c96789ea470e8a7d8022c851f1
|
7
|
+
data.tar.gz: 1945c8a72ce0cc6fb6c4cdda8a8f8baabad6f020175d25f8109fb240f58c3cf175cd1b846c9fc7830c6bba31356f83975e69eac8736b3cf7aa0fbf7c88d8d7fb
|
data/HISTORY.md
CHANGED
data/lib/wavefront-cli/base.rb
CHANGED
@@ -46,7 +46,7 @@ module WavefrontCli
|
|
46
46
|
end
|
47
47
|
|
48
48
|
# Normally we map the class name to a similar one in the SDK.
|
49
|
-
# Overriding
|
49
|
+
# Overriding this method lets you map to something else.
|
50
50
|
#
|
51
51
|
def _sdk_class
|
52
52
|
self.class.name.sub(/Cli/, '')
|
@@ -349,60 +349,6 @@ module WavefrontCli
|
|
349
349
|
raise(WavefrontCli::Exception::CredentialError, 'Missing API endpoint.')
|
350
350
|
end
|
351
351
|
|
352
|
-
# Give it a path to a file (as a string) and it will return the
|
353
|
-
# contents of that file as a Ruby object. Automatically detects
|
354
|
-
# JSON and YAML. Raises an exception if it doesn't look like
|
355
|
-
# either. If path is '-' then it will read STDIN.
|
356
|
-
#
|
357
|
-
# @param path [String] the file to load
|
358
|
-
# @return [Hash] a Ruby object of the loaded file
|
359
|
-
# @raise WavefrontCli::Exception::UnsupportedFileFormat if the
|
360
|
-
# filetype is unknown.
|
361
|
-
# @raise pass through any error loading or parsing the file
|
362
|
-
#
|
363
|
-
def load_file(path)
|
364
|
-
return load_from_stdin if path == '-'
|
365
|
-
|
366
|
-
file = Pathname.new(path)
|
367
|
-
extname = file.extname.downcase
|
368
|
-
|
369
|
-
raise WavefrontCli::Exception::FileNotFound unless file.exist?
|
370
|
-
|
371
|
-
return load_json(file) if extname == '.json'
|
372
|
-
return load_yaml(file) if %w[.yaml .yml].include?(extname)
|
373
|
-
|
374
|
-
raise WavefrontCli::Exception::UnsupportedFileFormat
|
375
|
-
end
|
376
|
-
|
377
|
-
def load_json(file)
|
378
|
-
read_json(IO.read(file))
|
379
|
-
end
|
380
|
-
|
381
|
-
def load_yaml(file)
|
382
|
-
read_yaml(IO.read(file))
|
383
|
-
end
|
384
|
-
|
385
|
-
# Read STDIN and return a Ruby object, assuming that STDIN is
|
386
|
-
# valid JSON or YAML. This is a dumb method, it does no
|
387
|
-
# buffering, so STDIN must be a single block of data. This
|
388
|
-
# appears to be a valid assumption for use-cases of this CLI.
|
389
|
-
#
|
390
|
-
# @return [Object]
|
391
|
-
# @raise Wavefront::Exception::UnparseableInput if the input
|
392
|
-
# does not parse
|
393
|
-
#
|
394
|
-
def load_from_stdin
|
395
|
-
raw = STDIN.read
|
396
|
-
|
397
|
-
if raw.start_with?('---')
|
398
|
-
read_yaml(raw)
|
399
|
-
else
|
400
|
-
read_json(raw)
|
401
|
-
end
|
402
|
-
rescue RuntimeError
|
403
|
-
raise Wavefront::Exception::UnparseableInput
|
404
|
-
end
|
405
|
-
|
406
352
|
# Below here are common methods. Most are used by most classes,
|
407
353
|
# but if they don't match a command described in the docopt
|
408
354
|
# text, the dispatcher will never call them. So, there's no
|
@@ -451,50 +397,8 @@ module WavefrontCli
|
|
451
397
|
end
|
452
398
|
|
453
399
|
def do_import
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
[raw].flatten.each do |obj|
|
458
|
-
resp = import_object(obj)
|
459
|
-
next if options[:noop]
|
460
|
-
|
461
|
-
errs += 1 unless resp.ok?
|
462
|
-
puts import_message(obj, resp)
|
463
|
-
end
|
464
|
-
|
465
|
-
exit errs
|
466
|
-
end
|
467
|
-
|
468
|
-
def import_message(obj, resp)
|
469
|
-
format('%-15<id>s %-10<status>s %<message>s',
|
470
|
-
id: obj[:id] || obj[:url],
|
471
|
-
status: resp.ok? ? 'IMPORTED' : 'FAILED',
|
472
|
-
message: resp.status.message)
|
473
|
-
end
|
474
|
-
|
475
|
-
def import_object(raw)
|
476
|
-
raw = preprocess_rawfile(raw) if respond_to?(:preprocess_rawfile)
|
477
|
-
prepped = import_to_create(raw)
|
478
|
-
|
479
|
-
if options[:upsert]
|
480
|
-
import_upsert(raw, prepped)
|
481
|
-
elsif options[:update]
|
482
|
-
import_update(raw)
|
483
|
-
else
|
484
|
-
wf.create(prepped)
|
485
|
-
end
|
486
|
-
end
|
487
|
-
|
488
|
-
def import_upsert(raw, prepped)
|
489
|
-
update_call = import_update(raw)
|
490
|
-
return update_call if update_call.ok?
|
491
|
-
|
492
|
-
puts 'update failed, inserting' if options[:verbose] || options[:debug]
|
493
|
-
wf.create(prepped)
|
494
|
-
end
|
495
|
-
|
496
|
-
def import_update(raw)
|
497
|
-
wf.update(raw[:id], raw, false)
|
400
|
+
require_relative 'subcommands/import'
|
401
|
+
WavefrontCli::Subcommand::Import.new(self, options).run!
|
498
402
|
end
|
499
403
|
|
500
404
|
def do_delete
|
@@ -604,18 +508,6 @@ module WavefrontCli
|
|
604
508
|
# rubocop:enable Metrics/MethodLength
|
605
509
|
# rubocop:enable Metrics/CyclomaticComplexity
|
606
510
|
|
607
|
-
# Most things will re-import with the POST method if you remove
|
608
|
-
# the ID.
|
609
|
-
#
|
610
|
-
def import_to_create(raw)
|
611
|
-
raw.each_with_object({}) do |(k, v), a|
|
612
|
-
a[k.to_sym] = v unless k == :id
|
613
|
-
end
|
614
|
-
rescue StandardError => e
|
615
|
-
puts e if options[:debug]
|
616
|
-
raise WavefrontCli::Exception::UnparseableInput
|
617
|
-
end
|
618
|
-
|
619
511
|
# Return a detailed description of one item, if an ID has been
|
620
512
|
# given, or all items if it has not.
|
621
513
|
#
|
@@ -665,14 +557,16 @@ module WavefrontCli
|
|
665
557
|
end
|
666
558
|
# rubocop:enable Metrics/MethodLength
|
667
559
|
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
560
|
+
# Most things will re-import with the POST method if you remove
|
561
|
+
# the ID.
|
562
|
+
#
|
563
|
+
def import_to_create(raw)
|
564
|
+
raw.each_with_object({}) do |(k, v), a|
|
565
|
+
a[k.to_sym] = v unless k == :id
|
566
|
+
end
|
567
|
+
rescue StandardError => e
|
568
|
+
puts e if options[:debug]
|
569
|
+
raise WavefrontCli::Exception::UnparseableInput
|
676
570
|
end
|
677
571
|
end
|
678
572
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../exception'
|
4
|
+
|
5
|
+
module WavefrontCli
|
6
|
+
module Helper
|
7
|
+
#
|
8
|
+
# Give it a path to a file (as a string) and it will return the
|
9
|
+
# contents of that file as a Ruby object. Automatically detects
|
10
|
+
# JSON and YAML. Raises an exception if it doesn't look like
|
11
|
+
# either. If path is '-' then it will read STDIN.
|
12
|
+
#
|
13
|
+
# @param path [String] the file to load
|
14
|
+
# @return [Hash] a Ruby object of the loaded file
|
15
|
+
# @raise WavefrontCli::Exception::UnsupportedFileFormat if the
|
16
|
+
# filetype is unknown.
|
17
|
+
# @raise pass through any error loading or parsing the file
|
18
|
+
#
|
19
|
+
class LoadFile
|
20
|
+
attr_reader :path
|
21
|
+
|
22
|
+
def initialize(path)
|
23
|
+
@path = path
|
24
|
+
end
|
25
|
+
|
26
|
+
def load
|
27
|
+
return load_from_stdin if path == '-'
|
28
|
+
|
29
|
+
file = Pathname.new(path)
|
30
|
+
extname = file.extname.downcase
|
31
|
+
|
32
|
+
raise WavefrontCli::Exception::FileNotFound unless file.exist?
|
33
|
+
|
34
|
+
return load_json(file) if extname == '.json'
|
35
|
+
return load_yaml(file) if %w[.yaml .yml].include?(extname)
|
36
|
+
|
37
|
+
raise WavefrontCli::Exception::UnsupportedFileFormat
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def load_json(file)
|
43
|
+
read_json(IO.read(file))
|
44
|
+
end
|
45
|
+
|
46
|
+
def load_yaml(file)
|
47
|
+
read_yaml(IO.read(file))
|
48
|
+
end
|
49
|
+
|
50
|
+
# Read STDIN and return a Ruby object, assuming that STDIN is
|
51
|
+
# valid JSON or YAML. This is a dumb method, it does no
|
52
|
+
# buffering, so STDIN must be a single block of data. This
|
53
|
+
# appears to be a valid assumption for use-cases of this CLI.
|
54
|
+
#
|
55
|
+
# @return [Object]
|
56
|
+
# @raise Wavefront::Exception::UnparseableInput if the input
|
57
|
+
# does not parse
|
58
|
+
#
|
59
|
+
def load_from_stdin
|
60
|
+
raw = STDIN.read
|
61
|
+
|
62
|
+
if raw.start_with?('---')
|
63
|
+
read_yaml(raw)
|
64
|
+
else
|
65
|
+
read_json(raw)
|
66
|
+
end
|
67
|
+
rescue RuntimeError
|
68
|
+
raise Wavefront::Exception::UnparseableInput
|
69
|
+
end
|
70
|
+
|
71
|
+
def read_json(io)
|
72
|
+
JSON.parse(io, symbolize_names: true)
|
73
|
+
end
|
74
|
+
|
75
|
+
def read_yaml(io)
|
76
|
+
YAML.safe_load(io, symbolize_names: true)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../helpers/load_file'
|
4
|
+
|
5
|
+
module WavefrontCli
|
6
|
+
module Subcommand
|
7
|
+
#
|
8
|
+
# Stuff to import an object
|
9
|
+
#
|
10
|
+
class Import
|
11
|
+
attr_reader :wf, :options
|
12
|
+
|
13
|
+
def initialize(calling_class, options)
|
14
|
+
@calling_class = calling_class
|
15
|
+
@wf = calling_class.wf
|
16
|
+
@options = options
|
17
|
+
@message = 'IMPORTED'
|
18
|
+
end
|
19
|
+
|
20
|
+
def run!
|
21
|
+
errs = 0
|
22
|
+
|
23
|
+
[raw_input].flatten.each do |obj|
|
24
|
+
resp = import_object(obj)
|
25
|
+
next if options[:noop]
|
26
|
+
|
27
|
+
errs += 1 unless resp.ok?
|
28
|
+
puts import_message(obj, resp)
|
29
|
+
end
|
30
|
+
|
31
|
+
exit errs
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def raw_input
|
37
|
+
WavefrontCli::Helper::LoadFile.new(options[:'<file>']).load
|
38
|
+
end
|
39
|
+
|
40
|
+
def import_message(obj, resp)
|
41
|
+
format('%-15<id>s %-10<status>s %<message>s',
|
42
|
+
id: obj[:id] || obj[:url],
|
43
|
+
status: resp.ok? ? @message : 'FAILED',
|
44
|
+
message: resp.status.message)
|
45
|
+
end
|
46
|
+
|
47
|
+
def import_object(raw)
|
48
|
+
raw = preprocess_rawfile(raw) if respond_to?(:preprocess_rawfile)
|
49
|
+
prepped = @calling_class.import_to_create(raw)
|
50
|
+
|
51
|
+
if options[:upsert]
|
52
|
+
import_upsert(raw, prepped)
|
53
|
+
elsif options[:update]
|
54
|
+
@message = 'UPDATED'
|
55
|
+
import_update(raw)
|
56
|
+
else
|
57
|
+
wf.create(prepped)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def import_upsert(raw, prepped)
|
62
|
+
update_call = import_update(raw)
|
63
|
+
|
64
|
+
if update_call.ok?
|
65
|
+
@message = 'UPDATED'
|
66
|
+
return update_call
|
67
|
+
end
|
68
|
+
|
69
|
+
puts 'update failed, inserting' if options[:verbose] || options[:debug]
|
70
|
+
wf.create(prepped)
|
71
|
+
end
|
72
|
+
|
73
|
+
def import_update(raw)
|
74
|
+
wf.update(raw[:id], raw, false)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/spec/test_mixins/import.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../../lib/wavefront-cli/helpers/load_file'
|
4
|
+
|
3
5
|
module WavefrontCliTest
|
4
6
|
#
|
5
7
|
# Mixin to test standard 'import' commands
|
@@ -25,7 +27,7 @@ module WavefrontCliTest
|
|
25
27
|
assert_abort_on_missing_creds("import #{import_file}")
|
26
28
|
end
|
27
29
|
|
28
|
-
def
|
30
|
+
def _test_import_update
|
29
31
|
Spy.teardown
|
30
32
|
|
31
33
|
out, err = capture_io do
|
@@ -38,15 +40,19 @@ module WavefrontCliTest
|
|
38
40
|
end
|
39
41
|
|
40
42
|
assert_empty(err)
|
41
|
-
assert_equal('1556812163465
|
43
|
+
assert_equal('1556812163465 UPDATED', out.strip)
|
42
44
|
|
43
45
|
assert_exits_with('File not found.', 'import /no/such/file')
|
44
46
|
assert_usage('import -u')
|
45
47
|
assert_abort_on_missing_creds("import -u #{import_file}")
|
46
48
|
end
|
47
49
|
|
50
|
+
def load_file(file)
|
51
|
+
WavefrontCli::Helper::LoadFile.new(file).load
|
52
|
+
end
|
53
|
+
|
48
54
|
def test_import_fields
|
49
|
-
x = cmd_instance.import_to_create(
|
55
|
+
x = cmd_instance.import_to_create(load_file(import_file))
|
50
56
|
assert_instance_of(Hash, x)
|
51
57
|
import_fields.each { |f| assert_includes(x.keys, f) }
|
52
58
|
blocked_import_fields.each { |f| refute_includes(x.keys, f) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wavefront-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.1.
|
4
|
+
version: 5.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Fisher
|
@@ -239,6 +239,7 @@ files:
|
|
239
239
|
- lib/wavefront-cli/event.rb
|
240
240
|
- lib/wavefront-cli/exception.rb
|
241
241
|
- lib/wavefront-cli/externallink.rb
|
242
|
+
- lib/wavefront-cli/helpers/load_file.rb
|
242
243
|
- lib/wavefront-cli/ingestionpolicy.rb
|
243
244
|
- lib/wavefront-cli/integration.rb
|
244
245
|
- lib/wavefront-cli/maintenancewindow.rb
|
@@ -272,6 +273,7 @@ files:
|
|
272
273
|
- lib/wavefront-cli/spy.rb
|
273
274
|
- lib/wavefront-cli/stdlib/array.rb
|
274
275
|
- lib/wavefront-cli/stdlib/string.rb
|
276
|
+
- lib/wavefront-cli/subcommands/import.rb
|
275
277
|
- lib/wavefront-cli/usage.rb
|
276
278
|
- lib/wavefront-cli/user.rb
|
277
279
|
- lib/wavefront-cli/usergroup.rb
|