kennel 1.98.0 → 1.99.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: c3a596895475dbc4577d69916cb277fecfb45add58faf0bf1b6e06d314f161c3
4
- data.tar.gz: 1f618cd4aa9a8eed2ad38ec067876e21f6d3f148d541a96bcc9afaa79619a48d
3
+ metadata.gz: 0363ce2c85e194b4c6eca7e657a614d3eb0e27d7c0a5f4a55871bf39fc90f5f9
4
+ data.tar.gz: 075f01f5fa4f153f1a8c07ec000b7abf246e3c0dd9082d5709661240191b07f1
5
5
  SHA512:
6
- metadata.gz: 4324951f97ef28dd0a5081231ea6aa676b81c3f405598dcf683d0ad5abc5dc346333d0e5029e84c5c742aa896b90aa1c11cd5891483f5c3bb5e67f0bec6ba6a8
7
- data.tar.gz: 44e1c9af9868579db4497c2a9807a814bc6a78e49956c165d0b954fd4cbc0d6511ee046a43777354ef4f18c79ab70e5ae5061468ab5fd410aab5f55f1f219af2
6
+ metadata.gz: 6834defb05ea8844a19fdaa80a8e3cb7154305bbf3dbc6a66c24d76cc4b050305020c14ca7712a105d1514c421cf4a1f4674b9dfccc93b694e17daba8d8abf8b
7
+ data.tar.gz: 87f2c790faa21b2e63beaca026c565e6c940aa9dae0cc624b7060d81ed4b6cfce7894c77ccf56b60751a9fb3d1ed0b1dfc2c2c27a893ea88e0097b2d44138a05
data/Readme.md CHANGED
@@ -16,7 +16,6 @@ Manage Datadog Monitors / Dashboards / Slos as code
16
16
  ![](template/github/screen.png?raw=true)
17
17
 
18
18
  ### Example code
19
-
20
19
  ```Ruby
21
20
  # teams/foo.rb
22
21
  module Teams
@@ -52,9 +51,7 @@ end
52
51
  ```
53
52
 
54
53
  <!-- NOT IN template/Readme.md -->
55
-
56
54
  ## Installation
57
-
58
55
  - create a new private `kennel` repo for your organization (do not fork this repo)
59
56
  - use the template folder as starting point:
60
57
  ```Bash
@@ -70,14 +67,12 @@ end
70
67
  <!-- NOT IN -->
71
68
 
72
69
  ## Structure
73
-
74
70
  - `projects/` monitors/dashboards/etc scoped by project
75
71
  - `teams/` team definitions
76
72
  - `parts/` monitors/dashboards/etc that are used by multiple projects
77
73
  - `generated/` projects as json, to show current state and proposed changes in PRs
78
74
 
79
75
  ## Workflows
80
-
81
76
  <!-- ONLY IN template/Readme.md
82
77
  ### Setup
83
78
  - clone the repo
@@ -91,7 +86,6 @@ end
91
86
  -->
92
87
 
93
88
  ### Adding a team
94
-
95
89
  - `mention` is used for all team monitors via `super()`
96
90
  - `renotify_interval` is used for all team monitors (defaults to `0` / off)
97
91
  - `tags` is used for all team monitors/dashboards (defaults to `team:<team-name>`)
@@ -208,14 +202,30 @@ When manually creating to import, it is best to remove the `id` and delete the m
208
202
  When an `id` is set and the original resource is deleted, kennel will fail to update,
209
203
  removing the `id` will cause kennel to create a new resource in datadog.
210
204
 
205
+ ### Organizing many projects
206
+ Having many projects (and their sub-resources) can quickly get out of hand.
211
207
 
212
- ### Skipping validations
208
+ Use this class structure to keep things organized:
209
+ ```Ruby
210
+ # projects/project_a/base.rb
211
+ module ProjectA
212
+ class Base < Kennel::Models::Project
213
+ defaults(
214
+ kennel_id: -> { "project_a" },
215
+ ...
216
+
217
+ # projects/project_a/monitors/foo_alert.rb
218
+ module ProjectA
219
+ module Monitors
220
+ class FooAlert < Kennel::Models::Monitor
221
+ ...
222
+ ```
213
223
 
224
+ ### Skipping validations
214
225
  Some validations might be too strict for your usecase or just wrong, please [open an issue](https://github.com/grosser/kennel/issues) and
215
226
  to unblock use the `validate: -> { false }` option.
216
227
 
217
228
  ### Linking resources with kennel_id
218
-
219
229
  Link resources with their kennel_id in the format `project kennel_id` + `:` + `resource kennel_id`,
220
230
  this should be used to create dependent resources like monitor + slos,
221
231
  so they can be created in a single update and can be re-created if any of them is deleted.
@@ -230,13 +240,11 @@ so they can be created in a single update and can be re-created if any of them i
230
240
  |Slo|monitor|`monitor_ids: -> ["foo:bar"]`|
231
241
 
232
242
  ### Debugging changes locally
233
-
234
243
  - rebase on updated `master` to not undo other changes
235
244
  - figure out project name by converting the class name to snake-case
236
245
  - run `PROJECT=foo bundle exec rake kennel:update_datadog` to test changes for a single project (monitors: remove mentions while debugging to avoid alert spam)
237
246
 
238
247
  ### Reuse
239
-
240
248
  Add to `parts/<folder>`.
241
249
 
242
250
  ```Ruby
@@ -266,15 +274,12 @@ end
266
274
  ## Helpers
267
275
 
268
276
  ### Listing un-muted alerts
269
-
270
277
  Run `rake kennel:alerts TAG=service:my-service` to see all un-muted alerts for a given datadog monitor tag.
271
278
 
272
279
  ### Validating mentions work
273
-
274
280
  `rake kennel:validate_mentions` should run as part of CI
275
281
 
276
282
  ### Grepping through all of datadog
277
-
278
283
  ```Bash
279
284
  rake kennel:dump > tmp/dump
280
285
  cat tmp/dump | grep foo
@@ -289,7 +294,6 @@ https://foo.datadog.com/monitor/123
289
294
  ```
290
295
 
291
296
  ### Find all monitors with No-Data
292
-
293
297
  `rake kennel:nodata TAG=team:foo`
294
298
 
295
299
  <!-- NOT IN template/Readme.md -->
@@ -297,11 +301,9 @@ https://foo.datadog.com/monitor/123
297
301
  ## Development
298
302
 
299
303
  ### Benchmarking
300
-
301
304
  Setting `FORCE_GET_CACHE=true` will cache all get requests, which makes benchmarking improvements more reliable.
302
305
 
303
306
  ### Integration testing
304
-
305
307
  ```Bash
306
308
  rake play
307
309
  cd template
@@ -214,27 +214,47 @@ module Kennel
214
214
  end
215
215
 
216
216
  if ["query alert", "service check"].include?(type) # TODO: most likely more types need this
217
- # verify is_match/is_exact_match uses available variables
218
- message = data.fetch(:message)
219
- used = message.scan(/{{\s*([#^]is(?:_exact)?_match)\s*([^\s}]+)/)
220
- if used.any?
221
- allowed = data.fetch(:query)[/by\s*[({]([^})]+)[})]/, 1]
222
- .to_s.gsub(/["']/, "").split(/\s*,\s*/)
223
- .map! { |w| %("#{w}.name") }
224
- used.uniq.each do |match, group|
225
- next if allowed.include?(group)
226
- invalid!(
227
- "#{match} used with #{group}, but can only be used with #{allowed.join(", ")}. " \
228
- "Group the query by #{group.sub(".name", "").tr('"', "")} or change the #{match}"
229
- )
230
- end
231
- end
217
+ validate_message_variables(data)
232
218
  end
233
219
 
234
220
  unless ALLOWED_PRIORITY_CLASSES.include?(priority.class)
235
221
  invalid! "priority needs to be an Integer"
236
222
  end
237
223
  end
224
+
225
+ # verify is_match/is_exact_match and {{foo.name}} uses available variables
226
+ def validate_message_variables(data)
227
+ message = data.fetch(:message)
228
+
229
+ used =
230
+ message.scan(/{{\s*(?:[#^]is(?:_exact)?_match)\s*"([^\s}]+)"/) + # {{#is_match "environment.name" "production"}}
231
+ message.scan(/{{\s*([^}]+\.name)\s*}}/) # Pod {{pod.name}} failed
232
+ return if used.empty?
233
+ used.flatten!(1)
234
+ used.uniq!
235
+
236
+ # TODO
237
+ # - also match without by
238
+ # - separate parsers for query and service
239
+ # - service must always allow `host`, maybe others
240
+ return unless match = data.fetch(:query).match(/(?:{([^}]*)}\s*)?by\s*[({]([^})]+)[})]/)
241
+
242
+ allowed =
243
+ match[1].to_s.split(/\s*,\s*/).map { |k| k.split(":", 2)[-2] } + # {a:b} -> a TODO: does not work for service check
244
+ match[2].to_s.gsub(/["']/, "").split(/\s*,\s*/) # by {a} -> a
245
+
246
+ allowed.compact!
247
+ allowed.uniq!
248
+ allowed.map! { |w| "#{w.tr('"', "")}.name" }
249
+
250
+ forbidden = used - allowed
251
+ return if forbidden.empty?
252
+
253
+ invalid! <<~MSG.rstrip
254
+ Used #{forbidden.join(", ")} in the message, but can only be used with #{allowed.join(", ")}.
255
+ Group or filter the query by #{forbidden.map { |f| f.sub(".name", "") }.join(", ")} to use it.
256
+ MSG
257
+ end
238
258
  end
239
259
  end
240
260
  end
@@ -26,7 +26,7 @@ module Kennel
26
26
  type: type,
27
27
  subtype: subtype,
28
28
  options: options,
29
- name: name,
29
+ name: "#{name}#{LOCK}",
30
30
  locations: locations == :all ? LOCATIONS : locations
31
31
  }
32
32
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Kennel
3
- VERSION = "1.98.0"
3
+ VERSION = "1.99.0"
4
4
  end
data/template/Readme.md CHANGED
@@ -16,7 +16,6 @@ Manage Datadog Monitors / Dashboards / Slos as code
16
16
  ![](github/screen.png?raw=true)
17
17
 
18
18
  ### Example code
19
-
20
19
  ```Ruby
21
20
  # teams/foo.rb
22
21
  module Teams
@@ -53,14 +52,12 @@ end
53
52
 
54
53
 
55
54
  ## Structure
56
-
57
55
  - `projects/` monitors/dashboards/etc scoped by project
58
56
  - `teams/` team definitions
59
57
  - `parts/` monitors/dashboards/etc that are used by multiple projects
60
58
  - `generated/` projects as json, to show current state and proposed changes in PRs
61
59
 
62
60
  ## Workflows
63
-
64
61
  ### Setup
65
62
  - clone the repo
66
63
  - `gem install bundler && bundle install`
@@ -72,7 +69,6 @@ end
72
69
  - verify it works by running `rake plan`, it might show some diff, but should not crash
73
70
 
74
71
  ### Adding a team
75
-
76
72
  - `mention` is used for all team monitors via `super()`
77
73
  - `renotify_interval` is used for all team monitors (defaults to `0` / off)
78
74
  - `tags` is used for all team monitors/dashboards (defaults to `team:<team-name>`)
@@ -189,14 +185,30 @@ When manually creating to import, it is best to remove the `id` and delete the m
189
185
  When an `id` is set and the original resource is deleted, kennel will fail to update,
190
186
  removing the `id` will cause kennel to create a new resource in datadog.
191
187
 
188
+ ### Organizing many projects
189
+ Having many projects (and their sub-resources) can quickly get out of hand.
192
190
 
193
- ### Skipping validations
191
+ Use this class structure to keep things organized:
192
+ ```Ruby
193
+ # projects/project_a/base.rb
194
+ module ProjectA
195
+ class Base < Kennel::Models::Project
196
+ defaults(
197
+ kennel_id: -> { "project_a" },
198
+ ...
199
+
200
+ # projects/project_a/monitors/foo_alert.rb
201
+ module ProjectA
202
+ module Monitors
203
+ class FooAlert < Kennel::Models::Monitor
204
+ ...
205
+ ```
194
206
 
207
+ ### Skipping validations
195
208
  Some validations might be too strict for your usecase or just wrong, please [open an issue](https://github.com/grosser/kennel/issues) and
196
209
  to unblock use the `validate: -> { false }` option.
197
210
 
198
211
  ### Linking resources with kennel_id
199
-
200
212
  Link resources with their kennel_id in the format `project kennel_id` + `:` + `resource kennel_id`,
201
213
  this should be used to create dependent resources like monitor + slos,
202
214
  so they can be created in a single update and can be re-created if any of them is deleted.
@@ -211,13 +223,11 @@ so they can be created in a single update and can be re-created if any of them i
211
223
  |Slo|monitor|`monitor_ids: -> ["foo:bar"]`|
212
224
 
213
225
  ### Debugging changes locally
214
-
215
226
  - rebase on updated `master` to not undo other changes
216
227
  - figure out project name by converting the class name to snake-case
217
228
  - run `PROJECT=foo bundle exec rake kennel:update_datadog` to test changes for a single project (monitors: remove mentions while debugging to avoid alert spam)
218
229
 
219
230
  ### Reuse
220
-
221
231
  Add to `parts/<folder>`.
222
232
 
223
233
  ```Ruby
@@ -247,15 +257,12 @@ end
247
257
  ## Helpers
248
258
 
249
259
  ### Listing un-muted alerts
250
-
251
260
  Run `rake kennel:alerts TAG=service:my-service` to see all un-muted alerts for a given datadog monitor tag.
252
261
 
253
262
  ### Validating mentions work
254
-
255
263
  `rake kennel:validate_mentions` should run as part of CI
256
264
 
257
265
  ### Grepping through all of datadog
258
-
259
266
  ```Bash
260
267
  rake kennel:dump > tmp/dump
261
268
  cat tmp/dump | grep foo
@@ -270,6 +277,5 @@ https://foo.datadog.com/monitor/123
270
277
  ```
271
278
 
272
279
  ### Find all monitors with No-Data
273
-
274
280
  `rake kennel:nodata TAG=team:foo`
275
281
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kennel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.98.0
4
+ version: 1.99.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-29 00:00:00.000000000 Z
11
+ date: 2021-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday