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
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WavefrontCli
4
+ #
5
+ # Handle fatal errors.
6
+ #
7
+ module ExceptionMixins
8
+ # rubocop:disable Metrics/MethodLength
9
+ # rubocop:disable Metrics/AbcSize
10
+ # rubocop:disable Metrics/CyclomaticComplexity
11
+ # rubocop:disable Metrics/PerceivedComplexity
12
+ def exception_handler(exception)
13
+ case exception
14
+ when WavefrontCli::Exception::UnhandledCommand
15
+ abort 'Fatal error. Unsupported command. Please open a Github issue.'
16
+ when WavefrontCli::Exception::InvalidInput
17
+ abort "Invalid input. #{exception.message}"
18
+ when Interrupt
19
+ abort "\nOperation aborted at user request."
20
+ when WavefrontCli::Exception::ConfigFileNotFound
21
+ abort "Configuration file #{exception}' not found."
22
+ when WavefrontCli::Exception::CredentialError
23
+ handle_missing_credentials(exception)
24
+ when WavefrontCli::Exception::MandatoryValue
25
+ abort 'A value must be supplied.'
26
+ when Wavefront::Exception::NetworkTimeout
27
+ abort 'Connection timed out.'
28
+ when Wavefront::Exception::InvalidPermission
29
+ abort "'#{exception}' is not a valid Wavefront permission."
30
+ when Wavefront::Exception::InvalidUserGroupId
31
+ abort "'#{exception}' is not a valid user group ID."
32
+ when Wavefront::Exception::InvalidAccountId
33
+ abort "'#{exception}' is not a valid system or user account ID."
34
+ when Wavefront::Exception::InvalidRoleId
35
+ abort "'#{exception}' is not a valid role ID."
36
+ when Wavefront::Exception::InvalidApiTokenId
37
+ abort "'#{exception}' is not a valid API token ID."
38
+ when Wavefront::Exception::InvalidIngestionPolicyId
39
+ abort "'#{exception}' is not a valid ingestion policy ID."
40
+ when WavefrontCli::Exception::InvalidValue
41
+ abort "Invalid value for #{exception}."
42
+ when WavefrontCli::Exception::ProfileExists
43
+ abort "Profile '#{exception}' already exists."
44
+ when WavefrontCli::Exception::ProfileNotFound
45
+ abort "Profile '#{exception}' not found."
46
+ when WavefrontCli::Exception::FileNotFound
47
+ abort 'File not found.'
48
+ when WavefrontCli::Exception::InsufficientData
49
+ abort "Insufficient data. #{exception.message}"
50
+ when WavefrontCli::Exception::InvalidQuery
51
+ abort "Invalid query. API message: '#{exception.message}'."
52
+ when WavefrontCli::Exception::SystemError
53
+ abort "Host system error. #{exception.message}"
54
+ when WavefrontCli::Exception::UnparseableInput
55
+ abort "Cannot parse input. #{exception.message}"
56
+ when WavefrontCli::Exception::UnparseableSearchPattern
57
+ abort 'Searches require a key, a value, and a match operator.'
58
+ when WavefrontCli::Exception::UnsupportedFileFormat
59
+ abort 'Unsupported file format.'
60
+ when WavefrontCli::Exception::UnsupportedOperation
61
+ abort "Unsupported operation.\n#{exception.message}"
62
+ when WavefrontCli::Exception::UnsupportedOutput
63
+ abort exception.message
64
+ when WavefrontCli::Exception::UnsupportedNoop
65
+ abort 'Multiple API call operations cannot be performed as no-ops.'
66
+ when WavefrontCli::Exception::UserGroupNotFound
67
+ abort "Cannot find user group '#{exception.message}'."
68
+ when Wavefront::Exception::UnsupportedWriter
69
+ abort "Unsupported writer '#{exception.message}'."
70
+ when WavefrontCli::Exception::UserError
71
+ abort "User error: #{exception.message}."
72
+ when WavefrontCli::Exception::ImpossibleSearch
73
+ abort 'Search on non-existent key. Please use a top-level field.'
74
+ when Wavefront::Exception::InvalidSamplingValue
75
+ abort 'Sampling rates must be between 0 and 0.05.'
76
+ else
77
+ warn "general error: #{exception}"
78
+ backtrace_message(exception)
79
+ abort
80
+ end
81
+ end
82
+ # rubocop:enable Metrics/MethodLength
83
+ # rubocop:enable Metrics/AbcSize
84
+ # rubocop:enable Metrics/PerceivedComplexity
85
+ # rubocop:enable Metrics/CyclomaticComplexity
86
+ end
87
+ end
@@ -92,7 +92,7 @@ module WavefrontHclOutput
92
92
  def quote_value(val)
93
93
  case val.class.to_s.to_sym
94
94
  when :String
95
- format('"%<value>s"', value: val.gsub(/\"/, '\"'))
95
+ format('"%<value>s"', value: val.gsub(/"/, '\"'))
96
96
  else
97
97
  val
98
98
  end
@@ -51,20 +51,26 @@ module WavefrontCli
51
51
 
52
52
  # @return [Hash] options for the SDK query method
53
53
  #
54
- # rubocop:disable Metrics/AbcSize
55
54
  def q_opts
55
+ basic_q_opts.tap do |o|
56
+ o[:n] = options[:name]
57
+ o[:p] = options[:points]
58
+ o[:view] = 'HISTOGRAM' if options[:histogramview]
59
+ o[:cached] = false if options[:nocache]
60
+ end.compact
61
+ end
62
+
63
+ # Every query gets these options. They're modified by q_opts
64
+ #
65
+ def basic_q_opts
56
66
  { autoEvents: options[:events],
57
67
  i: options[:inclusive],
58
68
  summarization: options[:summarize] || 'mean',
59
69
  listMode: true,
60
- strict: true,
70
+ strict: !options[:nostrict],
61
71
  includeObsoleteMetrics: options[:obsolete],
62
- sorted: true }.tap do |o|
63
- o[:n] = options[:name] if options[:name]
64
- o[:p] = options[:points] if options[:points]
65
- end
72
+ sorted: true }
66
73
  end
67
- # rubocop:enable Metrics/AbcSize
68
74
 
69
75
  # @return [Integer] start of query window. If one has been
70
76
  # given, that; if not, ten minutes ago
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module WavefrontCli
6
+ #
7
+ # CLI coverage for the v2 'role' API.
8
+ #
9
+ class Role < WavefrontCli::Base
10
+ alias do_permissions do_describe
11
+
12
+ def do_create
13
+ wf.create({ name: options[:'<name>'],
14
+ description: options[:description],
15
+ permissions: options[:permission] }.compact)
16
+ end
17
+
18
+ def do_accounts
19
+ things_with_role(:account, options[:'<id>'])
20
+ end
21
+
22
+ def do_groups
23
+ things_with_role(:usergroup, options[:'<id>'])
24
+ end
25
+
26
+ def do_give_to
27
+ wf.add_assignees(options[:'<id>'], options[:'<member>'])
28
+ end
29
+
30
+ def do_take_from
31
+ wf.remove_assignees(options[:'<id>'], options[:'<member>'])
32
+ end
33
+
34
+ def do_grant
35
+ wf.grant(options[:'<permission>'], Array(options[:'<id>']))
36
+ end
37
+
38
+ def do_revoke
39
+ wf.revoke(options[:'<permission>'], Array(options[:'<id>']))
40
+ end
41
+
42
+ private
43
+
44
+ # Search for objects of the given type with the given role
45
+ #
46
+ def things_with_role(thing, role)
47
+ require 'wavefront-sdk/search'
48
+ wfs = Wavefront::Search.new(mk_creds, mk_opts)
49
+ wfs.search(thing,
50
+ conds_to_query(["roles~#{role}"]),
51
+ limit: :all, sort_field: :id)
52
+ end
53
+ end
54
+ end
@@ -173,20 +173,14 @@ module WavefrontCli
173
173
 
174
174
  def validate_groups
175
175
  options[:group].each { |g| wf_usergroup_id?(g) }
176
- rescue Wavefront::Exception::InvalidUserGroupId => e
177
- raise e, 'Invalid usergroup ID'
178
176
  end
179
177
 
180
178
  def validate_tokens
181
179
  options[:usertoken].each { |t| wf_apitoken_id?(t) }
182
- rescue Wavefront::Exception::InvalidApiTokenId => e
183
- raise e, 'Invalid API token'
184
180
  end
185
181
 
186
182
  def validate_perms
187
183
  options[:permission].each { |p| wf_permission?(p) }
188
- rescue Wavefront::Exception::InvalidPermission => e
189
- raise e, 'Invalid permission'
190
184
  end
191
185
 
192
186
  def descriptive_name
@@ -42,14 +42,6 @@ module WavefrontCli
42
42
 
43
43
  private
44
44
 
45
- def require_sdk_class
46
- require 'wavefront-sdk/unstable/spy'
47
- end
48
-
49
- def _sdk_class
50
- 'Wavefront::Unstable::Spy'
51
- end
52
-
53
45
  def rate
54
46
  return 0.01 unless options[:rate]
55
47
 
@@ -12,27 +12,27 @@ module WavefrontCli
12
12
  end
13
13
 
14
14
  alias do_users do_describe
15
+ alias do_roles do_describe
15
16
  alias do_permissions do_describe
16
17
 
17
18
  def do_create
18
- wf.create(name: options[:'<name>'],
19
- permissions: options[:permission])
19
+ wf.create(name: options[:'<name>'], roleIDs: options[:roleid])
20
20
  end
21
21
 
22
- def do_add_user
22
+ def do_add_to
23
23
  wf.add_users_to_group(options[:'<id>'], options[:'<user>'])
24
24
  end
25
25
 
26
- def do_remove_user
26
+ def do_remove_from
27
27
  wf.remove_users_from_group(options[:'<id>'], options[:'<user>'])
28
28
  end
29
29
 
30
- def do_grant
31
- wf.grant(options[:'<permission>'], Array(options[:'<id>']))
30
+ def do_add_role
31
+ wf.add_roles_to_group(options[:'<id>'], options[:'<role>'])
32
32
  end
33
33
 
34
- def do_revoke
35
- wf.revoke(options[:'<permission>'], Array(options[:'<id>']))
34
+ def do_remove_role
35
+ wf.remove_roles_from_group(options[:'<id>'], options[:'<role>'])
36
36
  end
37
37
 
38
38
  def import_to_create(raw)
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- WF_CLI_VERSION = '6.1.0'
3
+ WF_CLI_VERSION = '7.1.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>'],
@@ -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