kennel 1.18.2 → 1.19.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 734334b788520b60627349b1938a3ff689a7a7f70a73ea2ae89461c0e0ec36e8
4
- data.tar.gz: 72996467fb2c1f1ca7a3af55e0e7a70f28c8db29173dedb5ccb0e9010137ec58
3
+ metadata.gz: ce664560cea8f70dc49a11711f81a38faab96a425439fc0e58afa0e35318ddf6
4
+ data.tar.gz: 761f7741b0787dea3d09bc22b15467f8fa5b3626504a593e93d4edd6728a6088
5
5
  SHA512:
6
- metadata.gz: 2cf10e3bfa2a185ced7fcd831cff8fdac2405a99a053d9c6eb58507fcb06acdf7b73597cd10a77674ce3c57cdd4346ff9651f0b2f56428e690ee2546cbe4cae2
7
- data.tar.gz: e9b6b44dbf0e83613ed4492e21cd521105777286e3e094e917baf02d9ada504971396ca176c22856ed8ac33501f7066c98917e8366752c0bfa0ae27e9a6ec05e
6
+ metadata.gz: d6e9573898edfd15e5fb34f1ab749b6bc5a8f4f70a75d855e229dc9a98af66c30a748b348d4095b7d361bb8f71cda6b75448e08c4cc9f1efda7b6312bf32d791
7
+ data.tar.gz: 0e42c01940e220d1a4fce162419b4c9279ead3a1f751f74b4ae15033c2399773ed2886779189b2ea93411963ae3e87da230a2656d1dcd21a20de6a26291f1a2e
@@ -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
- data = @api.show(resource, id)
16
- case resource
17
- when "dash"
18
- data = data[:dash]
19
- IGNORED.each { |k| data.delete(k) }
20
- <<~RUBY
21
- Kennel::Models::Dash.new(
22
- self,
23
- #{pretty_print(data).lstrip}
24
- )
25
- RUBY
26
- else
27
- raise ArgumentError, "#{resource} is not supported"
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
@@ -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
- READONLY_ATTRIBUTES.each { |k| actual.delete k }
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}"
@@ -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 diff(actual)
48
- actual.delete :resource
49
- actual.delete :created_by
50
- actual[:template_variables] ||= []
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 as_json, actual, :graphs, :definition
55
- super
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.fetch(:template_variables).map { |v| "$#{v.fetch(:name)}" }
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
- all = definitions.map do |title, viz, type, queries, options = {}, ignored = nil|
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 diff(actual)
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
@@ -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 diff(actual)
50
- actual.delete(:disableCog)
51
- actual.delete(:disableEditing)
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
- ignore_defaults as_json[:widgets], actual[:widgets], WIDGET_DEFAULTS
75
- ignore_request_defaults as_json, actual, :widgets, :tile_def
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
@@ -7,7 +7,8 @@ module Kennel
7
7
  COLORS = {
8
8
  "Alert" => :red,
9
9
  "Warn" => :yellow,
10
- "No Data" => :cyan
10
+ "No Data" => :cyan,
11
+ "Ignored" => :magenta # resolved but still broken
11
12
  }.freeze
12
13
 
13
14
  class << self
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)
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Kennel
3
- VERSION = "1.18.2"
3
+ VERSION = "1.19.0"
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.18.2
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-12 00:00:00.000000000 Z
11
+ date: 2018-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday