kennel 1.62.0 → 1.66.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: 46e59b9fbb4e26336ff51f94150419fbe3dfdcc6754c05f425b6ce7059c03bb5
4
- data.tar.gz: 10e2eed990407521ca3ae5923387f7e893d52e98af8e739b565ca6cd85c50d2a
3
+ metadata.gz: 0bfed774a67cfbd29eea6800403e1a61c16a182e96ea69fe730770c2e4fa392c
4
+ data.tar.gz: 2bd236d4dc087fc81e39282d5b7efa26b3422565fd75a62a601966a02a6c8a8c
5
5
  SHA512:
6
- metadata.gz: 31de1f04bce918536b6c752e73e06e398e9ecef92bf6b67265fd79939f1e23f278f549ac668f88f7391626c248d6db8b2a8193ca3cc19c69bb2a080a910a0276
7
- data.tar.gz: ace9e229690a761b0b11e7b95a83a24fd93c777ddd617deb1fd7a31c58652126bc4993ca0715f4a8d8546e5190fd41d814593ac337e4f2ea58617831c2f2d704
6
+ metadata.gz: 47944bbb4119eb15b998aaacafa53a2738b18031017ba8b0688f5470ce4067e263360f77b9ebd18348398ce328fb75b99ed5805a2ab3d4df56e6fb38180aa955
7
+ data.tar.gz: 575bc37d35aec741c6479c1f8370992305f1c8f17058d52cfd257f7f638e3663954c88e5d14cf2d045fcbd6ddd21bb573039032ff6171f3f0e30dc9bf381a840
data/Readme.md CHANGED
@@ -2,11 +2,12 @@
2
2
 
3
3
  ![](template/github/cage.jpg?raw=true)
4
4
 
5
- Keep datadog monitors/dashboards/etc in version control, avoid chaotic management via UI.
5
+ Manage datadog monitors/dashboards/slos as code
6
6
 
7
- - Documented, reusable, automated, and searchable configuration
7
+ - Documented, reusable, and searchable
8
8
  - Changes are PR reviewed and auditable
9
- - Automated deletion when removed from code
9
+ - Updating shows diff before applying
10
+ - Automated import of existing monitors/dashboards/slos
10
11
 
11
12
  ![](template/github/screen.png?raw=true)
12
13
  <!-- NOT IN template/Readme.md -->
@@ -183,6 +184,14 @@ Run `rake kennel:alerts TAG=service:my-service` to see all un-muted alerts for a
183
184
 
184
185
  `rake kennel:validate_mentions` should run as part of CI
185
186
 
187
+ ### Grepping through all of datadog
188
+
189
+ `TYPE=monitor rake kennel:dump`
190
+
191
+ ### Find all monitors with No-Data
192
+
193
+ `rake kennel:nodata TAG=team:foo`
194
+
186
195
  ## Examples
187
196
 
188
197
  ### Reusable monitors/dashes/etc
@@ -219,10 +228,10 @@ end
219
228
  ```Bash
220
229
  rake play
221
230
  cd template
222
- rake kennel:plan
231
+ rake plan
223
232
  ```
224
233
 
225
- Then make changes to play around, do not commit changes and make sure to revert with a `rake kennel:update` after deleting everything.
234
+ Then make changes to play around, do not commit changes and make sure to revert with a `rake kennel:update_datadog` after deleting everything.
226
235
 
227
236
  To make changes via the UI, make a new free datadog account and use it's credentaisl instead.
228
237
 
data/lib/kennel/api.rb CHANGED
@@ -43,12 +43,12 @@ module Kennel
43
43
  end
44
44
 
45
45
  def delete(api_resource, id)
46
- request :delete, "/api/v1/#{api_resource}/#{id}"
46
+ request :delete, "/api/v1/#{api_resource}/#{id}", ignore_404: true
47
47
  end
48
48
 
49
49
  private
50
50
 
51
- def request(method, path, body: nil, params: {})
51
+ def request(method, path, body: nil, params: {}, ignore_404: false)
52
52
  params = params.merge(application_key: @app_key, api_key: @api_key)
53
53
  query = Faraday::FlatParamsEncoder.encode(params)
54
54
  response = nil
@@ -66,7 +66,7 @@ module Kennel
66
66
  Kennel.err.puts "Retrying on server error #{response.status} for #{path}"
67
67
  end
68
68
 
69
- unless response.success?
69
+ if !response.success? && (response.status != 404 || !ignore_404)
70
70
  message = +"Error #{response.status} during #{method.upcase} #{path}\n"
71
71
  message << "request:\n#{JSON.pretty_generate(body)}\nresponse:\n" if body
72
72
  message << response.body
@@ -32,11 +32,12 @@ module Kennel
32
32
  private
33
33
 
34
34
  def load_data
35
- @data = begin
36
- Marshal.load(File.read(@file)) # rubocop:disable Security/MarshalLoad
37
- rescue StandardError
38
- {}
39
- end
35
+ @data =
36
+ begin
37
+ Marshal.load(File.read(@file)) # rubocop:disable Security/MarshalLoad
38
+ rescue StandardError
39
+ {}
40
+ end
40
41
  end
41
42
 
42
43
  def persist
@@ -7,13 +7,13 @@ module Kennel
7
7
  class << self
8
8
  def report(token, &block)
9
9
  return yield unless token
10
- new(token).report(&block)
10
+ new(token, Utils.capture_sh("git rev-parse HEAD").strip).report(&block)
11
11
  end
12
12
  end
13
13
 
14
- def initialize(token)
14
+ def initialize(token, git_sha)
15
15
  @token = token
16
- @git_sha = Utils.capture_sh("git rev-parse HEAD").strip
16
+ @git_sha = git_sha
17
17
  origin = ENV["PROJECT_REPOSITORY"] || Utils.capture_sh("git remote -v").split("\n").first
18
18
  @repo_part = origin[%r{github\.com[:/](.+?)(\.git|$)}, 1] || raise("no origin found")
19
19
  end
@@ -27,8 +27,6 @@ module Kennel
27
27
  comment "```\n#{output || "Error"}\n```"
28
28
  end
29
29
 
30
- private
31
-
32
30
  # https://developer.github.com/v3/repos/comments/#create-a-commit-comment
33
31
  def comment(body)
34
32
  # truncate to maximum allowed comment size for github to avoid 422
@@ -39,6 +37,8 @@ module Kennel
39
37
  post "commits/#{@git_sha}/comments", body: body
40
38
  end
41
39
 
40
+ private
41
+
42
42
  def post(path, data)
43
43
  url = "https://api.github.com/repos/#{@repo_part}/#{path}"
44
44
  response = Faraday.post(url, data.to_json, authorization: "token #{@token}")
@@ -21,7 +21,7 @@ module Kennel
21
21
  self.class.name
22
22
  end
23
23
 
24
- def to_json
24
+ def to_json # rubocop:disable Lint/ToJSON
25
25
  raise NotImplementedError, "Use as_json"
26
26
  end
27
27
  end
@@ -8,7 +8,7 @@ module Kennel
8
8
  QUERY_INTERVALS = ["1m", "5m", "10m", "15m", "30m", "1h", "2h", "4h", "1d"].freeze
9
9
  OPTIONAL_SERVICE_CHECK_THRESHOLDS = [:ok, :warning].freeze
10
10
  READONLY_ATTRIBUTES = superclass::READONLY_ATTRIBUTES + [
11
- :multi, :matching_downtimes, :overall_state_modified, :overall_state
11
+ :multi, :matching_downtimes, :overall_state_modified, :overall_state, :restricted_roles
12
12
  ]
13
13
 
14
14
  # defaults that datadog uses when options are not sent, so safe to leave out if our values match their defaults
@@ -54,7 +54,6 @@ module Kennel
54
54
  query: query.strip,
55
55
  message: message.strip,
56
56
  tags: tags.uniq,
57
- restricted_roles: nil,
58
57
  options: {
59
58
  timeout_h: timeout_h,
60
59
  notify_no_data: notify_no_data,
@@ -133,7 +132,7 @@ module Kennel
133
132
 
134
133
  case actual[:type]
135
134
  when "event alert"
136
- # setting 0 results in thresholds not getting returned from the api
135
+ # setting nothing results in thresholds not getting returned from the api
137
136
  options[:thresholds] ||= { critical: 0 }
138
137
 
139
138
  when "service check"
@@ -42,7 +42,10 @@ module Kennel
42
42
 
43
43
  self.class.send(:normalize, expected, actual)
44
44
 
45
- HashDiff.diff(actual, expected, use_lcs: false)
45
+ # strict: ignore Integer vs Float
46
+ # similarity: show diff when not 100% similar
47
+ # use_lcs: saner output
48
+ Hashdiff.diff(actual, expected, use_lcs: false, strict: false, similarity: 1)
46
49
  end
47
50
 
48
51
  def tracking_id
@@ -6,11 +6,12 @@ module Kennel
6
6
  DEFAULTS = {
7
7
  description: nil,
8
8
  query: nil,
9
+ groups: nil,
9
10
  monitor_ids: [],
10
11
  thresholds: []
11
12
  }.freeze
12
13
 
13
- settings :type, :description, :thresholds, :query, :tags, :monitor_ids, :monitor_tags, :name
14
+ settings :type, :description, :thresholds, :query, :tags, :monitor_ids, :monitor_tags, :name, :groups
14
15
 
15
16
  defaults(
16
17
  id: -> { nil },
@@ -18,7 +19,8 @@ module Kennel
18
19
  query: -> { DEFAULTS.fetch(:query) },
19
20
  description: -> { DEFAULTS.fetch(:description) },
20
21
  monitor_ids: -> { DEFAULTS.fetch(:monitor_ids) },
21
- thresholds: -> { DEFAULTS.fetch(:thresholds) }
22
+ thresholds: -> { DEFAULTS.fetch(:thresholds) },
23
+ groups: -> { DEFAULTS.fetch(:groups) }
22
24
  )
23
25
 
24
26
  def initialize(*)
@@ -39,8 +41,15 @@ module Kennel
39
41
  type: type
40
42
  }
41
43
 
42
- data[:query] = query if query
43
- data[:id] = id if id
44
+ if v = query
45
+ data[:query] = v
46
+ end
47
+ if v = id
48
+ data[:id] = v
49
+ end
50
+ if v = groups
51
+ data[:groups] = v
52
+ end
44
53
 
45
54
  @as_json = data
46
55
  end
data/lib/kennel/tasks.rb CHANGED
@@ -111,14 +111,21 @@ namespace :kennel do
111
111
  end
112
112
  end
113
113
 
114
- desc "Convert existing resources to copy-pastable definitions to import existing resources RESOURCE=dash ID=1234"
114
+ desc "Convert existing resources to copy-pastable definitions to import existing resources RESOURCE=[dashboard,monitor,slo] ID=1234"
115
115
  task import: :environment do
116
- resource = ENV["RESOURCE"] || Kennel::Tasks.abort("Call with RESOURCE=dash") # TODO: add others
116
+ resource = ENV["RESOURCE"] || Kennel::Tasks.abort("Call with RESOURCE= dashboard or monitor or slo")
117
117
  id = ENV["ID"] || Kennel::Tasks.abort("Call with ID=1234")
118
118
  id = Integer(id) if id =~ /^\d+$/ # dashboards can have alphanumeric ids
119
119
  puts Kennel::Importer.new(Kennel.send(:api)).import(resource, id)
120
120
  end
121
121
 
122
+ desc "Dump ALL of datadog config as raw json ... useful for grep/search TYPE=slo|monitor|dashboard"
123
+ task dump: :environment do
124
+ Kennel.send(:api).list(ENV.fetch("TYPE")).each do |r|
125
+ Kennel.out.puts JSON.pretty_generate(r)
126
+ end
127
+ end
128
+
122
129
  task :environment do
123
130
  require "kennel"
124
131
  gem "dotenv"
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Kennel
3
- VERSION = "1.62.0"
3
+ VERSION = "1.66.0"
4
4
  end
data/template/Readme.md CHANGED
@@ -2,11 +2,12 @@
2
2
 
3
3
  ![](github/cage.jpg?raw=true)
4
4
 
5
- Keep datadog monitors/dashboards/etc in version control, avoid chaotic management via UI.
5
+ Manage datadog monitors/dashboards/slos as code
6
6
 
7
- - Documented, reusable, automated, and searchable configuration
7
+ - Documented, reusable, and searchable
8
8
  - Changes are PR reviewed and auditable
9
- - Automated deletion when removed from code
9
+ - Updating shows diff before applying
10
+ - Automated import of existing monitors/dashboards/slos
10
11
 
11
12
  ![](github/screen.png?raw=true)
12
13
 
@@ -165,6 +166,14 @@ Run `rake kennel:alerts TAG=service:my-service` to see all un-muted alerts for a
165
166
 
166
167
  `rake kennel:validate_mentions` should run as part of CI
167
168
 
169
+ ### Grepping through all of datadog
170
+
171
+ `TYPE=monitor rake kennel:dump`
172
+
173
+ ### Find all monitors with No-Data
174
+
175
+ `rake kennel:nodata TAG=team:foo`
176
+
168
177
  ## Examples
169
178
 
170
179
  ### Reusable monitors/dashes/etc
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.62.0
4
+ version: 1.66.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: 2020-01-22 00:00:00.000000000 Z
11
+ date: 2020-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.3.9
33
+ version: '1.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.3.9
40
+ version: '1.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: net-http-persistent-retry
43
43
  requirement: !ruby/object:Gem::Requirement