dogapi 1.36.0 → 1.37.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5c534abc672555cbdf8ae3e4ad066a06bc6d066b
4
- data.tar.gz: 349b0b8721a13b3bbe97d4f3183dc739a259a4d7
2
+ SHA256:
3
+ metadata.gz: 762f1d3fe87b94278a55cca80da8824b0c2db3c420ea9e8192cd1f33d7a274ce
4
+ data.tar.gz: c60248ed8d4cc8e3d3f96662651878f42591bd336c4c6d58511489e504474607
5
5
  SHA512:
6
- metadata.gz: b23eaa485025ad841b5a74683c85009fc3eca097b2681ae9045af8a146adc1f6b881c49d46919f40fe54ff691d671b162928b07eab83666ccad1f5c23fea593e
7
- data.tar.gz: a8d31cf15e3f1d61e6fc0da448994b57fae3d5f6a6846b3713bbb95ced32890da0af5f05a281040cfccc75015adb68921679b7a1769ec8cefb9570b3c2696738
6
+ metadata.gz: '09565868bb18c71030b625b908a8783f83f135e237c6e6fe8600ecd745141c34cd3e2bc019fb24ad84d01fdb5b839d56cd4dc57db9fe751b37c13ec43f31593b'
7
+ data.tar.gz: d93617177693a86273716dd2ccc99bb3e79ef2aa77a44cd021a635a7181e34df9485592a2ed341c9cae50407007add7a9e30348a77212aea28ab7332da2b38bb
@@ -0,0 +1,44 @@
1
+ trigger:
2
+ batch: false
3
+ branches:
4
+ include:
5
+ - master
6
+
7
+ pr:
8
+ branches:
9
+ include:
10
+ - master
11
+
12
+ jobs:
13
+ - job: UnitTests
14
+ pool:
15
+ vmImage: "Ubuntu-16.04"
16
+ strategy:
17
+ matrix:
18
+ Rb23:
19
+ RUBY_VERSION: '2.3.7'
20
+ TASK: spec
21
+ Rb24:
22
+ RUBY_VERSION: '2.4.6'
23
+ TASK: spec
24
+ Rb25:
25
+ RUBY_VERSION: '2.5.5'
26
+ TASK: spec
27
+ Rb26:
28
+ RUBY_VERSION: '2.6.3'
29
+ TASK: spec
30
+ Lint:
31
+ RUBY_VERSION: '2.6.3'
32
+ TASK: rubocop
33
+ steps:
34
+ - task: UseRubyVersion@0
35
+ displayName: Use Ruby $(RUBY_VERSION)
36
+ inputs:
37
+ versionSpec: $(RUBY_VERSION)
38
+ addToPath: true
39
+ - script: |
40
+ gem install bundler
41
+ bundle install --retry=3 --jobs=4
42
+ displayName: 'bundle install'
43
+ - script: bundle exec rake $(TASK)
44
+ displayName: Run $(TASK) via bundle
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2018-10-01 12:52:09 +0200 using RuboCop version 0.49.1.
3
+ # on 2019-10-23 14:52:35 -0500 using RuboCop version 0.49.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -51,14 +51,14 @@ Layout/EmptyLines:
51
51
  - 'lib/capistrano/datadog/v2.rb'
52
52
  - 'lib/dogapi/facade.rb'
53
53
 
54
- # Offense count: 63
54
+ # Offense count: 78
55
55
  # Cop supports --auto-correct.
56
56
  # Configuration parameters: EnforcedStyle, SupportedStyles.
57
57
  # SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines
58
58
  Layout/EmptyLinesAroundClassBody:
59
59
  Enabled: false
60
60
 
61
- # Offense count: 1
61
+ # Offense count: 4
62
62
  # Cop supports --auto-correct.
63
63
  Layout/EmptyLinesAroundMethodBody:
64
64
  Exclude:
@@ -85,10 +85,20 @@ Layout/ExtraSpacing:
85
85
 
86
86
  # Offense count: 2
87
87
  # Cop supports --auto-correct.
88
- # Configuration parameters: SupportedStyles, IndentationWidth.
88
+ # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
89
+ # SupportedStyles: consistent, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
90
+ Layout/FirstParameterIndentation:
91
+ Exclude:
92
+ - 'spec/spec_helper.rb'
93
+
94
+ # Offense count: 3
95
+ # Cop supports --auto-correct.
96
+ # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
89
97
  # SupportedStyles: special_inside_parentheses, consistent, align_braces
90
98
  Layout/IndentHash:
91
- EnforcedStyle: consistent
99
+ Exclude:
100
+ - 'lib/dogapi/v1/event.rb'
101
+ - 'lib/dogapi/v1/service_level_objective.rb'
92
102
 
93
103
  # Offense count: 1
94
104
  # Cop supports --auto-correct.
@@ -120,7 +130,7 @@ Layout/SpaceAfterComma:
120
130
  Exclude:
121
131
  - 'examples/custom_metric.rb'
122
132
 
123
- # Offense count: 75
133
+ # Offense count: 83
124
134
  # Cop supports --auto-correct.
125
135
  # Configuration parameters: EnforcedStyle, SupportedStyles.
126
136
  # SupportedStyles: space, no_space
@@ -147,12 +157,29 @@ Layout/SpaceAroundOperators:
147
157
  - 'examples/custom_metric.rb'
148
158
  - 'lib/dogapi/event.rb'
149
159
 
150
- # Offense count: 1
160
+ # Offense count: 8
161
+ # Cop supports --auto-correct.
162
+ Layout/SpaceBeforeComma:
163
+ Exclude:
164
+ - 'lib/dogapi/facade.rb'
165
+ - 'lib/dogapi/v1/service_level_objective.rb'
166
+
167
+ # Offense count: 2
151
168
  # Cop supports --auto-correct.
152
169
  # Configuration parameters: AllowForAlignment.
153
170
  Layout/SpaceBeforeFirstArg:
154
171
  Exclude:
155
172
  - 'lib/capistrano/datadog/v2.rb'
173
+ - 'lib/dogapi/v1/service_level_objective.rb'
174
+
175
+ # Offense count: 6
176
+ # Cop supports --auto-correct.
177
+ # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces.
178
+ # SupportedStyles: space, no_space, compact
179
+ # SupportedStylesForEmptyBraces: space, no_space
180
+ Layout/SpaceInsideHashLiteralBraces:
181
+ Exclude:
182
+ - 'spec/integration/service_level_objective_spec.rb'
156
183
 
157
184
  # Offense count: 1
158
185
  # Cop supports --auto-correct.
@@ -201,44 +228,42 @@ Lint/UselessAssignment:
201
228
  Exclude:
202
229
  - 'lib/capistrano/datadog.rb'
203
230
 
204
- # Offense count: 11
231
+ # Offense count: 13
205
232
  Metrics/AbcSize:
206
233
  Max: 51
207
234
 
208
- # Offense count: 18
235
+ # Offense count: 24
209
236
  # Configuration parameters: CountComments, ExcludedMethods.
210
237
  Metrics/BlockLength:
211
- Max: 96
212
- Exclude:
213
- - 'spec/integration/monitor_spec.rb'
238
+ Max: 102
214
239
 
215
- # Offense count: 2
240
+ # Offense count: 5
216
241
  Metrics/CyclomaticComplexity:
217
- Max: 8
242
+ Max: 11
218
243
 
219
- # Offense count: 15
244
+ # Offense count: 18
220
245
  # Configuration parameters: CountComments.
221
246
  Metrics/MethodLength:
222
247
  Max: 34
223
248
 
224
- # Offense count: 2
249
+ # Offense count: 7
225
250
  # Configuration parameters: CountKeywordArgs.
226
251
  Metrics/ParameterLists:
227
- Max: 7
252
+ Max: 11
228
253
 
229
- # Offense count: 1
254
+ # Offense count: 4
230
255
  Metrics/PerceivedComplexity:
231
- Max: 9
256
+ Max: 12
232
257
 
233
- # Offense count: 11
258
+ # Offense count: 13
234
259
  Style/AccessorMethodName:
235
260
  Exclude:
236
261
  - 'lib/dogapi/facade.rb'
237
262
  - 'lib/dogapi/v1/alert.rb'
238
263
  - 'lib/dogapi/v1/dash.rb'
264
+ - 'lib/dogapi/v1/dashboard.rb'
239
265
  - 'lib/dogapi/v1/embed.rb'
240
266
  - 'lib/dogapi/v1/screenboard.rb'
241
- - 'lib/dogapi/v1/dashboard.rb'
242
267
  - 'lib/dogapi/v1/user.rb'
243
268
 
244
269
  # Offense count: 1
@@ -283,7 +308,7 @@ Style/ClassMethods:
283
308
  Exclude:
284
309
  - 'lib/dogapi/common.rb'
285
310
 
286
- # Offense count: 2
311
+ # Offense count: 3
287
312
  Style/ClassVars:
288
313
  Exclude:
289
314
  - 'lib/dogapi/common.rb'
@@ -295,24 +320,24 @@ Style/ColonMethodCall:
295
320
  - 'lib/capistrano/datadog.rb'
296
321
  - 'lib/capistrano/datadog/v2.rb'
297
322
 
298
- # Offense count: 2
323
+ # Offense count: 1
299
324
  # Cop supports --auto-correct.
300
325
  # Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerBackticks.
301
326
  # SupportedStyles: backticks, percent_x, mixed
302
327
  Style/CommandLiteral:
303
328
  Exclude:
304
- - 'lib/capistrano/datadog.rb'
305
329
  - 'lib/dogapi/common.rb'
306
330
 
307
- # Offense count: 1
331
+ # Offense count: 2
308
332
  # Cop supports --auto-correct.
309
333
  # Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly, IncludeTernaryExpressions.
310
334
  # SupportedStyles: assign_to_condition, assign_inside_condition
311
335
  Style/ConditionalAssignment:
312
336
  Exclude:
313
337
  - 'lib/capistrano/datadog.rb'
338
+ - 'lib/dogapi/v1/service_level_objective.rb'
314
339
 
315
- # Offense count: 20
340
+ # Offense count: 21
316
341
  # Cop supports --auto-correct.
317
342
  Style/DefWithParentheses:
318
343
  Exclude:
@@ -322,28 +347,9 @@ Style/DefWithParentheses:
322
347
  - 'lib/dogapi/v1/metric.rb'
323
348
  - 'lib/dogapi/v1/screenboard.rb'
324
349
 
325
- # Offense count: 21
350
+ # Offense count: 23
326
351
  Style/Documentation:
327
- Exclude:
328
- - 'spec/**/*'
329
- - 'test/**/*'
330
- - 'lib/capistrano/datadog.rb'
331
- - 'lib/capistrano/datadog/v2.rb'
332
- - 'lib/capistrano/datadog/v3.rb'
333
- - 'lib/dogapi/common.rb'
334
- - 'lib/dogapi/v1/alert.rb'
335
- - 'lib/dogapi/v1/comment.rb'
336
- - 'lib/dogapi/v1/dash.rb'
337
- - 'lib/dogapi/v1/metadata.rb'
338
- - 'lib/dogapi/v1/monitor.rb'
339
- - 'lib/dogapi/v1/screenboard.rb'
340
- - 'lib/dogapi/v1/search.rb'
341
- - 'lib/dogapi/v1/service_check.rb'
342
- - 'lib/dogapi/v1/snapshot.rb'
343
- - 'lib/dogapi/v1/user.rb'
344
- - 'lib/dogapi/v1/integration.rb'
345
- - 'lib/dogapi/v1/usage.rb'
346
- - 'lib/dogapi/v1/metric.rb'
352
+ Enabled: false
347
353
 
348
354
  # Offense count: 1
349
355
  # Cop supports --auto-correct.
@@ -351,7 +357,7 @@ Style/EmptyLiteral:
351
357
  Exclude:
352
358
  - 'lib/dogapi/v1/metric.rb'
353
359
 
354
- # Offense count: 2
360
+ # Offense count: 3
355
361
  # Configuration parameters: MinBodyLength.
356
362
  Style/GuardClause:
357
363
  Exclude:
@@ -399,7 +405,7 @@ Style/LineEndConcatenation:
399
405
  Exclude:
400
406
  - 'dogapi.gemspec'
401
407
 
402
- # Offense count: 15
408
+ # Offense count: 18
403
409
  # Cop supports --auto-correct.
404
410
  Style/MethodCallWithoutArgsParentheses:
405
411
  Exclude:
@@ -414,7 +420,7 @@ Style/MultilineIfThen:
414
420
  Exclude:
415
421
  - 'lib/capistrano/datadog.rb'
416
422
 
417
- # Offense count: 21
423
+ # Offense count: 30
418
424
  # Cop supports --auto-correct.
419
425
  Style/MutableConstant:
420
426
  Enabled: false
@@ -434,12 +440,17 @@ Style/Not:
434
440
  Exclude:
435
441
  - 'lib/dogapi/v1/metric.rb'
436
442
 
437
- # Offense count: 5
443
+ # Offense count: 1
444
+ # Cop supports --auto-correct.
445
+ # Configuration parameters: Strict.
446
+ Style/NumericLiterals:
447
+ MinDigits: 8
448
+
449
+ # Offense count: 4
438
450
  # Cop supports --auto-correct.
439
451
  # Configuration parameters: PreferredDelimiters.
440
452
  Style/PercentLiteralDelimiters:
441
453
  Exclude:
442
- - 'lib/capistrano/datadog.rb'
443
454
  - 'lib/dogapi/common.rb'
444
455
  - 'spec/integration/event_spec.rb'
445
456
  - 'spec/integration/monitor_spec.rb'
@@ -452,12 +463,11 @@ Style/PreferredHashMethods:
452
463
  Exclude:
453
464
  - 'lib/dogapi/common.rb'
454
465
 
455
- # Offense count: 3
466
+ # Offense count: 2
456
467
  # Cop supports --auto-correct.
457
468
  Style/RedundantBegin:
458
469
  Exclude:
459
470
  - 'lib/capistrano/datadog.rb'
460
- - 'lib/dogapi/common.rb'
461
471
  - 'lib/dogapi/v1/metric.rb'
462
472
 
463
473
  # Offense count: 2
@@ -497,7 +507,7 @@ Style/SpecialGlobalVars:
497
507
  Exclude:
498
508
  - 'dogapi.gemspec'
499
509
 
500
- # Offense count: 22
510
+ # Offense count: 23
501
511
  # Cop supports --auto-correct.
502
512
  # Configuration parameters: EnforcedStyle, SupportedStyles, ConsistentQuotesInMultiline.
503
513
  # SupportedStyles: single_quotes, double_quotes
@@ -509,6 +519,7 @@ Style/StringLiterals:
509
519
  - 'examples/Capfile'
510
520
  - 'examples/custom_event.rb'
511
521
  - 'lib/dogapi/event.rb'
522
+ - 'spec/integration/service_level_objective_spec.rb'
512
523
 
513
524
  # Offense count: 10
514
525
  # Cop supports --auto-correct.
@@ -526,11 +537,11 @@ Style/TrailingCommaInLiteral:
526
537
 
527
538
  # Offense count: 2
528
539
  # Cop supports --auto-correct.
529
- # Configuration parameters: EnforcedStyle, SupportedStyles, MinSize, WordRegex.
540
+ # Configuration parameters: SupportedStyles, WordRegex.
530
541
  # SupportedStyles: percent, brackets
531
542
  Style/WordArray:
532
- Exclude:
533
- - 'examples/custom_event.rb'
543
+ EnforcedStyle: percent
544
+ MinSize: 3
534
545
 
535
546
  # Offense count: 1
536
547
  # Cop supports --auto-correct.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changes
2
2
 
3
+ ## 1.37.0 / 2019-11-04
4
+
5
+ * [FEATURE] Add Service Level Objectives support. See [#188][], thanks [@platinummonkey][]
6
+ * [IMPROVEMENTS] Don't fail if `hostname` binary is not installed. See [#179][], thanks [@pschipitsch][]
7
+ * [IMPROVEMENTS] Use headers-only for api and app keys for endpoints that support this. See [#189][], thanks [@ssc3][]
8
+ * [IMPROVEMENTS] Make `query` and `options` optional for `update_monitor` calls. See [#192][], thanks [@unclebconnor][]
9
+
3
10
  ## 1.36.0 / 2019-06-05
4
11
 
5
12
  * [BUGFIX] Pass the options as params to request, not body content. See [#157][], thanks [@wonko][]
@@ -246,6 +253,10 @@ This is the last release compatible with Ruby 1.8. ([EOL 2013-06-30](https://www
246
253
  [#172]: https://github.com/DataDog/dogapi-rb/issues/172
247
254
  [#173]: https://github.com/DataDog/dogapi-rb/issues/173
248
255
  [#174]: https://github.com/DataDog/dogapi-rb/issues/174
256
+ [#179]: https://github.com/DataDog/dogapi-rb/issues/179
257
+ [#188]: https://github.com/DataDog/dogapi-rb/issues/188
258
+ [#189]: https://github.com/DataDog/dogapi-rb/issues/189
259
+ [#192]: https://github.com/DataDog/dogapi-rb/issues/192
249
260
  [@ArjenSchwarz]: https://github.com/ArjenSchwarz
250
261
  [@Kaixiang]: https://github.com/Kaixiang
251
262
  [@TaylURRE]: https://github.com/TaylURRE
@@ -265,8 +276,12 @@ This is the last release compatible with Ruby 1.8. ([EOL 2013-06-30](https://www
265
276
  [@miknight]: https://github.com/miknight
266
277
  [@nots]: https://github.com/nots
267
278
  [@orien]: https://github.com/orien
279
+ [@platinummonkey]: https://github.com/platinummonkey
280
+ [@pschipitsch]: https://github.com/pschipitsch
268
281
  [@rmoriz]: https://github.com/rmoriz
282
+ [@ssc3]: https://github.com/ssc3
269
283
  [@treeder]: https://github.com/treeder
284
+ [@unclebconnor]: https://github.com/unclebconnor
270
285
  [@winebarrel]: https://github.com/winebarrel
271
286
  [@wonko]: https://github.com/wonko
272
287
  [@yyuu]: https://github.com/yyuu
data/README.rdoc CHANGED
@@ -1,8 +1,7 @@
1
1
  = Ruby Client for Datadog API
2
2
 
3
- {<img src="https://badge.fury.io/rb/dogapi.png" alt="Gem Version" />}[http://badge.fury.io/rb/dogapi]
4
-
5
- {<img src="https://travis-ci.org/DataDog/dogapi-rb.png?branch=master" alt="Build Status" />}[https://travis-ci.org/DataDog/dogapi-rb]
3
+ {<img src="https://badge.fury.io/rb/dogapi.svg" alt="Gem Version" />}[http://badge.fury.io/rb/dogapi]
4
+ {<img src="https://dev.azure.com/datadoghq/dogapi-rb/_apis/build/status/DataDog.dogapi-rb?branchName=master" alt="Build Status" />}[https://dev.azure.com/datadoghq/dogapi-rb/_build/latest?definitionId=16&branchName=master]
6
5
 
7
6
  The Ruby client is a library suitable for inclusion in existing Ruby projects or for development of standalone scripts. It provides an abstraction on top of Datadog's raw HTTP interface for reporting events and metrics.
8
7
 
@@ -166,6 +165,3 @@ data point you will need to pass a list of +Time+, +float+ pairs, instead of a s
166
165
  query = 'sum:metric.count{*}.as_count()'
167
166
 
168
167
  dog.get_points(query, from, to)
169
-
170
-
171
-
@@ -90,7 +90,7 @@ module Capistrano
90
90
  end
91
91
 
92
92
  def report()
93
- hostname = %x[hostname -f].strip
93
+ hostname = Dogapi.find_localhost
94
94
  user = Etc.getlogin
95
95
 
96
96
  # Lazy randomness
data/lib/dogapi/common.rb CHANGED
@@ -2,9 +2,11 @@ require 'cgi'
2
2
  require 'net/https'
3
3
  require 'socket'
4
4
  require 'uri'
5
+ require 'English'
5
6
 
6
7
  require 'rubygems'
7
8
  require 'multi_json'
9
+ require 'set'
8
10
 
9
11
  module Dogapi
10
12
 
@@ -68,6 +70,7 @@ module Dogapi
68
70
 
69
71
  # Superclass that deals with the details of communicating with the DataDog API
70
72
  class APIService
73
+ attr_reader :api_key, :application_key
71
74
  def initialize(api_key, application_key, silent=true, timeout=nil, endpoint=nil)
72
75
  @api_key = api_key
73
76
  @application_key = application_key
@@ -115,8 +118,10 @@ module Dogapi
115
118
  resp = nil
116
119
  connect do |conn|
117
120
  begin
118
- current_url = url + prepare_params(extra_params, with_app_key)
121
+ current_url = url + prepare_params(extra_params, url, with_app_key)
119
122
  req = method.new(current_url)
123
+ req['DD-API-KEY'] = @api_key
124
+ req['DD-APPLICATION-KEY'] = @application_key if with_app_key
120
125
 
121
126
  if send_json
122
127
  req.content_type = 'application/json'
@@ -131,15 +136,31 @@ module Dogapi
131
136
  end
132
137
  end
133
138
 
134
- def prepare_params(extra_params, with_app_key)
135
- params = { api_key: @api_key }
136
- params[:application_key] = @application_key if with_app_key
139
+ def prepare_params(extra_params, url, with_app_key)
140
+ params = set_api_and_app_keys_in_params(url, with_app_key)
137
141
  params = extra_params.merge params unless extra_params.nil?
138
142
  qs_params = params.map { |k, v| CGI.escape(k.to_s) + '=' + CGI.escape(v.to_s) }
139
143
  qs = '?' + qs_params.join('&')
140
144
  qs
141
145
  end
142
146
 
147
+ def set_api_and_app_keys_in_params(url, with_app_key)
148
+ set_of_urls = Set.new ['/api/v1/series',
149
+ '/api/v1/check_run',
150
+ '/api/v1/events',
151
+ '/api/v1/screen']
152
+
153
+ include_in_params = set_of_urls.include?(url)
154
+
155
+ if include_in_params
156
+ params = { api_key: @api_key }
157
+ params[:application_key] = @application_key if with_app_key
158
+ else
159
+ params = {}
160
+ end
161
+ return params
162
+ end
163
+
143
164
  def handle_response(resp)
144
165
  if resp.code == 204 || resp.body == '' || resp.body == 'null' || resp.body.nil?
145
166
  return resp.code, {}
@@ -163,11 +184,9 @@ module Dogapi
163
184
  @@hostname = nil
164
185
 
165
186
  def Dogapi.find_localhost
166
- begin
167
- # prefer hostname -f over Socket.gethostname
168
- @@hostname ||= %x[hostname -f].strip
169
- rescue
170
- raise 'Cannot determine local hostname via hostname -f'
171
- end
187
+ @@hostname ||= %x[hostname -f].strip
188
+ rescue SystemCallError
189
+ raise $ERROR_INFO unless $ERROR_INFO.class.name == 'Errno::ENOENT'
190
+ @@hostname = Addrinfo.getaddrinfo(Socket.gethostname, nil, nil, nil, nil, Socket::AI_CANONNAME).first.canonname
172
191
  end
173
192
  end
data/lib/dogapi/facade.rb CHANGED
@@ -95,6 +95,8 @@ module Dogapi
95
95
  @hosts_svc = Dogapi::V1::HostsService.new(@api_key, @application_key, silent, timeout, @datadog_host)
96
96
  @integration_svc = Dogapi::V1::IntegrationService.new(@api_key, @application_key, silent, timeout, @datadog_host)
97
97
  @usage_svc = Dogapi::V1::UsageService.new(@api_key, @application_key, silent, timeout, @datadog_host)
98
+ @service_level_objective_svc = Dogapi::V1::ServiceLevelObjectiveService.new(@api_key, @application_key, silent,
99
+ timeout, @datadog_host)
98
100
 
99
101
  # Support for Dashboard List API v2.
100
102
  @v2 = Dogapi::ClientV2.new(@api_key, @application_key, true, true, @datadog_host)
@@ -616,6 +618,58 @@ module Dogapi
616
618
  @monitor_svc.unmute_host(hostname)
617
619
  end
618
620
 
621
+ #
622
+ # SERVICE LEVEL OBJECTIVES
623
+ #
624
+
625
+ def create_service_level_objective(type: , name: , description: nil, tags: nil, thresholds: nil, numerator: nil,
626
+ denominator: nil, monitor_ids: nil, monitor_search: nil, groups: nil)
627
+ @service_level_objective_svc.create_service_level_objective(type: type, name: name, description: description,
628
+ tags: tags, thresholds: thresholds,
629
+ numerator: numerator, denominator: denominator,
630
+ monitor_ids: monitor_ids,
631
+ monitor_search: monitor_search, groups: groups)
632
+ end
633
+
634
+ def update_service_level_objective(slo_id: , type: , name: nil, description: nil, tags: nil, thresholds: nil,
635
+ numerator: nil, denominator: nil, monitor_ids: nil, monitor_search: nil,
636
+ groups: nil)
637
+ @service_level_objective_svc.update_service_level_objective(slo_id: slo_id, type: type, name: name,
638
+ description: description, tags: tags,
639
+ thresholds: thresholds, numerator: numerator,
640
+ denominator: denominator, monitor_ids: monitor_ids,
641
+ monitor_search: monitor_search, groups: groups)
642
+ end
643
+
644
+ def get_service_level_objective(slo_id)
645
+ @service_level_objective_svc.get_service_level_objective(slo_id)
646
+ end
647
+
648
+ def get_service_level_objective_history(slo_id, from_ts, to_ts)
649
+ @service_level_objective_svc.get_service_level_objective_history(slo_id, from_ts, to_ts)
650
+ end
651
+
652
+ def search_service_level_objective(slo_ids: nil, query: nil, offset: nil, limit: nil)
653
+ @service_level_objective_svc.search_service_level_objective(slo_ids: slo_ids, query: query, offset: offset,
654
+ limit: limit)
655
+ end
656
+
657
+ def can_delete_service_level_objective(slo_ids)
658
+ @service_level_objective_svc.can_delete_service_level_objective(slo_ids)
659
+ end
660
+
661
+ def delete_service_level_objective(slo_id)
662
+ @service_level_objective_svc.delete_service_level_objective(slo_id)
663
+ end
664
+
665
+ def delete_many_service_level_objective(slo_ids)
666
+ @service_level_objective_svc.delete_many_service_level_objective(slo_ids)
667
+ end
668
+
669
+ def delete_timeframes_service_level_objective(ops)
670
+ @service_level_objective_svc.delete_timeframes_service_level_objective(ops)
671
+ end
672
+
619
673
  #
620
674
  # SERVICE CHECKS
621
675
  #
data/lib/dogapi/v1.rb CHANGED
@@ -11,6 +11,7 @@ require 'dogapi/v1/monitor'
11
11
  require 'dogapi/v1/screenboard'
12
12
  require 'dogapi/v1/search'
13
13
  require 'dogapi/v1/service_check'
14
+ require 'dogapi/v1/service_level_objective'
14
15
  require 'dogapi/v1/snapshot'
15
16
  require 'dogapi/v1/tag'
16
17
  require 'dogapi/v1/user'
@@ -16,10 +16,15 @@ module Dogapi
16
16
  request(Net::HTTP::Post, "/api/#{API_VERSION}/monitor", nil, body, true)
17
17
  end
18
18
 
19
- def update_monitor(monitor_id, query, options)
20
- body = {
21
- 'query' => query,
22
- }.merge options
19
+ def update_monitor(monitor_id, query = nil, options = {})
20
+ body = {}.merge options
21
+ unless query.nil?
22
+ body = {
23
+ 'query' => query
24
+ }.merge body
25
+ warn '[DEPRECATION] query param is not required anymore and should be set to nil.'\
26
+ ' To update the query, set it in the options parameter instead'
27
+ end
23
28
 
24
29
  request(Net::HTTP::Put, "/api/#{API_VERSION}/monitor/#{monitor_id}", nil, body, true)
25
30
  end
@@ -0,0 +1,117 @@
1
+ require 'dogapi'
2
+
3
+ module Dogapi
4
+ class V1 # for namespacing
5
+
6
+ # Implements Service Level Objectives endpoints
7
+ class ServiceLevelObjectiveService < Dogapi::APIService
8
+
9
+ API_VERSION = 'v1'
10
+
11
+ def create_service_level_objective(type: , name: , description: nil, tags: nil, thresholds: nil,
12
+ numerator: nil, denominator: nil, monitor_ids: nil, monitor_search: nil,
13
+ groups: nil)
14
+ body = {
15
+ type: type,
16
+ name: name,
17
+ thresholds: thresholds
18
+ }
19
+ if type == 'metric'
20
+ body[:query] = {
21
+ numerator: numerator,
22
+ denominator: denominator
23
+ }
24
+ else
25
+ body[:monitor_search] = monitor_search unless monitor_search.nil?
26
+ body[:monitor_ids] = monitor_ids unless monitor_ids.nil?
27
+ body[:groups] = groups unless groups.nil?
28
+ end
29
+ body[:tags] = tags unless tags.nil?
30
+ body[:description] = description unless description.nil?
31
+
32
+ request(Net::HTTP::Post, "/api/#{API_VERSION}/slo", nil, body, true)
33
+ end
34
+
35
+ def update_service_level_objective(slo_id: , type: , name: nil, description: nil, tags: nil,
36
+ thresholds: nil, numerator: nil, denominator: nil, monitor_ids: nil,
37
+ monitor_search: nil, groups: nil)
38
+ body = {
39
+ type: type
40
+ }
41
+
42
+ body[:name] = name unless name.nil?
43
+
44
+ body[:thresholds] = thresholds unless thresholds.nil?
45
+
46
+ if type == 'metric'
47
+ if !numerator.nil? && !denominator.nil?
48
+ body[:query] = {
49
+ numerator: numerator,
50
+ denominator: denominator
51
+ }
52
+ end
53
+ else
54
+ body[:monitor_search] = monitor_search unless monitor_search.nil?
55
+ body[:monitor_ids] = monitor_ids unless monitor_ids.nil?
56
+ body[:groups] = groups unless groups.nil?
57
+ end
58
+ body[:tags] = tags unless tags.nil?
59
+ body[:description] = description unless description.nil?
60
+
61
+ request(Net::HTTP::Put, "/api/#{API_VERSION}/slo/#{slo_id}", nil, body, true)
62
+ end
63
+
64
+ def get_service_level_objective(slo_id)
65
+ request(Net::HTTP::Get, "/api/#{API_VERSION}/slo/#{slo_id}", nil, nil, false)
66
+ end
67
+
68
+ def search_service_level_objective(slo_ids: nil, query: nil, offset: nil, limit: nil)
69
+ params = {}
70
+ params[:offset] = offset unless offset.nil?
71
+ params[:limit] = limit unless limit.nil?
72
+ if !slo_ids.nil?
73
+ params[:ids] = slo_ids.join(',')
74
+ else
75
+ params[:query] = query
76
+ end
77
+
78
+ request(Net::HTTP::Get, "/api/#{API_VERSION}/slo/", params, nil, false)
79
+ end
80
+
81
+ def delete_service_level_objective(slo_id)
82
+ request(Net::HTTP::Delete, "/api/#{API_VERSION}/slo/#{slo_id}", nil, nil, false)
83
+ end
84
+
85
+ def delete_many_service_level_objective(slo_ids)
86
+ body = {
87
+ ids: slo_ids
88
+ }
89
+ request(Net::HTTP::Delete, "/api/#{API_VERSION}/slo/", nil, body, true)
90
+ end
91
+
92
+ def delete_timeframes_service_level_objective(ops)
93
+ # ops is a hash of slo_id: [<timeframe>] to delete
94
+ request(Net::HTTP::Post, "/api/#{API_VERSION}/slo/bulk_delete", nil, ops, true)
95
+ end
96
+
97
+ def get_service_level_objective_history(slo_id, from_ts, to_ts)
98
+ params = {
99
+ from_ts: from_ts,
100
+ to_ts: to_ts
101
+ }
102
+ request(Net::HTTP::Get, "/api/#{API_VERSION}/slo/#{slo_id}/history", params, nil, false)
103
+ end
104
+
105
+ def can_delete_service_level_objective(slo_ids)
106
+ params = {}
107
+ if slo_ids.is_a?Array
108
+ params[:ids] = slo_ids.join(',')
109
+ else
110
+ params[:ids] = slo_ids
111
+ end
112
+ request(Net::HTTP::Get, "/api/#{API_VERSION}/slo/can_delete", params, nil, false)
113
+ end
114
+
115
+ end
116
+ end
117
+ end
@@ -1,3 +1,3 @@
1
1
  module Dogapi
2
- VERSION = '1.36.0'
2
+ VERSION = '1.37.0'
3
3
  end
@@ -18,9 +18,7 @@ describe Dogapi::Client do
18
18
  stub_request(:put, /#{url}/).to_return(body: '{}').then.to_raise(StandardError)
19
19
  expect(dog.send(:update_comment, COMMENT_ID, options)).to eq ['200', {}]
20
20
 
21
- expect(WebMock).to have_requested(:put, url).with(
22
- query: default_query
23
- )
21
+ expect(WebMock).to have_requested(:put, url)
24
22
  end
25
23
  end
26
24
 
@@ -12,9 +12,7 @@ describe Dogapi::APIService do
12
12
  stub_request(:get, /#{url}/).to_return(body: '{}').then.to_raise(StandardError)
13
13
  expect(service.request(Net::HTTP::Get, '/api/v1/awesome', nil, nil, true, true)).to eq(['200', {}])
14
14
 
15
- expect(WebMock).to have_requested(:get, url).with(
16
- query: default_query
17
- )
15
+ expect(WebMock).to have_requested(:get, url)
18
16
  end
19
17
  end
20
18
  context 'and it is down' do
@@ -22,9 +20,7 @@ describe Dogapi::APIService do
22
20
  stub_request(:get, /#{url}/).to_timeout
23
21
  expect(service.request(Net::HTTP::Get, '/api/v1/awesome', nil, nil, true, true)).to eq([-1, {}])
24
22
 
25
- expect(WebMock).to have_requested(:get, url).with(
26
- query: default_query
27
- )
23
+ expect(WebMock).to have_requested(:get, url)
28
24
  end
29
25
  end
30
26
  end
@@ -0,0 +1,71 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Dogapi::Client do
4
+ SLO_ID = '42424242424242424242424242424242'.freeze
5
+ SLO_TYPE = 'metric'.freeze
6
+ SLO_NAME = 'test slo'.freeze
7
+ SLO_DESCRIPTION = 'test slo description'.freeze
8
+ SLO_QUERY_NUMERATOR = 'sum:test.metric.metric{type:good}.as_count()'.freeze
9
+ SLO_QUERY_DENOMINATOR = 'sum:test.metric.metric{*}.as_count()'.freeze
10
+ SLO_TAGS = ['type:test'].freeze
11
+ SLO_THRESHOLDS = [{ timeframe: '7d', target: 90 }, { timeframe: '30d', target: 95 }].freeze
12
+
13
+ describe '#create_service_level_objective' do
14
+ it_behaves_like 'an api method with named args',
15
+ :create_service_level_objective, {type: SLO_TYPE, name: SLO_NAME, description: SLO_DESCRIPTION,
16
+ tags: SLO_TAGS, thresholds: SLO_THRESHOLDS,
17
+ numerator: SLO_QUERY_NUMERATOR,
18
+ denominator: SLO_QUERY_DENOMINATOR},
19
+ :post, '/slo', 'type' => SLO_TYPE, 'name' => SLO_NAME, 'thresholds' => SLO_THRESHOLDS,
20
+ 'query' => { numerator: SLO_QUERY_NUMERATOR, denominator: SLO_QUERY_DENOMINATOR },
21
+ 'tags' => SLO_TAGS, 'description' => SLO_DESCRIPTION
22
+ end
23
+
24
+ describe '#update_service_level_objective' do
25
+ it_behaves_like 'an api method with named args',
26
+ :update_service_level_objective, {slo_id: SLO_ID, type: SLO_TYPE, name: SLO_NAME},
27
+ :put, "/slo/#{SLO_ID}", 'type' => SLO_TYPE, 'name' => SLO_NAME
28
+ end
29
+
30
+ describe '#get_service_level_objective' do
31
+ it_behaves_like 'an api method',
32
+ :get_service_level_objective, [SLO_ID],
33
+ :get, "/slo/#{SLO_ID}"
34
+ end
35
+
36
+ describe '#get_service_level_objective_history' do
37
+ it_behaves_like 'an api method with params',
38
+ :get_service_level_objective_history, [SLO_ID],
39
+ :get, "/slo/#{SLO_ID}/history", 'from_ts' => 0, 'to_ts' => 1000000
40
+ end
41
+
42
+ describe '#can_delete_service_level_objective' do
43
+ it_behaves_like 'an api method with params',
44
+ :can_delete_service_level_objective, [],
45
+ :get, "/slo/can_delete", 'ids' => [SLO_ID]
46
+ end
47
+
48
+ describe '#search_service_level_objective' do
49
+ it_behaves_like 'an api method with named args making params',
50
+ :search_service_level_objective, {slo_ids: [SLO_ID]},
51
+ :get, '/slo/', 'ids' => SLO_ID
52
+ end
53
+
54
+ describe '#delete_service_level_objective' do
55
+ it_behaves_like 'an api method',
56
+ :delete_service_level_objective, [SLO_ID],
57
+ :delete, "/slo/#{SLO_ID}"
58
+ end
59
+
60
+ describe '#delete_many_service_level_objective' do
61
+ it_behaves_like 'an api method',
62
+ :delete_many_service_level_objective, [[SLO_ID]],
63
+ :delete, '/slo/', 'ids' => [SLO_ID]
64
+ end
65
+
66
+ describe '#delete_timeframes_service_level_objective' do
67
+ it_behaves_like 'an api method',
68
+ :delete_timeframes_service_level_objective, [{ SLO_ID => ['7d'] }],
69
+ :post, '/slo/bulk_delete', SLO_ID => ['7d']
70
+ end
71
+ end
data/spec/spec_helper.rb CHANGED
@@ -37,12 +37,27 @@ module SpecDog
37
37
  body = MultiJson.dump(body) if body
38
38
 
39
39
  expect(WebMock).to have_requested(request, /#{url}|#{old_url}/).with(
40
- query: default_query,
41
40
  body: body
42
41
  )
43
42
  end
44
43
  end
45
44
 
45
+ shared_examples 'an api method with named args' do |command, args, request, endpoint, body|
46
+ it 'queries the api' do
47
+ url = api_url + endpoint
48
+ old_url = old_api_url + endpoint
49
+ stub_request(request, /#{url}|#{old_url}/).to_return(body: '{}').then.to_raise(StandardError)
50
+ expect(dog.send(command, **args)).to eq ['200', {}]
51
+
52
+ body = MultiJson.dump(body) if body
53
+
54
+ expect(WebMock).to have_requested(request, /#{url}|#{old_url}/).with(
55
+ # ignore query: default_query -- here as in the test it's never properly included
56
+ body: body
57
+ )
58
+ end
59
+ end
60
+
46
61
  shared_examples 'an api method with options' do |command, args, request, endpoint, body|
47
62
  include_examples 'an api method', command, args, request, endpoint, body
48
63
  it 'queries the api with options' do
@@ -55,7 +70,6 @@ module SpecDog
55
70
  body = MultiJson.dump(body ? (body.merge options) : options)
56
71
 
57
72
  expect(WebMock).to have_requested(request, /#{url}|#{old_url}/).with(
58
- query: default_query,
59
73
  body: body
60
74
  )
61
75
  end
@@ -67,7 +81,7 @@ module SpecDog
67
81
  stub_request(request, /#{url}/).to_return(body: '{}').then.to_raise(StandardError)
68
82
  expect(dog.send(command, *args, *params.values)).to eq ['200', {}]
69
83
  params.each { |k, v| params[k] = v.join(',') if v.is_a? Array }
70
- params = params.merge default_query
84
+ params = params
71
85
 
72
86
  expect(WebMock).to have_requested(request, url).with(
73
87
  query: params
@@ -75,6 +89,20 @@ module SpecDog
75
89
  end
76
90
  end
77
91
 
92
+ shared_examples 'an api method with named args making params' do |command, args, request, endpoint, params|
93
+ it 'queries the api with params' do
94
+ url = api_url + endpoint
95
+ stub_request(request, /#{url}/).to_return(body: '{}').then.to_raise(StandardError)
96
+ expect(dog.send(command, **args)).to eq ['200', {}]
97
+ params.each { |k, v| params[k] = v.join(',') if v.is_a? Array }
98
+ # hack/note: do not merge with default_query for this test case
99
+
100
+ expect(WebMock).to have_requested(request, url).with(
101
+ query: params
102
+ )
103
+ end
104
+ end
105
+
78
106
  shared_examples 'an api method with optional params' do |command, args, request, endpoint, opt_params|
79
107
  include_examples 'an api method', command, args, request, endpoint
80
108
  it 'queries the api with optional params' do
@@ -83,7 +111,7 @@ module SpecDog
83
111
  expect(dog.send(command, *args, opt_params)).to eq ['200', {}]
84
112
 
85
113
  opt_params.each { |k, v| opt_params[k] = v.join(',') if v.is_a? Array }
86
- params = opt_params.merge default_query
114
+ params = opt_params
87
115
 
88
116
  expect(WebMock).to have_requested(request, url).with(
89
117
  query: params
@@ -101,7 +129,6 @@ module SpecDog
101
129
  body = MultiJson.dump(body) if body
102
130
 
103
131
  expect(WebMock).to have_requested(request, url).with(
104
- query: default_query,
105
132
  body: body
106
133
  )
107
134
  end
@@ -117,7 +144,6 @@ module SpecDog
117
144
  body = MultiJson.dump(body ? (body.merge options) : options)
118
145
 
119
146
  expect(WebMock).to have_requested(request, url).with(
120
- query: default_query,
121
147
  body: body
122
148
  )
123
149
  end
@@ -129,7 +155,7 @@ module SpecDog
129
155
  stub_request(request, /#{url}/).to_return(body: '{}').then.to_raise(StandardError)
130
156
  expect(dog2.send(command, *args, *params.values)).to eq ['200', {}]
131
157
  params.each { |k, v| params[k] = v.join(',') if v.is_a? Array }
132
- params = params.merge default_query
158
+ params = params
133
159
 
134
160
  expect(WebMock).to have_requested(request, url).with(
135
161
  query: params
@@ -144,7 +170,7 @@ module SpecDog
144
170
  stub_request(request, /#{url}/).to_return(body: '{}').then.to_raise(StandardError)
145
171
  expect(dog2.send(command, *args, opt_params)).to eq ['200', {}]
146
172
  opt_params.each { |k, v| opt_params[k] = v.join(',') if v.is_a? Array }
147
- params = opt_params.merge default_query
173
+ params = opt_params
148
174
 
149
175
  expect(WebMock).to have_requested(request, url).with(
150
176
  query: params
@@ -48,6 +48,44 @@ describe 'Common' do
48
48
  expect(conn.port).to eq 443
49
49
  end
50
50
  end
51
+
52
+ it 'respects http headers' do
53
+ service = Dogapi::APIService.new('api_key', 'app_key', true, nil, 'https://app.example.com')
54
+
55
+ expect(service.api_key).to eq 'api_key'
56
+ expect(service.application_key).to eq 'app_key'
57
+ end
58
+
59
+ it 'sets api and app keys in params' do
60
+ service = Dogapi::APIService.new('api_key', 'app_key', true, nil, 'https://app.example.com')
61
+
62
+ urls = ['/api/v1/series',
63
+ '/api/v1/check_run',
64
+ '/api/v1/events',
65
+ '/api/v1/screen']
66
+
67
+ urls.each do |url|
68
+ params = service.set_api_and_app_keys_in_params(url, true)
69
+ expect(params).to have_key(:api_key)
70
+ expect(params[:api_key]).to eq service.api_key
71
+ expect(params).to have_key(:application_key)
72
+ expect(params[:application_key]).to eq service.application_key
73
+ end
74
+ end
75
+
76
+ it 'does not set api and app keys in params' do
77
+ service = Dogapi::APIService.new('api_key', 'app_key', true, nil, 'https://app.example.com')
78
+
79
+ urls = ['/api/v2/series',
80
+ '/api/v1/random_endpoint',
81
+ '/api/v1/dashboards',
82
+ '/api/v2/users']
83
+
84
+ urls.each do |url|
85
+ params = service.set_api_and_app_keys_in_params(url, true)
86
+ expect(params).to eq({})
87
+ end
88
+ end
51
89
  end
52
90
  end
53
91
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dogapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.36.0
4
+ version: 1.37.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-05 00:00:00.000000000 Z
11
+ date: 2019-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -74,12 +74,12 @@ extensions: []
74
74
  extra_rdoc_files:
75
75
  - README.rdoc
76
76
  files:
77
+ - ".azure-pipelines/all.yml"
77
78
  - ".gitignore"
78
79
  - ".rspec"
79
80
  - ".rubocop.yml"
80
81
  - ".rubocop_todo.yml"
81
82
  - ".tailor"
82
- - ".travis.yml"
83
83
  - CHANGELOG.md
84
84
  - Gemfile
85
85
  - LICENSE
@@ -114,6 +114,7 @@ files:
114
114
  - lib/dogapi/v1/screenboard.rb
115
115
  - lib/dogapi/v1/search.rb
116
116
  - lib/dogapi/v1/service_check.rb
117
+ - lib/dogapi/v1/service_level_objective.rb
117
118
  - lib/dogapi/v1/snapshot.rb
118
119
  - lib/dogapi/v1/tag.rb
119
120
  - lib/dogapi/v1/usage.rb
@@ -136,6 +137,7 @@ files:
136
137
  - spec/integration/screenboard_spec.rb
137
138
  - spec/integration/search_spec.rb
138
139
  - spec/integration/service_check_spec.rb
140
+ - spec/integration/service_level_objective_spec.rb
139
141
  - spec/integration/snapshot_spec.rb
140
142
  - spec/integration/tag_spec.rb
141
143
  - spec/integration/usage_spec.rb
@@ -174,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
176
  version: '0'
175
177
  requirements: []
176
178
  rubyforge_project:
177
- rubygems_version: 2.6.8
179
+ rubygems_version: 2.7.6
178
180
  signing_key:
179
181
  specification_version: 4
180
182
  summary: Ruby bindings for Datadog's API
@@ -194,6 +196,7 @@ test_files:
194
196
  - spec/integration/screenboard_spec.rb
195
197
  - spec/integration/search_spec.rb
196
198
  - spec/integration/service_check_spec.rb
199
+ - spec/integration/service_level_objective_spec.rb
197
200
  - spec/integration/snapshot_spec.rb
198
201
  - spec/integration/tag_spec.rb
199
202
  - spec/integration/usage_spec.rb
data/.travis.yml DELETED
@@ -1,15 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.0
4
- - 2.1
5
- - 2.2
6
- - 2.3
7
- - 2.4
8
- - 2.5
9
- script: bundle exec rake $TASK
10
- env:
11
- - TASK=spec
12
- matrix:
13
- include:
14
- env: TASK=rubocop
15
- rvm: 2.5