flapjack 0.5.1 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
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