wavefront-cli 5.1.1 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
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)