wavefront-cli 3.2.3 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HISTORY.md +12 -0
- data/lib/wavefront-cli/base.rb +32 -6
- data/lib/wavefront-cli/command_mixins/tag.rb +12 -0
- data/lib/wavefront-cli/commands/alert.rb +1 -5
- data/lib/wavefront-cli/commands/base.rb +2 -1
- data/lib/wavefront-cli/constants.rb +4 -0
- data/lib/wavefront-cli/controller.rb +2 -0
- data/lib/wavefront-cli/display/base.rb +43 -4
- data/lib/wavefront-cli/display/printer/terse.rb +14 -4
- data/lib/wavefront-cli/exception.rb +2 -0
- data/lib/wavefront-cli/version.rb +1 -1
- data/spec/spec_helper.rb +46 -1
- data/spec/wavefront-cli/alert_spec.rb +3 -10
- data/spec/wavefront-cli/base_spec.rb +54 -1
- data/spec/wavefront-cli/cloudintegration_spec.rb +1 -9
- data/spec/wavefront-cli/commands/base_spec.rb +1 -1
- data/spec/wavefront-cli/dashboard_spec.rb +3 -10
- data/spec/wavefront-cli/derivedmetric_spec.rb +1 -10
- data/spec/wavefront-cli/display/printer/terse_spec.rb +3 -3
- data/spec/wavefront-cli/event_spec.rb +1 -9
- data/spec/wavefront-cli/externallink_spec.rb +1 -10
- data/spec/wavefront-cli/maintenancewindow_spec.rb +1 -11
- data/spec/wavefront-cli/notificant_spec.rb +2 -11
- data/spec/wavefront-cli/proxy_spec.rb +1 -10
- data/spec/wavefront-cli/savedsearch_spec.rb +1 -9
- data/spec/wavefront-cli/source_spec.rb +1 -9
- data/spec/wavefront-cli/user_spec.rb +1 -9
- data/spec/wavefront-cli/usergroup_spec.rb +1 -8
- data/spec/wavefront-cli/webhook_spec.rb +1 -9
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ce4081f6a736ace3019e5c4fc3cadcc91d04e028ea4f04a034250ccef7afc14
|
4
|
+
data.tar.gz: 3c00162398ae62804cde46e1cfc7e058d953f22566cd72d63df799e78f0cbf69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc66b3ce0e7f6942516c79bbed8f93f97d57e4adc3b84f40770bf49a00d26f943e94007307edb5eb71542aaec023374acab623d0fbd712bcc5ed22cb7cf69501
|
7
|
+
data.tar.gz: c5263da338dc6472e6beb7d9c221fa30036e8fcbc825ec7d39b4f1688fb75f65a3dd6b68f022c82885a4f906727cd5cd06e4ca90516830218958669cae73b512
|
data/HISTORY.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 3.3.0 (10/06/2019)
|
4
|
+
* Support negation searches. Search for alerts with targets *not* containing
|
5
|
+
`str` with `wf alert search target!~str`.
|
6
|
+
* Add `tag pathsearch` command. Searches for tags whose hierarchical names
|
7
|
+
begin with the given element(s).
|
8
|
+
* Better printing of structured search results. For example `wf alert search
|
9
|
+
tags=X`.
|
10
|
+
* Support freetext searches. Use `wf <object> search freetext=string` and you
|
11
|
+
will be given a list of the objects which match the search along with the
|
12
|
+
matching keys. (Not values!) Adding `-l` presents all matching objects in
|
13
|
+
full.
|
14
|
+
|
3
15
|
## 3.2.3 (24/05/2019)
|
4
16
|
* Don't print erroneous pagination message when using `list --all`.
|
5
17
|
* Require 3.3.2 of [the SDK](https://github.com/snltd/wavefront-sdk).
|
data/lib/wavefront-cli/base.rb
CHANGED
@@ -456,15 +456,41 @@ module WavefrontCli
|
|
456
456
|
|
457
457
|
# Turn a list of search conditions into an API query
|
458
458
|
#
|
459
|
+
# @param conds [Array]
|
460
|
+
# @return [Array[Hash]]
|
461
|
+
#
|
459
462
|
def conds_to_query(conds)
|
460
|
-
conds.
|
461
|
-
key, value = cond.split(
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
463
|
+
conds.map do |cond|
|
464
|
+
key, value = cond.split(SEARCH_SPLIT, 2)
|
465
|
+
{ key: key, value: value }.merge(matching_method(cond))
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
470
|
+
# rubocop:disable Metrics/MethodLength
|
471
|
+
# @param cond [String] a search condition, like "key=value"
|
472
|
+
# @return [Hash] of matchingMethod and negated
|
473
|
+
#
|
474
|
+
def matching_method(cond)
|
475
|
+
case cond
|
476
|
+
when /^\w+~/
|
477
|
+
{ matchingMethod: 'CONTAINS', negated: false }
|
478
|
+
when /^\w+!~/
|
479
|
+
{ matchingMethod: 'CONTAINS', negated: true }
|
480
|
+
when /^\w+=/
|
481
|
+
{ matchingMethod: 'EXACT', negated: false }
|
482
|
+
when /^\w+!=/
|
483
|
+
{ matchingMethod: 'EXACT', negated: true }
|
484
|
+
when /^\w+\^/
|
485
|
+
{ matchingMethod: 'STARTSWITH', negated: false }
|
486
|
+
when /^\w+!\^/
|
487
|
+
{ matchingMethod: 'STARTSWITH', negated: true }
|
488
|
+
else
|
489
|
+
raise(WavefrontCli::Exception::UnparseableSearchPattern, cond)
|
466
490
|
end
|
467
491
|
end
|
492
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
493
|
+
# rubocop:enable Metrics/MethodLength
|
468
494
|
|
469
495
|
# Most things will re-import with the POST method if you remove
|
470
496
|
# the ID.
|
@@ -23,6 +23,18 @@ module WavefrontCli
|
|
23
23
|
def do_tag_clear
|
24
24
|
wf.tag_set(options[:'<id>'], [])
|
25
25
|
end
|
26
|
+
|
27
|
+
def do_tag_pathsearch
|
28
|
+
require 'wavefront-sdk/search'
|
29
|
+
wfs = Wavefront::Search.new(mk_creds, mk_opts)
|
30
|
+
|
31
|
+
query = { key: 'tags',
|
32
|
+
value: options[:'<word>'],
|
33
|
+
matchingMethod: 'TAGPATH',
|
34
|
+
negated: false }
|
35
|
+
|
36
|
+
wfs.search(search_key, query, range_hash)
|
37
|
+
end
|
26
38
|
end
|
27
39
|
end
|
28
40
|
end
|
@@ -23,11 +23,7 @@ class WavefrontCommandAlert < WavefrontCommandBase
|
|
23
23
|
"update #{CMN} <key=value> <id>",
|
24
24
|
"unsnooze #{CMN} <id>",
|
25
25
|
"search #{CMN} [-al] [-o offset] [-L limit] <condition>...",
|
26
|
-
|
27
|
-
"tag set #{CMN} <id> <tag>...",
|
28
|
-
"tag clear #{CMN} <id>",
|
29
|
-
"tag add #{CMN} <id> <tag>",
|
30
|
-
"tag delete #{CMN} <id> <tag>",
|
26
|
+
tag_commands,
|
31
27
|
"currently #{CMN} <state>",
|
32
28
|
"queries #{CMN} [-b] [<id>]",
|
33
29
|
"install #{CMN} <id>",
|
@@ -41,7 +41,8 @@ class WavefrontCommandBase
|
|
41
41
|
"tag set #{CMN} <id> <tag>...",
|
42
42
|
"tag clear #{CMN} <id>",
|
43
43
|
"tag add #{CMN} <id> <tag>",
|
44
|
-
"tag delete #{CMN} <id> <tag>"
|
44
|
+
"tag delete #{CMN} <id> <tag>",
|
45
|
+
"tag pathsearch #{CMN} [-al] [-o offset] [-L limit] <word>"]
|
45
46
|
end
|
46
47
|
|
47
48
|
# Anything which takes ACLs provides the same interface
|
@@ -140,6 +140,8 @@ class WavefrontCliController
|
|
140
140
|
abort "Cannot find user group '#{e.message}'."
|
141
141
|
rescue Wavefront::Exception::UnsupportedWriter => e
|
142
142
|
abort "Unsupported writer '#{e.message}'."
|
143
|
+
rescue WavefrontCli::Exception::ImpossibleSearch
|
144
|
+
abort 'Search on non-existent key. Please use a top-level field.'
|
143
145
|
rescue StandardError => e
|
144
146
|
warn "general error: #{e}"
|
145
147
|
warn "Backtrace:\n\t#{e.backtrace.join("\n\t")}"
|
@@ -219,15 +219,44 @@ module WavefrontDisplay
|
|
219
219
|
end
|
220
220
|
|
221
221
|
def do_search_brief
|
222
|
-
|
223
|
-
c.split(/\W/, 2).first.to_sym
|
224
|
-
end).uniq
|
222
|
+
search_keys = search_display_keys
|
225
223
|
|
226
224
|
if data.empty?
|
227
225
|
puts 'No matches.'
|
226
|
+
elsif search_keys.include?(:freetext)
|
227
|
+
display_brief_freetext_results
|
228
228
|
else
|
229
|
-
multicolumn(*
|
229
|
+
multicolumn(*search_keys)
|
230
230
|
end
|
231
|
+
rescue KeyError
|
232
|
+
raise WavefrontCli::Exception::ImpossibleSearch
|
233
|
+
end
|
234
|
+
|
235
|
+
# For freetext searches, we just display the matching fields in "brief"
|
236
|
+
# mode.
|
237
|
+
#
|
238
|
+
def display_brief_freetext_results
|
239
|
+
search_keys = freetext_keys
|
240
|
+
|
241
|
+
data.map! do |d|
|
242
|
+
mf = d.select do |_k, v|
|
243
|
+
search_keys.any? { |s| v.to_s.include?(s) }
|
244
|
+
end
|
245
|
+
|
246
|
+
{ id: d[:id], matching_fields: mf.to_h.keys }
|
247
|
+
end
|
248
|
+
|
249
|
+
multicolumn(:id, :matching_fields)
|
250
|
+
end
|
251
|
+
|
252
|
+
def freetext_keys
|
253
|
+
options[:'<condition>'].map { |c| c.split(SEARCH_SPLIT, 2).last }
|
254
|
+
end
|
255
|
+
|
256
|
+
def search_display_keys
|
257
|
+
([:id] + options[:'<condition>'].map do |c|
|
258
|
+
c.split(SEARCH_SPLIT, 2).first.to_sym
|
259
|
+
end).uniq
|
231
260
|
end
|
232
261
|
|
233
262
|
def do_search
|
@@ -262,6 +291,16 @@ module WavefrontDisplay
|
|
262
291
|
end
|
263
292
|
end
|
264
293
|
|
294
|
+
def do_tag_pathsearch
|
295
|
+
if data.empty?
|
296
|
+
puts 'No matches.'
|
297
|
+
elsif options[:long]
|
298
|
+
long_output
|
299
|
+
else
|
300
|
+
multicolumn(:id, :name)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
265
304
|
def do_queries
|
266
305
|
if options[:brief]
|
267
306
|
multicolumn(:condition)
|
@@ -2,7 +2,7 @@ require_relative '../../stdlib/array'
|
|
2
2
|
|
3
3
|
module WavefrontDisplayPrinter
|
4
4
|
#
|
5
|
-
# Print
|
5
|
+
# Print values which are per-row. The terse listings, primarily
|
6
6
|
#
|
7
7
|
class Terse
|
8
8
|
attr_reader :data, :fmt
|
@@ -20,11 +20,21 @@ module WavefrontDisplayPrinter
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def stringify(data, keys)
|
23
|
-
data.map { |e| e.tap { keys.each { |k| e[k] =
|
23
|
+
data.map { |e| e.tap { keys.each { |k| e[k] = to_string(e[k]) } } }
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
27
|
-
|
26
|
+
def to_string(value)
|
27
|
+
if value.is_a?(Array)
|
28
|
+
value.join(', ')
|
29
|
+
elsif value.is_a?(Map)
|
30
|
+
map_to_string(value)
|
31
|
+
else
|
32
|
+
value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def map_to_string(value)
|
37
|
+
format('%s=%s', value.keys[0], value.values.join(','))
|
28
38
|
end
|
29
39
|
|
30
40
|
def to_s
|
@@ -8,6 +8,7 @@ module WavefrontCli
|
|
8
8
|
class MandatoryValue < RuntimeError; end
|
9
9
|
class ConfigFileNotFound < IOError; end
|
10
10
|
class FileNotFound < IOError; end
|
11
|
+
class ImpossibleSearch < RuntimeError; end
|
11
12
|
class InsufficientData < RuntimeError; end
|
12
13
|
class InvalidInput < RuntimeError; end
|
13
14
|
class InvalidValue < RuntimeError; end
|
@@ -17,6 +18,7 @@ module WavefrontCli
|
|
17
18
|
class UnhandledCommand < RuntimeError; end
|
18
19
|
class UnparseableInput < RuntimeError; end
|
19
20
|
class UnparseableResponse < RuntimeError; end
|
21
|
+
class UnparseableSearchPattern < RuntimeError; end
|
20
22
|
class UnsupportedFileFormat < RuntimeError; end
|
21
23
|
class UnsupportedNoop < RuntimeError; end
|
22
24
|
class UnsupportedOperation < RuntimeError; end
|
@@ -1 +1 @@
|
|
1
|
-
WF_CLI_VERSION = '3.
|
1
|
+
WF_CLI_VERSION = '3.3.0'.freeze
|
data/spec/spec_helper.rb
CHANGED
@@ -75,7 +75,6 @@ CANNED_RESPONSE = DummyResponse.new
|
|
75
75
|
# requisite display methods are called.
|
76
76
|
#
|
77
77
|
# @param cmd [String] command line args to supply to the Wavefront
|
78
|
-
# command
|
79
78
|
# @param call [Hash]
|
80
79
|
# @param spies [Array[Hash]] array of spies to set up, for stubbing
|
81
80
|
# methods in any class. Hash has keys :class, :method, :return.
|
@@ -265,6 +264,52 @@ def missing_creds(cmd, subcmds)
|
|
265
264
|
end
|
266
265
|
end
|
267
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
|
+
|
268
313
|
# Generic list tests, needed by most commands
|
269
314
|
#
|
270
315
|
def list_tests(cmd, pth = nil, klass = nil)
|
@@ -10,7 +10,8 @@ def search_body(val)
|
|
10
10
|
query: [
|
11
11
|
{ key: 'status',
|
12
12
|
value: val,
|
13
|
-
matchingMethod: 'EXACT'
|
13
|
+
matchingMethod: 'EXACT',
|
14
|
+
negated: false }
|
14
15
|
],
|
15
16
|
sort: { field: 'status', ascending: true } }
|
16
17
|
end
|
@@ -66,15 +67,6 @@ describe "#{word} command" do
|
|
66
67
|
method: :post, path: "/api/v2/#{word}/#{id}/undelete")
|
67
68
|
cmd_to_call(word, "snooze #{id}",
|
68
69
|
method: :post, path: "/api/v2/#{word}/#{id}/snooze")
|
69
|
-
cmd_to_call(word, "search id=#{id}",
|
70
|
-
method: :post, path: "/api/v2/search/#{word}",
|
71
|
-
body: { limit: 10,
|
72
|
-
offset: 0,
|
73
|
-
query: [{ key: 'id',
|
74
|
-
value: id,
|
75
|
-
matchingMethod: 'EXACT' }],
|
76
|
-
sort: { field: 'id', ascending: true } },
|
77
|
-
headers: JSON_POST_HEADERS)
|
78
70
|
cmd_to_call(word, "snooze -T 800 #{id}",
|
79
71
|
method: :post,
|
80
72
|
path: "/api/v2/#{word}/#{id}/snooze?seconds=800")
|
@@ -106,6 +98,7 @@ describe "#{word} command" do
|
|
106
98
|
path: "/api/v2/search/#{word}",
|
107
99
|
body: search_body('in_maintenance'))
|
108
100
|
cmd_to_call(word, 'queries', path: "/api/v2/#{word}?limit=999&offset=0")
|
101
|
+
search_tests(word, id)
|
109
102
|
tag_tests(word, id, bad_id)
|
110
103
|
noop_tests(word, id, true)
|
111
104
|
test_list_output(word)
|
@@ -49,6 +49,59 @@ class WavefrontCliBaseTest < MiniTest::Test
|
|
49
49
|
|
50
50
|
def test_dispatch
|
51
51
|
assert_raises(WavefrontCli::Exception::UnhandledCommand) { wf.dispatch }
|
52
|
-
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_conds_to_query
|
55
|
+
assert_equal([{ key: 'mykey',
|
56
|
+
value: 'myvalue',
|
57
|
+
matchingMethod: 'EXACT',
|
58
|
+
negated: false }],
|
59
|
+
wf.conds_to_query(%w[mykey=myvalue]))
|
60
|
+
|
61
|
+
assert_equal([{ key: 'mykey',
|
62
|
+
value: 'myvalue',
|
63
|
+
matchingMethod: 'EXACT',
|
64
|
+
negated: true }],
|
65
|
+
wf.conds_to_query(%w[mykey!=myvalue]))
|
66
|
+
|
67
|
+
assert_equal([{ key: 'mykey',
|
68
|
+
value: 'myvalue',
|
69
|
+
matchingMethod: 'CONTAINS',
|
70
|
+
negated: true }],
|
71
|
+
wf.conds_to_query(%w[mykey!~myvalue]))
|
72
|
+
|
73
|
+
assert_equal([{ key: 'mykey',
|
74
|
+
value: 'myvalue',
|
75
|
+
matchingMethod: 'STARTSWITH',
|
76
|
+
negated: false }],
|
77
|
+
wf.conds_to_query(%w[mykey^myvalue]))
|
78
|
+
|
79
|
+
assert_equal([{ key: 'mykey',
|
80
|
+
value: 'myvalue',
|
81
|
+
matchingMethod: 'EXACT',
|
82
|
+
negated: true }],
|
83
|
+
wf.conds_to_query(%w[mykey!=myvalue]))
|
84
|
+
|
85
|
+
assert_raises(WavefrontCli::Exception::UnparseableSearchPattern) do
|
86
|
+
wf.conds_to_query(%w[what!nonsense])
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_matching_method
|
91
|
+
assert_equal({ matchingMethod: 'EXACT', negated: true },
|
92
|
+
wf.matching_method('key!=val'))
|
93
|
+
assert_equal({ matchingMethod: 'EXACT', negated: false },
|
94
|
+
wf.matching_method('key=val'))
|
95
|
+
assert_equal({ matchingMethod: 'STARTSWITH', negated: false },
|
96
|
+
wf.matching_method('key^val'))
|
97
|
+
assert_equal({ matchingMethod: 'STARTSWITH', negated: true },
|
98
|
+
wf.matching_method('key!^val'))
|
99
|
+
assert_equal({ matchingMethod: 'CONTAINS', negated: false },
|
100
|
+
wf.matching_method('key~val'))
|
101
|
+
assert_equal({ matchingMethod: 'CONTAINS', negated: true },
|
102
|
+
wf.matching_method('key!~val'))
|
103
|
+
assert_raises(WavefrontCli::Exception::UnparseableSearchPattern) do
|
104
|
+
wf.matching_method('what nonsense')
|
105
|
+
end
|
53
106
|
end
|
54
107
|
end
|
@@ -13,19 +13,11 @@ describe 'cloudintegration command' do
|
|
13
13
|
"undelete #{id}"])
|
14
14
|
list_tests(word, 'cloudintegration', k)
|
15
15
|
noop_tests(word, id, false, 'cloudintegration', k)
|
16
|
+
search_tests(word, id, k)
|
16
17
|
cmd_to_call(word, "describe #{id}",
|
17
18
|
{ path: "/api/v2/cloudintegration/#{id}" }, k)
|
18
19
|
cmd_to_call(word, "delete #{id}",
|
19
20
|
{ method: :delete, path: "/api/v2/cloudintegration/#{id}" }, k)
|
20
|
-
cmd_to_call(word, "search -L 100 id~#{id}",
|
21
|
-
{ method: :post, path: '/api/v2/search/cloudintegration',
|
22
|
-
body: { limit: '100',
|
23
|
-
offset: 0,
|
24
|
-
query: [{ key: 'id',
|
25
|
-
value: id,
|
26
|
-
matchingMethod: 'CONTAINS' }],
|
27
|
-
sort: { field: 'id', ascending: true } },
|
28
|
-
headers: JSON_POST_HEADERS }, WavefrontCli::CloudIntegration)
|
29
21
|
cmd_to_call(word, "undelete #{id}",
|
30
22
|
{ method: :post,
|
31
23
|
path: "/api/v2/cloudintegration/#{id}/undelete" }, k)
|
@@ -30,15 +30,6 @@ describe "#{word} command" do
|
|
30
30
|
method: :delete, path: "/api/v2/#{word}/#{id}")
|
31
31
|
end
|
32
32
|
|
33
|
-
cmd_to_call(word, "search id=#{id}",
|
34
|
-
method: :post, path: "/api/v2/search/#{word}",
|
35
|
-
body: { limit: 10,
|
36
|
-
offset: 0,
|
37
|
-
query: [{ key: 'id',
|
38
|
-
value: id,
|
39
|
-
matchingMethod: 'EXACT' }],
|
40
|
-
sort: { field: 'id', ascending: true } },
|
41
|
-
headers: JSON_POST_HEADERS)
|
42
33
|
cmd_to_call(word,
|
43
34
|
'favs',
|
44
35
|
method: :post,
|
@@ -47,7 +38,8 @@ describe "#{word} command" do
|
|
47
38
|
offset: 0,
|
48
39
|
query: [{ key: 'favorite',
|
49
40
|
value: 'true',
|
50
|
-
matchingMethod: 'EXACT'
|
41
|
+
matchingMethod: 'EXACT',
|
42
|
+
negated: false }],
|
51
43
|
sort: { field: 'id',
|
52
44
|
ascending: true } }.to_json)
|
53
45
|
|
@@ -74,6 +66,7 @@ describe "#{word} command" do
|
|
74
66
|
invalid_ids(word, ["describe #{bad_id}", "delete #{bad_id}",
|
75
67
|
"undelete #{bad_id}"])
|
76
68
|
tag_tests(word, id, bad_id)
|
69
|
+
search_tests(word, id)
|
77
70
|
test_list_output(word)
|
78
71
|
acl_tests(word, id, bad_id)
|
79
72
|
end
|
@@ -15,6 +15,7 @@ describe "#{word} command" do
|
|
15
15
|
"undelete #{id}", "history #{id}"])
|
16
16
|
list_tests(word, nil, k)
|
17
17
|
noop_tests(word, id, true, word, k)
|
18
|
+
search_tests(word, id, k)
|
18
19
|
cmd_to_call(word, "describe #{id}", { path: "/api/v2/#{word}/#{id}" }, k)
|
19
20
|
cmd_to_call(word, "describe -v 7 #{id}",
|
20
21
|
{ path: "/api/v2/#{word}/#{id}/history/7" }, k)
|
@@ -34,16 +35,6 @@ describe "#{word} command" do
|
|
34
35
|
{ method: :delete, path: "/api/v2/#{word}/#{id}" }, k)
|
35
36
|
end
|
36
37
|
|
37
|
-
cmd_to_call(word, "search id=#{id}",
|
38
|
-
{ method: :post, path: "/api/v2/search/#{word}",
|
39
|
-
body: { limit: 10,
|
40
|
-
offset: 0,
|
41
|
-
query: [{ key: 'id',
|
42
|
-
value: id,
|
43
|
-
matchingMethod: 'EXACT' }],
|
44
|
-
sort: { field: 'id', ascending: true } },
|
45
|
-
headers: JSON_POST_HEADERS }, k)
|
46
|
-
|
47
38
|
cmd_to_call(word, "undelete #{id}",
|
48
39
|
{ method: :post, path: "/api/v2/#{word}/#{id}/undelete" }, k)
|
49
40
|
invalid_ids(word, ["describe #{bad_id}", "delete #{bad_id}",
|
@@ -44,9 +44,9 @@ class WavefrontDisplayPrinterTerse < MiniTest::Test
|
|
44
44
|
[:things]))
|
45
45
|
end
|
46
46
|
|
47
|
-
def
|
48
|
-
assert_equal('a, b, c', wf.
|
49
|
-
assert_equal('abc', wf.
|
47
|
+
def test_to_string
|
48
|
+
assert_equal('a, b, c', wf.to_string(%w[a b c]))
|
49
|
+
assert_equal('abc', wf.to_string('abc'))
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_end_to_end
|
@@ -16,14 +16,6 @@ describe "#{word} command" do
|
|
16
16
|
cmd_to_call(word, "close #{id}",
|
17
17
|
method: :post, path: "/api/v2/#{word}/#{id}/close")
|
18
18
|
tag_tests(word, id, bad_id)
|
19
|
-
|
20
|
-
method: :post, path: "/api/v2/search/#{word}",
|
21
|
-
body: { limit: 10,
|
22
|
-
offset: '11',
|
23
|
-
query: [{ key: 'id',
|
24
|
-
value: id,
|
25
|
-
matchingMethod: 'EXACT' }],
|
26
|
-
sort: { field: 'id', ascending: true } },
|
27
|
-
headers: JSON_POST_HEADERS)
|
19
|
+
search_tests(word, id)
|
28
20
|
test_list_output(word)
|
29
21
|
end
|
@@ -12,20 +12,11 @@ describe "#{word} command" do
|
|
12
12
|
missing_creds(word, ['list', "describe #{id}", "delete #{id}"])
|
13
13
|
list_tests(word, 'extlink', k)
|
14
14
|
noop_tests(word, id, false, 'extlink', k)
|
15
|
+
search_tests(word, id, k, 'extlink')
|
15
16
|
cmd_to_call(word, "describe #{id}", { path: "/api/v2/extlink/#{id}" }, k)
|
16
17
|
cmd_to_call(word, "delete #{id}",
|
17
18
|
{ method: :delete, path: "/api/v2/extlink/#{id}" }, k)
|
18
19
|
invalid_ids(word, ["describe #{bad_id}", "delete #{bad_id}"])
|
19
|
-
cmd_to_call(word, "search -L 100 id~#{id}",
|
20
|
-
{ method: :post,
|
21
|
-
path: '/api/v2/search/extlink',
|
22
|
-
body: { limit: '100',
|
23
|
-
offset: 0,
|
24
|
-
query: [{ key: 'id',
|
25
|
-
value: id,
|
26
|
-
matchingMethod: 'CONTAINS' }],
|
27
|
-
sort: { field: 'id', ascending: true } },
|
28
|
-
headers: JSON_POST_HEADERS }, WavefrontCli::ExternalLink)
|
29
20
|
|
30
21
|
cmd_to_call(word, 'create name description template',
|
31
22
|
{ method: :post,
|
@@ -12,22 +12,12 @@ describe "#{word} command" do
|
|
12
12
|
missing_creds(word, ['list', "describe #{id}", "delete #{id}"])
|
13
13
|
list_tests(word, 'maintenancewindow', k)
|
14
14
|
noop_tests(word, id, false, 'maintenancewindow', k)
|
15
|
+
search_tests(word, id, k, 'maintenancewindow')
|
15
16
|
cmd_to_call(word, "describe #{id}",
|
16
17
|
{ path: "/api/v2/maintenancewindow/#{id}" }, k)
|
17
18
|
cmd_to_call(word, "delete #{id}",
|
18
19
|
{ method: :delete, path: "/api/v2/maintenancewindow/#{id}" }, k)
|
19
20
|
invalid_ids(word, ["describe #{bad_id}", "delete #{bad_id}"])
|
20
|
-
cmd_to_call(word, "search -o 100 id=#{id}",
|
21
|
-
{ method: :post, path: '/api/v2/search/maintenancewindow',
|
22
|
-
body: { limit: 10,
|
23
|
-
offset: '100',
|
24
|
-
query: [{ key: 'id',
|
25
|
-
value: id,
|
26
|
-
matchingMethod: 'EXACT' }],
|
27
|
-
sort: { field: 'id', ascending: true } },
|
28
|
-
headers: JSON_POST_HEADERS },
|
29
|
-
WavefrontCli::MaintenanceWindow)
|
30
|
-
|
31
21
|
cmd_to_call(word, 'create -d testing -H shark tester',
|
32
22
|
{ method: :post, path: '/api/v2/maintenancewindow',
|
33
23
|
body: {
|
@@ -18,18 +18,9 @@ describe "#{word} command" do
|
|
18
18
|
"delete #{bad_id}",
|
19
19
|
"test #{bad_id}",
|
20
20
|
"update #{bad_id} key=value"])
|
21
|
-
list_tests(word)
|
22
21
|
cmd_to_call(word, "describe #{id}", path: "/api/v2/#{word}/#{id}")
|
23
|
-
|
24
|
-
|
25
|
-
method: :post, path: "/api/v2/search/#{word}",
|
26
|
-
body: { limit: 10,
|
27
|
-
offset: 0,
|
28
|
-
query: [{ key: 'id',
|
29
|
-
value: id,
|
30
|
-
matchingMethod: 'EXACT' }],
|
31
|
-
sort: { field: 'id', ascending: true } },
|
32
|
-
headers: JSON_POST_HEADERS)
|
22
|
+
list_tests(word)
|
23
|
+
search_tests(word, id)
|
33
24
|
noop_tests(word, id)
|
34
25
|
test_list_output(word)
|
35
26
|
end
|
@@ -25,15 +25,6 @@ describe "#{word} command" do
|
|
25
25
|
invalid_ids(word, ["describe #{bad_id}", "delete #{bad_id}",
|
26
26
|
"undelete #{bad_id}", "rename #{bad_id} newname"])
|
27
27
|
invalid_something(word, ["rename #{id} '(>_<)'"], 'proxy name')
|
28
|
-
|
29
|
-
method: :post, path: "/api/v2/search/#{word}",
|
30
|
-
body: { limit: 10,
|
31
|
-
offset: '10',
|
32
|
-
query: [{ key: 'id',
|
33
|
-
value: id,
|
34
|
-
matchingMethod: 'EXACT' }],
|
35
|
-
sort: { field: 'id', ascending: true } },
|
36
|
-
headers: JSON_POST_HEADERS)
|
37
|
-
|
28
|
+
search_tests(word, id)
|
38
29
|
test_list_output(word)
|
39
30
|
end
|
@@ -12,18 +12,10 @@ describe "#{word} command" do
|
|
12
12
|
missing_creds(word, ['list', "describe #{id}", "delete #{id}"])
|
13
13
|
list_tests(word, 'savedsearch', k)
|
14
14
|
noop_tests(word, id, false, 'savedsearch', k)
|
15
|
+
search_tests(word, id, k, 'savedsearch')
|
15
16
|
cmd_to_call(word, "describe #{id}", { path: "/api/v2/#{word}/#{id}" }, k)
|
16
17
|
cmd_to_call(word, "delete #{id}",
|
17
18
|
{ method: :delete, path: "/api/v2/#{word}/#{id}" }, k)
|
18
19
|
invalid_ids(word, ["describe #{bad_id}", "delete #{bad_id}"])
|
19
|
-
cmd_to_call(word, "search -L 100 id~#{id}",
|
20
|
-
{ method: :post, path: '/api/v2/search/savedsearch',
|
21
|
-
body: { limit: '100',
|
22
|
-
offset: 0,
|
23
|
-
query: [{ key: 'id',
|
24
|
-
value: id,
|
25
|
-
matchingMethod: 'CONTAINS' }],
|
26
|
-
sort: { field: 'id', ascending: true } },
|
27
|
-
headers: JSON_POST_HEADERS }, WavefrontCli::SavedSearch)
|
28
20
|
test_list_output(word, k)
|
29
21
|
end
|
@@ -18,17 +18,9 @@ describe "#{word} command" do
|
|
18
18
|
method: :delete, path: "/api/v2/#{word}/#{id}")
|
19
19
|
invalid_ids(word, ["describe #{bad_id}", "clear #{bad_id}"])
|
20
20
|
tag_tests(word, id, bad_id)
|
21
|
-
cmd_to_call(word, "search -f json id^#{id}",
|
22
|
-
method: :post, path: "/api/v2/search/#{word}",
|
23
|
-
body: { limit: 10,
|
24
|
-
offset: 0,
|
25
|
-
query: [{ key: 'id',
|
26
|
-
value: id,
|
27
|
-
matchingMethod: 'STARTSWITH' }],
|
28
|
-
sort: { field: 'id', ascending: true } },
|
29
|
-
headers: JSON_POST_HEADERS)
|
30
21
|
cmd_noop(word, 'list',
|
31
22
|
['GET https://metrics.wavefront.com/api/v2/source'])
|
32
23
|
cmd_noop(word, 'describe src',
|
33
24
|
['GET https://metrics.wavefront.com/api/v2/source/src'])
|
25
|
+
search_tests(word, id)
|
34
26
|
end
|
@@ -89,15 +89,7 @@ describe "#{word} command" do
|
|
89
89
|
body: 'group=agent_management',
|
90
90
|
headers: hdrs)
|
91
91
|
|
92
|
-
|
93
|
-
{ method: :post, path: "/api/v2/search/#{word}",
|
94
|
-
body: { limit: '40',
|
95
|
-
offset: 0,
|
96
|
-
query: [{ key: 'id',
|
97
|
-
value: id,
|
98
|
-
matchingMethod: 'EXACT' }],
|
99
|
-
sort: { field: 'id', ascending: true } },
|
100
|
-
headers: JSON_POST_HEADERS }, WavefrontCli::User)
|
92
|
+
search_tests(word, id)
|
101
93
|
|
102
94
|
invalid_ids(word, ["describe #{bad_id}",
|
103
95
|
"delete #{bad_id}",
|
@@ -84,14 +84,7 @@ describe "#{word} command" do
|
|
84
84
|
path: "/api/v2/#{word}/revoke/#{priv1}",
|
85
85
|
body: [gid1].to_json }, k)
|
86
86
|
|
87
|
-
|
88
|
-
{ method: :post, path: "/api/v2/search/#{word}",
|
89
|
-
body: { limit: '40',
|
90
|
-
offset: 0,
|
91
|
-
query: [{ key: 'id',
|
92
|
-
value: 'string',
|
93
|
-
matchingMethod: 'EXACT' }],
|
94
|
-
sort: { field: 'id', ascending: true } } }, k)
|
87
|
+
search_tests(word, gid1, k)
|
95
88
|
|
96
89
|
invalid_ids(word, ["describe #{bad_id}",
|
97
90
|
"delete #{bad_id}",
|
@@ -15,14 +15,6 @@ describe "#{word} command" do
|
|
15
15
|
cmd_to_call(word, "delete #{id}", method: :delete,
|
16
16
|
path: "/api/v2/#{word}/#{id}")
|
17
17
|
invalid_ids(word, ["describe #{bad_id}", "delete #{bad_id}"])
|
18
|
-
|
19
|
-
method: :post, path: "/api/v2/search/#{word}",
|
20
|
-
body: { limit: '100',
|
21
|
-
offset: '100',
|
22
|
-
query: [{ key: 'id',
|
23
|
-
value: id,
|
24
|
-
matchingMethod: 'CONTAINS' }],
|
25
|
-
sort: { field: 'id', ascending: true } },
|
26
|
-
headers: JSON_POST_HEADERS)
|
18
|
+
search_tests(word, id)
|
27
19
|
test_list_output(word)
|
28
20
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wavefront-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Fisher
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docopt
|