flapjack 0.8.11 → 0.8.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/CONTRIBUTING.md +35 -0
  4. data/Gemfile +1 -1
  5. data/README.md +16 -14
  6. data/bin/flapjack-feed-events +124 -0
  7. data/bin/flapjack-nagios-receiver +1 -1
  8. data/bin/flapjack-nsca-receiver +1 -1
  9. data/etc/flapjack_config.yaml.example +1 -2
  10. data/features/cli_flapjack-feed-events.feature +104 -0
  11. data/features/steps/events_steps.rb +2 -2
  12. data/features/steps/packaging-lintian_steps.rb +2 -2
  13. data/features/support/env.rb +7 -1
  14. data/flapjack.gemspec +2 -3
  15. data/lib/flapjack/configuration.rb +1 -0
  16. data/lib/flapjack/data/contact.rb +1 -1
  17. data/lib/flapjack/data/event.rb +25 -21
  18. data/lib/flapjack/data/notification_rule.rb +43 -29
  19. data/lib/flapjack/gateways/api.rb +1 -1
  20. data/lib/flapjack/gateways/api/contact_methods.rb +13 -13
  21. data/lib/flapjack/gateways/jabber.rb +2 -2
  22. data/lib/flapjack/gateways/jsonapi.rb +16 -10
  23. data/lib/flapjack/gateways/jsonapi/contact_methods.rb +6 -6
  24. data/lib/flapjack/gateways/jsonapi/entity_methods.rb +2 -2
  25. data/lib/flapjack/gateways/jsonapi/medium_methods.rb +5 -4
  26. data/lib/flapjack/gateways/jsonapi/metrics_methods.rb +100 -0
  27. data/lib/flapjack/gateways/jsonapi/notification_rule_methods.rb +28 -11
  28. data/lib/flapjack/gateways/jsonapi/pagerduty_credential_methods.rb +2 -1
  29. data/lib/flapjack/gateways/pagerduty.rb +7 -0
  30. data/lib/flapjack/gateways/web.rb +7 -2
  31. data/lib/flapjack/gateways/web/public/css/nv.d3.css +769 -0
  32. data/lib/flapjack/gateways/web/public/js/backbone.jsonapi.js +150 -44
  33. data/lib/flapjack/gateways/web/public/js/d3.v3.min.js +5 -0
  34. data/lib/flapjack/gateways/web/public/js/flapjack.js +78 -0
  35. data/lib/flapjack/gateways/web/public/js/modules/contact.js +521 -0
  36. data/lib/flapjack/gateways/web/public/js/modules/entity.js +28 -0
  37. data/lib/flapjack/gateways/web/public/js/modules/medium.js +39 -0
  38. data/lib/flapjack/gateways/web/public/js/moment.js +2489 -0
  39. data/lib/flapjack/gateways/web/public/js/nv.d3.min.js +6 -0
  40. data/lib/flapjack/gateways/web/public/js/select2.js +12 -12
  41. data/lib/flapjack/gateways/web/public/js/self_stats.js +78 -0
  42. data/lib/flapjack/gateways/web/views/edit_contacts.html.erb +108 -73
  43. data/lib/flapjack/gateways/web/views/layout.erb +11 -12
  44. data/lib/flapjack/gateways/web/views/self_stats.html.erb +32 -4
  45. data/lib/flapjack/patches.rb +1 -1
  46. data/lib/flapjack/pikelet.rb +1 -1
  47. data/lib/flapjack/version.rb +1 -1
  48. data/spec/lib/flapjack/data/contact_spec.rb +0 -1
  49. data/spec/lib/flapjack/data/notification_rule_spec.rb +6 -4
  50. data/spec/lib/flapjack/gateways/jsonapi/contact_methods_spec.rb +15 -0
  51. data/spec/lib/flapjack/gateways/jsonapi/entity_methods_spec.rb +19 -4
  52. data/spec/lib/flapjack/gateways/jsonapi/medium_methods_spec.rb +2 -3
  53. data/spec/lib/flapjack/gateways/jsonapi/notification_rule_methods_spec.rb +41 -3
  54. data/spec/lib/flapjack/gateways/jsonapi/pagerduty_credential_methods_spec.rb +2 -2
  55. data/spec/lib/flapjack/gateways/pagerduty_spec.rb +16 -0
  56. data/spec/spec_helper.rb +14 -2
  57. metadata +20 -17
  58. data/lib/flapjack/gateways/web/public/css/bootstrap-responsive.min.css +0 -9
  59. data/lib/flapjack/gateways/web/public/css/bootstrap-theme.css +0 -397
  60. data/lib/flapjack/gateways/web/public/css/bootstrap-theme.min.css +0 -7
  61. data/lib/flapjack/gateways/web/public/css/bootstrap.min.css +0 -7
  62. data/lib/flapjack/gateways/web/public/css/font-awesome.min.css +0 -4
  63. data/lib/flapjack/gateways/web/public/js/backbone-min.js +0 -2
  64. data/lib/flapjack/gateways/web/public/js/bootstrap.min.js +0 -6
  65. data/lib/flapjack/gateways/web/public/js/contacts.js +0 -490
  66. data/lib/flapjack/gateways/web/public/js/jquery-1.10.2.min.js +0 -6
  67. data/lib/flapjack/gateways/web/public/js/moment.min.js +0 -6
  68. data/lib/flapjack/gateways/web/public/js/select2.min.js +0 -22
  69. data/lib/flapjack/gateways/web/public/js/underscore-min.js +0 -6
data/flapjack.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.version = Flapjack::VERSION
20
20
 
21
21
  gem.add_dependency 'dante'
22
- gem.add_dependency 'oj'
22
+ gem.add_dependency 'oj', '>= 2.9.0'
23
23
  gem.add_dependency 'eventmachine', '~> 1.0.0'
24
24
  gem.add_dependency 'hiredis'
25
25
  gem.add_dependency 'em-synchrony', '~> 1.0.2'
@@ -39,6 +39,5 @@ Gem::Specification.new do |gem|
39
39
  gem.add_dependency 'tzinfo', '~> 1.0.1'
40
40
  gem.add_dependency 'tzinfo-data'
41
41
  gem.add_dependency 'rbtrace'
42
-
43
- gem.add_development_dependency 'rake'
42
+ gem.add_dependency 'rake'
44
43
  end
@@ -38,6 +38,7 @@ module Flapjack
38
38
 
39
39
  redis_path = (redis['path'] || nil)
40
40
  base_opts = {:db => (redis['db'] || 0)}
41
+ base_opts[:driver] = redis['driver'] if redis['driver']
41
42
  redis_config = base_opts.merge(
42
43
  (redis_path ? { :path => redis_path } :
43
44
  { :host => (redis['host'] || '127.0.0.1'),
@@ -31,7 +31,7 @@ module Flapjack
31
31
  k =~ /^contact:(.*)$/
32
32
  id = $1
33
33
  contact = self.find_by_id(id, :redis => redis)
34
- ret << contact if contact
34
+ ret << contact unless contact.nil?
35
35
  ret
36
36
  }.sort_by {|c| [c.last_name, c.first_name]}
37
37
  end
@@ -121,30 +121,11 @@ module Flapjack
121
121
  def self.parse_and_validate(raw, opts = {})
122
122
  errors = []
123
123
  if parsed = ::Oj.load(raw)
124
-
125
124
  if parsed.is_a?(Hash)
126
- missing_keys = REQUIRED_KEYS.select {|k|
127
- !parsed.has_key?(k) || parsed[k].nil? || parsed[k].empty?
128
- }
129
- unless missing_keys.empty?
130
- errors << "Event hash has missing keys '#{missing_keys.join('\', \'')}'"
131
- end
132
-
133
- unknown_keys = parsed.keys - (REQUIRED_KEYS + OPTIONAL_KEYS)
134
- unless unknown_keys.empty?
135
- errors << "Event hash has unknown key(s) '#{unknown_keys.join('\', \'')}'"
136
- end
125
+ errors = validation_errors_for_hash(parsed, opts)
137
126
  else
138
- errors << "Event must be a JSON hash, see https://github.com/flpjck/flapjack/wiki/DATA_STRUCTURES#event-queue"
139
- end
140
-
141
- if errors.empty?
142
- errors += VALIDATIONS.keys.inject([]) {|ret,vk|
143
- ret << "Event #{VALIDATIONS[vk]}" unless vk.call(parsed)
144
- ret
145
- }
127
+ errors << "Event must be a JSON hash, see https://github.com/flapjack/flapjack/wiki/DATA_STRUCTURES#event-queue"
146
128
  end
147
-
148
129
  return parsed if errors.empty?
149
130
  end
150
131
 
@@ -160,6 +141,29 @@ module Flapjack
160
141
  nil
161
142
  end
162
143
 
144
+ def self.validation_errors_for_hash(hash, opts = {})
145
+ errors = []
146
+ missing_keys = REQUIRED_KEYS.select {|k|
147
+ !hash.has_key?(k) || hash[k].nil? || hash[k].empty?
148
+ }
149
+ unless missing_keys.empty?
150
+ errors << "Event hash has missing keys '#{missing_keys.join('\', \'')}'"
151
+ end
152
+
153
+ unknown_keys = hash.keys - (REQUIRED_KEYS + OPTIONAL_KEYS)
154
+ unless unknown_keys.empty?
155
+ errors << "Event hash has unknown key(s) '#{unknown_keys.join('\', \'')}'"
156
+ end
157
+
158
+ if errors.empty?
159
+ errors += VALIDATIONS.keys.inject([]) {|ret,vk|
160
+ ret << "Event #{VALIDATIONS[vk]}" unless vk.call(hash)
161
+ ret
162
+ }
163
+ end
164
+ errors
165
+ end
166
+
163
167
  # creates, or modifies, an event object and adds it to the events list in redis
164
168
  # 'entity' => entity,
165
169
  # 'check' => check,
@@ -16,17 +16,26 @@ module Flapjack
16
16
  :time_restrictions, :unknown_media, :warning_media, :critical_media,
17
17
  :unknown_blackhole, :warning_blackhole, :critical_blackhole
18
18
 
19
+ def self.all(options = {})
20
+ raise "Redis connection not set" unless redis = options[:redis]
21
+ redis.keys("contact_notification_rules:*").inject([]) do |memo, contact_key|
22
+ redis.smembers(contact_key).each do |rule_id|
23
+ ret = self.find_by_id(rule_id, :redis => redis)
24
+ memo << ret unless ret.nil?
25
+ end
26
+ memo
27
+ end
28
+ end
29
+
19
30
  def self.exists_with_id?(rule_id, options = {})
20
31
  raise "Redis connection not set" unless redis = options[:redis]
21
32
  raise "No id value passed" unless not (rule_id.nil? || rule_id == '')
22
- logger = options[:logger]
23
33
  redis.exists("notification_rule:#{rule_id}")
24
34
  end
25
35
 
26
36
  def self.find_by_id(rule_id, options = {})
27
37
  raise "Redis connection not set" unless redis = options[:redis]
28
38
  raise "No id value passed" unless not (rule_id.nil? || rule_id == '')
29
- logger = options[:logger]
30
39
 
31
40
  # sanity check
32
41
  return unless redis.exists("notification_rule:#{rule_id}")
@@ -34,6 +43,14 @@ module Flapjack
34
43
  self.new({:id => rule_id.to_s}, {:redis => redis})
35
44
  end
36
45
 
46
+ def self.find_by_ids(rule_ids, options = {})
47
+ raise "Redis connection not set" unless redis = options[:redis]
48
+
49
+ rule_ids.map do |id|
50
+ self.find_by_id(id, options)
51
+ end
52
+ end
53
+
37
54
  # replacing save! etc
38
55
  def self.add(rule_data, options = {})
39
56
  raise "Redis connection not set" unless redis = options[:redis]
@@ -43,15 +60,18 @@ module Flapjack
43
60
  return errors
44
61
  end
45
62
  rule_id = rule_data[:id] || SecureRandom.uuid
46
- errors = self.add_or_update(rule_data.merge(:id => rule_id), options)
63
+
64
+ errors = self.add_or_update(rule_data.merge(:id => rule_id), :redis => redis, :logger => options[:logger])
47
65
  return errors unless errors.nil? || errors.empty?
66
+
48
67
  self.find_by_id(rule_id, :redis => redis)
49
68
  end
50
69
 
51
- def update(rule_data, opts = {})
52
- errors = self.class.add_or_update({:contact_id => @contact_id}.merge(rule_data.merge(:id => @id)),
53
- :redis => @redis, :logger => opts[:logger])
70
+ def update(update_data, opts = {})
71
+ rule_data = @redis.hgetall("notification_rule:#{@id}").merge(update_data.merge(:id => @id))
72
+ errors = self.class.add_or_update(rule_data, :redis => @redis, :logger => opts[:logger])
54
73
  return errors unless errors.nil? || errors.empty?
74
+
55
75
  refresh
56
76
  nil
57
77
  end
@@ -69,7 +89,6 @@ module Flapjack
69
89
  return unless !tr.nil? && tr.is_a?(Hash)
70
90
  return if timezone.nil? && !timezone.is_a?(ActiveSupport::TimeZone)
71
91
  return unless tr = prepare_time_restriction(tr, timezone)
72
-
73
92
  IceCube::Schedule.from_hash(tr)
74
93
  end
75
94
 
@@ -216,39 +235,34 @@ module Flapjack
216
235
  # this will hand back a 'deep' copy
217
236
  tr = symbolize(time_restriction)
218
237
 
219
- return unless tr.has_key?(:start_time) && tr.has_key?(:end_time)
238
+ return unless (tr.has_key?(:start_time) || tr.has_key?(:start_date)) &&
239
+ (tr.has_key?(:end_time) || tr.has_key?(:end_date))
220
240
 
221
- parsed_time = proc {|t|
222
- if t.is_a?(Time)
223
- t
241
+ parsed_time = proc {|tr, field|
242
+ if t = tr.delete(field)
243
+ t = t.dup
244
+ t = t[:time] if t.is_a?(Hash)
245
+
246
+ if t.is_a?(Time)
247
+ t
248
+ else
249
+ begin; (timezone || Time).parse(t); rescue ArgumentError; nil; end
250
+ end
224
251
  else
225
- begin; (timezone || Time).parse(t); rescue ArgumentError; nil; end
252
+ nil
226
253
  end
227
254
  }
228
255
 
229
- start_time = case tr[:start_time]
230
- when String, Time
231
- parsed_time.call(tr.delete(:start_time).dup)
232
- when Hash
233
- time_hash = tr.delete(:start_time).dup
234
- parsed_time.call(time_hash[:time])
235
- end
236
-
237
- end_time = case tr[:end_time]
238
- when String, Time
239
- parsed_time.call(tr.delete(:end_time).dup)
240
- when Hash
241
- time_hash = tr.delete(:end_time).dup
242
- parsed_time.call(time_hash[:time])
243
- end
256
+ start_time = parsed_time.call(tr, :start_date) || parsed_time.call(tr, :start_time)
257
+ end_time = parsed_time.call(tr, :end_date) || parsed_time.call(tr, :end_time)
244
258
 
245
259
  return unless start_time && end_time
246
260
 
247
- tr[:start_date] = timezone ?
261
+ tr[:start_time] = timezone ?
248
262
  {:time => start_time, :zone => timezone.name} :
249
263
  start_time
250
264
 
251
- tr[:end_date] = timezone ?
265
+ tr[:end_time] = timezone ?
252
266
  {:time => end_time, :zone => timezone.name} :
253
267
  end_time
254
268
 
@@ -3,7 +3,7 @@
3
3
  # A HTTP-based API server, which provides queries to determine the status of
4
4
  # entities and the checks that are reported against them.
5
5
  #
6
- # There's a matching flapjack-diner gem at https://github.com/flpjck/flapjack-diner
6
+ # There's a matching flapjack-diner gem at https://github.com/flapjack/flapjack-diner
7
7
  # which consumes data from this API.
8
8
 
9
9
  require 'time'
@@ -94,7 +94,7 @@ module Flapjack
94
94
  end
95
95
 
96
96
  # Returns all the contacts
97
- # https://github.com/flpjck/flapjack/wiki/API#wiki-get_contacts
97
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-get_contacts
98
98
  app.get '/contacts' do
99
99
  content_type :json
100
100
  "[" +
@@ -105,7 +105,7 @@ module Flapjack
105
105
  end
106
106
 
107
107
  # Returns the core information about the specified contact
108
- # https://github.com/flpjck/flapjack/wiki/API#wiki-get_contacts_id
108
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-get_contacts_id
109
109
  app.get '/contacts/:contact_id' do
110
110
  content_type :json
111
111
 
@@ -114,7 +114,7 @@ module Flapjack
114
114
  end
115
115
 
116
116
  # Lists this contact's notification rules
117
- # https://github.com/flpjck/flapjack/wiki/API#wiki-get_contacts_id_notification_rules
117
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-get_contacts_id_notification_rules
118
118
  app.get '/contacts/:contact_id/notification_rules' do
119
119
  content_type :json
120
120
 
@@ -122,7 +122,7 @@ module Flapjack
122
122
  end
123
123
 
124
124
  # Get the specified notification rule for this user
125
- # https://github.com/flpjck/flapjack/wiki/API#wiki-get_contacts_id_notification_rules_id
125
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-get_contacts_id_notification_rules_id
126
126
  app.get '/notification_rules/:id' do
127
127
  content_type :json
128
128
 
@@ -131,7 +131,7 @@ module Flapjack
131
131
  end
132
132
 
133
133
  # Creates a notification rule for a contact
134
- # https://github.com/flpjck/flapjack/wiki/API#wiki-post_contacts_id_notification_rules
134
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-post_contacts_id_notification_rules
135
135
  app.post '/notification_rules' do
136
136
  content_type :json
137
137
 
@@ -157,7 +157,7 @@ module Flapjack
157
157
  end
158
158
 
159
159
  # Updates a notification rule
160
- # https://github.com/flpjck/flapjack/wiki/API#wiki-put_notification_rules_id
160
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-put_notification_rules_id
161
161
  app.put('/notification_rules/:id') do
162
162
  content_type :json
163
163
 
@@ -180,7 +180,7 @@ module Flapjack
180
180
  end
181
181
 
182
182
  # Deletes a notification rule
183
- # https://github.com/flpjck/flapjack/wiki/API#wiki-put_notification_rules_id
183
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-put_notification_rules_id
184
184
  app.delete('/notification_rules/:id') do
185
185
  logger.debug("delete /notification_rules/#{params[:id]}")
186
186
  rule = find_rule(params[:id])
@@ -191,7 +191,7 @@ module Flapjack
191
191
  end
192
192
 
193
193
  # Returns the media of a contact
194
- # https://github.com/flpjck/flapjack/wiki/API#wiki-get_contacts_id_media
194
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-get_contacts_id_media
195
195
  app.get '/contacts/:contact_id/media' do
196
196
  content_type :json
197
197
 
@@ -209,7 +209,7 @@ module Flapjack
209
209
  end
210
210
 
211
211
  # Returns the specified media of a contact
212
- # https://github.com/flpjck/flapjack/wiki/API#wiki-get_contacts_id_media_media
212
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-get_contacts_id_media_media
213
213
  app.get('/contacts/:contact_id/media/:id') do
214
214
  content_type :json
215
215
 
@@ -229,7 +229,7 @@ module Flapjack
229
229
  end
230
230
 
231
231
  # Creates or updates a media of a contact
232
- # https://github.com/flpjck/flapjack/wiki/API#wiki-put_contacts_id_media_media
232
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-put_contacts_id_media_media
233
233
  app.put('/contacts/:contact_id/media/:id') do
234
234
  content_type :json
235
235
 
@@ -275,7 +275,7 @@ module Flapjack
275
275
  end
276
276
 
277
277
  # Returns the timezone of a contact
278
- # https://github.com/flpjck/flapjack/wiki/API#wiki-get_contacts_id_timezone
278
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-get_contacts_id_timezone
279
279
  app.get('/contacts/:contact_id/timezone') do
280
280
  content_type :json
281
281
 
@@ -284,7 +284,7 @@ module Flapjack
284
284
  end
285
285
 
286
286
  # Sets the timezone of a contact
287
- # https://github.com/flpjck/flapjack/wiki/API#wiki-put_contacts_id_timezone
287
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-put_contacts_id_timezone
288
288
  app.put('/contacts/:contact_id/timezone') do
289
289
  content_type :json
290
290
 
@@ -294,7 +294,7 @@ module Flapjack
294
294
  end
295
295
 
296
296
  # Removes the timezone of a contact
297
- # https://github.com/flpjck/flapjack/wiki/API#wiki-put_contacts_id_timezone
297
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-put_contacts_id_timezone
298
298
  app.delete('/contacts/:contact_id/timezone') do
299
299
  contact = find_contact(params[:contact_id])
300
300
  contact.timezone = nil
@@ -379,7 +379,7 @@ module Flapjack
379
379
  number_found = entity_list.length
380
380
  case
381
381
  when number_found == 0
382
- msg = "found no entities matching /#{pattern}/"
382
+ msg = "found no entities matching /#{entity_pattern}/"
383
383
  when number_found >= 1
384
384
  failing_list = Flapjack::Data::EntityCheck.find_all_failing_by_entity(:redis => @redis)
385
385
  entities = failing_list.select {|k,v| v.count >= 1 && entity_list.include?(k) }
@@ -414,7 +414,7 @@ module Flapjack
414
414
  number_found = entity_names.length
415
415
  case
416
416
  when number_found == 0
417
- msg = "found no entities matching /#{pattern}/"
417
+ msg = "found no entities matching /#{entity_pattern}/"
418
418
  when number_found >= 1
419
419
  entities = entity_names.map {|name|
420
420
  Flapjack::Data::Entity.find_by_name(name, :redis => @redis)
@@ -3,7 +3,7 @@
3
3
  # A HTTP-based API server, which provides queries to determine the status of
4
4
  # entities and the checks that are reported against them.
5
5
  #
6
- # There's a matching flapjack-diner gem at https://github.com/flpjck/flapjack-diner
6
+ # There's a matching flapjack-diner gem at https://github.com/flapjack/flapjack-diner
7
7
  # which consumes data from this API.
8
8
 
9
9
  require 'time'
@@ -20,6 +20,7 @@ require 'flapjack/gateways/jsonapi/check_methods'
20
20
  require 'flapjack/gateways/jsonapi/contact_methods'
21
21
  require 'flapjack/gateways/jsonapi/entity_methods'
22
22
  require 'flapjack/gateways/jsonapi/medium_methods'
23
+ require 'flapjack/gateways/jsonapi/metrics_methods'
23
24
  require 'flapjack/gateways/jsonapi/notification_rule_methods'
24
25
  require 'flapjack/gateways/jsonapi/pagerduty_credential_methods'
25
26
  require 'flapjack/gateways/jsonapi/report_methods'
@@ -53,9 +54,16 @@ module Flapjack
53
54
  end
54
55
 
55
56
  class NotificationRuleNotFound < RuntimeError
56
- attr_reader :rule_id
57
- def initialize(rule_id)
58
- @rule_id = rule_id
57
+ attr_reader :notification_rule_id
58
+ def initialize(notification_rule_id)
59
+ @notification_rule_id = notification_rule_id
60
+ end
61
+ end
62
+
63
+ class NotificationRulesNotFound < RuntimeError
64
+ attr_reader :notification_rule_ids
65
+ def initialize(notification_rule_ids)
66
+ @notification_rule_ids = notification_rule_ids
59
67
  end
60
68
  end
61
69
 
@@ -132,7 +140,9 @@ module Flapjack
132
140
  when Flapjack::Gateways::JSONAPI::ContactsNotFound
133
141
  rescue_error.call(404, e, request_info, "could not find contacts '" + e.contact_ids.join(', ') + "'")
134
142
  when Flapjack::Gateways::JSONAPI::NotificationRuleNotFound
135
- rescue_error.call(404, e, request_info,"could not find notification rule '#{e.rule_id}'")
143
+ rescue_error.call(404, e, request_info,"could not find notification rule '#{e.notification_rule_id}'")
144
+ when Flapjack::Gateways::JSONAPI::NotificationRulesNotFound
145
+ rescue_error.call(404, e, request_info, "could not find notification rules '" + e.notification_rule_ids.join(', ') + "'")
136
146
  when Flapjack::Gateways::JSONAPI::EntityNotFound
137
147
  rescue_error.call(404, e, request_info, "could not find entity '#{e.entity}'")
138
148
  when Flapjack::Gateways::JSONAPI::EntityCheckNotFound
@@ -241,11 +251,6 @@ module Flapjack
241
251
  headers(cors_headers)
242
252
  end
243
253
 
244
- def location(ids)
245
- location = "#{base_url}#{request.path_info}#{ids.length == 1 ? '/' + ids.first : '?ids=' + ids.join(',')}"
246
- headers({'Location' => location})
247
- end
248
-
249
254
  def err(status, *msg)
250
255
  msg_str = msg.join(", ")
251
256
  logger.info "Error: #{msg_str}"
@@ -405,6 +410,7 @@ module Flapjack
405
410
  register Flapjack::Gateways::JSONAPI::ContactMethods
406
411
  register Flapjack::Gateways::JSONAPI::EntityMethods
407
412
  register Flapjack::Gateways::JSONAPI::MediumMethods
413
+ register Flapjack::Gateways::JSONAPI::MetricsMethods
408
414
  register Flapjack::Gateways::JSONAPI::NotificationRuleMethods
409
415
  register Flapjack::Gateways::JSONAPI::PagerdutyCredentialMethods
410
416
  register Flapjack::Gateways::JSONAPI::ReportMethods
@@ -89,15 +89,15 @@ module Flapjack
89
89
 
90
90
  semaphore.release
91
91
 
92
- ids = contacts_data.map {|c| c['id']}
93
- location(ids)
94
- status 201
92
+ contact_ids = contacts_data.map {|c| c['id']}
95
93
 
96
- contacts_data.map {|cd| cd['id']}.to_json
94
+ response.headers['Location'] = "#{base_url}/contacts/#{contact_ids.join(',')}"
95
+ status 201
96
+ contact_ids.to_json
97
97
  end
98
98
 
99
99
  # Returns all (/contacts) or some (/contacts/1,2,3) or one (/contacts/2) contact(s)
100
- # https://github.com/flpjck/flapjack/wiki/API#wiki-get_contacts
100
+ # https://github.com/flapjack/flapjack/wiki/API#wiki-get_contacts
101
101
  app.get %r{^/contacts(?:/)?([^/]+)?$} do
102
102
  requested_contacts = if params[:captures] && params[:captures][0]
103
103
  params[:captures][0].split(',').uniq
@@ -108,7 +108,7 @@ module Flapjack
108
108
  contacts = if requested_contacts
109
109
  Flapjack::Data::Contact.find_by_ids(requested_contacts, :logger => logger, :redis => redis)
110
110
  else
111
- Flapjack::Data::Contact.all(:redis => redis)
111
+ Flapjack::Data::Contact.all(:redis => redis).reject {|c| c.id.nil? || c.id.empty? }
112
112
  end
113
113
  contacts.compact!
114
114