flapjack 0.5.1 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/.gitignore
ADDED
data/Rakefile
CHANGED
@@ -1,11 +1,64 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'fileutils'
|
5
5
|
require 'spec/rake/spectask'
|
6
|
+
require 'rake'
|
7
|
+
|
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
|
6
37
|
|
7
|
-
#
|
8
|
-
|
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
|
47
|
+
|
48
|
+
begin
|
49
|
+
require 'rcov/rcovtask'
|
50
|
+
Rcov::RcovTask.new do |test|
|
51
|
+
test.libs << 'test'
|
52
|
+
test.pattern = 'test/**/test_*.rb'
|
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
|
59
|
+
end
|
60
|
+
|
61
|
+
begin
|
9
62
|
require 'cucumber/rake/task'
|
10
63
|
|
11
64
|
Cucumber::Rake::Task.new do |task|
|
@@ -17,38 +70,25 @@ end
|
|
17
70
|
Spec::Rake::SpecTask.new do |t|
|
18
71
|
t.spec_opts = ["--options", "spec/spec.opts"]
|
19
72
|
end
|
73
|
+
task :test => :check_dependencies
|
20
74
|
|
75
|
+
task :default => :test
|
21
76
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
files = `git ls-files`.split.delete_if {|file| file =~ /^(spec\/|\.gitignore)/}
|
26
|
-
puts
|
27
|
-
puts "Copy and paste into flapjack.gemspec:"
|
28
|
-
puts
|
29
|
-
puts " s.executables = #{executables.inspect}"
|
30
|
-
puts " s.files = #{files.inspect}"
|
31
|
-
puts
|
32
|
-
puts
|
33
|
-
end
|
77
|
+
require 'rake/rdoctask'
|
78
|
+
Rake::RDocTask.new do |rdoc|
|
79
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
34
80
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
FileUtils.mkdir_p('pkg')
|
40
|
-
puts
|
41
|
-
puts "Flapjack gems:"
|
42
|
-
Dir.glob("flapjack-*.gem").each do |gem|
|
43
|
-
dest = File.join('pkg', gem)
|
44
|
-
FileUtils.mv gem, dest
|
45
|
-
puts " " + dest
|
46
|
-
end
|
81
|
+
rdoc.rdoc_dir = 'rdoc'
|
82
|
+
rdoc.title = "flapjack #{version}"
|
83
|
+
rdoc.rdoc_files.include('README*')
|
84
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
47
85
|
end
|
48
86
|
|
49
|
-
|
87
|
+
#
|
88
|
+
# misc
|
89
|
+
#
|
50
90
|
desc "display FIXMEs in the codebase"
|
51
|
-
task :fixmes do
|
91
|
+
task :fixmes do
|
52
92
|
output = `grep -nR FIXME lib/* spec/* bin/`
|
53
93
|
output.split("\n").each do |line|
|
54
94
|
parts = line.split(':')
|
@@ -58,7 +98,7 @@ task :fixmes do
|
|
58
98
|
end
|
59
99
|
|
60
100
|
desc "build a tarball suitable for building packages from"
|
61
|
-
task :tarball do
|
101
|
+
task :tarball do
|
62
102
|
require 'open-uri'
|
63
103
|
require 'tmpdir'
|
64
104
|
tmpdir = Dir.mktmpdir
|
@@ -109,7 +149,7 @@ task :tarball do
|
|
109
149
|
# save file
|
110
150
|
saved_file = "/tmp/#{details[:filename]}"
|
111
151
|
File.open(saved_file, 'w') do |f|
|
112
|
-
f << open(details[:source]).read
|
152
|
+
f << open(details[:source]).read
|
113
153
|
end
|
114
154
|
|
115
155
|
`tar zxf #{saved_file} -C #{tmpdir}`
|
@@ -127,7 +167,7 @@ task :tarball do
|
|
127
167
|
end
|
128
168
|
|
129
169
|
desc "dump out statements to create sqlite3 schema"
|
130
|
-
task :dm_debug do
|
170
|
+
task :dm_debug do
|
131
171
|
require 'lib/flapjack/persistence/data_mapper'
|
132
172
|
|
133
173
|
DataMapper.logger.set_log(STDOUT, :debug)
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.5.3
|
@@ -0,0 +1,433 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'yajl/json_gem'
|
6
|
+
|
7
|
+
module Netsaint
|
8
|
+
class Service
|
9
|
+
def self.all
|
10
|
+
@services = []
|
11
|
+
|
12
|
+
Netsaint::Config.services.each do |id, attributes|
|
13
|
+
attributes.each do |attrs|
|
14
|
+
@services << self.new(attrs.merge("id" => id))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
#@services[0..500]
|
19
|
+
@services
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(opts={})
|
23
|
+
@attributes = opts
|
24
|
+
|
25
|
+
@attributes.keys.each do |key|
|
26
|
+
if key == "id" || !self.respond_to?(key.to_sym)
|
27
|
+
instance_eval <<-METHOD
|
28
|
+
def #{key}
|
29
|
+
@attributes["#{key}"]
|
30
|
+
end
|
31
|
+
METHOD
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def flapjack_id
|
37
|
+
"#{id}-#{description.downcase.gsub(' ', '_')}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_command
|
41
|
+
parts = @attributes["check_command"].split('!')
|
42
|
+
command_id = parts.first
|
43
|
+
arguments = parts[1..-1]
|
44
|
+
|
45
|
+
attrs = { "arguments" => arguments,
|
46
|
+
"hostname" => self.id }
|
47
|
+
#command = ::Netsaint::Command.get(command_id)
|
48
|
+
#command.attributes = attrs
|
49
|
+
#command.expand_command_line
|
50
|
+
"exit 0"
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_flapjack
|
54
|
+
{"id" => flapjack_id, "command" => check_command, "interval" => check_interval.to_i * 60 }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Command
|
59
|
+
def self.all
|
60
|
+
@commands = []
|
61
|
+
|
62
|
+
Netsaint::Config.commands.each do |id, attributes|
|
63
|
+
attributes.each do |attrs|
|
64
|
+
@commands << self.new(attrs.merge("id" => id))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
@commands
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.get(id)
|
72
|
+
attrs = Netsaint::Config.commands[id].first
|
73
|
+
command = attrs.merge({"id" => id})
|
74
|
+
|
75
|
+
self.new(command)
|
76
|
+
end
|
77
|
+
|
78
|
+
def initialize(opts={})
|
79
|
+
@attributes = opts
|
80
|
+
|
81
|
+
@attributes.keys.each do |key|
|
82
|
+
if key == "id" || !self.respond_to?(key.to_sym)
|
83
|
+
instance_eval <<-METHOD
|
84
|
+
def #{key}
|
85
|
+
@attributes["#{key}"]
|
86
|
+
end
|
87
|
+
METHOD
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def attributes=(attrs)
|
93
|
+
@attributes.merge!(attrs)
|
94
|
+
end
|
95
|
+
|
96
|
+
def expand_command_line
|
97
|
+
@attributes["command_line"].gsub(/\$\w+\$/) do |string|
|
98
|
+
lookup_macro(string)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def lookup_macro(string)
|
103
|
+
case string
|
104
|
+
when /^\$USER\d+\$$/
|
105
|
+
::Netsaint::Config.fetch(string)[string]
|
106
|
+
when /^\$ARG(\d+)\$$/
|
107
|
+
index = $1.to_i - 1
|
108
|
+
@attributes["arguments"][index]
|
109
|
+
when "$HOSTNAME$"
|
110
|
+
@attributes["hostname"]
|
111
|
+
when "$HOSTADDRESS$"
|
112
|
+
hostname = @attributes["hostname"]
|
113
|
+
::Netsaint::Host.get(hostname).address
|
114
|
+
else
|
115
|
+
raise "Don't know how to handle the #{string} macro!"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class Host
|
121
|
+
def self.get(id)
|
122
|
+
attrs = Netsaint::Config.hosts[id].first
|
123
|
+
host = attrs.merge({"id" => id})
|
124
|
+
|
125
|
+
self.new(host)
|
126
|
+
end
|
127
|
+
|
128
|
+
def initialize(opts={})
|
129
|
+
@attributes = opts
|
130
|
+
|
131
|
+
@attributes.keys.each do |key|
|
132
|
+
if key == "id" || !self.respond_to?(key.to_sym)
|
133
|
+
instance_eval <<-METHOD
|
134
|
+
def #{key}
|
135
|
+
@attributes["#{key}"]
|
136
|
+
end
|
137
|
+
METHOD
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class ConfigFile
|
144
|
+
attr_accessor :filename, :config
|
145
|
+
|
146
|
+
def initialize(filename, opts={})
|
147
|
+
@filename = filename
|
148
|
+
@config = {}
|
149
|
+
end
|
150
|
+
|
151
|
+
def read
|
152
|
+
@raw_cfg = File.readlines(@filename).grep(/^[^#]/).map {|l| l.strip.empty? ? nil : l.strip }.compact
|
153
|
+
end
|
154
|
+
|
155
|
+
def extract(keyname, opts={}, &blk)
|
156
|
+
opts[:delete] ||= true
|
157
|
+
attrs = @config.find_all {|k, v| k =~ /^#{keyname}\[/ }
|
158
|
+
extracted = {}
|
159
|
+
|
160
|
+
attrs.each do |key, value|
|
161
|
+
@config.delete(key) if opts[:delete]
|
162
|
+
name = key[/#{keyname}\[(.+)\]/, 1]
|
163
|
+
extracted[name] ||= []
|
164
|
+
if value.class == Array
|
165
|
+
value.each { |v| extracted[name] << v }
|
166
|
+
else
|
167
|
+
extracted[name] << value
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
if block_given?
|
173
|
+
yielded = extracted.map do |key, value|
|
174
|
+
key, value = yield key, value
|
175
|
+
[ key, value ]
|
176
|
+
end
|
177
|
+
extracted = Hash[yielded]
|
178
|
+
end
|
179
|
+
|
180
|
+
extracted
|
181
|
+
end
|
182
|
+
|
183
|
+
def build_timeperiods
|
184
|
+
timeperiods = extract "timeperiod" do |key, value|
|
185
|
+
value.map! do |v|
|
186
|
+
parts = v.split(';')
|
187
|
+
{ "timeperiod_alias" => parts[1], "sun_timeranges" => parts[2],
|
188
|
+
"mon_timeranges" => parts[3], "tue_timeranges" => parts[4],
|
189
|
+
"wed_timeranges" => parts[5], "thu_timeranges" => parts[6],
|
190
|
+
"fri_timeranges" => parts[7], "sat_timeranges" => parts[8] }
|
191
|
+
end
|
192
|
+
[ key, value ]
|
193
|
+
end
|
194
|
+
|
195
|
+
@config["timeperiods"] = timeperiods
|
196
|
+
end
|
197
|
+
|
198
|
+
def build_services
|
199
|
+
services = extract "service" do |key, value|
|
200
|
+
value.map! do |v|
|
201
|
+
parts = v.split(';')
|
202
|
+
{ "description" => parts[0], "volatile" => parts[1],
|
203
|
+
"check_period" => parts[2], "max_attempts" => parts[3],
|
204
|
+
"check_interval" => parts[4], "retry_interval" => parts[5],
|
205
|
+
"notification_group" => parts[6], "notification_interval" => parts[7],
|
206
|
+
"notification_period" => parts[8], "notify_recovery" => parts[9],
|
207
|
+
"notify_critical" => parts[10], "notify_warning" => parts[11],
|
208
|
+
"event_hander" => parts[12], "check_command" => parts[13] }
|
209
|
+
end
|
210
|
+
[ key, value ]
|
211
|
+
end
|
212
|
+
|
213
|
+
@config["services"] = services
|
214
|
+
end
|
215
|
+
|
216
|
+
def build_contactgroups
|
217
|
+
contactgroups = extract "contactgroup" do |key, value|
|
218
|
+
value.map! do |v|
|
219
|
+
parts = v.split(';')
|
220
|
+
{ "group_alias" => parts[0], "contacts" => parts[1] }
|
221
|
+
end
|
222
|
+
[ key, value ]
|
223
|
+
end
|
224
|
+
|
225
|
+
@config["contactgroups"] = contactgroups
|
226
|
+
end
|
227
|
+
|
228
|
+
def build_contacts
|
229
|
+
contacts = extract "contact" do |key, value|
|
230
|
+
value.map! do |v|
|
231
|
+
parts = v.split(';')
|
232
|
+
{ "contact_alias" => parts[0], "svc_notification_period" => parts[1],
|
233
|
+
"host_notification_period" => parts[2], "notify_service_recovery" => parts[3],
|
234
|
+
"notify_service_critical" => parts[4], "notify_service_warning" => parts[5],
|
235
|
+
"notify_host_recovery" => parts[6], "notify_host_down" => parts[7],
|
236
|
+
"notify_host_unreachable" => parts[8], "service_notify_commands" => parts[9],
|
237
|
+
"host_notify_commands" => parts[10], "email_address" => parts[11],
|
238
|
+
"pager" => parts[12] }
|
239
|
+
end
|
240
|
+
[ key, value ]
|
241
|
+
end
|
242
|
+
|
243
|
+
@config["contacts"] = contacts
|
244
|
+
end
|
245
|
+
|
246
|
+
def build_hosts
|
247
|
+
hosts = extract "host" do |key, value|
|
248
|
+
value.map! do |v|
|
249
|
+
parts = v.split(';')
|
250
|
+
{ "host_alias" => parts[0], "address" => parts[1],
|
251
|
+
"parent_hosts" => parts[2], "host_check_command" => parts[3],
|
252
|
+
"max_attempts" => parts[4], "notification_interval" => parts[5],
|
253
|
+
"notification_period" => parts[6], "notify_recovery" => parts[7],
|
254
|
+
"notify_down" => parts[8], "notify_unreachable" => parts[9],
|
255
|
+
"event_handler" => parts[10] }
|
256
|
+
end
|
257
|
+
[ key, value]
|
258
|
+
end
|
259
|
+
|
260
|
+
@config["hosts"] = hosts
|
261
|
+
end
|
262
|
+
|
263
|
+
def build_commands
|
264
|
+
commands = extract "command" do |key, value|
|
265
|
+
value.map! do |v|
|
266
|
+
parts = v.split(';')
|
267
|
+
{ "command_line" => parts[0] }
|
268
|
+
end
|
269
|
+
[ key, value]
|
270
|
+
end
|
271
|
+
|
272
|
+
@config["commands"] = commands
|
273
|
+
end
|
274
|
+
|
275
|
+
def to_hash
|
276
|
+
self.read unless @raw_cfg
|
277
|
+
|
278
|
+
@raw_cfg.each do |o|
|
279
|
+
parts = o.scan(/^([^=]+)=(.+)$/).flatten
|
280
|
+
key = parts.first
|
281
|
+
value = parts.last
|
282
|
+
case
|
283
|
+
when @config[key] && @config[key].class == Array
|
284
|
+
@config[key] << value
|
285
|
+
when @config[key]
|
286
|
+
@config[key] = [ @config[key] ]
|
287
|
+
else
|
288
|
+
@config[key] = value
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
build_timeperiods
|
293
|
+
build_services
|
294
|
+
build_contactgroups
|
295
|
+
build_contacts
|
296
|
+
build_hosts
|
297
|
+
build_commands
|
298
|
+
|
299
|
+
@config
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
303
|
+
|
304
|
+
class Config
|
305
|
+
include Enumerable
|
306
|
+
|
307
|
+
class << self
|
308
|
+
attr_accessor :root, :configs, :files
|
309
|
+
|
310
|
+
@@configs = []
|
311
|
+
@@files = []
|
312
|
+
|
313
|
+
def root=(arg)
|
314
|
+
@@root = arg
|
315
|
+
@@root = Pathname.new(@@root) unless @@root.class == Pathname
|
316
|
+
end
|
317
|
+
|
318
|
+
def build
|
319
|
+
filename = @@root.join('netsaint.cfg')
|
320
|
+
build_file(filename)
|
321
|
+
end
|
322
|
+
|
323
|
+
def build_file(filename)
|
324
|
+
file = ConfigFile.new(filename)
|
325
|
+
hash = file.to_hash
|
326
|
+
@@files << file
|
327
|
+
@@configs << hash
|
328
|
+
%w(cfg_file resource_file).each do |linked_file|
|
329
|
+
if hash[linked_file]
|
330
|
+
hash[linked_file].each do |name|
|
331
|
+
path = relativise_path(name)
|
332
|
+
build_file(path)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def relativise_path(filename)
|
339
|
+
@@match = nil
|
340
|
+
parent = @@root.dirname.dirname
|
341
|
+
path = parent + filename.to_s[1..-1]
|
342
|
+
|
343
|
+
path
|
344
|
+
end
|
345
|
+
|
346
|
+
# Makes Enumerable mixin work
|
347
|
+
def each
|
348
|
+
@@configs.each {|i| yield i }
|
349
|
+
end
|
350
|
+
|
351
|
+
# Search across all configs for a particular key.
|
352
|
+
#
|
353
|
+
# Can be passed a string:
|
354
|
+
#
|
355
|
+
# Netsaint::Config.fetch("command_check_interval") # => {"command_check_interval" => "1"}
|
356
|
+
#
|
357
|
+
# Or a regex:
|
358
|
+
#
|
359
|
+
# Netsaint::Config.fetch(/^\$USER\d+\$$/) # => { "$USER2$"=>"/tmp", "$USER1$"=>"/boot" }
|
360
|
+
#
|
361
|
+
def fetch(key)
|
362
|
+
configs = @@configs.find_all {|c| c.keys.find {|k| k[k]} }
|
363
|
+
results = configs.map {|c| Hash[c.find_all { |k,v| k[key] }] }
|
364
|
+
results.inject {|final, hash| final.merge(hash) }
|
365
|
+
end
|
366
|
+
|
367
|
+
%w(timeperiods services contactgroups contacts hosts commands).each do |method|
|
368
|
+
class_eval <<-METHOD
|
369
|
+
def #{method}
|
370
|
+
#{method} = {}
|
371
|
+
@@configs.each do |c|
|
372
|
+
c["#{method}"].each do |key, value|
|
373
|
+
#{method}[key] ||= []
|
374
|
+
#{method}[key] << value
|
375
|
+
#{method}[key].flatten!
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
#{method}
|
380
|
+
end
|
381
|
+
METHOD
|
382
|
+
end
|
383
|
+
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
command = ARGV[0]
|
389
|
+
|
390
|
+
case command
|
391
|
+
when "print"
|
392
|
+
options = ARGV[2..-1]
|
393
|
+
options = Hash[options.map {|o| o.scan(/--(.+)=(.+)/).flatten }]
|
394
|
+
|
395
|
+
netsaint_root = Pathname.new(options["source"]).expand_path
|
396
|
+
Netsaint::Config.root = netsaint_root
|
397
|
+
Netsaint::Config.build
|
398
|
+
|
399
|
+
command = ARGV[0]
|
400
|
+
type = ARGV[1]
|
401
|
+
|
402
|
+
json = { type => Netsaint::Config.method(type).call }.to_json
|
403
|
+
|
404
|
+
if filename = options["to"]
|
405
|
+
File.open(filename, 'w') do |f|
|
406
|
+
f << json
|
407
|
+
end
|
408
|
+
else
|
409
|
+
puts json
|
410
|
+
end
|
411
|
+
|
412
|
+
when "dump"
|
413
|
+
options = ARGV[1..-1]
|
414
|
+
options = Hash[options.map {|o| o.scan(/--(.+)=(.+)/).flatten }]
|
415
|
+
|
416
|
+
netsaint_root = Pathname.new(options["source"]).expand_path
|
417
|
+
Netsaint::Config.root = netsaint_root
|
418
|
+
Netsaint::Config.build
|
419
|
+
|
420
|
+
@checks = Netsaint::Service.all.map { |service| service.to_flapjack }
|
421
|
+
|
422
|
+
json = { "batch" => {"id" => 1, "created_at" => Time.now}, "checks" => @checks }.to_json
|
423
|
+
|
424
|
+
if filename = options["to"]
|
425
|
+
File.open(filename, 'w') do |f|
|
426
|
+
f << json
|
427
|
+
end
|
428
|
+
puts "Dumped config to #{filename}"
|
429
|
+
else
|
430
|
+
puts json
|
431
|
+
end
|
432
|
+
|
433
|
+
end
|