sensu 0.9.5 → 0.9.6.beta

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/lib/sensu/config.rb DELETED
@@ -1,266 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- require 'bundler/setup'
4
-
5
- gem 'eventmachine', '~> 1.0.0.beta.4'
6
-
7
- require 'optparse'
8
- require 'time'
9
- require 'json'
10
- require 'hashie'
11
- require 'amqp'
12
- require 'cabin'
13
- require 'cabin/outputs/em/stdlib-logger'
14
-
15
- require File.join(File.dirname(__FILE__), 'version')
16
- require File.join(File.dirname(__FILE__), 'patches', 'ruby')
17
- require File.join(File.dirname(__FILE__), 'patches', 'amqp')
18
-
19
- if ENV['RBTRACE']
20
- require 'rbtrace'
21
- end
22
-
23
- module Sensu
24
- class Config
25
- attr_accessor :logger, :settings
26
-
27
- DEFAULT_OPTIONS = {
28
- :config_file => '/etc/sensu/config.json',
29
- :config_dir => '/etc/sensu/conf.d'
30
- }
31
-
32
- def initialize(options={})
33
- @options = DEFAULT_OPTIONS.merge(options)
34
- setup_logging
35
- setup_settings
36
- end
37
-
38
- def invalid_config(message)
39
- puts 'CONFIGURATION INVALID: ' + message
40
- puts 'SENSU NOT RUNNING'
41
- exit 2
42
- end
43
-
44
- def setup_logging
45
- if @options[:log_file]
46
- if File.writable?(@options[:log_file]) || !File.exist?(@options[:log_file]) && File.writable?(File.dirname(@options[:log_file]))
47
- STDOUT.reopen(@options[:log_file], 'a')
48
- STDERR.reopen(STDOUT)
49
- STDOUT.sync = true
50
- else
51
- invalid_config('log file is not writable: ' + @options[:log_file])
52
- end
53
- end
54
- @logger = Cabin::Channel.new
55
- log_output = File.basename($0) == 'rake' ? '/tmp/sensu-test.log' : STDOUT
56
- @logger.subscribe(Cabin::Outputs::EM::StdlibLogger.new(Logger.new(log_output)))
57
- @logger.level = @options[:verbose] ? :debug : :info
58
- if Signal.list.include?('USR1')
59
- Signal.trap('USR1') do
60
- @logger.level = @logger.level == :info ? :debug : :info
61
- end
62
- end
63
- end
64
-
65
- def validate_common_settings
66
- @settings.checks.each do |name, details|
67
- if details.key?('status') || details.key?('output')
68
- invalid_config('reserved key (output or status) defined in check ' + name)
69
- end
70
- unless details.interval.is_a?(Integer) && details.interval > 0
71
- invalid_config('missing interval for check ' + name)
72
- end
73
- unless details.command.is_a?(String)
74
- invalid_config('missing command for check ' + name)
75
- end
76
- unless details.standalone
77
- unless details.subscribers.is_a?(Array) && details.subscribers.count > 0
78
- invalid_config('missing subscribers for check ' + name)
79
- end
80
- details.subscribers.each do |subscriber|
81
- unless subscriber.is_a?(String) && !subscriber.empty?
82
- invalid_config('a check subscriber must be a string (not empty) for check ' + name)
83
- end
84
- end
85
- end
86
- if details.key?('handler')
87
- unless details.handler.is_a?(String)
88
- invalid_config('handler must be a string for check ' + name)
89
- end
90
- end
91
- if details.key?('handlers')
92
- unless details.handlers.is_a?(Array)
93
- invalid_config('handlers must be an array for check ' + name)
94
- end
95
- end
96
- end
97
- end
98
-
99
- def validate_server_settings
100
- unless @settings.handlers.include?('default')
101
- invalid_config('missing default handler')
102
- end
103
- @settings.handlers.each do |name, details|
104
- unless details.is_a?(Hash)
105
- invalid_config('handler details must be a hash for handler ' + name)
106
- end
107
- unless details['type'].is_a?(String)
108
- invalid_config('missing type for handler ' + name)
109
- end
110
- case details['type']
111
- when 'pipe'
112
- unless details.command.is_a?(String)
113
- invalid_config('missing command for pipe handler ' + name)
114
- end
115
- when 'amqp'
116
- unless details.exchange.is_a?(Hash)
117
- invalid_config('missing exchange details for amqp handler ' + name)
118
- end
119
- unless details.exchange.name.is_a?(String)
120
- invalid_config('missing exchange name for amqp handler ' + name)
121
- end
122
- if details.exchange.key?('type')
123
- unless %w[direct fanout topic].include?(details.exchange['type'])
124
- invalid_config('invalid exchange type for amqp handler ' + name)
125
- end
126
- end
127
- when 'set'
128
- unless details.handlers.is_a?(Array) && details.handlers.count > 0
129
- invalid_config('missing handler set for handler ' + name)
130
- end
131
- else
132
- invalid_config('unknown type for handler ' + name)
133
- end
134
- end
135
- end
136
-
137
- def validate_api_settings
138
- unless @settings.api.port.is_a?(Integer)
139
- invalid_config('api port must be an integer')
140
- end
141
- if @settings.api.key?('user') || @settings.api.key?('password')
142
- unless @settings.api.user.is_a?(String)
143
- invalid_config('api user must be a string')
144
- end
145
- unless @settings.api.password.is_a?(String)
146
- invalid_config('api password must be a string')
147
- end
148
- end
149
- end
150
-
151
- def validate_client_settings
152
- unless @settings.client.name.is_a?(String)
153
- invalid_config('client must have a name')
154
- end
155
- unless @settings.client.address.is_a?(String)
156
- invalid_config('client must have an address (ip or hostname)')
157
- end
158
- unless @settings.client.subscriptions.is_a?(Array) && @settings.client.subscriptions.count > 0
159
- invalid_config('client must have subscriptions')
160
- end
161
- @settings.client.subscriptions.each do |subscription|
162
- unless subscription.is_a?(String) && !subscription.empty?
163
- invalid_config('a client subscription must be a string (not empty)')
164
- end
165
- end
166
- end
167
-
168
- def has_keys(keys)
169
- keys.each do |key|
170
- unless @settings.key?(key)
171
- invalid_config('missing the following key: ' + key)
172
- end
173
- end
174
- end
175
-
176
- def validate_settings
177
- @logger.debug('[validate] -- validating configuration')
178
- has_keys(%w[checks])
179
- validate_common_settings
180
- case File.basename($0)
181
- when 'rake'
182
- has_keys(%w[api handlers client])
183
- validate_server_settings
184
- validate_api_settings
185
- validate_client_settings
186
- when 'sensu-server'
187
- has_keys(%w[handlers])
188
- validate_server_settings
189
- when 'sensu-api'
190
- has_keys(%w[api])
191
- validate_api_settings
192
- when 'sensu-client'
193
- has_keys(%w[client])
194
- validate_client_settings
195
- end
196
- @logger.info('[validate] -- configuration valid -- running')
197
- end
198
-
199
- def setup_settings
200
- if File.readable?(@options[:config_file])
201
- begin
202
- config_hash = JSON.parse(File.open(@options[:config_file], 'r').read)
203
- %w[rabbitmq redis].each do |key|
204
- config_hash[key] ||= Hash.new
205
- end
206
- rescue JSON::ParserError => error
207
- invalid_config('configuration file (' + @options[:config_file] + ') must be valid json: ' + error.to_s)
208
- end
209
- @settings = Hashie::Mash.new(config_hash)
210
- else
211
- invalid_config('configuration file does not exist or is not readable: ' + @options[:config_file])
212
- end
213
- if File.exists?(@options[:config_dir])
214
- Dir[@options[:config_dir] + '/**/*.json'].each do |snippet_file|
215
- if File.readable?(snippet_file)
216
- begin
217
- snippet_hash = JSON.parse(File.open(snippet_file, 'r').read)
218
- rescue JSON::ParserError => error
219
- invalid_config('configuration snippet file (' + snippet_file + ') must be valid json: ' + error.to_s)
220
- end
221
- merged_settings = @settings.to_hash.deep_merge(snippet_hash)
222
- @logger.warn('[settings] -- configuration snippet (' + snippet_file + ') applied changes: ' + @settings.deep_diff(merged_settings).to_json)
223
- @settings = Hashie::Mash.new(merged_settings)
224
- else
225
- invalid_config('configuration snippet file is not readable: ' + snippet_file)
226
- end
227
- end
228
- end
229
- validate_settings
230
- end
231
-
232
- def self.read_arguments(arguments)
233
- options = Hash.new
234
- optparse = OptionParser.new do |opts|
235
- opts.on('-h', '--help', 'Display this message') do
236
- puts opts
237
- exit
238
- end
239
- opts.on('-V', '--version', 'Display version') do
240
- puts Sensu::VERSION
241
- exit
242
- end
243
- opts.on('-c', '--config FILE', 'Sensu JSON config FILE. Default is /etc/sensu/config.json') do |file|
244
- options[:config_file] = file
245
- end
246
- opts.on('-d', '--config_dir DIR', 'DIR for supplemental Sensu JSON config files. Default is /etc/sensu/conf.d/') do |dir|
247
- options[:config_dir] = dir
248
- end
249
- opts.on('-l', '--log FILE', 'Log to a given FILE. Default is to log to stdout') do |file|
250
- options[:log_file] = file
251
- end
252
- opts.on('-v', '--verbose', 'Enable verbose logging') do
253
- options[:verbose] = true
254
- end
255
- opts.on('-b', '--background', 'Fork into the background') do
256
- options[:daemonize] = true
257
- end
258
- opts.on('-p', '--pid_file FILE', 'Write the PID to a given FILE') do |file|
259
- options[:pid_file] = file
260
- end
261
- end
262
- optparse.parse!(arguments)
263
- DEFAULT_OPTIONS.merge(options)
264
- end
265
- end
266
- end
data/lib/sensu/version.rb DELETED
@@ -1,3 +0,0 @@
1
- module Sensu
2
- VERSION = "0.9.5"
3
- end