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.
- data/.gitignore +16 -0
- data/Rakefile +72 -32
- data/VERSION +1 -0
- data/bin/flapjack-netsaint-parser +433 -0
- data/bin/flapjack-populator +29 -0
- data/bin/flapjack-stats +10 -5
- data/{etc → dist/etc}/default/flapjack-notifier +0 -0
- data/{etc → dist/etc}/default/flapjack-workers +0 -0
- data/{etc → dist/etc}/flapjack/flapjack-notifier.conf.example +0 -0
- data/{etc → dist/etc}/flapjack/recipients.conf.example +0 -0
- data/{etc → dist/etc}/init.d/flapjack-notifier +0 -0
- data/{etc → dist/etc}/init.d/flapjack-workers +7 -7
- data/dist/puppet/flapjack/files/.stub +0 -0
- data/dist/puppet/flapjack/manifests/common.pp +61 -0
- data/dist/puppet/flapjack/manifests/notifier.pp +13 -0
- data/dist/puppet/flapjack/manifests/worker.pp +13 -0
- data/dist/puppet/flapjack/templates/.stub +0 -0
- data/dist/puppet/ruby/manifests/dev.pp +5 -0
- data/dist/puppet/ruby/manifests/rubygems.pp +14 -0
- data/dist/puppet/sqlite3/manifests/dev.pp +5 -0
- data/features/netsaint-config-converter.feature +126 -0
- data/features/steps/flapjack-importer_steps.rb +112 -0
- data/features/steps/flapjack-netsaint-parser_steps.rb +51 -0
- data/features/steps/flapjack-worker-manager_steps.rb +6 -8
- data/features/support/env.rb +22 -19
- data/flapjack.gemspec +186 -23
- data/lib/flapjack.rb +4 -0
- data/spec/check_sandbox/echo +3 -0
- data/spec/check_sandbox/sandboxed_check +5 -0
- data/spec/configs/flapjack-notifier-couchdb.ini +25 -0
- data/spec/configs/flapjack-notifier.ini +39 -0
- data/spec/configs/recipients.ini +14 -0
- data/spec/helpers.rb +15 -0
- data/spec/inifile_spec.rb +66 -0
- data/spec/mock-notifiers/mock/init.rb +3 -0
- data/spec/mock-notifiers/mock/mock.rb +19 -0
- data/spec/notifier-directories/spoons/testmailer/init.rb +20 -0
- data/spec/notifier_application_spec.rb +222 -0
- data/spec/notifier_filters_spec.rb +52 -0
- data/spec/notifier_options_multiplexer_spec.rb +71 -0
- data/spec/notifier_options_spec.rb +115 -0
- data/spec/notifier_spec.rb +57 -0
- data/spec/notifiers/mailer_spec.rb +36 -0
- data/spec/notifiers/xmpp_spec.rb +36 -0
- data/spec/persistence/datamapper_spec.rb +74 -0
- data/spec/persistence/mock_persistence_backend.rb +26 -0
- data/spec/simple.ini +6 -0
- data/spec/spec.opts +4 -0
- data/spec/test-filters/blocker.rb +13 -0
- data/spec/test-filters/mock.rb +13 -0
- data/spec/transports/beanstalkd_spec.rb +44 -0
- data/spec/transports/mock_transport.rb +58 -0
- data/spec/worker_application_spec.rb +62 -0
- data/spec/worker_options_spec.rb +83 -0
- 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
|
13
|
-
|
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
|
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
|
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
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
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,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,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
|