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
@@ -7,6 +7,16 @@ module WavefrontDisplay
7
7
  # Format human-readable output for proxies.
8
8
  #
9
9
  class Proxy < Base
10
+ def do_list
11
+ filter_inactive_proxies! if options[:active]
12
+ super
13
+ end
14
+
15
+ def do_list_brief
16
+ filter_inactive_proxies! if options[:active]
17
+ super
18
+ end
19
+
10
20
  def do_describe
11
21
  readable_time(:lastCheckInTime)
12
22
  long_output
@@ -15,5 +25,11 @@ module WavefrontDisplay
15
25
  def do_versions
16
26
  multicolumn(:id, :version, :name)
17
27
  end
28
+
29
+ private
30
+
31
+ def filter_inactive_proxies!
32
+ data.delete_if { |p| p[:status] != 'ACTIVE' }
33
+ end
18
34
  end
19
35
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module WavefrontDisplay
6
+ #
7
+ # Format human-readable output for role command
8
+ #
9
+ class Role < Base
10
+ def do_list_brief
11
+ data.map! do |d|
12
+ d.merge(acct_count: "#{d[:linkedAccountsCount]} accounts",
13
+ group_count: "#{d[:linkedGroupsCount]} groups")
14
+ end
15
+ multicolumn(:id, :name, :acct_count, :group_count)
16
+ end
17
+
18
+ def do_accounts
19
+ if data.empty?
20
+ puts "No accounts have role '#{options[:'<id>']}'."
21
+ else
22
+ multicolumn(:identifier)
23
+ end
24
+ end
25
+
26
+ def do_groups
27
+ if data.empty?
28
+ puts "No groups have role '#{options[:'<id>']}'."
29
+ else
30
+ multicolumn(:id, :name)
31
+ end
32
+ end
33
+
34
+ def do_permissions
35
+ if data[:permissions].empty?
36
+ puts "Role '#{options[:'<id>']}' has no permissions."
37
+ else
38
+ puts data[:permissions]
39
+ end
40
+ end
41
+
42
+ def do_grant
43
+ puts format("Granted '%<perm>s' permission to '%<id>s'.",
44
+ perm: options[:'<permission>'],
45
+ id: options[:'<id>'])
46
+ end
47
+
48
+ def do_revoke
49
+ puts format("Revoked '%<perm>s' permission from '%<id>s'.",
50
+ perm: options[:'<permission>'],
51
+ id: options[:'<id>'])
52
+ end
53
+
54
+ def do_give_to
55
+ puts format("Gave '%<role>s' to %<members>s.",
56
+ members: quoted(options[:'<member>']),
57
+ role: options[:'<id>']).fold(TW, 0)
58
+ end
59
+
60
+ def do_take_from
61
+ puts format("Took '%<role>s' from %<members>s.",
62
+ members: quoted(options[:'<member>']),
63
+ role: options[:'<id>']).fold(TW, 0)
64
+ end
65
+ end
66
+ end
@@ -8,6 +8,7 @@ module WavefrontDisplay
8
8
  #
9
9
  class Settings < Base
10
10
  def do_list_permissions
11
+ data.sort_by! { |p| p[:groupName] }
11
12
  options[:long] ? long_output : multicolumn(:groupName)
12
13
  end
13
14
 
@@ -15,28 +15,28 @@ module WavefrontDisplay
15
15
  puts "Deleted user group '#{options[:'<id>']}'."
16
16
  end
17
17
 
18
- def do_add_user
18
+ def do_add_to
19
19
  puts format("Added %<quoted_user>s to '%<group_id>s'.",
20
20
  quoted_user: quoted(options[:'<user>']),
21
21
  group_id: options[:'<id>']).fold(TW, 0)
22
22
  end
23
23
 
24
- def do_remove_user
24
+ def do_remove_from
25
25
  puts format("Removed %<quoted_user>s from '%<group_id>s'.",
26
26
  quoted_user: quoted(options[:'<user>']),
27
27
  group_id: options[:'<id>']).fold(TW, 0)
28
28
  end
29
29
 
30
- def do_grant
31
- puts format("Granted '%<perm>s' permission to '%<group_id>s'.",
32
- perm: options[:'<permission>'],
33
- group_id: options[:'<id>'])
30
+ def do_add_role
31
+ puts format("Added %<quoted_role>s to '%<group_id>s'.",
32
+ quoted_role: quoted(options[:'<role>']),
33
+ group_id: options[:'<id>']).fold(TW, 0)
34
34
  end
35
35
 
36
- def do_revoke
37
- puts format("Revoked '%<perm>s' permission from '%<group_id>s'.",
38
- perm: options[:'<permission>'],
39
- group_id: options[:'<id>'])
36
+ def do_remove_role
37
+ puts format("Removed %<quoted_role>s from '%<group_id>s'.",
38
+ quoted_role: quoted(options[:'<role>']),
39
+ group_id: options[:'<id>']).fold(TW, 0)
40
40
  end
41
41
 
42
42
  def do_users
@@ -47,12 +47,16 @@ module WavefrontDisplay
47
47
  end)
48
48
  end
49
49
 
50
- def do_permissions
51
- puts(if !data.include?(:permissions) || data[:permissions].empty?
52
- "Group '#{options[:'<id>']}' has no permissions."
50
+ def do_roles
51
+ puts(if !data.include?(:roles) || data[:roles].empty?
52
+ "Group '#{options[:'<id>']}' has no roles attached."
53
53
  else
54
- data[:permissions]
54
+ data[:roles].map { |r| r[:id] }
55
55
  end)
56
56
  end
57
+
58
+ def do_permissions
59
+ puts data[:roles].map { |r| r[:permissions] }.flatten.sort.uniq
60
+ end
57
61
  end
58
62
  end
@@ -0,0 +1,89 @@
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::InvalidAwsExternalId
35
+ abort "'#{exception}' is not a valid AWS external ID."
36
+ when Wavefront::Exception::InvalidRoleId
37
+ abort "'#{exception}' is not a valid role ID."
38
+ when Wavefront::Exception::InvalidApiTokenId
39
+ abort "'#{exception}' is not a valid API token ID."
40
+ when Wavefront::Exception::InvalidIngestionPolicyId
41
+ abort "'#{exception}' is not a valid ingestion policy ID."
42
+ when WavefrontCli::Exception::InvalidValue
43
+ abort "Invalid value for #{exception}."
44
+ when WavefrontCli::Exception::ProfileExists
45
+ abort "Profile '#{exception}' already exists."
46
+ when WavefrontCli::Exception::ProfileNotFound
47
+ abort "Profile '#{exception}' not found."
48
+ when WavefrontCli::Exception::FileNotFound
49
+ abort 'File not found.'
50
+ when WavefrontCli::Exception::InsufficientData
51
+ abort "Insufficient data. #{exception.message}"
52
+ when WavefrontCli::Exception::InvalidQuery
53
+ abort "Invalid query. API message: '#{exception.message}'."
54
+ when WavefrontCli::Exception::SystemError
55
+ abort "Host system error. #{exception.message}"
56
+ when WavefrontCli::Exception::UnparseableInput
57
+ abort "Cannot parse input. #{exception.message}"
58
+ when WavefrontCli::Exception::UnparseableSearchPattern
59
+ abort 'Searches require a key, a value, and a match operator.'
60
+ when WavefrontCli::Exception::UnsupportedFileFormat
61
+ abort 'Unsupported file format.'
62
+ when WavefrontCli::Exception::UnsupportedOperation
63
+ abort "Unsupported operation.\n#{exception.message}"
64
+ when WavefrontCli::Exception::UnsupportedOutput
65
+ abort exception.message
66
+ when WavefrontCli::Exception::UnsupportedNoop
67
+ abort 'Multiple API call operations cannot be performed as no-ops.'
68
+ when WavefrontCli::Exception::UserGroupNotFound
69
+ abort "Cannot find user group '#{exception.message}'."
70
+ when Wavefront::Exception::UnsupportedWriter
71
+ abort "Unsupported writer '#{exception.message}'."
72
+ when WavefrontCli::Exception::UserError
73
+ abort "User error: #{exception.message}."
74
+ when WavefrontCli::Exception::ImpossibleSearch
75
+ abort 'Search on non-existent key. Please use a top-level field.'
76
+ when Wavefront::Exception::InvalidSamplingValue
77
+ abort 'Sampling rates must be between 0 and 0.05.'
78
+ else
79
+ warn "general error: #{exception}"
80
+ backtrace_message(exception)
81
+ abort
82
+ end
83
+ end
84
+ # rubocop:enable Metrics/MethodLength
85
+ # rubocop:enable Metrics/AbcSize
86
+ # rubocop:enable Metrics/PerceivedComplexity
87
+ # rubocop:enable Metrics/CyclomaticComplexity
88
+ end
89
+ 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
@@ -91,7 +91,7 @@ module WavefrontHclOutput
91
91
  end
92
92
 
93
93
  def quote_value(val)
94
- val.gsub!(/\$/, '$$') if v.is_a?(String)
94
+ val.gsub!(/\$/, '$$') if val.is_a?(String)
95
95
  super
96
96
  end
97
97
  end
@@ -7,6 +7,11 @@ module WavefrontCli
7
7
  # CLI coverage for the v2 'proxy' API.
8
8
  #
9
9
  class Proxy < WavefrontCli::Base
10
+ def do_list
11
+ options[:all] = true if options[:active]
12
+ super
13
+ end
14
+
10
15
  def no_api_response
11
16
  %w[do_versions]
12
17
  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)