wavefront-cli 0.0.5 → 1.0.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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/Gemfile +1 -1
- data/README.md +21 -21
- data/Rakefile +2 -2
- data/bin/{wavefront → wf} +6 -2
- data/lib/wavefront-cli/alert.rb +7 -6
- data/lib/wavefront-cli/base.rb +27 -6
- data/lib/wavefront-cli/commands/alert.rb +2 -1
- data/lib/wavefront-cli/commands/base.rb +54 -29
- data/lib/wavefront-cli/commands/dashboard.rb +1 -0
- data/lib/wavefront-cli/commands/event.rb +7 -3
- data/lib/wavefront-cli/commands/integration.rb +2 -1
- data/lib/wavefront-cli/commands/link.rb +2 -2
- data/lib/wavefront-cli/commands/proxy.rb +2 -1
- data/lib/wavefront-cli/commands/savedsearch.rb +2 -1
- data/lib/wavefront-cli/commands/source.rb +3 -2
- data/lib/wavefront-cli/commands/webhook.rb +2 -1
- data/lib/wavefront-cli/commands/window.rb +2 -1
- data/lib/wavefront-cli/commands/write.rb +10 -6
- data/lib/wavefront-cli/constants.rb +1 -1
- data/lib/wavefront-cli/controller.rb +6 -4
- data/lib/wavefront-cli/dashboard.rb +6 -6
- data/lib/wavefront-cli/display/alert.rb +8 -4
- data/lib/wavefront-cli/display/base.rb +115 -170
- data/lib/wavefront-cli/display/cloudintegration.rb +2 -2
- data/lib/wavefront-cli/display/event.rb +1 -1
- data/lib/wavefront-cli/display/maintenancewindow.rb +1 -1
- data/lib/wavefront-cli/display/metric.rb +6 -7
- data/lib/wavefront-cli/display/printer/base.rb +24 -0
- data/lib/wavefront-cli/display/printer/long.rb +186 -0
- data/lib/wavefront-cli/display/printer/terse.rb +55 -0
- data/lib/wavefront-cli/display/query.rb +1 -2
- data/lib/wavefront-cli/display/savedsearch.rb +1 -1
- data/lib/wavefront-cli/display/source.rb +7 -3
- data/lib/wavefront-cli/display/webhook.rb +3 -4
- data/lib/wavefront-cli/event.rb +62 -23
- data/lib/wavefront-cli/exception.rb +1 -1
- data/lib/wavefront-cli/opt_handler.rb +6 -6
- data/lib/wavefront-cli/query.rb +5 -6
- data/lib/wavefront-cli/source.rb +5 -1
- data/lib/wavefront-cli/string.rb +59 -0
- data/lib/wavefront-cli/version.rb +1 -1
- data/lib/wavefront-cli/write.rb +4 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/wavefront-cli/alert_spec.rb +16 -5
- data/spec/wavefront-cli/base_spec.rb +5 -2
- data/spec/wavefront-cli/cli_help_spec.rb +7 -5
- data/spec/wavefront-cli/cloudintegration_spec.rb +9 -0
- data/spec/wavefront-cli/commands/alert_spec.rb +16 -0
- data/spec/wavefront-cli/commands/base_spec.rb +133 -0
- data/spec/wavefront-cli/commands/dashboard_spec.rb +16 -0
- data/spec/wavefront-cli/commands/event_spec.rb +17 -0
- data/spec/wavefront-cli/commands/integration_spec.rb +21 -0
- data/spec/wavefront-cli/commands/link_spec.rb +21 -0
- data/spec/wavefront-cli/commands/message_spec.rb +16 -0
- data/spec/wavefront-cli/commands/metric_spec.rb +16 -0
- data/spec/wavefront-cli/commands/proxy_spec.rb +16 -0
- data/spec/wavefront-cli/commands/query_spec.rb +16 -0
- data/spec/wavefront-cli/commands/spec_helper.rb +4 -0
- data/spec/wavefront-cli/commands/webhook_spec.rb +16 -0
- data/spec/wavefront-cli/commands/window_spec.rb +21 -0
- data/spec/wavefront-cli/commands/write_spec.rb +17 -0
- data/spec/wavefront-cli/dashboard_spec.rb +14 -4
- data/spec/wavefront-cli/display/base_spec.rb +162 -0
- data/spec/wavefront-cli/display/printer/base_spec.rb +20 -0
- data/spec/wavefront-cli/display/printer/long_spec.rb +137 -0
- data/spec/wavefront-cli/display/printer/terse_spec.rb +46 -0
- data/spec/wavefront-cli/display/spec_helper.rb +5 -0
- data/spec/wavefront-cli/event_spec.rb +9 -0
- data/spec/wavefront-cli/externallink_spec.rb +9 -0
- data/spec/wavefront-cli/maintanancewindow_spec.rb +10 -0
- data/spec/wavefront-cli/proxy_spec.rb +9 -0
- data/spec/wavefront-cli/savedsearch_spec.rb +9 -0
- data/spec/wavefront-cli/source_spec.rb +13 -1
- data/spec/wavefront-cli/string_spec.rb +51 -0
- data/spec/wavefront-cli/user_spec.rb +2 -2
- data/spec/wavefront-cli/webhook_spec.rb +9 -0
- data/wavefront-cli.gemspec +5 -5
- metadata +59 -22
- data/Gemfile.lock +0 -65
@@ -5,10 +5,10 @@ require_relative './version'
|
|
5
5
|
require_relative './opt_handler'
|
6
6
|
require_relative './exception'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
# $LOAD_PATH.<< Pathname.new(__FILE__).dirname.realpath.parent.parent
|
9
|
+
# .parent + 'lib'
|
10
|
+
# $LOAD_PATH.<< Pathname.new(__FILE__).dirname.realpath.parent.parent
|
11
|
+
# .parent + 'wavefront-sdk' + 'lib'
|
12
12
|
|
13
13
|
CMD_DIR = Pathname.new(__FILE__).dirname + 'commands'
|
14
14
|
|
@@ -59,6 +59,8 @@ class WavefrontCliController
|
|
59
59
|
|
60
60
|
begin
|
61
61
|
[cmd, sanitize_keys(Docopt.docopt(usage[cmd], argv: args))]
|
62
|
+
rescue Docopt::DocoptLanguageError => e
|
63
|
+
abort "mangled command description:\n#{e.message}"
|
62
64
|
rescue Docopt::Exit => e
|
63
65
|
abort e.message
|
64
66
|
end
|
@@ -10,13 +10,13 @@ module WavefrontCli
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def do_delete
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
word = if wf.describe(options[:'<id>']).status.code == 200
|
14
|
+
'Soft'
|
15
|
+
else
|
16
|
+
'Permanently'
|
17
|
+
end
|
18
18
|
|
19
|
-
puts " deleting dashboard '#{options[:'<id>']}'."
|
19
|
+
puts "#{word} deleting dashboard '#{options[:'<id>']}'."
|
20
20
|
wf.delete(options[:'<id>'])
|
21
21
|
end
|
22
22
|
|
@@ -24,17 +24,21 @@ module WavefrontDisplay
|
|
24
24
|
long_output
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
|
27
|
+
def do_history
|
28
|
+
drop_fields(:inTrash)
|
29
|
+
long_output
|
30
|
+
end
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
+
def do_snooze
|
33
|
+
w = options[:time] ? "for #{options[:time]} seconds" : 'indefinitely'
|
34
|
+
puts "Snoozed alert '#{options[:'<id>']}' #{w}."
|
32
35
|
end
|
33
36
|
|
34
37
|
def do_unsnooze
|
35
38
|
puts "Unsnoozed alert '#{options[:'<id>']}'."
|
36
39
|
end
|
37
40
|
|
41
|
+
# rubocop:disable Metrics/AbcSize
|
38
42
|
def do_summary
|
39
43
|
kw = data.keys.map(&:size).max + 2
|
40
44
|
data.delete_if { |_k, v| v.zero? } unless options[:all]
|
@@ -7,45 +7,33 @@ module WavefrontDisplay
|
|
7
7
|
# as that which fetches the data, in a WavefrontDisplay class,
|
8
8
|
# extending this one.
|
9
9
|
#
|
10
|
-
# We provide long_output() and
|
10
|
+
# We provide #long_output() and #multicolumn() methods to solve
|
11
11
|
# standard formatting problems. To use them, define a do_() method
|
12
12
|
# but rather than printing the output, have it call the method.
|
13
13
|
#
|
14
14
|
class Base
|
15
15
|
include WavefrontCli::Constants
|
16
16
|
|
17
|
-
attr_reader :data, :options
|
18
|
-
:hide_blank
|
17
|
+
attr_reader :data, :options
|
19
18
|
|
20
|
-
#
|
21
|
-
#
|
19
|
+
# @param data [Map, Hash, Array] the data returned by the SDK
|
20
|
+
# response.
|
21
|
+
# @param options [Hash] options from docopt
|
22
22
|
#
|
23
|
-
def run_error(method)
|
24
|
-
return unless respond_to?(method)
|
25
|
-
send(method)
|
26
|
-
exit 1
|
27
|
-
end
|
28
|
-
|
29
23
|
def initialize(data, options = {})
|
30
|
-
@data = data
|
24
|
+
@data = data.is_a?(Map) ? Map(put_id_first(data)) : data
|
31
25
|
@options = options
|
32
|
-
@indent = 0
|
33
|
-
@indent_step = options[:indent_step] || 2
|
34
|
-
@hide_blank = options[:hide_blank] || true
|
35
26
|
end
|
36
27
|
|
28
|
+
# find the correct method to deal with the output of the user's
|
29
|
+
# command.
|
30
|
+
#
|
37
31
|
def run(method)
|
38
32
|
if method == 'do_list'
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
return
|
46
|
-
end
|
47
|
-
|
48
|
-
if respond_to?("#{method}_brief")
|
33
|
+
run_list
|
34
|
+
elsif method == 'do_search'
|
35
|
+
run_search
|
36
|
+
elsif respond_to?("#{method}_brief")
|
49
37
|
send("#{method}_brief")
|
50
38
|
elsif respond_to?(method)
|
51
39
|
send(method)
|
@@ -54,134 +42,64 @@ module WavefrontDisplay
|
|
54
42
|
end
|
55
43
|
end
|
56
44
|
|
57
|
-
|
58
|
-
|
45
|
+
# Choose the correct list handler. The user can specifiy a long
|
46
|
+
# listing with the --long options.
|
47
|
+
#
|
48
|
+
def run_list
|
49
|
+
if options[:long]
|
50
|
+
do_list
|
51
|
+
else
|
52
|
+
do_list_brief
|
53
|
+
end
|
59
54
|
end
|
60
55
|
|
61
|
-
#
|
62
|
-
#
|
56
|
+
# Choose the correct search handler. The user can specifiy a long
|
57
|
+
# listing with the --long options.
|
63
58
|
#
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
d = modified_data || data
|
70
|
-
want = d.each_with_object({}) { |r, a| a[r[col1]] = r[col2] }
|
71
|
-
@indent_str = ''
|
72
|
-
@kw = key_width(want)
|
73
|
-
|
74
|
-
want.each do |k, v|
|
75
|
-
v = v.join(', ') if v.is_a?(Array)
|
76
|
-
print_line(k, v)
|
59
|
+
def run_search
|
60
|
+
if options[:long]
|
61
|
+
do_search
|
62
|
+
else
|
63
|
+
do_search_brief
|
77
64
|
end
|
78
65
|
end
|
79
66
|
|
80
|
-
#
|
81
|
-
#
|
67
|
+
# Display classes can provide a do_method_code() method, which
|
68
|
+
# handles <code> errors when running do_method(). (Code is 404
|
69
|
+
# etc.)
|
82
70
|
#
|
83
|
-
# @param
|
84
|
-
# will be printed in the order given.
|
71
|
+
# @param method [Symbol] the error method we wish to call
|
85
72
|
#
|
86
|
-
def
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
data.each do |obj|
|
91
|
-
val = obj[k]
|
92
|
-
val = val.join(', ') if val.is_a?(Array)
|
93
|
-
len[k] = val.size if val.size > len[k]
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
fmt = keys.each_with_object('') { |k, out| out.<< "%-#{len[k]}s " }
|
98
|
-
|
99
|
-
data.each do |obj|
|
100
|
-
args = keys.map do |k|
|
101
|
-
obj[k].is_a?(Array) ? obj[k].join(', ') : obj[k]
|
102
|
-
end
|
103
|
-
|
104
|
-
puts format(fmt, *args)
|
105
|
-
end
|
73
|
+
def run_error(method)
|
74
|
+
return unless respond_to?(method)
|
75
|
+
send(method)
|
76
|
+
exit 1
|
106
77
|
end
|
107
78
|
|
108
|
-
|
109
|
-
|
79
|
+
# If the data contains an 'id' key, move it to the start.
|
80
|
+
#
|
81
|
+
def put_id_first(data)
|
82
|
+
data.key?(:id) ? { id: data[:id] }.merge(data) : data
|
110
83
|
end
|
111
84
|
|
112
|
-
#
|
113
|
-
#
|
114
|
-
#
|
85
|
+
# Default display method for 'describe' and long-list methods.
|
86
|
+
# Wraps around #_two_columns() giving you the chance to modify
|
87
|
+
# @data on the fly
|
115
88
|
#
|
116
|
-
# @param
|
117
|
-
#
|
118
|
-
# @param
|
119
|
-
#
|
120
|
-
#
|
121
|
-
# @returns [Nil]
|
89
|
+
# @param fields [Array[Symbol]] a list of fields you wish to
|
90
|
+
# display. If this is nil, all fields are displayed.
|
91
|
+
# @param modified_data [Hash, Array] lets you modify @data
|
92
|
+
# in-line. If this is truthy, it is used. Passing
|
93
|
+
# modified_data means that any fields parameter is ignored.
|
122
94
|
#
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
kw = key_width(row) unless kw
|
127
|
-
@kw = kw unless @kw
|
128
|
-
set_indent(indent)
|
129
|
-
|
130
|
-
row.each do |k, v|
|
131
|
-
next if v.respond_to?(:empty?) && v.empty? && hide_blank
|
132
|
-
|
133
|
-
if v.is_a?(String) && v.match(/<.*>/)
|
134
|
-
v = v.gsub(%r{<\/?[^>]*>}, '').delete("\n")
|
135
|
-
end
|
136
|
-
|
137
|
-
if v.is_a?(Hash)
|
138
|
-
print_line(k)
|
139
|
-
@indent += indent_step
|
140
|
-
@kw -= 2
|
141
|
-
_two_columns([v], kw - indent_step)
|
142
|
-
elsif v.is_a?(Array)
|
143
|
-
print_array(k, v)
|
144
|
-
else
|
145
|
-
print_line(k, v)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
puts if indent.zero?
|
149
|
-
end
|
150
|
-
|
151
|
-
@indent -= indent_step if indent > 0
|
152
|
-
@kw += 2
|
153
|
-
set_indent(indent)
|
154
|
-
end
|
155
|
-
|
156
|
-
def print_array(k, v)
|
157
|
-
v.each_with_index do |w, i|
|
158
|
-
if w.is_a?(Hash)
|
159
|
-
print_line(k) if i.zero?
|
160
|
-
@indent += indent_step
|
161
|
-
@kw -= 2
|
162
|
-
_two_columns([w], kw - indent_step)
|
163
|
-
print_line('', '---') unless i == v.size - 1
|
164
|
-
else
|
165
|
-
if i.zero?
|
166
|
-
print_line(k, v.shift)
|
167
|
-
else
|
168
|
-
print_line('', w)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
95
|
+
def long_output(fields = nil, modified_data = nil)
|
96
|
+
require_relative 'printer/long'
|
97
|
+
puts WavefrontDisplayPrinter::Long.new(data, fields, modified_data)
|
172
98
|
end
|
173
99
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
# @param indent [Integer] number of leading spaces on line
|
178
|
-
#
|
179
|
-
def print_line(key, value = '')
|
180
|
-
if key.empty?
|
181
|
-
puts ' ' * kw + value
|
182
|
-
else
|
183
|
-
puts indent_str + format("%-#{kw}s%s", key, value).fold(TW, kw)
|
184
|
-
end
|
100
|
+
def multicolumn(*columns)
|
101
|
+
require_relative 'printer/terse'
|
102
|
+
puts WavefrontDisplayPrinter::Terse.new(data, *columns)
|
185
103
|
end
|
186
104
|
|
187
105
|
# Give it a key-value hash, and it will return the size of the first
|
@@ -191,31 +109,30 @@ module WavefrontDisplay
|
|
191
109
|
# @param pad [Integer] the number of spaces you want between columns
|
192
110
|
# @return [Integer] length of longest key + pad
|
193
111
|
#
|
194
|
-
def key_width(hash, pad = 2)
|
112
|
+
def key_width(hash = {}, pad = 2)
|
195
113
|
return 0 if hash.keys.empty?
|
196
114
|
hash.keys.map(&:size).max + pad
|
197
115
|
end
|
198
116
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
#
|
203
|
-
return unless line
|
204
|
-
line.gsub(/(.{1,#{cols - offset}})(\s+|\Z)/, "\\1\n#{' ' *
|
205
|
-
offset}").rstrip
|
206
|
-
end
|
207
|
-
|
117
|
+
# return [String] the name of the thing we're operating on, like
|
118
|
+
# 'alert' or 'dashboard'.
|
119
|
+
#
|
208
120
|
def friendly_name
|
209
121
|
self.class.name.split('::').last.gsub(/([a-z])([A-Z])/, '\\1 \\2')
|
210
122
|
.downcase
|
211
123
|
end
|
212
124
|
|
125
|
+
# The following do_ methods are default handlers called
|
126
|
+
# following their namesake operation in the corresponding
|
127
|
+
# WavefrontCli class. They can be overriden in the inheriting
|
128
|
+
# class.
|
129
|
+
#
|
213
130
|
def do_list
|
214
131
|
long_output
|
215
132
|
end
|
216
133
|
|
217
134
|
def do_list_brief
|
218
|
-
|
135
|
+
multicolumn(:id, :name)
|
219
136
|
end
|
220
137
|
|
221
138
|
def do_import
|
@@ -231,6 +148,26 @@ module WavefrontDisplay
|
|
231
148
|
puts "Undeleted #{friendly_name} '#{options[:'<id>']}'."
|
232
149
|
end
|
233
150
|
|
151
|
+
def do_search_brief
|
152
|
+
display_keys = ([:id] + options[:'<condition>'].map do |c|
|
153
|
+
c.split(/\W/, 2).first.to_sym
|
154
|
+
end).uniq
|
155
|
+
|
156
|
+
if data.empty?
|
157
|
+
puts 'No matches.'
|
158
|
+
else
|
159
|
+
multicolumn(*display_keys)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def do_search
|
164
|
+
if data.empty?
|
165
|
+
puts 'No matches.'
|
166
|
+
else
|
167
|
+
long_output
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
234
171
|
def do_tag_add
|
235
172
|
puts "Tagged #{friendly_name} '#{options[:'<id>']}'."
|
236
173
|
end
|
@@ -259,46 +196,54 @@ module WavefrontDisplay
|
|
259
196
|
# we deem not of interest to the user.
|
260
197
|
#
|
261
198
|
# @param keys [Symbol] keys you do not wish to be shown.
|
199
|
+
# @return [Nil]
|
262
200
|
#
|
263
201
|
def drop_fields(*keys)
|
264
|
-
data.
|
202
|
+
if data.is_a?(Array)
|
203
|
+
data.each { |i| i.delete_if { |k, _v| keys.include?(k.to_sym) } }
|
204
|
+
else
|
205
|
+
data.delete_if { |k, _v| keys.include?(k.to_sym) }
|
206
|
+
end
|
265
207
|
end
|
266
208
|
|
267
209
|
# Modify, in-place, the data structure to make times
|
268
210
|
# human-readable. Automatically handles second and millisecond
|
269
|
-
# epoch times.
|
211
|
+
# epoch times. Currently only operates on top-level keys.
|
212
|
+
#
|
213
|
+
# param keys [Symbol, Array[Symbol]] the keys you wish to be
|
214
|
+
# turned into readable times.
|
215
|
+
# return [Nil]
|
270
216
|
#
|
271
217
|
def readable_time(*keys)
|
272
|
-
keys.each
|
273
|
-
next unless data.key?(k)
|
274
|
-
data[k] = human_time(data[k])
|
275
|
-
end
|
218
|
+
keys.each { |k| data[k] = human_time(data[k]) if data.key?(k) }
|
276
219
|
end
|
277
220
|
|
278
|
-
|
221
|
+
# Make a time human-readable. Automatically deals with epoch
|
222
|
+
# seconds and epoch milliseconds
|
223
|
+
#
|
224
|
+
# param t [Integer, String] a timestamp. If it's a string, it is
|
225
|
+
# converted to an int.
|
226
|
+
# param force_utc [Boolean] force output in UTC. Currently only
|
227
|
+
# used for unit tests.
|
228
|
+
# return [String] a human-readable timestamp
|
229
|
+
#
|
230
|
+
def human_time(t, force_utc = false)
|
231
|
+
raise ArgumentError unless t.is_a?(Numeric) || t.is_a?(String)
|
279
232
|
str = t.to_s
|
280
233
|
|
281
|
-
if str
|
234
|
+
if str =~ /^\d{13}$/
|
282
235
|
fmt = '%Q'
|
283
236
|
out_fmt = HUMAN_TIME_FORMAT_MS
|
284
|
-
|
237
|
+
elsif str =~ /^\d{10}$/
|
285
238
|
fmt = '%s'
|
286
239
|
out_fmt = HUMAN_TIME_FORMAT
|
240
|
+
else
|
241
|
+
raise ArgumentError
|
287
242
|
end
|
288
243
|
|
289
|
-
DateTime.strptime(str, fmt).
|
244
|
+
ret = DateTime.strptime(str, fmt).to_time
|
245
|
+
ret = ret.utc if force_utc
|
246
|
+
ret.strftime(out_fmt)
|
290
247
|
end
|
291
|
-
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
|
-
# Extensions to the String class to help with formatting.
|
296
|
-
#
|
297
|
-
class String
|
298
|
-
|
299
|
-
# Fold long command lines and suitably indent
|
300
|
-
#
|
301
|
-
def fold(width = TW, indent = 10)
|
302
|
-
scan(/\S.{0,#{width - 2}}\S(?=\s|$)|\S+/).join("\n" + ' ' * indent)
|
303
248
|
end
|
304
249
|
end
|
@@ -6,12 +6,12 @@ module WavefrontDisplay
|
|
6
6
|
#
|
7
7
|
class CloudIntegration < Base
|
8
8
|
def do_list_brief
|
9
|
-
|
9
|
+
multicolumn(:id, :service)
|
10
10
|
end
|
11
11
|
|
12
12
|
def do_describe
|
13
13
|
readable_time(:lastReceivedDataPointMs, :lastProcessingTimestamp)
|
14
|
-
drop_fields(:forceSave)
|
14
|
+
drop_fields(:forceSave, :inTrash, :deleted)
|
15
15
|
long_output
|
16
16
|
end
|
17
17
|
end
|
@@ -6,17 +6,16 @@ module WavefrontDisplay
|
|
6
6
|
#
|
7
7
|
class Metric < Base
|
8
8
|
def do_describe
|
9
|
-
if data.hosts.empty?
|
10
|
-
puts
|
9
|
+
if data.empty? || data.hosts.empty?
|
10
|
+
puts 'No matches.'
|
11
11
|
exit
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
{ host:
|
16
|
-
|
17
|
-
end.sort_by{ |h| h[:last_update] }.reverse
|
14
|
+
@data = data['hosts'].map do |h, _aggr|
|
15
|
+
{ host: h[:host], last_update: human_time(h[:last_update]) }
|
16
|
+
end.sort_by { |h| h[:last_update] }.reverse
|
18
17
|
|
19
|
-
|
18
|
+
multicolumn(:host, :last_update)
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module WavefrontDisplayPrinter
|
2
|
+
#
|
3
|
+
# Base class for the two printer classes
|
4
|
+
#
|
5
|
+
class Base
|
6
|
+
attr_reader :out
|
7
|
+
|
8
|
+
# Give it a key-value hash, and it will return the size of the first
|
9
|
+
# column to use when formatting that data.
|
10
|
+
#
|
11
|
+
# @param hash [Hash] the data for which you need a column width
|
12
|
+
# @param pad [Integer] the number of spaces you want between columns
|
13
|
+
# @return [Integer] length of longest key + pad
|
14
|
+
#
|
15
|
+
def key_width(hash = {}, pad = 2)
|
16
|
+
return 0 if hash.keys.empty?
|
17
|
+
hash.keys.map(&:size).max + pad
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
out.join("\n")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|