flapjack-diner 1.0.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rubocop.yml +21 -0
  4. data/.rubocop_todo.yml +135 -0
  5. data/Gemfile +7 -0
  6. data/README.md +86 -20
  7. data/flapjack-diner.gemspec +11 -15
  8. data/lib/flapjack-diner.rb +23 -548
  9. data/lib/flapjack-diner/argument_validator.rb +31 -22
  10. data/lib/flapjack-diner/resources/checks.rb +58 -0
  11. data/lib/flapjack-diner/resources/contacts.rb +70 -0
  12. data/lib/flapjack-diner/resources/entities.rb +68 -0
  13. data/lib/flapjack-diner/resources/maintenance_periods.rb +82 -0
  14. data/lib/flapjack-diner/resources/media.rb +61 -0
  15. data/lib/flapjack-diner/resources/notification_rules.rb +66 -0
  16. data/lib/flapjack-diner/resources/notifications.rb +27 -0
  17. data/lib/flapjack-diner/resources/pagerduty_credentials.rb +60 -0
  18. data/lib/flapjack-diner/resources/reports.rb +33 -0
  19. data/lib/flapjack-diner/tools.rb +277 -0
  20. data/lib/flapjack-diner/version.rb +1 -1
  21. data/spec/argument_validator_spec.rb +15 -15
  22. data/spec/flapjack-diner_spec.rb +58 -1275
  23. data/spec/pacts/flapjack-diner-flapjack.json +4522 -0
  24. data/spec/resources/checks_spec.rb +171 -0
  25. data/spec/resources/contacts_spec.rb +297 -0
  26. data/spec/resources/entities_spec.rb +181 -0
  27. data/spec/resources/maintenance_periods_spec.rb +603 -0
  28. data/spec/resources/media_spec.rb +277 -0
  29. data/spec/resources/notification_rules_spec.rb +341 -0
  30. data/spec/resources/notifications_spec.rb +210 -0
  31. data/spec/resources/pagerduty_credentials_spec.rb +243 -0
  32. data/spec/resources/reports_spec.rb +255 -0
  33. data/spec/spec_helper.rb +14 -2
  34. metadata +35 -72
@@ -1,566 +1,41 @@
1
1
  require 'httparty'
2
2
  require 'json'
3
- require 'uri'
4
3
 
5
4
  require 'flapjack-diner/version'
6
5
  require 'flapjack-diner/argument_validator'
7
6
 
7
+ %w(contacts media pagerduty_credentials notification_rules entities checks
8
+ maintenance_periods notifications reports).each do |resource|
9
+
10
+ require "flapjack-diner/resources/#{resource}"
11
+ end
12
+
13
+ require 'flapjack-diner/tools'
14
+
15
+ # NB: clients will need to handle any exceptions caused by,
16
+ # e.g., network failures or non-parseable JSON data.
17
+
8
18
  module Flapjack
19
+ # Top level module for Flapjack::Diner API consumer.
9
20
  module Diner
10
- SUCCESS_STATUS_CODES = [200, 201, 204]
11
-
12
21
  include HTTParty
13
22
 
14
23
  format :json
15
24
 
16
25
  class << self
17
-
18
26
  attr_accessor :logger, :return_keys_as_strings
19
27
 
20
- # NB: clients will need to handle any exceptions caused by,
21
- # e.g., network failures or non-parseable JSON data.
22
-
23
- # 1: Contacts
24
- def create_contacts(*args)
25
- ids, params, data = unwrap_ids_and_params(*args)
26
- data.each do |d|
27
- validate_params(d) do
28
- validate :query => [:first_name, :last_name, :email], :as => [:required, :string]
29
- validate :query => :timezone, :as => :string
30
- validate :query => :tags, :as => :array_of_strings
31
- end
32
- end
33
- perform_post('/contacts', nil, :contacts => data)
34
- end
35
-
36
- def contacts(*ids)
37
- extract_get('contacts', perform_get('/contacts', ids))
38
- end
39
-
40
- def update_contacts(*args)
41
- ids, params, data = unwrap_ids_and_params(*args)
42
- raise "'update_contacts' requires at least one contact id parameter" if ids.nil? || ids.empty?
43
- validate_params(params) do
44
- validate :query => [:first_name, :last_name,
45
- :email, :timezone], :as => :string
46
- validate :query => :tags, :as => :array_of_strings
47
- end
48
- ops = params.inject([]) do |memo, (k,v)|
49
- case k
50
- when :add_entity
51
- memo << {:op => 'add',
52
- :path => '/contacts/0/links/entities/-',
53
- :value => v}
54
- when :remove_entity
55
- memo << {:op => 'remove',
56
- :path => "/contacts/0/links/entities/#{v}"}
57
- # # Not supported yet due to id brokenness
58
- # when :add_medium
59
- # memo << {:op => 'add',
60
- # :path => '/contacts/0/links/media/-',
61
- # :value => v}
62
- # when :remove_medium
63
- # memo << {:op => 'remove',
64
- # :path => "/contacts/0/links/media/#{v}"}
65
- when :add_notification_rule
66
- memo << {:op => 'add',
67
- :path => '/contacts/0/links/notification_rules/-',
68
- :value => v}
69
- when :remove_notification_rule
70
- memo << {:op => 'remove',
71
- :path => "/contacts/0/links/notification_rules/#{v}"}
72
- when :first_name, :last_name, :email, :timezone, :tags
73
- memo << {:op => 'replace',
74
- :path => "/contacts/0/#{k.to_s}",
75
- :value => v}
76
- end
77
- memo
78
- end
79
- raise "'update_contacts' did not find any valid update fields" if ops.empty?
80
- perform_patch("/contacts/#{escaped_ids(ids)}", nil, ops)
81
- end
82
-
83
- def delete_contacts(*ids)
84
- raise "'delete_contacts' requires at least one contact id parameter" if ids.nil? || ids.empty?
85
- perform_delete('/contacts', ids)
86
- end
87
-
88
-
89
- # 2: Media
90
- def create_contact_media(*args)
91
- ids, params, data = unwrap_ids_and_params(*args)
92
- raise "'create_contact_media' requires at least one contact id parameter" if ids.nil? || ids.empty?
93
- data.each do |d|
94
- validate_params(d) do
95
- validate :query => [:type, :address], :as => [:required, :string]
96
- validate :query => [:interval, :rollup_threshold], :as => [:required, :integer]
97
- end
98
- end
99
- perform_post("/contacts/#{escaped_ids(ids)}/media", nil, :media => data)
100
- end
101
-
102
- def media(*ids)
103
- extract_get('media', perform_get('/media', ids))
104
- end
105
-
106
- def update_media(*args)
107
- ids, params, data = unwrap_ids_and_params(*args)
108
- raise "'update_media' requires at least one media id parameter" if ids.nil? || ids.empty?
109
- validate_params(params) do
110
- validate :query => :address, :as => :string
111
- validate :query => [:interval, :rollup_threshold], :as => :integer
112
- end
113
- ops = params.inject([]) do |memo, (k,v)|
114
- case k
115
- when :address, :interval, :rollup_threshold
116
- memo << {:op => 'replace',
117
- :path => "/media/0/#{k.to_s}",
118
- :value => v}
119
- end
120
- memo
121
- end
122
- raise "'update_media' did not find any valid update fields" if ops.empty?
123
- perform_patch("/media/#{escaped_ids(ids)}", nil, ops)
124
- end
125
-
126
- def delete_media(*ids)
127
- raise "'delete_media' requires at least one media id parameter" if ids.nil? || ids.empty?
128
- perform_delete('/media', ids)
129
- end
130
-
131
- # 2a: Pagerduty credentials
132
- def create_contact_pagerduty_credentials(*args)
133
- ids, params, data = unwrap_ids_and_params(*args)
134
- raise "'create_contact_pagerduty_credentials' requires at least one contact id parameter" if ids.nil? || ids.empty?
135
- data.each do |d|
136
- validate_params(d) do
137
- validate :query => [:service_key, :subdomain, :username, :password], :as => [:required, :string]
138
- end
139
- end
140
- perform_post("/contacts/#{escaped_ids(ids)}/pagerduty_credentials", nil, :pagerduty_credentials => data)
141
- end
142
-
143
- def pagerduty_credentials(*ids)
144
- extract_get('pagerduty_credentials', perform_get('/pagerduty_credentials', ids))
145
- end
146
-
147
- def update_pagerduty_credentials(*args)
148
- ids, params, data = unwrap_ids_and_params(*args)
149
- raise "'update_pagerduty_credentials' requires at least one pagerduty_credentials id parameter" if ids.nil? || ids.empty?
150
- validate_params(params) do
151
- validate :query => [:service_key, :subdomain, :username, :password], :as => :string
152
- end
153
- ops = params.inject([]) do |memo, (k,v)|
154
- case k
155
- when :service_key, :subdomain, :username, :password
156
- memo << {:op => 'replace',
157
- :path => "/pagerduty_credentials/0/#{k.to_s}",
158
- :value => v}
159
- end
160
- memo
161
- end
162
- raise "'update_pagerduty_credentials did not find any valid update fields" if ops.empty?
163
- perform_patch("/pagerduty_credentials/#{escaped_ids(ids)}", nil, ops)
164
- end
165
-
166
- def delete_pagerduty_credentials(*ids)
167
- raise "'delete_pagerduty_credentials' requires at least one pagerduty_credentials id parameter" if ids.nil? || ids.empty?
168
- perform_delete('/pagerduty_credentials', ids)
169
- end
170
-
171
-
172
- # 3: Notification Rules
173
- def create_contact_notification_rules(*args)
174
- ids, params, data = unwrap_ids_and_params(*args)
175
- raise "'create_contact_notification_rules' requires at least one contact id parameter" if ids.nil? || ids.empty?
176
- data.each do |d|
177
- validate_params(d) do
178
- validate :query => [:entities, :regex_entities, :tags, :regex_tags,
179
- :unknown_media, :warning_media, :critical_media], :as => :array_of_strings
180
- validate :query => [:unknown_blackhole, :warning_blackhole, :critical_blackhole],
181
- :as => :boolean
182
- end
183
- end
184
- perform_post("/contacts/#{escaped_ids(ids)}/notification_rules", nil, :notification_rules => data)
185
- end
186
-
187
- def notification_rules(*ids)
188
- extract_get('notification_rules', perform_get('/notification_rules', ids))
189
- end
190
-
191
- def update_notification_rules(*args)
192
- ids, params, data = unwrap_ids_and_params(*args)
193
- raise "'update_notification_rules' requires at least one notification rule id parameter" if ids.nil? || ids.empty?
194
- validate_params(params) do
195
- validate :query => [:entities, :regex_entities, :tags, :regex_tags,
196
- :unknown_media, :warning_media, :critical_media], :as => :array_of_strings
197
- validate :query => [:unknown_blackhole, :warning_blackhole, :critical_blackhole],
198
- :as => :boolean
199
- end
200
- ops = params.inject([]) do |memo, (k,v)|
201
- case k
202
- when :entities, :regex_entities, :tags, :regex_tags,
203
- :time_restrictions, :unknown_media, :warning_media, :critical_media,
204
- :unknown_blackhole, :warning_blackhole, :critical_blackhole
205
-
206
- memo << {:op => 'replace',
207
- :path => "/notification_rules/0/#{k.to_s}",
208
- :value => v}
209
- end
210
- memo
211
- end
212
- raise "'update_notification_rules' did not find any valid update fields" if ops.empty?
213
- perform_patch("/notification_rules/#{escaped_ids(ids)}", nil, ops)
214
- end
215
-
216
- def delete_notification_rules(*ids)
217
- raise "'delete_notification_rules' requires at least one notification rule id parameter" if ids.nil? || ids.empty?
218
- perform_delete('/notification_rules', ids)
219
- end
220
-
221
-
222
- # 4: Entities & 5: Checks
223
- def create_entities(*args)
224
- ids, params, data = unwrap_ids_and_params(*args)
225
- data.each do |d|
226
- validate_params(d) do
227
- validate :query => :id, :as => [:required, :string]
228
- validate :query => :name, :as => :string
229
- validate :query => :tags, :as => :array_of_strings
230
- end
231
- end
232
- perform_post('/entities', nil, :entities => data)
233
- end
234
-
235
- def entities(*ids)
236
- extract_get('entities', perform_get('/entities', ids))
237
- end
238
-
239
- def checks(*ids)
240
- extract_get('checks', perform_get('/checks', ids))
241
- end
242
-
243
- def update_entities(*args)
244
- ids, params, data = unwrap_ids_and_params(*args)
245
- raise "'update_entities' requires at least one entity id parameter" if ids.nil? || ids.empty?
246
- validate_params(params) do
247
- validate :query => :name, :as => :string
248
- validate :query => :tags, :as => :array_of_strings
249
- end
250
- ops = params.inject([]) do |memo, (k,v)|
251
- case k
252
- when :name, :tags
253
- memo << {:op => 'replace',
254
- :path => "/entities/0/#{k.to_s}",
255
- :value => v}
256
- when :add_contact
257
- memo << {:op => 'add',
258
- :path => '/entities/0/links/contacts/-',
259
- :value => v}
260
- when :remove_contact
261
- memo << {:op => 'remove',
262
- :path => "/entities/0/links/contacts/#{v}"}
263
- end
264
- memo
265
- end
266
- raise "'update_entities' did not find any valid update fields" if ops.empty?
267
- perform_patch("/entities/#{escaped_ids(ids)}", nil, ops)
268
- end
269
-
270
- def update_checks(*args)
271
- ids, params, data = unwrap_ids_and_params(*args)
272
- raise "'update_checks' requires at least one check id parameter" if ids.nil? || ids.empty?
273
- validate_params(params) do
274
- validate :query => :enabled, :as => :boolean
275
- end
276
- ops = params.inject([]) do |memo, (k,v)|
277
- case k
278
- when :enabled
279
- memo << {:op => 'replace',
280
- :path => "/checks/0/#{k.to_s}",
281
- :value => v}
282
- end
283
- memo
284
- end
285
- raise "'update_checks' did not find any valid update fields" if ops.empty?
286
- perform_patch("/checks/#{escaped_ids(ids)}", nil, ops)
287
- end
288
-
289
- ['entities', 'checks'].each do |data_type|
290
-
291
- define_method("create_scheduled_maintenances_#{data_type}") do |*args|
292
- ids, params, data = unwrap_ids_and_params(*args)
293
- raise "'create_scheduled_maintenances_#{data_type}' requires at least one #{data_type} id parameter" if ids.nil? || ids.empty?
294
- data.each do |d|
295
- validate_params(d) do
296
- validate :query => :start_time, :as => [:required, :time]
297
- validate :query => :duration, :as => [:required, :integer]
298
- validate :query => :summary, :as => :string
299
- end
300
- end
301
- perform_post("/scheduled_maintenances/#{data_type}", ids,
302
- :scheduled_maintenances => data)
303
- end
304
-
305
- define_method("create_unscheduled_maintenances_#{data_type}") do |*args|
306
- ids, params, data = unwrap_ids_and_params(*args)
307
- raise "'create_unscheduled_maintenances_#{data_type}' requires at least one #{data_type} id parameter" if ids.nil? || ids.empty?
308
- data.each do |d|
309
- validate_params(d) do
310
- validate :query => :duration, :as => [:required, :integer]
311
- validate :query => :summary, :as => :string
312
- end
313
- end
314
- perform_post("/unscheduled_maintenances/#{data_type}", ids,
315
- :unscheduled_maintenances => data)
316
- end
317
-
318
- define_method("create_test_notifications_#{data_type}") do |*args|
319
- ids, params, data = unwrap_ids_and_params(*args)
320
- raise "'create_test_notifications_#{data_type}' requires at least one #{data_type} id parameter" if ids.nil? || ids.empty?
321
- data.each do |d|
322
- validate_params(d) do
323
- validate :query => :summary, :as => :string
324
- end
325
- end
326
- perform_post("/test_notifications/#{data_type}", ids,
327
- :test_notifications => data)
328
- end
329
-
330
- define_method("update_unscheduled_maintenances_#{data_type}") do |*args|
331
- ids, params, data = unwrap_ids_and_params(*args)
332
- raise "'update_unscheduled_maintenances_#{data_type}' requires at least one #{data_type} id parameter" if ids.nil? || ids.empty?
333
- validate_params(params) do
334
- validate :query => :end_time, :as => :time
335
- end
336
- ops = params.inject([]) do |memo, (k,v)|
337
- case k
338
- when :end_time
339
- memo << {:op => 'replace',
340
- :path => "/unscheduled_maintenances/0/#{k.to_s}",
341
- :value => v}
342
- end
343
- memo
344
- end
345
- raise "'update_unscheduled_maintenances_#{data_type}' did not find any valid update fields" if ops.empty?
346
- perform_patch("/unscheduled_maintenances/#{data_type}", ids, ops)
347
- end
348
-
349
- define_method("delete_scheduled_maintenances_#{data_type}") do |*args|
350
- ids, params, data = unwrap_ids_and_params(*args)
351
- raise "'delete_scheduled_maintenances_#{data_type}' requires at least one #{data_type} id parameter" if ids.nil? || ids.empty?
352
- validate_params(params) do
353
- validate :query => :start_time, :as => [:required, :time]
354
- end
355
- perform_delete("/scheduled_maintenances/#{data_type}", ids, params)
356
- end
357
-
358
- end
359
-
360
-
361
- # 6: Reports
362
-
363
- ['entities', 'checks'].each do |data_type|
364
- define_method("status_report_#{data_type}") do |*ids|
365
- extract_get('status_reports', perform_get("/status_report/#{data_type}", ids))
366
- end
367
-
368
- ['scheduled_maintenance', 'unscheduled_maintenance', 'downtime', 'outage'].each do |report_type|
369
- define_method("#{report_type}_report_#{data_type}") do |*args|
370
- ids, params, data = unwrap_ids_and_params(*args)
371
- validate_params(params) do
372
- validate :query => [:start_time, :end_time], :as => :time
373
- end
374
- extract_get("#{report_type}_reports", perform_get("/#{report_type}_report/#{data_type}", ids, params))
375
- end
376
- end
377
- end
378
-
379
- def last_error
380
- @last_error
381
- end
382
-
383
- private
384
-
385
- def extract_get(name, response)
386
- result = (response.nil? || response.is_a?(TrueClass)) ? response : response[name]
387
-
388
- if return_keys_as_strings.is_a?(TrueClass)
389
- return result
390
- else
391
- return symbolize(result)
392
- end
393
- end
394
-
395
- def perform_get(path, ids = [], data = [])
396
- req_uri = build_uri(path, ids, data)
397
- logger.info "GET #{req_uri}" if logger
398
- response = get(req_uri.request_uri)
399
- handle_response(response)
400
- end
401
-
402
- def perform_post(path, ids = [], data = [])
403
- req_uri = build_uri(path, ids)
404
- if logger
405
- log_post = "POST #{req_uri}"
406
- log_post << "\n Params: #{data.inspect}" if data
407
- logger.info log_post
408
- end
409
- opts = data ? {:body => prepare_nested_query(data).to_json, :headers => {'Content-Type' => 'application/vnd.api+json'}} : {}
410
- response = post(req_uri.request_uri, opts)
411
- handle_response(response)
412
- end
413
-
414
- def perform_patch(path, ids = [], data = [])
415
- req_uri = build_uri(path, ids)
416
- if logger
417
- log_patch = "PATCH #{req_uri}"
418
- log_patch << "\n Params: #{data.inspect}" if data
419
- logger.info log_patch
420
- end
421
- opts = data ? {:body => prepare_nested_query(data).to_json,
422
- :headers => {'Content-Type' => 'application/json-patch+json'}} : {}
423
- response = patch(req_uri.request_uri, opts)
424
- handle_response(response)
425
- end
426
-
427
- def perform_delete(path, ids = [], data = [])
428
- req_uri = build_uri(path, ids, data)
429
- logger.info "DELETE #{req_uri}" if logger
430
- response = delete(req_uri.request_uri)
431
- handle_response(response)
432
- end
433
-
434
- def handle_response(response)
435
- response_body = response.body
436
- response_start = response_body ? response_body[0..300] : nil
437
- if logger
438
- response_message = " #{response.message}" unless (response.message.nil? || response.message == "")
439
- logger.info " Response Code: #{response.code}#{response_message}"
440
- logger.info " Response Body: #{response_start}" if response_start
441
- end
442
- parsed_response = response.respond_to?(:parsed_response) ? response.parsed_response : nil
443
- unless SUCCESS_STATUS_CODES.include?(response.code)
444
- self.last_error = {'status_code' => response.code}.merge(parsed_response)
445
- return nil
446
- end
447
- return true unless (response.code == 200) && parsed_response
448
- parsed_response
449
- end
450
-
451
- def validate_params(query = {}, &validation)
452
- ArgumentValidator.new(query).instance_eval(&validation) if block_given?
453
- end
454
-
455
- # copied from Rack::Utils -- builds the query string for GETs
456
- def build_nested_query(value, prefix = nil)
457
- if value.respond_to?(:iso8601)
458
- raise ArgumentError, "value must be a Hash" if prefix.nil?
459
- "#{prefix}=#{escape(value.iso8601)}"
460
- else
461
- case value
462
- when Array
463
- value.map { |v|
464
- build_nested_query(v, "#{prefix}[]")
465
- }.join("&")
466
- when Hash
467
- value.map { |k, v|
468
- build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
469
- }.join("&")
470
- when String, Integer
471
- raise ArgumentError, "value must be a Hash" if prefix.nil?
472
- "#{prefix}=#{escape(value.to_s)}"
473
- else
474
- prefix
475
- end
476
- end
477
- end
478
-
479
- def escaped_ids(ids = [])
480
- ids.collect{|id| URI.escape(id.to_s)}.join(',')
481
- end
482
-
483
- def escape(s)
484
- URI.encode_www_form_component(s)
485
- end
486
-
487
- def unwrap_ids_and_params(*args)
488
- ids = []
489
- params = {}
490
- data = []
491
-
492
- args.each do |arg|
493
- case arg
494
- when Array
495
- raise "Array arguments may only contain data Hashes" unless arg.all? {|a| a.is_a?(Hash)}
496
- data += arg
497
- when Hash
498
- params.update(arg)
499
- when String, Integer
500
- ids << arg.to_s
501
- else
502
- raise "Arguments must be a Hash (parameters), String/Integer (ids), or Arrays of Hashes (data)"
503
- end
504
- end
505
-
506
- [ids, params, data]
507
- end
508
-
509
- # used for the JSON data hashes in POST, PUT, DELETE
510
- def prepare_nested_query(value)
511
- if value.respond_to?(:iso8601)
512
- value.iso8601
513
- else
514
- case value
515
- when Array
516
- value.map { |v| prepare_nested_query(v) }
517
- when Hash
518
- value.inject({}) do |memo, (k, v)|
519
- memo[k] = prepare_nested_query(v)
520
- memo
521
- end
522
- when Integer, TrueClass, FalseClass, NilClass
523
- value
524
- else
525
- value.to_s
526
- end
527
- end
528
- end
529
-
530
- def protocol_host_port
531
- self.base_uri =~ /^(?:(https?):\/\/)?([a-zA-Z0-9][a-zA-Z0-9\.\-]*[a-zA-Z0-9])(?::(\d+))?/i
532
- protocol = ($1 || 'http').downcase
533
- host = $2
534
- port = $3
535
-
536
- if port.nil? || port.to_i < 1 || port.to_i > 65535
537
- port = 'https'.eql?(protocol) ? 443 : 80
538
- else
539
- port = port.to_i
540
- end
541
-
542
- [protocol, host, port]
543
- end
544
-
545
- def build_uri(path, ids = [], params = [])
546
- pr, ho, po = protocol_host_port
547
- if !ids.nil? && !ids.empty?
548
- path += '/' + escaped_ids(ids)
549
- end
550
- URI::HTTP.build(:protocol => pr, :host => ho, :port => po,
551
- :path => path, :query => (params.nil? || params.empty? ? nil : build_nested_query(params)))
552
- end
553
-
554
- def last_error=(error)
555
- @last_error = error
556
- end
557
-
558
- def symbolize(obj)
559
- return obj.inject({}){|memo,(k,v)| memo[k.to_sym] = symbolize(v); memo} if obj.is_a? Hash
560
- return obj.inject([]){|memo,v | memo << symbolize(v); memo} if obj.is_a? Array
561
- return obj
562
- end
563
-
28
+ include Flapjack::Diner::Resources::Contacts
29
+ include Flapjack::Diner::Resources::Media
30
+ include Flapjack::Diner::Resources::PagerdutyCredentials
31
+ include Flapjack::Diner::Resources::NotificationRules
32
+ include Flapjack::Diner::Resources::Entities
33
+ include Flapjack::Diner::Resources::Checks
34
+ include Flapjack::Diner::Resources::MaintenancePeriods
35
+ include Flapjack::Diner::Resources::Notifications
36
+ include Flapjack::Diner::Resources::Reports
37
+
38
+ include Flapjack::Diner::Tools
564
39
  end
565
40
  end
566
41
  end