flapjack 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. data/.gitignore +16 -0
  2. data/Rakefile +72 -32
  3. data/VERSION +1 -0
  4. data/bin/flapjack-netsaint-parser +433 -0
  5. data/bin/flapjack-populator +29 -0
  6. data/bin/flapjack-stats +10 -5
  7. data/{etc → dist/etc}/default/flapjack-notifier +0 -0
  8. data/{etc → dist/etc}/default/flapjack-workers +0 -0
  9. data/{etc → dist/etc}/flapjack/flapjack-notifier.conf.example +0 -0
  10. data/{etc → dist/etc}/flapjack/recipients.conf.example +0 -0
  11. data/{etc → dist/etc}/init.d/flapjack-notifier +0 -0
  12. data/{etc → dist/etc}/init.d/flapjack-workers +7 -7
  13. data/dist/puppet/flapjack/files/.stub +0 -0
  14. data/dist/puppet/flapjack/manifests/common.pp +61 -0
  15. data/dist/puppet/flapjack/manifests/notifier.pp +13 -0
  16. data/dist/puppet/flapjack/manifests/worker.pp +13 -0
  17. data/dist/puppet/flapjack/templates/.stub +0 -0
  18. data/dist/puppet/ruby/manifests/dev.pp +5 -0
  19. data/dist/puppet/ruby/manifests/rubygems.pp +14 -0
  20. data/dist/puppet/sqlite3/manifests/dev.pp +5 -0
  21. data/features/netsaint-config-converter.feature +126 -0
  22. data/features/steps/flapjack-importer_steps.rb +112 -0
  23. data/features/steps/flapjack-netsaint-parser_steps.rb +51 -0
  24. data/features/steps/flapjack-worker-manager_steps.rb +6 -8
  25. data/features/support/env.rb +22 -19
  26. data/flapjack.gemspec +186 -23
  27. data/lib/flapjack.rb +4 -0
  28. data/spec/check_sandbox/echo +3 -0
  29. data/spec/check_sandbox/sandboxed_check +5 -0
  30. data/spec/configs/flapjack-notifier-couchdb.ini +25 -0
  31. data/spec/configs/flapjack-notifier.ini +39 -0
  32. data/spec/configs/recipients.ini +14 -0
  33. data/spec/helpers.rb +15 -0
  34. data/spec/inifile_spec.rb +66 -0
  35. data/spec/mock-notifiers/mock/init.rb +3 -0
  36. data/spec/mock-notifiers/mock/mock.rb +19 -0
  37. data/spec/notifier-directories/spoons/testmailer/init.rb +20 -0
  38. data/spec/notifier_application_spec.rb +222 -0
  39. data/spec/notifier_filters_spec.rb +52 -0
  40. data/spec/notifier_options_multiplexer_spec.rb +71 -0
  41. data/spec/notifier_options_spec.rb +115 -0
  42. data/spec/notifier_spec.rb +57 -0
  43. data/spec/notifiers/mailer_spec.rb +36 -0
  44. data/spec/notifiers/xmpp_spec.rb +36 -0
  45. data/spec/persistence/datamapper_spec.rb +74 -0
  46. data/spec/persistence/mock_persistence_backend.rb +26 -0
  47. data/spec/simple.ini +6 -0
  48. data/spec/spec.opts +4 -0
  49. data/spec/test-filters/blocker.rb +13 -0
  50. data/spec/test-filters/mock.rb +13 -0
  51. data/spec/transports/beanstalkd_spec.rb +44 -0
  52. data/spec/transports/mock_transport.rb +58 -0
  53. data/spec/worker_application_spec.rb +62 -0
  54. data/spec/worker_options_spec.rb +83 -0
  55. metadata +166 -47
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'yajl'
5
+ require 'beanstalk-client'
6
+
7
+ command = ARGV[0]
8
+
9
+ case command
10
+ when "deploy"
11
+ options = ARGV[1..-1]
12
+ options = Hash[options.map {|o| o.scan(/--(.+)=(.+)/).flatten }]
13
+
14
+ @queue = Beanstalk::Connection.new('localhost:11300', 'checks')
15
+
16
+ filename = options["from"]
17
+ file = File.new(filename)
18
+ parser = Yajl::Parser.new
19
+ batch = parser.parse(file)
20
+ batch_id = batch["batch"]["id"]
21
+
22
+ batch["checks"].each do |check|
23
+ job = check.merge({"batch_id" => batch_id})
24
+ @queue.yput(job)
25
+ end
26
+
27
+ puts "Deployed batch #{batch_id}"
28
+ end
29
+
data/bin/flapjack-stats CHANGED
@@ -3,14 +3,19 @@
3
3
  require 'rubygems'
4
4
  require 'beanstalk-client'
5
5
 
6
- begin
6
+ begin
7
7
  beanstalk = Beanstalk::Pool.new(['localhost:11300'])
8
- loop do
8
+ loop do
9
9
  time = Time.now
10
10
  beanstalk.list_tubes['localhost:11300'].each do |tube_name|
11
11
  next if tube_name == 'default'
12
- stats = beanstalk.stats_tube(tube_name)
13
- puts "#{time.to_i} [#{tube_name}] total: #{stats['total-jobs']}, waiting: #{stats['current-waiting']}, ready: #{stats['current-jobs-ready']}"
12
+ stats = beanstalk.stats_tube(tube_name)
13
+ message = []
14
+ message << "#{time} [#{tube_name}]"
15
+ message << "total: #{stats['total-jobs']}"
16
+ message << "waiting: #{stats['current-waiting']}"
17
+ message << "ready: #{stats['current-jobs-ready']}"
18
+ puts message.join(', ')
14
19
  end
15
20
  sleep 1
16
21
  end
@@ -18,5 +23,5 @@ rescue Beanstalk::NotConnected
18
23
  puts "beanstalk isn't up!"
19
24
  exit 2
20
25
  end
21
-
26
+
22
27
 
File without changes
File without changes
File without changes
File without changes
@@ -1,12 +1,12 @@
1
1
  #!/bin/bash
2
2
  #
3
- # Copyright (c) 2009 Lindsay Holmwood <lindsay@holmwood.id.au>
3
+ # Copyright (c) 2009-2011 Lindsay Holmwood <lindsay@holmwood.id.au>
4
4
  #
5
5
  # flapjack-workers
6
- # Boots flapjack-workers, check executors for Flapjack.
6
+ # Boots flapjack-workers, check executors for Flapjack.
7
7
  #
8
8
 
9
- PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local:/usr/local/sbin:/usr/local/bin
9
+ PATH=$PATH:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local:/usr/local/sbin:/usr/local/bin
10
10
 
11
11
  if [ -f /etc/default/flapjack-workers ]; then
12
12
  . /etc/default/flapjack-workers
@@ -16,9 +16,9 @@ fi
16
16
  RETVAL=0
17
17
 
18
18
  if [ ! $(which flapjack-worker-manager) ]; then
19
- echo "flapjack-worker-manager isn't on your path."
20
- echo "Refusing to start."
21
- exit 1
19
+ echo "flapjack-worker-manager isn't on your path."
20
+ echo "Refusing to start."
21
+ exit 1
22
22
  fi
23
23
 
24
24
  # Evaluate command
@@ -37,7 +37,7 @@ case "$1" in
37
37
  ;;
38
38
  *)
39
39
  echo "Usage: flapjack-workers {start|stop|restart}"
40
- exit 1
40
+ RETVAL=1
41
41
  ;;
42
42
  esac
43
43
 
File without changes
@@ -0,0 +1,61 @@
1
+ class flapjack::common {
2
+
3
+ include ruby::rubygems
4
+ include sqlite3::dev
5
+
6
+ $version = "0.5.3"
7
+
8
+ package { "flapjack":
9
+ ensure => $version,
10
+ provider => gem,
11
+ require => [ Package["rubygems"],
12
+ Package["libsqlite3-dev"] ],
13
+ }
14
+
15
+ file { "/var/run/flapjack":
16
+ ensure => directory,
17
+ mode => 777,
18
+ require => [ Package["flapjack"] ],
19
+ }
20
+
21
+ file { "/etc/flapjack":
22
+ ensure => directory,
23
+ require => [ Package["flapjack"] ],
24
+ }
25
+
26
+ exec { "symlink-latest-flapjack-gem":
27
+ command => "ln -sf $(dirname $(dirname $(dirname $(gem which flapjack/patches)))) /usr/lib/flapjack",
28
+ path => "/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin",
29
+ unless => "readlink /usr/lib/flapjack |grep -E '$version$'",
30
+ require => [ Package["flapjack"] ]
31
+ }
32
+
33
+ exec { "populate-etc-flapjack":
34
+ command => "cp $(dirname $(dirname $(dirname $(gem which flapjack))))/dist/etc/flapjack/* /etc/flapjack",
35
+ creates => [ "/etc/flapjack/flapjack-notifier.conf.example", "/etc/flapjack/recipients.conf.example" ],
36
+ path => "/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin",
37
+ require => [ File["/etc/flapjack"],
38
+ Package["flapjack"] ],
39
+ }
40
+
41
+ file { "/etc/default/flapjack-workers":
42
+ source => "/usr/lib/flapjack/dist/etc/default/flapjack-workers",
43
+ require => [ Exec["symlink-latest-flapjack-gem"] ],
44
+ }
45
+
46
+ file { "/etc/default/flapjack-notifier":
47
+ source => "/usr/lib/flapjack/dist/etc/default/flapjack-notifier",
48
+ require => [ Exec["symlink-latest-flapjack-gem"] ],
49
+ }
50
+
51
+ file { "/etc/init.d/flapjack-workers":
52
+ source => "/usr/lib/flapjack/dist/etc/init.d/flapjack-workers",
53
+ require => [ Exec["symlink-latest-flapjack-gem"] ],
54
+ }
55
+
56
+ file { "/etc/init.d/flapjack-notifier":
57
+ source => "/usr/lib/flapjack/dist/etc/init.d/flapjack-notifier",
58
+ require => [ Exec["symlink-latest-flapjack-gem"] ],
59
+ }
60
+
61
+ }
@@ -0,0 +1,13 @@
1
+ class flapjack::notifier {
2
+ include flapjack::common
3
+
4
+ service { "flapjack-notifier":
5
+ enable => true,
6
+ ensure => running,
7
+ require => [ Package["flapjack"],
8
+ Exec["populate-etc-flapjack"],
9
+ File["/etc/default/flapjack-notifier"],
10
+ File["/etc/init.d/flapjack-notifier"] ],
11
+ }
12
+
13
+ }
@@ -0,0 +1,13 @@
1
+ class flapjack::worker {
2
+ include flapjack::common
3
+
4
+ service { "flapjack-workers":
5
+ enable => true,
6
+ ensure => running,
7
+ require => [ Package["flapjack"],
8
+ Exec["populate-etc-flapjack"],
9
+ File["/etc/default/flapjack-workers"],
10
+ File["/etc/init.d/flapjack-workers"] ],
11
+ }
12
+
13
+ }
File without changes
@@ -0,0 +1,5 @@
1
+ class ruby::dev {
2
+ package { "ruby-dev":
3
+ ensure => present,
4
+ }
5
+ }
@@ -0,0 +1,14 @@
1
+ class ruby::rubygems {
2
+ package { "rubygems":
3
+ ensure => present,
4
+ tag => "puppet"
5
+ }
6
+
7
+ exec { "export-rubygems-path":
8
+ command => "echo 'export PATH=\$PATH:/var/lib/gems/1.8/bin' >> /etc/bash.bashrc",
9
+ path => "/bin:/usr/bin",
10
+ unless => "grep -c '/var/lib/gems/1.8/bin' /etc/bash.bashrc",
11
+ require => [ Package["rubygems"] ],
12
+ tag => "puppet"
13
+ }
14
+ }
@@ -0,0 +1,5 @@
1
+ class sqlite3::dev {
2
+ package { "libsqlite3-dev":
3
+ ensure => present
4
+ }
5
+ }
@@ -0,0 +1,126 @@
1
+ Feature: Netsaint -> Flapjack configuration converter
2
+ To assist the migration to Flapjack
3
+ An operator needs to migrate
4
+ A functioning netsaint or nagios configuration
5
+ Into Flapjack's native configuration system
6
+
7
+ @parse
8
+ Scenario: Parse + print netsaint services
9
+ Given NetSaint configuration is at "features/support/data/etc/netsaint"
10
+ When I run "flapjack-netsaint-parser" with the following arguments:
11
+ | argument |
12
+ | print |
13
+ | services |
14
+ | --source=features/support/data/etc/netsaint |
15
+ Then I should see a valid JSON output
16
+ And I should see a list of services
17
+ And I should see the following attributes for every service:
18
+ | attribute |
19
+ | check_command |
20
+ | description |
21
+
22
+ @parse
23
+ Scenario: Parse + print netsaint timeperiods
24
+ Given NetSaint configuration is at "features/support/data/etc/netsaint"
25
+ When I run "flapjack-netsaint-parser" with the following arguments:
26
+ | argument |
27
+ | print |
28
+ | timeperiods |
29
+ | --source=features/support/data/etc/netsaint |
30
+ Then I should see a valid JSON output
31
+ And I should see a list of timeperiods
32
+ And I should see the following attributes for every timeperiod:
33
+ | attribute | nillable? |
34
+ | timeperiod_alias | true |
35
+
36
+ @parse
37
+ Scenario: Parse + print netsaint contacts
38
+ Given NetSaint configuration is at "features/support/data/etc/netsaint"
39
+ When I run "flapjack-netsaint-parser" with the following arguments:
40
+ | argument |
41
+ | print |
42
+ | contacts |
43
+ | --source=features/support/data/etc/netsaint |
44
+ Then I should see a valid JSON output
45
+ And I should see a list of contacts
46
+ And I should see the following attributes for every contact:
47
+ | attribute |
48
+ | contact_alias |
49
+ | email_address |
50
+ | host_notification_period |
51
+ | host_notify_commands |
52
+ | notify_host_down |
53
+ | notify_host_unreachable |
54
+ | notify_service_warning |
55
+ | notify_service_recovery |
56
+ | notify_service_critical |
57
+ | notify_host_recovery |
58
+ | service_notify_commands |
59
+ | svc_notification_period |
60
+ And I should see the following attributes for every contact:
61
+ | attribute | nillable? |
62
+ | pager | true |
63
+
64
+ @parse
65
+ Scenario: Parse + print netsaint contactgroups
66
+ Given NetSaint configuration is at "features/support/data/etc/netsaint"
67
+ When I run "flapjack-netsaint-parser" with the following arguments:
68
+ | argument |
69
+ | print |
70
+ | contactgroups |
71
+ | --source=features/support/data/etc/netsaint |
72
+ Then I should see a valid JSON output
73
+ And I should see a list of contactgroups
74
+ And I should see the following attributes for every contactgroup:
75
+ | attribute |
76
+ | contacts |
77
+ | group_alias |
78
+
79
+ @parse
80
+ Scenario: Parse + print netsaint hosts
81
+ Given NetSaint configuration is at "features/support/data/etc/netsaint"
82
+ When I run "flapjack-netsaint-parser" with the following arguments:
83
+ | argument |
84
+ | print |
85
+ | hosts |
86
+ | --source=features/support/data/etc/netsaint |
87
+ Then I should see a valid JSON output
88
+ And I should see a list of hosts
89
+ And I should see the following attributes for every host:
90
+ | attribute |
91
+ | host_alias |
92
+ | address |
93
+ | parent_hosts |
94
+ | host_check_command |
95
+ | max_attempts |
96
+ | notification_interval |
97
+ | notification_period |
98
+ | notify_recovery |
99
+ | notify_down |
100
+ | notify_unreachable |
101
+ And I should see the following attributes for every host:
102
+ | attribute | nillable? |
103
+ | event_handler | true |
104
+
105
+ @import
106
+ Scenario: Import Netsaint config
107
+ Given NetSaint configuration is at "features/support/data/etc/netsaint"
108
+ And no file exists at "features/support/tmp/dump.json"
109
+ And beanstalkd is running
110
+ And there are no jobs on the "checks" beanstalkd queue
111
+ When I run "flapjack-netsaint-parser" with the following arguments:
112
+ | argument |
113
+ | dump |
114
+ | --source=features/support/data/etc/netsaint |
115
+ | --format=json |
116
+ | --to=features/support/tmp/dump.json |
117
+ Then I should see "features/support/tmp/dump.json" in the output
118
+ Then I should see valid JSON in "features/support/tmp/dump.json"
119
+ Then I should see a valid JSON batch in "features/support/tmp/dump.json"
120
+ When I run "flapjack-populator" with the following arguments:
121
+ | argument |
122
+ | deploy |
123
+ | --from=features/support/tmp/dump.json |
124
+ Then I should see "Deployed batch \d+" in the output
125
+ Then there should be several jobs on the "checks" beanstalkd queue
126
+
@@ -0,0 +1,112 @@
1
+ When /^I run "([^"]*)" with the following arguments:$/ do |script, table|
2
+ @arguments = []
3
+ table.hashes.each do |attrs|
4
+ @arguments << attrs["argument"]
5
+ end
6
+
7
+ command = "bin/#{script} #{@arguments.join(' ')}"
8
+
9
+ @output = `#{command}`
10
+ $?.exitstatus.should == 0
11
+ end
12
+
13
+ Then /^I should see a batch of checks in the output$/ do
14
+ @data["batches"].should_not be_nil
15
+ @data["batches"].size.should > 0
16
+
17
+ @data["batches"].each do |batch|
18
+ batch["checks"].should_not be_nil
19
+ batch["checks"].size.should > 0
20
+
21
+ batch["checks"].each do |check|
22
+ check["id"].should_not be_nil
23
+ check["command"].should_not be_nil
24
+ end
25
+ end
26
+ end
27
+
28
+ Then /^I should see a batch of checks with relationships in the output$/ do
29
+ @data["batches"].should_not be_nil
30
+ @data["batches"].size.should > 0
31
+
32
+ @data["batches"].each do |batch|
33
+ batch["checks"].should_not be_nil
34
+ batch["checks"].size.should > 0
35
+
36
+ batch["checks"].each do |check|
37
+ check.key?("parent_id").should be_true
38
+ check.key?("child_id").should be_true
39
+ end
40
+ end
41
+ end
42
+
43
+ Given /^no file exists at "([^"]*)"$/ do |filename|
44
+ FileUtils.rm_f(filename).should be_true
45
+ end
46
+
47
+ Then /^I should see valid JSON in "([^"]*)"$/ do |filename|
48
+ lambda {
49
+ file = File.new(filename, 'r')
50
+ parser = Yajl::Parser.new
51
+ @data = parser.parse(file)
52
+ }.should_not raise_error
53
+ end
54
+
55
+ Given /^I run the importer$/ do
56
+ pending # express the regexp above with the code you wish you had
57
+ end
58
+
59
+ Given /^the necessary checks and relationships are created$/ do
60
+ pending # express the regexp above with the code you wish you had
61
+ end
62
+
63
+ Then /^the latest batch of checks should be in the work queue$/ do
64
+ pending # express the regexp above with the code you wish you had
65
+ end
66
+
67
+ Then /^I should see "([^"]*)" in the output$/ do |regex|
68
+ @output.should =~ /#{regex}/i
69
+ end
70
+
71
+ Given /^beanstalkd is running$/ do
72
+ system("which beanstalkd > /dev/null 2>&1").should be_true
73
+
74
+ @pipe = IO.popen("beanstalkd")
75
+
76
+ # So beanstalkd has a moment to catch its breath.
77
+ sleep 0.5
78
+
79
+ at_exit do
80
+ Process.kill("KILL", @pipe.pid)
81
+ end
82
+ end
83
+
84
+ Given /^there are no jobs on the "([^"]*)" beanstalkd queue$/ do |queue_name|
85
+ @queue = Beanstalk::Connection.new('localhost:11300', queue_name)
86
+ 100.times { @queue.put('foo') }
87
+ until @queue.stats["current-jobs-ready"] == 0
88
+ job = @queue.reserve
89
+ job.delete
90
+ end
91
+ end
92
+
93
+ Then /^there should be several jobs on the "([^"]*)" beanstalkd queue$/ do |queue_name|
94
+ @queue = Beanstalk::Connection.new('localhost:11300', queue_name)
95
+ @queue.stats["current-jobs-ready"].should > 0
96
+ end
97
+
98
+
99
+ Then /^I should see a valid JSON batch in "([^"]*)"$/ do |filename|
100
+ lambda {
101
+ file = File.new(filename, 'r')
102
+ parser = Yajl::Parser.new
103
+ @data = parser.parse(file)
104
+ }.should_not raise_error
105
+
106
+ @data["checks"].size.should > 0
107
+ @data["checks"].each do |check|
108
+ %w(id command interval).each do |attr|
109
+ check[attr].should_not be_nil
110
+ end
111
+ end
112
+ end