sensu 0.12.6 → 0.13.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
data/lib/sensu/process.rb DELETED
@@ -1,48 +0,0 @@
1
- module Sensu
2
- class Process
3
- def initialize
4
- @logger = Logger.get
5
- end
6
-
7
- def write_pid(file)
8
- begin
9
- File.open(file, 'w') do |pid_file|
10
- pid_file.puts(::Process.pid)
11
- end
12
- rescue
13
- @logger.fatal('could not write to pid file', {
14
- :pid_file => file
15
- })
16
- @logger.fatal('SENSU NOT RUNNING!')
17
- exit 2
18
- end
19
- end
20
-
21
- def daemonize
22
- srand
23
- if fork
24
- exit
25
- end
26
- unless ::Process.setsid
27
- @logger.fatal('cannot detach from controlling terminal')
28
- @logger.fatal('SENSU NOT RUNNING!')
29
- exit 2
30
- end
31
- Signal.trap('SIGHUP', 'IGNORE')
32
- if fork
33
- exit
34
- end
35
- Dir.chdir('/')
36
- ObjectSpace.each_object(IO) do |io|
37
- unless [STDIN, STDOUT, STDERR].include?(io)
38
- begin
39
- unless io.closed?
40
- io.close
41
- end
42
- rescue
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,106 +0,0 @@
1
- gem 'amqp', '1.0.0'
2
-
3
- require 'amqp'
4
-
5
- module AMQ
6
- module Client
7
- module Async
8
- module Adapter
9
- def send_heartbeat
10
- if tcp_connection_established? && !reconnecting?
11
- if !@handling_skipped_hearbeats && @last_server_heartbeat
12
- send_frame(Protocol::HeartbeatFrame)
13
- if @last_server_heartbeat < (Time.now - (self.heartbeat_interval * 2))
14
- logger.error('detected missing amqp heartbeats')
15
- self.handle_skipped_hearbeats
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end
24
-
25
- module Sensu
26
- class RabbitMQError < StandardError; end
27
-
28
- class RabbitMQ
29
- attr_reader :channel
30
-
31
- def initialize
32
- @on_error = Proc.new {}
33
- @before_reconnect = Proc.new {}
34
- @after_reconnect = Proc.new {}
35
- end
36
-
37
- def on_error(&block)
38
- @on_error = block
39
- end
40
-
41
- def before_reconnect(&block)
42
- @before_reconnect = block
43
- end
44
-
45
- def after_reconnect(&block)
46
- @after_reconnect = block
47
- end
48
-
49
- def connect(options={})
50
- timeout = EM::Timer.new(20) do
51
- error = RabbitMQError.new('timed out while attempting to connect')
52
- @on_error.call(error)
53
- end
54
- on_failure = Proc.new do
55
- error = RabbitMQError.new('failed to connect')
56
- @on_error.call(error)
57
- end
58
- @connection = AMQP.connect(options, {
59
- :on_tcp_connection_failure => on_failure,
60
- :on_possible_authentication_failure => on_failure
61
- })
62
- @connection.logger = Logger.get
63
- @connection.on_open do
64
- timeout.cancel
65
- end
66
- reconnect = Proc.new do
67
- unless @connection.reconnecting?
68
- @before_reconnect.call
69
- @connection.periodically_reconnect(5)
70
- end
71
- end
72
- @connection.on_tcp_connection_loss(&reconnect)
73
- @connection.on_skipped_heartbeats(&reconnect)
74
- @channel = AMQP::Channel.new(@connection)
75
- @channel.auto_recovery = true
76
- @channel.on_error do |channel, channel_close|
77
- error = RabbitMQError.new('rabbitmq channel closed')
78
- @on_error.call(error)
79
- end
80
- prefetch = 1
81
- if options.is_a?(Hash)
82
- prefetch = options[:prefetch] || 1
83
- end
84
- @channel.on_recovery do
85
- @after_reconnect.call
86
- @channel.prefetch(prefetch)
87
- end
88
- @channel.prefetch(prefetch)
89
- end
90
-
91
- def connected?
92
- @connection.connected?
93
- end
94
-
95
- def close
96
- @connection.close
97
- end
98
-
99
- def self.connect(options={})
100
- options ||= Hash.new
101
- rabbitmq = self.new
102
- rabbitmq.connect(options)
103
- rabbitmq
104
- end
105
- end
106
- end
@@ -1,483 +0,0 @@
1
- module Sensu
2
- class Settings
3
- include Utilities
4
-
5
- attr_reader :indifferent_access, :loaded_env, :loaded_files
6
-
7
- def initialize
8
- @logger = Logger.get
9
- @settings = Hash.new
10
- SETTINGS_CATEGORIES.each do |category|
11
- @settings[category] = Hash.new
12
- end
13
- @indifferent_access = false
14
- @loaded_env = false
15
- @loaded_files = Array.new
16
- end
17
-
18
- def indifferent_access!
19
- @settings = with_indifferent_access(@settings)
20
- @indifferent_access = true
21
- end
22
-
23
- def to_hash
24
- unless @indifferent_access
25
- indifferent_access!
26
- end
27
- @settings
28
- end
29
-
30
- def [](key)
31
- to_hash[key]
32
- end
33
-
34
- SETTINGS_CATEGORIES.each do |category|
35
- define_method(category) do
36
- @settings[category].map do |name, details|
37
- details.merge(:name => name.to_s)
38
- end
39
- end
40
-
41
- type = category.to_s.chop
42
-
43
- define_method((type + '_exists?').to_sym) do |name|
44
- @settings[category].has_key?(name.to_sym)
45
- end
46
-
47
- define_method(('invalid_' + type).to_sym) do |details, reason|
48
- invalid(reason, {
49
- type => details
50
- })
51
- end
52
- end
53
-
54
- def load_env
55
- if ENV['RABBITMQ_URL']
56
- @settings[:rabbitmq] = ENV['RABBITMQ_URL']
57
- @logger.warn('using rabbitmq url environment variable', {
58
- :rabbitmq_url => ENV['RABBITMQ_URL']
59
- })
60
- end
61
- ENV['REDIS_URL'] ||= ENV['REDISTOGO_URL']
62
- if ENV['REDIS_URL']
63
- @settings[:redis] = ENV['REDIS_URL']
64
- @logger.warn('using redis url environment variable', {
65
- :redis_url => ENV['REDIS_URL']
66
- })
67
- end
68
- ENV['API_PORT'] ||= ENV['PORT']
69
- if ENV['API_PORT']
70
- @settings[:api] ||= Hash.new
71
- @settings[:api][:port] = ENV['API_PORT']
72
- @logger.warn('using api port environment variable', {
73
- :api_port => ENV['API_PORT']
74
- })
75
- end
76
- @indifferent_access = false
77
- @loaded_env = true
78
- end
79
-
80
- def load_file(file)
81
- @logger.debug('loading config file', {
82
- :config_file => file
83
- })
84
- if File.file?(file) && File.readable?(file)
85
- begin
86
- contents = File.open(file, 'r').read
87
- config = Oj.load(contents, :mode => :strict)
88
- merged = deep_merge(@settings, config)
89
- unless @loaded_files.empty?
90
- changes = deep_diff(@settings, merged)
91
- @logger.warn('config file applied changes', {
92
- :config_file => file,
93
- :changes => redact_sensitive(changes)
94
- })
95
- end
96
- @settings = merged
97
- @indifferent_access = false
98
- @loaded_files << file
99
- rescue Oj::ParseError => error
100
- @logger.error('config file must be valid json', {
101
- :config_file => file,
102
- :error => error.to_s
103
- })
104
- @logger.warn('ignoring config file', {
105
- :config_file => file
106
- })
107
- end
108
- else
109
- @logger.error('config file does not exist or is not readable', {
110
- :config_file => file
111
- })
112
- @logger.warn('ignoring config file', {
113
- :config_file => file
114
- })
115
- end
116
- end
117
-
118
- def load_directory(directory)
119
- path = directory.gsub(/\\(?=\S)/, '/')
120
- Dir.glob(File.join(path, '**/*.json')).each do |file|
121
- load_file(file)
122
- end
123
- end
124
-
125
- def set_env
126
- ENV['SENSU_CONFIG_FILES'] = @loaded_files.join(':')
127
- end
128
-
129
- def validate
130
- @logger.debug('validating settings')
131
- SETTINGS_CATEGORIES.each do |category|
132
- unless @settings[category].is_a?(Hash)
133
- invalid(category.to_s + ' must be a hash')
134
- end
135
- send(category).each do |details|
136
- send(('validate_' + category.to_s.chop).to_sym, details)
137
- end
138
- end
139
- case File.basename($0)
140
- when 'sensu-client'
141
- validate_client
142
- when 'sensu-api'
143
- validate_api
144
- when 'rspec'
145
- validate_client
146
- validate_api
147
- end
148
- @logger.debug('settings are valid')
149
- end
150
-
151
- private
152
-
153
- def invalid(reason, data={})
154
- @logger.fatal('invalid settings', {
155
- :reason => reason
156
- }.merge(data))
157
- @logger.fatal('SENSU NOT RUNNING!')
158
- exit 2
159
- end
160
-
161
- def validate_subdue(type, details)
162
- condition = details[:subdue]
163
- data = {
164
- type => details
165
- }
166
- unless condition.is_a?(Hash)
167
- invalid(type + ' subdue must be a hash', data)
168
- end
169
- if condition.has_key?(:at)
170
- unless %w[handler publisher].include?(condition[:at])
171
- invalid(type + ' subdue at must be either handler or publisher', data)
172
- end
173
- end
174
- if condition.has_key?(:begin) || condition.has_key?(:end)
175
- begin
176
- Time.parse(condition[:begin])
177
- Time.parse(condition[:end])
178
- rescue
179
- invalid(type + ' subdue begin & end times must be valid', data)
180
- end
181
- end
182
- if condition.has_key?(:days)
183
- unless condition[:days].is_a?(Array)
184
- invalid(type + ' subdue days must be an array', data)
185
- end
186
- condition[:days].each do |day|
187
- days = %w[sunday monday tuesday wednesday thursday friday saturday]
188
- unless day.is_a?(String) && days.include?(day.downcase)
189
- invalid(type + ' subdue days must be valid days of the week', data)
190
- end
191
- end
192
- end
193
- if condition.has_key?(:exceptions)
194
- unless condition[:exceptions].is_a?(Array)
195
- invalid(type + ' subdue exceptions must be an array', data)
196
- end
197
- condition[:exceptions].each do |exception|
198
- unless exception.is_a?(Hash)
199
- invalid(type + ' subdue exceptions must each be a hash', data)
200
- end
201
- if exception.has_key?(:begin) || exception.has_key?(:end)
202
- begin
203
- Time.parse(exception[:begin])
204
- Time.parse(exception[:end])
205
- rescue
206
- invalid(type + ' subdue exception begin & end times must be valid', data)
207
- end
208
- end
209
- end
210
- end
211
- end
212
-
213
- def validate_check(check)
214
- unless check[:name] =~ /^[\w\.-]+$/
215
- invalid_check(check, 'check name cannot contain spaces or special characters')
216
- end
217
- unless (check[:interval].is_a?(Integer) && check[:interval] > 0) || !check[:publish]
218
- invalid_check(check, 'check is missing interval')
219
- end
220
- unless check[:command].is_a?(String)
221
- invalid_check(check, 'check is missing command')
222
- end
223
- if check.has_key?(:standalone)
224
- unless !!check[:standalone] == check[:standalone]
225
- invalid_check(check, 'check standalone must be boolean')
226
- end
227
- end
228
- unless check[:standalone]
229
- unless check[:subscribers].is_a?(Array)
230
- invalid_check(check, 'check is missing subscribers')
231
- end
232
- check[:subscribers].each do |subscriber|
233
- unless subscriber.is_a?(String) && !subscriber.empty?
234
- invalid_check(check, 'check subscribers must each be a string')
235
- end
236
- end
237
- end
238
- if check.has_key?(:timeout)
239
- unless check[:timeout].is_a?(Numeric)
240
- invalid_check(check, 'check timeout must be numeric')
241
- end
242
- end
243
- if check.has_key?(:handler)
244
- unless check[:handler].is_a?(String)
245
- invalid_check(check, 'check handler must be a string')
246
- end
247
- end
248
- if check.has_key?(:handlers)
249
- unless check[:handlers].is_a?(Array)
250
- invalid_check(check, 'check handlers must be an array')
251
- end
252
- check[:handlers].each do |handler_name|
253
- unless handler_name.is_a?(String)
254
- invalid_check(check, 'check handlers must each be a string')
255
- end
256
- end
257
- end
258
- if check.has_key?(:low_flap_threshold) || check.has_key?(:high_flap_threshold)
259
- unless check[:low_flap_threshold].is_a?(Integer)
260
- invalid_check(check, 'check low flap threshold must be numeric')
261
- end
262
- unless check[:high_flap_threshold].is_a?(Integer)
263
- invalid_check(check, 'check high flap threshold must be numeric')
264
- end
265
- end
266
- if check.has_key?(:subdue)
267
- validate_subdue('check', check)
268
- end
269
- end
270
-
271
- def validate_mutator(mutator)
272
- unless mutator[:command].is_a?(String)
273
- invalid_mutator(mutator, 'mutator is missing command')
274
- end
275
- if mutator.has_key?(:timeout)
276
- unless mutator[:timeout].is_a?(Numeric)
277
- invalid_mutator(mutator, 'mutator timeout must be numeric')
278
- end
279
- end
280
- end
281
-
282
- def validate_filter(filter)
283
- unless filter[:attributes].is_a?(Hash)
284
- invalid_filter(filter, 'filter attributes must be a hash')
285
- end
286
- if filter.has_key?(:negate)
287
- unless !!filter[:negate] == filter[:negate]
288
- invalid_filter(filter, 'filter negate must be boolean')
289
- end
290
- end
291
- end
292
-
293
- def validate_handler(handler)
294
- unless handler[:type].is_a?(String)
295
- invalid_handler(handler, 'handler is missing type')
296
- end
297
- case handler[:type]
298
- when 'pipe'
299
- unless handler[:command].is_a?(String)
300
- invalid_handler(handler, 'handler is missing command')
301
- end
302
- when 'tcp', 'udp'
303
- unless handler[:socket].is_a?(Hash)
304
- invalid_handler(handler, 'handler is missing socket hash')
305
- end
306
- unless handler[:socket][:host].is_a?(String)
307
- invalid_handler(handler, 'handler is missing socket host')
308
- end
309
- unless handler[:socket][:port].is_a?(Integer)
310
- invalid_handler(handler, 'handler is missing socket port')
311
- end
312
- when 'amqp'
313
- unless handler[:exchange].is_a?(Hash)
314
- invalid_handler(handler, 'handler is missing exchange hash')
315
- end
316
- unless handler[:exchange][:name].is_a?(String)
317
- invalid_handler(handler, 'handler is missing exchange name')
318
- end
319
- if handler[:exchange].has_key?(:type)
320
- unless %w[direct fanout topic].include?(handler[:exchange][:type])
321
- invalid_handler(handler, 'handler exchange type is invalid')
322
- end
323
- end
324
- when 'set'
325
- unless handler[:handlers].is_a?(Array)
326
- invalid_handler(handler, 'handler set handlers must be an array')
327
- end
328
- handler[:handlers].each do |handler_name|
329
- unless handler_name.is_a?(String)
330
- invalid_handler(handler, 'handler set handlers must each be a string')
331
- end
332
- if handler_exists?(handler_name) && @settings[:handlers][handler_name.to_sym][:type] == 'set'
333
- invalid_handler(handler, 'handler sets cannot be nested')
334
- end
335
- end
336
- else
337
- invalid_handler(handler, 'unknown handler type')
338
- end
339
- if handler.has_key?(:timeout)
340
- unless handler[:timeout].is_a?(Numeric)
341
- invalid_handler(handler, 'handler timeout must be numeric')
342
- end
343
- end
344
- if handler.has_key?(:filter)
345
- unless handler[:filter].is_a?(String)
346
- invalid_handler(handler, 'handler filter must be a string')
347
- end
348
- end
349
- if handler.has_key?(:filters)
350
- unless handler[:filters].is_a?(Array)
351
- invalid_handler(handler, 'handler filters must be an array')
352
- end
353
- handler[:filters].each do |filter_name|
354
- unless filter_name.is_a?(String)
355
- invalid_handler(handler, 'handler filters items must be strings')
356
- end
357
- end
358
- end
359
- if handler.has_key?(:mutator)
360
- unless handler[:mutator].is_a?(String)
361
- invalid_handler(handler, 'handler mutator must be a string')
362
- end
363
- end
364
- if handler.has_key?(:handle_flapping)
365
- unless !!handler[:handle_flapping] == handler[:handle_flapping]
366
- invalid_handler(handler, 'handler handle_flapping must be boolean')
367
- end
368
- end
369
- if handler.has_key?(:severities)
370
- unless handler[:severities].is_a?(Array) && !handler[:severities].empty?
371
- invalid_handler(handler, 'handler severities must be an array and not empty')
372
- end
373
- handler[:severities].each do |severity|
374
- unless SEVERITIES.include?(severity)
375
- invalid_handler(handler, 'handler severities are invalid')
376
- end
377
- end
378
- end
379
- if handler.has_key?(:subdue)
380
- validate_subdue('handler', handler)
381
- end
382
- end
383
-
384
- def validate_client
385
- unless @settings[:client].is_a?(Hash)
386
- invalid('missing client configuration')
387
- end
388
- unless @settings[:client][:name] =~ /^[\w\.-]+$/
389
- invalid('client must have a name and it cannot contain spaces or special characters')
390
- end
391
- unless @settings[:client][:address].is_a?(String)
392
- invalid('client must have an address')
393
- end
394
- unless @settings[:client][:subscriptions].is_a?(Array)
395
- invalid('client must have subscriptions')
396
- end
397
- @settings[:client][:subscriptions].each do |subscription|
398
- unless subscription.is_a?(String) && !subscription.empty?
399
- invalid('client subscriptions must each be a string')
400
- end
401
- end
402
- if @settings[:client].has_key?(:socket)
403
- unless @settings[:client][:socket].is_a?(Hash)
404
- invalid('client socket must be a hash')
405
- end
406
- if @settings[:client][:socket].has_key?(:bind)
407
- unless @settings[:client][:socket][:bind].is_a?(String)
408
- invalid('client socket bind must be a string')
409
- end
410
- end
411
- if @settings[:client][:socket].has_key?(:port)
412
- unless @settings[:client][:socket][:port].is_a?(Integer)
413
- invalid('client socket port must be an integer')
414
- end
415
- end
416
- end
417
- if @settings[:client].has_key?(:keepalive)
418
- unless @settings[:client][:keepalive].is_a?(Hash)
419
- invalid('client keepalive must be a hash')
420
- end
421
- if @settings[:client][:keepalive].has_key?(:handler)
422
- unless @settings[:client][:keepalive][:handler].is_a?(String)
423
- invalid('client keepalive handler must be a string')
424
- end
425
- end
426
- if @settings[:client][:keepalive].has_key?(:handlers)
427
- handlers = @settings[:client][:keepalive][:handlers]
428
- unless handlers.is_a?(Array)
429
- invalid('client keepalive handlers must be an array')
430
- end
431
- handlers.each do |handler_name|
432
- unless handler_name.is_a?(String)
433
- invalid('client keepalive handlers must each be a string')
434
- end
435
- end
436
- end
437
- if @settings[:client][:keepalive].has_key?(:thresholds)
438
- thresholds = @settings[:client][:keepalive][:thresholds]
439
- unless thresholds.is_a?(Hash)
440
- invalid('client keepalive thresholds must be a hash')
441
- end
442
- if thresholds.has_key?(:warning)
443
- unless thresholds[:warning].is_a?(Integer)
444
- invalid('client keepalive warning threshold must be an integer')
445
- end
446
- end
447
- if thresholds.has_key?(:critical)
448
- unless thresholds[:critical].is_a?(Integer)
449
- invalid('client keepalive critical threshold must be an integer')
450
- end
451
- end
452
- end
453
- end
454
- if @settings[:client].has_key?(:redact)
455
- unless @settings[:client][:redact].is_a?(Array)
456
- invalid('client redact must be an array')
457
- end
458
- @settings[:client][:redact].each do |key|
459
- unless key.is_a?(String) && !key.empty?
460
- invalid('client redact keys must each be a string')
461
- end
462
- end
463
- end
464
- end
465
-
466
- def validate_api
467
- unless @settings[:api].is_a?(Hash)
468
- invalid('missing api configuration')
469
- end
470
- unless @settings[:api][:port].is_a?(Integer)
471
- invalid('api port must be an integer')
472
- end
473
- if @settings[:api].has_key?(:user) || @settings[:api].has_key?(:password)
474
- unless @settings[:api][:user].is_a?(String)
475
- invalid('api user must be a string')
476
- end
477
- unless @settings[:api][:password].is_a?(String)
478
- invalid('api password must be a string')
479
- end
480
- end
481
- end
482
- end
483
- end