wavefront-cli 8.5.1 → 9.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/.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)
|