kennel 1.60.1 → 1.61.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d555de2128376fcfe551b2e7d95dfb724c819adc9f5b401ec155ba2d278607cb
4
- data.tar.gz: bfa004cefabf58c7328118878e0cc1ffc10253098a6176b53ce3ae295adc41c6
3
+ metadata.gz: ddec1e52bda24d78c94d0cce08ef0ec8069831d21fa7b5c708093173a1d17b7e
4
+ data.tar.gz: 16ce37dbdfdd641b358800a75c54183a430d31536e68ad821fe48d7ada98129c
5
5
  SHA512:
6
- metadata.gz: c02a3b3308a8149e8efb2f014156017dc8e1cf8a5ad06507939f69f807c463f295554cddf48affd07706d0699e5df1a965fb44db2a8cb3459dd97401f511d70d
7
- data.tar.gz: 06e3f9c53a1f2d9b7646a0ebc556eb6970957ff700ddcd448869844e46e0fa4564ae91bbc6ab57f5dd7eb713bce351171fbd038399d24de80a177dc7d8e5dee8
6
+ metadata.gz: 76747928bf1fc2b8208add017d9f43953366f5de8c0b305cfe74b725ddd8bc40a02d2593b4c00a9d4f1f43652c32e83bd3261424ef2e9fe55a0f01b61a5b7190
7
+ data.tar.gz: 34ec05f6b7d198fea07a20c7bcf4fdd580c4551fc07d0c61c9820f37da9968994f6da9f4301db37d31d3a76a73ed63cb3f3529b1f2838ade6974607e02b784a8
data/Readme.md CHANGED
@@ -6,8 +6,7 @@ Keep datadog monitors/dashboards/etc in version control, avoid chaotic managemen
6
6
 
7
7
  - Documented, reusable, automated, and searchable configuration
8
8
  - Changes are PR reviewed and auditable
9
- - Good defaults like no-data / re-notify are preselected
10
- - Reliable cleanup with automated deletion
9
+ - Automated deletion when removed from code
11
10
 
12
11
  ![](template/github/screen.png?raw=true)
13
12
  <!-- NOT IN template/Readme.md -->
@@ -18,7 +17,7 @@ Keep datadog monitors/dashboards/etc in version control, avoid chaotic managemen
18
17
  ```Bash
19
18
  git clone git@github.com:your-org/kennel.git
20
19
  git clone git@github.com:grosser/kennel.git seed
21
- mv seed/teamplate/* kennel/
20
+ mv seed/template/* kennel/
22
21
  cd kennel && git add . && git commit -m 'initial'
23
22
  ```
24
23
  - add a basic projects and teams so others can copy-paste to get started
@@ -31,7 +30,7 @@ Keep datadog monitors/dashboards/etc in version control, avoid chaotic managemen
31
30
 
32
31
  - `projects/` monitors/dashboards/etc scoped by project
33
32
  - `teams/` team definitions
34
- - `parts/` monitors/dashes/etc that are used by multiple projects
33
+ - `parts/` monitors/dashboards/etc that are used by multiple projects
35
34
  - `generated/` projects as json, to show current state and proposed changes in PRs
36
35
 
37
36
  ## Workflows
@@ -13,6 +13,7 @@ module Kennel
13
13
  REQUEST_DEFAULTS = {
14
14
  style: { line_width: "normal", palette: "dog_classic", line_type: "solid" }
15
15
  }.freeze
16
+ TIMESERIES_DEFAULTS = { show_legend: false, legend_size: "0" }.freeze
16
17
  SUPPORTED_DEFINITION_OPTIONS = [:events, :markers, :precision].freeze
17
18
 
18
19
  settings :title, :description, :definitions, :widgets, :layout_type
@@ -32,39 +33,68 @@ module Kennel
32
33
  def normalize(expected, actual)
33
34
  super
34
35
 
35
- base_pairs(expected, actual).each do |pair|
36
+ widgets_pairs(expected, actual).each do |pair|
36
37
  # datadog always adds 2 to slo widget height
37
38
  # need to check fir layout since some monitors have height/width in their definition
38
- pair.dig(1, :widgets)&.each do |widget|
39
+ pair[1].each do |widget|
39
40
  if widget.dig(:definition, :type) == "slo" && widget.dig(:layout, :height)
40
41
  widget[:layout][:height] -= 2
41
42
  end
42
43
  end
43
44
 
44
45
  # conditional_formats ordering is randomly changed by datadog, compare a stable ordering
45
- pair.each do |b|
46
- b[:widgets]&.each do |w|
47
- if formats = w.dig(:definition, :conditional_formats)
48
- w[:definition][:conditional_formats] = formats.sort_by(&:hash)
46
+ pair.each do |widgets|
47
+ widgets.each do |widget|
48
+ if formats = widget.dig(:definition, :conditional_formats)
49
+ widget[:definition][:conditional_formats] = formats.sort_by(&:hash)
49
50
  end
50
51
  end
51
52
  end
52
53
 
53
- ignore_request_defaults(*pair, :widgets, :definition)
54
- pair.each { |dash| dash[:widgets]&.each { |w| w.delete(:id) } }
54
+ ignore_definition_defaults_for_type pair, "timeseries", TIMESERIES_DEFAULTS
55
+
56
+ ignore_request_defaults(*pair)
57
+
58
+ # ids are kinda random so we always discard them
59
+ pair.each { |widgets| widgets.each { |w| w.delete(:id) } }
55
60
  end
56
61
  end
57
62
 
58
63
  private
59
64
 
65
+ def ignore_definition_defaults_for_type(pair, type, defaults)
66
+ pair.map(&:size).max.times do |i|
67
+ if pair.all? { |w| w.dig(i, :definition, :type) == type }
68
+ ignore_defaults(pair[0], pair[1], defaults, nesting: :definition)
69
+ end
70
+ end
71
+ end
72
+
73
+ # discard styles/conditional_formats/aggregator if nothing would change when we applied (both are default or nil)
74
+ def ignore_request_defaults(expected, actual)
75
+ [expected.size, actual.size].max.times do |i|
76
+ a_r = actual.dig(i, :definition, :requests) || []
77
+ e_r = expected.dig(i, :definition, :requests) || []
78
+ ignore_defaults e_r, a_r, REQUEST_DEFAULTS
79
+ end
80
+ end
81
+
82
+ def ignore_defaults(expected, actual, defaults, nesting: nil)
83
+ [expected.size, actual.size].max.times do |i|
84
+ e = expected.dig(i, *nesting) || {}
85
+ a = actual.dig(i, *nesting) || {}
86
+ ignore_default(e, a, defaults)
87
+ end
88
+ end
89
+
60
90
  # expand nested widgets into expected/actual pairs for default resolution
61
- # [a, e] -> [[a, e], [aw1, ew1], ...]
62
- def base_pairs(*pair)
63
- result = [pair]
64
- slots = pair.map { |d| d[:widgets]&.size }.compact.max.to_i
91
+ # [a, e] -> [[a-w, e-w], [a-w1-w1, e-w1-w1], ...]
92
+ def widgets_pairs(*pair)
93
+ result = [pair.map { |d| d[:widgets] || [] }]
94
+ slots = result[0].map(&:size).max
65
95
  slots.times do |i|
66
- nested = pair.map { |d| d.dig(:widgets, i, :definition) || {} }
67
- result << nested if nested.any? { |d| d.key?(:widgets) }
96
+ nested = pair.map { |d| d.dig(:widgets, i, :definition, :widgets) || [] }
97
+ result << nested if nested.any?(&:any?)
68
98
  end
69
99
  result
70
100
  end
@@ -95,7 +125,8 @@ module Kennel
95
125
  end
96
126
 
97
127
  def resolve_linked_tracking_ids(id_map)
98
- as_json[:widgets].each do |widget|
128
+ widgets = as_json[:widgets].flat_map { |w| [w, *w.dig(:definition, :widgets) || []] }
129
+ widgets.each do |widget|
99
130
  next unless definition = widget[:definition]
100
131
  case definition[:type]
101
132
  when "uptime"
@@ -6,11 +6,6 @@ module Kennel
6
6
  READONLY_ATTRIBUTES = [
7
7
  :deleted, :id, :created, :created_at, :creator, :org_id, :modified, :modified_at, :api_resource
8
8
  ].freeze
9
- REQUEST_DEFAULTS = {
10
- style: { width: "normal", palette: "dog_classic", type: "solid" },
11
- conditional_formats: [],
12
- aggregator: "avg"
13
- }.freeze
14
9
  API_LIST_INCOMPLETE = false
15
10
 
16
11
  settings :id, :kennel_id
@@ -22,25 +17,6 @@ module Kennel
22
17
  self::READONLY_ATTRIBUTES.each { |k| actual.delete k }
23
18
  end
24
19
 
25
- # discard styles/conditional_formats/aggregator if nothing would change when we applied (both are default or nil)
26
- def ignore_request_defaults(expected, actual, level1, level2)
27
- actual = actual[level1] || {}
28
- expected = expected[level1] || {}
29
- [expected.size.to_i, actual.size.to_i].max.times do |i|
30
- a_r = actual.dig(i, level2, :requests) || []
31
- e_r = expected.dig(i, level2, :requests) || []
32
- ignore_defaults e_r, a_r, self::REQUEST_DEFAULTS
33
- end
34
- end
35
-
36
- def ignore_defaults(expected, actual, defaults)
37
- [expected&.size.to_i, actual&.size.to_i].max.times do |i|
38
- e = expected[i] || {}
39
- a = actual[i] || {}
40
- ignore_default(e, a, defaults)
41
- end
42
- end
43
-
44
20
  def ignore_default(expected, actual, defaults)
45
21
  definitions = [actual, expected]
46
22
  defaults.each do |key, default|
@@ -81,16 +57,17 @@ module Kennel
81
57
  def resolve_link(id, id_map, force: false)
82
58
  found = id_map[id]
83
59
  return found if found && found != :new
60
+ api_resource = self.class.api_resource
84
61
 
85
62
  if found == :new
86
63
  if force
87
- invalid! "Monitor #{id} will be created in the current run and can only be used after that"
64
+ invalid! "#{api_resource.capitalize} #{id} will be created in the current run and can only be used after that"
88
65
  else
89
- Kennel.err.puts "Monitor #{id} will be created in the current run, the next run will link it properly"
66
+ Kennel.err.puts "#{api_resource.capitalize} #{id} will be created in the current run, the next run will link it properly"
90
67
  Kennel::MISSING_ID
91
68
  end
92
69
  else
93
- invalid! "Unable to find monitor #{id} (does not exist and is not being created by the current run)"
70
+ invalid! "Unable to find #{api_resource} #{id} (does not exist and is not being created by the current run)"
94
71
  end
95
72
  end
96
73
 
@@ -147,7 +147,8 @@ module Kennel
147
147
  def print_plan(step, list, color)
148
148
  return if list.empty?
149
149
  list.each do |_, e, a, diff|
150
- Kennel.out.puts Utils.color(color, "#{step} #{tracking_id(e&.as_json || a)}")
150
+ api_resource = (e ? e.class.api_resource : a.fetch(:api_resource))
151
+ Kennel.out.puts Utils.color(color, "#{step} #{api_resource} #{tracking_id(e&.as_json || a)}")
151
152
  print_diff(diff) if diff # only for update
152
153
  end
153
154
  end
@@ -25,7 +25,7 @@ module Kennel
25
25
  if bad.any?
26
26
  invalid!(
27
27
  "queries #{bad.join(", ")} must use the template variables #{variables.join(", ")}\n" \
28
- "If that is not possible, add `validate_template_variables: -> { false } # query foo in bar does not have baz tag`"
28
+ "If that is not possible, add `validate: -> { false } # query foo in bar does not have baz tag`"
29
29
  )
30
30
  end
31
31
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Kennel
3
- VERSION = "1.60.1"
3
+ VERSION = "1.61.4"
4
4
  end
@@ -6,8 +6,7 @@ Keep datadog monitors/dashboards/etc in version control, avoid chaotic managemen
6
6
 
7
7
  - Documented, reusable, automated, and searchable configuration
8
8
  - Changes are PR reviewed and auditable
9
- - Good defaults like no-data / re-notify are preselected
10
- - Reliable cleanup with automated deletion
9
+ - Automated deletion when removed from code
11
10
 
12
11
  ![](github/screen.png?raw=true)
13
12
 
@@ -15,7 +14,7 @@ Keep datadog monitors/dashboards/etc in version control, avoid chaotic managemen
15
14
 
16
15
  - `projects/` monitors/dashboards/etc scoped by project
17
16
  - `teams/` team definitions
18
- - `parts/` monitors/dashes/etc that are used by multiple projects
17
+ - `parts/` monitors/dashboards/etc that are used by multiple projects
19
18
  - `generated/` projects as json, to show current state and proposed changes in PRs
20
19
 
21
20
  ## Workflows
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.60.1
4
+ version: 1.61.4
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-12-18 00:00:00.000000000 Z
11
+ date: 2020-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -102,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
102
  version: '0'
103
103
  requirements: []
104
104
  rubyforge_project:
105
- rubygems_version: 2.7.6
105
+ rubygems_version: 2.7.6.2
106
106
  signing_key:
107
107
  specification_version: 4
108
108
  summary: Keep datadog monitors/dashboards/etc in version control, avoid chaotic management