wavefront-cli 6.1.0 → 7.1.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +34 -1
  3. data/HISTORY.md +17 -1
  4. data/README.md +2 -3
  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/commands/.rubocop.yml +34 -0
  9. data/lib/wavefront-cli/commands/account.rb +61 -0
  10. data/lib/wavefront-cli/commands/alert.rb +1 -0
  11. data/lib/wavefront-cli/commands/base.rb +1 -1
  12. data/lib/wavefront-cli/commands/query.rb +4 -1
  13. data/lib/wavefront-cli/commands/role.rb +44 -0
  14. data/lib/wavefront-cli/commands/spy.rb +0 -5
  15. data/lib/wavefront-cli/commands/usergroup.rb +7 -11
  16. data/lib/wavefront-cli/commands/write.rb +7 -2
  17. data/lib/wavefront-cli/controller.rb +5 -63
  18. data/lib/wavefront-cli/display/account.rb +122 -0
  19. data/lib/wavefront-cli/display/alert.rb +8 -0
  20. data/lib/wavefront-cli/display/base.rb +1 -1
  21. data/lib/wavefront-cli/display/cloudintegration.rb +3 -2
  22. data/lib/wavefront-cli/display/printer/long.rb +2 -1
  23. data/lib/wavefront-cli/display/role.rb +66 -0
  24. data/lib/wavefront-cli/display/settings.rb +1 -0
  25. data/lib/wavefront-cli/display/usergroup.rb +18 -14
  26. data/lib/wavefront-cli/exception_handler.rb +87 -0
  27. data/lib/wavefront-cli/output/hcl/base.rb +1 -1
  28. data/lib/wavefront-cli/query.rb +13 -7
  29. data/lib/wavefront-cli/role.rb +54 -0
  30. data/lib/wavefront-cli/serviceaccount.rb +0 -6
  31. data/lib/wavefront-cli/spy.rb +0 -8
  32. data/lib/wavefront-cli/usergroup.rb +8 -8
  33. data/lib/wavefront-cli/version.rb +1 -1
  34. data/lib/wavefront-cli/write.rb +28 -4
  35. data/spec/.rubocop.yml +34 -0
  36. data/spec/test_mixins/delete.rb +1 -2
  37. data/spec/wavefront-cli/account_spec.rb +303 -0
  38. data/spec/wavefront-cli/alert_spec.rb +28 -0
  39. data/spec/wavefront-cli/commands/write_spec.rb +1 -1
  40. data/spec/wavefront-cli/event_spec.rb +1 -1
  41. data/spec/wavefront-cli/output/csv/query_spec.rb +1 -1
  42. data/spec/wavefront-cli/output/wavefront/query_spec.rb +2 -2
  43. data/spec/wavefront-cli/query_spec.rb +20 -3
  44. data/spec/wavefront-cli/role_spec.rb +187 -0
  45. data/spec/wavefront-cli/serviceaccount_spec.rb +3 -3
  46. data/spec/wavefront-cli/usergroup_spec.rb +48 -43
  47. data/spec/wavefront-cli/write_spec.rb +44 -0
  48. data/wavefront-cli.gemspec +3 -3
  49. metadata +30 -27
  50. data/lib/wavefront-cli/commands/user.rb +0 -54
  51. data/lib/wavefront-cli/display/user.rb +0 -103
  52. data/lib/wavefront-cli/user.rb +0 -92
  53. data/spec/wavefront-cli/resources/responses/user-list.json +0 -1
  54. data/spec/wavefront-cli/user_spec.rb +0 -311
@@ -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
@@ -13,6 +13,6 @@ class WavefrontCommmandWriteTest < WavefrontCommmandBaseTest
13
13
  def setup
14
14
  @wf = WavefrontCommandWrite.new
15
15
  @col_width = 25
16
- @skip_cmd = /write (point|file|distribution)/
16
+ @skip_cmd = /write (point|file|distribution|noise)/
17
17
  end
18
18
  end
@@ -13,8 +13,8 @@ TEST_EVENT_DIR = Pathname.new('/tmp/wf_event_test')
13
13
  #
14
14
  class EventEndToEndTest < EndToEndTest
15
15
  attr_reader :test_state_dir
16
- include Wavefront::Mixins
17
16
 
17
+ include Wavefront::Mixins
18
18
  include WavefrontCliTest::Describe
19
19
  include WavefrontCliTest::Delete
20
20
  # Ones above work, ones below don't
@@ -161,7 +161,7 @@ class WavefrontOutputCsvTest < MiniTest::Test
161
161
  out.each do |l|
162
162
  c = l.split(',', 5)
163
163
  assert_equal(c[0], 'solaris.network.obytes64')
164
- assert_match(/^[\d\.]+$/, c[1])
164
+ assert_match(/^[\d.]+$/, c[1])
165
165
  # query returns epoch s timestamp, raw returns epoch ms
166
166
  assert_match(/^\d+$/, c[2])
167
167
  assert(c[2].size == 10 || c[2].size == 13)
@@ -61,13 +61,13 @@ class WavefrontOutputWavefrontTest < MiniTest::Test
61
61
  out.each do |l|
62
62
  c = l.split(' ', 5)
63
63
  assert_equal(c[0], 'solaris.network.obytes64')
64
- assert_match(/^[\d\.]+$/, c[1])
64
+ assert_match(/^[\d.]+$/, c[1])
65
65
  # query returns epoch s timestamp, raw returns epoch ms
66
66
  assert_match(/^\d+$/, c[2])
67
67
  assert(c[2].size == 10 || c[2].size == 13)
68
68
  assert_match(/^source=[-\w]+$/, c[3])
69
69
  assert_match(/^source=[-\w]+$/, c[3])
70
- c[4].split.each { |t| assert_match(/^\w+=\"[-\w]+\"$/, t) }
70
+ c[4].split.each { |t| assert_match(/^\w+="[-\w]+"$/, t) }
71
71
  end
72
72
  end
73
73
  end
@@ -27,9 +27,10 @@ class QueryEndToEndTest < EndToEndTest
27
27
  assert_noop(
28
28
  "-s #{epoch_time[0]} -k #{query}",
29
29
  'uri: GET https://default.wavefront.com/api/v2/chart/api',
30
- 'params: {:i=>false, :summarization=>"mean", :listMode=>true, ' \
31
- ':strict=>true, :sorted=>true, :q=>"ts(\"dev.cli.test\")", ' \
32
- ":g=>:m, :s=>#{epoch_time[0]}}"
30
+ 'params: {:autoEvents=>false, :i=>false, :summarization=>"mean", ' \
31
+ ':listMode=>true, :strict=>true, :includeObsoleteMetrics=>false, ' \
32
+ ':sorted=>true, :q=>"ts(\"dev.cli.test\")", :g=>:m, ' \
33
+ ":s=>#{epoch_time[0]}}"
33
34
  )
34
35
  end
35
36
 
@@ -92,6 +93,22 @@ class QueryEndToEndTest < EndToEndTest
92
93
  assert_match(/query\s+ts\("cpu.0.pc.user"\)/, out)
93
94
  end
94
95
 
96
+ def test_query_with_start_and_end_and_nostrict_and_nocache
97
+ out, err = capture_io do
98
+ assert_cmd_gets_with_params("-s #{epoch_time[0]} -CK #{query}",
99
+ '/api/v2/chart/api',
100
+ { q: query,
101
+ g: 'm',
102
+ i: 'false',
103
+ strict: 'false',
104
+ s: epoch_time[0].to_s,
105
+ cached: 'false' }, canned_response)
106
+ end
107
+
108
+ assert_empty(err)
109
+ assert_match(/query\s+ts\("cpu.0.pc.user"\)/, out)
110
+ end
111
+
95
112
  def test_query_with_start_and_end_and_name
96
113
  out, err = capture_io do
97
114
  assert_cmd_gets_with_params(
@@ -0,0 +1,187 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../support/command_base'
5
+ require_relative '../../lib/wavefront-cli/role'
6
+
7
+ # Ensure 'role' commands produce the correct API calls.
8
+ #
9
+ class RoleEndToEndTest < EndToEndTest
10
+ include WavefrontCliTest::List
11
+ include WavefrontCliTest::Describe
12
+ include WavefrontCliTest::Dump
13
+ include WavefrontCliTest::Search
14
+ include WavefrontCliTest::Delete
15
+ include WavefrontCliTest::Set
16
+
17
+ def test_create
18
+ quietly do
19
+ assert_cmd_posts("create #{role_name}",
20
+ '/api/v2/role',
21
+ name: role_name, permissions: [])
22
+ end
23
+
24
+ assert_abort_on_missing_creds("create #{role_name}")
25
+ assert_usage('create')
26
+ end
27
+
28
+ def test_create_with_permissions
29
+ quietly do
30
+ assert_cmd_posts("create -p #{permissions[0]} -p #{permissions[1]} " \
31
+ "#{role_name}",
32
+ '/api/v2/role',
33
+ name: role_name, permissions: permissions)
34
+ end
35
+ end
36
+
37
+ def test_create_with_permissions_and_description
38
+ quietly do
39
+ assert_cmd_posts("create -p #{permissions[0]} -p #{permissions[1]} " \
40
+ "-d description #{role_name}",
41
+ '/api/v2/role',
42
+ name: role_name,
43
+ permissions: permissions,
44
+ description: 'description')
45
+ end
46
+ end
47
+
48
+ def test_accounts
49
+ assert_repeated_output("No accounts have role '#{id}'.") do
50
+ assert_cmd_posts("accounts #{id}",
51
+ '/api/v2/search/account',
52
+ { limit: 999,
53
+ offset: 0,
54
+ query: [{ key: 'roles',
55
+ value: id,
56
+ matchingMethod: 'CONTAINS',
57
+ negated: false }],
58
+ sort: { field: 'id', ascending: true } })
59
+ end
60
+
61
+ assert_abort_on_missing_creds("accounts #{id}")
62
+ assert_invalid_id("accounts #{invalid_id}")
63
+ assert_usage('accounts')
64
+ end
65
+
66
+ def test_groups
67
+ assert_repeated_output("No groups have role '#{id}'.") do
68
+ assert_cmd_posts("groups #{id}",
69
+ '/api/v2/search/usergroup',
70
+ { limit: 999,
71
+ offset: 0,
72
+ query: [{ key: 'roles',
73
+ value: id,
74
+ matchingMethod: 'CONTAINS',
75
+ negated: false }],
76
+ sort: { field: 'id', ascending: true } })
77
+ end
78
+
79
+ assert_abort_on_missing_creds("groups #{id}")
80
+ assert_invalid_id("groups #{invalid_id}")
81
+ assert_usage('groups')
82
+ end
83
+
84
+ def test_permissions
85
+ assert_repeated_output("Role '#{id}' has no permissions.") do
86
+ assert_cmd_gets("permissions #{id}",
87
+ "/api/v2/role/#{id}",
88
+ { permissions: [] }.to_json)
89
+ end
90
+
91
+ out, err = capture_io do
92
+ assert_cmd_gets("permissions #{id}",
93
+ "/api/v2/role/#{id}",
94
+ { permissions: permissions }.to_json)
95
+ end
96
+
97
+ assert_equal(permissions.join("\n"), out.strip)
98
+ assert_empty err
99
+
100
+ assert_abort_on_missing_creds("permissions #{id}")
101
+ assert_invalid_id("permissions #{invalid_id}")
102
+ assert_usage('permissions')
103
+ end
104
+
105
+ def test_give_to
106
+ assert_repeated_output("Gave '#{id}' to '#{accounts.first}'.") do
107
+ assert_cmd_posts("give #{id} to #{accounts.first}",
108
+ "/api/v2/role/#{id}/addAssignees",
109
+ [accounts.first].to_json)
110
+ end
111
+
112
+ assert_abort_on_missing_creds("give #{id} to #{accounts.first}")
113
+ assert_invalid_id("give #{invalid_id} to #{accounts.first}")
114
+ end
115
+
116
+ def test_take_from
117
+ out, err = capture_io do
118
+ assert_cmd_posts("take #{id} from #{accounts.join(' ')}",
119
+ "/api/v2/role/#{id}/removeAssignees",
120
+ accounts.to_json)
121
+ end
122
+
123
+ assert_equal("Took '#{id}' from '#{accounts.first}', '#{accounts.last}'.",
124
+ out.strip.tr("\n", ' '))
125
+
126
+ assert_empty err
127
+
128
+ assert_abort_on_missing_creds("take #{id} from #{accounts.join(' ')}")
129
+ assert_invalid_id("take #{invalid_id} from #{accounts.join(' ')}")
130
+ end
131
+
132
+ def test_grant
133
+ assert_repeated_output(
134
+ "Granted '#{permissions.first}' permission to '#{id}'."
135
+ ) do
136
+ assert_cmd_posts("grant #{permissions.first} to #{id}",
137
+ "/api/v2/role/grant/#{permissions.first}",
138
+ [id].to_json)
139
+ end
140
+
141
+ assert_abort_on_missing_creds("grant #{permissions.first} to #{id}")
142
+ assert_invalid_id("grant #{permissions.first} to #{invalid_id}")
143
+ end
144
+
145
+ def test_revoke
146
+ assert_repeated_output(
147
+ "Revoked '#{permissions.last}' permission from '#{id}'."
148
+ ) do
149
+ assert_cmd_posts("revoke #{permissions.last} from #{id}",
150
+ "/api/v2/role/revoke/#{permissions.last}",
151
+ [id].to_json)
152
+ end
153
+
154
+ assert_abort_on_missing_creds("revoke #{permissions.last} from #{id}")
155
+ assert_invalid_id("revoke #{permissions.last} from #{invalid_id}")
156
+ end
157
+
158
+ private
159
+
160
+ def id
161
+ '2659191e-aad4-4302-a94e-9667e1517127'
162
+ end
163
+
164
+ def invalid_id
165
+ '__BAD__'
166
+ end
167
+
168
+ def cmd_word
169
+ 'role'
170
+ end
171
+
172
+ def role_name
173
+ 'test_role'
174
+ end
175
+
176
+ def permissions
177
+ %w[alerts_management events_management]
178
+ end
179
+
180
+ def accounts
181
+ %w[someone@example.com sa::testacct]
182
+ end
183
+
184
+ def set_key
185
+ 'description'
186
+ end
187
+ end
@@ -154,17 +154,17 @@ class ServiceAccountEndToEndTest < EndToEndTest
154
154
  end
155
155
 
156
156
  def test_create_invalid_usergroup
157
- assert_exits_with('Unable to run command. Invalid usergroup ID.',
157
+ assert_exits_with("'abcdefg' is not a valid user group ID.",
158
158
  "create -g abcdefg #{id}")
159
159
  end
160
160
 
161
161
  def test_create_invalid_permission
162
- assert_exits_with('Unable to run command. Invalid permission.',
162
+ assert_exits_with("'123456' is not a valid Wavefront permission.",
163
163
  "create -p 123456 #{id}")
164
164
  end
165
165
 
166
166
  def test_create_invalid_token
167
- assert_exits_with('Unable to run command. Invalid API token.',
167
+ assert_exits_with("'abcdefg' is not a valid API token ID.",
168
168
  "create -k abcdefg #{id}")
169
169
  end
170
170
 
@@ -18,19 +18,18 @@ class UserGroupEndToEndTest < EndToEndTest
18
18
  quietly do
19
19
  assert_cmd_posts("create #{groupname}",
20
20
  '/api/v2/usergroup',
21
- name: groupname, permissions: [])
21
+ name: groupname, roleIDs: [])
22
22
  end
23
23
 
24
24
  assert_abort_on_missing_creds("create #{groupname}")
25
25
  assert_usage('create')
26
26
  end
27
27
 
28
- def test_create_with_privileges
28
+ def test_create_with_roles
29
29
  quietly do
30
- assert_cmd_posts("create -p #{privileges[0]} -p #{privileges[1]} " \
31
- "#{groupname}",
30
+ assert_cmd_posts("create -r #{roles[0]} -r #{roles[1]} #{groupname}",
32
31
  '/api/v2/usergroup',
33
- name: groupname, permissions: privileges)
32
+ name: groupname, roleIDs: roles)
34
33
  end
35
34
  end
36
35
 
@@ -44,25 +43,15 @@ class UserGroupEndToEndTest < EndToEndTest
44
43
  assert_usage('users')
45
44
  end
46
45
 
47
- def test_permissions
48
- assert_repeated_output("Group '#{id}' has no permissions.") do
49
- assert_cmd_gets("permissions #{id}", "/api/v2/usergroup/#{id}")
50
- end
51
-
52
- assert_abort_on_missing_creds("permissions #{id}")
53
- assert_invalid_id("permissions #{invalid_id}")
54
- assert_usage('permissions')
55
- end
56
-
57
46
  def test_add_user
58
47
  assert_repeated_output("Added '#{users[0]}' to '#{id}'.") do
59
- assert_cmd_posts("add user #{id} #{users[0]}",
48
+ assert_cmd_posts("add to #{id} #{users[0]}",
60
49
  "/api/v2/usergroup/#{id}/addUsers",
61
50
  [users[0]].to_json)
62
51
  end
63
52
 
64
- assert_abort_on_missing_creds("add user #{id} #{users[0]}")
65
- assert_invalid_id("add user #{invalid_id} #{users[0]}")
53
+ assert_abort_on_missing_creds("add to #{id} #{users[0]}")
54
+ assert_invalid_id("add to #{invalid_id} #{users[0]}")
66
55
  end
67
56
 
68
57
  # assert_repeated_output can't cope with line wrapping, and suppressing it
@@ -70,7 +59,7 @@ class UserGroupEndToEndTest < EndToEndTest
70
59
  #
71
60
  def test_add_multiple_users
72
61
  quietly do
73
- assert_cmd_posts("add user #{id} #{users[0]} #{users[1]}",
62
+ assert_cmd_posts("add to #{id} #{users[0]} #{users[1]}",
74
63
  "/api/v2/usergroup/#{id}/addUsers",
75
64
  users.to_json)
76
65
  end
@@ -78,43 +67,58 @@ class UserGroupEndToEndTest < EndToEndTest
78
67
 
79
68
  def test_remove_user
80
69
  quietly do
81
- assert_cmd_posts("remove user #{id} #{users[0]}",
70
+ assert_cmd_posts("remove from #{id} #{users[0]}",
82
71
  "/api/v2/usergroup/#{id}/removeUsers",
83
72
  [users[0]].to_json)
84
73
  end
85
74
 
86
- assert_abort_on_missing_creds("remove user #{id} #{users[0]}")
87
- assert_invalid_id("remove user #{invalid_id} #{users[0]}")
75
+ assert_abort_on_missing_creds("remove from #{id} #{users[0]}")
76
+ assert_invalid_id("remove from #{invalid_id} #{users[0]}")
88
77
  end
89
78
 
90
79
  def test_remove_multiple_users
91
80
  quietly do
92
- assert_cmd_posts("remove user #{id} #{users[0]} #{users[1]}",
81
+ assert_cmd_posts("remove from #{id} #{users[0]} #{users[1]}",
93
82
  "/api/v2/usergroup/#{id}/removeUsers",
94
83
  users.to_json)
95
84
  end
96
85
  end
97
86
 
98
- def test_grant
99
- assert_repeated_output(
100
- "Granted '#{privileges[1]}' permission to '#{id}'."
101
- ) do
102
- assert_cmd_posts("grant #{privileges[1]} to #{id}",
103
- "/api/v2/usergroup/grant/#{privileges[1]}",
104
- [id].to_json)
87
+ def test_add_role
88
+ quietly do
89
+ assert_cmd_posts("add role #{id} #{roles[0]}",
90
+ "/api/v2/usergroup/#{id}/addRoles",
91
+ [roles[0]].to_json)
105
92
  end
106
93
 
107
- assert_abort_on_missing_creds("grant #{privileges[1]} to #{id}")
108
- assert_invalid_id("grant #{privileges[1]} to #{invalid_id}")
94
+ assert_abort_on_missing_creds("add role #{id} #{roles[0]}")
95
+ assert_invalid_id("add role #{invalid_id} #{roles[0]}")
109
96
  end
110
97
 
111
- def test_revoke
112
- assert_repeated_output(
113
- "Revoked '#{privileges[0]}' permission from '#{id}'."
114
- ) do
115
- assert_cmd_posts("revoke #{privileges[0]} from #{id}",
116
- "/api/v2/usergroup/revoke/#{privileges[0]}",
117
- [id].to_json)
98
+ def test_add_multiple_roles
99
+ quietly do
100
+ assert_cmd_posts("add role #{id} #{roles[0]} #{roles[1]}",
101
+ "/api/v2/usergroup/#{id}/addRoles",
102
+ roles.to_json)
103
+ end
104
+ end
105
+
106
+ def test_remove_role
107
+ quietly do
108
+ assert_cmd_posts("remove role #{id} #{roles[0]}",
109
+ "/api/v2/usergroup/#{id}/removeRoles",
110
+ [roles[0]].to_json)
111
+ end
112
+
113
+ assert_abort_on_missing_creds("remove role #{id} #{roles[0]}")
114
+ assert_invalid_id("remove role #{invalid_id} #{roles[0]}")
115
+ end
116
+
117
+ def test_remove_multiple_roles
118
+ quietly do
119
+ assert_cmd_posts("remove role #{id} #{roles[0]} #{roles[1]}",
120
+ "/api/v2/usergroup/#{id}/removeRoles",
121
+ roles.to_json)
118
122
  end
119
123
  end
120
124
 
@@ -144,11 +148,12 @@ class UserGroupEndToEndTest < EndToEndTest
144
148
  'testgroup'
145
149
  end
146
150
 
147
- def privileges
148
- %w[alerts_management events_management]
149
- end
150
-
151
151
  def users
152
152
  %w[someone@somewhere.com other@elsewhere.com]
153
153
  end
154
+
155
+ def roles
156
+ %w[01234567-aad4-4302-a94e-9667e1517127
157
+ abcdefab-abcd-4302-a94e-9667e1517127]
158
+ end
154
159
  end