kennel 1.80.0 → 1.81.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 +4 -4
- data/Readme.md +14 -9
- data/lib/kennel/models/dashboard.rb +3 -3
- data/lib/kennel/models/monitor.rb +1 -1
- data/lib/kennel/models/record.rb +8 -9
- data/lib/kennel/models/slo.rb +1 -1
- data/lib/kennel/syncer.rb +47 -18
- data/lib/kennel/version.rb +1 -1
- data/template/Readme.md +11 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 577e1080c2efe476233752e7199c6179b5b2c9f611479a9d36ce23301077a6dd
|
4
|
+
data.tar.gz: d4fa1df4c77bd31c9c067c1f2a762ef304502da58fda08add91f651f683a86f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf160d7bb083a7ad5d1912cd6de95d783203f1b52c8f119a1ab0c7e09a60ca71d2b526346dff1c78cf8710e0b3cb00a63821583a3a7864097c22fc6c6fc27fd9
|
7
|
+
data.tar.gz: 3022a0ae8b3d9b37d625ee58402d886f8d29d03ddc6693f2f7331acd2a08d41a16df1ed7942102780e3e2d47b0f0f2afbbf935076de60f4bf54268ecff435a91
|
data/Readme.md
CHANGED
@@ -212,15 +212,20 @@ removing the `id` will cause kennel to create a new resource in datadog.
|
|
212
212
|
Some validations might be too strict for your usecase or just wrong, please [open an issue](https://github.com/grosser/kennel/issues) and
|
213
213
|
to unblock use the `validate: -> { false }` option.
|
214
214
|
|
215
|
-
### Linking with
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
215
|
+
### Linking resources with kennel_id
|
216
|
+
|
217
|
+
Link resources with their kennel_id in the format `project kennel_id` + `:` + `resource kennel_id`,
|
218
|
+
this should be used to create dependent resources like monitor + slos,
|
219
|
+
so they can be created in a single update and can be re-created if any of them is deleted.
|
220
|
+
|
221
|
+
|Resource|Type|Syntax|
|
222
|
+
|---|---|---|
|
223
|
+
|Dashboard|uptime|`monitor: {id: "foo:bar"}`|
|
224
|
+
|Dashboard|alert_graph|`alert_id: "foo:bar"`|
|
225
|
+
|Dashboard|slo|`slo_id: "foo:bar"`|
|
226
|
+
|Monitor|composite|`query: -> { "%{foo:bar} && %{foo:baz}" }`|
|
227
|
+
|Monitor|slo alert|`query: -> { "error_budget(\"%{foo:bar}\").over(\"7d\") > 123.0" }`|
|
228
|
+
|Slo|monitor|`monitor_ids: -> ["foo:bar"]`|
|
224
229
|
|
225
230
|
### Debugging changes locally
|
226
231
|
|
@@ -140,16 +140,16 @@ module Kennel
|
|
140
140
|
when "uptime"
|
141
141
|
if ids = definition[:monitor_ids]
|
142
142
|
definition[:monitor_ids] = ids.map do |id|
|
143
|
-
tracking_id?(id) ? resolve_link(id, :monitor, id_map, **args) : id
|
143
|
+
tracking_id?(id) ? (resolve_link(id, :monitor, id_map, **args) || id) : id
|
144
144
|
end
|
145
145
|
end
|
146
146
|
when "alert_graph"
|
147
147
|
if (id = definition[:alert_id]) && tracking_id?(id)
|
148
|
-
definition[:alert_id] = resolve_link(id, :monitor, id_map, **args).to_s
|
148
|
+
definition[:alert_id] = (resolve_link(id, :monitor, id_map, **args) || id).to_s
|
149
149
|
end
|
150
150
|
when "slo"
|
151
151
|
if (id = definition[:slo_id]) && tracking_id?(id)
|
152
|
-
definition[:slo_id] = resolve_link(id, :slo, id_map, **args).to_s
|
152
|
+
definition[:slo_id] = (resolve_link(id, :slo, id_map, **args) || id).to_s
|
153
153
|
end
|
154
154
|
end
|
155
155
|
end
|
@@ -116,7 +116,7 @@ module Kennel
|
|
116
116
|
when "composite", "slo alert"
|
117
117
|
type = (as_json[:type] == "composite" ? :monitor : :slo)
|
118
118
|
as_json[:query] = as_json[:query].gsub(/%{(.*?)}/) do
|
119
|
-
resolve_link($1, type, id_map, **args)
|
119
|
+
resolve_link($1, type, id_map, **args) || $&
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
data/lib/kennel/models/record.rb
CHANGED
@@ -65,19 +65,18 @@ module Kennel
|
|
65
65
|
|
66
66
|
private
|
67
67
|
|
68
|
-
def resolve_link(
|
69
|
-
|
70
|
-
if
|
68
|
+
def resolve_link(tracking_id, type, id_map, force:)
|
69
|
+
id = id_map[tracking_id]
|
70
|
+
if id == :new
|
71
71
|
if force
|
72
|
-
#
|
73
|
-
invalid! "#{id} needs to already exist, try again"
|
72
|
+
invalid! "#{type} #{tracking_id} was referenced but is also created by the current run.\nIt could not be created because of a circular dependency, try creating only some of the resources"
|
74
73
|
else
|
75
|
-
|
74
|
+
nil # will be re-resolved after the linked object was created
|
76
75
|
end
|
77
|
-
elsif
|
78
|
-
|
76
|
+
elsif id
|
77
|
+
id
|
79
78
|
else
|
80
|
-
invalid! "Unable to find #{type} #{
|
79
|
+
invalid! "Unable to find #{type} #{tracking_id} (does not exist and is not being created by the current run)"
|
81
80
|
end
|
82
81
|
end
|
83
82
|
|
data/lib/kennel/models/slo.rb
CHANGED
@@ -69,7 +69,7 @@ module Kennel
|
|
69
69
|
def resolve_linked_tracking_ids!(id_map, **args)
|
70
70
|
return unless as_json[:monitor_ids] # ignore_default can remove it
|
71
71
|
as_json[:monitor_ids] = as_json[:monitor_ids].map do |id|
|
72
|
-
id.is_a?(String) ? resolve_link(id, :monitor, id_map, **args) : id
|
72
|
+
id.is_a?(String) ? (resolve_link(id, :monitor, id_map, **args) || id) : id
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
data/lib/kennel/syncer.rb
CHANGED
@@ -38,23 +38,14 @@ module Kennel
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def update
|
41
|
-
|
42
|
-
|
43
|
-
@create.each do |_, e|
|
44
|
-
e.resolve_linked_tracking_ids!({}, force: true)
|
45
|
-
|
41
|
+
each_resolved @create do |_, e|
|
46
42
|
reply = @api.create e.class.api_resource, e.as_json
|
47
43
|
id = reply.fetch(:id)
|
48
|
-
|
49
|
-
# resolve ids we could previously no resolve
|
50
|
-
changed.delete e
|
51
|
-
resolve_linked_tracking_ids! from: [reply], to: changed
|
52
|
-
|
44
|
+
populate_id_map [reply] # allow resolving ids we could previously no resolve
|
53
45
|
Kennel.out.puts "Created #{e.class.api_resource} #{tracking_id(e.as_json)} #{e.url(id)}"
|
54
46
|
end
|
55
47
|
|
56
|
-
@update
|
57
|
-
e.resolve_linked_tracking_ids!({}, force: true)
|
48
|
+
each_resolved @update do |id, e|
|
58
49
|
@api.update e.class.api_resource, id, e.as_json
|
59
50
|
Kennel.out.puts "Updated #{e.class.api_resource} #{tracking_id(e.as_json)} #{e.url(id)}"
|
60
51
|
end
|
@@ -67,6 +58,37 @@ module Kennel
|
|
67
58
|
|
68
59
|
private
|
69
60
|
|
61
|
+
# loop over items until everything is resolved or crash when we get stuck
|
62
|
+
# this solves cases like composite monitors depending on each other or monitor->monitor slo->slo monitor chains
|
63
|
+
def each_resolved(list)
|
64
|
+
list = list.dup
|
65
|
+
loop do
|
66
|
+
return if list.empty?
|
67
|
+
list.reject! do |id, e|
|
68
|
+
if resolved?(e)
|
69
|
+
yield id, e
|
70
|
+
true
|
71
|
+
else
|
72
|
+
false
|
73
|
+
end
|
74
|
+
end ||
|
75
|
+
assert_resolved(list[0][1]) # resolve something or show a circular dependency error
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# TODO: optimize by storing an instance variable if already resolved
|
80
|
+
def resolved?(e)
|
81
|
+
assert_resolved e
|
82
|
+
true
|
83
|
+
rescue ValidationError
|
84
|
+
false
|
85
|
+
end
|
86
|
+
|
87
|
+
# raises ValidationError when not resolved
|
88
|
+
def assert_resolved(e)
|
89
|
+
resolve_linked_tracking_ids! [e], force: true
|
90
|
+
end
|
91
|
+
|
70
92
|
def noop?
|
71
93
|
@create.empty? && @update.empty? && @delete.empty?
|
72
94
|
end
|
@@ -74,9 +96,15 @@ module Kennel
|
|
74
96
|
def calculate_diff
|
75
97
|
@update = []
|
76
98
|
@delete = []
|
99
|
+
@id_map = {}
|
77
100
|
|
78
101
|
actual = Progress.progress("Downloading definitions") { download_definitions }
|
79
|
-
|
102
|
+
|
103
|
+
# resolve dependencies to avoid diff
|
104
|
+
populate_id_map actual
|
105
|
+
@expected.each { |e| @id_map[e.tracking_id] ||= :new }
|
106
|
+
resolve_linked_tracking_ids! @expected
|
107
|
+
|
80
108
|
filter_by_project! actual
|
81
109
|
|
82
110
|
Progress.progress "Diffing" do
|
@@ -107,7 +135,6 @@ module Kennel
|
|
107
135
|
|
108
136
|
ensure_all_ids_found
|
109
137
|
@create = @expected.map { |e| [nil, e] }
|
110
|
-
@create.sort_by! { |_, e| -DELETE_ORDER.index(e.class.api_resource) }
|
111
138
|
end
|
112
139
|
|
113
140
|
@delete.sort_by! { |_, _, a| DELETE_ORDER.index a.fetch(:api_resource) }
|
@@ -214,10 +241,12 @@ module Kennel
|
|
214
241
|
end
|
215
242
|
end
|
216
243
|
|
217
|
-
def
|
218
|
-
|
219
|
-
|
220
|
-
|
244
|
+
def populate_id_map(actual)
|
245
|
+
actual.each { |a| @id_map[tracking_id(a)] = a.fetch(:id) }
|
246
|
+
end
|
247
|
+
|
248
|
+
def resolve_linked_tracking_ids!(list, force: false)
|
249
|
+
list.each { |e| e.resolve_linked_tracking_ids!(@id_map, force: force) }
|
221
250
|
end
|
222
251
|
|
223
252
|
def filter_by_project!(definitions)
|
data/lib/kennel/version.rb
CHANGED
data/template/Readme.md
CHANGED
@@ -196,13 +196,17 @@ to unblock use the `validate: -> { false }` option.
|
|
196
196
|
|
197
197
|
### Linking with kennel_ids
|
198
198
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
199
|
+
Link resources via their kennel_id `projects kennel_id` + `:` + `monitors kennel id`,
|
200
|
+
this should be used to create dependent resources like monitor + slos.
|
201
|
+
|
202
|
+
|Resource|Type|Syntax|
|
203
|
+
|---|---|---|
|
204
|
+
|Dashboard|uptime|`monitor: {id: "foo:bar"}`|
|
205
|
+
|Dashboard|alert_graph|`alert_id: "foo:bar"`|
|
206
|
+
|Dashboard|slo|`slo_id: "foo:bar"`|
|
207
|
+
|Monitor|composite|`query: -> { "%{foo:bar} && %{foo:baz}" }`|
|
208
|
+
|Monitor|slo alert|`query: -> { "error_budget(\"%{foo:bar}\").over(\"7d\") > 123.0" }`|
|
209
|
+
|Slo|monitor|`monitor_ids: -> ["foo:bar"]`|
|
206
210
|
|
207
211
|
### Debugging changes locally
|
208
212
|
|
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.
|
4
|
+
version: 1.81.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-01-
|
11
|
+
date: 2021-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|