flapjack 0.5.5 → 0.6.23
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 +10 -0
- data/.rbenv-version +1 -0
- data/.rspec +10 -0
- data/Gemfile +18 -0
- data/Guardfile +14 -0
- data/README.md +152 -173
- data/Rakefile +53 -150
- data/bin/flapjack +72 -0
- data/bin/flapjack-nagios-receiver +111 -0
- data/bin/flapjack-nagios-receiver-control +15 -0
- data/bin/flapjack-netsaint-parser +0 -2
- data/bin/flapjack-populator +133 -16
- data/bin/install-flapjack-systemwide +2 -2
- data/config.ru +11 -0
- data/dist/etc/init.d/flapjack +46 -0
- data/dist/etc/init.d/flapjack-nagios-receiver +36 -0
- data/doc/GLOSSARY.md +19 -0
- data/etc/flapjack_config.yaml.example +90 -0
- data/features/events.feature +132 -0
- data/features/notifications.feature +57 -0
- data/features/packaging-lintian.feature +5 -3
- data/features/steps/events_steps.rb +164 -0
- data/features/steps/flapjack-importer_steps.rb +2 -5
- data/features/steps/flapjack-worker_steps.rb +13 -6
- data/features/steps/notifications_steps.rb +178 -0
- data/features/steps/packaging-lintian_steps.rb +14 -0
- data/features/steps/time_travel_steps.rb +34 -0
- data/features/support/env.rb +63 -36
- data/flapjack.gemspec +35 -186
- data/lib/flapjack.rb +2 -0
- data/lib/flapjack/api.rb +274 -0
- data/lib/flapjack/api/entity_check_presenter.rb +184 -0
- data/lib/flapjack/api/entity_presenter.rb +66 -0
- data/lib/flapjack/cli/worker_manager.rb +1 -2
- data/lib/flapjack/configuration.rb +11 -0
- data/lib/flapjack/coordinator.rb +288 -0
- data/lib/flapjack/daemonizing.rb +186 -0
- data/lib/flapjack/data/contact.rb +45 -0
- data/lib/flapjack/data/entity.rb +89 -0
- data/lib/flapjack/data/entity_check.rb +396 -0
- data/lib/flapjack/data/event.rb +144 -0
- data/lib/flapjack/data/notification.rb +13 -0
- data/lib/flapjack/executive.rb +289 -0
- data/lib/flapjack/filters/acknowledgement.rb +39 -0
- data/lib/flapjack/filters/{any_parents_failed.rb → base.rb} +6 -4
- data/lib/flapjack/filters/delays.rb +53 -0
- data/lib/flapjack/filters/detect_mass_client_failures.rb +44 -0
- data/lib/flapjack/filters/ok.rb +25 -5
- data/lib/flapjack/filters/scheduled_maintenance.rb +17 -0
- data/lib/flapjack/filters/unscheduled_maintenance.rb +17 -0
- data/lib/flapjack/jabber.rb +294 -0
- data/lib/flapjack/notification/common.rb +23 -0
- data/lib/flapjack/notification/email.rb +107 -0
- data/lib/flapjack/notification/email/alert.html.haml +48 -0
- data/lib/flapjack/notification/email/alert.text.erb +14 -0
- data/lib/flapjack/notification/sms.rb +42 -0
- data/lib/flapjack/notification/sms/messagenet.rb +49 -0
- data/lib/flapjack/notifier_engine.rb +4 -4
- data/lib/flapjack/notifiers/mailer/mailer.rb +6 -7
- data/lib/flapjack/notifiers/xmpp/xmpp.rb +12 -12
- data/lib/flapjack/pagerduty.rb +230 -0
- data/lib/flapjack/patches.rb +108 -19
- data/lib/flapjack/persistence/data_mapper/models/check.rb +5 -3
- data/lib/flapjack/persistence/data_mapper/models/check_template.rb +2 -0
- data/lib/flapjack/persistence/data_mapper/models/event.rb +2 -0
- data/lib/flapjack/persistence/data_mapper/models/node.rb +3 -1
- data/lib/flapjack/persistence/data_mapper/models/related_check.rb +3 -1
- data/lib/flapjack/pikelet.rb +56 -0
- data/lib/flapjack/transports/beanstalkd.rb +1 -1
- data/lib/flapjack/transports/result.rb +6 -6
- data/lib/flapjack/utility.rb +46 -0
- data/lib/flapjack/version.rb +5 -0
- data/lib/flapjack/web.rb +198 -0
- data/lib/flapjack/web/views/acknowledge.haml +55 -0
- data/lib/flapjack/web/views/check.haml +162 -0
- data/lib/flapjack/web/views/index.haml +92 -0
- data/lib/flapjack/web/views/self_stats.haml +56 -0
- data/lib/flapjack/{applications/worker.rb → worker/application.rb} +0 -0
- data/lib/flapjack/worker/cli.rb +49 -0
- data/{spec → spec.old}/check_sandbox/echo +0 -0
- data/{spec → spec.old}/check_sandbox/sandboxed_check +0 -0
- data/{spec → spec.old}/configs/flapjack-notifier-couchdb.ini +0 -0
- data/{spec → spec.old}/configs/flapjack-notifier.ini +0 -0
- data/{spec → spec.old}/configs/recipients.ini +0 -0
- data/{spec → spec.old}/helpers.rb +0 -0
- data/{spec → spec.old}/inifile_spec.rb +0 -0
- data/{spec → spec.old}/mock-notifiers/mock/init.rb +0 -0
- data/{spec → spec.old}/mock-notifiers/mock/mock.rb +0 -0
- data/{spec → spec.old}/notifier-directories/spoons/testmailer/init.rb +0 -0
- data/{spec → spec.old}/notifier_application_spec.rb +0 -0
- data/{spec → spec.old}/notifier_filters_spec.rb +0 -0
- data/{spec → spec.old}/notifier_options_multiplexer_spec.rb +0 -0
- data/{spec → spec.old}/notifier_options_spec.rb +0 -0
- data/{spec → spec.old}/notifier_spec.rb +0 -0
- data/{spec → spec.old}/notifiers/mailer_spec.rb +0 -0
- data/{spec → spec.old}/notifiers/xmpp_spec.rb +0 -0
- data/{spec → spec.old}/persistence/datamapper_spec.rb +0 -0
- data/{spec → spec.old}/persistence/mock_persistence_backend.rb +0 -0
- data/{spec → spec.old}/simple.ini +0 -0
- data/{spec → spec.old}/spec.opts +0 -0
- data/{spec → spec.old}/test-filters/blocker.rb +0 -0
- data/{spec → spec.old}/test-filters/mock.rb +0 -0
- data/{spec → spec.old}/transports/beanstalkd_spec.rb +0 -0
- data/{spec → spec.old}/transports/mock_transport.rb +0 -0
- data/{spec → spec.old}/worker_application_spec.rb +0 -0
- data/{spec → spec.old}/worker_options_spec.rb +0 -0
- data/spec/lib/flapjack/api/entity_check_presenter_spec.rb +117 -0
- data/spec/lib/flapjack/api/entity_presenter_spec.rb +92 -0
- data/spec/lib/flapjack/api_spec.rb +170 -0
- data/spec/lib/flapjack/coordinator_spec.rb +16 -0
- data/spec/lib/flapjack/data/entity_check_spec.rb +398 -0
- data/spec/lib/flapjack/data/entity_spec.rb +71 -0
- data/spec/lib/flapjack/data/event_spec.rb +6 -0
- data/spec/lib/flapjack/executive_spec.rb +59 -0
- data/spec/lib/flapjack/filters/acknowledgement_spec.rb +6 -0
- data/spec/lib/flapjack/filters/delays_spec.rb +6 -0
- data/spec/lib/flapjack/filters/detect_mass_client_failures_spec.rb +6 -0
- data/spec/lib/flapjack/filters/ok_spec.rb +6 -0
- data/spec/lib/flapjack/filters/scheduled_maintenance_spec.rb +6 -0
- data/spec/lib/flapjack/filters/unscheduled_maintenance_spec.rb +6 -0
- data/spec/lib/flapjack/jabber_spec.rb +150 -0
- data/spec/lib/flapjack/notification/email_spec.rb +6 -0
- data/spec/lib/flapjack/notification/sms_spec.rb +6 -0
- data/spec/lib/flapjack/pikelet_spec.rb +28 -0
- data/spec/lib/flapjack/web_spec.rb +188 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/support/profile_all_formatter.rb +44 -0
- data/spec/support/uncolored_doc_formatter.rb +9 -0
- data/tasks/events.rake +85 -0
- data/tmp/acknowledge.rb +14 -0
- data/tmp/create_config_yaml.rb +16 -0
- data/tmp/create_events_failure.rb +33 -0
- data/tmp/create_events_ok.rb +33 -0
- data/tmp/create_events_ok_fail_ack_ok.rb +54 -0
- data/tmp/create_events_ok_failure.rb +40 -0
- data/tmp/create_events_ok_failure_ack.rb +54 -0
- data/tmp/dummy_entities.json +1 -0
- data/tmp/generate_nagios_test_hosts.rb +16 -0
- data/tmp/parse_config_yaml.rb +7 -0
- data/tmp/redis_delete_all_keys.rb +11 -0
- data/tmp/test_entities.json +1 -0
- metadata +482 -221
- data/TODO.md +0 -36
- data/VERSION +0 -1
- data/bin/flapjack-benchmark +0 -50
- data/bin/flapjack-notifier +0 -21
- data/bin/flapjack-notifier-manager +0 -43
- data/bin/flapjack-stats +0 -27
- data/bin/flapjack-worker +0 -13
- data/bin/flapjack-worker-manager +0 -35
- data/dist/etc/init.d/flapjack-notifier +0 -47
- data/dist/etc/init.d/flapjack-workers +0 -44
- data/features/flapjack-notifier-manager.feature +0 -19
- data/features/flapjack-worker-manager.feature +0 -27
- data/features/flapjack-worker.feature +0 -27
- data/features/netsaint-config-converter.feature +0 -126
- data/features/persistence/couch.feature +0 -105
- data/features/persistence/sqlite3.feature +0 -105
- data/features/persistence/steps/couch_steps.rb +0 -25
- data/features/persistence/steps/generic_steps.rb +0 -102
- data/features/persistence/steps/sqlite3_steps.rb +0 -13
- data/features/steps/flapjack-notifier-manager_steps.rb +0 -24
- data/features/steps/flapjack-worker-manager_steps.rb +0 -48
- data/lib/flapjack/applications/notifier.rb +0 -222
- data/lib/flapjack/cli/notifier.rb +0 -108
- data/lib/flapjack/cli/notifier_manager.rb +0 -86
- data/lib/flapjack/cli/worker.rb +0 -51
data/Rakefile
CHANGED
|
@@ -1,176 +1,79 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
unless $:.include?(File.dirname(__FILE__) + '/lib/')
|
|
4
|
+
$: << File.dirname(__FILE__) + '/lib'
|
|
5
|
+
end
|
|
6
|
+
|
|
4
7
|
require 'fileutils'
|
|
5
|
-
require 'spec/rake/spectask'
|
|
6
8
|
require 'rake'
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
# Release management
|
|
10
|
-
#
|
|
11
|
-
begin
|
|
12
|
-
require 'jeweler'
|
|
13
|
-
Jeweler::Tasks.new do |gem|
|
|
14
|
-
gem.name = "flapjack"
|
|
15
|
-
gem.summary = %Q{a scalable and distributed monitoring system}
|
|
16
|
-
gem.description = %Q{lapjack is highly scalable and distributed monitoring system. It understands the Nagios plugin format, and can easily be scaled from 1 server to 1000.}
|
|
17
|
-
gem.email = "lindsay@holmwood.id.au"
|
|
18
|
-
gem.homepage = "http://flapjack-project.com/"
|
|
19
|
-
gem.authors = ["Lindsay Holmwood"]
|
|
20
|
-
gem.has_rdoc = false
|
|
21
|
-
|
|
22
|
-
gem.add_dependency('daemons', '= 1.0.10')
|
|
23
|
-
gem.add_dependency('beanstalk-client', '= 1.0.2')
|
|
24
|
-
gem.add_dependency('log4r', '= 1.1.5')
|
|
25
|
-
gem.add_dependency('xmpp4r', '= 0.5')
|
|
26
|
-
gem.add_dependency('tmail', '= 1.2.3.1')
|
|
27
|
-
gem.add_dependency('yajl-ruby', '= 0.6.4')
|
|
28
|
-
gem.add_dependency('sqlite3-ruby', '= 1.2.5')
|
|
29
|
-
|
|
30
|
-
# Don't release unsanitised NetSaint config into gem.
|
|
31
|
-
gem.files.exclude('features/support/data/etc/netsaint')
|
|
32
|
-
end
|
|
33
|
-
Jeweler::GemcutterTasks.new
|
|
34
|
-
rescue LoadError
|
|
35
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
|
36
|
-
end
|
|
10
|
+
require 'resque/tasks'
|
|
37
11
|
|
|
38
|
-
|
|
39
|
-
# Testing
|
|
40
|
-
#
|
|
41
|
-
require 'rake/testtask'
|
|
42
|
-
Rake::TestTask.new(:test) do |test|
|
|
43
|
-
test.libs << 'lib' << 'test'
|
|
44
|
-
test.pattern = 'test/**/test_*.rb'
|
|
45
|
-
test.verbose = true
|
|
46
|
-
end
|
|
12
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
|
47
13
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
test.verbose = true
|
|
54
|
-
end
|
|
55
|
-
rescue LoadError
|
|
56
|
-
task :rcov do
|
|
57
|
-
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
|
58
|
-
end
|
|
14
|
+
require 'cucumber'
|
|
15
|
+
require 'cucumber/rake/task'
|
|
16
|
+
require 'colorize'
|
|
17
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
|
18
|
+
t.cucumber_opts = "features --format pretty"
|
|
59
19
|
end
|
|
60
20
|
|
|
61
|
-
|
|
62
|
-
|
|
21
|
+
require 'rspec/core/rake_task'
|
|
22
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
63
23
|
|
|
64
|
-
|
|
65
|
-
task.cucumber_opts = "--require features/"
|
|
66
|
-
end
|
|
67
|
-
rescue LoadError
|
|
68
|
-
end
|
|
24
|
+
task :default => :spec
|
|
69
25
|
|
|
70
|
-
Spec::Rake::SpecTask.new do |t|
|
|
71
|
-
t.spec_opts = ["--options", "spec/spec.opts"]
|
|
72
|
-
end
|
|
73
|
-
task :test => :check_dependencies
|
|
74
26
|
|
|
75
|
-
|
|
27
|
+
desc "build gem"
|
|
28
|
+
task :build => :verify do
|
|
29
|
+
build_output = `gem build flapjack.gemspec`
|
|
30
|
+
puts build_output
|
|
76
31
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
32
|
+
gem_filename = build_output[/File: (.*)/,1]
|
|
33
|
+
pkg_path = "pkg"
|
|
34
|
+
FileUtils.mkdir_p(pkg_path)
|
|
35
|
+
FileUtils.mv(gem_filename, pkg_path)
|
|
80
36
|
|
|
81
|
-
|
|
82
|
-
rdoc.title = "flapjack #{version}"
|
|
83
|
-
rdoc.rdoc_files.include('README*')
|
|
84
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
37
|
+
puts "Gem built in #{pkg_path}/#{gem_filename}".green
|
|
85
38
|
end
|
|
86
39
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
output = `grep -nR FIXME lib/* spec/* bin/`
|
|
93
|
-
output.split("\n").each do |line|
|
|
94
|
-
parts = line.split(':')
|
|
95
|
-
puts "#{parts[0].strip} +#{parts[1].strip}"
|
|
96
|
-
puts " - #{parts[3].strip}"
|
|
40
|
+
desc "push gem"
|
|
41
|
+
task :push do
|
|
42
|
+
filenames = Dir.glob("pkg/*.gem")
|
|
43
|
+
filenames_with_times = filenames.map do |filename|
|
|
44
|
+
[filename, File.mtime(filename)]
|
|
97
45
|
end
|
|
46
|
+
|
|
47
|
+
newest = filenames_with_times.sort_by { |tuple| tuple.last }.last
|
|
48
|
+
newest_filename = newest.first
|
|
49
|
+
|
|
50
|
+
command = "gem push #{newest_filename}"
|
|
51
|
+
system(command)
|
|
98
52
|
end
|
|
99
53
|
|
|
100
|
-
desc "
|
|
101
|
-
task :
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
current_commit = `git log`.first.split[1][0..5]
|
|
107
|
-
release_tarball = "/tmp/flapjack-#{current_commit}.tar.gz"
|
|
108
|
-
flapjack_path = File.join(tmpdir, "flapjack-#{current_commit}")
|
|
109
|
-
repo_path = File.expand_path(File.dirname(__FILE__))
|
|
110
|
-
ignores = %w(.gitignore .git)
|
|
111
|
-
|
|
112
|
-
# create new staging directory
|
|
113
|
-
command = "git clone #{repo_path} #{flapjack_path}"
|
|
114
|
-
`#{command}`
|
|
115
|
-
|
|
116
|
-
# remove files we don't want to publish
|
|
117
|
-
ignores.each do |filename|
|
|
118
|
-
path = File.join(flapjack_path, filename)
|
|
119
|
-
FileUtils.rm_rf(path)
|
|
54
|
+
desc "clean up various generated files"
|
|
55
|
+
task :clean do
|
|
56
|
+
[ "pkg/"].each do |filename|
|
|
57
|
+
puts "Removing #{filename}"
|
|
58
|
+
FileUtils.rm_rf(filename)
|
|
120
59
|
end
|
|
60
|
+
end
|
|
121
61
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
:source => "http://github.com/brianmario/yajl-ruby/tarball/0.6.4",
|
|
132
|
-
:filename => "yajl-ruby-0.6.4.tar.gz"
|
|
133
|
-
},
|
|
134
|
-
:tmail => {
|
|
135
|
-
:source => "http://rubyforge.org/frs/download.php/35297/tmail-1.2.3.1.tgz",
|
|
136
|
-
:filename => "tmail-1.2.3.1.tar.gz"
|
|
137
|
-
},
|
|
138
|
-
:xmpp4r => {
|
|
139
|
-
:source => "http://download.gna.org/xmpp4r/xmpp4r-0.4.tgz",
|
|
140
|
-
:filename => "xmpp4r-0.4.tar.gz"
|
|
141
|
-
},
|
|
142
|
-
:log4r => {
|
|
143
|
-
:source => "http://qa.debian.org/watch/sf.php/log4r/log4r-1.0.5.tgz",
|
|
144
|
-
:filename => "log4r-1.0.5.tar.gz"
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
deps.each_pair do |name, details|
|
|
148
|
-
puts "Pulling in #{name} dependency..."
|
|
149
|
-
# save file
|
|
150
|
-
saved_file = "/tmp/#{details[:filename]}"
|
|
151
|
-
File.open(saved_file, 'w') do |f|
|
|
152
|
-
f << open(details[:source]).read
|
|
62
|
+
namespace :verify do
|
|
63
|
+
task :uncommitted do
|
|
64
|
+
uncommitted = `git ls-files -m`.split("\n")
|
|
65
|
+
if uncommitted.size > 0
|
|
66
|
+
puts "The following files are uncommitted:".red
|
|
67
|
+
uncommitted.each do |filename|
|
|
68
|
+
puts " - #{filename}".red
|
|
69
|
+
end
|
|
70
|
+
exit 1
|
|
153
71
|
end
|
|
154
|
-
|
|
155
|
-
`tar zxf #{saved_file} -C #{tmpdir}`
|
|
156
72
|
end
|
|
157
73
|
|
|
158
|
-
|
|
159
|
-
under = File.dirname(tmpdir)
|
|
160
|
-
staging = File.join("/tmp", "flapjack-#{current_commit}")
|
|
161
|
-
FileUtils.mv(tmpdir, staging)
|
|
162
|
-
actual = File.basename(staging)
|
|
163
|
-
command = "cd #{under} ; tar czf #{release_tarball} #{actual}"
|
|
164
|
-
system(command)
|
|
165
|
-
|
|
166
|
-
puts "Release tarball with deps at #{release_tarball}"
|
|
74
|
+
task :all => [ :uncommitted ]
|
|
167
75
|
end
|
|
168
76
|
|
|
169
|
-
|
|
170
|
-
task :
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
DataMapper.logger.set_log(STDOUT, :debug)
|
|
174
|
-
DataMapper.setup(:default, "sqlite3:///tmp/sqlite3.db")
|
|
175
|
-
DataMapper.auto_migrate!
|
|
176
|
-
end
|
|
77
|
+
# FIXME: getting that intermittent gherken lexing error so removing :features from verify list
|
|
78
|
+
#task :verify => [ 'verify:all', :spec, :features]
|
|
79
|
+
task :verify => [ 'verify:all', :spec]
|
data/bin/flapjack
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'yaml'
|
|
4
|
+
require 'optparse'
|
|
5
|
+
require 'ostruct'
|
|
6
|
+
|
|
7
|
+
options = OpenStruct.new
|
|
8
|
+
options.config = File.join('etc', 'flapjack_config.yaml')
|
|
9
|
+
options.daemonize = nil
|
|
10
|
+
|
|
11
|
+
OptionParser.new do |opts|
|
|
12
|
+
opts.banner = "Usage: flapjack [options]"
|
|
13
|
+
|
|
14
|
+
opts.on("-c", "--config [PATH]", String, "PATH to the config file to use") do |c|
|
|
15
|
+
options.config = c
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
opts.on("-d", "--[no-]daemonize", "Daemonize?") do |d|
|
|
19
|
+
options.daemonize = d
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
opts.on("-p", "--pidfile [PATH]", String, "PATH to the pidfile to write to") do |p|
|
|
23
|
+
options.pidfile = p
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end.parse!(ARGV)
|
|
27
|
+
|
|
28
|
+
FLAPJACK_ENV = ENV['FLAPJACK_ENV'] || 'development'
|
|
29
|
+
|
|
30
|
+
# load the config hash for the current environment
|
|
31
|
+
|
|
32
|
+
if File.file?(options.config)
|
|
33
|
+
config = YAML::load_file(options.config)
|
|
34
|
+
else
|
|
35
|
+
puts "Could not find config file at '#{options.config}', you may want to specify one with the --config option"
|
|
36
|
+
exit(false)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
config_env = config[FLAPJACK_ENV]
|
|
40
|
+
|
|
41
|
+
if config_env.nil? || config_env.empty?
|
|
42
|
+
puts "No config data for environment '#{FLAPJACK_ENV}' found in '#{options.config}'"
|
|
43
|
+
exit(false)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
if options.pidfile.nil?
|
|
47
|
+
pid_file = (config_env['pid_file'] || 'tmp/pids/flapjack.pid')
|
|
48
|
+
else
|
|
49
|
+
pid_file = options.pidfile
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# add lib to the default include path
|
|
53
|
+
unless $:.include?(File.dirname(__FILE__) + '/../lib/')
|
|
54
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# TODO Flapjack falls over when Redis restarted -- trap errors and attempt reconnect
|
|
58
|
+
|
|
59
|
+
require 'flapjack/coordinator'
|
|
60
|
+
|
|
61
|
+
coordinator = Flapjack::Coordinator.new(config_env)
|
|
62
|
+
coordinator.log_file = (config_env['log_file'] || 'log/flapjack.log')
|
|
63
|
+
coordinator.pid_file = pid_file
|
|
64
|
+
|
|
65
|
+
if options.daemonize.nil?
|
|
66
|
+
daemonize = !!config_env['daemonize']
|
|
67
|
+
else
|
|
68
|
+
daemonize = options.daemonize
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
puts "Daemonising ... " if daemonize
|
|
72
|
+
coordinator.start(:daemonize => daemonize)
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'redis'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'yaml'
|
|
6
|
+
require 'optparse'
|
|
7
|
+
require 'ostruct'
|
|
8
|
+
require 'flapjack/data/entity_check'
|
|
9
|
+
|
|
10
|
+
options = OpenStruct.new
|
|
11
|
+
options.config = File.join('etc', 'flapjack_config.yaml')
|
|
12
|
+
options.daemonize = nil
|
|
13
|
+
|
|
14
|
+
OptionParser.new do |opts|
|
|
15
|
+
opts.banner = "Usage: flapjack-nagios-receiver [options]"
|
|
16
|
+
|
|
17
|
+
opts.on("-c", "--config [PATH]", String, "PATH to the config file to use") do |c|
|
|
18
|
+
options.config = c
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
opts.on("-f", "--fifo [PATH]", String, "PATH to the nagios perfdata named pipe") do |f|
|
|
22
|
+
options.fifo_path = f
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end.parse!(ARGV)
|
|
26
|
+
|
|
27
|
+
FLAPJACK_ENV = ENV['FLAPJACK_ENV'] || 'development'
|
|
28
|
+
|
|
29
|
+
# load the config hash for the current environment
|
|
30
|
+
|
|
31
|
+
if File.file?(options.config)
|
|
32
|
+
config = YAML::load(File.open(options.config))
|
|
33
|
+
else
|
|
34
|
+
puts "Could not find config file at '#{options.config}', you may want to specify one with the --config option"
|
|
35
|
+
exit(false)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
config_env = config[FLAPJACK_ENV]
|
|
39
|
+
|
|
40
|
+
if config_env.nil? || config_env.empty?
|
|
41
|
+
puts "No config data for environment '#{FLAPJACK_ENV}' found in '#{options.config}'"
|
|
42
|
+
exit(false)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# add lib to the default include path
|
|
46
|
+
#unless $:.include?(File.dirname(__FILE__) + '/../lib/')
|
|
47
|
+
# $: << File.dirname(__FILE__) + '/../lib'
|
|
48
|
+
#end
|
|
49
|
+
|
|
50
|
+
# nagios.cfg contains the following templates for host and service data (modified from the default
|
|
51
|
+
# to include hoststate / servicestate, and a fake service 'HOST' for hostperfdata, so that the
|
|
52
|
+
# fields match up
|
|
53
|
+
# host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\tHOST\t$HOSTSTATE$\t$HOSTEXECUTIONTIME$\t$HOSTLATENCY$\t$HOSTOUTPUT$\t$HOSTPERFDATA$
|
|
54
|
+
# service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICESTATE$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$
|
|
55
|
+
|
|
56
|
+
@redis_host = config_env['redis']['host'] || 'localhost'
|
|
57
|
+
@redis_port = config_env['redis']['port'] || '6379'
|
|
58
|
+
@redis_path = config_env['redis']['path'] || nil
|
|
59
|
+
@redis_db = config_env['redis']['db'] || 0
|
|
60
|
+
|
|
61
|
+
if config_env.nil? || config_env.empty?
|
|
62
|
+
puts "No config data for environment '#{FLAPJACK_ENV}'"
|
|
63
|
+
exit(false)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def process_input
|
|
67
|
+
|
|
68
|
+
if @redis_path
|
|
69
|
+
redis = Redis.new(:db => @redis_db, :path => @redis_path)
|
|
70
|
+
else
|
|
71
|
+
redis = Redis.new(:db => @redis_db, :host => @redis_host, :port => @redis_port)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
puts "ARGV after option processing looks like this: [#{ARGV.inspect}]"
|
|
75
|
+
|
|
76
|
+
begin
|
|
77
|
+
while line = ARGF.readline.split("\t")
|
|
78
|
+
object_type, timestamp, entity, check, state, check_time, check_latency, check_output, check_perfdata = line
|
|
79
|
+
puts "#{object_type}, #{timestamp}, #{entity}, #{check}, #{state}, #{check_output}"
|
|
80
|
+
next unless line.length == 9
|
|
81
|
+
next unless timestamp =~ /^\d+$/
|
|
82
|
+
next unless (object_type == '[HOSTPERFDATA]') or (object_type == '[SERVICEPERFDATA]')
|
|
83
|
+
state = 'ok' if state.downcase == 'up'
|
|
84
|
+
state = 'critical' if state.downcase == 'down'
|
|
85
|
+
event = {
|
|
86
|
+
'entity' => entity,
|
|
87
|
+
'check' => check,
|
|
88
|
+
'type' => 'service',
|
|
89
|
+
'state' => state,
|
|
90
|
+
'summary' => check_output,
|
|
91
|
+
'timestamp' => timestamp,
|
|
92
|
+
}.to_json
|
|
93
|
+
redis.rpush 'events', event
|
|
94
|
+
end
|
|
95
|
+
rescue Redis::CannotConnectError
|
|
96
|
+
puts "Error, unable to to connect to the redis server (#{$!})"
|
|
97
|
+
rescue EOFError
|
|
98
|
+
puts "Error - end of file reached when reading from the named pipe. Nagios down?"
|
|
99
|
+
sleep 10
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def main
|
|
104
|
+
while true
|
|
105
|
+
process_input
|
|
106
|
+
sleep 10
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
main
|
|
111
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'daemons'
|
|
4
|
+
opts = {
|
|
5
|
+
:app_name => 'flapjack-nagios-receiver',
|
|
6
|
+
:dir_mode => :normal,
|
|
7
|
+
:dir => '/var/run/flapjack',
|
|
8
|
+
:multiple => false,
|
|
9
|
+
:backtrace => true,
|
|
10
|
+
:monitor => false,
|
|
11
|
+
:log_dir => '/var/log/flapjack',
|
|
12
|
+
:log_output => true,
|
|
13
|
+
}
|
|
14
|
+
Daemons.run(File.join(File.dirname(__FILE__) ,'flapjack-nagios-receiver'), opts)
|
|
15
|
+
|
data/bin/flapjack-populator
CHANGED
|
@@ -1,29 +1,146 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
require 'rubygems'
|
|
4
3
|
require 'yajl'
|
|
5
|
-
require '
|
|
4
|
+
require 'redis'
|
|
5
|
+
require 'yaml'
|
|
6
|
+
require 'optparse'
|
|
7
|
+
require 'ostruct'
|
|
8
|
+
require 'flapjack/data/entity_check'
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
options = OpenStruct.new
|
|
11
|
+
options.config = File.join('etc', 'flapjack_config.yaml')
|
|
12
|
+
options.daemonize = nil
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
command = ARGV.shift
|
|
15
|
+
|
|
16
|
+
banner = "Usage: flapjack-populator command [options]\n"
|
|
17
|
+
banner += "\n"
|
|
18
|
+
banner += " commands:\n"
|
|
19
|
+
banner += " - import-entities\n"
|
|
20
|
+
banner += " - import-contacts\n"
|
|
21
|
+
banner += " - purge-events (purge queued monitoring events)\n"
|
|
22
|
+
|
|
23
|
+
OptionParser.new do |opts|
|
|
24
|
+
opts.banner = "Usage: flapjack-populator command [options]"
|
|
25
|
+
|
|
26
|
+
opts.on("-c", "--config [PATH]", String, "PATH to the config file to use") do |c|
|
|
27
|
+
options.config = c
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
opts.on("-f", "--from [FILE]", String, "path to the FILE to import") do |f|
|
|
31
|
+
options.from = f
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end.parse!(ARGV)
|
|
35
|
+
|
|
36
|
+
FLAPJACK_ENV = ENV['FLAPJACK_ENV'] || 'development'
|
|
37
|
+
|
|
38
|
+
# load the config hash for the current environment
|
|
39
|
+
|
|
40
|
+
if File.file?(options.config)
|
|
41
|
+
config = YAML::load(File.open(options.config))
|
|
42
|
+
else
|
|
43
|
+
puts "Could not find config file at '#{options.config}', you may want to specify one with the --config option"
|
|
44
|
+
exit(false)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
config_env = config[FLAPJACK_ENV]
|
|
13
48
|
|
|
14
|
-
|
|
49
|
+
if config_env.nil? || config_env.empty?
|
|
50
|
+
puts "No config data for environment '#{FLAPJACK_ENV}' found in '#{options.config}'"
|
|
51
|
+
exit(false)
|
|
52
|
+
end
|
|
15
53
|
|
|
16
|
-
|
|
54
|
+
if options.from
|
|
55
|
+
filename = options.from
|
|
17
56
|
file = File.new(filename)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
parser = Yajl::Parser.new
|
|
60
|
+
|
|
61
|
+
@redis_host = config_env['redis']['host'] || 'localhost'
|
|
62
|
+
@redis_port = config_env['redis']['port'] || '6379'
|
|
63
|
+
@redis_path = config_env['redis']['path'] || nil
|
|
64
|
+
@redis_db = config_env['redis']['db'] || 0
|
|
21
65
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
66
|
+
# add lib to the default include path
|
|
67
|
+
unless $:.include?(File.dirname(__FILE__) + '/../lib/')
|
|
68
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def get_redis_connection
|
|
72
|
+
if @redis_path
|
|
73
|
+
redis = Redis.new(:db => @redis_db, :path => @redis_path)
|
|
74
|
+
else
|
|
75
|
+
redis = Redis.new(:db => @redis_db, :host => @redis_host, :port => @redis_port)
|
|
25
76
|
end
|
|
77
|
+
redis
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
case command
|
|
81
|
+
when "import-contacts"
|
|
82
|
+
@persistence = get_redis_connection
|
|
83
|
+
contacts = parser.parse(file)
|
|
84
|
+
contacts.each {|contact|
|
|
85
|
+
if not contact['id']
|
|
86
|
+
puts "Contact not imported as it has no id: " + contact.inspect
|
|
87
|
+
next
|
|
88
|
+
end
|
|
89
|
+
@persistence.multi
|
|
90
|
+
@persistence.del("contact:#{contact['id']}")
|
|
91
|
+
@persistence.del("contact_media:#{contact['id']}")
|
|
92
|
+
@persistence.del("contact_pagerduty:#{contact['id']}")
|
|
93
|
+
@persistence.hset("contact:#{contact['id']}", 'first_name', contact['first_name'])
|
|
94
|
+
@persistence.hset("contact:#{contact['id']}", 'last_name', contact['last_name'])
|
|
95
|
+
@persistence.hset("contact:#{contact['id']}", 'email', contact['email'])
|
|
96
|
+
contact['media'].each_pair {|medium, address|
|
|
97
|
+
case medium
|
|
98
|
+
when 'pagerduty'
|
|
99
|
+
@persistence.hset("contact_media:#{contact['id']}", medium, address['service_key'])
|
|
100
|
+
@persistence.hset("contact_pagerduty:#{contact['id']}", 'subdomain', address['subdomain'])
|
|
101
|
+
@persistence.hset("contact_pagerduty:#{contact['id']}", 'username', address['username'])
|
|
102
|
+
@persistence.hset("contact_pagerduty:#{contact['id']}", 'password', address['password'])
|
|
103
|
+
else
|
|
104
|
+
@persistence.hset("contact_media:#{contact['id']}", medium, address)
|
|
105
|
+
end
|
|
106
|
+
}
|
|
107
|
+
@persistence.exec
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
when "import-entities"
|
|
111
|
+
@persistence = get_redis_connection
|
|
112
|
+
entities = parser.parse(file)
|
|
113
|
+
entities.each {|entity|
|
|
114
|
+
if not entity['id']
|
|
115
|
+
puts "Entity not imported as it has no id: " + entity.inspect
|
|
116
|
+
next
|
|
117
|
+
end
|
|
118
|
+
@persistence.multi
|
|
119
|
+
existing_name = @persistence.hget("entity:#{entity['id']}", 'name')
|
|
120
|
+
@persistence.del("entity_id:#{existing_name}") unless existing_name == entity['name']
|
|
121
|
+
@persistence.set("entity_id:#{entity['name']}", entity['id'])
|
|
122
|
+
@persistence.hset("entity:#{entity['id']}", 'name', entity['name'])
|
|
123
|
+
|
|
124
|
+
@persistence.del("contacts_for:#{entity['id']}")
|
|
125
|
+
entity['contacts'].each {|contact|
|
|
126
|
+
@persistence.sadd("contacts_for:#{entity['id']}", contact)
|
|
127
|
+
}
|
|
128
|
+
@persistence.exec
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
when "purge-events"
|
|
133
|
+
@persistence = get_redis_connection
|
|
134
|
+
events_size = @persistence.llen('events')
|
|
135
|
+
puts "purging #{events_size} events..."
|
|
136
|
+
timestamp = Time.now.to_i
|
|
137
|
+
puts "renaming events to events.#{timestamp}"
|
|
138
|
+
@persistence.rename('events', "events.#{timestamp}")
|
|
139
|
+
puts "setting expiry of events.#{timestamp} to 8 hours"
|
|
140
|
+
@persistence.expire("events.#{timestamp}", (60 * 60 * 8))
|
|
26
141
|
|
|
27
|
-
|
|
142
|
+
else
|
|
143
|
+
puts "you need to give me something to do, eg a command like 'import-entities' or 'import-clients' etc"
|
|
144
|
+
raise ArgumentError
|
|
28
145
|
end
|
|
29
146
|
|