flapjack 1.1.0 → 1.2.0rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +12 -7
  5. data/CHANGELOG.md +12 -0
  6. data/Gemfile +6 -2
  7. data/Gemfile-ruby1.9 +29 -0
  8. data/Gemfile-ruby1.9.lock +251 -0
  9. data/README.md +2 -2
  10. data/Rakefile +1 -0
  11. data/etc/flapjack_config.yaml.example +2 -2
  12. data/features/steps/events_steps.rb +2 -2
  13. data/features/steps/flapjack-netsaint-parser_steps.rb +1 -1
  14. data/features/support/env.rb +1 -6
  15. data/lib/flapjack/cli/import.rb +2 -5
  16. data/lib/flapjack/cli/purge.rb +4 -4
  17. data/lib/flapjack/cli/receiver.rb +122 -54
  18. data/lib/flapjack/cli/server.rb +0 -5
  19. data/lib/flapjack/coordinator.rb +6 -0
  20. data/lib/flapjack/data/contact.rb +10 -62
  21. data/lib/flapjack/data/entity.rb +36 -52
  22. data/lib/flapjack/data/entity_check.rb +90 -21
  23. data/lib/flapjack/data/event.rb +4 -5
  24. data/lib/flapjack/data/notification.rb +8 -10
  25. data/lib/flapjack/data/notification_rule.rb +32 -35
  26. data/lib/flapjack/data/tagged.rb +48 -0
  27. data/lib/flapjack/gateways/jabber.rb +4 -5
  28. data/lib/flapjack/gateways/jsonapi/check_methods.rb +45 -7
  29. data/lib/flapjack/gateways/jsonapi/check_presenter.rb +1 -1
  30. data/lib/flapjack/gateways/jsonapi/contact_methods.rb +8 -2
  31. data/lib/flapjack/gateways/jsonapi/entity_methods.rb +26 -8
  32. data/lib/flapjack/gateways/jsonapi/medium_methods.rb +13 -9
  33. data/lib/flapjack/gateways/jsonapi/metrics_methods.rb +2 -2
  34. data/lib/flapjack/gateways/jsonapi/notification_rule_methods.rb +1 -1
  35. data/lib/flapjack/gateways/jsonapi/pagerduty_credential_methods.rb +24 -17
  36. data/lib/flapjack/gateways/jsonapi/rack/json_params_parser.rb +1 -1
  37. data/lib/flapjack/gateways/jsonapi/report_methods.rb +4 -4
  38. data/lib/flapjack/gateways/jsonapi.rb +52 -31
  39. data/lib/flapjack/gateways/oobetet.rb +2 -3
  40. data/lib/flapjack/gateways/pagerduty.rb +9 -8
  41. data/lib/flapjack/gateways/web/public/js/backbone.jsonapi.js +19 -0
  42. data/lib/flapjack/gateways/web/public/js/flapjack.js +6 -2
  43. data/lib/flapjack/gateways/web/public/js/modules/contact.js +9 -14
  44. data/lib/flapjack/gateways/web/public/js/modules/medium.js +1 -0
  45. data/lib/flapjack/gateways/web/public/js/self_stats.js +1 -1
  46. data/lib/flapjack/gateways/web/views/edit_contacts.html.erb +3 -3
  47. data/lib/flapjack/gateways/web.rb +8 -7
  48. data/lib/flapjack/notifier.rb +2 -4
  49. data/lib/flapjack/processor.rb +2 -2
  50. data/lib/flapjack/version.rb +1 -1
  51. data/lib/flapjack.rb +10 -0
  52. data/spec/lib/flapjack/coordinator_spec.rb +18 -0
  53. data/spec/lib/flapjack/data/contact_spec.rb +4 -12
  54. data/spec/lib/flapjack/data/entity_check_spec.rb +56 -3
  55. data/spec/lib/flapjack/data/entity_spec.rb +79 -67
  56. data/spec/lib/flapjack/data/event_spec.rb +78 -78
  57. data/spec/lib/flapjack/data/notification_rule_spec.rb +4 -2
  58. data/spec/lib/flapjack/gateways/jsonapi/check_methods_spec.rb +94 -11
  59. data/spec/lib/flapjack/gateways/jsonapi/entity_methods_spec.rb +84 -0
  60. data/spec/lib/flapjack/gateways/pagerduty_spec.rb +5 -3
  61. data/spec/lib/flapjack/gateways/web_spec.rb +3 -3
  62. data/spec/service_consumers/pact_helper.rb +74 -0
  63. data/spec/service_consumers/pacts/flapjack-diner_v1.0.json +4522 -0
  64. data/spec/service_consumers/provider_states_for_flapjack-diner.rb +356 -0
  65. data/spec/spec_helper.rb +0 -8
  66. data/spec/support/jsonapi_helper.rb +1 -1
  67. data/tasks/benchmarks.rake +6 -3
  68. data/tasks/profile.rake +1 -1
  69. data/tmp/acknowledge.rb +0 -3
  70. data/tmp/create_event_ok.rb +0 -3
  71. data/tmp/create_event_unknown.rb +0 -3
  72. data/tmp/create_events_failure.rb +0 -3
  73. data/tmp/create_events_ok.rb +0 -3
  74. data/tmp/create_events_ok_fail_ack_ok.rb +0 -3
  75. data/tmp/create_events_ok_failure.rb +2 -5
  76. data/tmp/create_events_ok_failure_ack.rb +0 -3
  77. data/tmp/test_json_post.rb +4 -3
  78. data/tmp/test_notification_rules_api.rb +2 -3
  79. metadata +13 -8
  80. data/lib/flapjack/data/tag.rb +0 -61
  81. data/lib/flapjack/data/tag_set.rb +0 -16
  82. data/spec/lib/flapjack/data/tag_spec.rb +0 -36
@@ -2,9 +2,7 @@
2
2
 
3
3
  require 'dante'
4
4
  require 'redis'
5
-
6
- require 'oj'
7
- Oj.default_options = { :indent => 0, :mode => :strict }
5
+ require 'hiredis'
8
6
 
9
7
  require 'flapjack/configuration'
10
8
  require 'flapjack/data/event'
@@ -21,16 +19,28 @@ module Flapjack
21
19
  @options = options
22
20
 
23
21
  @config = Flapjack::Configuration.new
24
- @config.load(global_options[:config])
25
- @config_env = @config.all
26
22
 
27
- if @config_env.nil? || @config_env.empty?
28
- exit_now! "No config data for environment '#{FLAPJACK_ENV}' found in '#{global_options[:config]}'"
23
+ if 'mirror'.eql?(@options[:type]) &&
24
+ (global_options[:config].nil? || global_options[:config].strip.empty?)
25
+
26
+ @config_env = {}
27
+ @config_runner = {}
28
+ else
29
+ @config.load(global_options[:config])
30
+ @config_env = @config.all
31
+
32
+ if @config_env.nil? || @config_env.empty?
33
+ exit_now! "No config data for environment '#{FLAPJACK_ENV}' found in '#{global_options[:config]}'"
34
+ end
35
+
36
+ @config_runner = @config_env["#{@options[:type]}-receiver"] || {}
29
37
  end
30
38
 
31
- @config_runner = @config_env["#{@options[:type]}-receiver"] || {}
39
+ @redis_options = @config.for_redis
40
+ end
32
41
 
33
- @pidfile = case
42
+ def pidfile
43
+ @pidfile ||= case
34
44
  when !@options[:pidfile].nil?
35
45
  @options[:pidfile]
36
46
  when !@config_env['pid_dir'].nil?
@@ -38,8 +48,10 @@ module Flapjack
38
48
  else
39
49
  "/var/run/flapjack/#{@options[:type]}-receiver.pid"
40
50
  end
51
+ end
41
52
 
42
- @logfile = case
53
+ def logfile
54
+ @logfile ||= case
43
55
  when !@options[:logfile].nil?
44
56
  @options[:logfile]
45
57
  when !@config_env['log_dir'].nil?
@@ -47,8 +59,6 @@ module Flapjack
47
59
  else
48
60
  "/var/run/flapjack/#{@options[:type]}-receiver.log"
49
61
  end
50
-
51
- @redis_options = @config.for_redis
52
62
  end
53
63
 
54
64
  def start
@@ -97,7 +107,7 @@ module Flapjack
97
107
  def status
98
108
  if runner(@options[:type]).daemon_running?
99
109
  pid = get_pid
100
- uptime = Time.now - File.stat(@pidfile).ctime
110
+ uptime = Time.now - File.stat(pidfile).ctime
101
111
  puts "#{@options[:type]}-receiver is running: pid #{pid}, uptime #{uptime}"
102
112
  else
103
113
  exit_now! "#{@options[:type]}-receiver is not running"
@@ -109,22 +119,30 @@ module Flapjack
109
119
  end
110
120
 
111
121
  def mirror
122
+ if (@options[:dest].nil? || @options[:dest].strip.empty?) &&
123
+ @redis_options.nil?
124
+
125
+ exit_now! "No destination redis URL passed, and none configured"
126
+ end
127
+
112
128
  mirror_receive(:source => @options[:source],
113
- :all => @options[:all], :follow => @options[:follow],
114
- :last => @options[:last], :time => @options[:time])
129
+ :dest => @options[:dest] || @redis_options,
130
+ :include => @options[:include], :all => @options[:all],
131
+ :follow => @options[:follow], :last => @options[:last],
132
+ :time => @options[:time])
115
133
  end
116
134
 
117
135
  private
118
136
 
119
137
  def redis
120
- @redis ||= Redis.new(@redis_options)
138
+ @redis ||= Redis.new(@redis_options.merge(:driver => :hiredis))
121
139
  end
122
140
 
123
141
  def runner(type)
124
142
  return @runner if @runner
125
143
 
126
- @runner = Dante::Runner.new("#{@options[:type]}-receiver", :pid_path => @pidfile,
127
- :log_path => @logfile)
144
+ @runner = Dante::Runner.new("#{@options[:type]}-receiver", :pid_path => pidfile,
145
+ :log_path => logfile)
128
146
  @runner
129
147
  end
130
148
 
@@ -254,7 +272,7 @@ module Flapjack
254
272
  end
255
273
 
256
274
  def get_pid
257
- IO.read(@pidfile).chomp.to_i
275
+ IO.read(pidfile).chomp.to_i
258
276
  rescue StandardError
259
277
  pid = nil
260
278
  end
@@ -298,7 +316,6 @@ module Flapjack
298
316
  end
299
317
 
300
318
  def json_feeder(opts = {})
301
-
302
319
  input = if opts[:from]
303
320
  File.open(opts[:from]) # Explodes if file does not exist.
304
321
  elsif $stdin.tty?
@@ -328,16 +345,30 @@ module Flapjack
328
345
  puts "Done."
329
346
  end
330
347
 
331
-
332
348
  def mirror_receive(opts)
333
349
  unless opts[:follow] || opts[:all]
334
350
  exit_now! "one or both of --follow or --all is required"
335
351
  end
336
352
 
337
- source_redis = Redis.new(:url => opts[:source])
353
+ include_re = nil
354
+ unless opts[:include].nil? || opts[:include].strip.empty?
355
+ begin
356
+ include_re = Regexp.new(opts[:include].strip)
357
+ rescue RegexpError
358
+ exit_now! "could not parse include Regexp: #{opts[:include].strip}"
359
+ end
360
+ end
361
+
362
+ source_addr = opts[:source]
363
+ source_redis = Redis.new(:url => source_addr, :driver => :hiredis)
338
364
 
339
- archives = mirror_get_archive_keys_stats(source_redis)
340
- raise "found no archives!" unless archives && archives.length > 0
365
+ dest_addr = opts[:dest]
366
+ dest_redis = Redis.new(:url => dest_addr, :driver => :hiredis)
367
+
368
+ refresh_archive_index(source_addr, :source => source_redis, :dest => dest_redis)
369
+ archives = mirror_get_archive_keys_stats(source_addr, :source => source_redis,
370
+ :dest => dest_redis)
371
+ raise "found no archives!" if archives.empty?
341
372
 
342
373
  puts "found archives: #{archives.inspect}"
343
374
 
@@ -350,53 +381,85 @@ module Flapjack
350
381
  events_sent = 0
351
382
  case
352
383
  when opts[:all]
353
- archive_key = archives[0][:name]
384
+ archive_idx = 0
354
385
  cursor = -1
355
386
  when opts[:last], opts[:time]
356
387
  raise "Sorry, unimplemented"
357
388
  else
358
389
  # wait for the next event to be archived, so point the cursor at a non-existant
359
390
  # slot in the list, the one before the 0'th
360
- archive_key = archives[-1][:name]
391
+ archive_idx = archives.size - 1
361
392
  cursor = -1 - archives[-1][:size]
362
393
  end
363
394
 
395
+ archive_key = archives[archive_idx][:name]
364
396
  puts archive_key
365
397
 
366
398
  loop do
367
- new_archive_key = false
368
- # something to read at cursor?
369
- event = source_redis.lindex(archive_key, cursor)
370
- if event
371
- Flapjack::Data::Event.add(event, :redis => redis)
372
- events_sent += 1
373
- print "#{events_sent} " if events_sent % 1000 == 0
399
+ event_json = source_redis.lindex(archive_key, cursor)
400
+ if event_json
401
+ event = Flapjack::Data::Event.parse_and_validate(event_json)
402
+ if !event.nil? && (include_re.nil? ||
403
+ (include_re === "#{event['entity']}:#{event['check']}"))
404
+
405
+ Flapjack::Data::Event.add(event, :redis => dest_redis)
406
+ events_sent += 1
407
+ print "#{events_sent} " if events_sent % 1000 == 0
408
+ end
374
409
  cursor -= 1
410
+ next
411
+ end
412
+
413
+ archives = mirror_get_archive_keys_stats(source_addr,
414
+ :source => source_redis, :dest => dest_redis)
415
+
416
+ if archives.any? {|a| a[:size] == 0}
417
+ # data may be out of date -- refresh, then reject any immediately
418
+ # expired keys directly; don't keep chasing updated data
419
+ refresh_archive_index(source_addr, :source => source_redis, :dest => dest_redis)
420
+ archives = mirror_get_archive_keys_stats(source_addr,
421
+ :source => source_redis, :dest => dest_redis).select {|a| a[:size] > 0}
422
+ end
423
+
424
+ if archives.empty?
425
+ sleep 1
426
+ next
427
+ end
428
+
429
+ archive_idx = archives.index {|a| a[:name] == archive_key }
430
+ archive_idx = archive_idx.nil? ? 0 : (archive_idx + 1)
431
+ if archives[archive_idx]
432
+ archive_key = archives[archive_idx][:name]
433
+ puts archive_key
434
+ cursor = -1
375
435
  else
376
- puts "\narchive key: #{archive_key}, cursor: #{cursor}"
377
- # do we need to look at the next archive bucket?
378
- archives = mirror_get_archive_keys_stats(source_redis)
379
- i = archives.index {|a| a[:name] == archive_key }
380
- if archives[i][:size] = (cursor.abs + 1)
381
- if archives[i + 1]
382
- archive_key = archives[i + 1][:name]
383
- puts archive_key
384
- cursor = -1
385
- new_archive_key = true
386
- else
387
- return unless opts[:follow]
388
- end
389
- end
390
- sleep 1 unless new_archive_key
436
+ break unless opts[:follow]
437
+ sleep 1
391
438
  end
392
439
  end
393
440
  end
394
441
 
395
- def mirror_get_archive_keys_stats(source_redis)
396
- source_redis.keys("events_archive:*").sort.map {|a|
397
- { :name => a,
398
- :size => source_redis.llen(a) }
399
- }
442
+ def mirror_get_archive_keys_stats(name, opts = {})
443
+ source_redis = opts[:source]
444
+ dest_redis = opts[:dest]
445
+ dest_redis.smembers("known_events_archive_keys:#{name}").sort.collect do |eak|
446
+ {:name => eak, :size => source_redis.llen(eak)}
447
+ end
448
+ end
449
+
450
+ def refresh_archive_index(name, opts = {})
451
+ source_redis = opts[:source]
452
+ dest_redis = opts[:dest]
453
+ # refresh the key name cache, avoid repeated calls to redis KEYS
454
+ # this cache will be updated any time a new archive bucket is created
455
+ archive_keys = source_redis.keys("events_archive:*").group_by do |ak|
456
+ (source_redis.llen(ak) > 0) ? 't' : 'f'
457
+ end
458
+
459
+ {'f' => :srem, 't' => :sadd}.each_pair do |k, cmd|
460
+ next unless archive_keys.has_key?(k) && !archive_keys[k].empty?
461
+ dest_redis.send(cmd, "known_events_archive_keys:#{name}", archive_keys[k])
462
+ end
400
463
  end
401
464
 
402
465
  end
@@ -596,9 +659,13 @@ command :receiver do |receiver|
596
659
  receiver.desc 'Mirror receiver'
597
660
  receiver.command :mirror do |mirror|
598
661
 
599
- mirror.flag [:s, 'source'], :desc => 'URL of source redis database, eg redis://localhost:6379/0',
662
+ mirror.flag [:s, 'source'], :desc => 'URL of source redis database, e.g. redis://localhost:6379/0',
600
663
  :required => true
601
664
 
665
+ mirror.flag [:d, 'dest'], :desc => 'URL of destination redis database, e.g. redis://localhost:6379/1'
666
+
667
+ mirror.flag [:i, 'include'], :desc => 'Regexp which must match event id for it to be mirrored'
668
+
602
669
  # one or both of follow, all is required
603
670
  mirror.switch [:f, 'follow'], :desc => 'keep reading events as they are archived on the source',
604
671
  :default_value => nil
@@ -615,6 +682,7 @@ command :receiver do |receiver|
615
682
  :default_value => nil
616
683
 
617
684
  mirror.action do |global_options,options,args|
685
+ options.merge!(:type => 'mirror')
618
686
  receiver = Flapjack::CLI::Receiver.new(global_options, options)
619
687
  receiver.mirror
620
688
  end
@@ -2,11 +2,6 @@
2
2
 
3
3
  require 'dante'
4
4
 
5
- require 'oj'
6
- Oj.mimic_JSON
7
- Oj.default_options = { :indent => 0, :mode => :strict }
8
- require 'active_support/json'
9
-
10
5
  require 'flapjack/coordinator'
11
6
 
12
7
  module Flapjack
@@ -32,6 +32,12 @@ module Flapjack
32
32
  EM.synchrony do
33
33
  setup_signals if options[:signals]
34
34
 
35
+ redis = Flapjack::RedisPool.new(:config => @redis_options, :size => 1)
36
+ ['entity', 'check'].each do |type|
37
+ discovered = redis.keys("#{type}_tag:*")
38
+ redis.sadd("known_tags:#{type}_tag", discovered) unless discovered.empty?
39
+ end
40
+
35
41
  begin
36
42
  add_pikelets(pikelets(@config.all))
37
43
  loop do
@@ -7,8 +7,6 @@ require 'set'
7
7
  require 'ice_cube'
8
8
  require 'flapjack/data/entity'
9
9
  require 'flapjack/data/notification_rule'
10
- require 'flapjack/data/tag'
11
- require 'flapjack/data/tag_set'
12
10
 
13
11
  require 'securerandom'
14
12
 
@@ -21,7 +19,6 @@ module Flapjack
21
19
  attr_accessor :id, :first_name, :last_name, :email, :media,
22
20
  :media_intervals, :media_rollup_thresholds, :pagerduty_credentials
23
21
 
24
- TAG_PREFIX = 'contact_tag'
25
22
  ALL_MEDIA = ['email', 'sms', 'sms_twilio', 'jabber', 'pagerduty', 'sns']
26
23
 
27
24
  def self.all(options = {})
@@ -75,9 +72,12 @@ module Flapjack
75
72
  end
76
73
 
77
74
  self.add_or_update(contact_id, contact_data, :redis => redis)
78
- if contact = self.find_by_id(contact_id, :redis => redis)
75
+ contact = self.find_by_id(contact_id, :redis => redis)
76
+
77
+ unless contact.nil?
79
78
  contact.notification_rules # invoke to create general rule
80
79
  end
80
+
81
81
  contact
82
82
  end
83
83
 
@@ -128,9 +128,6 @@ module Flapjack
128
128
  # the main alerts sorted set, remove all alerts_by sorted sets
129
129
  # for the contact
130
130
 
131
- # remove this contact from all tags it's marked with
132
- self.delete_tags(*self.tags.to_a)
133
-
134
131
  # remove all associated notification rules
135
132
  self.notification_rules.each do |nr|
136
133
  self.delete_notification_rule(nr)
@@ -252,8 +249,8 @@ module Flapjack
252
249
  rule = self.add_notification_rule({
253
250
  :entities => [],
254
251
  :regex_entities => [],
255
- :tags => Flapjack::Data::TagSet.new([]),
256
- :regex_tags => Flapjack::Data::TagSet.new([]),
252
+ :tags => Set.new([]),
253
+ :regex_tags => Set.new([]),
257
254
  :time_restrictions => [],
258
255
  :warning_media => ALL_MEDIA,
259
256
  :critical_media => ALL_MEDIA,
@@ -415,37 +412,6 @@ module Flapjack
415
412
  @redis.zcard("contact_alerting_checks:#{self.id}:media:#{media}")
416
413
  end
417
414
 
418
- # FIXME
419
- # do a mixin with the following tag methods, they will be the same
420
- # across all objects we allow tags on
421
-
422
- # return the set of tags for this contact
423
- def tags
424
- @tags ||= Flapjack::Data::TagSet.new( @redis.keys("#{TAG_PREFIX}:*").inject([]) {|memo, tag|
425
- if Flapjack::Data::Tag.find(tag, :redis => @redis).include?(@id.to_s)
426
- memo << tag.sub(/^#{TAG_PREFIX}:/, '')
427
- end
428
- memo
429
- } )
430
- end
431
-
432
- # adds tags to this contact
433
- def add_tags(*enum)
434
- enum.each do |t|
435
- Flapjack::Data::Tag.create("#{TAG_PREFIX}:#{t}", [@id], :redis => @redis)
436
- tags.add(t)
437
- end
438
- end
439
-
440
- # removes tags from this contact
441
- def delete_tags(*enum)
442
- enum.each do |t|
443
- tag = Flapjack::Data::Tag.find("#{TAG_PREFIX}:#{t}", :redis => @redis)
444
- tag.delete(@id)
445
- tags.delete(t)
446
- end
447
- end
448
-
449
415
  # return a list of media enabled for this contact
450
416
  # eg [ 'email', 'sms' ]
451
417
  def media_list
@@ -488,32 +454,20 @@ module Flapjack
488
454
  end
489
455
  end
490
456
 
491
- def to_json(*args)
492
- { "id" => self.id,
493
- "first_name" => self.first_name,
494
- "last_name" => self.last_name,
495
- "email" => self.email,
496
- "media" => self.media,
497
- "media_intervals" => self.media_intervals,
498
- "media_rollup_thresholds" => self.media_rollup_thresholds,
499
- "timezone" => self.timezone.name,
500
- "tags" => self.tags.to_a
501
- }.to_json
502
- end
503
-
504
457
  def to_jsonapi(opts = {})
505
- { "id" => self.id,
458
+ json_data = {
459
+ "id" => self.id,
506
460
  "first_name" => self.first_name,
507
461
  "last_name" => self.last_name,
508
462
  "email" => self.email,
509
463
  "timezone" => self.timezone.name,
510
- "tags" => self.tags.to_a,
511
464
  "links" => {
512
465
  :entities => opts[:entity_ids] || [],
513
466
  :media => self.media_ids || [],
514
467
  :notification_rules => self.notification_rule_ids || [],
515
468
  }
516
- }.to_json
469
+ }
470
+ Flapjack.dump_json(json_data)
517
471
  end
518
472
 
519
473
  private
@@ -536,12 +490,6 @@ module Flapjack
536
490
 
537
491
  redis.hmset("contact:#{contact_id}", *attrs) unless attrs.empty?
538
492
 
539
- if ( ! contact_data['tags'].nil? && contact_data['tags'].is_a?(Enumerable))
540
- contact_data['tags'].each do |t|
541
- Flapjack::Data::Tag.create("#{TAG_PREFIX}:#{t}", [contact_id], :redis => redis)
542
- end
543
- end
544
-
545
493
  unless contact_data['media'].nil?
546
494
  redis.del("contact_media:#{contact_id}")
547
495
  redis.del("contact_media_intervals:#{contact_id}")
@@ -3,8 +3,7 @@
3
3
  require 'securerandom'
4
4
 
5
5
  require 'flapjack/data/contact'
6
- require 'flapjack/data/tag'
7
- require 'flapjack/data/tag_set'
6
+ require 'flapjack/data/tagged'
8
7
 
9
8
  module Flapjack
10
9
 
@@ -14,7 +13,7 @@ module Flapjack
14
13
 
15
14
  attr_accessor :name, :id
16
15
 
17
- TAG_PREFIX = 'entity_tag'
16
+ include Tagged
18
17
 
19
18
  def self.all(options = {})
20
19
  raise "Redis connection not set" unless redis = options[:redis]
@@ -452,9 +451,14 @@ module Flapjack
452
451
  redis.sadd("contacts_for:#{entity_id}", contact_id)
453
452
  }
454
453
  end
455
- self.new(:name => entity_name,
456
- :id => entity_id,
457
- :redis => redis)
454
+
455
+ e = self.new(:name => entity_name,
456
+ :id => entity_id,
457
+ :redis => redis)
458
+ if entity['tags'] && entity['tags'].respond_to?(:each)
459
+ e.add_tags(*entity['tags'])
460
+ end
461
+ e
458
462
  end
459
463
 
460
464
  def self.find_by_name(entity_name, options = {})
@@ -508,25 +512,14 @@ module Flapjack
508
512
  }.sort
509
513
  end
510
514
 
511
- def self.find_all_with_tags(tags, options = {})
512
- raise "Redis connection not set" unless redis = options[:redis]
513
- tags_prefixed = tags.collect {|tag|
514
- "#{TAG_PREFIX}:#{tag}"
515
- }
516
- logger.debug "tags_prefixed: #{tags_prefixed.inspect}" if logger = options[:logger]
517
- Flapjack::Data::Tag.find_intersection(tags_prefixed, :redis => redis).collect {|entity_id|
518
- Flapjack::Data::Entity.find_by_id(entity_id, :redis => redis).name
519
- }.compact
520
- end
521
-
522
515
  def self.current_names(options = {})
523
516
  raise "Redis connection not set" unless redis = options[:redis]
524
517
  redis.zrange('current_entities', 0, -1)
525
518
  end
526
519
 
527
- def self.find_all_with_failing_checks(options)
520
+ def self.find_all_names_with_failing_checks(options)
528
521
  raise "Redis connection not set" unless redis = options[:redis]
529
- Flapjack::Data::EntityCheck.find_current_failing_by_entity(:redis => redis).keys
522
+ Flapjack::Data::EntityCheck.find_current_names_failing_by_entity(:redis => redis).keys
530
523
  end
531
524
 
532
525
  def contacts
@@ -552,6 +545,19 @@ module Flapjack
552
545
  end
553
546
  end
554
547
 
548
+ def self.check_ids_for(entity_ids, options = {})
549
+ raise "Redis connection not set" unless redis = options[:redis]
550
+
551
+ entity_ids.inject({}) do |memo, entity_id|
552
+ entity_name = redis.hget("entity:#{entity_id}", 'name')
553
+ unless entity_name.nil? || entity_name.empty?
554
+ checks = Flapjack::Data::EntityCheck.find_all_names_for_entity_name(entity_name, :redis => redis)
555
+ memo[entity_id] = checks.collect {|check| "#{entity_name}:#{check}" }
556
+ end
557
+ memo
558
+ end
559
+ end
560
+
555
561
  def check_list
556
562
  @redis.zrange("current_checks:#{@name}", 0, -1)
557
563
  end
@@ -562,45 +568,23 @@ module Flapjack
562
568
  checks.length
563
569
  end
564
570
 
565
- def tags
566
- @tags ||= Flapjack::Data::TagSet.new( @redis.keys("#{TAG_PREFIX}:*").inject([]) {|memo, entity_tag|
567
- if Flapjack::Data::Tag.find(entity_tag, :redis => @redis).include?(@id.to_s)
568
- memo << entity_tag.sub(/^#{TAG_PREFIX}:/, '')
569
- end
570
- memo
571
- } )
572
- end
573
-
574
- def add_tags(*enum)
575
- enum.each do |t|
576
- Flapjack::Data::Tag.create("#{TAG_PREFIX}:#{t}", [@id], :redis => @redis)
577
- tags.add(t)
578
- end
579
- end
580
-
581
- def delete_tags(*enum)
582
- enum.each do |t|
583
- tag = Flapjack::Data::Tag.find("#{TAG_PREFIX}:#{t}", :redis => @redis)
584
- tag.delete(@id)
585
- tags.delete(t)
586
- end
587
- end
588
-
589
- def as_json(*args)
590
- {
591
- "id" => self.id,
592
- "name" => self.name,
593
- }
594
- end
571
+ # def as_json(*args)
572
+ # {
573
+ # "id" => self.id,
574
+ # "name" => self.name,
575
+ # }
576
+ # end
595
577
 
596
578
  def to_jsonapi(opts = {})
597
- {
579
+ json_data = {
598
580
  "id" => self.id,
599
581
  "name" => self.name,
600
582
  "links" => {
601
- :contacts => opts[:contact_ids] || [],
583
+ :contacts => opts[:contact_ids] || [],
584
+ :checks => opts[:check_ids] || [],
602
585
  }
603
- }.to_json
586
+ }
587
+ Flapjack.dump_json(json_data)
604
588
  end
605
589
 
606
590
  private