kennel 1.58.0 → 1.59.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 +1 -0
- data/lib/kennel.rb +5 -1
- data/lib/kennel/api.rb +16 -1
- data/lib/kennel/models/dashboard.rb +3 -3
- data/lib/kennel/models/monitor.rb +1 -0
- data/lib/kennel/models/project.rb +12 -0
- data/lib/kennel/models/record.rb +13 -7
- data/lib/kennel/models/slo.rb +1 -1
- data/lib/kennel/syncer.rb +1 -0
- data/lib/kennel/tasks.rb +19 -8
- data/lib/kennel/version.rb +1 -1
- data/template/Readme.md +1 -0
- 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: c20add02263916021ed0498253e11e79193b5bf603651c28cbacbf614b02287c
|
|
4
|
+
data.tar.gz: ec8ff5e6fa15c10b2f3113feb7f3459f48b9520259952ab91786f56001192f53
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b69a0f24eeca1fb532c4b46f18f398e5df1630ae5f8da96b3ea7a263e68e3a211b31e4762f979ff022290ec5fc54a011ba3177a3ee9156ee4ee20541385b48e8
|
|
7
|
+
data.tar.gz: 30e5d810b9351afb83ec40f29c17d9828bd85d41ecea39c3e273011f3ed32ffa2c1729d495aeaad1668bb958e4b407f696916dd57eb3992da08588cf4bf8576e
|
data/Readme.md
CHANGED
|
@@ -45,6 +45,7 @@ Keep datadog monitors/dashboards/etc in version control, avoid chaotic managemen
|
|
|
45
45
|
- copy any `API Key` and add it to `.env` as `DATADOG_API_KEY`
|
|
46
46
|
- find or create (check last page) your personal "Application Key" and add it to `.env` as `DATADOG_APP_KEY=`
|
|
47
47
|
- change the `DATADOG_SUBDOMAIN=app` in `.env` to your companies subdomain if you have one
|
|
48
|
+
- verify it works by running `rake plan`, it might show some diff, but should not crash
|
|
48
49
|
-->
|
|
49
50
|
|
|
50
51
|
### Adding a team
|
data/lib/kennel.rb
CHANGED
|
@@ -29,6 +29,10 @@ require "kennel/models/project"
|
|
|
29
29
|
require "kennel/models/team"
|
|
30
30
|
|
|
31
31
|
module Kennel
|
|
32
|
+
MISSING_ID = 1
|
|
33
|
+
class ValidationError < RuntimeError
|
|
34
|
+
end
|
|
35
|
+
|
|
32
36
|
@out = $stdout
|
|
33
37
|
@err = $stderr
|
|
34
38
|
|
|
@@ -68,7 +72,7 @@ module Kennel
|
|
|
68
72
|
Progress.progress "Generating" do
|
|
69
73
|
load_all
|
|
70
74
|
parts = Models::Project.recursive_subclasses.flat_map do |project_class|
|
|
71
|
-
project_class.new.
|
|
75
|
+
project_class.new.validated_parts
|
|
72
76
|
end
|
|
73
77
|
parts.map(&:tracking_id).group_by { |id| id }.select do |id, same|
|
|
74
78
|
raise "#{id} is defined #{same.size} times" if same.size != 1
|
data/lib/kennel/api.rb
CHANGED
|
@@ -13,7 +13,22 @@ module Kennel
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def list(api_resource, params = {})
|
|
16
|
-
|
|
16
|
+
if api_resource == "slo"
|
|
17
|
+
raise ArgumentError if params[:limit] || params[:offset]
|
|
18
|
+
limit = 1000
|
|
19
|
+
offset = 0
|
|
20
|
+
all = []
|
|
21
|
+
|
|
22
|
+
loop do
|
|
23
|
+
result = request :get, "/api/v1/#{api_resource}", params: params.merge(limit: limit, offset: offset)
|
|
24
|
+
data = result.fetch(:data)
|
|
25
|
+
all.concat data
|
|
26
|
+
break all if data.size < limit
|
|
27
|
+
offset += limit
|
|
28
|
+
end
|
|
29
|
+
else
|
|
30
|
+
request :get, "/api/v1/#{api_resource}", params: params
|
|
31
|
+
end
|
|
17
32
|
end
|
|
18
33
|
|
|
19
34
|
def create(api_resource, attributes)
|
|
@@ -101,16 +101,16 @@ module Kennel
|
|
|
101
101
|
when "uptime"
|
|
102
102
|
if ids = definition[:monitor_ids]
|
|
103
103
|
definition[:monitor_ids] = ids.map do |id|
|
|
104
|
-
tracking_id?(id) ? resolve_link(id, id_map
|
|
104
|
+
tracking_id?(id) ? resolve_link(id, id_map) : id
|
|
105
105
|
end
|
|
106
106
|
end
|
|
107
107
|
when "alert_graph"
|
|
108
108
|
if (id = definition[:alert_id]) && tracking_id?(id)
|
|
109
|
-
definition[:alert_id] = resolve_link(id, id_map
|
|
109
|
+
definition[:alert_id] = resolve_link(id, id_map).to_s
|
|
110
110
|
end
|
|
111
111
|
when "slo"
|
|
112
112
|
if (id = definition[:slo_id]) && tracking_id?(id)
|
|
113
|
-
definition[:slo_id] = resolve_link(id, id_map
|
|
113
|
+
definition[:slo_id] = resolve_link(id, id_map).to_s
|
|
114
114
|
end
|
|
115
115
|
end
|
|
116
116
|
end
|
|
@@ -105,6 +105,7 @@ module Kennel
|
|
|
105
105
|
def resolve_linked_tracking_ids(id_map)
|
|
106
106
|
if as_json[:type] == "composite"
|
|
107
107
|
as_json[:query] = as_json[:query].gsub(/%\{(.*?)\}/) do
|
|
108
|
+
# need force here since it validates the id exists
|
|
108
109
|
resolve_link($1, id_map, force: true)
|
|
109
110
|
end
|
|
110
111
|
end
|
|
@@ -14,6 +14,18 @@ module Kennel
|
|
|
14
14
|
instance_method(method_in_file).source_location.first.sub("#{Bundler.root}/", "")
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
|
+
|
|
18
|
+
def validated_parts
|
|
19
|
+
all = parts
|
|
20
|
+
validate_parts(all)
|
|
21
|
+
all
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
# hook for users to add custom validations via `prepend`
|
|
27
|
+
def validate_parts(parts)
|
|
28
|
+
end
|
|
17
29
|
end
|
|
18
30
|
end
|
|
19
31
|
end
|
data/lib/kennel/models/record.rb
CHANGED
|
@@ -13,9 +13,6 @@ module Kennel
|
|
|
13
13
|
}.freeze
|
|
14
14
|
API_LIST_INCOMPLETE = false
|
|
15
15
|
|
|
16
|
-
class ValidationError < RuntimeError
|
|
17
|
-
end
|
|
18
|
-
|
|
19
16
|
settings :id, :kennel_id
|
|
20
17
|
|
|
21
18
|
class << self
|
|
@@ -81,10 +78,19 @@ module Kennel
|
|
|
81
78
|
|
|
82
79
|
private
|
|
83
80
|
|
|
84
|
-
def resolve_link(id, id_map, force:)
|
|
85
|
-
id_map[id]
|
|
86
|
-
|
|
87
|
-
|
|
81
|
+
def resolve_link(id, id_map, force: false)
|
|
82
|
+
found = id_map[id]
|
|
83
|
+
return found if found && found != :new
|
|
84
|
+
|
|
85
|
+
if found == :new
|
|
86
|
+
if force
|
|
87
|
+
invalid! "Monitor #{id} will be created in the current run and can only be used after that"
|
|
88
|
+
else
|
|
89
|
+
Kennel.err.puts "Monitor #{id} will be created in the current run, the next run will link it properly"
|
|
90
|
+
Kennel::MISSING_ID
|
|
91
|
+
end
|
|
92
|
+
else
|
|
93
|
+
invalid! "Unable to find monitor #{id} (does not exist and is not being created by the current run)"
|
|
88
94
|
end
|
|
89
95
|
end
|
|
90
96
|
|
data/lib/kennel/models/slo.rb
CHANGED
|
@@ -55,7 +55,7 @@ module Kennel
|
|
|
55
55
|
|
|
56
56
|
def resolve_linked_tracking_ids(id_map)
|
|
57
57
|
as_json[:monitor_ids] = as_json[:monitor_ids].map do |id|
|
|
58
|
-
id.is_a?(String) ? resolve_link(id, id_map
|
|
58
|
+
id.is_a?(String) ? resolve_link(id, id_map) : id
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
data/lib/kennel/syncer.rb
CHANGED
|
@@ -195,6 +195,7 @@ module Kennel
|
|
|
195
195
|
|
|
196
196
|
def resolve_linked_tracking_ids(actual)
|
|
197
197
|
map = actual.each_with_object({}) { |a, lookup| lookup[tracking_id(a)] = a.fetch(:id) }
|
|
198
|
+
@expected.each { |e| map[e.tracking_id] ||= :new }
|
|
198
199
|
@expected.each { |e| e.resolve_linked_tracking_ids(map) }
|
|
199
200
|
end
|
|
200
201
|
|
data/lib/kennel/tasks.rb
CHANGED
|
@@ -4,12 +4,23 @@ require "kennel"
|
|
|
4
4
|
require "kennel/unmuted_alerts"
|
|
5
5
|
require "kennel/importer"
|
|
6
6
|
|
|
7
|
+
module Kennel
|
|
8
|
+
module Tasks
|
|
9
|
+
class << self
|
|
10
|
+
def abort(message = nil)
|
|
11
|
+
Kennel.err.puts message if message
|
|
12
|
+
raise SystemExit.new(1), message
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
7
18
|
namespace :kennel do
|
|
8
19
|
desc "Ensure there are no uncommited changes that would be hidden from PR reviewers"
|
|
9
20
|
task no_diff: :generate do
|
|
10
21
|
result = `git status --porcelain`.strip
|
|
11
|
-
abort "Diff found:\n#{result}\nrun `rake generate` and commit the diff to fix" unless result == ""
|
|
12
|
-
abort "Error during diffing" unless $CHILD_STATUS.success?
|
|
22
|
+
Kennel::Tasks.abort "Diff found:\n#{result}\nrun `rake generate` and commit the diff to fix" unless result == ""
|
|
23
|
+
Kennel::Tasks.abort "Error during diffing" unless $CHILD_STATUS.success?
|
|
13
24
|
end
|
|
14
25
|
|
|
15
26
|
# ideally do this on every run, but it's slow (~1.5s) and brittle (might not find all + might find false-positives)
|
|
@@ -38,7 +49,7 @@ namespace :kennel do
|
|
|
38
49
|
url = (subdomain ? "https://zendesk.datadoghq.com" : "") + "/account/settings"
|
|
39
50
|
puts "Invalid mentions found, either ignore them by adding to `KNOWN` env var or add them via #{url}"
|
|
40
51
|
bad.each { |f, v| puts "Invalid mention #{v} in monitor message of #{f}" }
|
|
41
|
-
abort
|
|
52
|
+
Kennel::Tasks.abort
|
|
42
53
|
end
|
|
43
54
|
end
|
|
44
55
|
|
|
@@ -76,16 +87,16 @@ namespace :kennel do
|
|
|
76
87
|
|
|
77
88
|
desc "show unmuted alerts filtered by TAG, for example TAG=team:foo"
|
|
78
89
|
task alerts: :environment do
|
|
79
|
-
tag = ENV["TAG"] || abort("Call with TAG=foo:bar")
|
|
90
|
+
tag = ENV["TAG"] || Kennel::Tasks.abort("Call with TAG=foo:bar")
|
|
80
91
|
Kennel::UnmutedAlerts.print(Kennel.send(:api), tag)
|
|
81
92
|
end
|
|
82
93
|
|
|
83
94
|
desc "show monitors with no data by TAG, for example TAG=team:foo"
|
|
84
95
|
task nodata: :environment do
|
|
85
|
-
tag = ENV["TAG"] || abort("Call with TAG=foo:bar")
|
|
96
|
+
tag = ENV["TAG"] || Kennel::Tasks.abort("Call with TAG=foo:bar")
|
|
86
97
|
monitors = Kennel.send(:api).list("monitor", monitor_tags: tag, group_states: "no data")
|
|
87
98
|
monitors.select! { |m| m[:overall_state] == "No Data" }
|
|
88
|
-
monitors.reject! { |m| m[:tags].include?
|
|
99
|
+
monitors.reject! { |m| m[:tags].include? "nodata:ignore" }
|
|
89
100
|
if monitors.any?
|
|
90
101
|
Kennel.err.puts <<~TEXT
|
|
91
102
|
This is a useful task to find monitors that have mis-spelled metrics or never received data at any time.
|
|
@@ -103,8 +114,8 @@ namespace :kennel do
|
|
|
103
114
|
|
|
104
115
|
desc "Convert existing resources to copy-pastable definitions to import existing resources RESOURCE=dash ID=1234"
|
|
105
116
|
task import: :environment do
|
|
106
|
-
resource = ENV["RESOURCE"] || abort("Call with RESOURCE=dash") # TODO: add others
|
|
107
|
-
id = ENV["ID"] || abort("Call with ID=1234")
|
|
117
|
+
resource = ENV["RESOURCE"] || Kennel::Tasks.abort("Call with RESOURCE=dash") # TODO: add others
|
|
118
|
+
id = ENV["ID"] || Kennel::Tasks.abort("Call with ID=1234")
|
|
108
119
|
id = Integer(id) if id =~ /^\d+$/ # dashboards can have alphanumeric ids
|
|
109
120
|
puts Kennel::Importer.new(Kennel.send(:api)).import(resource, id)
|
|
110
121
|
end
|
data/lib/kennel/version.rb
CHANGED
data/template/Readme.md
CHANGED
|
@@ -28,6 +28,7 @@ Keep datadog monitors/dashboards/etc in version control, avoid chaotic managemen
|
|
|
28
28
|
- copy any `API Key` and add it to `.env` as `DATADOG_API_KEY`
|
|
29
29
|
- find or create (check last page) your personal "Application Key" and add it to `.env` as `DATADOG_APP_KEY=`
|
|
30
30
|
- change the `DATADOG_SUBDOMAIN=app` in `.env` to your companies subdomain if you have one
|
|
31
|
+
- verify it works by running `rake plan`, it might show some diff, but should not crash
|
|
31
32
|
|
|
32
33
|
### Adding a team
|
|
33
34
|
|
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.59.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: 2019-
|
|
11
|
+
date: 2019-12-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|