wavefront-cli 8.5.1 → 9.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +4 -4
- data/.github/workflows/test.yml +2 -2
- data/.rubocop.yml +1 -4
- data/HISTORY.md +12 -0
- data/README.md +4 -2
- data/lib/wavefront-cli/base.rb +2 -2
- data/lib/wavefront-cli/commands/base.rb +10 -9
- data/lib/wavefront-cli/commands/derivedmetric.rb +1 -1
- data/lib/wavefront-cli/commands/metric.rb +3 -3
- data/lib/wavefront-cli/commands/metricspolicy.rb +33 -0
- data/lib/wavefront-cli/commands/query.rb +5 -5
- data/lib/wavefront-cli/commands/write.rb +12 -12
- data/lib/wavefront-cli/config.rb +4 -4
- data/lib/wavefront-cli/constants.rb +2 -1
- data/lib/wavefront-cli/controller.rb +19 -15
- data/lib/wavefront-cli/display/metricspolicy.rb +15 -0
- data/lib/wavefront-cli/display/printer/long.rb +11 -13
- data/lib/wavefront-cli/display/printer/sparkline.rb +3 -3
- data/lib/wavefront-cli/display/query.rb +1 -1
- data/lib/wavefront-cli/display/write.rb +2 -1
- data/lib/wavefront-cli/event.rb +2 -2
- data/lib/wavefront-cli/exception_handler.rb +4 -1
- data/lib/wavefront-cli/helpers/load_file.rb +2 -2
- data/lib/wavefront-cli/maintenancewindow.rb +1 -1
- data/lib/wavefront-cli/metricspolicy.rb +42 -0
- data/lib/wavefront-cli/opt_handler.rb +2 -3
- data/lib/wavefront-cli/output/csv/query.rb +2 -2
- data/lib/wavefront-cli/output/hcl/dashboard.rb +6 -6
- data/lib/wavefront-cli/output/hcl/stdlib/array.rb +1 -1
- data/lib/wavefront-cli/output/wavefront/query.rb +7 -7
- data/lib/wavefront-cli/stdlib/string.rb +4 -4
- data/lib/wavefront-cli/usage.rb +1 -1
- data/lib/wavefront-cli/version.rb +1 -1
- data/lib/wavefront-cli/write.rb +13 -17
- data/spec/constants.rb +4 -5
- data/spec/support/command_base.rb +12 -0
- data/spec/support/minitest_assertions.rb +14 -10
- data/spec/support/output_tester.rb +2 -2
- data/spec/support/supported_commands.rb +3 -1
- data/spec/test_mixins/import.rb +2 -2
- data/spec/test_mixins/search.rb +9 -7
- data/spec/test_mixins/set.rb +1 -1
- data/spec/wavefront-cli/account_spec.rb +6 -4
- data/spec/wavefront-cli/alert_spec.rb +29 -6
- data/spec/wavefront-cli/commands/base_spec.rb +2 -2
- data/spec/wavefront-cli/commands/config_spec.rb +2 -2
- data/spec/wavefront-cli/config_spec.rb +3 -3
- data/spec/wavefront-cli/controller_spec.rb +2 -0
- data/spec/wavefront-cli/dashboard_spec.rb +1 -1
- data/spec/wavefront-cli/derivedmetric_spec.rb +9 -7
- data/spec/wavefront-cli/display/printer/long_spec.rb +5 -3
- data/spec/wavefront-cli/display/printer/terse_spec.rb +1 -1
- data/spec/wavefront-cli/event_spec.rb +14 -11
- data/spec/wavefront-cli/event_store_spec.rb +16 -12
- data/spec/wavefront-cli/externallink_spec.rb +5 -3
- data/spec/wavefront-cli/maintenancewindow_spec.rb +25 -19
- data/spec/wavefront-cli/message_spec.rb +3 -3
- data/spec/wavefront-cli/metricspolicy_spec.rb +30 -0
- data/spec/wavefront-cli/opt_handler_spec.rb +1 -1
- data/spec/wavefront-cli/output/helpers.rb +1 -1
- data/spec/wavefront-cli/proxy_spec.rb +1 -1
- data/spec/wavefront-cli/query_spec.rb +1 -1
- data/spec/wavefront-cli/role_spec.rb +4 -3
- data/spec/wavefront-cli/serviceaccount_spec.rb +7 -5
- data/spec/wavefront-cli/stdlib/string_spec.rb +3 -1
- data/spec/wavefront-cli/usage_spec.rb +1 -1
- data/spec/wavefront-cli/{write_spec.rb → write_class_spec.rb} +1 -14
- data/wavefront-cli.gemspec +13 -15
- metadata +32 -149
- data/spec/spec_helper.rb +0 -113
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'wavefront-sdk/support/mixins'
|
4
|
+
require_relative 'base'
|
5
|
+
require_relative 'helpers/load_file'
|
6
|
+
|
7
|
+
module WavefrontCli
|
8
|
+
#
|
9
|
+
# CLI coverage for the metricspolicy part of the v2 'usage' API.
|
10
|
+
#
|
11
|
+
class MetricsPolicy < WavefrontCli::Base
|
12
|
+
def do_describe
|
13
|
+
wf.describe(options[:version])
|
14
|
+
end
|
15
|
+
|
16
|
+
def do_history
|
17
|
+
wf.history(options[:offset] || 0, options[:limit] || 100)
|
18
|
+
end
|
19
|
+
|
20
|
+
def do_revert
|
21
|
+
wf.revert(options[:'<version>'])
|
22
|
+
end
|
23
|
+
|
24
|
+
def do_update
|
25
|
+
raw = WavefrontCli::Helper::LoadFile.new(options[:'<file>']).load
|
26
|
+
rules = process_update(raw)
|
27
|
+
wf.update(policyRules: rules)
|
28
|
+
end
|
29
|
+
|
30
|
+
# It looks like the API expects arrays of ID strings for accounts, groups,
|
31
|
+
# and roles, but when you export one, those fields are objects with name
|
32
|
+
# and ID.
|
33
|
+
#
|
34
|
+
def process_update(raw)
|
35
|
+
raw[:policyRules].tap do |rule|
|
36
|
+
rule[:accounts] = rule[:accounts].map { |r| r[:id] }
|
37
|
+
rule[:userGroups] = rule[:userGroups].map { |r| r[:id] }
|
38
|
+
rule[:roles] = rule[:roles].map { |r| r[:id] }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -43,11 +43,10 @@ module WavefrontCli
|
|
43
43
|
# constructor.
|
44
44
|
# @param cli_opts [Hash] options from docopt, which may include
|
45
45
|
# the location of the config file and the stanza within it
|
46
|
-
# @return [Hash] keys are none, one, or both of :file and
|
47
|
-
# :profile
|
46
|
+
# @return [Hash] keys are none, one, or both of :file and :profile
|
48
47
|
#
|
49
48
|
def setup_cred_opts(cli_opts)
|
50
|
-
cred_opts = { raise_on_no_profile: true }
|
49
|
+
cred_opts = cli_opts[:config] ? { raise_on_no_profile: true } : {}
|
51
50
|
|
52
51
|
if cli_opts[:config]
|
53
52
|
cred_opts[:file] = Pathname.new(cli_opts[:config])
|
@@ -32,7 +32,7 @@ module WavefrontCsvOutput
|
|
32
32
|
def raw_output
|
33
33
|
resp.each_with_object([]) do |point, a|
|
34
34
|
point[:points].each do |p|
|
35
|
-
a
|
35
|
+
a << csv_format(options[:'<metric>'],
|
36
36
|
p[:value],
|
37
37
|
p[:timestamp],
|
38
38
|
options[:host],
|
@@ -48,7 +48,7 @@ module WavefrontCsvOutput
|
|
48
48
|
|
49
49
|
resp[:timeseries].each_with_object([]) do |ts, a|
|
50
50
|
ts[:data].each do |point|
|
51
|
-
a
|
51
|
+
a << csv_format(ts[:label],
|
52
52
|
point[1],
|
53
53
|
point[0],
|
54
54
|
ts[:host],
|
@@ -32,19 +32,19 @@ module WavefrontHclOutput
|
|
32
32
|
# @return [String] HCL list of vals
|
33
33
|
#
|
34
34
|
def listmaker(vals, method)
|
35
|
-
vals.each_with_object([]) { |v, a| a
|
35
|
+
vals.each_with_object([]) { |v, a| a << send(method, v) }.to_hcl_list
|
36
36
|
end
|
37
37
|
|
38
38
|
def vhandle_sections(vals)
|
39
39
|
vals.each_with_object([]) do |section, a|
|
40
|
-
a
|
40
|
+
a << ("name = \"#{section[:name]}\"\n row = " +
|
41
41
|
handle_rows(section[:rows])).braced(4)
|
42
42
|
end.to_hcl_list
|
43
43
|
end
|
44
44
|
|
45
45
|
def handle_rows(rows)
|
46
46
|
rows.each_with_object([]) do |row, a|
|
47
|
-
a
|
47
|
+
a << "chart = #{handle_charts(row[:charts])}".braced(8)
|
48
48
|
end.to_hcl_list
|
49
49
|
end
|
50
50
|
|
@@ -58,10 +58,10 @@ module WavefrontHclOutput
|
|
58
58
|
lines = chart.each_with_object([]) do |(k, v), a|
|
59
59
|
next unless fields.include?(k)
|
60
60
|
|
61
|
-
a
|
61
|
+
a << format('%<key>s = %<value>s', key: k, value: quote_value(v))
|
62
62
|
end
|
63
63
|
|
64
|
-
lines
|
64
|
+
lines << "source = #{handle_sources(chart[:sources])}"
|
65
65
|
lines.to_hcl_obj(10)
|
66
66
|
end
|
67
67
|
|
@@ -75,7 +75,7 @@ module WavefrontHclOutput
|
|
75
75
|
|
76
76
|
k = 'queryBuilderEnabled' if k == 'querybuilderEnabled'
|
77
77
|
|
78
|
-
a
|
78
|
+
a << format('%<key>s = %<value>s',
|
79
79
|
key: k.to_snake,
|
80
80
|
value: quote_value(v))
|
81
81
|
end.to_hcl_obj(14)
|
@@ -20,11 +20,11 @@ module WavefrontWavefrontOutput
|
|
20
20
|
def raw_output
|
21
21
|
resp.each_with_object('') do |point, a|
|
22
22
|
point[:points].each do |p|
|
23
|
-
a
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
a << "#{wavefront_format(options[:'<metric>'],
|
24
|
+
p[:value],
|
25
|
+
p[:timestamp],
|
26
|
+
options[:host],
|
27
|
+
point[:tags])}\n"
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -34,7 +34,7 @@ module WavefrontWavefrontOutput
|
|
34
34
|
|
35
35
|
resp[:timeseries].each_with_object([]) do |ts, a|
|
36
36
|
ts[:data].each do |point|
|
37
|
-
a
|
37
|
+
a << wavefront_format(ts[:label],
|
38
38
|
point[1],
|
39
39
|
point[0],
|
40
40
|
ts[:host],
|
@@ -46,7 +46,7 @@ module WavefrontWavefrontOutput
|
|
46
46
|
def wavefront_format(path, value, timestamp, source, tags = nil)
|
47
47
|
arr = [path, value, timestamp, format('source=%<source>s',
|
48
48
|
source: source)]
|
49
|
-
arr
|
49
|
+
arr << tags.to_wf_tag if tags && !tags.empty?
|
50
50
|
arr.join(' ')
|
51
51
|
end
|
52
52
|
end
|
@@ -10,7 +10,7 @@ class String
|
|
10
10
|
# @param indent [Integer] size of hanging indent, in chars
|
11
11
|
#
|
12
12
|
def cmd_fold(twidth = TW, indent = 10)
|
13
|
-
gsub(/(-\w) /, '\\1^').scan_line(twidth - 12).join("\n
|
13
|
+
gsub(/(-\w) /, '\\1^').scan_line(twidth - 12).join("\n#{' ' * indent}")
|
14
14
|
.restored
|
15
15
|
end
|
16
16
|
|
@@ -58,7 +58,7 @@ class String
|
|
58
58
|
#
|
59
59
|
def value_fold(indent = 0, twidth = TW)
|
60
60
|
max_line_length = twidth - indent - 4
|
61
|
-
scan_line(max_line_length).join("\n
|
61
|
+
scan_line(max_line_length).join("\n#{' ' * indent}")
|
62
62
|
end
|
63
63
|
|
64
64
|
# @param width [Integer] length of longest string (width of
|
@@ -94,7 +94,7 @@ class String
|
|
94
94
|
#
|
95
95
|
def to_snake
|
96
96
|
gsub(/(.)([A-Z])/) do
|
97
|
-
Regexp.last_match[1]
|
97
|
+
"#{Regexp.last_match[1]}_#{Regexp.last_match[2].downcase}"
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
@@ -102,7 +102,7 @@ class String
|
|
102
102
|
|
103
103
|
def indent_folded_lines(chunks, twidth, indent, prefix)
|
104
104
|
chunks.join(' ').scan_line(twidth - indent - 5).map do |line|
|
105
|
-
prefix
|
105
|
+
"#{prefix}#{' ' * indent}#{line}"
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
data/lib/wavefront-cli/usage.rb
CHANGED
data/lib/wavefront-cli/write.rb
CHANGED
@@ -74,8 +74,8 @@ module WavefrontCli
|
|
74
74
|
end
|
75
75
|
# rubocop:enable Metrics/AbcSize
|
76
76
|
|
77
|
-
# Turn our user's representation of a distribution into one
|
78
|
-
#
|
77
|
+
# Turn our user's representation of a distribution into one which suits
|
78
|
+
# Wavefront. The SDK can do this for us.
|
79
79
|
#
|
80
80
|
def mk_dist
|
81
81
|
xpanded = expand_dist(options[:'<val>'])
|
@@ -83,7 +83,11 @@ module WavefrontCli
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def extra_options
|
86
|
-
|
86
|
+
if options[:using]
|
87
|
+
{ writer: options[:using] }
|
88
|
+
else
|
89
|
+
{ writer: :http }
|
90
|
+
end
|
87
91
|
end
|
88
92
|
|
89
93
|
# I chose to prioritise UI consistency over internal elegance
|
@@ -108,6 +112,7 @@ module WavefrontCli
|
|
108
112
|
port: options[:port] || default_port,
|
109
113
|
socket: options[:socket],
|
110
114
|
endpoint: options[:endpoint],
|
115
|
+
agent: "wavefront-cli-#{WF_CLI_VERSION}",
|
111
116
|
token: options[:token] }
|
112
117
|
end
|
113
118
|
|
@@ -115,18 +120,9 @@ module WavefrontCli
|
|
115
120
|
distribution? ? 40_000 : 2878
|
116
121
|
end
|
117
122
|
|
123
|
+
# The SDK writer plugins validate the credentials they need
|
118
124
|
def validate_opts
|
119
125
|
validate_opts_file if options[:file]
|
120
|
-
|
121
|
-
if options[:using] == 'unix'
|
122
|
-
return true if options[:socket]
|
123
|
-
|
124
|
-
raise(WavefrontCli::Exception::CredentialError, 'No socket path.')
|
125
|
-
end
|
126
|
-
|
127
|
-
return true if options[:proxy]
|
128
|
-
|
129
|
-
raise(WavefrontCli::Exception::CredentialError, 'No proxy address.')
|
130
126
|
end
|
131
127
|
|
132
128
|
def validate_opts_file
|
@@ -167,7 +163,7 @@ module WavefrontCli
|
|
167
163
|
#
|
168
164
|
def process_input_file(data)
|
169
165
|
data.each_with_object([]) do |l, a|
|
170
|
-
a
|
166
|
+
a << process_line(l)
|
171
167
|
rescue WavefrontCli::Exception::UnparseableInput => e
|
172
168
|
puts "Bad input. #{e.message}."
|
173
169
|
next
|
@@ -426,17 +422,17 @@ module WavefrontCli
|
|
426
422
|
#
|
427
423
|
def valid_timestamp?(timestamp)
|
428
424
|
(timestamp.is_a?(Integer) ||
|
429
|
-
timestamp.is_a?(String) && timestamp.match(/^\d+$/)) &&
|
425
|
+
(timestamp.is_a?(String) && timestamp.match(/^\d+$/))) &&
|
430
426
|
timestamp.to_i > 946_684_800 &&
|
431
427
|
timestamp.to_i < (Time.now.to_i + 31_557_600)
|
432
428
|
end
|
433
429
|
|
434
430
|
def setup_fmt(fmt)
|
435
|
-
@fmt = fmt.
|
431
|
+
@fmt = fmt.chars
|
436
432
|
end
|
437
433
|
|
438
434
|
def load_data(file)
|
439
|
-
|
435
|
+
File.read(file)
|
440
436
|
rescue StandardError
|
441
437
|
raise WavefrontCli::Exception::FileNotFound
|
442
438
|
end
|
data/spec/constants.rb
CHANGED
@@ -12,10 +12,9 @@ TW = 80
|
|
12
12
|
|
13
13
|
ENDPOINT = 'metrics.wavefront.com'
|
14
14
|
TOKEN = '0123456789-ABCDEF'
|
15
|
-
RES_DIR = ROOT
|
16
|
-
CF = RES_DIR
|
15
|
+
RES_DIR = ROOT.join('spec', 'wavefront-cli', 'resources')
|
16
|
+
CF = RES_DIR.join('wavefront.conf')
|
17
17
|
CF_VAL = IniFile.load(CF)
|
18
|
-
JSON_POST_HEADERS = {
|
19
|
-
|
20
|
-
}.freeze
|
18
|
+
JSON_POST_HEADERS = { 'Content-Type': 'application/json',
|
19
|
+
Accept: 'application/json' }.freeze
|
21
20
|
TEE_ZERO = Time.now.freeze
|
@@ -9,11 +9,13 @@ require_relative '../../lib/wavefront-cli/controller'
|
|
9
9
|
# commands.
|
10
10
|
#
|
11
11
|
class EndToEndTest < MiniTest::Test
|
12
|
+
attr_accessor :single_perm
|
12
13
|
attr_reader :wf
|
13
14
|
|
14
15
|
def setup
|
15
16
|
before_setup if respond_to?(:before_setup)
|
16
17
|
@wf = WavefrontCliController
|
18
|
+
@single_perm = false
|
17
19
|
end
|
18
20
|
|
19
21
|
def api_path
|
@@ -79,4 +81,14 @@ class EndToEndTest < MiniTest::Test
|
|
79
81
|
{ status: { result: 'OK', message: '', code: 200 },
|
80
82
|
items: [] }.to_json
|
81
83
|
end
|
84
|
+
|
85
|
+
def blank_envvars
|
86
|
+
%w[WAVEFRONT_ENDPOINT WAVEFRONT_PROXY WAVEFRONT_TOKEN].each do |v|
|
87
|
+
ENV[v] = nil
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def config?
|
92
|
+
Pathname.new(Dir.home).join('.wavefront').exist?
|
93
|
+
end
|
82
94
|
end
|
@@ -147,10 +147,13 @@ module Minitest
|
|
147
147
|
end
|
148
148
|
|
149
149
|
def assert_cmd_posts(command, api_path, payload = 'null',
|
150
|
-
response =
|
150
|
+
response = nil, extra_headers = {})
|
151
|
+
response ||= dummy_response
|
151
152
|
all_permutations do |p|
|
152
153
|
assert_posts("https://#{p[:endpoint]}#{api_path}",
|
153
|
-
mk_headers(p[:token]
|
154
|
+
mk_headers(p[:token], extra_headers),
|
155
|
+
payload,
|
156
|
+
response) do
|
154
157
|
wf.new("#{cmd_word} #{command} #{p[:cmdline]}".split)
|
155
158
|
end
|
156
159
|
end
|
@@ -166,7 +169,7 @@ module Minitest
|
|
166
169
|
end
|
167
170
|
|
168
171
|
def assert_cmd_deletes(command, api_path, response = dummy_response)
|
169
|
-
|
172
|
+
all_permutations do |p|
|
170
173
|
assert_deletes("https://#{p[:endpoint]}#{api_path}",
|
171
174
|
mk_headers(p[:token]), response) do
|
172
175
|
wf.new("#{cmd_word} #{command} #{p[:cmdline]}".split)
|
@@ -188,13 +191,14 @@ module Minitest
|
|
188
191
|
assert_empty(err)
|
189
192
|
end
|
190
193
|
|
191
|
-
# Run tests with all available permutations
|
192
|
-
#
|
193
|
-
#
|
194
|
+
# Run tests with all available permutations, unless the single_perm class
|
195
|
+
# variable is set. This lets us run tests faster by running fewer (but
|
196
|
+
# still a good random selection) and lets us run tests which must only be
|
197
|
+
# run once, like tests which pop stuff off the event stack.
|
194
198
|
#
|
195
199
|
def all_permutations
|
196
200
|
perms = permutations
|
197
|
-
perms =
|
201
|
+
perms = perms.shuffle.take(1) if @single_perm || ENV['FAST_TESTS']
|
198
202
|
|
199
203
|
perms.each do |p|
|
200
204
|
yield(p)
|
@@ -213,11 +217,11 @@ module Minitest
|
|
213
217
|
|
214
218
|
private
|
215
219
|
|
216
|
-
def mk_headers(token = nil)
|
220
|
+
def mk_headers(token = nil, extra_headers = {})
|
217
221
|
{ Accept: /.*/,
|
218
222
|
'Accept-Encoding': /.*/,
|
219
|
-
Authorization:
|
220
|
-
'User-Agent': "wavefront-cli-#{WF_CLI_VERSION}" }
|
223
|
+
Authorization: "Bearer #{token || '0123456789-ABCDEF'}",
|
224
|
+
'User-Agent': "wavefront-cli-#{WF_CLI_VERSION}" }.merge(extra_headers)
|
221
225
|
end
|
222
226
|
|
223
227
|
# Every command we simulate running is done under the following
|
@@ -14,7 +14,7 @@ class OutputTester
|
|
14
14
|
# @return [Object] canned raw responses used to test outputs
|
15
15
|
#
|
16
16
|
def load_input(file, only_items = true)
|
17
|
-
ret = JSON.parse(
|
17
|
+
ret = JSON.parse(File.read(RES_DIR.join('display', file)),
|
18
18
|
symbolize_names: true)
|
19
19
|
only_items ? ret[:items] : ret
|
20
20
|
end
|
@@ -23,7 +23,7 @@ class OutputTester
|
|
23
23
|
# @return [String]
|
24
24
|
#
|
25
25
|
def load_expected(file)
|
26
|
-
|
26
|
+
File.read(RES_DIR.join('display', file))
|
27
27
|
end
|
28
28
|
|
29
29
|
def in_and_out(input, expected, only_items = true)
|
@@ -2,11 +2,13 @@
|
|
2
2
|
|
3
3
|
require_relative '../constants'
|
4
4
|
|
5
|
+
# Produces a list of wf's commands
|
6
|
+
#
|
5
7
|
class SupportedCommands
|
6
8
|
attr_reader :cmd_dir
|
7
9
|
|
8
10
|
def initialize
|
9
|
-
@cmd_dir = ROOT
|
11
|
+
@cmd_dir = ROOT.join('lib', 'wavefront-cli', 'commands')
|
10
12
|
end
|
11
13
|
|
12
14
|
def all
|
data/spec/test_mixins/import.rb
CHANGED
@@ -61,11 +61,11 @@ module WavefrontCliTest
|
|
61
61
|
private
|
62
62
|
|
63
63
|
def import_file
|
64
|
-
RES_DIR
|
64
|
+
RES_DIR.join('imports', "#{api_path}.json")
|
65
65
|
end
|
66
66
|
|
67
67
|
def update_file
|
68
|
-
RES_DIR
|
68
|
+
RES_DIR.join('updates', "#{api_path}.json")
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
data/spec/test_mixins/search.rb
CHANGED
@@ -18,17 +18,19 @@ module WavefrontCliTest
|
|
18
18
|
sort: { field: 'id', ascending: true })
|
19
19
|
end
|
20
20
|
|
21
|
+
json_body = { limit: 10,
|
22
|
+
offset: 0,
|
23
|
+
query: [{ key: 'id',
|
24
|
+
value: id,
|
25
|
+
matchingMethod: 'EXACT',
|
26
|
+
negated: false }],
|
27
|
+
sort: { field: 'id', ascending: true } }.to_json
|
28
|
+
|
21
29
|
assert_noop(
|
22
30
|
"search id=#{id}",
|
23
31
|
'uri: POST https://default.wavefront.com/api/v2/search/' \
|
24
32
|
"#{search_api_path}",
|
25
|
-
|
26
|
-
offset: 0,
|
27
|
-
query: [{ key: 'id',
|
28
|
-
value: id,
|
29
|
-
matchingMethod: 'EXACT',
|
30
|
-
negated: false }],
|
31
|
-
sort: { field: 'id', ascending: true } }.to_json
|
33
|
+
"body: #{json_body}"
|
32
34
|
)
|
33
35
|
assert_abort_on_missing_creds("search id=#{id}")
|
34
36
|
assert_usage('search')
|
data/spec/test_mixins/set.rb
CHANGED
@@ -228,10 +228,12 @@ class AccountEndToEndTest < EndToEndTest
|
|
228
228
|
cmd = "validate #{user_list.join(' ')}"
|
229
229
|
|
230
230
|
quietly do
|
231
|
-
assert_cmd_posts(
|
232
|
-
|
233
|
-
|
234
|
-
|
231
|
+
assert_cmd_posts(
|
232
|
+
cmd,
|
233
|
+
'/api/v2/account/validateAccounts',
|
234
|
+
user_list.to_json,
|
235
|
+
File.read(RES_DIR.join('responses', 'user-validate.json'))
|
236
|
+
)
|
235
237
|
end
|
236
238
|
|
237
239
|
assert_noop(cmd,
|
@@ -21,6 +21,25 @@ class AlertEndToEndTest < EndToEndTest
|
|
21
21
|
include WavefrontCliTest::History
|
22
22
|
include WavefrontCliTest::Acl
|
23
23
|
|
24
|
+
# This test isn't run if whoever runs it has a config file, because it tests
|
25
|
+
# wf's behaviour only if that file does not exist. CI will never have that
|
26
|
+
# file.
|
27
|
+
#
|
28
|
+
def test_no_config_no_envvars
|
29
|
+
skip if config?
|
30
|
+
|
31
|
+
blank_envvars
|
32
|
+
wf = WavefrontCliController
|
33
|
+
|
34
|
+
out, err = capture_io do
|
35
|
+
assert_raises(SystemExit) { wf.new(%w[alert list]) }
|
36
|
+
end
|
37
|
+
|
38
|
+
assert_empty(err)
|
39
|
+
assert out.start_with?('Credential error. Missing api token.')
|
40
|
+
assert_match(/You may also run 'wf config setup'/, out)
|
41
|
+
end
|
42
|
+
|
24
43
|
def test_latest
|
25
44
|
quietly do
|
26
45
|
assert_cmd_gets("latest #{id}", "/api/v2/alert/#{id}/history")
|
@@ -48,10 +67,12 @@ class AlertEndToEndTest < EndToEndTest
|
|
48
67
|
id: id, v: nil, name: nil)
|
49
68
|
end
|
50
69
|
|
70
|
+
json_body = { id: id, name: nil, v: nil }.to_json
|
71
|
+
|
51
72
|
assert_noop("clone #{id}",
|
52
73
|
'uri: POST https://default.wavefront.com/api/v2/' \
|
53
74
|
"alert/#{id}/clone",
|
54
|
-
|
75
|
+
"body: #{json_body}")
|
55
76
|
|
56
77
|
assert_invalid_id("clone #{invalid_id}")
|
57
78
|
assert_usage('clone')
|
@@ -65,10 +86,12 @@ class AlertEndToEndTest < EndToEndTest
|
|
65
86
|
id: id, v: 5, name: nil)
|
66
87
|
end
|
67
88
|
|
89
|
+
json_body = { id: id, name: nil, v: 5 }.to_json
|
90
|
+
|
68
91
|
assert_noop("clone #{id} --version 5",
|
69
92
|
'uri: POST https://default.wavefront.com/api/v2/' \
|
70
93
|
"alert/#{id}/clone",
|
71
|
-
|
94
|
+
"body: #{json_body}")
|
72
95
|
|
73
96
|
assert_invalid_id("clone -v 10 #{invalid_id}")
|
74
97
|
assert_usage('clone -v')
|
@@ -173,7 +196,7 @@ class AlertEndToEndTest < EndToEndTest
|
|
173
196
|
assert_noop('snoozed',
|
174
197
|
'uri: POST https://default.wavefront.com/api/v2/' \
|
175
198
|
'search/alert',
|
176
|
-
|
199
|
+
"body: #{state_search('snoozed').to_json}")
|
177
200
|
|
178
201
|
assert_abort_on_missing_creds('snoozed')
|
179
202
|
end
|
@@ -193,7 +216,7 @@ class AlertEndToEndTest < EndToEndTest
|
|
193
216
|
assert_noop('firing',
|
194
217
|
'uri: POST https://default.wavefront.com/api/v2/' \
|
195
218
|
'search/alert',
|
196
|
-
|
219
|
+
"body: #{state_search('firing').to_json}")
|
197
220
|
|
198
221
|
assert_abort_on_missing_creds('firing')
|
199
222
|
end
|
@@ -213,7 +236,7 @@ class AlertEndToEndTest < EndToEndTest
|
|
213
236
|
assert_noop('currently firing',
|
214
237
|
'uri: POST https://default.wavefront.com/api/v2/' \
|
215
238
|
'search/alert',
|
216
|
-
|
239
|
+
"body: #{state_search('firing').to_json}")
|
217
240
|
|
218
241
|
assert_abort_on_missing_creds('currently firing')
|
219
242
|
end
|
@@ -233,7 +256,7 @@ class AlertEndToEndTest < EndToEndTest
|
|
233
256
|
assert_noop('currently in_maintenance',
|
234
257
|
'uri: POST https://default.wavefront.com/api/v2/' \
|
235
258
|
'search/alert',
|
236
|
-
|
259
|
+
"body: #{state_search('in_maintenance').to_json}")
|
237
260
|
|
238
261
|
assert_abort_on_missing_creds('currently in_maintenance')
|
239
262
|
end
|
@@ -68,7 +68,7 @@ class WavefrontCommmandBaseTest < MiniTest::Test
|
|
68
68
|
assert wf.commands.start_with?("Usage:\n")
|
69
69
|
assert wf.commands.match(/ --help$/)
|
70
70
|
|
71
|
-
wf.commands(600).split("\n")[1
|
71
|
+
wf.commands(600).split("\n")[1..].each do |c|
|
72
72
|
next if skip_cmd && c.match(skip_cmd)
|
73
73
|
|
74
74
|
assert_match(/^ \w+/, c)
|
@@ -80,7 +80,7 @@ class WavefrontCommmandBaseTest < MiniTest::Test
|
|
80
80
|
assert wf.options(600).start_with?("Global options:\n")
|
81
81
|
assert_match(/\nOptions:/, wf.options)
|
82
82
|
|
83
|
-
wf.options(600).split("\n")[1
|
83
|
+
wf.options(600).split("\n")[1..].each do |o|
|
84
84
|
next if o == 'Global options:' || o == 'Options:' || o.empty?
|
85
85
|
|
86
86
|
assert_instance_of(String, o)
|
@@ -20,7 +20,7 @@ class WavefrontCommmandConfigTest < WavefrontCommmandBaseTest
|
|
20
20
|
refute wf.options(600).start_with?("Global options:\n")
|
21
21
|
assert_match(/Options:\n/, wf.options)
|
22
22
|
|
23
|
-
wf.options(600).split("\n")[1
|
23
|
+
wf.options(600).split("\n")[1..].each do |o|
|
24
24
|
next if o == 'Global options:' || o == 'Options:' || o.empty?
|
25
25
|
|
26
26
|
assert_instance_of(String, o)
|
@@ -35,7 +35,7 @@ class WavefrontCommmandConfigTest < WavefrontCommmandBaseTest
|
|
35
35
|
assert wf.commands.start_with?("Usage:\n")
|
36
36
|
assert wf.commands.match(/ --help$/)
|
37
37
|
|
38
|
-
wf.commands(600).split("\n")[1
|
38
|
+
wf.commands(600).split("\n")[1..].each do |c|
|
39
39
|
next if skip_cmd && c.match(skip_cmd)
|
40
40
|
|
41
41
|
assert_match(/^ \w+/, c)
|