kennel 1.113.1 → 1.114.0

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: af3ac09353ce317e01997ae925ac4873b24708bc710bec0cedf1cf3b78334396
4
- data.tar.gz: 148af144d196c02155eeb0f295f59aaadaa157f3943d7a93af1154cc9f644779
3
+ metadata.gz: b1266c924cd004d26036f81424b92ca52cf0720f041a6cc1ee0a7d1533b19f93
4
+ data.tar.gz: 250117caacd886189bde046f5a8166746a8cd6b87c7330fc106954cf4c7fae20
5
5
  SHA512:
6
- metadata.gz: be15b9ec70bb981a851e0a0dd55fad94a0d765a4747111ff12aa1dde90d1dffb8f1228aee85bf83020df7cbd94d64c9ef2df4dfb7532e664c2aeca5e151fe9fd
7
- data.tar.gz: 85916df4a2ea0cbc8dd72e033dd3a2159fe8cbd60f44d4869cf62f014eeeabce5a7e633807772e9bd9b0af312b60a78571ec63e16b2106a178bb2cfb38ed3332
6
+ metadata.gz: aba95188ef4c6c2b7e974f53ba60ad3aac21b29dcb353bc6b05790374ba0a0c4113c0dd316e1e84975723a8d4d4e117102c13d18e18ddf7050fa97931b506af8
7
+ data.tar.gz: 15903c3da36d10fd42220431da69ac76c7c95d1407771e2f7c5c6bb0dfe132c2054e32131ba12b149eb41c52ebfb17f3004bdc78aab6a54c7f28600515a08632
data/Readme.md CHANGED
@@ -72,6 +72,95 @@ end
72
72
  - `parts/` monitors/dashboards/etc that are used by multiple projects
73
73
  - `generated/` projects as json, to show current state and proposed changes in PRs
74
74
 
75
+ ## About the models
76
+
77
+ Kennel provides several classes which act as models for different purposes:
78
+
79
+ * `Kennel::Models::Dashboard`, `Kennel::Models::Monitor`, `Kennel::Models::Slo`, `Kennel::Models::SyntheticTest`;
80
+ these models represent the various Datadog objects
81
+ * `Kennel::Models::Project`; a container for a collection of Datadog objects
82
+ * `Kennel::Models::Team`; provides defaults and values (e.g. tags, mentions) for the other models.
83
+
84
+ After loading all the `*.rb` files under `projects/`, Kennel's starting point
85
+ is to find all the subclasses of `Kennel::Models::Project`, and for each one,
86
+ create an instance of that subclass (via `.new`) and then call `#parts` on that
87
+ instance. `parts` should return a collection of the Datadog-objects (Dashboard / Monitor / etc).
88
+
89
+ ### Model Settings
90
+
91
+ Each of the models defines various settings; for example, a Monitor has `name`, `message`,
92
+ `type`, `query`, `tags`, and many more.
93
+
94
+ When defining a subclass of a model, one can use `defaults` to provide default values for
95
+ those settings:
96
+
97
+ ```Ruby
98
+ class MyMonitor < Kennel::Models::Monitor
99
+ defaults(
100
+ name: "Error rate",
101
+ type: "query alert",
102
+ critical: 5.0,
103
+ query: -> {
104
+ "some datadog metric expression > #{critical}"
105
+ },
106
+ # ...
107
+ )
108
+ end
109
+ ```
110
+
111
+ This is equivalent to defining instance methods of those names, which return those values:
112
+
113
+ ```Ruby
114
+ class MyMonitor < Kennel::Models::Monitor
115
+ def name
116
+ "Error rate"
117
+ end
118
+
119
+ def type
120
+ "query alert"
121
+ end
122
+
123
+ def critical
124
+ 5.0
125
+ end
126
+
127
+ def query
128
+ "some datadog metric expression > #{critical}"
129
+ end
130
+ end
131
+ ```
132
+
133
+ except that `defaults` will complain if you try to use a setting name which doesn't
134
+ exist. Note also that you can use either plain values (`critical: 5.0`), or procs
135
+ (`query: -> { ... }`). Using a plain value is equivalent to using a proc which returns
136
+ that same value; use whichever suits you best.
137
+
138
+ When you _instantiate_ a model class, you can pass settings in the constructor, after
139
+ the project:
140
+
141
+ ```Ruby
142
+ project = Kennel::Models::Project.new
143
+ my_monitor = MyMonitor.new(
144
+ project,
145
+ critical: 10.0,
146
+ message: -> {
147
+ <<~MESSAGE
148
+ Something bad is happening and you should be worried.
149
+
150
+ #{super()}
151
+ MESSAGE
152
+ },
153
+ )
154
+ ```
155
+
156
+ This works just like `defaults` (it checks the setting names, and it accepts
157
+ either plain values or procs), but it applies just to this instance of the class,
158
+ rather than to the class as a whole (i.e. it defines singleton methods, rather
159
+ than instance methods).
160
+
161
+ Most of the examples in this Readme use the proc syntax (`critical: -> { 5.0 }`) but
162
+ for simple constants you may prefer to use the plain syntax (`critical: 5.0`).
163
+
75
164
  ## Workflows
76
165
  <!-- ONLY IN template/Readme.md
77
166
 
@@ -131,12 +131,15 @@ module Kennel
131
131
  as_json[:query] = as_json[:query].gsub(/%{(.*?)}/) do
132
132
  resolve($1, type, id_map, **args) || $&
133
133
  end
134
+ else # do nothing
134
135
  end
135
136
  end
136
137
 
137
138
  def validate_update!(_actuals, diffs)
138
- if bad_diff = diffs.find { |diff| diff[1] == "type" }
139
- invalid! "Datadog does not allow update of #{bad_diff[1]} (#{bad_diff[2].inspect} -> #{bad_diff[3].inspect})"
139
+ # ensure type does not change, but not if it's metric->query which is supported and used by importer.rb
140
+ _, path, from, to = diffs.detect { |_, path, _, _| path == "type" }
141
+ if path && !(from == "metric alert" && to == "query alert")
142
+ invalid! "Datadog does not allow update of #{path} (#{from.inspect} -> #{to.inspect})"
140
143
  end
141
144
  end
142
145
 
@@ -145,7 +148,7 @@ module Kennel
145
148
  end
146
149
 
147
150
  def self.url(id)
148
- Utils.path_to_url "/monitors##{id}/edit"
151
+ Utils.path_to_url "/monitors/#{id}/edit"
149
152
  end
150
153
 
151
154
  def self.parse_url(url)
@@ -208,6 +211,10 @@ module Kennel
208
211
  def validate_json(data)
209
212
  super
210
213
 
214
+ if data[:name]&.start_with?(" ")
215
+ invalid! "name cannot start with a space"
216
+ end
217
+
211
218
  type = data.fetch(:type)
212
219
 
213
220
  # do not allow deprecated type that will be coverted by datadog and then produce a diff
@@ -238,6 +245,10 @@ module Kennel
238
245
  unless ALLOWED_PRIORITY_CLASSES.include?(priority.class)
239
246
  invalid! "priority needs to be an Integer"
240
247
  end
248
+
249
+ if data.dig(:options, :timeout_h)&.> 24
250
+ invalid! "timeout_h must be <= 24"
251
+ end
241
252
  end
242
253
 
243
254
  # verify is_match/is_exact_match and {{foo.name}} uses available variables
@@ -3,6 +3,16 @@ module Kennel
3
3
  module SettingsAsMethods
4
4
  SETTING_OVERRIDABLE_METHODS = [].freeze
5
5
 
6
+ AS_PROCS = ->(options) do
7
+ options.transform_values do |v|
8
+ if v.class == Proc
9
+ v
10
+ else
11
+ -> { v }
12
+ end
13
+ end
14
+ end
15
+
6
16
  def self.included(base)
7
17
  base.extend ClassMethods
8
18
  base.instance_variable_set(:@settings, [])
@@ -31,7 +41,7 @@ module Kennel
31
41
  end
32
42
 
33
43
  def defaults(options)
34
- options.each do |name, block|
44
+ AS_PROCS.call(options).each do |name, block|
35
45
  validate_setting_exist name
36
46
  define_method name, &block
37
47
  end
@@ -58,12 +68,7 @@ module Kennel
58
68
  raise ArgumentError, "Expected #{self.class.name}.new options to be a Hash, got a #{options.class}"
59
69
  end
60
70
 
61
- options.each do |k, v|
62
- next if v.class == Proc
63
- raise ArgumentError, "Expected #{self.class.name}.new option :#{k} to be Proc, for example `#{k}: -> { 12 }`"
64
- end
65
-
66
- options.each do |name, block|
71
+ AS_PROCS.call(options).each do |name, block|
67
72
  self.class.send :validate_setting_exist, name
68
73
  define_singleton_method name, &block
69
74
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Kennel
3
- VERSION = "1.113.1"
3
+ VERSION = "1.114.0"
4
4
  end
data/template/Readme.md CHANGED
@@ -56,6 +56,95 @@ end
56
56
  - `parts/` monitors/dashboards/etc that are used by multiple projects
57
57
  - `generated/` projects as json, to show current state and proposed changes in PRs
58
58
 
59
+ ## About the models
60
+
61
+ Kennel provides several classes which act as models for different purposes:
62
+
63
+ * `Kennel::Models::Dashboard`, `Kennel::Models::Monitor`, `Kennel::Models::Slo`, `Kennel::Models::SyntheticTest`;
64
+ these models represent the various Datadog objects
65
+ * `Kennel::Models::Project`; a container for a collection of Datadog objects
66
+ * `Kennel::Models::Team`; provides defaults and values (e.g. tags, mentions) for the other models.
67
+
68
+ After loading all the `*.rb` files under `projects/`, Kennel's starting point
69
+ is to find all the subclasses of `Kennel::Models::Project`, and for each one,
70
+ create an instance of that subclass (via `.new`) and then call `#parts` on that
71
+ instance. `parts` should return a collection of the Datadog-objects (Dashboard / Monitor / etc).
72
+
73
+ ### Model Settings
74
+
75
+ Each of the models defines various settings; for example, a Monitor has `name`, `message`,
76
+ `type`, `query`, `tags`, and many more.
77
+
78
+ When defining a subclass of a model, one can use `defaults` to provide default values for
79
+ those settings:
80
+
81
+ ```Ruby
82
+ class MyMonitor < Kennel::Models::Monitor
83
+ defaults(
84
+ name: "Error rate",
85
+ type: "query alert",
86
+ critical: 5.0,
87
+ query: -> {
88
+ "some datadog metric expression > #{critical}"
89
+ },
90
+ # ...
91
+ )
92
+ end
93
+ ```
94
+
95
+ This is equivalent to defining instance methods of those names, which return those values:
96
+
97
+ ```Ruby
98
+ class MyMonitor < Kennel::Models::Monitor
99
+ def name
100
+ "Error rate"
101
+ end
102
+
103
+ def type
104
+ "query alert"
105
+ end
106
+
107
+ def critical
108
+ 5.0
109
+ end
110
+
111
+ def query
112
+ "some datadog metric expression > #{critical}"
113
+ end
114
+ end
115
+ ```
116
+
117
+ except that `defaults` will complain if you try to use a setting name which doesn't
118
+ exist. Note also that you can use either plain values (`critical: 5.0`), or procs
119
+ (`query: -> { ... }`). Using a plain value is equivalent to using a proc which returns
120
+ that same value; use whichever suits you best.
121
+
122
+ When you _instantiate_ a model class, you can pass settings in the constructor, after
123
+ the project:
124
+
125
+ ```Ruby
126
+ project = Kennel::Models::Project.new
127
+ my_monitor = MyMonitor.new(
128
+ project,
129
+ critical: 10.0,
130
+ message: -> {
131
+ <<~MESSAGE
132
+ Something bad is happening and you should be worried.
133
+
134
+ #{super()}
135
+ MESSAGE
136
+ },
137
+ )
138
+ ```
139
+
140
+ This works just like `defaults` (it checks the setting names, and it accepts
141
+ either plain values or procs), but it applies just to this instance of the class,
142
+ rather than to the class as a whole (i.e. it defines singleton methods, rather
143
+ than instance methods).
144
+
145
+ Most of the examples in this Readme use the proc syntax (`critical: -> { 5.0 }`) but
146
+ for simple constants you may prefer to use the plain syntax (`critical: 5.0`).
147
+
59
148
  ## Workflows
60
149
 
61
150
  ### Setup
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.113.1
4
+ version: 1.114.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-05-15 00:00:00.000000000 Z
11
+ date: 2022-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday