wavefront-cli 4.2.1 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +1 -0
- data/.rubocop.yml +1 -14
- data/.travis.yml +4 -4
- data/Gemfile +2 -0
- data/HISTORY.md +82 -60
- data/Rakefile +2 -0
- data/bin/wf +1 -0
- data/lib/wavefront-cli/alert.rb +13 -5
- data/lib/wavefront-cli/apitoken.rb +2 -0
- data/lib/wavefront-cli/base.rb +95 -47
- data/lib/wavefront-cli/cloudintegration.rb +6 -0
- data/lib/wavefront-cli/command_mixins/acl.rb +6 -1
- data/lib/wavefront-cli/command_mixins/tag.rb +2 -0
- data/lib/wavefront-cli/commands/.rubocop.yml +3 -4
- data/lib/wavefront-cli/commands/alert.rb +2 -1
- data/lib/wavefront-cli/commands/apitoken.rb +6 -0
- data/lib/wavefront-cli/commands/base.rb +30 -21
- data/lib/wavefront-cli/commands/cloudintegration.rb +2 -0
- data/lib/wavefront-cli/commands/config.rb +2 -0
- data/lib/wavefront-cli/commands/dashboard.rb +2 -0
- data/lib/wavefront-cli/commands/derivedmetric.rb +2 -0
- data/lib/wavefront-cli/commands/event.rb +3 -1
- data/lib/wavefront-cli/commands/integration.rb +2 -1
- data/lib/wavefront-cli/commands/link.rb +2 -0
- data/lib/wavefront-cli/commands/message.rb +2 -0
- data/lib/wavefront-cli/commands/metric.rb +2 -0
- data/lib/wavefront-cli/commands/notificant.rb +2 -0
- data/lib/wavefront-cli/commands/proxy.rb +2 -0
- data/lib/wavefront-cli/commands/query.rb +2 -0
- data/lib/wavefront-cli/commands/savedsearch.rb +2 -0
- data/lib/wavefront-cli/commands/serviceaccount.rb +58 -0
- data/lib/wavefront-cli/commands/settings.rb +2 -0
- data/lib/wavefront-cli/commands/source.rb +3 -1
- data/lib/wavefront-cli/commands/user.rb +4 -1
- data/lib/wavefront-cli/commands/usergroup.rb +3 -0
- data/lib/wavefront-cli/commands/webhook.rb +2 -0
- data/lib/wavefront-cli/commands/window.rb +2 -0
- data/lib/wavefront-cli/commands/write.rb +2 -0
- data/lib/wavefront-cli/config.rb +23 -12
- data/lib/wavefront-cli/constants.rb +10 -4
- data/lib/wavefront-cli/controller.rb +53 -22
- data/lib/wavefront-cli/dashboard.rb +3 -0
- data/lib/wavefront-cli/derivedmetric.rb +12 -11
- data/lib/wavefront-cli/display/alert.rb +7 -4
- data/lib/wavefront-cli/display/apitoken.rb +2 -0
- data/lib/wavefront-cli/display/base.rb +34 -8
- data/lib/wavefront-cli/display/cloudintegration.rb +4 -2
- data/lib/wavefront-cli/display/dashboard.rb +2 -0
- data/lib/wavefront-cli/display/derivedmetric.rb +2 -0
- data/lib/wavefront-cli/display/distribution.rb +2 -0
- data/lib/wavefront-cli/display/event.rb +2 -0
- data/lib/wavefront-cli/display/externallink.rb +2 -0
- data/lib/wavefront-cli/display/integration.rb +2 -0
- data/lib/wavefront-cli/display/maintenancewindow.rb +2 -0
- data/lib/wavefront-cli/display/message.rb +7 -3
- data/lib/wavefront-cli/display/metric.rb +3 -1
- data/lib/wavefront-cli/display/notificant.rb +3 -1
- data/lib/wavefront-cli/display/printer/long.rb +36 -11
- data/lib/wavefront-cli/display/printer/sparkline.rb +3 -0
- data/lib/wavefront-cli/display/printer/terse.rb +6 -1
- data/lib/wavefront-cli/display/proxy.rb +2 -0
- data/lib/wavefront-cli/display/query.rb +35 -24
- data/lib/wavefront-cli/display/savedsearch.rb +2 -0
- data/lib/wavefront-cli/display/serviceaccount.rb +60 -0
- data/lib/wavefront-cli/display/settings.rb +2 -0
- data/lib/wavefront-cli/display/source.rb +18 -4
- data/lib/wavefront-cli/display/user.rb +56 -10
- data/lib/wavefront-cli/display/usergroup.rb +25 -19
- data/lib/wavefront-cli/display/webhook.rb +2 -0
- data/lib/wavefront-cli/display/write.rb +6 -2
- data/lib/wavefront-cli/event.rb +83 -62
- data/lib/wavefront-cli/exception.rb +3 -0
- data/lib/wavefront-cli/externallink.rb +6 -4
- data/lib/wavefront-cli/integration.rb +2 -0
- data/lib/wavefront-cli/maintenancewindow.rb +28 -17
- data/lib/wavefront-cli/message.rb +4 -0
- data/lib/wavefront-cli/metric.rb +4 -1
- data/lib/wavefront-cli/notificant.rb +2 -0
- data/lib/wavefront-cli/opt_handler.rb +2 -0
- data/lib/wavefront-cli/output/base.rb +8 -3
- data/lib/wavefront-cli/output/csv.rb +2 -0
- data/lib/wavefront-cli/output/csv/base.rb +2 -0
- data/lib/wavefront-cli/output/csv/query.rb +14 -7
- data/lib/wavefront-cli/output/hcl.rb +2 -0
- data/lib/wavefront-cli/output/hcl/alert.rb +2 -0
- data/lib/wavefront-cli/output/hcl/base.rb +10 -4
- data/lib/wavefront-cli/output/hcl/dashboard.rb +17 -8
- data/lib/wavefront-cli/output/hcl/notificant.rb +2 -0
- data/lib/wavefront-cli/output/hcl/stdlib/array.rb +2 -0
- data/lib/wavefront-cli/output/hcl/stdlib/string.rb +2 -0
- data/lib/wavefront-cli/output/json.rb +2 -0
- data/lib/wavefront-cli/output/ruby.rb +2 -0
- data/lib/wavefront-cli/output/wavefront.rb +2 -0
- data/lib/wavefront-cli/output/wavefront/query.rb +7 -4
- data/lib/wavefront-cli/output/yaml.rb +2 -0
- data/lib/wavefront-cli/proxy.rb +15 -3
- data/lib/wavefront-cli/query.rb +14 -12
- data/lib/wavefront-cli/savedsearch.rb +2 -0
- data/lib/wavefront-cli/serviceaccount.rb +179 -0
- data/lib/wavefront-cli/settings.rb +2 -0
- data/lib/wavefront-cli/source.rb +2 -0
- data/lib/wavefront-cli/stdlib/array.rb +3 -0
- data/lib/wavefront-cli/stdlib/string.rb +17 -11
- data/lib/wavefront-cli/user.rb +10 -4
- data/lib/wavefront-cli/usergroup.rb +4 -2
- data/lib/wavefront-cli/version.rb +3 -1
- data/lib/wavefront-cli/webhook.rb +2 -0
- data/lib/wavefront-cli/write.rb +80 -46
- data/spec/.rubocop.yml +3 -16
- data/spec/constants.rb +21 -0
- data/spec/spec_helper.rb +8 -422
- data/spec/support/command_base.rb +82 -0
- data/spec/support/minitest_assertions.rb +262 -0
- data/spec/support/output_tester.rb +32 -0
- data/spec/support/supported_commands.rb +19 -0
- data/spec/test_mixins/acl.rb +169 -0
- data/spec/test_mixins/delete.rb +25 -0
- data/spec/test_mixins/deleteundelete.rb +106 -0
- data/spec/test_mixins/describe.rb +24 -0
- data/spec/test_mixins/dump.rb +43 -0
- data/spec/test_mixins/general.rb +11 -0
- data/spec/test_mixins/history.rb +35 -0
- data/spec/test_mixins/import.rb +65 -0
- data/spec/test_mixins/list.rb +29 -0
- data/spec/test_mixins/search.rb +98 -0
- data/spec/test_mixins/set.rb +47 -0
- data/spec/test_mixins/tag.rb +99 -0
- data/spec/wavefront-cli/alert_spec.rb +288 -111
- data/spec/wavefront-cli/apitoken_spec.rb +53 -24
- data/spec/wavefront-cli/base_spec.rb +9 -27
- data/spec/wavefront-cli/cloudintegration_spec.rb +65 -29
- data/spec/wavefront-cli/commands/alert_spec.rb +1 -0
- data/spec/wavefront-cli/commands/base_spec.rb +15 -13
- data/spec/wavefront-cli/commands/cloudintegration_spec.rb +1 -0
- data/spec/wavefront-cli/commands/config_spec.rb +3 -0
- data/spec/wavefront-cli/commands/dashboard_spec.rb +1 -0
- data/spec/wavefront-cli/commands/derivedmetric_spec.rb +1 -0
- data/spec/wavefront-cli/commands/event_spec.rb +1 -0
- data/spec/wavefront-cli/commands/link_spec.rb +1 -0
- data/spec/wavefront-cli/commands/message_spec.rb +1 -0
- data/spec/wavefront-cli/commands/metric_spec.rb +1 -0
- data/spec/wavefront-cli/commands/proxy_spec.rb +1 -0
- data/spec/wavefront-cli/commands/query_spec.rb +1 -0
- data/spec/wavefront-cli/commands/webhook_spec.rb +1 -0
- data/spec/wavefront-cli/commands/window_spec.rb +1 -0
- data/spec/wavefront-cli/commands/write_spec.rb +1 -0
- data/spec/wavefront-cli/config_spec.rb +25 -14
- data/spec/wavefront-cli/controller_spec.rb +13 -3
- data/spec/wavefront-cli/dashboard_spec.rb +125 -76
- data/spec/wavefront-cli/derivedmetric_spec.rb +83 -67
- data/spec/wavefront-cli/display/base_spec.rb +5 -7
- data/spec/wavefront-cli/display/printer/long_spec.rb +20 -16
- data/spec/wavefront-cli/display/printer/terse_spec.rb +5 -4
- data/spec/wavefront-cli/event_spec.rb +360 -18
- data/spec/wavefront-cli/externallink_spec.rb +92 -58
- data/spec/wavefront-cli/integration_spec.rb +129 -31
- data/spec/wavefront-cli/maintenancewindow_spec.rb +270 -32
- data/spec/wavefront-cli/message_spec.rb +73 -30
- data/spec/wavefront-cli/metric_spec.rb +60 -22
- data/spec/wavefront-cli/notificant_spec.rb +45 -32
- data/spec/wavefront-cli/opt_handler_spec.rb +4 -1
- data/spec/wavefront-cli/output/csv/query_spec.rb +21 -19
- data/spec/wavefront-cli/output/csv_spec.rb +5 -2
- data/spec/wavefront-cli/output/hcl_spec.rb +5 -2
- data/spec/wavefront-cli/output/helpers.rb +18 -0
- data/spec/wavefront-cli/output/json_spec.rb +3 -1
- data/spec/wavefront-cli/output/ruby_spec.rb +3 -1
- data/spec/wavefront-cli/output/wavefront/query_spec.rb +3 -1
- data/spec/wavefront-cli/output/wavefront_spec.rb +6 -4
- data/spec/wavefront-cli/output/yaml_spec.rb +3 -1
- data/spec/wavefront-cli/proxy_spec.rb +49 -27
- data/spec/wavefront-cli/query_spec.rb +174 -92
- data/spec/wavefront-cli/resources/responses/query.json +1 -0
- data/spec/wavefront-cli/resources/updates/alert.json +15 -0
- data/spec/wavefront-cli/resources/updates/dashboard.json +1 -0
- data/spec/wavefront-cli/savedsearch_spec.rb +35 -18
- data/spec/wavefront-cli/serviceaccount_spec.rb +399 -0
- data/spec/wavefront-cli/settings_spec.rb +42 -11
- data/spec/wavefront-cli/source_spec.rb +120 -23
- data/spec/wavefront-cli/stdlib/array_spec.rb +2 -1
- data/spec/wavefront-cli/stdlib/string_spec.rb +9 -6
- data/spec/wavefront-cli/user_spec.rb +278 -108
- data/spec/wavefront-cli/usergroup_spec.rb +152 -102
- data/spec/wavefront-cli/webhook_spec.rb +30 -15
- data/spec/wavefront-cli/write_spec.rb +25 -1
- data/wavefront-cli.gemspec +5 -3
- metadata +65 -21
- data/spec/wavefront-cli/commands/spec_helper.rb +0 -3
- data/spec/wavefront-cli/display/spec_helper.rb +0 -3
data/lib/wavefront-cli/write.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'wavefront-sdk/support/mixins'
|
2
4
|
require_relative 'base'
|
3
5
|
|
@@ -10,15 +12,15 @@ module WavefrontCli
|
|
10
12
|
class Write < Base
|
11
13
|
attr_reader :fmt
|
12
14
|
include Wavefront::Mixins
|
13
|
-
SPLIT_PATTERN = /\s(?=(?:[^"]|"[^"]*")*$)
|
15
|
+
SPLIT_PATTERN = /\s(?=(?:[^"]|"[^"]*")*$)/.freeze
|
14
16
|
|
15
17
|
# rubocop:disable Metrics/AbcSize
|
16
18
|
def do_point
|
17
|
-
p = { path: options[:'<metric>'],
|
18
|
-
value: options[:'<value>'].delete('\\').to_f }
|
19
|
-
|
20
19
|
tags = tags_to_hash(options[:tag])
|
21
20
|
|
21
|
+
p = { path: options[:'<metric>'],
|
22
|
+
value: options[:'<value>'].delete('\\').to_f }
|
23
|
+
|
22
24
|
p[:tags] = tags unless tags.empty?
|
23
25
|
p[:source] = options[:host] if options[:host]
|
24
26
|
p[:ts] = parse_time(options[:time]) if options[:time]
|
@@ -32,17 +34,19 @@ module WavefrontCli
|
|
32
34
|
process_input(options[:'<file>'])
|
33
35
|
end
|
34
36
|
|
35
|
-
# rubocop:disable Metrics/AbcSize
|
36
37
|
def do_distribution
|
37
|
-
|
38
|
-
|
39
|
-
value: mk_dist }
|
38
|
+
send_point(make_distribution_point(tags_to_hash(options[:tag])))
|
39
|
+
end
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
# rubocop:disable Metrics/AbcSize
|
42
|
+
def make_distribution_point(tags)
|
43
|
+
{ path: options[:'<metric>'],
|
44
|
+
interval: options[:interval] || 'M',
|
45
|
+
tags: tags,
|
46
|
+
value: mk_dist }.tap do |p|
|
47
|
+
p[:source] = options[:host] if options[:host]
|
48
|
+
p[:ts] = parse_time(options[:time]) if options[:time]
|
49
|
+
end
|
46
50
|
end
|
47
51
|
# rubocop:enable Metrics/AbcSize
|
48
52
|
|
@@ -65,24 +69,26 @@ module WavefrontCli
|
|
65
69
|
#
|
66
70
|
def _sdk_class
|
67
71
|
return 'Wavefront::Distribution' if distribution?
|
72
|
+
|
68
73
|
'Wavefront::Write'
|
69
74
|
end
|
70
75
|
|
71
76
|
def distribution?
|
72
77
|
return true if options[:distribution]
|
78
|
+
|
73
79
|
options[:infileformat]&.include?('d')
|
74
80
|
end
|
75
81
|
|
76
82
|
def mk_creds
|
77
|
-
{ proxy:
|
78
|
-
port:
|
79
|
-
socket:
|
83
|
+
{ proxy: options[:proxy],
|
84
|
+
port: options[:port] || default_port,
|
85
|
+
socket: options[:socket],
|
80
86
|
endpoint: options[:endpoint],
|
81
|
-
token:
|
87
|
+
token: options[:token] }
|
82
88
|
end
|
83
89
|
|
84
90
|
def default_port
|
85
|
-
distribution? ?
|
91
|
+
distribution? ? 40_000 : 2878
|
86
92
|
end
|
87
93
|
|
88
94
|
def validate_opts
|
@@ -90,10 +96,12 @@ module WavefrontCli
|
|
90
96
|
|
91
97
|
if options[:using] == 'unix'
|
92
98
|
return true if options[:socket]
|
99
|
+
|
93
100
|
raise(WavefrontCli::Exception::CredentialError, 'No socket path.')
|
94
101
|
end
|
95
102
|
|
96
103
|
return true if options[:proxy]
|
104
|
+
|
97
105
|
raise(WavefrontCli::Exception::CredentialError, 'No proxy address.')
|
98
106
|
end
|
99
107
|
|
@@ -115,8 +123,7 @@ module WavefrontCli
|
|
115
123
|
def send_point(point)
|
116
124
|
call_write(point)
|
117
125
|
rescue Wavefront::Exception::InvalidEndpoint
|
118
|
-
abort format("Could not connect to proxy '
|
119
|
-
options[:proxy], options[:port])
|
126
|
+
abort format("Could not connect to proxy '%<proxy>s:%<port>s'.", options)
|
120
127
|
end
|
121
128
|
|
122
129
|
# Read the input, from a file or from STDIN, and turn each line
|
@@ -237,6 +244,7 @@ module WavefrontCli
|
|
237
244
|
options[:metric] ? [options[:metric], m].join('.') : m
|
238
245
|
rescue TypeError
|
239
246
|
return options[:metric] if options[:metric]
|
247
|
+
|
240
248
|
raise
|
241
249
|
end
|
242
250
|
|
@@ -264,14 +272,16 @@ module WavefrontCli
|
|
264
272
|
# @raise WavefrontCli::Exception::UnparseableInput if the line
|
265
273
|
# doesn't look right
|
266
274
|
#
|
267
|
-
# rubocop:disable Metrics/AbcSize
|
268
275
|
# rubocop:disable Metrics/CyclomaticComplexity
|
276
|
+
# rubocop:disable Metrics/MethodLength
|
277
|
+
# rubocop:disable Metrics/AbcSize
|
269
278
|
def process_line(line)
|
270
279
|
return true if line.empty?
|
280
|
+
|
271
281
|
chunks = line.split(SPLIT_PATTERN, fmt.length)
|
272
282
|
enough_fields?(line) # can raise exception
|
273
283
|
|
274
|
-
point = { path:
|
284
|
+
point = { path: extract_path(chunks),
|
275
285
|
value: extract_value(chunks) }
|
276
286
|
|
277
287
|
tags = line_tags(chunks)
|
@@ -283,8 +293,9 @@ module WavefrontCli
|
|
283
293
|
p[:interval] = options[:interval] || 'm' if fmt.include?('d')
|
284
294
|
end
|
285
295
|
end
|
286
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
287
296
|
# rubocop:enable Metrics/AbcSize
|
297
|
+
# rubocop:enable Metrics/MethodLength
|
298
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
288
299
|
|
289
300
|
# We can get tags from the file, from the -T option, or both.
|
290
301
|
# Merge them, making the -T win if there is a collision.
|
@@ -321,29 +332,49 @@ module WavefrontCli
|
|
321
332
|
#
|
322
333
|
# @param fmt [String] format of input file
|
323
334
|
#
|
324
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
325
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
326
|
-
# rubocop:disable Metrics/AbcSize
|
327
335
|
def valid_format?(fmt)
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
336
|
+
format_string_has_v_or_d?(fmt)
|
337
|
+
format_string_does_not_have_v_and_d?(fmt)
|
338
|
+
format_string_is_all_valid_chars?(fmt)
|
339
|
+
format_string_has_unique_chars?(fmt)
|
340
|
+
format_string_has_big_t_only_at_the_end?(fmt)
|
341
|
+
end
|
342
|
+
|
343
|
+
def format_string_has_v_or_d?(fmt)
|
344
|
+
return true if fmt.include?('v') || fmt.include?('d')
|
345
|
+
|
346
|
+
raise(WavefrontCli::Exception::UnparseableInput,
|
347
|
+
"format string must include 'v' or 'd'")
|
348
|
+
end
|
349
|
+
|
350
|
+
def format_string_does_not_have_v_and_d?(fmt)
|
351
|
+
return true unless fmt.include?('v') && fmt.include?('d')
|
352
|
+
|
353
|
+
raise(WavefrontCli::Exception::UnparseableInput,
|
354
|
+
"'v' and 'd' are mutually exclusive")
|
355
|
+
end
|
356
|
+
|
357
|
+
def format_string_is_all_valid_chars?(fmt)
|
358
|
+
return true if fmt =~ /^[dmstTv]+$/
|
359
|
+
|
360
|
+
raise(WavefrontCli::Exception::UnparseableInput,
|
361
|
+
'unsupported field in format string')
|
362
|
+
end
|
363
|
+
|
364
|
+
def format_string_has_unique_chars?(fmt)
|
365
|
+
return true if fmt.chars.sort == fmt.chars.uniq.sort
|
366
|
+
|
367
|
+
raise(WavefrontCli::Exception::UnparseableInput,
|
368
|
+
'repeated field in format string')
|
369
|
+
end
|
370
|
+
|
371
|
+
def format_string_has_big_t_only_at_the_end?(fmt)
|
372
|
+
return true unless fmt.include?('T')
|
373
|
+
return true if fmt.end_with?('T')
|
374
|
+
|
375
|
+
raise(WavefrontCli::Exception::UnparseableInput,
|
376
|
+
"if used, 'T' must come at end of format string")
|
377
|
+
end
|
347
378
|
|
348
379
|
# Make sure we have the right number of columns, according to
|
349
380
|
# the format string. We want to take every precaution we can to
|
@@ -359,8 +390,11 @@ module WavefrontCli
|
|
359
390
|
ncols = line.split(SPLIT_PATTERN).length
|
360
391
|
return true if fmt.include?('T') && ncols >= fmt.length
|
361
392
|
return true if ncols == fmt.length
|
393
|
+
|
362
394
|
raise(WavefrontCli::Exception::UnparseableInput,
|
363
|
-
format('Expected
|
395
|
+
format('Expected %<expected>s fields, got %<got>s',
|
396
|
+
expected: fmt.length,
|
397
|
+
got: ncols))
|
364
398
|
end
|
365
399
|
|
366
400
|
# Although the SDK does value checking, we'll add another layer
|
data/spec/.rubocop.yml
CHANGED
@@ -1,22 +1,9 @@
|
|
1
|
-
|
2
|
-
TargetRubyVersion: 2.2
|
3
|
-
|
4
|
-
Style/FormatStringToken:
|
5
|
-
Enabled: false
|
6
|
-
|
7
|
-
# Allow long blocks of tests
|
8
|
-
#
|
9
|
-
Metrics/BlockLength:
|
10
|
-
Max: 120
|
11
|
-
|
1
|
+
---
|
12
2
|
Metrics/MethodLength:
|
13
|
-
Max:
|
3
|
+
Max: 30
|
14
4
|
|
15
5
|
Metrics/AbcSize:
|
16
6
|
Max: 45
|
17
7
|
|
18
8
|
Metrics/ClassLength:
|
19
|
-
Max:
|
20
|
-
|
21
|
-
Metrics/CyclomaticComplexity:
|
22
|
-
Max: 10
|
9
|
+
Max: 250
|
data/spec/constants.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'inifile'
|
5
|
+
|
6
|
+
# Constants for testing
|
7
|
+
|
8
|
+
ROOT = Pathname.new(__dir__).parent
|
9
|
+
|
10
|
+
CMD = 'wf'
|
11
|
+
TW = 80
|
12
|
+
|
13
|
+
ENDPOINT = 'metrics.wavefront.com'
|
14
|
+
TOKEN = '0123456789-ABCDEF'
|
15
|
+
RES_DIR = ROOT + 'spec' + 'wavefront-cli' + 'resources'
|
16
|
+
CF = RES_DIR + 'wavefront.conf'
|
17
|
+
CF_VAL = IniFile.load(CF)
|
18
|
+
JSON_POST_HEADERS = {
|
19
|
+
'Content-Type': 'application/json', Accept: 'application/json'
|
20
|
+
}.freeze
|
21
|
+
TEE_ZERO = Time.now.freeze
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
require 'webmock/minitest'
|
3
5
|
require 'spy/integration'
|
@@ -8,47 +10,22 @@ require 'minitest/spec'
|
|
8
10
|
require 'pathname'
|
9
11
|
require_relative '../lib/wavefront-cli/controller'
|
10
12
|
|
11
|
-
def all_commands
|
12
|
-
cmd_dir = ROOT + 'lib' + 'wavefront-cli' + 'commands'
|
13
|
-
|
14
|
-
files = cmd_dir.children.select do |f|
|
15
|
-
f.extname == '.rb' && f.basename.to_s != 'base.rb'
|
16
|
-
end
|
17
|
-
|
18
|
-
files.each.with_object([]) { |c, a| a.<< c.basename.to_s.chomp('.rb') }
|
19
|
-
end
|
20
|
-
|
21
13
|
unless defined?(CMD)
|
22
14
|
ROOT = Pathname.new(__FILE__).dirname.parent
|
23
|
-
CMD = 'wavefront'
|
24
|
-
ENDPOINT = 'metrics.wavefront.com'
|
25
|
-
TOKEN = '0123456789-ABCDEF'
|
15
|
+
CMD = 'wavefront'
|
16
|
+
ENDPOINT = 'metrics.wavefront.com'
|
17
|
+
TOKEN = '0123456789-ABCDEF'
|
26
18
|
RES_DIR = Pathname.new(__FILE__).dirname + 'wavefront-cli' + 'resources'
|
27
19
|
CF = RES_DIR + 'wavefront.conf'
|
28
20
|
CF_VAL = IniFile.load(CF)
|
29
21
|
JSON_POST_HEADERS = {
|
30
22
|
'Content-Type': 'application/json', Accept: 'application/json'
|
31
23
|
}.freeze
|
32
|
-
|
33
|
-
BAD_TAG = '*BAD_TAG*'.freeze
|
24
|
+
BAD_TAG = '*BAD_TAG*'
|
34
25
|
TW = 80
|
35
26
|
HOME_CONFIG = Pathname.new(ENV['HOME']) + '.wavefront'
|
36
27
|
end
|
37
28
|
|
38
|
-
# Return an array of CLI permutations and the values to which they relate
|
39
|
-
#
|
40
|
-
def permutations
|
41
|
-
[["-t #{TOKEN} -E #{ENDPOINT}", { t: TOKEN, e: ENDPOINT }],
|
42
|
-
["-c #{CF}", { t: CF_VAL['default']['token'],
|
43
|
-
e: CF_VAL['default']['endpoint'] }],
|
44
|
-
["-c #{CF} -P other", { t: CF_VAL['other']['token'],
|
45
|
-
e: CF_VAL['other']['endpoint'] }],
|
46
|
-
["-c #{CF} -P other -t #{TOKEN}", { t: TOKEN,
|
47
|
-
e: CF_VAL['other']['endpoint'] }],
|
48
|
-
["-c #{CF} -E #{ENDPOINT}", { t: CF_VAL['default']['token'],
|
49
|
-
e: ENDPOINT }]]
|
50
|
-
end
|
51
|
-
|
52
29
|
# Object returned by cmd_to_call. Has just enough methods to satisfy
|
53
30
|
# the SDK
|
54
31
|
#
|
@@ -70,356 +47,6 @@ end
|
|
70
47
|
|
71
48
|
CANNED_RESPONSE = DummyResponse.new
|
72
49
|
|
73
|
-
# Match a command to the final API call it should produce, applying
|
74
|
-
# options in as many combinations as possible, and ensuring the
|
75
|
-
# requisite display methods are called.
|
76
|
-
#
|
77
|
-
# @param cmd [String] command line args to supply to the Wavefront
|
78
|
-
# @param call [Hash]
|
79
|
-
# @param spies [Array[Hash]] array of spies to set up, for stubbing
|
80
|
-
# methods in any class. Hash has keys :class, :method, :return.
|
81
|
-
# rubocop:disable Metrics/AbcSize
|
82
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
83
|
-
def cmd_to_call(word, args, call, sdk_class = nil, spies = [])
|
84
|
-
headers = { 'Accept': /.*/,
|
85
|
-
'Accept-Encoding': /.*/,
|
86
|
-
'Authorization': 'Bearer 0123456789-ABCDEF',
|
87
|
-
'User-Agent': "wavefront-cli-#{WF_CLI_VERSION}" }
|
88
|
-
|
89
|
-
sdk_class ||= Object.const_get("WavefrontCli::#{word.capitalize}")
|
90
|
-
|
91
|
-
headers.merge!(call[:headers]) if call.key?(:headers)
|
92
|
-
method = call[:method] || :get
|
93
|
-
fmts = call[:formats] ? ['-f json', '-f yaml', '-f human', ''] : ['']
|
94
|
-
|
95
|
-
permutations.each do |opts, vals|
|
96
|
-
describe "with #{word} #{args}" do
|
97
|
-
fmts.each do |fmt|
|
98
|
-
cmd = "#{word} #{args} #{opts} #{fmt}"
|
99
|
-
|
100
|
-
uri = if call[:regex]
|
101
|
-
Regexp.new(call[:path])
|
102
|
-
else
|
103
|
-
'https://' + vals[:e] + call[:path]
|
104
|
-
end
|
105
|
-
|
106
|
-
h = headers.dup
|
107
|
-
h[:Authorization] = "Bearer #{vals[:t]}"
|
108
|
-
|
109
|
-
it "runs #{cmd} and makes the correct API call" do
|
110
|
-
if call.key?(:body)
|
111
|
-
stub_request(method, uri).with(headers: h, body: call[:body])
|
112
|
-
.to_return(body: {}.to_json,
|
113
|
-
status: 200)
|
114
|
-
else
|
115
|
-
stub_request(method, uri).with(headers: h)
|
116
|
-
.to_return(body: {}.to_json,
|
117
|
-
status: 200)
|
118
|
-
end
|
119
|
-
|
120
|
-
require "wavefront-sdk/#{sdk_class.name.split('::').last.downcase}"
|
121
|
-
spies.each do |spy|
|
122
|
-
Spy.on_instance_method(
|
123
|
-
Object.const_get(spy[:class]), spy[:method]
|
124
|
-
).and_return(spy[:return])
|
125
|
-
end
|
126
|
-
|
127
|
-
Spy.on_instance_method(
|
128
|
-
Object.const_get('Wavefront::ApiCaller'), :respond
|
129
|
-
).and_return(CANNED_RESPONSE)
|
130
|
-
|
131
|
-
d = Spy.on_instance_method(sdk_class, :display)
|
132
|
-
WavefrontCliController.new(cmd.split)
|
133
|
-
assert d.has_been_called?
|
134
|
-
assert_requested(method, uri, headers: h)
|
135
|
-
WebMock.reset!
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
142
|
-
# rubocop:enable Metrics/AbcSize
|
143
|
-
|
144
|
-
# Test no-ops
|
145
|
-
#
|
146
|
-
# @param output [Array] [URI, params]
|
147
|
-
#
|
148
|
-
def cmd_noop(word, cmd, output, sdk_class = nil)
|
149
|
-
cmd = [word] + cmd.split + ['--noop'] + ["-t #{TOKEN} -E #{ENDPOINT}"]
|
150
|
-
|
151
|
-
exit_code = output == :impossible ? 1 : 0
|
152
|
-
|
153
|
-
it "runs #{cmd.join(' ')} and gets output without an API call" do
|
154
|
-
out, err = capture_io do
|
155
|
-
sdk_class ||= Object.const_get("WavefrontCli::#{word.capitalize}")
|
156
|
-
require "wavefront-sdk/#{sdk_class.name.split('::').last.downcase}"
|
157
|
-
begin
|
158
|
-
WavefrontCliController.new(cmd).run
|
159
|
-
rescue SystemExit => e
|
160
|
-
assert_equal(exit_code, e.status)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
if output == :impossible
|
165
|
-
assert_equal('Multiple API call operations cannot be performed ' \
|
166
|
-
"as no-ops.\n", err)
|
167
|
-
assert_empty(out)
|
168
|
-
else
|
169
|
-
out = out.split("\n")
|
170
|
-
refute_empty(out)
|
171
|
-
assert_equal("SDK INFO: uri: #{output.first}", out.first)
|
172
|
-
if output.size > 1
|
173
|
-
assert_equal("SDK INFO: params: #{output.last}", out.last)
|
174
|
-
end
|
175
|
-
assert_empty(err)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
# Wrapper to standard noop tests
|
181
|
-
#
|
182
|
-
def noop_tests(cmd, id, nodelete = false, pth = nil, sdk_class = nil)
|
183
|
-
pth ||= cmd
|
184
|
-
cmd_noop(cmd, 'list',
|
185
|
-
["GET https://metrics.wavefront.com/api/v2/#{pth}",
|
186
|
-
offset: 0, limit: 100], sdk_class)
|
187
|
-
cmd_noop(cmd, "describe #{id}",
|
188
|
-
["GET https://metrics.wavefront.com/api/v2/#{pth}/#{id}"],
|
189
|
-
sdk_class)
|
190
|
-
|
191
|
-
if nodelete == :skip
|
192
|
-
elsif nodelete
|
193
|
-
cmd_noop(cmd, "delete #{id}", :impossible, sdk_class)
|
194
|
-
else
|
195
|
-
cmd_noop(cmd, "delete #{id}",
|
196
|
-
["DELETE https://metrics.wavefront.com/api/v2/#{pth}/#{id}"],
|
197
|
-
sdk_class)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
# Run a command we expect to fail, returning stdout and stderr
|
202
|
-
#
|
203
|
-
def fail_command(cmd)
|
204
|
-
capture_io do
|
205
|
-
begin
|
206
|
-
WavefrontCliController.new(cmd.split).run
|
207
|
-
rescue SystemExit => e
|
208
|
-
assert_equal(1, e.status)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def invalid_something(cmd, subcmds, thing)
|
214
|
-
subcmds.each do |sc|
|
215
|
-
it "fails '#{sc}' because of an invalid #{thing}" do
|
216
|
-
_out, err = fail_command("#{cmd} #{sc}")
|
217
|
-
assert_match(/^'.*' is not a valid #{thing}.\n$/, err)
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
def invalid_tags(cmd, subcmds)
|
223
|
-
subcmds.each do |sc|
|
224
|
-
it "fails '#{sc}' because of an invalid tag" do
|
225
|
-
_out, err = fail_command("#{cmd} #{sc}")
|
226
|
-
assert_equal(err, "Invalid input. '#{BAD_TAG}' is not a valid tag.\n")
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
def invalid_ids(cmd, subcmds)
|
232
|
-
subcmds.each do |sc|
|
233
|
-
it "fails '#{sc}' on invalid input" do
|
234
|
-
_out, err = fail_command("#{cmd} #{sc}")
|
235
|
-
assert_match(/^'.+' is not a valid \w/, err)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
# Without a token, you should get an error. If you don't supply an
|
241
|
-
# endpoint, it will default to 'metrics.wavefront.com'. The
|
242
|
-
# behaviour is different now, depending on whether you have
|
243
|
-
# ~/.wavefront or not.
|
244
|
-
#
|
245
|
-
def missing_creds(cmd, subcmds)
|
246
|
-
describe 'commands with missing credentials' do
|
247
|
-
subcmds.each do |subcmd|
|
248
|
-
it "'#{subcmd}' tells the user config file not found" do
|
249
|
-
_out, err = fail_command("#{cmd} #{subcmd} -c /f")
|
250
|
-
assert_equal("Configuration file '/f' not found.\n", err)
|
251
|
-
end
|
252
|
-
|
253
|
-
# I've generally got a config file on my dev box, but Travis
|
254
|
-
# won't have one. Therefore this test probably won't get run
|
255
|
-
# locally, but it will get run in CI, which is what counts.
|
256
|
-
#
|
257
|
-
next if HOME_CONFIG.exist?
|
258
|
-
|
259
|
-
it "'#{subcmd}' errors and tells the user to generate config" do
|
260
|
-
out, _err = fail_command("#{cmd} #{subcmd}")
|
261
|
-
assert_match(/Please run 'wf config setup'/, out)
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
def search_tests(word, id, klass = nil, pth = nil)
|
268
|
-
pth ||= word
|
269
|
-
cmd_to_call(word,
|
270
|
-
"search id=#{id}",
|
271
|
-
{ method: :post, path: "/api/v2/search/#{pth}",
|
272
|
-
body: { limit: 10,
|
273
|
-
offset: 0,
|
274
|
-
query: [{ key: 'id',
|
275
|
-
value: id,
|
276
|
-
matchingMethod: 'EXACT',
|
277
|
-
negated: false }],
|
278
|
-
sort: { field: 'id', ascending: true } },
|
279
|
-
headers: JSON_POST_HEADERS },
|
280
|
-
klass)
|
281
|
-
|
282
|
-
cmd_to_call(word,
|
283
|
-
"search id=#{id} thing!^word",
|
284
|
-
{ method: :post, path: "/api/v2/search/#{pth}",
|
285
|
-
body: { limit: 10,
|
286
|
-
offset: 0,
|
287
|
-
query: [{ key: 'id',
|
288
|
-
value: id,
|
289
|
-
matchingMethod: 'EXACT',
|
290
|
-
negated: false },
|
291
|
-
{ key: 'thing',
|
292
|
-
value: 'word',
|
293
|
-
matchingMethod: 'STARTSWITH',
|
294
|
-
negated: true }],
|
295
|
-
sort: { field: 'id', ascending: true } },
|
296
|
-
headers: JSON_POST_HEADERS },
|
297
|
-
klass)
|
298
|
-
|
299
|
-
cmd_to_call(word,
|
300
|
-
'search id!~avoid',
|
301
|
-
{ method: :post, path: "/api/v2/search/#{pth}",
|
302
|
-
body: { limit: 10,
|
303
|
-
offset: 0,
|
304
|
-
query: [{ key: 'id',
|
305
|
-
value: 'avoid',
|
306
|
-
matchingMethod: 'CONTAINS',
|
307
|
-
negated: true }],
|
308
|
-
sort: { field: 'id', ascending: true } },
|
309
|
-
headers: JSON_POST_HEADERS },
|
310
|
-
klass)
|
311
|
-
end
|
312
|
-
|
313
|
-
# Generic list tests, needed by most commands
|
314
|
-
#
|
315
|
-
def list_tests(cmd, pth = nil, klass = nil)
|
316
|
-
pth ||= cmd
|
317
|
-
cmd_to_call(cmd, 'list', { path: "/api/v2/#{pth}?limit=100&offset=0" },
|
318
|
-
klass)
|
319
|
-
cmd_to_call(cmd, 'list -L 50',
|
320
|
-
{ path: "/api/v2/#{pth}?limit=50&offset=0" },
|
321
|
-
klass)
|
322
|
-
cmd_to_call(cmd, 'list -L 20 -o 8',
|
323
|
-
{ path: "/api/v2/#{pth}?limit=20&offset=8" }, klass)
|
324
|
-
cmd_to_call(cmd, 'list -o 60',
|
325
|
-
{ path: "/api/v2/#{pth}?limit=100&offset=60" },
|
326
|
-
klass)
|
327
|
-
end
|
328
|
-
|
329
|
-
def tag_tests(cmd, id, bad_id, pth = nil, klass = nil)
|
330
|
-
pth ||= cmd
|
331
|
-
cmd_to_call(cmd, "tags #{id}", { path: "/api/v2/#{pth}/#{id}/tag" },
|
332
|
-
klass)
|
333
|
-
cmd_to_call(cmd, "tag set #{id} mytag",
|
334
|
-
{ method: :post,
|
335
|
-
path: "/api/v2/#{pth}/#{id}/tag",
|
336
|
-
body: %w[mytag].to_json,
|
337
|
-
headers: JSON_POST_HEADERS }, klass)
|
338
|
-
cmd_to_call(cmd, "tag set #{id} mytag1 mytag2",
|
339
|
-
{ method: :post,
|
340
|
-
path: "/api/v2/#{pth}/#{id}/tag",
|
341
|
-
body: %w[mytag1 mytag2].to_json,
|
342
|
-
headers: JSON_POST_HEADERS }, klass)
|
343
|
-
cmd_to_call(cmd, "tag add #{id} mytag",
|
344
|
-
{ method: :put, path: "/api/v2/#{pth}/#{id}/tag/mytag" },
|
345
|
-
klass)
|
346
|
-
cmd_to_call(cmd, "tag delete #{id} mytag",
|
347
|
-
{ method: :delete, path: "/api/v2/#{pth}/#{id}/tag/mytag" },
|
348
|
-
klass)
|
349
|
-
cmd_to_call(cmd, "tag clear #{id}", { method: :post,
|
350
|
-
path: "/api/v2/#{pth}/#{id}/tag",
|
351
|
-
body: [].to_json,
|
352
|
-
headers: JSON_POST_HEADERS }, klass)
|
353
|
-
invalid_ids(cmd, ["tags #{bad_id}",
|
354
|
-
"tag clear #{bad_id}",
|
355
|
-
"tag add #{bad_id} mytag",
|
356
|
-
"tag delete #{bad_id} mytag"])
|
357
|
-
invalid_tags(cmd, ["tag add #{id} #{BAD_TAG}",
|
358
|
-
"tag delete #{id} #{BAD_TAG}"])
|
359
|
-
end
|
360
|
-
|
361
|
-
def acl_tests(cmd, id, bad_id, pth = nil, klass = nil)
|
362
|
-
gid1 = '2659191e-aad4-4302-a94e-9667e1517127'
|
363
|
-
pth ||= cmd
|
364
|
-
|
365
|
-
cmd_to_call(cmd, "acls #{id}", { path: "/api/v2/#{pth}/acl?id=#{id}" },
|
366
|
-
klass)
|
367
|
-
|
368
|
-
spies = [{ class: "WavefrontCli::#{cmd.capitalize}",
|
369
|
-
method: :do_acls,
|
370
|
-
return: true }]
|
371
|
-
|
372
|
-
cmd_to_call(cmd, "acl clear #{id}",
|
373
|
-
{ method: :put,
|
374
|
-
path: "/api/v2/#{pth}/acl/set",
|
375
|
-
body: [{ entityId: id,
|
376
|
-
viewAcl: [],
|
377
|
-
modifyAcl: %w[abcd-1234] }].to_json,
|
378
|
-
headers: JSON_POST_HEADERS }, klass, [
|
379
|
-
{ class: "WavefrontCli::#{cmd.capitalize}",
|
380
|
-
method: :everyone_id,
|
381
|
-
return: 'abcd-1234' },
|
382
|
-
{ class: "WavefrontCli::#{cmd.capitalize}",
|
383
|
-
method: :do_acls,
|
384
|
-
return: true }
|
385
|
-
])
|
386
|
-
|
387
|
-
cmd_to_call(cmd, "acl grant view on #{id} to testuser1 testuser2",
|
388
|
-
{ method: :post,
|
389
|
-
path: "/api/v2/#{pth}/acl/add",
|
390
|
-
body: [{ entityId: id,
|
391
|
-
viewAcl: %w[testuser1 testuser2],
|
392
|
-
modifyAcl: [] }].to_json,
|
393
|
-
headers: JSON_POST_HEADERS }, klass, spies)
|
394
|
-
cmd_to_call(cmd, "acl revoke view on #{id} from testuser1",
|
395
|
-
{ method: :post,
|
396
|
-
path: "/api/v2/#{pth}/acl/remove",
|
397
|
-
body: [{ entityId: id,
|
398
|
-
viewAcl: %w[testuser1],
|
399
|
-
modifyAcl: [] }].to_json,
|
400
|
-
headers: JSON_POST_HEADERS }, klass, spies)
|
401
|
-
|
402
|
-
cmd_to_call(cmd, "acl grant modify on #{id} to testuser1",
|
403
|
-
{ method: :post,
|
404
|
-
path: "/api/v2/#{pth}/acl/add",
|
405
|
-
body: [{ entityId: id,
|
406
|
-
viewAcl: [],
|
407
|
-
modifyAcl: %w[testuser1] }].to_json,
|
408
|
-
headers: JSON_POST_HEADERS }, klass, spies)
|
409
|
-
cmd_to_call(cmd, "acl revoke modify on #{id} from testuser1",
|
410
|
-
{ method: :post,
|
411
|
-
path: "/api/v2/#{pth}/acl/remove",
|
412
|
-
body: [{ entityId: id,
|
413
|
-
viewAcl: [],
|
414
|
-
modifyAcl: %w[testuser1] }].to_json,
|
415
|
-
headers: JSON_POST_HEADERS }, klass, spies)
|
416
|
-
|
417
|
-
invalid_ids(cmd, ["acls #{bad_id}",
|
418
|
-
"acl clear #{bad_id}",
|
419
|
-
"acl grant modify on #{bad_id} to testuser1",
|
420
|
-
"acl revoke view on #{bad_id} from #{gid1}"])
|
421
|
-
end
|
422
|
-
|
423
50
|
# Unit tests
|
424
51
|
#
|
425
52
|
class CliMethodTest < MiniTest::Test
|
@@ -438,48 +65,6 @@ class CliMethodTest < MiniTest::Test
|
|
438
65
|
end
|
439
66
|
end
|
440
67
|
|
441
|
-
# Load in a canned query response
|
442
|
-
#
|
443
|
-
def load_query_response
|
444
|
-
JSON.parse(IO.read(RES_DIR + 'sample_query_response.json'),
|
445
|
-
symbolize_names: true)
|
446
|
-
end
|
447
|
-
|
448
|
-
def load_raw_query_response
|
449
|
-
JSON.parse(IO.read(RES_DIR + 'sample_raw_query_response.json'),
|
450
|
-
symbolize_names: true)
|
451
|
-
end
|
452
|
-
|
453
|
-
# We keep a bunch of Wavefront API responses as text files alongside
|
454
|
-
# canned responses in various formats. This class groups helpers for
|
455
|
-
# doing that.
|
456
|
-
#
|
457
|
-
class OutputTester
|
458
|
-
# @param file [String] filename to load
|
459
|
-
# @param only_items [Bool] true for the items hash, false for the
|
460
|
-
# whole loadedobject
|
461
|
-
# @return [Object] canned raw responses used to test outputs
|
462
|
-
#
|
463
|
-
def load_input(file, only_items = true)
|
464
|
-
ret = JSON.parse(IO.read(RES_DIR + 'display' + file),
|
465
|
-
symbolize_names: true)
|
466
|
-
only_items ? ret[:items] : ret
|
467
|
-
end
|
468
|
-
|
469
|
-
# @param file [String] file to load
|
470
|
-
# @return [String]
|
471
|
-
#
|
472
|
-
def load_expected(file)
|
473
|
-
IO.read(RES_DIR + 'display' + file)
|
474
|
-
end
|
475
|
-
|
476
|
-
def in_and_out(input, expected, only_items = true)
|
477
|
-
[load_input(input, only_items), load_expected(expected)]
|
478
|
-
end
|
479
|
-
end
|
480
|
-
|
481
|
-
OUTPUT_TESTER = OutputTester.new
|
482
|
-
|
483
68
|
# stdlib extensions
|
484
69
|
#
|
485
70
|
class Hash
|
@@ -507,7 +92,8 @@ def command_output(word, method, klass = nil, infile = nil)
|
|
507
92
|
infile ||= "#{word}-list.json"
|
508
93
|
json = IO.read(RES_DIR + 'responses' + infile)
|
509
94
|
resp = Wavefront::Response.new(json, 200)
|
510
|
-
klass ||= Object.const_get(format('WavefrontCli
|
95
|
+
klass ||= Object.const_get(format('WavefrontCli::%<class_word>s',
|
96
|
+
class_word: word.capitalize))
|
511
97
|
klass = klass.new(format: :human)
|
512
98
|
|
513
99
|
capture_io { klass.display(resp, method) }
|