kennel 1.18.2 → 1.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kennel/importer.rb +26 -18
- data/lib/kennel/models/base.rb +33 -22
- data/lib/kennel/models/dash.rb +18 -15
- data/lib/kennel/models/monitor.rb +2 -3
- data/lib/kennel/models/screen.rb +24 -21
- data/lib/kennel/unmuted_alerts.rb +2 -1
- data/lib/kennel/utils.rb +1 -1
- 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: ce664560cea8f70dc49a11711f81a38faab96a425439fc0e58afa0e35318ddf6
|
4
|
+
data.tar.gz: 761f7741b0787dea3d09bc22b15467f8fa5b3626504a593e93d4edd6728a6088
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6e9573898edfd15e5fb34f1ab749b6bc5a8f4f70a75d855e229dc9a98af66c30a748b348d4095b7d361bb8f71cda6b75448e08c4cc9f1efda7b6312bf32d791
|
7
|
+
data.tar.gz: 0e42c01940e220d1a4fce162419b4c9279ead3a1f751f74b4ae15033c2399773ed2886779189b2ea93411963ae3e87da230a2656d1dcd21a20de6a26291f1a2e
|
data/lib/kennel/importer.rb
CHANGED
@@ -2,36 +2,44 @@
|
|
2
2
|
|
3
3
|
module Kennel
|
4
4
|
class Importer
|
5
|
-
SORT_ORDER = [:title, :id, :description, :template_variables].freeze
|
6
|
-
|
7
|
-
# TODO: make model diff normalization reusable
|
8
|
-
IGNORED = Models::Base::READONLY_ATTRIBUTES - [:id] + [:created_by, :read_only]
|
5
|
+
SORT_ORDER = [:title, :name, :board_title, :id, :query, :message, :description, :template_variables].freeze
|
9
6
|
|
10
7
|
def initialize(api)
|
11
8
|
@api = api
|
12
9
|
end
|
13
10
|
|
14
11
|
def import(resource, id)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
12
|
+
model =
|
13
|
+
begin
|
14
|
+
Kennel::Models.const_get(resource.capitalize)
|
15
|
+
rescue NameError
|
16
|
+
raise ArgumentError, "#{resource} is not supported"
|
17
|
+
end
|
18
|
+
|
19
|
+
data = @api.show(model.api_resource, id)
|
20
|
+
data = data[resource.to_sym] || data
|
21
|
+
model.normalize({}, data)
|
22
|
+
data[:id] = id
|
23
|
+
|
24
|
+
# flatten monitor options so they are all on the base
|
25
|
+
if resource == "monitor"
|
26
|
+
data.merge!(data.delete(:options))
|
27
|
+
data.merge!(data.delete(:thresholds) || {})
|
28
|
+
data = data.slice(*model.instance_methods)
|
28
29
|
end
|
30
|
+
|
31
|
+
<<~RUBY
|
32
|
+
#{model.name}.new(
|
33
|
+
self,
|
34
|
+
#{pretty_print(data).lstrip}
|
35
|
+
)
|
36
|
+
RUBY
|
29
37
|
end
|
30
38
|
|
31
39
|
private
|
32
40
|
|
33
41
|
def pretty_print(hash)
|
34
|
-
list = hash.sort_by { |k, _| SORT_ORDER.index(k) || 999 }
|
42
|
+
list = hash.sort_by { |k, _| [SORT_ORDER.index(k) || 999, k] } # important to the front and rest deterministic
|
35
43
|
list.map do |k, v|
|
36
44
|
case v
|
37
45
|
when Hash, Array
|
data/lib/kennel/models/base.rb
CHANGED
@@ -53,6 +53,38 @@ module Kennel
|
|
53
53
|
supported = @set.map(&:inspect)
|
54
54
|
raise ArgumentError, "Unsupported setting #{name.inspect}, supported settings are #{supported.join(", ")}"
|
55
55
|
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def normalize(_expected, actual)
|
60
|
+
self::READONLY_ATTRIBUTES.each { |k| actual.delete k }
|
61
|
+
end
|
62
|
+
|
63
|
+
# discard styles/conditional_formats/aggregator if nothing would change when we applied (both are default or nil)
|
64
|
+
def ignore_request_defaults(expected, actual, level1, level2)
|
65
|
+
(actual[level1] || []).each_with_index do |a_w, wi|
|
66
|
+
a_r = a_w.dig(level2, :requests) || []
|
67
|
+
e_r = expected.dig(level1, wi, level2, :requests) || []
|
68
|
+
ignore_defaults e_r, a_r, REQUEST_DEFAULTS
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def ignore_defaults(expected, actual, defaults)
|
73
|
+
(expected || []).each_with_index do |e, i|
|
74
|
+
a = actual[i] || {}
|
75
|
+
ignore_default(e, a, defaults)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def ignore_default(expected, actual, defaults)
|
80
|
+
definitions = [actual, expected]
|
81
|
+
defaults.each do |key, default|
|
82
|
+
if definitions.all? { |r| !r.key?(key) || r[key] == default }
|
83
|
+
actual.delete(key)
|
84
|
+
expected.delete(key)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
56
88
|
end
|
57
89
|
|
58
90
|
def initialize(options = {})
|
@@ -86,7 +118,7 @@ module Kennel
|
|
86
118
|
expected = as_json
|
87
119
|
expected.delete(:id)
|
88
120
|
|
89
|
-
|
121
|
+
self.class.send(:normalize, expected, actual)
|
90
122
|
|
91
123
|
HashDiff.diff(actual, expected, use_lcs: false)
|
92
124
|
end
|
@@ -101,27 +133,6 @@ module Kennel
|
|
101
133
|
|
102
134
|
private
|
103
135
|
|
104
|
-
# discard styles/conditional_formats/aggregator if nothing would change when we applied (both are default or nil)
|
105
|
-
def ignore_request_defaults(expected, actual, level1, level2)
|
106
|
-
expected[level1].each_with_index do |e_w, wi|
|
107
|
-
e_r = e_w.dig(level2, :requests) || []
|
108
|
-
a_r = actual.dig(level1, wi, level2, :requests) || []
|
109
|
-
ignore_defaults e_r, a_r, REQUEST_DEFAULTS
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def ignore_defaults(expected, actual, defaults)
|
114
|
-
expected.each_with_index do |e, i|
|
115
|
-
next unless a = actual[i] # skip newly added
|
116
|
-
defaults.each do |key, default|
|
117
|
-
if [a, e].all? { |r| r[key].nil? || r[key] == default }
|
118
|
-
a.delete(key)
|
119
|
-
e.delete(key)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
136
|
# let users know which project/resource failed when something happens during diffing where the backtrace is hidden
|
126
137
|
def invalid!(message)
|
127
138
|
raise ValidationError, "#{tracking_id} #{message}"
|
data/lib/kennel/models/dash.rb
CHANGED
@@ -7,6 +7,10 @@ module Kennel
|
|
7
7
|
|
8
8
|
API_LIST_INCOMPLETE = true
|
9
9
|
SUPPORTED_GRAPH_OPTIONS = [:events, :markers].freeze
|
10
|
+
READONLY_ATTRIBUTES = (Base::READONLY_ATTRIBUTES + [:resource, :created_by, :read_only]).freeze
|
11
|
+
DEFINITION_DEFAULTS = { autoscale: true }.freeze
|
12
|
+
DASH_DEFAULTS = { template_variables: [] }.freeze
|
13
|
+
|
10
14
|
settings :id, :title, :description, :graphs, :kennel_id, :graphs, :definitions
|
11
15
|
|
12
16
|
defaults(
|
@@ -34,7 +38,6 @@ module Kennel
|
|
34
38
|
id: id,
|
35
39
|
title: "#{title}#{LOCK}",
|
36
40
|
description: description,
|
37
|
-
read_only: false, # TODO: delete it instead
|
38
41
|
template_variables: render_template_variables,
|
39
42
|
graphs: render_graphs
|
40
43
|
}
|
@@ -44,15 +47,20 @@ module Kennel
|
|
44
47
|
@json
|
45
48
|
end
|
46
49
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
actual
|
51
|
-
actual[:graphs].each do |g|
|
50
|
+
def self.normalize(expected, actual)
|
51
|
+
super
|
52
|
+
|
53
|
+
ignore_default expected, actual, DASH_DEFAULTS
|
54
|
+
(actual[:graphs] || {}).each do |g|
|
52
55
|
g[:definition].delete(:status)
|
53
56
|
end
|
54
|
-
ignore_request_defaults
|
55
|
-
|
57
|
+
ignore_request_defaults expected, actual, :graphs, :definition
|
58
|
+
|
59
|
+
(actual[:graphs] || []).each_with_index do |a_g, i|
|
60
|
+
a_d = a_g[:definition] || {}
|
61
|
+
e_d = expected.dig(:graphs, i, :definition) || {}
|
62
|
+
ignore_default e_d, a_d, DEFINITION_DEFAULTS
|
63
|
+
end
|
56
64
|
end
|
57
65
|
|
58
66
|
def url(id)
|
@@ -64,7 +72,7 @@ module Kennel
|
|
64
72
|
def validate_json(data)
|
65
73
|
# check for bad variables
|
66
74
|
# TODO: do the same check for apm_query and their group_by
|
67
|
-
variables = data
|
75
|
+
variables = (data[:template_variables] || []).map { |v| "$#{v.fetch(:name)}" }
|
68
76
|
queries = data[:graphs].flat_map { |g| g[:definition][:requests].map { |r| r[:q] }.compact }
|
69
77
|
bad = queries.grep_v(/(#{variables.map { |v| Regexp.escape(v) }.join("|")})\b/)
|
70
78
|
if bad.any?
|
@@ -86,7 +94,7 @@ module Kennel
|
|
86
94
|
end
|
87
95
|
|
88
96
|
def render_graphs
|
89
|
-
|
97
|
+
definitions.map do |title, viz, type, queries, options = {}, ignored = nil|
|
90
98
|
if ignored || (!title || !viz || !type || !queries || !options.is_a?(Hash))
|
91
99
|
raise ArgumentError, "Expected exactly 5 arguments for each definition (title, viz, type, queries, options)"
|
92
100
|
end
|
@@ -101,11 +109,6 @@ module Kennel
|
|
101
109
|
end
|
102
110
|
graph
|
103
111
|
end + graphs
|
104
|
-
|
105
|
-
# TODO: solve this via ignore-defaults
|
106
|
-
all.each do |g|
|
107
|
-
g[:definition][:autoscale] = true unless g[:definition].key?(:autoscale)
|
108
|
-
end
|
109
112
|
end
|
110
113
|
end
|
111
114
|
end
|
@@ -100,7 +100,8 @@ module Kennel
|
|
100
100
|
Utils.path_to_url "/monitors##{id}/edit"
|
101
101
|
end
|
102
102
|
|
103
|
-
def
|
103
|
+
def self.normalize(_expected, actual)
|
104
|
+
super
|
104
105
|
options = actual.fetch(:options)
|
105
106
|
options.delete(:silenced) # we do not manage silenced, so ignore it when diffing
|
106
107
|
options[:escalation_message] ||= nil # unset field is not returned and would break the diff
|
@@ -125,8 +126,6 @@ module Kennel
|
|
125
126
|
|
126
127
|
# nil or "" are not returned from the api
|
127
128
|
options[:evaluation_delay] ||= nil
|
128
|
-
|
129
|
-
super
|
130
129
|
end
|
131
130
|
|
132
131
|
private
|
data/lib/kennel/models/screen.rb
CHANGED
@@ -11,6 +11,23 @@ module Kennel
|
|
11
11
|
time: {},
|
12
12
|
timeframe: "1h"
|
13
13
|
}.freeze
|
14
|
+
READONLY_ATTRIBUTES = (Base::READONLY_ATTRIBUTES + [
|
15
|
+
:disableCog,
|
16
|
+
:disableEditing,
|
17
|
+
:isIntegration,
|
18
|
+
:isShared,
|
19
|
+
:original_title,
|
20
|
+
:read_only,
|
21
|
+
:resource,
|
22
|
+
:title,
|
23
|
+
:title_edited,
|
24
|
+
:created_by,
|
25
|
+
:board_bgtype,
|
26
|
+
:height,
|
27
|
+
:width,
|
28
|
+
:showGlobalTimeOnboarding
|
29
|
+
]).freeze
|
30
|
+
SCREEN_DEFAULTS = { template_variables: [] }.freeze
|
14
31
|
|
15
32
|
settings :id, :board_title, :description, :widgets, :kennel_id
|
16
33
|
|
@@ -46,22 +63,9 @@ module Kennel
|
|
46
63
|
@json
|
47
64
|
end
|
48
65
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
actual.delete(:isIntegration)
|
53
|
-
actual.delete(:isShared)
|
54
|
-
actual.delete(:original_title)
|
55
|
-
actual.delete(:read_only)
|
56
|
-
actual.delete(:resource)
|
57
|
-
actual.delete(:title)
|
58
|
-
actual.delete(:title_edited)
|
59
|
-
actual.delete(:created_by)
|
60
|
-
actual.delete(:board_bgtype)
|
61
|
-
actual.delete(:height)
|
62
|
-
actual.delete(:width)
|
63
|
-
actual.delete(:showGlobalTimeOnboarding)
|
64
|
-
actual[:template_variables] ||= []
|
66
|
+
def self.normalize(expected, actual)
|
67
|
+
super
|
68
|
+
|
65
69
|
(actual[:widgets] || []).each do |w|
|
66
70
|
# api randomly returns time.live_span or timeframe or empty time hash
|
67
71
|
if w.dig(:time, :live_span)
|
@@ -71,10 +75,9 @@ module Kennel
|
|
71
75
|
COPIED_WIDGET_VALUES.each { |v| w.delete v }
|
72
76
|
end
|
73
77
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
super
|
78
|
+
ignore_default expected, actual, SCREEN_DEFAULTS
|
79
|
+
ignore_defaults expected[:widgets], actual[:widgets], WIDGET_DEFAULTS
|
80
|
+
ignore_request_defaults expected, actual, :widgets, :tile_def
|
78
81
|
end
|
79
82
|
|
80
83
|
def url(id)
|
@@ -98,7 +101,7 @@ module Kennel
|
|
98
101
|
widgets.map do |widget|
|
99
102
|
widget = widget_defaults(widget[:type]).merge(widget)
|
100
103
|
if tile = widget[:tile_def]
|
101
|
-
tile[:autoscale] = true unless widget[:tile_def].key?(:autoscale)
|
104
|
+
tile[:autoscale] = true unless widget[:tile_def].key?(:autoscale) # TODO: use ignore_default
|
102
105
|
end
|
103
106
|
widget
|
104
107
|
end
|
data/lib/kennel/utils.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Kennel
|
3
3
|
module Utils
|
4
|
-
COLORS = { red: 31, green: 32, yellow: 33, cyan: 36, default: 0 }.freeze
|
4
|
+
COLORS = { red: 31, green: 32, yellow: 33, cyan: 36, magenta: 35, default: 0 }.freeze
|
5
5
|
|
6
6
|
class TeeIO < IO
|
7
7
|
def initialize(ios)
|
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.19.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: 2018-10-
|
11
|
+
date: 2018-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|