wavefront-cli 2.9.4 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/HISTORY.md +31 -19
  4. data/lib/wavefront-cli/alert.rb +23 -3
  5. data/lib/wavefront-cli/base.rb +39 -9
  6. data/lib/wavefront-cli/base_write.rb +66 -21
  7. data/lib/wavefront-cli/commands/alert.rb +3 -2
  8. data/lib/wavefront-cli/commands/cloudintegration.rb +3 -2
  9. data/lib/wavefront-cli/commands/dashboard.rb +3 -2
  10. data/lib/wavefront-cli/commands/derivedmetric.rb +3 -2
  11. data/lib/wavefront-cli/commands/integration.rb +3 -2
  12. data/lib/wavefront-cli/commands/link.rb +3 -2
  13. data/lib/wavefront-cli/commands/message.rb +1 -1
  14. data/lib/wavefront-cli/commands/notificant.rb +7 -6
  15. data/lib/wavefront-cli/commands/proxy.rb +3 -2
  16. data/lib/wavefront-cli/commands/savedsearch.rb +3 -2
  17. data/lib/wavefront-cli/commands/webhook.rb +3 -2
  18. data/lib/wavefront-cli/commands/window.rb +5 -2
  19. data/lib/wavefront-cli/commands/write.rb +11 -4
  20. data/lib/wavefront-cli/constants.rb +5 -0
  21. data/lib/wavefront-cli/controller.rb +2 -0
  22. data/lib/wavefront-cli/display/base.rb +3 -6
  23. data/lib/wavefront-cli/display/distribution.rb +14 -0
  24. data/lib/wavefront-cli/display/integration.rb +1 -1
  25. data/lib/wavefront-cli/display/maintenancewindow.rb +9 -0
  26. data/lib/wavefront-cli/display/source.rb +15 -4
  27. data/lib/wavefront-cli/event.rb +1 -1
  28. data/lib/wavefront-cli/maintenancewindow.rb +20 -1
  29. data/lib/wavefront-cli/query.rb +1 -1
  30. data/lib/wavefront-cli/version.rb +1 -1
  31. data/lib/wavefront-cli/write.rb +49 -3
  32. data/spec/spec_helper.rb +1 -6
  33. data/spec/wavefront-cli/base_spec.rb +12 -8
  34. data/spec/wavefront-cli/commands/write_spec.rb +1 -1
  35. data/spec/wavefront-cli/query_spec.rb +1 -1
  36. data/spec/wavefront-cli/write_spec.rb +20 -0
  37. data/wavefront-cli.gemspec +1 -1
  38. metadata +9 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 56e2d1e86b7889da1db692a783bab9f5cef73d244cbfc1e5fe22ac7140d34bdd
4
- data.tar.gz: ffba1e5d56717720094a76db34f06462d7a8421c20f6e45324f69c24b32c4421
3
+ metadata.gz: d12064132ca2cdf1520ff601c8ad3797adfcf0adf306f258bf27e7cf596748f0
4
+ data.tar.gz: 57e656c7b47e5c477e1b7ff3efd410b9aa659f83b00a3e730909fc36726d0079
5
5
  SHA512:
6
- metadata.gz: 11a3ce1cbb5648bacc9ae6c8c06780ab52d7dd3f039d820ca9d30550bc4e7f7b90bd095e3f129f614ab6b0647d8075a9e96fad22c4c1f4b3fd35fd825c765cbd
7
- data.tar.gz: d4e1279e1b09979e8976af7fbd04e0f397e9b73b2cec1570a1afe018f4724c332c9515eddd624781b6c3cac0827422ab0b6d876d6daf5b110d8f4b469faab97a
6
+ metadata.gz: 07f9bd142969a90d45e604abc9ef64ce166bcddcc031115bdb8a2ea0db96d299f21b654e03ec0b1a237462d8ac785c6423d34c0436fb77be8b8b8596a62fc4fc
7
+ data.tar.gz: cd92759ebce2f7df4ba85d7340d0c6683a082bb7e46daae33191638164fb9417cce27f3a96924773f623338ab98c2befe85b9702f145c97991737797cedc2a35
data/.rubocop.yml CHANGED
@@ -9,3 +9,5 @@ Metrics/ClassLength:
9
9
  Metrics/MethodLength:
10
10
  Max: 13
11
11
 
12
+ Style/NumericLiterals:
13
+ Enabled: false
data/HISTORY.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.10.0
4
+ * Most `list` subcommands accept `-a / --all`, and will show all
5
+ objects of the given type, with no pagination. (Exceptions are
6
+ `user`, which never paginated because the API doesn't, and
7
+ `source`, where the operation would take a prohibitively long
8
+ time.)
9
+ * `search` operations also accept `-a / --all`.
10
+ * Add `window ongoing` subcommand, to show currently open
11
+ maintenance windows.
12
+ * Add `window pending` subcommand, to show upcoming
13
+ maintenance windows. Defaults to windows in the next 24 hours, but
14
+ takes a decimal hour as an argument.
15
+ * Add `alert currently <state>` subcommand to list all alerts in any
16
+ allowable state.
17
+ * Use version 2 of [wavefront-sdk](https://github.com/snltd/wavefront-sdk).
18
+ * Write
19
+ [distributions](https://docs.wavefront.com/proxies_histograms.html)
20
+ to a proxy. Distributions can be specified singly, or streamed
21
+ from a file. Please see [this
22
+ page](https://sysdef.xyz/post/2018-04-08-wavefront-writer) for
23
+ more information.
24
+ * Add `-u / --using` option to `write` command. This lets you send
25
+ points to proxies using alternate transport methods. At the moment
26
+ only `-u http` is supported, but other mechanisms will be added as
27
+ they are made available by Wavefront.
28
+ * Display local times by default, in the same way as the UI.
29
+ * Improve quality of `--verbose` output when writing points.
30
+ * Improved usage error messages.
31
+ * Use a single connection when streaming data to a proxy from STDIN.
32
+ * Don't list hidden sources unless specifically asked.
33
+
3
34
  ## 2.9.3 (03/09/2018)
4
35
  * Fix a bug where indefinitely snoozed alerts broke `wf alert
5
36
  snoozed`.
@@ -29,17 +60,14 @@
29
60
  better, more flexible way.
30
61
 
31
62
  ## 2.7.0 (04/07/2018)
32
-
33
63
  * Add a `-i` option to the `report` command, to send delta metrics.
34
64
  * Fix delta metrics on the `write` command.
35
65
 
36
66
  ## 2.6.0 (27/06/2018)
37
-
38
67
  * Anything which can be imported can be imported from STDIN. The CLI
39
68
  will do its best to work out if the format is YAML or JSON.
40
69
 
41
70
  ## 2.5.0 (25/06/2018)
42
-
43
71
  * Support [derived
44
72
  metrics](https://docs.wavefront.com/derived_metrics.html).
45
73
  * Remove options which were not actually supported.
@@ -50,7 +78,6 @@
50
78
  * Remove obsolete code and test files.
51
79
 
52
80
  ## 2.4.0 (10/04/2017)
53
-
54
81
  * Support direct data ingestion via `report` command.
55
82
  * Support writing delta metrics.
56
83
  * Add `-q` to silenty write data points.
@@ -60,31 +87,24 @@
60
87
  provider](https://github.com/spaceapegames/terraform-provider-wavefront).
61
88
 
62
89
  ## 2.3.1 (24/03/2017)
63
-
64
90
  * Fix broken handling of negative values in `write` command.
65
91
 
66
92
  ## 2.3.0 (23/02/2017)
67
-
68
93
  * Add query aliases.
69
94
 
70
95
  ## 2.2.0 (18/02/2017)
71
-
72
96
  * Add `alert firing` and `alert snoozed` subcommands.
73
97
 
74
98
  ## 2.1.6 (11/01/2017)
75
-
76
99
  * Correctly handle `=` characters in `update` subcommands.
77
100
 
78
101
  ## 2.1.5 (05/12/2017)
79
-
80
102
  * Allow the user to tag events when they are created.
81
103
 
82
104
  ## 2.1.4 (15/11/2017)
83
-
84
105
  * `event create` bugfix.
85
106
 
86
107
  ## 2.1.3 (31/10/2017)
87
-
88
108
  * Use credential mechanism from SDK instead of rolling our own.
89
109
  * Fix bug which ignored supposedly supported environment variables,
90
110
  and add support for more.
@@ -92,38 +112,30 @@
92
112
  * Eradicate build warnings.
93
113
 
94
114
  ## 2.1.2 (31/10/2017)
95
-
96
115
  * Fix no-op bug.
97
116
  * Add BSD license.
98
117
 
99
118
  ## 2.1.1 (12/10/2017)
100
-
101
119
  * Fix bug in relative time specifications.
102
120
 
103
121
  ## 2.1.0 (12/10/2017)
104
-
105
122
  * Allow users to specify relative times, like `-10m`.
106
123
 
107
124
  ## 2.0.0 (09/10/2017)
108
-
109
125
  * Support viewing and managing of integrations.
110
126
  * Support notificants. (AKA alert targets).
111
127
  * Support new source descriptions.
112
128
  * Breaking change in `source` command.
113
129
 
114
130
  ## 1.0.3 (25/08/2017)
115
-
116
131
  * Fix nil tag bug in terse source listing.
117
132
 
118
133
  ## 1.0.2 (04/08/2017)
119
-
120
134
  * Greatly improve support for maintenance windows. They can now be
121
135
  extended, shrunk, and closed and created on the fly.
122
136
 
123
137
  ## 1.0.1 (31/07/2017)
124
-
125
138
  * Report `no data` if a query returns no data.
126
139
 
127
140
  ## 1.0.0 (28/07/2017)
128
-
129
141
  * First official release.
@@ -36,15 +36,35 @@ module WavefrontCli
36
36
  wf.history(options[:'<id>'], options[:offset], options[:limit])
37
37
  end
38
38
 
39
+ def do_currently
40
+ state = options[:'<state>'].to_s
41
+
42
+ if wf.respond_to?(state)
43
+ in_state(state)
44
+ else
45
+ abort format("'%s' is not a valid alert state.", state)
46
+ end
47
+ end
48
+
39
49
  def do_firing
40
- find_in_state(:firing)
50
+ in_state(:firing)
41
51
  end
42
52
 
43
53
  def do_snoozed
44
- find_in_state(:snoozed)
54
+ in_state(:firing)
55
+ end
56
+
57
+ # How many alerts are in the given state? If none, say so,
58
+ # rather than just printing nothing.
59
+ #
60
+ def in_state(status)
61
+ options[:all] = true
62
+ ret = find_in_state(status)
63
+ ok_exit(format('No alerts are currently %s.', status)) if ret.empty?
64
+ ret
45
65
  end
46
66
 
47
- # Does the work for #do_firing() and #do_snoozed()
67
+ # Does the work for #in_state
48
68
  # @param status [Symbol,String] the alert status you wish to
49
69
  # find
50
70
  # @return Wavefront::Response
@@ -1,6 +1,7 @@
1
1
  require 'yaml'
2
2
  require 'json'
3
3
  require 'wavefront-sdk/validators'
4
+ require_relative 'constants'
4
5
  require_relative 'exception'
5
6
 
6
7
  module WavefrontCli
@@ -22,10 +23,11 @@ module WavefrontCli
22
23
  attr_accessor :wf, :options, :klass, :klass_word
23
24
 
24
25
  include Wavefront::Validators
26
+ include WavefrontCli::Constants
25
27
 
26
28
  def initialize(options)
27
29
  @options = options
28
- sdk_class = self.class.name.sub(/Cli/, '')
30
+ sdk_class = _sdk_class
29
31
  @klass_word = sdk_class.split('::').last.downcase
30
32
  validate_input
31
33
 
@@ -37,6 +39,13 @@ module WavefrontCli
37
39
  send(:post_initialize, options) if respond_to?(:post_initialize)
38
40
  end
39
41
 
42
+ # Normally we map the class name to a similar one in the SDK.
43
+ # Overriding his method lets you map to something else.
44
+ #
45
+ def _sdk_class
46
+ self.class.name.sub(/Cli/, '')
47
+ end
48
+
40
49
  # Some subcommands don't make an API call, so they don't return
41
50
  # a Wavefront::Response object. You can override this method
42
51
  # with something which returns an array of methods like that.
@@ -50,7 +59,13 @@ module WavefrontCli
50
59
  end
51
60
 
52
61
  def options_and_exit
53
- puts options
62
+ ok_exit(options)
63
+ end
64
+
65
+ # Print a message and exit 0
66
+ #
67
+ def ok_exit(message)
68
+ puts message
54
69
  exit 0
55
70
  end
56
71
 
@@ -113,9 +128,12 @@ module WavefrontCli
113
128
  # @return [Hash] containing `debug`, `verbose`, and `noop`.
114
129
  #
115
130
  def mk_opts
116
- { debug: options[:debug],
117
- verbose: options[:verbose],
118
- noop: options[:noop] }
131
+ ret = { debug: options[:debug],
132
+ verbose: options[:verbose],
133
+ noop: options[:noop] }
134
+
135
+ ret.merge!(extra_options) if respond_to?(:extra_options)
136
+ ret
119
137
  end
120
138
 
121
139
  # To allow a user to default to different output formats for
@@ -334,6 +352,7 @@ module WavefrontCli
334
352
  # harm inheriting unneeded things. Some classes override them.
335
353
  #
336
354
  def do_list
355
+ return wf.list(ALL_PAGE_SIZE, :all) if options[:all]
337
356
  wf.list(options[:offset] || 0, options[:limit] || 100)
338
357
  end
339
358
 
@@ -374,12 +393,23 @@ module WavefrontCli
374
393
  def do_search(cond = options[:'<condition>'])
375
394
  require 'wavefront-sdk/search'
376
395
  wfs = Wavefront::Search.new(mk_creds, mk_opts)
377
-
378
396
  query = conds_to_query(cond)
397
+ wfs.search(search_key, query, range_hash)
398
+ end
399
+
400
+ # If the user has specified --all, override any limit and offset
401
+ # values
402
+ #
403
+ def range_hash
404
+ if options[:all]
405
+ limit = :all
406
+ offset = ALL_PAGE_SIZE
407
+ else
408
+ limit = options[:limit]
409
+ offset = options[:offset] || options[:cursor]
410
+ end
379
411
 
380
- wfs.search(search_key, query, limit: options[:limit],
381
- offset: options[:offset] ||
382
- options[:cursor])
412
+ { limit: limit, offset: offset }
383
413
  end
384
414
 
385
415
  # The search URI pattern doesn't always match the command name,
@@ -1,4 +1,4 @@
1
- require 'wavefront-sdk/mixins'
1
+ require 'wavefront-sdk/support/mixins'
2
2
  require_relative 'base'
3
3
 
4
4
  module WavefrontCli
@@ -24,7 +24,8 @@ module WavefrontCli
24
24
  def send_point(point)
25
25
  call_write(point)
26
26
  rescue Wavefront::Exception::InvalidEndpoint
27
- abort "could not speak to proxy #{options[:proxy]}:#{options[:port]}."
27
+ abort format("Could not connect to proxy '%s:%s'.",
28
+ options[:proxy], options[:port])
28
29
  end
29
30
 
30
31
  def do_file
@@ -56,10 +57,15 @@ module WavefrontCli
56
57
  end
57
58
  end
58
59
 
59
- # A wrapper which lets us send normal points or deltas
60
+ # A wrapper which lets us send normal points, deltas, or
61
+ # distributions
60
62
  #
61
- def call_write(data)
62
- options[:delta] ? wf.write_delta(data) : wf.write(data)
63
+ def call_write(data, openclose = true)
64
+ if options[:delta]
65
+ wf.write_delta(data, openclose)
66
+ else
67
+ wf.write(data, openclose)
68
+ end
63
69
  end
64
70
 
65
71
  # Read from standard in and stream points through an open
@@ -68,7 +74,7 @@ module WavefrontCli
68
74
  #
69
75
  def read_stdin
70
76
  open_connection
71
- STDIN.each_line { |l| call_write(process_line(l.strip)) }
77
+ STDIN.each_line { |l| call_write(process_line(l.strip), false) }
72
78
  close_connection
73
79
  rescue SystemExit, Interrupt
74
80
  puts 'ctrl-c. Exiting.'
@@ -84,8 +90,28 @@ module WavefrontCli
84
90
  # raise Wavefront::Exception::InvalidValue if it's not a value
85
91
  #
86
92
  def extract_value(chunks)
87
- v = chunks[fmt.index('v')]
88
- v.to_f
93
+ if fmt.include?('v')
94
+ v = chunks[fmt.index('v')]
95
+ v.to_f
96
+ else
97
+ raw = chunks[fmt.index('d')].split(',')
98
+ xpanded = expand_dist(raw)
99
+ wf.mk_distribution(xpanded)
100
+ end
101
+ end
102
+
103
+ # We will let users write a distribution as '1 1 1' or '3x1' or
104
+ # even a mix of the two
105
+ #
106
+ def expand_dist(dist)
107
+ dist.map do |v|
108
+ if v.is_a?(String) && v.include?('x')
109
+ x, val = v.split('x', 2)
110
+ Array.new(x.to_i, val.to_f)
111
+ else
112
+ v.to_f
113
+ end
114
+ end.flatten
89
115
  end
90
116
 
91
117
  # Find and return the source in a chunked line of input.
@@ -146,6 +172,7 @@ module WavefrontCli
146
172
  #
147
173
  # rubocop:disable Metrics/AbcSize
148
174
  # rubocop:disable Metrics/MethodLength
175
+ # rubocop:disable Metrics/CyclomaticComplexity
149
176
  def process_line(line)
150
177
  return true if line.empty?
151
178
  chunks = line.split(/\s+/, fmt.length)
@@ -156,8 +183,9 @@ module WavefrontCli
156
183
  tags: line_tags(chunks),
157
184
  value: extract_value(chunks) }
158
185
 
159
- point[:ts] = extract_ts(chunks) if fmt.include?('t')
160
- point[:source] = extract_source(chunks) if fmt.include?('s')
186
+ point[:ts] = extract_ts(chunks) if fmt.include?('t')
187
+ point[:source] = extract_source(chunks) if fmt.include?('s')
188
+ point[:interval] = options[:interval] || 'm' if fmt.include?('d')
161
189
  rescue TypeError
162
190
  raise(WavefrontCli::Exception::UnparseableInput,
163
191
  "could not process #{line}")
@@ -165,6 +193,7 @@ module WavefrontCli
165
193
 
166
194
  point
167
195
  end
196
+ # rubocop:enable Metrics/CyclomaticComplexity
168
197
  # rubocop:enable Metrics/MethodLength
169
198
  # rubocop:enable Metrics/AbcSize
170
199
 
@@ -195,22 +224,37 @@ module WavefrontCli
195
224
  end
196
225
  end
197
226
 
198
- # The format string must contain a 'v'. It must not contain
199
- # anything other than 'm', 't', 'T', 's', or 'v', and the 'T',
200
- # if there, must be at the end. No letter must appear more than
201
- # once.
227
+ # The format string must contain values. They can be single
228
+ # values or distributions. So we must have 'v' xor 'd'. It must
229
+ # not contain anything other than 'm', 't', 'T', 's', 'd', or
230
+ # 'v', and the 'T', if there, must be at the end. No letter must
231
+ # appear more than once.
202
232
  #
203
233
  # @param fmt [String] format of input file
204
234
  #
235
+ # rubocop:disable Metrics/PerceivedComplexity
236
+ # rubocop:disable Metrics/CyclomaticComplexity
237
+ # rubocop:disable Metrics/AbcSize
205
238
  def valid_format?(fmt)
206
- if fmt.include?('v') && fmt.match(/^[mstv]+T?$/) &&
207
- fmt == fmt.split('').uniq.join
208
- return true
209
- end
239
+ err = if fmt.include?('v') && fmt.include?('d')
240
+ "'v' and 'd' are mutually exclusive"
241
+ elsif !fmt.include?('v') && !fmt.include?('d')
242
+ "format string must include 'v' or 'd'"
243
+ elsif !fmt.match(/^[dmstTv]+$/)
244
+ 'unsupported field in format string'
245
+ elsif !fmt == fmt.split('').uniq.join
246
+ 'repeated field in format string'
247
+ elsif fmt.include?('T') && !fmt.end_with?('T')
248
+ "if used, 'T' must come at end of format string"
249
+ end
210
250
 
211
- raise(WavefrontCli::Exception::UnparseableInput,
212
- 'Invalid format string.')
251
+ return true if err.nil?
252
+
253
+ raise(WavefrontCli::Exception::UnparseableInput, err)
213
254
  end
255
+ # rubocop:enable Metrics/PerceivedComplexity
256
+ # rubocop:enable Metrics/CyclomaticComplexity
257
+ # rubocop:enable Metrics/AbcSize
214
258
 
215
259
  # Make sure we have the right number of columns, according to
216
260
  # the format string. We want to take every precaution we can to
@@ -224,7 +268,8 @@ module WavefrontCli
224
268
  ncols = line.split.length
225
269
  return true if fmt.include?('T') && ncols >= fmt.length
226
270
  return true if ncols == fmt.length
227
- raise WavefrontCli::Exception::UnparseableInput, 'wrong number of fields'
271
+ raise(WavefrontCli::Exception::UnparseableInput,
272
+ format('Expected %s fields, got %s', fmt.length, ncols))
228
273
  end
229
274
 
230
275
  # Although the SDK does value checking, we'll add another layer
@@ -8,7 +8,7 @@ class WavefrontCommandAlert < WavefrontCommandBase
8
8
  end
9
9
 
10
10
  def _commands
11
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit]",
11
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
12
12
  "firing #{CMN} [-o offset] [-L limit]",
13
13
  "snoozed #{CMN} [-o offset] [-L limit]",
14
14
  "describe #{CMN} [-f format] [-v version] <id>",
@@ -19,12 +19,13 @@ class WavefrontCommandAlert < WavefrontCommandBase
19
19
  "snooze #{CMN} [-T time] <id>",
20
20
  "update #{CMN} <key=value> <id>",
21
21
  "unsnooze #{CMN} <id>",
22
- "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>...",
22
+ "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>...",
23
23
  "tags #{CMN} [-f format] <id>",
24
24
  "tag set #{CMN} <id> <tag>...",
25
25
  "tag clear #{CMN} <id>",
26
26
  "tag add #{CMN} <id> <tag>",
27
27
  "tag delete #{CMN} <id> <tag>",
28
+ "currently #{CMN} <state>",
28
29
  "summary #{CMN} [-a]"]
29
30
  end
30
31
 
@@ -16,17 +16,18 @@ class WavefrontCommandCloudintegration < WavefrontCommandBase
16
16
  end
17
17
 
18
18
  def _commands
19
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit]",
19
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
20
20
  "describe #{CMN} [-f format] <id>",
21
21
  "delete #{CMN} <id>",
22
22
  "undelete #{CMN} <id>",
23
23
  "import #{CMN} <file>",
24
- "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>..."]
24
+ "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>..."]
25
25
  end
26
26
 
27
27
  def _options
28
28
  [common_options,
29
29
  '-l, --long list cloud integrations in detail',
30
+ '-a, --all list all cloud integrations',
30
31
  '-o, --offset=n start from nth cloud integration',
31
32
  '-L, --limit=COUNT number of cloud integrations to list',
32
33
  '-f, --format=STRING output format']
@@ -8,20 +8,21 @@ class WavefrontCommandDashboard < WavefrontCommandBase
8
8
  end
9
9
 
10
10
  def _commands
11
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit]",
11
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
12
12
  "describe #{CMN} [-f format] [-v version] <id>",
13
13
  "import #{CMN} [-f format] <file>",
14
14
  "update #{CMN} <key=value> <id>",
15
15
  "delete #{CMN} <id>",
16
16
  "undelete #{CMN} <id>",
17
17
  "history #{CMN} [-f format] [-o offset] [-L limit] <id>",
18
- "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>...",
18
+ "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>...",
19
19
  tag_commands]
20
20
  end
21
21
 
22
22
  def _options
23
23
  [common_options,
24
24
  '-l, --long list dashboards in detail',
25
+ '-a, --all list all dashboards',
25
26
  '-o, --offset=n start list from nth dashboard or revision',
26
27
  '-L, --limit=COUNT number of dashboards or revisions to list',
27
28
  '-v, --version=INTEGER version of dashboard',
@@ -16,7 +16,7 @@ class WavefrontCommandDerivedmetric < WavefrontCommandBase
16
16
  end
17
17
 
18
18
  def _commands
19
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit]",
19
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
20
20
  "describe #{CMN} [-f format] [-v version] <id>",
21
21
  "create #{CMN} [-d description] [-T tag...] [-O] [-i interval] " \
22
22
  '[-r range] <name> <query>',
@@ -25,13 +25,14 @@ class WavefrontCommandDerivedmetric < WavefrontCommandBase
25
25
  "delete #{CMN} <id>",
26
26
  "undelete #{CMN} <id>",
27
27
  "history #{CMN} [-f format] [-o offset] [-L limit] <id>",
28
- "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>...",
28
+ "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>...",
29
29
  tag_commands]
30
30
  end
31
31
 
32
32
  def _options
33
33
  [common_options,
34
34
  '-l, --long list derived metrics in detail',
35
+ '-a, --all list all derived metrics',
35
36
  '-o, --offset=n start list from nth derived metrics or ' \
36
37
  'revision',
37
38
  '-L, --limit=COUNT number of derived metrics or revisions to ' \
@@ -8,19 +8,20 @@ class WavefrontCommandIntegration < WavefrontCommandBase
8
8
  end
9
9
 
10
10
  def _commands
11
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit]",
11
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
12
12
  "describe #{CMN} [-f format] <id>",
13
13
  "install #{CMN} <id>",
14
14
  "uninstall #{CMN} <id>",
15
15
  "manifests #{CMN}",
16
16
  "status #{CMN} <id>",
17
17
  "statuses #{CMN}",
18
- "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>..."]
18
+ "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>..."]
19
19
  end
20
20
 
21
21
  def _options
22
22
  [common_options,
23
23
  '-l, --long list cloud integrations in detail',
24
+ '-a, --all list all cloud integrations',
24
25
  '-o, --offset=n start from nth cloud integration',
25
26
  '-L, --limit=COUNT number of cloud integrations to list',
26
27
  '-f, --format=STRING output format']
@@ -16,19 +16,20 @@ class WavefrontCommandLink < WavefrontCommandBase
16
16
  end
17
17
 
18
18
  def _commands
19
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit]",
19
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
20
20
  "describe #{CMN} [-f format] <id>",
21
21
  "create #{CMN} [-m regex] [-s regex] [-p str=regex...] <name> " \
22
22
  '<description> <template>',
23
23
  "delete #{CMN} <id>",
24
24
  "import #{CMN} <file>",
25
25
  "update #{CMN} <key=value> <id>",
26
- "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>..."]
26
+ "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>..."]
27
27
  end
28
28
 
29
29
  def _options
30
30
  [common_options,
31
31
  '-l, --long list external links in detail',
32
+ '-a, --all list all external links',
32
33
  '-o, --offset=n start from nth external link',
33
34
  '-L, --limit=COUNT number of external link to list',
34
35
  '-m, --metric-regex=REGEX metric filter regular expression',
@@ -8,7 +8,7 @@ class WavefrontCommandMessage < WavefrontCommandBase
8
8
  end
9
9
 
10
10
  def _commands
11
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit] [-a]",
11
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
12
12
  "mark #{CMN} [-f format] <id>"]
13
13
  end
14
14
 
@@ -4,24 +4,25 @@ require_relative 'base'
4
4
  #
5
5
  class WavefrontCommandNotificant < WavefrontCommandBase
6
6
  def description
7
- 'view and manage Wavefront notification targets'
7
+ 'view and manage Wavefront alert targets'
8
8
  end
9
9
 
10
10
  def _commands
11
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit]",
11
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
12
12
  "describe #{CMN} [-f format] <id>",
13
13
  "import #{CMN} <file>",
14
14
  "delete #{CMN} <id>",
15
15
  "test #{CMN} <id>",
16
16
  "update #{CMN} <key=value> <id>",
17
- "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>..."]
17
+ "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>..."]
18
18
  end
19
19
 
20
20
  def _options
21
21
  [common_options,
22
- '-l, --long list proxies in detail',
23
- '-o, --offset=n start from nth proxy',
22
+ '-l, --long list alert targets in detail',
23
+ '-a, --all list all alert targets',
24
+ '-o, --offset=n start from nth alert target',
24
25
  '-f, --format=STRING output format',
25
- '-L, --limit=COUNT number of proxies to list']
26
+ '-L, --limit=COUNT number of alert targets to list']
26
27
  end
27
28
  end
@@ -8,17 +8,18 @@ class WavefrontCommandProxy < WavefrontCommandBase
8
8
  end
9
9
 
10
10
  def _commands
11
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit]",
11
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
12
12
  "describe #{CMN} [-f format] <id>",
13
13
  "delete #{CMN} <id>",
14
14
  "undelete #{CMN} <id>",
15
15
  "rename #{CMN} <id> <name>",
16
- "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>..."]
16
+ "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>..."]
17
17
  end
18
18
 
19
19
  def _options
20
20
  [common_options,
21
21
  '-l, --long list proxies in detail',
22
+ '-a, --all list all proxies',
22
23
  '-o, --offset=n start from nth proxy',
23
24
  '-f, --format=STRING output format',
24
25
  '-L, --limit=COUNT number of proxies to list']
@@ -16,16 +16,17 @@ class WavefrontCommandSavedsearch < WavefrontCommandBase
16
16
  end
17
17
 
18
18
  def _commands
19
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit]",
19
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
20
20
  "describe #{CMN} [-f format] <id>",
21
21
  "delete #{CMN} <id>",
22
22
  "import #{CMN} <file>",
23
- "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>..."]
23
+ "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>..."]
24
24
  end
25
25
 
26
26
  def _options
27
27
  [common_options,
28
28
  '-l, --long list saved searches in detail',
29
+ '-a, --all list all saved searches',
29
30
  '-o, --offset=n start from nth saved search',
30
31
  '-L, --limit=COUNT number of saved searches to list',
31
32
  '-f, --format=STRING output format']
@@ -8,17 +8,18 @@ class WavefrontCommandWebhook < WavefrontCommandBase
8
8
  end
9
9
 
10
10
  def _commands
11
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit]",
11
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
12
12
  "describe #{CMN} [-f format] <id>",
13
13
  "delete #{CMN} <id>",
14
14
  "import #{CMN} <file>",
15
15
  "update #{CMN} <key=value> <id>",
16
- "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>..."]
16
+ "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>..."]
17
17
  end
18
18
 
19
19
  def _options
20
20
  [common_options,
21
21
  '-l, --long list webhooks in detail',
22
+ '-a, --all list all webhooks',
22
23
  '-o, --offset=n start list from nth webhook',
23
24
  '-L, --limit=COUNT number of webhooks to list',
24
25
  '-f, --format=STRING output format']
@@ -16,7 +16,7 @@ class WavefrontCommandWindow < WavefrontCommandBase
16
16
  end
17
17
 
18
18
  def _commands
19
- ["list #{CMN} [-l] [-f format] [-o offset] [-L limit]",
19
+ ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
20
20
  "describe #{CMN} [-f format] <id>",
21
21
  "create #{CMN} -d reason [-s time] [-e time] " \
22
22
  '[-A alert_tag...] [-T host_tag...] [-H host...] <title>',
@@ -25,12 +25,15 @@ class WavefrontCommandWindow < WavefrontCommandBase
25
25
  "delete #{CMN} <id>",
26
26
  "import #{CMN} <file>",
27
27
  "update #{CMN} <key=value> <id>",
28
- "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>..."]
28
+ "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>...",
29
+ "ongoing #{CMN}",
30
+ "pending #{CMN} [<hours>]"]
29
31
  end
30
32
 
31
33
  def _options
32
34
  [common_options,
33
35
  '-l, --long list maintenance windows in detail',
36
+ '-a, --all list all maintenance windows',
34
37
  '-o, --offset=n start from nth maintenance window',
35
38
  '-L, --limit=COUNT number of maintenance windows to list',
36
39
  '-d, --desc=STRING reason for maintenance window',
@@ -9,9 +9,12 @@ class WavefrontCommandWrite < WavefrontCommandBase
9
9
 
10
10
  def _commands
11
11
  ['point [-DnViq] [-c file] [-P profile] [-E proxy] [-t time] ' \
12
- '[-p port] [-H host] [-T tag...] <metric> <value>',
12
+ '[-p port] [-H host] [-T tag...] [-u method] <metric> <value>',
13
+ 'distribution [-DnViq] [-c file] [-P profile] [-E proxy] [-H host] ' \
14
+ '[-p port] [-T tag...] [-u method] [-I interval] <metric> <val>...',
13
15
  'file [-DnViq] [-c file] [-P profile] [-E proxy] [-H host] ' \
14
- '[-p port] [-F infileformat] [-m metric] [-T tag...] <file>']
16
+ '[-p port] [-F infileformat] [-m metric] [-T tag...] [-I interval] ' \
17
+ '[-u method] <file>']
15
18
  end
16
19
 
17
20
  def _options
@@ -26,6 +29,8 @@ class WavefrontCommandWrite < WavefrontCommandBase
26
29
  'a file will be assigned. If the file contains a metric name, ' \
27
30
  'the two will be dot-concatenated, with this value first',
28
31
  '-i, --delta increment metric by given value',
32
+ "-I, --interval=INTERVAL interval of distribution (default 'm')",
33
+ '-u, --using=METHOD method by which to send points',
29
34
  "-q, --quiet don't report the points sent summary " \
30
35
  '(unless there were errors)']
31
36
  end
@@ -33,7 +38,9 @@ class WavefrontCommandWrite < WavefrontCommandBase
33
38
  def postscript
34
39
  'Files are whitespace separated, and fields can be defined ' \
35
40
  "with the '-F' option. Use 't' for timestamp, 'm' for metric " \
36
- "name, 'v' for value, 's' for source, and 'T' for tags. Put 'T' " \
37
- 'last.'.cmd_fold(TW, 0)
41
+ "name, 'v' for value, 's' for source, 'd' for a comma-separated " \
42
+ "distribution, and 'T' for tags. Put 'T' last. Currently " \
43
+ "supported transport methods are 'socket' (the default) " \
44
+ "and 'http'.".cmd_fold(TW, 0)
38
45
  end
39
46
  end
@@ -12,5 +12,10 @@ module WavefrontCli
12
12
  endpoint: 'metrics.wavefront.com',
13
13
  format: :human
14
14
  }.freeze
15
+
16
+ # How many objects to get in each request when we are asked for
17
+ # --all
18
+ #
19
+ ALL_PAGE_SIZE = 999
15
20
  end
16
21
  end
@@ -120,6 +120,8 @@ class WavefrontCliController
120
120
  abort "Host system error. #{e.message}"
121
121
  rescue WavefrontCli::Exception::UnsupportedOperation => e
122
122
  abort "Unsupported operation.\n#{e.message}"
123
+ rescue Wavefront::Exception::UnsupportedWriter => e
124
+ abort "Unsupported writer '#{e.message}'."
123
125
  rescue StandardError => e
124
126
  warn "general error: #{e}"
125
127
  warn "re-run with '-D' for stack trace." unless opts[:debug]
@@ -122,14 +122,11 @@ module WavefrontDisplay
122
122
  def pagination_line
123
123
  return unless raw.respond_to?(:moreItems) && raw.moreItems == true
124
124
 
125
- if raw.respond_to?(:offset) && raw.respond_to?(:limit)
126
- puts 'List shows paginated output. Use -o and -L for more.'
127
- return
128
- end
129
-
130
125
  enditem = raw.limit > 0 ? raw.offset + raw.limit - 1 : 0
131
126
  puts format('List shows items %d to %d. Use -o and -L for more.',
132
127
  raw.offset, enditem)
128
+ rescue StandardError
129
+ puts 'List shows paginated output. Use -o and -L for more.'
133
130
  end
134
131
  # rubocop:enable Metrics/AbcSize
135
132
 
@@ -277,7 +274,7 @@ module WavefrontDisplay
277
274
  # rubocop:disable Style/DateTime
278
275
  ret = DateTime.strptime(str, fmt).to_time
279
276
  # rubocop:enable Style/DateTime
280
- ret = ret.utc if force_utc
277
+ ret = force_utc ? ret.utc : ret.localtime
281
278
  ret.strftime(out_fmt)
282
279
  end
283
280
 
@@ -0,0 +1,14 @@
1
+ require_relative 'write'
2
+
3
+ module WavefrontDisplay
4
+ # Format human-readable output when writing distributions
5
+ #
6
+ class Distribution < Write
7
+ # rubocop:disable Metrics/AbcSize
8
+ def do_distribution
9
+ report unless options[:quiet] || (data[:unsent] + data[:rejected] > 0)
10
+ exit(data.rejected.zero? && data.unsent.zero? ? 0 : 1)
11
+ end
12
+ # rubocop:enable Metrics/AbcSize
13
+ end
14
+ end
@@ -2,7 +2,7 @@ require_relative 'base'
2
2
 
3
3
  module WavefrontDisplay
4
4
  #
5
- # Format human-readable output for cloud integrations.
5
+ # Format human-readable output for integrations.
6
6
  #
7
7
  class Integration < Base
8
8
  def do_list_brief
@@ -15,5 +15,14 @@ module WavefrontDisplay
15
15
  def do_list_brief
16
16
  multicolumn(:id, :title)
17
17
  end
18
+
19
+ def do_pending
20
+ do_ongoing
21
+ end
22
+
23
+ def do_ongoing
24
+ readable_time_arr(:startTimeInSeconds, :endTimeInSeconds)
25
+ multicolumn(:id, :reason, :startTimeInSeconds, :endTimeInSeconds)
26
+ end
18
27
  end
19
28
  end
@@ -2,28 +2,39 @@ require_relative 'base'
2
2
 
3
3
  module WavefrontDisplay
4
4
  #
5
- # Format human-readable output for webhooks.
5
+ # Format human-readable output for sources.
6
6
  #
7
7
  class Source < Base
8
8
  def do_list
9
- drop_cluster_sources
9
+ massage_data
10
10
  long_output
11
11
  end
12
12
 
13
13
  def do_list_brief
14
- drop_cluster_sources
14
+ massage_data
15
15
  multicolumn(:id, :description)
16
16
  end
17
17
 
18
+ def massage_data
19
+ return if options[:all]
20
+ drop_cluster_sources
21
+ drop_hidden_sources
22
+ end
23
+
18
24
  def do_search_brief
19
25
  multicolumn(:id)
20
26
  end
21
27
 
28
+ # Filter out any sources with 'hidden=true'
29
+ #
30
+ def drop_hidden_sources
31
+ data.delete_if { |k| k.tags['hidden'] == true }
32
+ end
33
+
22
34
  # Filter out the Wavefront cluster sources. Don't sort them, or
23
35
  # using offset and cursor becomes confusing.
24
36
  #
25
37
  def drop_cluster_sources
26
- return if options[:all]
27
38
  data.delete_if { |k| k.id =~ /prod-[\da-f]{2}-/ }
28
39
  end
29
40
  end
@@ -1,6 +1,6 @@
1
1
  require 'fileutils'
2
2
  require 'open3'
3
- require 'wavefront-sdk/mixins'
3
+ require 'wavefront-sdk/support/mixins'
4
4
  require_relative 'base'
5
5
 
6
6
  EVENT_STATE_DIR = Pathname.new('/var/tmp/wavefront')
@@ -1,4 +1,4 @@
1
- require 'wavefront-sdk/mixins'
1
+ require 'wavefront-sdk/support/mixins'
2
2
  require_relative 'base'
3
3
 
4
4
  module WavefrontCli
@@ -81,5 +81,24 @@ module WavefrontCli
81
81
  def change_end_time(timestamp)
82
82
  wf.update(options[:'<id>'], endTimeInSeconds: timestamp)
83
83
  end
84
+
85
+ def do_ongoing
86
+ w = wf.ongoing
87
+ ok_exit('No maintenance windows currently ongoing.') if w.empty?
88
+ w
89
+ end
90
+
91
+ def do_pending
92
+ range = options[:'<hours>'].to_f
93
+ range = 24 unless range.positive?
94
+
95
+ w = wf.pending(range)
96
+
97
+ if w.empty?
98
+ ok_exit(format('No maintenance windows in the next %s hours.',
99
+ range))
100
+ end
101
+ w
102
+ end
84
103
  end
85
104
  end
@@ -1,4 +1,4 @@
1
- require 'wavefront-sdk/mixins'
1
+ require 'wavefront-sdk/support/mixins'
2
2
  require_relative 'base'
3
3
 
4
4
  module WavefrontCli
@@ -1 +1 @@
1
- WF_CLI_VERSION = '2.9.4'.freeze
1
+ WF_CLI_VERSION = '2.10.0'.freeze
@@ -7,16 +7,62 @@ module WavefrontCli
7
7
  # speaks to a proxy rather than to the API.
8
8
  #
9
9
  class Write < BaseWrite
10
+ # rubocop:disable Metrics/AbcSize
11
+ def do_distribution
12
+ p = { path: options[:'<metric>'],
13
+ interval: options[:interval] || 'M',
14
+ value: mk_dist,
15
+ tags: tags_to_hash(options[:tag]) }
16
+
17
+ p[:source] = options[:host] if options[:host]
18
+ p[:ts] = parse_time(options[:time]) if options[:time]
19
+ send_point(p)
20
+ end
21
+ # rubocop:enable Metrics/AbcSize
22
+
23
+ # Turn our user's representation of a distribution into one
24
+ # which suits Wavefront. The SDK can do this for us.
25
+ #
26
+ def mk_dist
27
+ xpanded = expand_dist(options[:'<val>'])
28
+ wf.mk_distribution(xpanded.map(&:to_f))
29
+ end
30
+
31
+ def extra_options
32
+ options[:using] ? { writer: options[:using] } : {}
33
+ end
34
+
35
+ # I chose to prioritise UI consistency over internal elegance
36
+ # here. The `write` command doesn't follow the age-old
37
+ # assumption that each command maps 1:1 to a similarly named SDK
38
+ # class. Write can use `write` or `distribution`.
39
+ #
40
+ def _sdk_class
41
+ return 'Wavefront::Distribution' if distribution?
42
+ 'Wavefront::Write'
43
+ end
44
+
45
+ def distribution?
46
+ return true if options[:distribution]
47
+ options[:infileformat] && options[:infileformat].include?('d')
48
+ end
49
+
10
50
  def mk_creds
11
- { proxy: options[:proxy], port: options[:port] || 2878 }
51
+ { proxy: options[:proxy],
52
+ port: options[:port] || default_port,
53
+ endpoint: options[:endpoint],
54
+ token: options[:token] }
55
+ end
56
+
57
+ def default_port
58
+ distribution? ? 40000 : 2878
12
59
  end
13
60
 
14
61
  def validate_opts
15
62
  validate_opts_file if options[:file]
16
63
 
17
64
  return true if options[:proxy]
18
- raise(WavefrontCli::Exception::CredentialError,
19
- 'Missing proxy address.')
65
+ raise(WavefrontCli::Exception::CredentialError, 'No proxy address.')
20
66
  end
21
67
 
22
68
  def validate_opts_file
data/spec/spec_helper.rb CHANGED
@@ -55,7 +55,6 @@ end
55
55
  # command
56
56
  # @param call [Hash]
57
57
  #
58
- # rubocop:disable Metrics/AbcSize
59
58
  def cmd_to_call(word, args, call, sdk_class = nil)
60
59
  headers = { 'Accept': /.*/,
61
60
  'Accept-Encoding': /.*/,
@@ -89,10 +88,7 @@ def cmd_to_call(word, args, call, sdk_class = nil)
89
88
 
90
89
  require "wavefront-sdk/#{sdk_class.name.split('::').last.downcase}"
91
90
  Spy.on_instance_method(
92
- Object.const_get(
93
- "Wavefront::#{sdk_class.name.split('::').last}"
94
- ),
95
- :respond
91
+ Object.const_get('Wavefront::ApiCaller'), :respond
96
92
  ).and_return({})
97
93
 
98
94
  d = Spy.on_instance_method(sdk_class, :display)
@@ -105,7 +101,6 @@ def cmd_to_call(word, args, call, sdk_class = nil)
105
101
  end
106
102
  end
107
103
  end
108
- # rubocop:enable Metrics/AbcSize
109
104
 
110
105
  # Run a command we expect to fail, returning stdout and stderr
111
106
  #
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require_relative '../spec_helper'
4
- require_relative '../../lib/wavefront-cli/base'
4
+ require_relative '../../lib/wavefront-cli/alert'
5
5
  require 'spy'
6
6
  require 'spy/integration'
7
7
 
@@ -26,21 +26,25 @@ DISP_DATA = {
26
26
  b: %w[list_1 list_2]
27
27
  }.freeze
28
28
 
29
- # Test base class
29
+ # Since I tidied up the file layout in wavefront-sdk, there's no
30
+ # longer a 1:1 mapping of CLI and SDK classes. wavefront-sdk/base is
31
+ # now wavefront-sdk/core/api. The only thing that broke was the
32
+ # tests in this class. Now we test the methods in the abstract base
33
+ # class via an instantiation of a concrete class. I don't think any
34
+ # of this matters.
30
35
  #
31
36
  class WavefrontCliBaseTest < MiniTest::Test
32
37
  attr_reader :wf, :wf_cmd
33
38
 
34
39
  def setup
35
- @wf = WavefrontCli::Base.new(OPTS)
36
- @wf_cmd = WavefrontCli::Base.new(OPTS_CMD)
37
- wf_cmd.define_singleton_method(:do_test_cmd) { true }
40
+ @wf = WavefrontCli::Alert.new(OPTS)
38
41
  end
39
42
 
40
43
  def test_mk_creds
41
- assert_equal wf.mk_creds, endpoint: 'test.wavefront.com',
42
- token: '0123456789-ABCDEF',
43
- agent: "wavefront-cli-#{WF_CLI_VERSION}"
44
+ assert_equal({ endpoint: 'test.wavefront.com',
45
+ token: '0123456789-ABCDEF',
46
+ agent: "wavefront-cli-#{WF_CLI_VERSION}" },
47
+ wf.mk_creds)
44
48
  end
45
49
 
46
50
  def test_dispatch
@@ -12,6 +12,6 @@ class WavefrontCommmandWriteTest < WavefrontCommmandBaseTest
12
12
  def setup
13
13
  @wf = WavefrontCommandWrite.new
14
14
  @col_width = 25
15
- @skip_cmd = /write (point|file)/
15
+ @skip_cmd = /write (point|file|distribution)/
16
16
  end
17
17
  end
@@ -4,7 +4,7 @@ word = 'query'
4
4
 
5
5
  require_relative '../spec_helper'
6
6
  require_relative "../../lib/wavefront-cli/#{word}"
7
- require 'wavefront-sdk/mixins'
7
+ require 'wavefront-sdk/support/mixins'
8
8
  # rubocop:disable Style/MixinUsage
9
9
  include Wavefront::Mixins
10
10
  # rubocop:enable Style/MixinUsage
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../../lib/wavefront-cli/write'
4
+
5
+ # Test base writer
6
+ #
7
+ class WavefrontCliWriteTest < MiniTest::Test
8
+ attr_reader :wf
9
+
10
+ def setup
11
+ @wf = WavefrontCli::Write.new({})
12
+ end
13
+
14
+ def test_expand_dist
15
+ assert_equal(wf.expand_dist([1, 1, 1]), [1, 1, 1])
16
+ assert_equal(wf.expand_dist(['3x1']), [1, 1, 1])
17
+ assert_equal(wf.expand_dist(%w[3x1 1x4]), [1, 1, 1, 4])
18
+ assert_equal(wf.expand_dist([1, 1, 1, '2x2']).sort, [2, 2, 1, 1, 1].sort)
19
+ end
20
+ end
@@ -23,7 +23,7 @@ Gem::Specification.new do |gem|
23
23
  gem.require_paths = %w[lib]
24
24
 
25
25
  gem.add_runtime_dependency 'docopt', '~> 0.6.0'
26
- gem.add_runtime_dependency 'wavefront-sdk', '~> 1.6', '>= 1.6.2'
26
+ gem.add_runtime_dependency 'wavefront-sdk', '~> 2.0', '>= 2.0.1'
27
27
 
28
28
  gem.add_development_dependency 'bundler', '~> 1.3'
29
29
  gem.add_development_dependency 'minitest', '~> 5.11', '>= 5.11.0'
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: 2.9.4
4
+ version: 2.10.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: 2018-09-22 00:00:00.000000000 Z
11
+ date: 2018-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docopt
@@ -30,20 +30,20 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.6'
33
+ version: '2.0'
34
34
  - - ">="
35
35
  - !ruby/object:Gem::Version
36
- version: 1.6.2
36
+ version: 2.0.1
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - "~>"
42
42
  - !ruby/object:Gem::Version
43
- version: '1.6'
43
+ version: '2.0'
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: 1.6.2
46
+ version: 2.0.1
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -200,6 +200,7 @@ files:
200
200
  - lib/wavefront-cli/display/cloudintegration.rb
201
201
  - lib/wavefront-cli/display/dashboard.rb
202
202
  - lib/wavefront-cli/display/derivedmetric.rb
203
+ - lib/wavefront-cli/display/distribution.rb
203
204
  - lib/wavefront-cli/display/event.rb
204
205
  - lib/wavefront-cli/display/externallink.rb
205
206
  - lib/wavefront-cli/display/integration.rb
@@ -303,6 +304,7 @@ files:
303
304
  - spec/wavefront-cli/stdlib/string_spec.rb
304
305
  - spec/wavefront-cli/user_spec.rb
305
306
  - spec/wavefront-cli/webhook_spec.rb
307
+ - spec/wavefront-cli/write_spec.rb
306
308
  - wavefront-cli.gemspec
307
309
  homepage: https://github.com/snltd/wavefront-cli
308
310
  licenses:
@@ -380,3 +382,4 @@ test_files:
380
382
  - spec/wavefront-cli/stdlib/string_spec.rb
381
383
  - spec/wavefront-cli/user_spec.rb
382
384
  - spec/wavefront-cli/webhook_spec.rb
385
+ - spec/wavefront-cli/write_spec.rb