kennel 1.89.1 → 1.91.2
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.rb +20 -3
- data/lib/kennel/api.rb +19 -2
- data/lib/kennel/importer.rb +4 -5
- data/lib/kennel/models/synthetic_test.rb +63 -0
- data/lib/kennel/syncer.rb +9 -14
- data/lib/kennel/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 78b7b57805cf2c4730b6a1320342240fe03e9cf786f07380210bb558361b7192
|
|
4
|
+
data.tar.gz: e56d5211430862f20dc92e4d3538be0befdd630a401bf1605de064b6ab9468b8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2631017430f4d33639317f56be0d639d1d60cf33e568f5b0b4f8031a4cc0d981ca2cc793a18864049cdfc7bb3cf9d852a8ca5f90e6a37779faa37a5cafdb3212
|
|
7
|
+
data.tar.gz: 9fa908dd061892c13b40e5cf1ab1de7d406ec7a99ed6a718c1cadee5ca5ecd17ec72e8c498c3b4bdf977542a51e1871fbb743e2b4296bcc5d0d071be6aba7d3c
|
data/lib/kennel.rb
CHANGED
|
@@ -23,6 +23,7 @@ require "kennel/models/record"
|
|
|
23
23
|
require "kennel/models/dashboard"
|
|
24
24
|
require "kennel/models/monitor"
|
|
25
25
|
require "kennel/models/slo"
|
|
26
|
+
require "kennel/models/synthetic_test"
|
|
26
27
|
|
|
27
28
|
# settings
|
|
28
29
|
require "kennel/models/project"
|
|
@@ -55,7 +56,7 @@ module Kennel
|
|
|
55
56
|
|
|
56
57
|
def store(parts)
|
|
57
58
|
Progress.progress "Storing" do
|
|
58
|
-
old = Dir["generated
|
|
59
|
+
old = Dir["generated/#{project_filter || "**"}/*"]
|
|
59
60
|
used = []
|
|
60
61
|
|
|
61
62
|
Utils.parallel(parts, max: 2) do |part|
|
|
@@ -83,7 +84,7 @@ module Kennel
|
|
|
83
84
|
end
|
|
84
85
|
|
|
85
86
|
def syncer
|
|
86
|
-
@syncer ||= Syncer.new(api, generated, project:
|
|
87
|
+
@syncer ||= Syncer.new(api, generated, project: project_filter)
|
|
87
88
|
end
|
|
88
89
|
|
|
89
90
|
def api
|
|
@@ -94,9 +95,21 @@ module Kennel
|
|
|
94
95
|
@generated ||= begin
|
|
95
96
|
Progress.progress "Generating" do
|
|
96
97
|
load_all
|
|
98
|
+
known = []
|
|
97
99
|
parts = Models::Project.recursive_subclasses.flat_map do |project_class|
|
|
98
|
-
project_class.new
|
|
100
|
+
project = project_class.new
|
|
101
|
+
kennel_id = project.kennel_id
|
|
102
|
+
if project_filter
|
|
103
|
+
known << kennel_id
|
|
104
|
+
next [] if kennel_id != project_filter
|
|
105
|
+
end
|
|
106
|
+
project.validated_parts
|
|
99
107
|
end
|
|
108
|
+
|
|
109
|
+
if project_filter && parts.empty?
|
|
110
|
+
raise "#{project_filter} does not match any projects, try any of these:\n#{known.uniq.sort.join("\n")}"
|
|
111
|
+
end
|
|
112
|
+
|
|
100
113
|
parts.group_by(&:tracking_id).each do |tracking_id, same|
|
|
101
114
|
next if same.size == 1
|
|
102
115
|
raise <<~ERROR
|
|
@@ -109,6 +122,10 @@ module Kennel
|
|
|
109
122
|
end
|
|
110
123
|
end
|
|
111
124
|
|
|
125
|
+
def project_filter
|
|
126
|
+
ENV["PROJECT"]
|
|
127
|
+
end
|
|
128
|
+
|
|
112
129
|
def load_all
|
|
113
130
|
["teams", "parts", "projects"].each do |folder|
|
|
114
131
|
Dir["#{folder}/**/*.rb"].sort.each { |f| require "./#{f}" }
|
data/lib/kennel/api.rb
CHANGED
|
@@ -14,6 +14,7 @@ module Kennel
|
|
|
14
14
|
def show(api_resource, id, params = {})
|
|
15
15
|
response = request :get, "/api/v1/#{api_resource}/#{id}", params: params
|
|
16
16
|
response = response.fetch(:data) if api_resource == "slo"
|
|
17
|
+
response[:id] = response.delete(:public_id) if api_resource == "synthetics/tests"
|
|
17
18
|
response
|
|
18
19
|
end
|
|
19
20
|
|
|
@@ -22,6 +23,14 @@ module Kennel
|
|
|
22
23
|
response = request :get, "/api/v1/#{api_resource}", params: paginated_params
|
|
23
24
|
response = response.fetch(:dashboards) if api_resource == "dashboard"
|
|
24
25
|
response = response.fetch(:data) if api_resource == "slo"
|
|
26
|
+
if api_resource == "synthetics/tests"
|
|
27
|
+
response = response.fetch(:tests)
|
|
28
|
+
response.each { |r| r[:id] = r.delete(:public_id) }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# ignore monitor synthetics create and that inherit the kennel_id, we do not directly manage them
|
|
32
|
+
response.reject! { |m| m[:type] == "synthetics alert" } if api_resource == "monitor"
|
|
33
|
+
|
|
25
34
|
response
|
|
26
35
|
end
|
|
27
36
|
end
|
|
@@ -29,18 +38,26 @@ module Kennel
|
|
|
29
38
|
def create(api_resource, attributes)
|
|
30
39
|
response = request :post, "/api/v1/#{api_resource}", body: attributes
|
|
31
40
|
response = response.fetch(:data).first if api_resource == "slo"
|
|
41
|
+
response[:id] = response.delete(:public_id) if api_resource == "synthetics/tests"
|
|
32
42
|
response
|
|
33
43
|
end
|
|
34
44
|
|
|
35
45
|
def update(api_resource, id, attributes)
|
|
36
|
-
request :put, "/api/v1/#{api_resource}/#{id}", body: attributes
|
|
46
|
+
response = request :put, "/api/v1/#{api_resource}/#{id}", body: attributes
|
|
47
|
+
response[:id] = response.delete(:public_id) if api_resource == "synthetics/tests"
|
|
48
|
+
response
|
|
37
49
|
end
|
|
38
50
|
|
|
39
51
|
# - force=true to not dead-lock on dependent monitors+slos
|
|
40
52
|
# external dependency on kennel managed resources is their problem, we don't block on it
|
|
41
53
|
# (?force=true did not work, force for dashboard is not documented but does not blow up)
|
|
42
54
|
def delete(api_resource, id)
|
|
43
|
-
|
|
55
|
+
if api_resource == "synthetics/tests"
|
|
56
|
+
# https://docs.datadoghq.com/api/latest/synthetics/#delete-tests
|
|
57
|
+
request :post, "/api/v1/#{api_resource}/delete", body: { public_ids: [id] }, ignore_404: true
|
|
58
|
+
else
|
|
59
|
+
request :delete, "/api/v1/#{api_resource}/#{id}", params: { force: "true" }, ignore_404: true
|
|
60
|
+
end
|
|
44
61
|
end
|
|
45
62
|
|
|
46
63
|
def fill_details!(api_resource, list)
|
data/lib/kennel/importer.rb
CHANGED
|
@@ -15,11 +15,8 @@ module Kennel
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
model =
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
rescue NameError
|
|
21
|
-
raise ArgumentError, "#{resource} is not supported"
|
|
22
|
-
end
|
|
18
|
+
Kennel::Models::Record.subclasses.detect { |c| c.api_resource == resource } ||
|
|
19
|
+
raise(ArgumentError, "#{resource} is not supported")
|
|
23
20
|
|
|
24
21
|
data = @api.show(model.api_resource, id)
|
|
25
22
|
id = data.fetch(:id) # keep native value
|
|
@@ -70,6 +67,8 @@ module Kennel
|
|
|
70
67
|
dry_up_widget_metadata!(widget)
|
|
71
68
|
(widget.dig(:definition, :markers) || []).each { |m| m[:label]&.delete! " " }
|
|
72
69
|
end
|
|
70
|
+
when "synthetics/tests"
|
|
71
|
+
data[:locations] = :all if data[:locations].sort == Kennel::Models::SyntheticTest::LOCATIONS.sort
|
|
73
72
|
else
|
|
74
73
|
# noop
|
|
75
74
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Kennel
|
|
3
|
+
module Models
|
|
4
|
+
class SyntheticTest < Record
|
|
5
|
+
TRACKING_FIELD = :message
|
|
6
|
+
DEFAULTS = {
|
|
7
|
+
}.freeze
|
|
8
|
+
READONLY_ATTRIBUTES = superclass::READONLY_ATTRIBUTES + [:status, :monitor_id]
|
|
9
|
+
LOCATIONS = ["aws:ca-central-1", "aws:eu-north-1", "aws:eu-west-1", "aws:eu-west-3", "aws:eu-west-2", "aws:ap-south-1", "aws:us-west-2", "aws:us-west-1", "aws:sa-east-1", "aws:us-east-2", "aws:ap-northeast-1", "aws:ap-northeast-2", "aws:eu-central-1", "aws:ap-southeast-2", "aws:ap-southeast-1"].freeze
|
|
10
|
+
|
|
11
|
+
settings :tags, :config, :message, :subtype, :type, :name, :locations, :options
|
|
12
|
+
|
|
13
|
+
defaults(
|
|
14
|
+
id: -> { nil },
|
|
15
|
+
tags: -> { @project.tags },
|
|
16
|
+
message: -> { "\n\n#{project.mention}" }
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
def as_json
|
|
20
|
+
return @as_json if @as_json
|
|
21
|
+
locations = locations()
|
|
22
|
+
data = {
|
|
23
|
+
message: message,
|
|
24
|
+
tags: tags,
|
|
25
|
+
config: config,
|
|
26
|
+
type: type,
|
|
27
|
+
subtype: subtype,
|
|
28
|
+
options: options,
|
|
29
|
+
name: name,
|
|
30
|
+
locations: locations == :all ? LOCATIONS : locations
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if v = id
|
|
34
|
+
data[:id] = v
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
@as_json = data
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.api_resource
|
|
41
|
+
"synthetics/tests"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.url(id)
|
|
45
|
+
Utils.path_to_url "/synthetics/details/#{id}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.parse_url(url)
|
|
49
|
+
url[/\/synthetics\/details\/([a-z\d-]{11,})/, 1] # id format is 1ab-2ab-3ab
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.normalize(expected, actual)
|
|
53
|
+
super
|
|
54
|
+
|
|
55
|
+
# tags come in a semi-random order and order is never updated
|
|
56
|
+
expected[:tags]&.sort!
|
|
57
|
+
actual[:tags].sort!
|
|
58
|
+
|
|
59
|
+
ignore_default(expected, actual, DEFAULTS)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/kennel/syncer.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
module Kennel
|
|
3
3
|
class Syncer
|
|
4
|
-
DELETE_ORDER = ["dashboard", "slo", "monitor"].freeze # dashboards references monitors + slos, slos reference monitors
|
|
4
|
+
DELETE_ORDER = ["dashboard", "slo", "monitor", "synthetics/tests"].freeze # dashboards references monitors + slos, slos reference monitors
|
|
5
5
|
LINE_UP = "\e[1A\033[K" # go up and clear
|
|
6
6
|
|
|
7
7
|
def initialize(api, expected, project: nil)
|
|
@@ -24,7 +24,14 @@ module Kennel
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def confirm
|
|
27
|
-
|
|
27
|
+
return false if noop?
|
|
28
|
+
return true if ENV["CI"] || !STDIN.tty?
|
|
29
|
+
if @delete.any? && @project_filter
|
|
30
|
+
Kennel.out.puts(
|
|
31
|
+
Utils.color(:red, "WARNING: deleting resources that had `id: -> { ...` breaks master branch")
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
Utils.ask("Execute Plan ?")
|
|
28
35
|
end
|
|
29
36
|
|
|
30
37
|
def update
|
|
@@ -99,7 +106,6 @@ module Kennel
|
|
|
99
106
|
actual = Progress.progress("Downloading definitions") { download_definitions }
|
|
100
107
|
|
|
101
108
|
Progress.progress "Diffing" do
|
|
102
|
-
filter_expected_by_project! @expected
|
|
103
109
|
populate_id_map @expected, actual
|
|
104
110
|
filter_actual_by_project! actual
|
|
105
111
|
resolve_linked_tracking_ids! @expected # resolve dependencies to avoid diff
|
|
@@ -244,16 +250,5 @@ module Kennel
|
|
|
244
250
|
!tracking_id || tracking_id.start_with?("#{@project_filter}:")
|
|
245
251
|
end
|
|
246
252
|
end
|
|
247
|
-
|
|
248
|
-
def filter_expected_by_project!(expected)
|
|
249
|
-
return unless @project_filter
|
|
250
|
-
original = expected.dup
|
|
251
|
-
expected.select! { |e| e.project.kennel_id == @project_filter }
|
|
252
|
-
|
|
253
|
-
if expected.empty?
|
|
254
|
-
possible = original.map { |e| e.project.kennel_id }.uniq.sort
|
|
255
|
-
raise "#{@project_filter} does not match any projects, try any of these:\n#{possible.join("\n")}"
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
253
|
end
|
|
259
254
|
end
|
data/lib/kennel/version.rb
CHANGED
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.91.2
|
|
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-07-
|
|
11
|
+
date: 2021-07-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -70,6 +70,7 @@ files:
|
|
|
70
70
|
- lib/kennel/models/project.rb
|
|
71
71
|
- lib/kennel/models/record.rb
|
|
72
72
|
- lib/kennel/models/slo.rb
|
|
73
|
+
- lib/kennel/models/synthetic_test.rb
|
|
73
74
|
- lib/kennel/models/team.rb
|
|
74
75
|
- lib/kennel/optional_validations.rb
|
|
75
76
|
- lib/kennel/progress.rb
|