wavefront-cli 5.1.0 → 5.1.1
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.
- 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
|