wavefront-cli 5.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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +37 -1
  3. data/HISTORY.md +29 -0
  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 +13 -121
  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/proxy.rb +2 -1
  13. data/lib/wavefront-cli/commands/query.rb +4 -1
  14. data/lib/wavefront-cli/commands/role.rb +44 -0
  15. data/lib/wavefront-cli/commands/spy.rb +0 -5
  16. data/lib/wavefront-cli/commands/usergroup.rb +7 -11
  17. data/lib/wavefront-cli/commands/write.rb +7 -2
  18. data/lib/wavefront-cli/controller.rb +5 -63
  19. data/lib/wavefront-cli/display/account.rb +122 -0
  20. data/lib/wavefront-cli/display/alert.rb +8 -0
  21. data/lib/wavefront-cli/display/base.rb +1 -1
  22. data/lib/wavefront-cli/display/cloudintegration.rb +3 -2
  23. data/lib/wavefront-cli/display/printer/long.rb +2 -1
  24. data/lib/wavefront-cli/display/proxy.rb +16 -0
  25. data/lib/wavefront-cli/display/role.rb +66 -0
  26. data/lib/wavefront-cli/display/settings.rb +1 -0
  27. data/lib/wavefront-cli/display/usergroup.rb +18 -14
  28. data/lib/wavefront-cli/exception_handler.rb +87 -0
  29. data/lib/wavefront-cli/helpers/load_file.rb +80 -0
  30. data/lib/wavefront-cli/output/hcl/base.rb +1 -1
  31. data/lib/wavefront-cli/output/hcl/dashboard.rb +1 -1
  32. data/lib/wavefront-cli/proxy.rb +5 -0
  33. data/lib/wavefront-cli/query.rb +13 -7
  34. data/lib/wavefront-cli/role.rb +54 -0
  35. data/lib/wavefront-cli/serviceaccount.rb +0 -6
  36. data/lib/wavefront-cli/spy.rb +0 -8
  37. data/lib/wavefront-cli/subcommands/import.rb +78 -0
  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/test_mixins/import.rb +9 -3
  44. data/spec/wavefront-cli/account_spec.rb +303 -0
  45. data/spec/wavefront-cli/alert_spec.rb +28 -0
  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 +32 -32
  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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2500c3c1046355e74eaa41f1e612a2f05054ffc54f752f79cac8f4c8f47dfd07
4
- data.tar.gz: 9676df59ed6592399703de971ea8b2f691fe09443c74147d60096b3789d83ae5
3
+ metadata.gz: b1e0ee9608157074b898b31b5c169f432e4feed2d4af31e184b80016675f73cc
4
+ data.tar.gz: 4e845f4a56684903f2f1d800ee41cad9a8062a969a8fcb31e839bd51fac3891c
5
5
  SHA512:
6
- metadata.gz: 441cf573c9c17603679bd39d3b1f9d0dcf15ca0fc68f8f0b72fa2969fc9384931d9b549e54b0659e5103f0f09f04d50b45987758ddcd54115ceb450bda832366
7
- data.tar.gz: d4236668320cc4167100784cc7c265c22a5d6bddf5e1a44da54c4b20c8b657e782582046551989800b0c4548f611c06aa900f5eb5ed3daaa46e1472d62f0f35a
6
+ metadata.gz: 4635ae95d16aeb2bcb779010fc435945300991f1853ba75488a9e2914b6860129be4257ca13d5765c004efb746ce5f03fa7d686f71bb13ec5fe860f77c4cddbe
7
+ data.tar.gz: 501b3425f488c977363b42ec9d362d3e0c56ef8ba0b7cc91a2feb1da8bb2b91d2a1c27ade8cf8d3e5c01f3bde74cf0a582ead9c84f4dc4f0ae6e71c1a3691cc9
@@ -1,14 +1,50 @@
1
1
  ---
2
2
 
3
3
  AllCops:
4
- TargetRubyVersion: 2.3
4
+ TargetRubyVersion: 2.4
5
5
 
6
6
  Metrics/ClassLength:
7
7
  Max: 400
8
8
 
9
+ Style/IfUnlessModifier:
10
+ Enabled: false # because it wants to make lines >80 chars
9
11
  Style/HashEachMethods:
10
12
  Enabled: true
11
13
  Style/HashTransformKeys:
12
14
  Enabled: true
13
15
  Style/HashTransformValues:
14
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
data/HISTORY.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 7.1.0 (2020-08-07)
4
+ * Remove `user` command. (Breaking change.)
5
+ * Add `account` command.
6
+ * Complete coverage of roles and user groups.
7
+ * Add `alert affected hosts` command to show which hosts are affected by one
8
+ or all firing alerts.
9
+ * Remove obsolete `group` subcommands. (`grant` and `revoke`).
10
+ * Add `write noise` command to send a flow of random data to an endpoint.
11
+ * Better information when working with cloud integrations.
12
+
13
+ ## 7.0.0 (unreleased)
14
+
15
+ ## 6.1.0 (2020-06-02)
16
+ * Add `-A` flag to `proxy list` command, to only list active proxies
17
+
18
+ ## 6.0.0 (2020-04-07)
19
+ * Remove `cluster` command. (Breaking change.)
20
+ * Add `role` command.
21
+ * Add `--nocache`, `--nostrict` and `--histogram-view` options to `query`
22
+ command.
23
+ * Require 5.x of [the SDK](https://github.com/snltd/wavefront-sdk).
24
+
25
+ ## 5.1.2 (2020-02-28)
26
+ * Fix regression in HCL dashboard export.
27
+ * Properly handle unavailable port when sending distributions to a proxy.
28
+
29
+ ## 5.1.1 (2020-02-20)
30
+ * Say whether `--upsert` did an update or an import.
31
+
3
32
  ## 5.1.0 (2020-02-20)
4
33
  * Add `-U` (`--upsert`) option to `import` sub-commands.
5
34
 
data/README.md CHANGED
@@ -33,7 +33,6 @@ Commands:
33
33
  alert view and manage alerts
34
34
  apitoken view and your own API tokens
35
35
  cloudintegration view and manage cloud integrations
36
- cluster view and manage monitored clusters
37
36
  config create and manage local configuration
38
37
  dashboard view and manage dashboards
39
38
  derivedmetric view and manage derived metrics
@@ -52,7 +51,6 @@ Commands:
52
51
  source view and manage source tags and descriptions
53
52
  spy monitor traffic going into Wavefront
54
53
  usage view and manage usage reports
55
- user view and manage Wavefront users
56
54
  usergroup view and manage Wavefront user groups
57
55
  webhook view and manage webhooks
58
56
  window view and manage maintenance windows
@@ -104,7 +102,7 @@ $ wf proxy list
104
102
 
105
103
  You can get more verbose listings with the `-l` flag. Results may be
106
104
  paginated. You can progress through pages with the `-L` and `-o`
107
- options, or user `--all` to get everything in one go.
105
+ options, or use `--all` to get everything in one go.
108
106
 
109
107
  ### Describing Things
110
108
 
@@ -152,7 +150,7 @@ mentioned above, human-readable listings and desctiptions may omit
152
150
  data which is not likely to be useful, or which is extremely hard to
153
151
  present in a readable way.
154
152
 
155
- If you `describe` an object like a dashboard, user, webhook etc as
153
+ If you `describe` an object like a dashboard, account, webhook etc as
156
154
  `json` or `yaml`, and send the output to a file, you can re-import
157
155
  that data. The format of the file to be imported is automatically
158
156
  detected.
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module WavefrontCli
6
+ #
7
+ # CLI coverage for the v2 'account' API.
8
+ #
9
+ class Account < WavefrontCli::Base
10
+ alias do_roles do_describe
11
+ alias do_groups do_describe
12
+ alias do_ingestionpolicy do_describe
13
+ alias do_permissions do_describe
14
+
15
+ def do_role_add_to
16
+ wf_account_id?(options[:'<id>'])
17
+ wf.add_roles(options[:'<id>'], options[:'<role>'])
18
+ end
19
+
20
+ def do_role_remove_from
21
+ wf_account_id?(options[:'<id>'])
22
+ wf.remove_roles(options[:'<id>'], options[:'<role>'])
23
+ end
24
+
25
+ def do_group_add_to
26
+ wf_account_id?(options[:'<id>'])
27
+ wf.add_user_groups(options[:'<id>'], options[:'<group>'])
28
+ end
29
+
30
+ def do_group_remove_from
31
+ wf_account_id?(options[:'<id>'])
32
+ wf.remove_user_groups(options[:'<id>'], options[:'<group>'])
33
+ end
34
+
35
+ def do_business_functions
36
+ wf_user_id?(options[:'<id>'])
37
+ wf.business_functions(options[:'<id>'])
38
+ end
39
+
40
+ def do_grant_to
41
+ wf.grant(options[:'<account>'], options[:'<permission>'])
42
+ end
43
+
44
+ def do_revoke_from
45
+ wf.revoke(options[:'<account>'], options[:'<permission>'])
46
+ end
47
+
48
+ def do_ingestionpolicy_add_to
49
+ wf_account_id?(options[:'<id>'])
50
+ wf.add_ingestion_policy(options[:'<policy>'], [options[:'<id>']])
51
+ end
52
+
53
+ def do_ingestionpolicy_remove_from
54
+ wf_account_id?(options[:'<id>'])
55
+ wf_ingestionpolicy_id?(options[:'<policy>'])
56
+ wf.remove_ingestion_policy(options[:'<policy>'], [options[:'<id>']])
57
+ end
58
+
59
+ def do_create_user
60
+ wf_user_id?(options[:'<id>'])
61
+ wf.user_create(user_body)
62
+ end
63
+
64
+ def do_invite_user
65
+ wf_user_id?(options[:'<id>'])
66
+ wf.user_invite([user_body])
67
+ end
68
+
69
+ def do_validate
70
+ wf.validate_accounts(options[:'<account>'])
71
+ end
72
+
73
+ def extra_validation
74
+ validate_policy
75
+ validate_permission
76
+ validate_roles
77
+ validate_groups
78
+ validate_accounts
79
+ end
80
+
81
+ private
82
+
83
+ def validate_policy
84
+ wf_ingestionpolicy_id?(options[:'<policy>']) if options[:'<policy>']
85
+ end
86
+
87
+ def validate_permission
88
+ wf_permission?(options[:'<permission>']) if options[:'<permission>']
89
+ end
90
+
91
+ def validate_roles
92
+ options[:'<role>'].each { |r| wf_role_id?(r) }
93
+ end
94
+
95
+ def validate_groups
96
+ options[:'<group>'].each { |g| wf_usergroup_id?(g) }
97
+ end
98
+
99
+ def validate_accounts
100
+ options[:'<account>'].each { |a| wf_account_id?(a) }
101
+ end
102
+
103
+ # Object used to create and invite users. We deal with the permissions
104
+ # seperately because if we don't supply any and they get compacted out,
105
+ # the user is created with a default set of perms, and we don't want that.
106
+ #
107
+ def user_body
108
+ raw = {
109
+ emailAddress: options[:'<id>'],
110
+ roles: options[:roleid],
111
+ ingestionPolicyId: options[:policyid],
112
+ userGroups: options[:groupid]
113
+ }.reject { |_k, v| v&.empty? }.compact
114
+
115
+ raw[:groups] = options[:permission]
116
+ raw
117
+ end
118
+ end
119
+ end
@@ -50,6 +50,14 @@ module WavefrontCli
50
50
  wf.history(options[:'<id>'], options[:offset], options[:limit])
51
51
  end
52
52
 
53
+ def do_affected_hosts
54
+ if options[:'<id>']
55
+ affected_hosts_for_id(options[:'<id>'])
56
+ else
57
+ all_affected_hosts
58
+ end
59
+ end
60
+
53
61
  def do_currently
54
62
  state = options[:'<state>'].to_s
55
63
 
@@ -146,5 +154,26 @@ module WavefrontCli
146
154
  end
147
155
  end.compact
148
156
  end
157
+
158
+ def all_affected_hosts
159
+ cannot_noop!
160
+ in_state(:firing).tap do |r|
161
+ r.response = r.response.items.each_with_object({}) do |alert, aggr|
162
+ aggr[alert[:id]] = affected_hosts_for_id(alert[:id]).response
163
+ end
164
+ end
165
+ end
166
+
167
+ def affected_hosts_for_id(id)
168
+ resp = wf.describe(id)
169
+
170
+ return if options[:noop]
171
+
172
+ return resp unless resp.ok? && resp.response.key?(:failingHostLabelPairs)
173
+
174
+ resp.tap do |r|
175
+ r.response = r.response[:failingHostLabelPairs].map { |h| h[:host] }
176
+ end
177
+ end
149
178
  end
150
179
  end
@@ -46,7 +46,7 @@ module WavefrontCli
46
46
  end
47
47
 
48
48
  # Normally we map the class name to a similar one in the SDK.
49
- # Overriding his method lets you map to something else.
49
+ # Overriding this method lets you map to something else.
50
50
  #
51
51
  def _sdk_class
52
52
  self.class.name.sub(/Cli/, '')
@@ -349,60 +349,6 @@ module WavefrontCli
349
349
  raise(WavefrontCli::Exception::CredentialError, 'Missing API endpoint.')
350
350
  end
351
351
 
352
- # Give it a path to a file (as a string) and it will return the
353
- # contents of that file as a Ruby object. Automatically detects
354
- # JSON and YAML. Raises an exception if it doesn't look like
355
- # either. If path is '-' then it will read STDIN.
356
- #
357
- # @param path [String] the file to load
358
- # @return [Hash] a Ruby object of the loaded file
359
- # @raise WavefrontCli::Exception::UnsupportedFileFormat if the
360
- # filetype is unknown.
361
- # @raise pass through any error loading or parsing the file
362
- #
363
- def load_file(path)
364
- return load_from_stdin if path == '-'
365
-
366
- file = Pathname.new(path)
367
- extname = file.extname.downcase
368
-
369
- raise WavefrontCli::Exception::FileNotFound unless file.exist?
370
-
371
- return load_json(file) if extname == '.json'
372
- return load_yaml(file) if %w[.yaml .yml].include?(extname)
373
-
374
- raise WavefrontCli::Exception::UnsupportedFileFormat
375
- end
376
-
377
- def load_json(file)
378
- read_json(IO.read(file))
379
- end
380
-
381
- def load_yaml(file)
382
- read_yaml(IO.read(file))
383
- end
384
-
385
- # Read STDIN and return a Ruby object, assuming that STDIN is
386
- # valid JSON or YAML. This is a dumb method, it does no
387
- # buffering, so STDIN must be a single block of data. This
388
- # appears to be a valid assumption for use-cases of this CLI.
389
- #
390
- # @return [Object]
391
- # @raise Wavefront::Exception::UnparseableInput if the input
392
- # does not parse
393
- #
394
- def load_from_stdin
395
- raw = STDIN.read
396
-
397
- if raw.start_with?('---')
398
- read_yaml(raw)
399
- else
400
- read_json(raw)
401
- end
402
- rescue RuntimeError
403
- raise Wavefront::Exception::UnparseableInput
404
- end
405
-
406
352
  # Below here are common methods. Most are used by most classes,
407
353
  # but if they don't match a command described in the docopt
408
354
  # text, the dispatcher will never call them. So, there's no
@@ -451,50 +397,8 @@ module WavefrontCli
451
397
  end
452
398
 
453
399
  def do_import
454
- raw = load_file(options[:'<file>'])
455
- errs = 0
456
-
457
- [raw].flatten.each do |obj|
458
- resp = import_object(obj)
459
- next if options[:noop]
460
-
461
- errs += 1 unless resp.ok?
462
- puts import_message(obj, resp)
463
- end
464
-
465
- exit errs
466
- end
467
-
468
- def import_message(obj, resp)
469
- format('%-15<id>s %-10<status>s %<message>s',
470
- id: obj[:id] || obj[:url],
471
- status: resp.ok? ? 'IMPORTED' : 'FAILED',
472
- message: resp.status.message)
473
- end
474
-
475
- def import_object(raw)
476
- raw = preprocess_rawfile(raw) if respond_to?(:preprocess_rawfile)
477
- prepped = import_to_create(raw)
478
-
479
- if options[:upsert]
480
- import_upsert(raw, prepped)
481
- elsif options[:update]
482
- import_update(raw)
483
- else
484
- wf.create(prepped)
485
- end
486
- end
487
-
488
- def import_upsert(raw, prepped)
489
- update_call = import_update(raw)
490
- return update_call if update_call.ok?
491
-
492
- puts 'update failed, inserting' if options[:verbose] || options[:debug]
493
- wf.create(prepped)
494
- end
495
-
496
- def import_update(raw)
497
- wf.update(raw[:id], raw, false)
400
+ require_relative 'subcommands/import'
401
+ WavefrontCli::Subcommand::Import.new(self, options).run!
498
402
  end
499
403
 
500
404
  def do_delete
@@ -581,7 +485,6 @@ module WavefrontCli
581
485
  # @param cond [String] a search condition, like "key=value"
582
486
  # @return [Hash] of matchingMethod and negated
583
487
  #
584
- # rubocop:disable Metrics/CyclomaticComplexity
585
488
  # rubocop:disable Metrics/MethodLength
586
489
  def matching_method(cond)
587
490
  case cond
@@ -602,19 +505,6 @@ module WavefrontCli
602
505
  end
603
506
  end
604
507
  # rubocop:enable Metrics/MethodLength
605
- # rubocop:enable Metrics/CyclomaticComplexity
606
-
607
- # Most things will re-import with the POST method if you remove
608
- # the ID.
609
- #
610
- def import_to_create(raw)
611
- raw.each_with_object({}) do |(k, v), a|
612
- a[k.to_sym] = v unless k == :id
613
- end
614
- rescue StandardError => e
615
- puts e if options[:debug]
616
- raise WavefrontCli::Exception::UnparseableInput
617
- end
618
508
 
619
509
  # Return a detailed description of one item, if an ID has been
620
510
  # given, or all items if it has not.
@@ -665,14 +555,16 @@ module WavefrontCli
665
555
  end
666
556
  # rubocop:enable Metrics/MethodLength
667
557
 
668
- private
669
-
670
- def read_json(io)
671
- JSON.parse(io, symbolize_names: true)
672
- end
673
-
674
- def read_yaml(io)
675
- YAML.safe_load(io, symbolize_names: true)
558
+ # Most things will re-import with the POST method if you remove
559
+ # the ID.
560
+ #
561
+ def import_to_create(raw)
562
+ raw.each_with_object({}) do |(k, v), a|
563
+ a[k.to_sym] = v unless k == :id
564
+ end
565
+ rescue StandardError => e
566
+ puts e if options[:debug]
567
+ raise WavefrontCli::Exception::UnparseableInput
676
568
  end
677
569
  end
678
570
  end