kennel 1.62.0 → 1.66.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: 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