kennel 2.20.0 → 2.21.1
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 +4 -4
- data/lib/kennel/api.rb +46 -28
- data/lib/kennel/importer.rb +8 -1
- data/lib/kennel/models/project.rb +11 -7
- data/lib/kennel/models/slo.rb +14 -9
- data/lib/kennel/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9487ffad47b72d1a4e4781239ef3fbd500f806e5d63590c03326d7c6b689529e
|
|
4
|
+
data.tar.gz: ec5258bd90e47766deb06f71ab8041b3009f6242279a7d9d9bdede0d36da67ec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2a02de737a11b72651a05c4fbf5bd6e8180cffb95f9d398696e70ee8c8a8c0217e264892582f842a22c9c73ab1f559035c23e1e8da0f74c14680bcf9757c0c63
|
|
7
|
+
data.tar.gz: 7a2ad8b0f2561a624d410453c601da3c39184625c0565ba5d78a51689bcde28a5a623e3791ee316f7cc3d4141f0d5482735f643ad46c60364f7122ae8e2e5adf
|
data/lib/kennel/api.rb
CHANGED
|
@@ -22,8 +22,9 @@ module Kennel
|
|
|
22
22
|
@client = Faraday.new(url: url)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def show(api_resource, id, params = {})
|
|
26
|
-
response = request :get, "/api/v1/#{api_resource}/#{id}", params: params
|
|
25
|
+
def show(api_resource, id, params = {}, ignore_404: false)
|
|
26
|
+
response = request :get, "/api/v1/#{api_resource}/#{id}", params: params, ignore_404: ignore_404
|
|
27
|
+
return if response.nil? # 404 that was ignored
|
|
27
28
|
response = response.fetch(:data) if api_resource == "slo"
|
|
28
29
|
response[:id] = response.delete(:public_id) if api_resource == "synthetics/tests"
|
|
29
30
|
self.class.with_tracking(api_resource, response)
|
|
@@ -74,7 +75,12 @@ module Kennel
|
|
|
74
75
|
# fill the resource with the full response from the `show` if `list` does not return it
|
|
75
76
|
def fill_details!(api_resource, list)
|
|
76
77
|
details_cache do |cache|
|
|
77
|
-
Utils.parallel(list) { |a| fill_detail!(api_resource, a, cache) }
|
|
78
|
+
results = Utils.parallel(list) { |a| fill_detail!(api_resource, a, cache) }
|
|
79
|
+
|
|
80
|
+
# drop resources that were not found (race condition between listing and showing)
|
|
81
|
+
list.select!.with_index { |_, i| results[i][1] }
|
|
82
|
+
|
|
83
|
+
results.count { |uncached, _| uncached }
|
|
78
84
|
end
|
|
79
85
|
end
|
|
80
86
|
|
|
@@ -96,15 +102,16 @@ module Kennel
|
|
|
96
102
|
end
|
|
97
103
|
|
|
98
104
|
# Make diff work even though we cannot mass-fetch definitions
|
|
105
|
+
# @return [uncached, found]
|
|
99
106
|
def fill_detail!(api_resource, a, cache)
|
|
100
|
-
uncached =
|
|
107
|
+
uncached = false
|
|
101
108
|
args = [api_resource, a.fetch(:id)]
|
|
102
109
|
full = cache.fetch(args, a.fetch(:modified_at)) do
|
|
103
|
-
uncached
|
|
104
|
-
show(*args)
|
|
110
|
+
uncached = true
|
|
111
|
+
show(*args, ignore_404: true)
|
|
105
112
|
end
|
|
106
|
-
a.merge!(full)
|
|
107
|
-
uncached
|
|
113
|
+
a.merge!(full) if full
|
|
114
|
+
[uncached, !!full]
|
|
108
115
|
end
|
|
109
116
|
|
|
110
117
|
def details_cache(&block)
|
|
@@ -117,29 +124,18 @@ module Kennel
|
|
|
117
124
|
cached = (ENV["FORCE_GET_CACHE"] && method == :get)
|
|
118
125
|
|
|
119
126
|
with_cache cached, path do
|
|
120
|
-
response =
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
request.headers["DD-API-KEY"] = @api_key
|
|
127
|
-
request.headers["DD-APPLICATION-KEY"] = @app_key
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
if response.status == 429
|
|
132
|
-
sleep_until_rate_limit_resets(response)
|
|
133
|
-
redo
|
|
127
|
+
response = request_with_retries(path, tries) do
|
|
128
|
+
@client.send(method, path) do |request|
|
|
129
|
+
request.body = JSON.generate(body) if body
|
|
130
|
+
request.headers["Content-type"] = "application/json"
|
|
131
|
+
request.headers["DD-API-KEY"] = @api_key
|
|
132
|
+
request.headers["DD-APPLICATION-KEY"] = @app_key
|
|
134
133
|
end
|
|
135
|
-
|
|
136
|
-
last_try = (i == tries - 1)
|
|
137
|
-
break if last_try || response.status < 500
|
|
138
|
-
Kennel.err.puts "Retrying on server error #{response.status} for #{path}"
|
|
139
|
-
sleep retry_backoff_time(i)
|
|
140
134
|
end
|
|
141
135
|
|
|
142
|
-
if
|
|
136
|
+
next if response.status == 404 && ignore_404
|
|
137
|
+
|
|
138
|
+
unless response.success?
|
|
143
139
|
message = "Error #{response.status} during #{method.upcase} #{path}\n"
|
|
144
140
|
message << "request:\n#{JSON.pretty_generate(body)}\nresponse:\n" if body
|
|
145
141
|
message << response.body.encode(message.encoding, invalid: :replace, undef: :replace)
|
|
@@ -154,6 +150,28 @@ module Kennel
|
|
|
154
150
|
end
|
|
155
151
|
end
|
|
156
152
|
|
|
153
|
+
# retry on rate-limits and server errors, giving up after `tries` attempts
|
|
154
|
+
def request_with_retries(path, tries, &block)
|
|
155
|
+
raise ArgumentError, "tries must be > 0" if tries < 1
|
|
156
|
+
response = nil
|
|
157
|
+
tries.times do |i|
|
|
158
|
+
response = Utils.retry Faraday::ConnectionFailed, Faraday::TimeoutError, times: 2, &block
|
|
159
|
+
|
|
160
|
+
# we do not count 429s into the "tries", tries are only for real errors
|
|
161
|
+
# so this could loop forever if datadog consistently 429s
|
|
162
|
+
if response.status == 429
|
|
163
|
+
sleep_until_rate_limit_resets(response)
|
|
164
|
+
redo
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
last_try = (i == tries - 1)
|
|
168
|
+
break if last_try || response.status < 500
|
|
169
|
+
Kennel.err.puts "Retrying on server error #{response.status} for #{path}"
|
|
170
|
+
sleep retry_backoff_time(i)
|
|
171
|
+
end
|
|
172
|
+
response
|
|
173
|
+
end
|
|
174
|
+
|
|
157
175
|
def sleep_until_rate_limit_resets(response)
|
|
158
176
|
limit = response.headers["x-ratelimit-limit"]
|
|
159
177
|
period = response.headers["x-ratelimit-period"]
|
data/lib/kennel/importer.rb
CHANGED
|
@@ -86,7 +86,14 @@ module Kennel
|
|
|
86
86
|
end
|
|
87
87
|
when "synthetics/tests"
|
|
88
88
|
data[:locations] = :all if data[:locations].sort == Kennel::Models::SyntheticTest::LOCATIONS.sort
|
|
89
|
-
|
|
89
|
+
when "slo"
|
|
90
|
+
# sli_specification it is only used by datadog if the user switched to "Bad Events"
|
|
91
|
+
# otherwise user would be trying to set sli_specification but the slo does not change since query is used
|
|
92
|
+
if data.key?(:query) && data.key?(:sli_specification)
|
|
93
|
+
delete = (data.dig(:sli_specification, :count, :bad_events_formula) ? :query : :sli_specification)
|
|
94
|
+
data.delete delete
|
|
95
|
+
end
|
|
96
|
+
else # uncovered
|
|
90
97
|
# noop
|
|
91
98
|
end
|
|
92
99
|
|
|
@@ -10,10 +10,16 @@ module Kennel
|
|
|
10
10
|
|
|
11
11
|
def self.file_location
|
|
12
12
|
return @file_location if defined?(@file_location)
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
methods = instance_methods(false)
|
|
14
|
+
if methods.any?
|
|
15
|
+
@file_location = methods.detect do |method|
|
|
16
|
+
location = instance_method(method).source_location.first
|
|
17
|
+
if (path = find_relative_path(location))
|
|
18
|
+
break path
|
|
19
|
+
end
|
|
20
|
+
end || raise("Unable to find file_location for #{name}")
|
|
15
21
|
else
|
|
16
|
-
@file_location = nil
|
|
22
|
+
@file_location = nil # not sure if this is actually needed
|
|
17
23
|
end
|
|
18
24
|
end
|
|
19
25
|
|
|
@@ -29,11 +35,9 @@ module Kennel
|
|
|
29
35
|
|
|
30
36
|
private
|
|
31
37
|
|
|
32
|
-
private_class_method def self.
|
|
38
|
+
private_class_method def self.find_relative_path(path)
|
|
33
39
|
return path unless File.absolute_path?(path)
|
|
34
|
-
path.dup.sub!("#{Bundler.root}/", "") ||
|
|
35
|
-
path.dup.sub!("#{Dir.pwd}/", "") ||
|
|
36
|
-
raise("Unable to make path #{path} relative with bundler root #{Bundler.root} or pwd #{Dir.pwd}")
|
|
40
|
+
path.dup.sub!("#{Bundler.root}/", "") || path.dup.sub!("#{Dir.pwd}/", "")
|
|
37
41
|
end
|
|
38
42
|
|
|
39
43
|
# hook for users to add custom filtering via `prepend`
|
data/lib/kennel/models/slo.rb
CHANGED
|
@@ -15,7 +15,8 @@ module Kennel
|
|
|
15
15
|
groups: nil,
|
|
16
16
|
monitor_ids: [],
|
|
17
17
|
thresholds: [],
|
|
18
|
-
primary: nil
|
|
18
|
+
primary: nil,
|
|
19
|
+
sli_specification: nil
|
|
19
20
|
}.freeze
|
|
20
21
|
|
|
21
22
|
settings :type, :description, :thresholds, :query, :tags, :monitor_ids, :monitor_tags, :name, :groups, :sli_specification, :primary
|
|
@@ -27,7 +28,8 @@ module Kennel
|
|
|
27
28
|
monitor_ids: -> { DEFAULTS.fetch(:monitor_ids) },
|
|
28
29
|
thresholds: -> { DEFAULTS.fetch(:thresholds) },
|
|
29
30
|
groups: -> { DEFAULTS.fetch(:groups) },
|
|
30
|
-
primary: -> { DEFAULTS.fetch(:primary) }
|
|
31
|
+
primary: -> { DEFAULTS.fetch(:primary) },
|
|
32
|
+
sli_specification: -> { DEFAULTS.fetch(:sli_specification) }
|
|
31
33
|
)
|
|
32
34
|
|
|
33
35
|
def build_json
|
|
@@ -50,9 +52,8 @@ module Kennel
|
|
|
50
52
|
data[:target_threshold] = threshold[:target]
|
|
51
53
|
end
|
|
52
54
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
data[:sli_specification] = sli_specification
|
|
55
|
+
if (v = sli_specification)
|
|
56
|
+
data[:sli_specification] = v
|
|
56
57
|
elsif (v = query)
|
|
57
58
|
data[:query] = v
|
|
58
59
|
end
|
|
@@ -102,10 +103,14 @@ module Kennel
|
|
|
102
103
|
[:timeframe, :warning_threshold, :target_threshold].each { |k| actual.delete k }
|
|
103
104
|
end
|
|
104
105
|
|
|
105
|
-
#
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
# discard deprecated query which stays in datadog forever when we are trying to set sli_specification
|
|
107
|
+
# (downgrading to query by setting sli_specification=nil is not supported in the api)
|
|
108
|
+
actual.delete :query if expected[:sli_specification]
|
|
109
|
+
|
|
110
|
+
# user set query so let's not worry about sli_specification even if this might be hiding bugs
|
|
111
|
+
# ideally we'd validate and tell the user that this will have no effect (see importer logic)
|
|
112
|
+
# but I'm not confident this will always be right
|
|
113
|
+
actual.delete :sli_specification if expected[:query]
|
|
109
114
|
|
|
110
115
|
ignore_default(expected, actual, DEFAULTS)
|
|
111
116
|
end
|
data/lib/kennel/version.rb
CHANGED