wavefront-cli 4.0.2 → 4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83528e35b66e2a098928edb63b4f62cf4f730153caf886e8d2132dd8ef870340
4
- data.tar.gz: 9a6affc13f2b2fc1c41052abbd25dae47c2412a7bd70b39ec84ab8516ee748fa
3
+ metadata.gz: 48f9a11ef858f502c05d4c4d89080a31267f70d96430e88e44deba5b2f929015
4
+ data.tar.gz: a1bbc741a8379fb2a5783688a858b8c12b5d020a1501d58478042fc303ca43c3
5
5
  SHA512:
6
- metadata.gz: 46710487da70d0ea78ec7ba703b608b634a80d8b837b0ac91d0f4b9efad7a36ede6365060eb3f25455f56fbbdfd55b015a92f87c5c684af86e32f77ed00b038e
7
- data.tar.gz: d7527a3814e9b2cc8fe1ba1f49fa294122406442e2c5c50ecdafd0f2b6a4a975a2c0c22b74fb01cb5a9379e07977b421d3a526b070714120d2ccfb64f0e59110
6
+ metadata.gz: 759172c664ff1b81f2e199afceb052a61f31f4c91b7f72ea69ad5e511dc19d7397d9731d7e03269d75b88bd3baa52bfedc3bc289c166a84b590fb71ea9bc7a11
7
+ data.tar.gz: 5c7a9545f5ea086dce5bc02588ddf678ebad99321e55c68026a9e12ad0645b5a4a0bffcffac155ca238ad79370cd00cf146bd8033780f83dfabe2d7322b6c378
data/HISTORY.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.1.0 (27/06/2019)
4
+ * Add `dump` subcommand for all importable object types. Produces
5
+ JSON or YAML output.
6
+ * Allow batch importing of objects. Works with files produced by
7
+ `dump` subcommand, or by manually creating a JSON or YAML array of
8
+ objects. Batch imports are automatically detected by the `import`
9
+ subcommand.
10
+
3
11
  ## 4.0.2 (20/06/2019)
4
12
  * Allow importing of dashboards which have a URL but not an ID.
5
13
 
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017-2018, Sysdef Ltd
1
+ Copyright (c) 2017-2019, Sysdef Ltd
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
data/README.md CHANGED
@@ -18,7 +18,7 @@ SDK](https://github.com/snltd/wavefront-sdk) and requires Ruby >=
18
18
  2.3. It has no "native extension" dependencies.
19
19
 
20
20
  For a far more comprehensive overview/tutorial, please read [this
21
- article](http://sysdef.xyz/post/2017-07-26-wavefront-cli).
21
+ article](https://sysdef.xyz/article/wavefront-cli).
22
22
 
23
23
  ```
24
24
  $ wf --help
@@ -11,7 +11,7 @@ module WavefrontCli
11
11
  include WavefrontCli::Mixin::Acl
12
12
 
13
13
  def import_fields
14
- %w[name condition minutes target severity displayExpression
14
+ %i[name condition minutes target severity displayExpression
15
15
  tags additionalInformation resolveAfterMinutes]
16
16
  end
17
17
 
@@ -128,8 +128,8 @@ module WavefrontCli
128
128
  import_fields.each_with_object({}) { |k, a| a[k.to_sym] = raw[k] }
129
129
  .tap do |ret|
130
130
 
131
- if raw.key?('resolveAfterMinutes')
132
- ret[:resolveMinutes] = raw['resolveAfterMinutes']
131
+ if raw.key?(:resolveAfterMinutes)
132
+ ret[:resolveMinutes] = raw[:resolveAfterMinutes]
133
133
  end
134
134
 
135
135
  if raw.key?('customerTagsWithCounts')
@@ -143,9 +143,10 @@ module WavefrontCli
143
143
  end
144
144
 
145
145
  # To allow a user to default to different output formats for
146
- # different object, we are able to define a format for each class.
147
- # instance, `alertformat` or `agentformat`. This method returns
148
- # such a string appropriate for the inheriting class.
146
+ # different object types, we are able to define a format for
147
+ # each class. instance, `alertformat` or `proxyformat`. This
148
+ # method returns such a symbol appropriate for the inheriting
149
+ # class.
149
150
  #
150
151
  # @return [Symbol] name of the option or config-file key which
151
152
  # sets the default output format for this class
@@ -164,25 +165,15 @@ module WavefrontCli
164
165
  # @raise WavefrontCli::Exception::UnhandledCommand if the
165
166
  # command does not match a `do_` method.
166
167
  #
167
- # rubocop:disable Metrics/AbcSize
168
168
  def dispatch
169
+ # Look through each deconstructed method name and see if the
170
+ # user supplied an option for each component. Call the first
171
+ # one that matches. The order will ensure we match
172
+ # "do_delete_tags" before we match "do_delete".
169
173
  #
170
- # Take a list of do_ methods, remove the 'do_' from their name,
171
- # and break them into arrays of '_' separated words.
172
- #
173
- m_list = methods.select { |m| m.to_s.start_with?('do_') }.map do |m|
174
- m.to_s.split('_')[1..-1]
175
- end
176
-
177
- # Sort that array of arrays by length, longest first. Then look
178
- # through each deconstructed method name and see if the user
179
- # supplied an option for each component. Call the first one that
180
- # matches. The order will ensure we match "do_delete_tags" before
181
- # we match "do_delete".
182
- #
183
- m_list.sort_by(&:length).reverse_each do |m|
184
- if m.reject { |w| options[w.to_sym] }.empty?
185
- method = (%w[do] + m).join('_')
174
+ method_word_list.reverse_each do |w_list|
175
+ if w_list.reject { |w| options[w.to_sym] }.empty?
176
+ method = name_of_do_method(w_list)
186
177
  return display(public_send(method), method)
187
178
  end
188
179
  end
@@ -193,7 +184,19 @@ module WavefrontCli
193
184
 
194
185
  raise WavefrontCli::Exception::UnhandledCommand
195
186
  end
196
- # rubocop:enable Metrics/AbcSize
187
+
188
+ def name_of_do_method(word_list)
189
+ (%w[do] + word_list).join('_')
190
+ end
191
+
192
+ # Take a list of do_ methods, remove the 'do_' from their name,
193
+ # and break them into arrays of '_' separated words. The array
194
+ # is sorted by length, longest first.
195
+ #
196
+ def method_word_list
197
+ do_methods = methods.select { |m| m.to_s.start_with?('do_') }
198
+ do_methods.map { |m| m.to_s.split('_')[1..-1] }.sort_by(&:length)
199
+ end
197
200
 
198
201
  # Display a Ruby object as JSON, YAML, or human-readable. We
199
202
  # provide a default method to format human-readable output, but
@@ -208,7 +211,6 @@ module WavefrontCli
208
211
  # @param method [String] the name of the method which produced
209
212
  # this output. Used to find a suitable humanize method.
210
213
  #
211
- # rubocop:disable Metrics/AbcSize
212
214
  def display(data, method)
213
215
  if no_api_response.include?(method)
214
216
  return display_no_api_response(data, method)
@@ -216,18 +218,22 @@ module WavefrontCli
216
218
 
217
219
  exit if options[:noop]
218
220
 
221
+ check_response_blocks(data)
222
+ status_error_handler(data, method)
223
+ handle_response(data.response, format_var, method)
224
+ end
225
+
226
+ def status_error_handler(data, method)
227
+ return if check_status(data.status)
228
+ handle_error(method, data.status.code) if format_var == :human
229
+ display_api_error(data.status)
230
+ end
231
+
232
+ def check_response_blocks(data)
219
233
  %i[status response].each do |b|
220
234
  abort "no #{b} block in API response" unless data.respond_to?(b)
221
235
  end
222
-
223
- unless check_status(data.status)
224
- handle_error(method, data.status.code) if format_var == :human
225
- display_api_error(data.status)
226
- end
227
-
228
- handle_response(data.response, format_var, method)
229
236
  end
230
- # rubocop:enable Metrics/AbcSize
231
237
 
232
238
  # Classes can provide methods which give the user information on
233
239
  # a given error code. They are named #handle_errcode_xxx, and
@@ -384,24 +390,51 @@ module WavefrontCli
384
390
  end
385
391
 
386
392
  # rubocop:disable Metrics/AbcSize
393
+ def do_dump
394
+ items = wf.list(ALL_PAGE_SIZE, :all).response.items
395
+
396
+ if options[:format] == 'yaml'
397
+ ok_exit items.to_yaml
398
+ elsif options[:format] == 'json'
399
+ ok_exit items.to_json
400
+ else
401
+ abort format("Dump format must be 'json' or 'yaml'. (Tried '%s')",
402
+ options[:format])
403
+ end
404
+ end
405
+ # rubocop:enable Metrics/AbcSize
406
+
387
407
  def do_import
388
408
  raw = load_file(options[:'<file>'])
389
- raw = preprocess_rawfile(raw) if respond_to?(:preprocess_rawfile)
409
+ errs = 0
390
410
 
391
- begin
392
- prepped = import_to_create(raw)
393
- rescue StandardError => e
394
- puts e if options[:debug]
395
- raise WavefrontCli::Exception::UnparseableInput
411
+ [raw].flatten.each do |obj|
412
+ resp = import_object(obj)
413
+ next if options[:noop]
414
+ errs += 1 unless resp.ok?
415
+ puts import_message(obj, resp)
396
416
  end
397
417
 
418
+ exit errs
419
+ end
420
+
421
+ def import_message(obj, resp)
422
+ format('%-15s %-10s %s',
423
+ obj[:id] || obj[:url],
424
+ resp.ok? ? 'IMPORTED' : 'FAILED',
425
+ resp.status.message)
426
+ end
427
+
428
+ def import_object(raw)
429
+ raw = preprocess_rawfile(raw) if respond_to?(:preprocess_rawfile)
430
+ prepped = import_to_create(raw)
431
+
398
432
  if options[:update]
399
433
  import_update(raw)
400
434
  else
401
435
  wf.create(prepped)
402
436
  end
403
437
  end
404
- # rubocop:enable Metrics/AbcSize
405
438
 
406
439
  def import_update(raw)
407
440
  wf.update(raw[:id], raw, false)
@@ -508,8 +541,11 @@ module WavefrontCli
508
541
  #
509
542
  def import_to_create(raw)
510
543
  raw.each_with_object({}) do |(k, v), a|
511
- a[k.to_sym] = v unless k == 'id'
544
+ a[k.to_sym] = v unless k == :id
512
545
  end
546
+ rescue StandardError => e
547
+ puts e if options[:debug]
548
+ raise WavefrontCli::Exception::UnparseableInput
513
549
  end
514
550
 
515
551
  # Return a detailed description of one item, if an ID has been
@@ -14,6 +14,7 @@ class WavefrontCommandAlert < WavefrontCommandBase
14
14
  "history #{CMN} [-o offset] [-L limit] <id>",
15
15
  "clone #{CMN} [-v version] <id>",
16
16
  "latest #{CMN} <id>",
17
+ "dump #{CMN}",
17
18
  "import #{CMN} [-u] <file>",
18
19
  "snooze #{CMN} [-T time] <id>",
19
20
  "set #{CMN} <key=value> <id>",
@@ -22,6 +22,7 @@ class WavefrontCommandCloudintegration < WavefrontCommandBase
22
22
  "undelete #{CMN} <id>",
23
23
  "enable #{CMN} <id>",
24
24
  "disable #{CMN} <id>",
25
+ "dump #{CMN}",
25
26
  "import #{CMN} [-u] <file>",
26
27
  "search #{CMN} [-al] [-o offset] [-L limit] <condition>..."]
27
28
  end
@@ -6,6 +6,7 @@ class WavefrontCommandDashboard < WavefrontCommandBase
6
6
  def _commands
7
7
  ["list #{CMN} [-alN] [-O fields] [-o offset] [-L limit]",
8
8
  "describe #{CMN} [-v version] <id>",
9
+ "dump #{CMN}",
9
10
  "import #{CMN} [-u] <file>",
10
11
  "set #{CMN} <key=value> <id>",
11
12
  "delete #{CMN} <id>",
@@ -20,6 +20,7 @@ class WavefrontCommandDerivedmetric < WavefrontCommandBase
20
20
  "describe #{CMN} [-v version] <id>",
21
21
  "create #{CMN} [-d description] [-T tag...] [-b] [-i interval] " \
22
22
  '[-r range] <name> <query>',
23
+ "dump #{CMN}",
23
24
  "import #{CMN} [-u] <file>",
24
25
  "set #{CMN} <key=value> <id>",
25
26
  "delete #{CMN} <id>",
@@ -21,6 +21,7 @@ class WavefrontCommandLink < WavefrontCommandBase
21
21
  "create #{CMN} [-m regex] [-s regex] [-p str=regex...] <name> " \
22
22
  '<description> <template>',
23
23
  "delete #{CMN} <id>",
24
+ "dump #{CMN}",
24
25
  "import #{CMN} [-u] <file>",
25
26
  "set #{CMN} <key=value> <id>",
26
27
  "search #{CMN} [-al] [-o offset] [-L limit] <condition>..."]
@@ -14,6 +14,7 @@ class WavefrontCommandNotificant < WavefrontCommandBase
14
14
  def _commands
15
15
  ["list #{CMN} [-al] [-O fields] [-o offset] [-L limit]",
16
16
  "describe #{CMN} <id>",
17
+ "dump #{CMN}",
17
18
  "import #{CMN} [-u] <file>",
18
19
  "delete #{CMN} <id>",
19
20
  "test #{CMN} <id>",
@@ -23,6 +23,7 @@ class WavefrontCommandSavedsearch < WavefrontCommandBase
23
23
  ["list #{CMN} [-al] [-O fields] [-o offset] [-L limit]",
24
24
  "describe #{CMN} <id>",
25
25
  "delete #{CMN} <id>",
26
+ "dump #{CMN}",
26
27
  "import #{CMN} [-u] <file>",
27
28
  "search #{CMN} [-al] [-o offset] [-L limit] <condition>..."]
28
29
  end
@@ -18,6 +18,7 @@ class WavefrontCommandUser < WavefrontCommandBase
18
18
  "invite #{CMN} [-m permission...] [-g group...] <id>",
19
19
  "set #{CMN} <key=value> <id>",
20
20
  "delete #{CMN} <user>...",
21
+ "dump #{CMN}",
21
22
  "import #{CMN} [-u] <file>",
22
23
  "groups #{CMN} <id>",
23
24
  "join #{CMN} <id> <group>...",
@@ -24,6 +24,7 @@ class WavefrontCommandUsergroup < WavefrontCommandBase
24
24
  "describe #{CMN} <id>",
25
25
  "create #{CMN} [-p permission...] <name>",
26
26
  "delete #{CMN} <id>",
27
+ "dump #{CMN}",
27
28
  "import #{CMN} [-u] <file>",
28
29
  "set #{CMN} <key=value> <id>",
29
30
  "users #{CMN} <id>",
@@ -7,6 +7,7 @@ class WavefrontCommandWebhook < WavefrontCommandBase
7
7
  ["list #{CMN} [-al] [-O fields] [-o offset] [-L limit]",
8
8
  "describe #{CMN} <id>",
9
9
  "delete #{CMN} <id>",
10
+ "dump #{CMN}",
10
11
  "import #{CMN} [-u] <file>",
11
12
  "set #{CMN} <key=value> <id>",
12
13
  "search #{CMN} [-al] [-o offset] [-L limit] <condition>..."]
@@ -23,6 +23,7 @@ class WavefrontCommandWindow < WavefrontCommandBase
23
23
  "close #{CMN} <id>",
24
24
  "extend #{CMN} (by|to) <time> <id>",
25
25
  "delete #{CMN} <id>",
26
+ "dump #{CMN}",
26
27
  "import #{CMN} [-u] <file>",
27
28
  "set #{CMN} <key=value> <id>",
28
29
  "search #{CMN} [-al] [-o offset] [-L limit] <condition>...",
@@ -1 +1 @@
1
- WF_CLI_VERSION = '4.0.2'.freeze
1
+ WF_CLI_VERSION = '4.1.0'.freeze
@@ -430,7 +430,7 @@ class CliMethodTest < MiniTest::Test
430
430
  end
431
431
 
432
432
  def import_tester(word, have_fields, do_not_have_fields = [])
433
- input = JSON.parse(IO.read(RES_DIR + 'imports' + "#{word}.json"))
433
+ input = wf.load_file(RES_DIR + 'imports' + "#{word}.json")
434
434
  x = wf.import_to_create(input)
435
435
  assert_instance_of(Hash, x)
436
436
  have_fields.each { |f| assert_includes(x.keys, f) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wavefront-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.2
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Fisher
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-20 00:00:00.000000000 Z
11
+ date: 2019-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docopt