kennel 1.48.0 → 1.52.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Readme.md +1 -0
- data/lib/kennel/importer.rb +18 -0
- data/lib/kennel/models/base.rb +7 -0
- data/lib/kennel/models/dashboard.rb +24 -11
- data/lib/kennel/models/monitor.rb +10 -0
- data/lib/kennel/syncer.rb +14 -3
- data/lib/kennel/tasks.rb +8 -0
- data/lib/kennel/version.rb +1 -1
- 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: 7d34d639d4d27f3953211bc4f94f36d559b5ada87d3f289219bf611c8183805d
|
4
|
+
data.tar.gz: c531670c166981073648ae9e12f1ca6c47f27a5642a4b8abf0fc5890134bcead
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e4f308f0076d4cc5f290c5041fc37a57a64986fb1d0ec586bf448b9293880fd42e67b6d6de60607369f2918efc7aeb87177fd7a27a1749ca272fdb2c5519d0f
|
7
|
+
data.tar.gz: e1852e1d4c0cceb841f73559ae248357ce5d1fdfe81e3d8a0a348374d2f1e6819befbc9fcdec0caae00cc72808430f91fd10d46b7dd88fe57b721faf55e1d882
|
data/Readme.md
CHANGED
@@ -160,6 +160,7 @@ To link to existing monitors via their kennel_id
|
|
160
160
|
|
161
161
|
- Screens `uptime` widgets can use `monitor: {id: "foo:bar"}`
|
162
162
|
- Screens `alert_graph` widgets can use `alert_id: "foo:bar"`
|
163
|
+
- Monitors `composite` can use `query: -> { "%{foo:bar} || %{foo:baz}" }`
|
163
164
|
|
164
165
|
### Debugging changes locally
|
165
166
|
|
data/lib/kennel/importer.rb
CHANGED
@@ -53,6 +53,9 @@ module Kennel
|
|
53
53
|
if query && critical
|
54
54
|
query.sub!(/([><=]) (#{Regexp.escape(critical.to_f.to_s)}|#{Regexp.escape(critical.to_i.to_s)})$/, "\\1 \#{critical}")
|
55
55
|
end
|
56
|
+
elsif resource == "dashboard"
|
57
|
+
widgets = data[:widgets]&.flat_map { |widget| widget.dig(:definition, :widgets) || [widget] }
|
58
|
+
widgets&.each { |widget| dry_up_query!(widget) }
|
56
59
|
end
|
57
60
|
|
58
61
|
# simplify template_variables to array of string when possible
|
@@ -71,6 +74,20 @@ module Kennel
|
|
71
74
|
|
72
75
|
private
|
73
76
|
|
77
|
+
# reduce duplication in imports by using dry `q: :metadata` when possible
|
78
|
+
def dry_up_query!(widget)
|
79
|
+
(widget.dig(:definition, :requests) || []).each do |request|
|
80
|
+
next unless request.is_a?(Hash)
|
81
|
+
next unless metadata = request[:metadata]
|
82
|
+
next unless query = request[:q]&.dup
|
83
|
+
metadata.each do |m|
|
84
|
+
next unless exp = m[:expression]
|
85
|
+
query.sub!(exp, "")
|
86
|
+
end
|
87
|
+
request[:q] = :metadata if query.delete(", ") == ""
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
74
91
|
def pretty_print(hash)
|
75
92
|
sort_widgets hash
|
76
93
|
|
@@ -84,6 +101,7 @@ module Kennel
|
|
84
101
|
.gsub(/(^\s*)"([a-zA-Z][a-zA-Z\d_]*)":/, "\\1\\2:") # "foo": 1 -> foo: 1
|
85
102
|
.gsub(/: \[\n\s+\]/, ": []") # empty arrays on a single line
|
86
103
|
.gsub(/^/, " ") # indent
|
104
|
+
.gsub('q: "metadata"', "q: :metadata") # bring symbols back
|
87
105
|
|
88
106
|
"\n#{pretty}\n "
|
89
107
|
elsif k == :message
|
data/lib/kennel/models/base.rb
CHANGED
@@ -148,6 +148,13 @@ module Kennel
|
|
148
148
|
|
149
149
|
private
|
150
150
|
|
151
|
+
def resolve_link(id, id_map, force:)
|
152
|
+
id_map[id] || begin
|
153
|
+
message = "Unable to find #{id} in existing monitors (they need to be created first to link them)"
|
154
|
+
force ? invalid!(message) : Kennel.err.puts(message)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
151
158
|
# let users know which project/resource failed when something happens during diffing where the backtrace is hidden
|
152
159
|
def invalid!(message)
|
153
160
|
raise ValidationError, "#{tracking_id} #{message}"
|
@@ -39,7 +39,7 @@ module Kennel
|
|
39
39
|
pair.each do |b|
|
40
40
|
b[:widgets]&.each do |w|
|
41
41
|
if formats = w.dig(:definition, :conditional_formats)
|
42
|
-
w[:definition][:conditional_formats] = formats.sort_by
|
42
|
+
w[:definition][:conditional_formats] = formats.sort_by(&:hash)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
@@ -73,12 +73,15 @@ module Kennel
|
|
73
73
|
|
74
74
|
def as_json
|
75
75
|
return @json if @json
|
76
|
+
all_widgets = render_definitions + widgets
|
77
|
+
expand_q all_widgets
|
78
|
+
|
76
79
|
@json = {
|
77
80
|
layout_type: layout_type,
|
78
81
|
title: "#{title}#{LOCK}",
|
79
82
|
description: description,
|
80
83
|
template_variables: render_template_variables,
|
81
|
-
widgets:
|
84
|
+
widgets: all_widgets
|
82
85
|
}
|
83
86
|
|
84
87
|
@json[:id] = id if id
|
@@ -98,11 +101,13 @@ module Kennel
|
|
98
101
|
case definition[:type]
|
99
102
|
when "uptime"
|
100
103
|
if ids = definition[:monitor_ids]
|
101
|
-
definition[:monitor_ids] = ids.map
|
104
|
+
definition[:monitor_ids] = ids.map do |id|
|
105
|
+
tracking_id?(id) ? resolve_link(id, id_map, force: false) : id
|
106
|
+
end
|
102
107
|
end
|
103
108
|
when "alert_graph"
|
104
|
-
if id = definition[:alert_id]
|
105
|
-
definition[:alert_id] = resolve_link(id, id_map).to_s
|
109
|
+
if (id = definition[:alert_id]) && tracking_id?(id)
|
110
|
+
definition[:alert_id] = resolve_link(id, id_map, force: false).to_s
|
106
111
|
end
|
107
112
|
end
|
108
113
|
end
|
@@ -110,16 +115,24 @@ module Kennel
|
|
110
115
|
|
111
116
|
private
|
112
117
|
|
113
|
-
def resolve_link(id, id_map)
|
114
|
-
return id unless tracking_id?(id)
|
115
|
-
id_map[id] ||
|
116
|
-
Kennel.err.puts("Unable to find #{id} in existing monitors (they need to be created first to link them)")
|
117
|
-
end
|
118
|
-
|
119
118
|
def tracking_id?(id)
|
120
119
|
id.is_a?(String) && !id.match?(/\A\d+\z/)
|
121
120
|
end
|
122
121
|
|
122
|
+
# creates queries from metadata to avoid having to keep q and expression in sync
|
123
|
+
#
|
124
|
+
# {q: :metadata, metadata: [{expression: "sum:bar", alias_name: "foo"}, ...], }
|
125
|
+
# -> {q: "sum:bar, ...", metadata: ..., }
|
126
|
+
def expand_q(widgets)
|
127
|
+
widgets = widgets.flat_map { |w| w.dig(:definition, :widgets) || w } # expand groups
|
128
|
+
widgets.each do |w|
|
129
|
+
w.dig(:definition, :requests)&.each do |request|
|
130
|
+
next unless request.is_a?(Hash) && request[:q] == :metadata
|
131
|
+
request[:q] = request.fetch(:metadata).map { |m| m.fetch(:expression) }.join(", ")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
123
136
|
def validate_json(data)
|
124
137
|
super
|
125
138
|
|
@@ -108,6 +108,16 @@ module Kennel
|
|
108
108
|
@as_json = data
|
109
109
|
end
|
110
110
|
|
111
|
+
# resolve composite monitors ... only works when referenced monitors already exist
|
112
|
+
# since leaving names or bad ids in the query breaks the monitor update
|
113
|
+
def resolve_linked_tracking_ids(id_map)
|
114
|
+
if as_json[:type] == "composite"
|
115
|
+
as_json[:query] = as_json[:query].gsub(/%\{(.*?)\}/) do
|
116
|
+
resolve_link($1, id_map, force: true)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
111
121
|
def self.api_resource
|
112
122
|
"monitor"
|
113
123
|
end
|
data/lib/kennel/syncer.rb
CHANGED
@@ -72,11 +72,22 @@ module Kennel
|
|
72
72
|
filter_by_project! actual
|
73
73
|
|
74
74
|
details_cache do |cache|
|
75
|
-
actual.
|
76
|
-
id = a.fetch(:id)
|
75
|
+
items = actual.map do |a|
|
77
76
|
e = matching_expected(a)
|
78
77
|
if e && @expected.delete(e)
|
79
|
-
|
78
|
+
[e, a]
|
79
|
+
else
|
80
|
+
[nil, a]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# fill details of things we need to compare (only do this part in parallel for safety & balancing)
|
85
|
+
Utils.parallel(items.select { |e, _| e && e.class::API_LIST_INCOMPLETE }) { |_, a| fill_details(a, cache) }
|
86
|
+
|
87
|
+
# pick out things to update or delete
|
88
|
+
items.each do |e, a|
|
89
|
+
id = a.fetch(:id)
|
90
|
+
if e
|
80
91
|
diff = e.diff(a)
|
81
92
|
@update << [id, e, a, diff] if diff.any?
|
82
93
|
elsif tracking_id(a) # was previously managed
|
data/lib/kennel/tasks.rb
CHANGED
@@ -55,6 +55,14 @@ namespace :kennel do
|
|
55
55
|
tag = ENV["TAG"] || abort("Call with TAG=foo:bar")
|
56
56
|
monitors = Kennel.send(:api).list("monitor", monitor_tags: tag, group_states: "no data")
|
57
57
|
monitors.select! { |m| m[:overall_state] == "No Data" }
|
58
|
+
monitors.reject! { |m| m[:tags].include? ["nodata:ignore"] }
|
59
|
+
if monitors.any?
|
60
|
+
Kennel.err.puts <<~TEXT
|
61
|
+
This is a useful task to find monitors that have mis-spelled metrics or never received data at any time.
|
62
|
+
To ignore monitors with nodata, tag the monitor with "nodata:ignore"
|
63
|
+
|
64
|
+
TEXT
|
65
|
+
end
|
58
66
|
|
59
67
|
monitors.each do |m|
|
60
68
|
Kennel.out.puts m[:name]
|
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.52.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-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|