kennel 1.62.1 → 1.66.1

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: f5ad82b24cba6eef0e7733dac0b4c0f51e54fb728338112c8505ddf84284df23
4
- data.tar.gz: c6bf110be71f0296d352797ed7f8ac364dfa18e580a632ef1ad21e427da65111
3
+ metadata.gz: 97bb44fcc344bb6e906a6cd364ccbd8e00cdbe499257b349ed3b30190087fa58
4
+ data.tar.gz: 17db69d7a4de5599aed07dac93db2563943be29bfa456099f330efd5f0dc2c55
5
5
  SHA512:
6
- metadata.gz: 85b2929f6e429c64be88d96dbbfb76f057fa56d1dea6eb81668e728b214ff4cd91a6345899199f95034c75414444519d6d7f585174687866f99c20481e547172
7
- data.tar.gz: 55412cc487dffdf9de2e4f715fb3773690591753793fe2ea799677f853b3c42348e1fbc6ed13a8e7adc3d45d0fd3ac9141a825ef10d4a2066cdb58350e3632ff
6
+ metadata.gz: 7385074e9d4d3b2e1868f501d74850510f9e6412474a55b8bb3b863c637e02bd4ca2ba065429c1566b86044ef66978e4e4aabff25bb6a3501d22cf388c009f79
7
+ data.tar.gz: 62c6acd58e137e577016e8f79b690a85ab9637ffab527382e94fdbf07cd752b767371ed468e9413f154c0d8dd61198c105be37a968b86ce814013d84c5ba86c1
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
@@ -132,7 +132,7 @@ module Kennel
132
132
 
133
133
  case actual[:type]
134
134
  when "event alert"
135
- # setting 0 results in thresholds not getting returned from the api
135
+ # setting nothing results in thresholds not getting returned from the api
136
136
  options[:thresholds] ||= { critical: 0 }
137
137
 
138
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/syncer.rb CHANGED
@@ -3,6 +3,7 @@ module Kennel
3
3
  class Syncer
4
4
  CACHE_FILE = "tmp/cache/details" # keep in sync with .travis.yml caching
5
5
  TRACKING_FIELDS = [:message, :description].freeze
6
+ DELETE_ORDER = ["dashboard", "slo", "monitor"].freeze # dashboards references monitors + slos, slos reference monitors
6
7
 
7
8
  def initialize(api, expected, project: nil)
8
9
  @api = api
@@ -98,6 +99,8 @@ module Kennel
98
99
  ensure_all_ids_found
99
100
  @create = @expected.map { |e| [nil, e] }
100
101
  end
102
+
103
+ @delete.sort_by! { |_, _, a| DELETE_ORDER.index a.fetch(:api_resource) }
101
104
  end
102
105
 
103
106
  # Make diff work even though we cannot mass-fetch definitions
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.1"
3
+ VERSION = "1.66.1"
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.1
4
+ version: 1.66.1
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-24 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