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
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
|