kennel 1.121.1 → 1.123.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 +8 -0
- data/lib/kennel/file_cache.rb +11 -11
- data/lib/kennel/github_reporter.rb +1 -1
- data/lib/kennel/importer.rb +16 -0
- data/lib/kennel/models/dashboard.rb +8 -16
- data/lib/kennel/models/monitor.rb +5 -13
- data/lib/kennel/models/project.rb +1 -6
- data/lib/kennel/models/record.rb +38 -10
- data/lib/kennel/models/slo.rb +15 -16
- data/lib/kennel/models/synthetic_test.rb +4 -11
- data/lib/kennel/progress.rb +22 -3
- data/lib/kennel/syncer.rb +3 -3
- data/lib/kennel/tasks.rb +11 -0
- data/lib/kennel/utils.rb +4 -6
- data/lib/kennel/version.rb +1 -1
- data/lib/kennel.rb +3 -2
- data/template/Readme.md +8 -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: f09678f23d63da04d4b5db81eaef471bc0aa437b62ac75082f7bd161f8cd38e4
|
4
|
+
data.tar.gz: a570cc2617295581459a5977727049c243d492312554496f0b1beb432ad8efe8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 560a1daae6cb797b0e53e06a694e5624667b5597d3d6fb5c783e0166154a8f594064d7bfc1f64fb541723e2b633130d4e8039a8caa3434145552a63114a88678
|
7
|
+
data.tar.gz: '091c93ee61b87146c69e6f8782aab7a3cf2c349a03936f686a099eaca1a96d762193ee8385220fcc9d8c694edacf89aa57c6751e6e8a17bcffb37b1f913f9591'
|
data/Readme.md
CHANGED
@@ -406,6 +406,14 @@ https://foo.datadog.com/monitor/123
|
|
406
406
|
### Find all monitors with No-Data
|
407
407
|
`rake kennel:nodata TAG=team:foo`
|
408
408
|
|
409
|
+
### Finding the tracking id of a resource
|
410
|
+
|
411
|
+
When trying to link resources together, this avoids having to go through datadog UI.
|
412
|
+
|
413
|
+
```Bash
|
414
|
+
rake kennel:tracking_id ID=123 RESOURCE=monitor
|
415
|
+
```
|
416
|
+
|
409
417
|
<!-- NOT IN template/Readme.md -->
|
410
418
|
|
411
419
|
## Development
|
data/lib/kennel/file_cache.rb
CHANGED
@@ -15,11 +15,13 @@ module Kennel
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def open
|
18
|
-
load_data
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
@data = load_data || {}
|
19
|
+
begin
|
20
|
+
expire_old_data
|
21
|
+
yield self
|
22
|
+
ensure
|
23
|
+
persist
|
24
|
+
end
|
23
25
|
end
|
24
26
|
|
25
27
|
def fetch(key, key_version)
|
@@ -35,12 +37,9 @@ module Kennel
|
|
35
37
|
private
|
36
38
|
|
37
39
|
def load_data
|
38
|
-
@
|
39
|
-
|
40
|
-
|
41
|
-
rescue StandardError
|
42
|
-
{}
|
43
|
-
end
|
40
|
+
Marshal.load(File.read(@file)) # rubocop:disable Security/MarshalLoad
|
41
|
+
rescue Errno::ENOENT, TypeError, ArgumentError
|
42
|
+
nil
|
44
43
|
end
|
45
44
|
|
46
45
|
def persist
|
@@ -49,6 +48,7 @@ module Kennel
|
|
49
48
|
|
50
49
|
Tempfile.create "kennel-file-cache", dir do |tmp|
|
51
50
|
Marshal.dump @data, tmp
|
51
|
+
tmp.flush
|
52
52
|
File.rename tmp.path, @file
|
53
53
|
end
|
54
54
|
end
|
data/lib/kennel/importer.rb
CHANGED
@@ -38,6 +38,8 @@ module Kennel
|
|
38
38
|
|
39
39
|
case resource
|
40
40
|
when "monitor"
|
41
|
+
raise "Import the synthetic test page and not the monitor" if data[:type] == "synthetics alert"
|
42
|
+
|
41
43
|
# flatten monitor options so they are all on the base which is how Monitor builds them
|
42
44
|
data.merge!(data.delete(:options))
|
43
45
|
data.merge!(data.delete(:thresholds) || {})
|
@@ -60,6 +62,8 @@ module Kennel
|
|
60
62
|
data[:critical] = data[:critical].to_i if data[:type] == "event alert"
|
61
63
|
|
62
64
|
data[:type] = "query alert" if data[:type] == "metric alert"
|
65
|
+
|
66
|
+
link_composite_monitors(data)
|
63
67
|
when "dashboard"
|
64
68
|
widgets = data[:widgets]&.flat_map { |widget| widget.dig(:definition, :widgets) || [widget] }
|
65
69
|
widgets&.each do |widget|
|
@@ -91,6 +95,18 @@ module Kennel
|
|
91
95
|
|
92
96
|
private
|
93
97
|
|
98
|
+
def link_composite_monitors(data)
|
99
|
+
if data[:type] == "composite"
|
100
|
+
data[:query].gsub!(/\d+/) do |id|
|
101
|
+
object = Kennel.send(:api).show("monitor", id)
|
102
|
+
tracking_id = Kennel::Models::Monitor.parse_tracking_id(object)
|
103
|
+
tracking_id ? "%{#{tracking_id}}" : id
|
104
|
+
rescue StandardError # monitor not found
|
105
|
+
id # keep the id
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
94
110
|
# reduce duplication in imports by using dry `q: :metadata` when possible
|
95
111
|
def dry_up_widget_metadata!(widget)
|
96
112
|
(widget.dig(:definition, :requests) || []).each do |request|
|
@@ -3,7 +3,6 @@ module Kennel
|
|
3
3
|
module Models
|
4
4
|
class Dashboard < Record
|
5
5
|
include TemplateVariables
|
6
|
-
include OptionalValidations
|
7
6
|
|
8
7
|
READONLY_ATTRIBUTES = superclass::READONLY_ATTRIBUTES + [
|
9
8
|
:author_handle, :author_name, :modified_at, :deleted_at, :url, :is_read_only, :notify_list, :restricted_roles
|
@@ -87,8 +86,7 @@ module Kennel
|
|
87
86
|
tags: -> do # not inherited by default to make onboarding to using dashboard tags simple
|
88
87
|
team = project.team
|
89
88
|
team.tag_dashboards ? team.tags : []
|
90
|
-
end
|
91
|
-
id: -> { nil }
|
89
|
+
end
|
92
90
|
)
|
93
91
|
|
94
92
|
class << self
|
@@ -152,29 +150,24 @@ module Kennel
|
|
152
150
|
end
|
153
151
|
end
|
154
152
|
|
155
|
-
def
|
156
|
-
return @json if @json
|
153
|
+
def build_json
|
157
154
|
all_widgets = render_definitions(definitions) + widgets
|
158
155
|
expand_q all_widgets
|
159
156
|
tags = tags()
|
160
157
|
tags_as_string = (tags.empty? ? "" : " (#{tags.join(" ")})")
|
161
158
|
|
162
|
-
|
159
|
+
json = super.merge(
|
163
160
|
layout_type: layout_type,
|
164
161
|
title: "#{title}#{tags_as_string}#{LOCK}",
|
165
162
|
description: description,
|
166
163
|
template_variables: render_template_variables,
|
167
164
|
template_variable_presets: template_variable_presets,
|
168
165
|
widgets: all_widgets
|
169
|
-
|
170
|
-
|
171
|
-
@json[:reflow_type] = reflow_type if reflow_type # setting nil breaks create with "ordered"
|
166
|
+
)
|
172
167
|
|
173
|
-
|
168
|
+
json[:reflow_type] = reflow_type if reflow_type # setting nil breaks create with "ordered"
|
174
169
|
|
175
|
-
|
176
|
-
|
177
|
-
@json
|
170
|
+
json
|
178
171
|
end
|
179
172
|
|
180
173
|
def self.url(id)
|
@@ -210,9 +203,8 @@ module Kennel
|
|
210
203
|
end
|
211
204
|
|
212
205
|
def validate_update!(_actuals, diffs)
|
213
|
-
|
214
|
-
|
215
|
-
end
|
206
|
+
_, path, from, to = diffs.find { |diff| diff[1] == "layout_type" }
|
207
|
+
invalid_update!(path, from, to) if path
|
216
208
|
end
|
217
209
|
|
218
210
|
private
|
@@ -2,8 +2,6 @@
|
|
2
2
|
module Kennel
|
3
3
|
module Models
|
4
4
|
class Monitor < Record
|
5
|
-
include OptionalValidations
|
6
|
-
|
7
5
|
RENOTIFY_INTERVALS = [0, 10, 20, 30, 40, 50, 60, 90, 120, 180, 240, 300, 360, 720, 1440].freeze # minutes
|
8
6
|
OPTIONAL_SERVICE_CHECK_THRESHOLDS = [:ok, :warning].freeze
|
9
7
|
READONLY_ATTRIBUTES = superclass::READONLY_ATTRIBUTES + [
|
@@ -41,7 +39,6 @@ module Kennel
|
|
41
39
|
renotify_interval: -> { project.team.renotify_interval },
|
42
40
|
warning: -> { nil },
|
43
41
|
ok: -> { nil },
|
44
|
-
id: -> { nil },
|
45
42
|
notify_no_data: -> { true }, # datadog sets this to false by default, but true is the safer
|
46
43
|
no_data_timeframe: -> { 60 },
|
47
44
|
notify_audit: -> { MONITOR_OPTION_DEFAULTS.fetch(:notify_audit) },
|
@@ -56,9 +53,8 @@ module Kennel
|
|
56
53
|
priority: -> { MONITOR_DEFAULTS.fetch(:priority) }
|
57
54
|
)
|
58
55
|
|
59
|
-
def
|
60
|
-
|
61
|
-
data = {
|
56
|
+
def build_json
|
57
|
+
data = super.merge(
|
62
58
|
name: "#{name}#{LOCK}",
|
63
59
|
type: type,
|
64
60
|
query: query.strip,
|
@@ -79,9 +75,7 @@ module Kennel
|
|
79
75
|
locked: false, # setting this to true prevents any edit and breaks updates when using replace workflow
|
80
76
|
renotify_interval: renotify_interval || 0
|
81
77
|
}
|
82
|
-
|
83
|
-
|
84
|
-
data[:id] = id if id
|
78
|
+
)
|
85
79
|
|
86
80
|
options = data[:options]
|
87
81
|
if data.fetch(:type) != "composite"
|
@@ -120,9 +114,7 @@ module Kennel
|
|
120
114
|
options[:renotify_statuses] = statuses
|
121
115
|
end
|
122
116
|
|
123
|
-
|
124
|
-
|
125
|
-
@as_json = data
|
117
|
+
data
|
126
118
|
end
|
127
119
|
|
128
120
|
def resolve_linked_tracking_ids!(id_map, **args)
|
@@ -140,7 +132,7 @@ module Kennel
|
|
140
132
|
# ensure type does not change, but not if it's metric->query which is supported and used by importer.rb
|
141
133
|
_, path, from, to = diffs.detect { |_, path, _, _| path == "type" }
|
142
134
|
if path && !(from == "metric alert" && to == "query alert")
|
143
|
-
|
135
|
+
invalid_update!(path, from, to)
|
144
136
|
end
|
145
137
|
end
|
146
138
|
|
@@ -20,7 +20,7 @@ module Kennel
|
|
20
20
|
def validated_parts
|
21
21
|
all = parts
|
22
22
|
unless all.is_a?(Array) && all.all? { |part| part.is_a?(Record) }
|
23
|
-
|
23
|
+
raise "Project #{kennel_id} #parts must return an array of Records"
|
24
24
|
end
|
25
25
|
|
26
26
|
validate_parts(all)
|
@@ -29,11 +29,6 @@ module Kennel
|
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
-
# let users know which project/resource failed when something happens during diffing where the backtrace is hidden
|
33
|
-
def invalid!(message)
|
34
|
-
raise ValidationError, "#{kennel_id} #{message}"
|
35
|
-
end
|
36
|
-
|
37
32
|
# hook for users to add custom validations via `prepend`
|
38
33
|
def validate_parts(parts)
|
39
34
|
end
|
data/lib/kennel/models/record.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
module Kennel
|
3
3
|
module Models
|
4
4
|
class Record < Base
|
5
|
+
include OptionalValidations
|
6
|
+
|
5
7
|
# Apart from if you just don't like the default for some reason,
|
6
8
|
# overriding MARKER_TEXT allows for namespacing within the same
|
7
9
|
# Datadog account. If you run one Kennel setup with marker text
|
@@ -30,6 +32,8 @@ module Kennel
|
|
30
32
|
|
31
33
|
settings :id, :kennel_id
|
32
34
|
|
35
|
+
defaults(id: nil)
|
36
|
+
|
33
37
|
class << self
|
34
38
|
def parse_any_url(url)
|
35
39
|
subclasses.detect do |s|
|
@@ -96,7 +100,7 @@ module Kennel
|
|
96
100
|
@tracking_id ||= begin
|
97
101
|
id = "#{project.kennel_id}:#{kennel_id}"
|
98
102
|
unless id.match?(ALLOWED_KENNEL_ID_REGEX) # <-> parse_tracking_id
|
99
|
-
raise
|
103
|
+
raise "#{id} must match #{ALLOWED_KENNEL_ID_REGEX}"
|
100
104
|
end
|
101
105
|
id
|
102
106
|
end
|
@@ -108,7 +112,7 @@ module Kennel
|
|
108
112
|
def add_tracking_id
|
109
113
|
json = as_json
|
110
114
|
if self.class.parse_tracking_id(json)
|
111
|
-
|
115
|
+
raise "#{tracking_id} Remove \"-- #{MARKER_TEXT}\" line from #{self.class::TRACKING_FIELD} to copy a resource"
|
112
116
|
end
|
113
117
|
json[self.class::TRACKING_FIELD] =
|
114
118
|
"#{json[self.class::TRACKING_FIELD]}\n" \
|
@@ -119,9 +123,29 @@ module Kennel
|
|
119
123
|
self.class.remove_tracking_id(as_json)
|
120
124
|
end
|
121
125
|
|
126
|
+
def build_json
|
127
|
+
{
|
128
|
+
id: id
|
129
|
+
}.compact
|
130
|
+
end
|
131
|
+
|
132
|
+
def as_json
|
133
|
+
@as_json ||= begin
|
134
|
+
json = build_json
|
135
|
+
(id = json.delete(:id)) && json[:id] = id
|
136
|
+
validate_json(json) if validate
|
137
|
+
json
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Can raise DisallowedUpdateError
|
122
142
|
def validate_update!(*)
|
123
143
|
end
|
124
144
|
|
145
|
+
def invalid_update!(field, old_value, new_value)
|
146
|
+
raise DisallowedUpdateError, "#{tracking_id} Datadog does not allow update of #{field} (#{old_value.inspect} -> #{new_value.inspect})"
|
147
|
+
end
|
148
|
+
|
125
149
|
private
|
126
150
|
|
127
151
|
def resolve(value, type, id_map, force:)
|
@@ -133,20 +157,24 @@ module Kennel
|
|
133
157
|
id.is_a?(String) && id.include?(":")
|
134
158
|
end
|
135
159
|
|
136
|
-
def resolve_link(
|
137
|
-
if id_map.new?(
|
160
|
+
def resolve_link(sought_tracking_id, sought_type, id_map, force:)
|
161
|
+
if id_map.new?(sought_type.to_s, sought_tracking_id)
|
138
162
|
if force
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
163
|
+
raise UnresolvableIdError, <<~MESSAGE
|
164
|
+
#{tracking_id} #{sought_type} #{sought_tracking_id} was referenced but is also created by the current run.
|
165
|
+
It could not be created because of a circular dependency. Try creating only some of the resources.
|
166
|
+
MESSAGE
|
143
167
|
else
|
144
168
|
nil # will be re-resolved after the linked object was created
|
145
169
|
end
|
146
|
-
elsif id = id_map.get(
|
170
|
+
elsif id = id_map.get(sought_type.to_s, sought_tracking_id)
|
147
171
|
id
|
148
172
|
else
|
149
|
-
|
173
|
+
raise UnresolvableIdError, <<~MESSAGE
|
174
|
+
#{tracking_id} Unable to find #{sought_type} #{sought_tracking_id}
|
175
|
+
This is either because it doesn't exist, and isn't being created by the current run;
|
176
|
+
or it does exist, but is being deleted.
|
177
|
+
MESSAGE
|
150
178
|
end
|
151
179
|
end
|
152
180
|
|
data/lib/kennel/models/slo.rb
CHANGED
@@ -15,7 +15,6 @@ module Kennel
|
|
15
15
|
settings :type, :description, :thresholds, :query, :tags, :monitor_ids, :monitor_tags, :name, :groups
|
16
16
|
|
17
17
|
defaults(
|
18
|
-
id: -> { nil },
|
19
18
|
tags: -> { @project.tags },
|
20
19
|
query: -> { DEFAULTS.fetch(:query) },
|
21
20
|
description: -> { DEFAULTS.fetch(:description) },
|
@@ -24,35 +23,25 @@ module Kennel
|
|
24
23
|
groups: -> { DEFAULTS.fetch(:groups) }
|
25
24
|
)
|
26
25
|
|
27
|
-
def
|
28
|
-
super
|
29
|
-
if thresholds.any? { |t| t[:warning] && t[:warning].to_f <= t[:critical].to_f }
|
30
|
-
raise ValidationError, "Threshold warning must be greater-than critical value"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def as_json
|
35
|
-
return @as_json if @as_json
|
36
|
-
data = {
|
26
|
+
def build_json
|
27
|
+
data = super.merge(
|
37
28
|
name: "#{name}#{LOCK}",
|
38
29
|
description: description,
|
39
30
|
thresholds: thresholds,
|
40
31
|
monitor_ids: monitor_ids,
|
41
32
|
tags: tags.uniq,
|
42
33
|
type: type
|
43
|
-
|
34
|
+
)
|
44
35
|
|
45
36
|
if v = query
|
46
37
|
data[:query] = v
|
47
38
|
end
|
48
|
-
|
49
|
-
data[:id] = v
|
50
|
-
end
|
39
|
+
|
51
40
|
if v = groups
|
52
41
|
data[:groups] = v
|
53
42
|
end
|
54
43
|
|
55
|
-
|
44
|
+
data
|
56
45
|
end
|
57
46
|
|
58
47
|
def self.api_resource
|
@@ -89,6 +78,16 @@ module Kennel
|
|
89
78
|
|
90
79
|
ignore_default(expected, actual, DEFAULTS)
|
91
80
|
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def validate_json(data)
|
85
|
+
super
|
86
|
+
|
87
|
+
if data[:thresholds].any? { |t| t[:warning] && t[:warning].to_f <= t[:critical].to_f }
|
88
|
+
invalid! "Threshold warning must be greater-than critical value"
|
89
|
+
end
|
90
|
+
end
|
92
91
|
end
|
93
92
|
end
|
94
93
|
end
|
@@ -11,15 +11,14 @@ module Kennel
|
|
11
11
|
settings :tags, :config, :message, :subtype, :type, :name, :locations, :options
|
12
12
|
|
13
13
|
defaults(
|
14
|
-
id: -> { nil },
|
15
14
|
tags: -> { @project.tags },
|
16
15
|
message: -> { "\n\n#{project.mention}" }
|
17
16
|
)
|
18
17
|
|
19
|
-
def
|
20
|
-
return @as_json if @as_json
|
18
|
+
def build_json
|
21
19
|
locations = locations()
|
22
|
-
|
20
|
+
|
21
|
+
super.merge(
|
23
22
|
message: message,
|
24
23
|
tags: tags,
|
25
24
|
config: config,
|
@@ -28,13 +27,7 @@ module Kennel
|
|
28
27
|
options: options,
|
29
28
|
name: "#{name}#{LOCK}",
|
30
29
|
locations: locations == :all ? LOCATIONS : locations
|
31
|
-
|
32
|
-
|
33
|
-
if v = id
|
34
|
-
data[:id] = v
|
35
|
-
end
|
36
|
-
|
37
|
-
@as_json = data
|
30
|
+
)
|
38
31
|
end
|
39
32
|
|
40
33
|
def self.api_resource
|
data/lib/kennel/progress.rb
CHANGED
@@ -4,7 +4,9 @@ require "benchmark"
|
|
4
4
|
module Kennel
|
5
5
|
class Progress
|
6
6
|
# print what we are doing and a spinner until it is done ... then show how long it took
|
7
|
-
def self.progress(name)
|
7
|
+
def self.progress(name, interval: 0.2, &block)
|
8
|
+
return progress_no_tty(name, &block) unless Kennel.err.tty?
|
9
|
+
|
8
10
|
Kennel.err.print "#{name} ... "
|
9
11
|
|
10
12
|
stop = false
|
@@ -16,15 +18,20 @@ module Kennel
|
|
16
18
|
loop do
|
17
19
|
break if stop
|
18
20
|
Kennel.err.print animation[count % animation.size]
|
19
|
-
sleep
|
21
|
+
sleep interval
|
20
22
|
Kennel.err.print "\b"
|
21
23
|
count += 1
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
|
-
time = Benchmark.realtime { result =
|
27
|
+
time = Benchmark.realtime { result = block.call }
|
26
28
|
|
27
29
|
stop = true
|
30
|
+
begin
|
31
|
+
spinner.run # wake thread, so it stops itself
|
32
|
+
rescue ThreadError
|
33
|
+
# thread was already dead, but we can't check with .alive? since it's a race condition
|
34
|
+
end
|
28
35
|
spinner.join
|
29
36
|
Kennel.err.print "#{time.round(2)}s\n"
|
30
37
|
|
@@ -32,5 +39,17 @@ module Kennel
|
|
32
39
|
ensure
|
33
40
|
stop = true # make thread stop without killing it
|
34
41
|
end
|
42
|
+
|
43
|
+
class << self
|
44
|
+
private
|
45
|
+
|
46
|
+
def progress_no_tty(name)
|
47
|
+
Kennel.err.puts "#{name} ..."
|
48
|
+
result = nil
|
49
|
+
time = Benchmark.realtime { result = yield }
|
50
|
+
Kennel.err.puts "#{name} ... #{time.round(2)}s"
|
51
|
+
result
|
52
|
+
end
|
53
|
+
end
|
35
54
|
end
|
36
55
|
end
|
data/lib/kennel/syncer.rb
CHANGED
@@ -42,7 +42,7 @@ module Kennel
|
|
42
42
|
|
43
43
|
def confirm
|
44
44
|
return false if noop?
|
45
|
-
return true if ENV["CI"] || !STDIN.tty?
|
45
|
+
return true if ENV["CI"] || !STDIN.tty? || !Kennel.err.tty?
|
46
46
|
Utils.ask("Execute Plan ?")
|
47
47
|
end
|
48
48
|
|
@@ -104,11 +104,11 @@ module Kennel
|
|
104
104
|
def resolved?(e)
|
105
105
|
assert_resolved e
|
106
106
|
true
|
107
|
-
rescue
|
107
|
+
rescue UnresolvableIdError
|
108
108
|
false
|
109
109
|
end
|
110
110
|
|
111
|
-
# raises
|
111
|
+
# raises UnresolvableIdError when not resolved
|
112
112
|
def assert_resolved(e)
|
113
113
|
resolve_linked_tracking_ids! [e], force: true
|
114
114
|
end
|
data/lib/kennel/tasks.rb
CHANGED
@@ -233,6 +233,17 @@ namespace :kennel do
|
|
233
233
|
end
|
234
234
|
end
|
235
235
|
|
236
|
+
desc "Resolve given id to kennel tracking-id RESOURCE= ID="
|
237
|
+
task tracking_id: "kennel:environment" do
|
238
|
+
resource = ENV.fetch("RESOURCE")
|
239
|
+
id = ENV.fetch("ID")
|
240
|
+
klass =
|
241
|
+
Kennel::Models::Record.subclasses.detect { |s| s.api_resource == resource } ||
|
242
|
+
raise("resource #{resource} not know")
|
243
|
+
object = Kennel.send(:api).show(resource, id)
|
244
|
+
Kennel.out.puts klass.parse_tracking_id(object)
|
245
|
+
end
|
246
|
+
|
236
247
|
task :environment do
|
237
248
|
Kennel::Tasks.load_environment
|
238
249
|
end
|
data/lib/kennel/utils.rb
CHANGED
@@ -42,7 +42,7 @@ module Kennel
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def ask(question)
|
45
|
-
Kennel.err.printf color(:red, "#{question} - press 'y' to continue: ")
|
45
|
+
Kennel.err.printf color(:red, "#{question} - press 'y' to continue: ", force: true)
|
46
46
|
begin
|
47
47
|
STDIN.gets.chomp == "y"
|
48
48
|
rescue Interrupt # do not show a backtrace if user decides to Ctrl+C here
|
@@ -51,12 +51,10 @@ module Kennel
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
def color(color, text)
|
55
|
-
|
56
|
-
end
|
54
|
+
def color(color, text, force: false)
|
55
|
+
return text unless force || Kennel.out.tty?
|
57
56
|
|
58
|
-
|
59
|
-
text.gsub(/\e\[\d+m(.*?)\e\[0m/, "\\1").gsub(/.#{Regexp.escape("\b")}/, "")
|
57
|
+
"\e[#{COLORS.fetch(color)}m#{text}\e[0m"
|
60
58
|
end
|
61
59
|
|
62
60
|
def capture_stdout
|
data/lib/kennel/version.rb
CHANGED
data/lib/kennel.rb
CHANGED
@@ -40,8 +40,9 @@ module Teams
|
|
40
40
|
end
|
41
41
|
|
42
42
|
module Kennel
|
43
|
-
|
44
|
-
|
43
|
+
ValidationError = Class.new(RuntimeError)
|
44
|
+
UnresolvableIdError = Class.new(RuntimeError)
|
45
|
+
DisallowedUpdateError = Class.new(RuntimeError)
|
45
46
|
|
46
47
|
include Kennel::Compatibility
|
47
48
|
|
data/template/Readme.md
CHANGED
@@ -388,3 +388,11 @@ https://foo.datadog.com/monitor/123
|
|
388
388
|
### Find all monitors with No-Data
|
389
389
|
`rake kennel:nodata TAG=team:foo`
|
390
390
|
|
391
|
+
### Finding the tracking id of a resource
|
392
|
+
|
393
|
+
When trying to link resources together, this avoids having to go through datadog UI.
|
394
|
+
|
395
|
+
```Bash
|
396
|
+
rake kennel:tracking_id ID=123 RESOURCE=monitor
|
397
|
+
```
|
398
|
+
|
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.123.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: 2022-
|
11
|
+
date: 2022-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: diff-lcs
|