wavefront-cli 5.1.1 → 7.2.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +37 -1
  3. data/HISTORY.md +34 -2
  4. data/README.md +2 -4
  5. data/lib/wavefront-cli/account.rb +119 -0
  6. data/lib/wavefront-cli/alert.rb +29 -0
  7. data/lib/wavefront-cli/base.rb +0 -2
  8. data/lib/wavefront-cli/cloudintegration.rb +12 -0
  9. data/lib/wavefront-cli/commands/.rubocop.yml +34 -0
  10. data/lib/wavefront-cli/commands/account.rb +61 -0
  11. data/lib/wavefront-cli/commands/alert.rb +1 -0
  12. data/lib/wavefront-cli/commands/base.rb +1 -1
  13. data/lib/wavefront-cli/commands/cloudintegration.rb +4 -1
  14. data/lib/wavefront-cli/commands/proxy.rb +2 -1
  15. data/lib/wavefront-cli/commands/query.rb +4 -1
  16. data/lib/wavefront-cli/commands/role.rb +44 -0
  17. data/lib/wavefront-cli/commands/spy.rb +0 -5
  18. data/lib/wavefront-cli/commands/usergroup.rb +7 -11
  19. data/lib/wavefront-cli/commands/write.rb +7 -2
  20. data/lib/wavefront-cli/controller.rb +5 -63
  21. data/lib/wavefront-cli/display/account.rb +122 -0
  22. data/lib/wavefront-cli/display/alert.rb +8 -0
  23. data/lib/wavefront-cli/display/base.rb +1 -1
  24. data/lib/wavefront-cli/display/cloudintegration.rb +15 -2
  25. data/lib/wavefront-cli/display/printer/long.rb +2 -1
  26. data/lib/wavefront-cli/display/proxy.rb +16 -0
  27. data/lib/wavefront-cli/display/role.rb +66 -0
  28. data/lib/wavefront-cli/display/settings.rb +1 -0
  29. data/lib/wavefront-cli/display/usergroup.rb +18 -14
  30. data/lib/wavefront-cli/exception_handler.rb +89 -0
  31. data/lib/wavefront-cli/output/hcl/base.rb +1 -1
  32. data/lib/wavefront-cli/output/hcl/dashboard.rb +1 -1
  33. data/lib/wavefront-cli/proxy.rb +5 -0
  34. data/lib/wavefront-cli/query.rb +13 -7
  35. data/lib/wavefront-cli/role.rb +54 -0
  36. data/lib/wavefront-cli/serviceaccount.rb +0 -6
  37. data/lib/wavefront-cli/spy.rb +0 -8
  38. data/lib/wavefront-cli/usergroup.rb +8 -8
  39. data/lib/wavefront-cli/version.rb +1 -1
  40. data/lib/wavefront-cli/write.rb +29 -5
  41. data/spec/.rubocop.yml +34 -0
  42. data/spec/test_mixins/delete.rb +1 -2
  43. data/spec/wavefront-cli/account_spec.rb +303 -0
  44. data/spec/wavefront-cli/alert_spec.rb +28 -0
  45. data/spec/wavefront-cli/cloudintegration_spec.rb +19 -6
  46. data/spec/wavefront-cli/commands/write_spec.rb +1 -1
  47. data/spec/wavefront-cli/event_spec.rb +1 -1
  48. data/spec/wavefront-cli/output/csv/query_spec.rb +1 -1
  49. data/spec/wavefront-cli/output/wavefront/query_spec.rb +2 -2
  50. data/spec/wavefront-cli/query_spec.rb +20 -3
  51. data/spec/wavefront-cli/role_spec.rb +187 -0
  52. data/spec/wavefront-cli/serviceaccount_spec.rb +3 -3
  53. data/spec/wavefront-cli/usergroup_spec.rb +48 -43
  54. data/spec/wavefront-cli/write_spec.rb +44 -0
  55. data/wavefront-cli.gemspec +3 -3
  56. metadata +28 -36
  57. data/lib/wavefront-cli/commands/cluster.rb +0 -44
  58. data/lib/wavefront-cli/commands/user.rb +0 -54
  59. data/lib/wavefront-cli/display/monitoredcluster.rb +0 -14
  60. data/lib/wavefront-cli/display/user.rb +0 -103
  61. data/lib/wavefront-cli/monitoredcluster.rb +0 -50
  62. data/lib/wavefront-cli/user.rb +0 -92
  63. data/spec/wavefront-cli/monitoredcluster_spec.rb +0 -85
  64. data/spec/wavefront-cli/resources/responses/user-list.json +0 -1
  65. data/spec/wavefront-cli/user_spec.rb +0 -311
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- WF_CLI_VERSION = '5.1.1'
3
+ WF_CLI_VERSION = '7.2.0'
@@ -9,15 +9,16 @@ module WavefrontCli
9
9
  #
10
10
  class Write < Base
11
11
  attr_reader :fmt
12
+
12
13
  include Wavefront::Mixins
13
14
  SPLIT_PATTERN = /\s(?=(?:[^"]|"[^"]*")*$)/.freeze
14
15
 
15
16
  # rubocop:disable Metrics/AbcSize
16
- def do_point
17
+ def do_point(value = options[:'<value>'])
17
18
  tags = tags_to_hash(options[:tag])
18
19
 
19
20
  p = { path: options[:'<metric>'],
20
- value: options[:'<value>'].delete('\\').to_f }
21
+ value: sane_value(value) }
21
22
 
22
23
  p[:tags] = tags unless tags.empty?
23
24
  p[:source] = options[:host] if options[:host]
@@ -36,6 +37,31 @@ module WavefrontCli
36
37
  send_point(make_distribution_point(tags_to_hash(options[:tag])))
37
38
  end
38
39
 
40
+ def do_noise
41
+ loop do
42
+ do_point(random_value(options[:min] || -10, options[:max] || 10))
43
+ sleep(sleep_time)
44
+ end
45
+ end
46
+
47
+ def random_value(min, max)
48
+ return min if min == max
49
+
50
+ rand(max.to_f - min.to_f) + min.to_f
51
+ end
52
+
53
+ def sane_value(value)
54
+ return value if value.is_a?(Numeric)
55
+
56
+ raise WavefrontCli::Exception::InvalidValue unless value.is_a?(String)
57
+
58
+ value.delete('\\').to_f
59
+ end
60
+
61
+ def sleep_time
62
+ options[:interval] ? options[:interval].to_f : 1
63
+ end
64
+
39
65
  # rubocop:disable Metrics/AbcSize
40
66
  def make_distribution_point(tags)
41
67
  { path: options[:'<metric>'],
@@ -121,7 +147,7 @@ module WavefrontCli
121
147
  def send_point(point)
122
148
  call_write(point)
123
149
  rescue Wavefront::Exception::InvalidEndpoint
124
- abort format("Could not connect to proxy '%<proxy>s:%<port>s'.", options)
150
+ abort format("Could not connect to proxy '%<proxy>s:%<port>s'.", wf.creds)
125
151
  end
126
152
 
127
153
  # Read the input, from a file or from STDIN, and turn each line
@@ -270,7 +296,6 @@ module WavefrontCli
270
296
  # @raise WavefrontCli::Exception::UnparseableInput if the line
271
297
  # doesn't look right
272
298
  #
273
- # rubocop:disable Metrics/CyclomaticComplexity
274
299
  # rubocop:disable Metrics/MethodLength
275
300
  # rubocop:disable Metrics/AbcSize
276
301
  def process_line(line)
@@ -293,7 +318,6 @@ module WavefrontCli
293
318
  end
294
319
  # rubocop:enable Metrics/AbcSize
295
320
  # rubocop:enable Metrics/MethodLength
296
- # rubocop:enable Metrics/CyclomaticComplexity
297
321
 
298
322
  # We can get tags from the file, from the -T option, or both.
299
323
  # Merge them, making the -T win if there is a collision.
@@ -14,3 +14,37 @@ Style/HashTransformKeys:
14
14
  Enabled: true
15
15
  Style/HashTransformValues:
16
16
  Enabled: true
17
+
18
+ # new compatabilities
19
+ Layout/EmptyLinesAroundAttributeAccessor:
20
+ Enabled: true
21
+ Layout/SpaceAroundMethodCallOperator:
22
+ Enabled: true
23
+ Lint/RaiseException:
24
+ Enabled: true
25
+ Lint/StructNewOverride:
26
+ Enabled: true
27
+ Style/ExponentialNotation:
28
+ Enabled: true
29
+ Style/SlicingWithRange:
30
+ Enabled: true
31
+ Lint/DeprecatedOpenSSLConstant:
32
+ Enabled: true
33
+ Lint/MixedRegexpCaptureTypes:
34
+ Enabled: true
35
+ Style/RedundantRegexpCharacterClass:
36
+ Enabled: true
37
+ Style/RedundantRegexpEscape:
38
+ Enabled: true
39
+ Style/AccessorGrouping:
40
+ Enabled: true
41
+ Style/BisectedAttrAccessor:
42
+ Enabled: true
43
+ Style/RedundantAssignment:
44
+ Enabled: true
45
+ Style/RedundantFetchBlock:
46
+ Enabled: true
47
+
48
+ # Is nothing sacred?
49
+ Layout/LineLength:
50
+ Max: 80
@@ -15,8 +15,7 @@ module WavefrontCliTest
15
15
 
16
16
  assert_noop(
17
17
  "delete #{id}",
18
- 'uri: DELETE https://default.wavefront.com/api/v2/' \
19
- "#{api_path}/#{id}"
18
+ "uri: DELETE https://default.wavefront.com/api/v2/#{api_path}/#{id}"
20
19
  )
21
20
 
22
21
  assert_abort_on_missing_creds("delete #{id}")
@@ -0,0 +1,303 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../support/command_base'
5
+ require_relative '../../lib/wavefront-cli/account'
6
+
7
+ # Ensure 'account' commands produce the correct API calls.
8
+ #
9
+ class AccountEndToEndTest < EndToEndTest
10
+ include WavefrontCliTest::List
11
+ include WavefrontCliTest::Delete
12
+ include WavefrontCliTest::Describe
13
+ include WavefrontCliTest::Search
14
+
15
+ def test_role_add_to
16
+ quietly do
17
+ assert_cmd_posts("role add to #{id} #{roles.join(' ')}",
18
+ "/api/v2/account/#{id}/addRoles",
19
+ roles.to_json)
20
+ end
21
+
22
+ assert_invalid_id("role add to #{invalid_id} #{roles.first}")
23
+ assert_invalid_id("role add to #{id} #{invalid_role}")
24
+ assert_abort_on_missing_creds("role add to #{id} #{roles.last}")
25
+ assert_usage("role add to #{roles.first}")
26
+ end
27
+
28
+ def test_role_remove_from
29
+ quietly do
30
+ assert_cmd_posts("role remove from #{id} #{roles.join(' ')}",
31
+ "/api/v2/account/#{id}/removeRoles",
32
+ roles.to_json)
33
+ end
34
+
35
+ assert_invalid_id("role remove from #{invalid_id} #{roles.first}")
36
+ assert_abort_on_missing_creds("role remove from #{id} #{roles.last}")
37
+ assert_usage("role remove from #{roles.first}")
38
+ end
39
+
40
+ def test_add_group_to
41
+ assert_repeated_output("Added '#{id}' to '#{groups.first}'.") do
42
+ assert_cmd_posts("group add to #{id} #{groups.first}",
43
+ "/api/v2/account/#{id}/addUserGroups",
44
+ [groups.first].to_json)
45
+ end
46
+
47
+ assert_invalid_id("group add to #{id} #{invalid_group}")
48
+ assert_invalid_id("group add to #{invalid_id} #{groups.first}")
49
+ assert_abort_on_missing_creds("group add to #{id} #{groups.last}")
50
+ assert_usage("group add to #{groups.first}")
51
+ end
52
+
53
+ def test_remove_group_from
54
+ assert_repeated_output("Removed '#{id}' from '#{groups.first}', " \
55
+ "'#{groups.last}'.") do
56
+ assert_cmd_posts("group remove from #{id} #{groups.join(' ')}",
57
+ "/api/v2/account/#{id}/removeUserGroups",
58
+ groups.to_json)
59
+ end
60
+
61
+ assert_invalid_id("group remove from #{id} #{invalid_group}")
62
+ assert_invalid_id("group remove from #{invalid_id} #{groups.first}")
63
+ assert_abort_on_missing_creds("group remove from #{id} #{groups.last}")
64
+ assert_usage("group remove from #{groups.first}")
65
+ end
66
+
67
+ def test_business_functions
68
+ quietly do
69
+ assert_cmd_gets("business functions #{id}",
70
+ "/api/v2/account/#{id}/businessFunctions")
71
+ end
72
+
73
+ assert_noop("business functions #{id}",
74
+ 'uri: GET https://default.wavefront.com/api/v2/account/' \
75
+ "#{id}/businessFunctions")
76
+ assert_invalid_id("business functions #{invalid_id}")
77
+ assert_abort_on_missing_creds("business functions #{id}")
78
+ assert_usage('business functions')
79
+ end
80
+
81
+ def test_grant_to
82
+ assert_repeated_output("Granted '#{permission}' to '#{id}'.") do
83
+ assert_cmd_posts("grant #{permission} to #{id}",
84
+ "/api/v2/account/grant/#{permission}",
85
+ [id].to_json)
86
+ end
87
+
88
+ assert_invalid_id("grant #{permission} to #{invalid_id}")
89
+ assert_abort_on_missing_creds("grant #{permission} to #{id}")
90
+ assert_usage("grant #{permission}")
91
+ end
92
+
93
+ def test_revoke_from
94
+ assert_repeated_output("Revoked '#{permission}' from '#{id}'.") do
95
+ assert_cmd_posts("revoke #{permission} from #{id}",
96
+ "/api/v2/account/revoke/#{permission}",
97
+ [id].to_json)
98
+ end
99
+
100
+ out, err = capture_io do
101
+ assert_raises(SystemExit) do
102
+ wf.new("account revoke #{invalid_permission} from #{id}".split)
103
+ end
104
+ end
105
+
106
+ assert_empty out
107
+ assert_equal("'made_up_permission' is not a valid Wavefront permission.",
108
+ err.strip)
109
+
110
+ assert_invalid_id("revoke #{permission} from #{invalid_id}")
111
+ assert_abort_on_missing_creds("revoke #{permission} from #{id}")
112
+ assert_usage("revoke #{permission}")
113
+ end
114
+
115
+ def test_roles
116
+ assert_repeated_output("'#{id}' has no roles.") do
117
+ assert_cmd_gets("roles #{id}", "/api/v2/account/#{id}", [])
118
+ end
119
+
120
+ assert_abort_on_missing_creds("roles #{id}")
121
+ assert_invalid_id("roles #{invalid_id}")
122
+ assert_usage('roles')
123
+ end
124
+
125
+ def test_add_ingestionpolicy_to
126
+ assert_repeated_output("Added '#{policy}' to '#{id}'.") do
127
+ assert_cmd_posts("ingestionpolicy add to #{id} #{policy}",
128
+ '/api/v2/account/addingestionpolicy',
129
+ { ingestionPolicyId: policy,
130
+ accounts: [id] }.to_json)
131
+ end
132
+
133
+ assert_invalid_id("ingestionpolicy add to #{invalid_id} #{policy}")
134
+ assert_invalid_id("ingestionpolicy add to #{id} #{invalid_policy}")
135
+ assert_abort_on_missing_creds("ingestionpolicy add to #{id} #{policy}")
136
+ assert_usage("ingestionpolicy add to #{policy}")
137
+ end
138
+
139
+ def test_remove_ingestionpolicy_remove
140
+ assert_repeated_output("Removed '#{policy}' from '#{id}'.") do
141
+ assert_cmd_posts("ingestionpolicy remove from #{id} #{policy}",
142
+ '/api/v2/account/removeingestionpolicies',
143
+ { ingestionPolicyId: policy,
144
+ accounts: [id] }.to_json)
145
+ end
146
+
147
+ assert_invalid_id("ingestionpolicy remove from #{invalid_id} #{policy}")
148
+ assert_invalid_id("ingestionpolicy remove from #{id} #{invalid_policy}")
149
+ assert_abort_on_missing_creds("ingestionpolicy remove from #{id} #{policy}")
150
+ assert_usage("ingestionpolicy remove from #{policy}")
151
+ end
152
+
153
+ def test_ingestionpolicy
154
+ assert_repeated_output("'#{id}' has no ingestion policy.") do
155
+ assert_cmd_gets("ingestionpolicy #{id}", "/api/v2/account/#{id}", [])
156
+ end
157
+
158
+ assert_abort_on_missing_creds("ingestionpolicy #{id}")
159
+ assert_invalid_id("ingestionpolicy #{invalid_id}")
160
+ assert_usage('ingestionpolicy')
161
+ end
162
+
163
+ def test_groups
164
+ assert_repeated_output("'#{id}' does not belong to any groups.") do
165
+ assert_cmd_gets("groups #{id}", "/api/v2/account/#{id}", [])
166
+ end
167
+
168
+ assert_invalid_id("groups #{invalid_id}")
169
+ assert_abort_on_missing_creds("groups #{id}")
170
+ assert_usage('groups')
171
+ end
172
+
173
+ def test_permissions
174
+ assert_repeated_output("'#{id}' does not have any permissions " \
175
+ 'directly attached.') do
176
+ assert_cmd_gets("permissions #{id}", "/api/v2/account/#{id}", [])
177
+ end
178
+
179
+ assert_abort_on_missing_creds("permissions #{id}")
180
+ assert_invalid_id("permissions #{invalid_id}")
181
+ assert_usage('permissions')
182
+ end
183
+
184
+ def test_invite_with_group
185
+ expected_body = [{ emailAddress: id,
186
+ userGroups: [groups.first],
187
+ groups: [] }].to_json
188
+
189
+ assert_repeated_output("Sent invitation to '#{id}'.") do
190
+ assert_cmd_posts("invite user -g #{groups.first} #{id}",
191
+ '/api/v2/account/user/invite',
192
+ expected_body)
193
+ end
194
+
195
+ assert_noop("invite user -g #{groups.first} #{id}",
196
+ 'uri: POST https://default.wavefront.com/api/v2/account/user' \
197
+ '/invite',
198
+ "body: #{expected_body}")
199
+ assert_invalid_id("invite user -g #{groups.first} #{invalid_id}")
200
+ assert_abort_on_missing_creds("invite user -g #{groups.first} #{id}")
201
+ assert_usage('invite user')
202
+ end
203
+
204
+ def test_invite_with_role_and_policy
205
+ expected_body = [{ emailAddress: id,
206
+ roles: roles,
207
+ ingestionPolicyId: policy,
208
+ groups: [] }].to_json
209
+
210
+ assert_repeated_output("Sent invitation to '#{id}'.") do
211
+ assert_cmd_posts(
212
+ "invite user -r #{roles.join(' -r ')} -i #{policy} #{id}",
213
+ '/api/v2/account/user/invite',
214
+ expected_body
215
+ )
216
+ end
217
+
218
+ assert_noop("invite user -r #{roles.join(' -r ')} -i #{policy} #{id}",
219
+ 'uri: POST https://default.wavefront.com/api/v2/account/user' \
220
+ '/invite',
221
+ "body: #{expected_body}")
222
+ assert_invalid_id("invite user -m #{permission} #{invalid_id}")
223
+ assert_abort_on_missing_creds("invite user -m #{permission} #{id}")
224
+ assert_usage('invite user')
225
+ end
226
+
227
+ def test_validate
228
+ cmd = "validate #{user_list.join(' ')}"
229
+
230
+ quietly do
231
+ assert_cmd_posts(cmd,
232
+ '/api/v2/account/validateAccounts',
233
+ user_list.to_json,
234
+ IO.read(RES_DIR + 'responses' + 'user-validate.json'))
235
+ end
236
+
237
+ assert_noop(cmd,
238
+ 'uri: POST https://default.wavefront.com/api/v2/account' \
239
+ '/validateAccounts',
240
+ "body: #{user_list.to_json}")
241
+ assert_abort_on_missing_creds(cmd)
242
+ assert_usage('validate')
243
+ end
244
+
245
+ private
246
+
247
+ def id
248
+ 'someone@example.com'
249
+ end
250
+
251
+ def invalid_id
252
+ 'bad' * 200
253
+ end
254
+
255
+ def cmd_word
256
+ 'account'
257
+ end
258
+
259
+ def groups
260
+ %w[2659191e-aad4-4302-a94e-9667e1517127
261
+ abcdef12-1234-abcd-1234-abcdef012345]
262
+ end
263
+
264
+ def invalid_group
265
+ '__bad_group__'
266
+ end
267
+
268
+ def roles
269
+ %w[87654321-aad4-4302-a94e-9667e1517127
270
+ 12345678-1234-abcd-1234-abcdef012345]
271
+ end
272
+
273
+ def invalid_role
274
+ '__bad_role__'
275
+ end
276
+
277
+ def list_response
278
+ { items: [{ identifier: 'user1@example.com' },
279
+ { identifier: 'user2@example.com' }] }.to_json
280
+ end
281
+
282
+ def permission
283
+ 'alerts_management'
284
+ end
285
+
286
+ def invalid_permission
287
+ 'made_up_permission'
288
+ end
289
+
290
+ def user_list
291
+ %w[someone@example.com
292
+ sa:testsysacct
293
+ no-such-thing]
294
+ end
295
+
296
+ def policy
297
+ 'test-policy-1579802191234'
298
+ end
299
+
300
+ def invalid_policy
301
+ '__some_nonsense_or_other__'
302
+ end
303
+ end
@@ -238,6 +238,34 @@ class AlertEndToEndTest < EndToEndTest
238
238
  assert_abort_on_missing_creds('currently in_maintenance')
239
239
  end
240
240
 
241
+ def test_affected_hosts_single
242
+ quietly do
243
+ assert_cmd_gets("affected hosts #{id}", "/api/v2/alert/#{id}")
244
+ end
245
+ assert_abort_on_missing_creds("affected hosts #{id}")
246
+ assert_invalid_id("affected hosts #{invalid_id}")
247
+
248
+ assert_noop(
249
+ "affected hosts #{id}",
250
+ "uri: GET https://default.wavefront.com/api/v2/alert/#{id}"
251
+ )
252
+ end
253
+
254
+ def test_affected_hosts_all
255
+ out, err = capture_io do
256
+ assert_raises(SystemExit) do
257
+ assert_cmd_posts('affected hosts',
258
+ '/api/v2/search/alert',
259
+ state_search('firing').to_json)
260
+ end
261
+ end
262
+
263
+ assert_empty(err)
264
+ assert_equal('No alerts are currently firing.', out.rstrip)
265
+ assert_cannot_noop('affected hosts')
266
+ assert_abort_on_missing_creds('affected hosts')
267
+ end
268
+
241
269
  private
242
270
 
243
271
  def id