kennel 1.98.0 → 1.99.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
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