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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba1d58935b541b89cb78318964470bb209933a491d9b81e23785de0fb6ab2654
4
- data.tar.gz: aed4b13dc2c35ced80073e592fd0d2ba2afda8dfb763d2c6baa4b1f30851cf53
3
+ metadata.gz: 78b7b57805cf2c4730b6a1320342240fe03e9cf786f07380210bb558361b7192
4
+ data.tar.gz: e56d5211430862f20dc92e4d3538be0befdd630a401bf1605de064b6ab9468b8
5
5
  SHA512:
6
- metadata.gz: d3595608df6e40ec4241bf2b758f1ed1b3fde0e63dff7f5a4fa393a358cf9cb9fa33bb0c5f72899b7df54817cb9482366d9c387e3c21a33249e35e3bcc4fc8ea
7
- data.tar.gz: 745ec8c762acc885a9d0f2ae23fc9f43ca05f56b8c580501075e2b9237e7199a09499053cebb45e5bfa477aa0a187cabf5899e05f7bf6c361f952347ab6cac34
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: ENV["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.validated_parts
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
- request :delete, "/api/v1/#{api_resource}/#{id}", params: { force: "true" }, ignore_404: true
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)
@@ -15,11 +15,8 @@ module Kennel
15
15
  end
16
16
 
17
17
  model =
18
- begin
19
- Kennel::Models.const_get(resource.capitalize)
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
- ENV["CI"] || !STDIN.tty? || Utils.ask("Execute Plan ?") unless noop?
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
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Kennel
3
- VERSION = "1.89.1"
3
+ VERSION = "1.91.2"
4
4
  end
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.89.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-01 00:00:00.000000000 Z
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