sensu 0.28.6 → 0.29.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +71 -0
- data/exe/sensu-install +6 -1
- data/lib/sensu/api/http_handler.rb +81 -19
- data/lib/sensu/api/routes.rb +3 -0
- data/lib/sensu/api/routes/clients.rb +11 -3
- data/lib/sensu/api/routes/info.rb +4 -1
- data/lib/sensu/api/routes/request.rb +5 -1
- data/lib/sensu/api/routes/settings.rb +23 -0
- data/lib/sensu/api/utilities/filter_response_content.rb +44 -0
- data/lib/sensu/api/utilities/publish_check_request.rb +51 -1
- data/lib/sensu/cli.rb +8 -2
- data/lib/sensu/constants.rb +1 -1
- data/lib/sensu/daemon.rb +4 -3
- data/lib/sensu/server/process.rb +187 -137
- data/lib/sensu/utilities.rb +4 -3
- data/sensu.gemspec +3 -3
- metadata +10 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31731ea9a2311f9aecc12057e03442fb2dffca7e
|
4
|
+
data.tar.gz: ee7b95c65a89a73693717c5220bf7a515ee54634
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1a0e54b2e28998c7653b78f54278ec6f28c2a716fedfc8ab24b59108d33ff9998d60b77776c05e48e556b1decf43c15a2c95ee06842528ae3671cbd7957349a
|
7
|
+
data.tar.gz: d7ed4d7d2cb4794ab2933237d383eb37331dda2adaed120117c25ce36cacb7d4a4cd6e8249439d5f08c1ed52e2e63b5e48e2594603078bcf9f120ca6a52d936b
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,74 @@
|
|
1
|
+
## 0.29.0 - 2017-03-29
|
2
|
+
|
3
|
+
### Features
|
4
|
+
|
5
|
+
Sensu server tasks, replacing the Sensu server leader functionality,
|
6
|
+
distributing certain server responsibilities amongst the running Sensu
|
7
|
+
servers. A server task can only run on one Sensu server at a time. Sensu
|
8
|
+
servers partake in an election process to become responsible for one or
|
9
|
+
more tasks. A task can failover to another Sensu server.
|
10
|
+
|
11
|
+
Sensu API response object filtering for any GET request. Filtering is done
|
12
|
+
with one or more dot notation query parameters, beginning with `filter.`,
|
13
|
+
to specify object attributes to filter by, e.g.
|
14
|
+
`/events?filter.client.environment=production&filter.check.contact=ops`.
|
15
|
+
|
16
|
+
Added API endpoint GET `/settings` to provided the APIs running
|
17
|
+
configuration. Sensitive setting values are redacted by default, unless
|
18
|
+
the query parameter `redacted` is set to `false`, e.g.
|
19
|
+
`/settings?redacted=false`.
|
20
|
+
|
21
|
+
Added support for invalidating a Sensu client when deleting it via the
|
22
|
+
Sensu API DELETE `/clients/:name` endpoint, disallowing further client
|
23
|
+
keepalives and check results until the client is either successfully
|
24
|
+
removed from the client registry or for a specified duration of time. To
|
25
|
+
invalidate a Sensu client until it is deleted, the query parameter
|
26
|
+
`invalidate` must be set to `true`, e.g.
|
27
|
+
`/clients/app01.example.com?invalidate=true`. To invalidate the client for
|
28
|
+
a certain amount of time (in seconds), the query parameter
|
29
|
+
`invalidate_expire` must be set as well, e.g.
|
30
|
+
`/clients/app01.example.com?invalidate=true&invalidate_expire=300`.
|
31
|
+
|
32
|
+
Added a Sensu settings hexdigest, exposed via the Sensu API GET `/info`
|
33
|
+
endpoint, providing a means to determine if a Sensu server's configuration
|
34
|
+
differs from the rest.
|
35
|
+
|
36
|
+
Added a proxy argument to `sensu-install`. To use a proxy for Sensu plugin
|
37
|
+
and extension installation with `sensu-install`, use the `-x` or
|
38
|
+
`--proxy` argument, e.g. `sensu-install -e statsd --proxy
|
39
|
+
http://proxy.example.com:8080`.
|
40
|
+
|
41
|
+
Added support for issuing proxy check requests via the Sensu API POST
|
42
|
+
`/request` endpoint.
|
43
|
+
|
44
|
+
The Sensu API now logs response times.
|
45
|
+
|
46
|
+
The Sensu API now returns a 405 (Method Not Allowed) when an API endpoint
|
47
|
+
does not support a HTTP request method, e.g. `PUT`, and sets the HTTP
|
48
|
+
header "Allow" to indicate which HTTP request methods are supported by the
|
49
|
+
requested endpoint.
|
50
|
+
|
51
|
+
Added a built-in filter for check dependencies, `check_dependencies`,
|
52
|
+
which implements the check dependency filtering logic in the Sensu Plugin
|
53
|
+
library.
|
54
|
+
|
55
|
+
Added default values for Sensu CLI options `config_file`
|
56
|
+
(`"/etc/sensu/config.json"`) and `config_dirs` (`["/etc/sensu/conf.d"]`).
|
57
|
+
These defaults are only applied when the associated file and/or directory
|
58
|
+
exist.
|
59
|
+
|
60
|
+
### Other
|
61
|
+
|
62
|
+
Added a Rubocop configuration file and rake tasks for a slow introduction.
|
63
|
+
|
64
|
+
### Fixes
|
65
|
+
|
66
|
+
The built-in filter `occurrences` now supports `refresh` for flapping
|
67
|
+
events (action `flapping`).
|
68
|
+
|
69
|
+
Force the configured Redis port to be an integer, as some users make the
|
70
|
+
mistake of using a string.
|
71
|
+
|
1
72
|
## 0.28.5 - 2017-03-23
|
2
73
|
|
3
74
|
### Fixes
|
data/exe/sensu-install
CHANGED
@@ -10,7 +10,8 @@ module Sensu
|
|
10
10
|
:verbose => false,
|
11
11
|
:plugins => [],
|
12
12
|
:extensions => [],
|
13
|
-
:clean => false
|
13
|
+
:clean => false,
|
14
|
+
:proxy => nil
|
14
15
|
}
|
15
16
|
optparse = OptionParser.new do |opts|
|
16
17
|
opts.on("-h", "--help", "Display this message") do
|
@@ -38,6 +39,9 @@ module Sensu
|
|
38
39
|
opts.on("-c", "--clean", "Clean up (remove) other installed versions of the plugin(s) and/or extension(s)") do
|
39
40
|
options[:clean] = true
|
40
41
|
end
|
42
|
+
opts.on("-x", "--proxy PROXY", "Install Sensu plugins and extensions via a PROXY URL") do |proxy|
|
43
|
+
options[:proxy] = proxy
|
44
|
+
end
|
41
45
|
end
|
42
46
|
optparse.parse!(arguments)
|
43
47
|
options
|
@@ -70,6 +74,7 @@ module Sensu
|
|
70
74
|
gem_command << " --no-ri --no-rdoc"
|
71
75
|
gem_command << " --verbose" if options[:verbose]
|
72
76
|
gem_command << " --source #{options[:source]}" if options[:source]
|
77
|
+
gem_command << " --http-proxy #{options[:proxy]}" if options[:proxy]
|
73
78
|
log gem_command if options[:verbose]
|
74
79
|
unless system(gem_command)
|
75
80
|
log "failed to install Sensu gem '#{gem_name}'"
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "sensu/api/routes"
|
2
|
+
require "sensu/api/utilities/filter_response_content"
|
2
3
|
|
3
4
|
gem "em-http-server", "0.1.8"
|
4
5
|
|
@@ -9,6 +10,7 @@ module Sensu
|
|
9
10
|
module API
|
10
11
|
class HTTPHandler < EM::HttpServer::Server
|
11
12
|
include Routes
|
13
|
+
include Utilities::FilterResponseContent
|
12
14
|
|
13
15
|
attr_accessor :logger, :settings, :redis, :transport
|
14
16
|
|
@@ -19,6 +21,7 @@ module Sensu
|
|
19
21
|
# @result [Hash]
|
20
22
|
def request_details
|
21
23
|
return @request_details if @request_details
|
24
|
+
@request_start_time = Time.now.to_f
|
22
25
|
_, remote_address = Socket.unpack_sockaddr_in(get_peername)
|
23
26
|
@request_details = {
|
24
27
|
:remote_address => remote_address,
|
@@ -40,12 +43,14 @@ module Sensu
|
|
40
43
|
@logger.debug("api request", request_details)
|
41
44
|
end
|
42
45
|
|
43
|
-
# Log the HTTP response.
|
46
|
+
# Log the HTTP response. This method calculates the
|
47
|
+
# request/response time.
|
44
48
|
def log_response
|
45
49
|
@logger.info("api response", {
|
46
50
|
:request => request_details,
|
47
51
|
:status => @response.status,
|
48
|
-
:content_length => @response.content.to_s.bytesize
|
52
|
+
:content_length => @response.content.to_s.bytesize,
|
53
|
+
:time => (Time.now.to_f - @request_start_time).round(3)
|
49
54
|
})
|
50
55
|
end
|
51
56
|
|
@@ -61,13 +66,20 @@ module Sensu
|
|
61
66
|
|
62
67
|
# Parse the HTTP request query string for parameters. This
|
63
68
|
# method creates `@params`, a hash of parsed query parameters,
|
64
|
-
# used by the API routes.
|
69
|
+
# used by the API routes. This method also creates
|
70
|
+
# `@filter_params`, a hash of parsed response content filter
|
71
|
+
# parameters.
|
65
72
|
def parse_parameters
|
66
73
|
@params = {}
|
67
74
|
if @http_query_string
|
68
75
|
@http_query_string.split("&").each do |pair|
|
69
76
|
key, value = pair.split("=")
|
70
77
|
@params[key.to_sym] = value
|
78
|
+
if key.start_with?("filter.")
|
79
|
+
filter_param = key.sub(/^filter\./, "")
|
80
|
+
@filter_params ||= {}
|
81
|
+
@filter_params[filter_param] = value
|
82
|
+
end
|
71
83
|
end
|
72
84
|
end
|
73
85
|
end
|
@@ -166,13 +178,17 @@ module Sensu
|
|
166
178
|
# Respond to an HTTP request. The routes set `@response_status`,
|
167
179
|
# `@response_status_string`, and `@response_content`
|
168
180
|
# appropriately. The HTTP response status defaults to `200` with
|
169
|
-
# the status string `OK`.
|
170
|
-
#
|
171
|
-
#
|
181
|
+
# the status string `OK`. If filter params were provided,
|
182
|
+
# `@response_content` is filtered (mutated). The Sensu API only
|
183
|
+
# returns JSON response content, `@response_content` is assumed
|
184
|
+
# to be a Ruby object that can be serialized as JSON.
|
172
185
|
def respond
|
173
186
|
@response.status = @response_status || 200
|
174
187
|
@response.status_string = @response_status_string || "OK"
|
175
188
|
if @response_content && @http_request_method != HEAD_METHOD
|
189
|
+
if @http_request_method == GET_METHOD && @filter_params
|
190
|
+
filter_response_content!
|
191
|
+
end
|
176
192
|
@response.content_type "application/json"
|
177
193
|
@response.content = Sensu::JSON.dump(@response_content)
|
178
194
|
end
|
@@ -281,6 +297,14 @@ module Sensu
|
|
281
297
|
respond
|
282
298
|
end
|
283
299
|
|
300
|
+
# Respond to the HTTP request with a `405` (Method Not Allowed) response.
|
301
|
+
def method_not_allowed!(allowed_http_methods=[])
|
302
|
+
@response.headers["Allow"] = allowed_http_methods.join(", ")
|
303
|
+
@response_status = 405
|
304
|
+
@response_status_string = "Method Not Allowed"
|
305
|
+
respond
|
306
|
+
end
|
307
|
+
|
284
308
|
# Respond to the HTTP request with a `412` (Precondition Failed)
|
285
309
|
# response.
|
286
310
|
def precondition_failed!
|
@@ -297,25 +321,63 @@ module Sensu
|
|
297
321
|
respond
|
298
322
|
end
|
299
323
|
|
324
|
+
# Determine the allowed HTTP methods for a route. The route
|
325
|
+
# regular expressions and associated route method calls are
|
326
|
+
# provided by `ROUTES`. This method returns an array of HTTP
|
327
|
+
# methods that have a route that matches the HTTP request URI.
|
328
|
+
#
|
329
|
+
# @return [Array]
|
330
|
+
def allowed_http_methods?
|
331
|
+
ROUTES.map { |http_method, routes|
|
332
|
+
match = routes.detect do |route|
|
333
|
+
@http_request_uri =~ route[0]
|
334
|
+
end
|
335
|
+
match ? http_method : nil
|
336
|
+
}.flatten.compact
|
337
|
+
end
|
338
|
+
|
339
|
+
# Determine the route method for the HTTP request method and
|
340
|
+
# URI. The route regular expressions and associated route method
|
341
|
+
# calls are provided by `ROUTES`. This method will return the
|
342
|
+
# first route method name (Ruby symbol) that has matching URI
|
343
|
+
# regular expression. If an HTTP method is not supported, or
|
344
|
+
# there is not a matching regular expression, `nil` will be
|
345
|
+
# returned.
|
346
|
+
#
|
347
|
+
# @return [Symbol]
|
348
|
+
def determine_route_method
|
349
|
+
if ROUTES.has_key?(@http_request_method)
|
350
|
+
route = ROUTES[@http_request_method].detect do |route|
|
351
|
+
@http_request_uri =~ route[0]
|
352
|
+
end
|
353
|
+
route ? route[1] : nil
|
354
|
+
else
|
355
|
+
nil
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
300
359
|
# Route the HTTP request. OPTIONS HTTP requests will always
|
301
|
-
# return a `200` with no response content.
|
302
|
-
#
|
303
|
-
#
|
304
|
-
#
|
360
|
+
# return a `200` with no response content. This method uses
|
361
|
+
# `determine_route_method()` to determine the symbolized route
|
362
|
+
# method to send/call. If a route method does not exist for the
|
363
|
+
# HTTP request method and URI, this method uses
|
364
|
+
# `allowed_http_methods?()` to determine if a 404 (Not Found) or
|
365
|
+
# 405 (Method Not Allowed) HTTP response should be used.
|
305
366
|
def route_request
|
306
367
|
if @http_request_method == OPTIONS_METHOD
|
307
368
|
respond
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
unless route.nil?
|
313
|
-
send(route[1])
|
369
|
+
else
|
370
|
+
route_method = determine_route_method
|
371
|
+
if route_method
|
372
|
+
send(route_method)
|
314
373
|
else
|
315
|
-
|
374
|
+
allowed_http_methods = allowed_http_methods?
|
375
|
+
if allowed_http_methods.empty?
|
376
|
+
not_found!
|
377
|
+
else
|
378
|
+
method_not_allowed!(allowed_http_methods)
|
379
|
+
end
|
316
380
|
end
|
317
|
-
else
|
318
|
-
not_found!
|
319
381
|
end
|
320
382
|
end
|
321
383
|
|
data/lib/sensu/api/routes.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "sensu/api/routes/settings"
|
1
2
|
require "sensu/api/routes/info"
|
2
3
|
require "sensu/api/routes/health"
|
3
4
|
require "sensu/api/routes/clients"
|
@@ -13,6 +14,7 @@ require "sensu/api/routes/silenced"
|
|
13
14
|
module Sensu
|
14
15
|
module API
|
15
16
|
module Routes
|
17
|
+
include Settings
|
16
18
|
include Info
|
17
19
|
include Health
|
18
20
|
include Clients
|
@@ -32,6 +34,7 @@ module Sensu
|
|
32
34
|
OPTIONS_METHOD = "OPTIONS".freeze
|
33
35
|
|
34
36
|
GET_ROUTES = [
|
37
|
+
[SETTINGS_URI, :get_settings],
|
35
38
|
[INFO_URI, :get_info],
|
36
39
|
[HEALTH_URI, :get_health],
|
37
40
|
[CLIENTS_URI, :get_clients],
|
@@ -113,8 +113,11 @@ module Sensu
|
|
113
113
|
# DELETE /clients/:client_name
|
114
114
|
def delete_client
|
115
115
|
client_name = parse_uri(CLIENT_URI).first
|
116
|
-
|
116
|
+
client_key = "client:#{client_name}"
|
117
|
+
signature_key = "#{client_key}:signature"
|
118
|
+
@redis.get(client_key) do |client_json|
|
117
119
|
unless client_json.nil?
|
120
|
+
@redis.set(signature_key, "invalidated") if @params[:invalidate]
|
118
121
|
@redis.hgetall("events:#{client_name}") do |events|
|
119
122
|
events.each do |check_name, event_json|
|
120
123
|
resolve_event(event_json)
|
@@ -125,8 +128,13 @@ module Sensu
|
|
125
128
|
if events.empty? || attempts == 5
|
126
129
|
@logger.info("deleting client from registry", :client_name => client_name)
|
127
130
|
@redis.srem("clients", client_name) do
|
128
|
-
@redis.del(
|
129
|
-
@
|
131
|
+
@redis.del(client_key)
|
132
|
+
invalidate_expire = integer_parameter(@params[:invalidate_expire])
|
133
|
+
if @params[:invalidate] && invalidate_expire
|
134
|
+
@redis.expire(signature_key, invalidate_expire)
|
135
|
+
else
|
136
|
+
@redis.del(signature_key)
|
137
|
+
end
|
130
138
|
@redis.del("events:#{client_name}")
|
131
139
|
@redis.smembers("result:#{client_name}") do |checks|
|
132
140
|
checks.each do |check_name|
|
@@ -26,7 +26,11 @@ module Sensu
|
|
26
26
|
:reason => data[:reason],
|
27
27
|
:creator => data[:creator]
|
28
28
|
}
|
29
|
-
|
29
|
+
if check[:proxy_requests]
|
30
|
+
publish_proxy_check_requests(check)
|
31
|
+
else
|
32
|
+
publish_check_request(check)
|
33
|
+
end
|
30
34
|
@response_content = {:issued => Time.now.to_i}
|
31
35
|
accepted!
|
32
36
|
else
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "sensu/utilities"
|
2
|
+
|
3
|
+
module Sensu
|
4
|
+
module API
|
5
|
+
module Routes
|
6
|
+
module Settings
|
7
|
+
include Utilities
|
8
|
+
|
9
|
+
SETTINGS_URI = /^\/settings$/
|
10
|
+
|
11
|
+
# GET /settings
|
12
|
+
def get_settings
|
13
|
+
if @params[:redacted] == "false"
|
14
|
+
@response_content = @settings.to_hash
|
15
|
+
else
|
16
|
+
@response_content = redact_sensitive(@settings.to_hash)
|
17
|
+
end
|
18
|
+
respond
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "sensu/utilities"
|
2
|
+
|
3
|
+
module Sensu
|
4
|
+
module API
|
5
|
+
module Utilities
|
6
|
+
module FilterResponseContent
|
7
|
+
include Sensu::Utilities
|
8
|
+
|
9
|
+
# Create a nested hash from a dot notation key and value.
|
10
|
+
#
|
11
|
+
# @param dot_notation [String]
|
12
|
+
# @param value [Object]
|
13
|
+
# @return [Hash]
|
14
|
+
def dot_notation_to_hash(dot_notation, value)
|
15
|
+
hash = {}
|
16
|
+
dot_notation.split(".").reverse.each do |key|
|
17
|
+
if hash.empty?
|
18
|
+
hash = {key.to_sym => value}
|
19
|
+
else
|
20
|
+
hash = {key.to_sym => hash}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
hash
|
24
|
+
end
|
25
|
+
|
26
|
+
# Filter the response content if filter parameters have been
|
27
|
+
# provided. This method mutates `@response_content`, only
|
28
|
+
# retaining array items that match the attributes provided via
|
29
|
+
# filter parameters.
|
30
|
+
def filter_response_content!
|
31
|
+
if @response_content.is_a?(Array) && !@filter_params.empty?
|
32
|
+
attributes = {}
|
33
|
+
@filter_params.each do |key, value|
|
34
|
+
attributes = deep_merge(attributes, dot_notation_to_hash(key, value))
|
35
|
+
end
|
36
|
+
@response_content.select! do |object|
|
37
|
+
attributes_match?(object, attributes, false)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,7 +1,11 @@
|
|
1
|
+
require "sensu/utilities"
|
2
|
+
|
1
3
|
module Sensu
|
2
4
|
module API
|
3
5
|
module Utilities
|
4
6
|
module PublishCheckRequest
|
7
|
+
include Sensu::Utilities
|
8
|
+
|
5
9
|
# Determine the Sensu Transport publish options for a
|
6
10
|
# subscription. If a subscription begins with a Transport pipe
|
7
11
|
# type, either "direct:" or "roundrobin:", the subscription uses
|
@@ -33,7 +37,10 @@ module Sensu
|
|
33
37
|
#
|
34
38
|
# @param check [Hash] definition.
|
35
39
|
def publish_check_request(check)
|
36
|
-
payload = check.
|
40
|
+
payload = check.reject do |key, value|
|
41
|
+
[:subscribers, :interval].include?(key)
|
42
|
+
end
|
43
|
+
payload[:issued] = Time.now.to_i
|
37
44
|
@logger.info("publishing check request", {
|
38
45
|
:payload => payload,
|
39
46
|
:subscribers => check[:subscribers]
|
@@ -51,6 +58,49 @@ module Sensu
|
|
51
58
|
end
|
52
59
|
end
|
53
60
|
end
|
61
|
+
|
62
|
+
# Create and publish one or more proxy check requests. This
|
63
|
+
# method iterates through the Sensu client registry for clients
|
64
|
+
# that matched provided proxy request client attributes. A proxy
|
65
|
+
# check request is created for each client in the registry that
|
66
|
+
# matches the proxy request client attributes. Proxy check
|
67
|
+
# requests have their client tokens subsituted by the associated
|
68
|
+
# client attributes values. The check requests are published to
|
69
|
+
# the Transport via `publish_check_request()`.
|
70
|
+
#
|
71
|
+
# @param check [Hash] definition.
|
72
|
+
def publish_proxy_check_requests(check)
|
73
|
+
client_attributes = check[:proxy_requests][:client_attributes]
|
74
|
+
unless client_attributes.empty?
|
75
|
+
@redis.smembers("clients") do |clients|
|
76
|
+
clients.each do |client_name|
|
77
|
+
@redis.get("client:#{client_name}") do |client_json|
|
78
|
+
unless client_json.nil?
|
79
|
+
client = Sensu::JSON.load(client_json)
|
80
|
+
if attributes_match?(client, client_attributes)
|
81
|
+
@logger.debug("creating a proxy check request", {
|
82
|
+
:client => client,
|
83
|
+
:check => check
|
84
|
+
})
|
85
|
+
proxy_check, unmatched_tokens = object_substitute_tokens(check.dup, client)
|
86
|
+
if unmatched_tokens.empty?
|
87
|
+
proxy_check[:source] ||= client[:name]
|
88
|
+
publish_check_request(proxy_check)
|
89
|
+
else
|
90
|
+
@logger.warn("failed to publish a proxy check request", {
|
91
|
+
:reason => "unmatched client tokens",
|
92
|
+
:unmatched_tokens => unmatched_tokens,
|
93
|
+
:client => client,
|
94
|
+
:check => check
|
95
|
+
})
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
54
104
|
end
|
55
105
|
end
|
56
106
|
end
|
data/lib/sensu/cli.rb
CHANGED
@@ -11,6 +11,12 @@ module Sensu
|
|
11
11
|
# @return [Hash] options
|
12
12
|
def self.read(arguments=ARGV)
|
13
13
|
options = {}
|
14
|
+
if File.exist?("/etc/sensu/config.json")
|
15
|
+
options[:config_file] = "/etc/sensu/config.json"
|
16
|
+
end
|
17
|
+
if Dir.exist?("/etc/sensu/conf.d")
|
18
|
+
options[:config_dirs] = ["/etc/sensu/conf.d"]
|
19
|
+
end
|
14
20
|
optparse = OptionParser.new do |opts|
|
15
21
|
opts.on("-h", "--help", "Display this message") do
|
16
22
|
puts opts
|
@@ -20,10 +26,10 @@ module Sensu
|
|
20
26
|
puts VERSION
|
21
27
|
exit
|
22
28
|
end
|
23
|
-
opts.on("-c", "--config FILE", "Sensu JSON config FILE") do |file|
|
29
|
+
opts.on("-c", "--config FILE", "Sensu JSON config FILE. Default: /etc/sensu/config.json (if exists)") do |file|
|
24
30
|
options[:config_file] = file
|
25
31
|
end
|
26
|
-
opts.on("-d", "--config_dir DIR[,DIR]", "DIR or comma-delimited DIR list for Sensu JSON config files") do |dir|
|
32
|
+
opts.on("-d", "--config_dir DIR[,DIR]", "DIR or comma-delimited DIR list for Sensu JSON config files. Default: /etc/sensu/conf.d (if exists)") do |dir|
|
27
33
|
options[:config_dirs] = dir.split(",")
|
28
34
|
end
|
29
35
|
opts.on("--validate_config", "Validate the compiled configuration and exit") do
|
data/lib/sensu/constants.rb
CHANGED
data/lib/sensu/daemon.rb
CHANGED
@@ -4,12 +4,12 @@ gem "eventmachine", "1.2.2"
|
|
4
4
|
|
5
5
|
gem "sensu-json", "2.1.0"
|
6
6
|
gem "sensu-logger", "1.2.1"
|
7
|
-
gem "sensu-settings", "
|
7
|
+
gem "sensu-settings", "10.0.0"
|
8
8
|
gem "sensu-extension", "1.5.1"
|
9
|
-
gem "sensu-extensions", "1.
|
9
|
+
gem "sensu-extensions", "1.9.0"
|
10
10
|
gem "sensu-transport", "7.0.2"
|
11
11
|
gem "sensu-spawn", "2.2.1"
|
12
|
-
gem "sensu-redis", "2.1.
|
12
|
+
gem "sensu-redis", "2.1.1"
|
13
13
|
|
14
14
|
require "time"
|
15
15
|
require "uri"
|
@@ -142,6 +142,7 @@ module Sensu
|
|
142
142
|
@logger.fatal("SENSU NOT RUNNING!")
|
143
143
|
exit 2
|
144
144
|
end
|
145
|
+
@settings.set_env!
|
145
146
|
end
|
146
147
|
|
147
148
|
# Load Sensu extensions and log any notices. Set the logger and
|
data/lib/sensu/server/process.rb
CHANGED
@@ -11,7 +11,9 @@ module Sensu
|
|
11
11
|
include Mutate
|
12
12
|
include Handle
|
13
13
|
|
14
|
-
attr_reader :
|
14
|
+
attr_reader :tasks, :in_progress
|
15
|
+
|
16
|
+
TASKS = ["check_request_publisher", "client_monitor", "check_result_monitor"]
|
15
17
|
|
16
18
|
STANDARD_CHECK_TYPE = "standard".freeze
|
17
19
|
|
@@ -34,14 +36,17 @@ module Sensu
|
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
37
|
-
# Override Daemon initialize() to support Sensu server
|
38
|
-
#
|
39
|
+
# Override Daemon initialize() to support Sensu server tasks and
|
40
|
+
# the handling event count.
|
39
41
|
#
|
40
42
|
# @param options [Hash]
|
41
43
|
def initialize(options={})
|
42
44
|
super
|
43
|
-
@
|
44
|
-
@timers[:
|
45
|
+
@tasks = []
|
46
|
+
@timers[:tasks] = {}
|
47
|
+
TASKS.each do |task|
|
48
|
+
@timers[:tasks][task.to_sym] = []
|
49
|
+
end
|
45
50
|
@in_progress = Hash.new(0)
|
46
51
|
end
|
47
52
|
|
@@ -150,7 +155,7 @@ module Sensu
|
|
150
155
|
if (signature.nil? || signature.empty?) && client[:signature]
|
151
156
|
@redis.set(signature_key, client[:signature])
|
152
157
|
end
|
153
|
-
if signature.nil? || signature.empty? ||
|
158
|
+
if signature.nil? || signature.empty? || client[:signature] == signature
|
154
159
|
@redis.multi
|
155
160
|
@redis.set(client_key, Sensu::JSON.dump(client))
|
156
161
|
@redis.sadd("clients", client[:name])
|
@@ -429,18 +434,11 @@ module Sensu
|
|
429
434
|
# @return [TrueClass, FalseClass]
|
430
435
|
def check_flapping?(stored_event, check)
|
431
436
|
if check.has_key?(:low_flap_threshold) && check.has_key?(:high_flap_threshold)
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
check[:total_state_change] > check[:low_flap_threshold]
|
436
|
-
else
|
437
|
-
check[:total_state_change] >= check[:high_flap_threshold]
|
438
|
-
end
|
437
|
+
was_flapping = stored_event && stored_event[:action] == EVENT_FLAPPING_ACTION
|
438
|
+
if was_flapping
|
439
|
+
check[:total_state_change] > check[:low_flap_threshold]
|
439
440
|
else
|
440
|
-
|
441
|
-
details[:client] = stored_event[:client] if stored_event
|
442
|
-
@logger.error("invalid check flap thresholds", details)
|
443
|
-
false
|
441
|
+
check[:total_state_change] >= check[:high_flap_threshold]
|
444
442
|
end
|
445
443
|
else
|
446
444
|
false
|
@@ -607,7 +605,10 @@ module Sensu
|
|
607
605
|
# `client_key` as the client name. Dynamically create client
|
608
606
|
# data can be updated using the API (POST /clients/:client). If
|
609
607
|
# a client does exist and it has a client signature, the check
|
610
|
-
# result must have a matching signature or it is discarded.
|
608
|
+
# result must have a matching signature or it is discarded. If
|
609
|
+
# the client does not exist, but a client signature exists, the
|
610
|
+
# check result must have a matching signature or it is
|
611
|
+
# discarded.
|
611
612
|
#
|
612
613
|
# @param result [Hash] data.
|
613
614
|
# @yield [client] callback/block to be called with client data,
|
@@ -633,10 +634,20 @@ module Sensu
|
|
633
634
|
yield(client)
|
634
635
|
end
|
635
636
|
else
|
636
|
-
client
|
637
|
-
|
638
|
-
|
639
|
-
|
637
|
+
@redis.get("client:#{client_key}:signature") do |signature|
|
638
|
+
if signature.nil? || signature.empty? || result[:signature] == signature
|
639
|
+
client = create_client(client_key)
|
640
|
+
client[:type] = "proxy" if result[:check][:source]
|
641
|
+
update_client_registry(client) do
|
642
|
+
yield(client)
|
643
|
+
end
|
644
|
+
else
|
645
|
+
@logger.warn("invalid check result signature", {
|
646
|
+
:result => result,
|
647
|
+
:signature => signature
|
648
|
+
})
|
649
|
+
yield(nil)
|
650
|
+
end
|
640
651
|
end
|
641
652
|
end
|
642
653
|
end
|
@@ -843,18 +854,16 @@ module Sensu
|
|
843
854
|
# creats an EventMachine timer for the request. This method will
|
844
855
|
# be called after every check cron request for subsequent
|
845
856
|
# requests. The timer is stored in the timer hash under
|
846
|
-
# `:
|
847
|
-
#
|
848
|
-
#
|
849
|
-
# the request is published, to stop the timer hash from growing
|
850
|
-
# infinitely.
|
857
|
+
# `:tasks`, so it can be cancelled etc. The check cron request
|
858
|
+
# timer object is removed from the timer hash after the request
|
859
|
+
# is published, to stop the timer hash from growing infinitely.
|
851
860
|
#
|
852
861
|
# @param check [Hash] definition.
|
853
862
|
def schedule_check_cron_request(check)
|
854
863
|
cron_time = determine_check_cron_time(check)
|
855
|
-
@timers[:
|
864
|
+
@timers[:tasks][:check_request_publisher] << EM::Timer.new(cron_time) do |timer|
|
856
865
|
create_check_request_proc(check).call
|
857
|
-
@timers[:
|
866
|
+
@timers[:tasks][:check_request_publisher].delete(timer)
|
858
867
|
schedule_check_cron_request(check)
|
859
868
|
end
|
860
869
|
end
|
@@ -874,17 +883,16 @@ module Sensu
|
|
874
883
|
# using an intial calculated request splay EventMachine timer
|
875
884
|
# and an EventMachine periodic timer for subsequent check
|
876
885
|
# requests. The timers are stored in the timers hash under
|
877
|
-
# `:
|
878
|
-
# Sensu server leader, so they can be cancelled etc.
|
886
|
+
# `:tasks`, so they can be cancelled etc.
|
879
887
|
#
|
880
888
|
# @param check [Hash] definition.
|
881
889
|
def schedule_check_interval_requests(check)
|
882
890
|
request_splay = testing? ? 0 : calculate_check_request_splay(check)
|
883
891
|
interval = testing? ? 0.5 : check[:interval]
|
884
|
-
@timers[:
|
892
|
+
@timers[:tasks][:check_request_publisher] << EM::Timer.new(request_splay) do
|
885
893
|
create_check_request = create_check_request_proc(check)
|
886
894
|
create_check_request.call
|
887
|
-
@timers[:
|
895
|
+
@timers[:tasks][:check_request_publisher] << EM::PeriodicTimer.new(interval, &create_check_request)
|
888
896
|
end
|
889
897
|
end
|
890
898
|
|
@@ -1041,10 +1049,10 @@ module Sensu
|
|
1041
1049
|
|
1042
1050
|
# Set up the client monitor, a periodic timer to run
|
1043
1051
|
# `determine_stale_clients()` every 30 seconds. The timer is
|
1044
|
-
# stored in the timers hash under `:
|
1052
|
+
# stored in the timers hash under `:tasks`.
|
1045
1053
|
def setup_client_monitor
|
1046
1054
|
@logger.debug("monitoring client keepalives")
|
1047
|
-
@timers[:
|
1055
|
+
@timers[:tasks][:client_monitor] << EM::PeriodicTimer.new(30) do
|
1048
1056
|
determine_stale_clients
|
1049
1057
|
end
|
1050
1058
|
end
|
@@ -1087,31 +1095,21 @@ module Sensu
|
|
1087
1095
|
|
1088
1096
|
# Set up the check result monitor, a periodic timer to run
|
1089
1097
|
# `determine_stale_check_results()` every 30 seconds. The timer
|
1090
|
-
# is stored in the timers hash under `:
|
1098
|
+
# is stored in the timers hash under `:tasks`.
|
1091
1099
|
def setup_check_result_monitor(interval = 30)
|
1092
1100
|
@logger.debug("monitoring check results")
|
1093
|
-
@timers[:
|
1101
|
+
@timers[:tasks][:check_result_monitor] << EM::PeriodicTimer.new(interval) do
|
1094
1102
|
determine_stale_check_results(interval)
|
1095
1103
|
end
|
1096
1104
|
end
|
1097
1105
|
|
1098
|
-
# Set up the leader duties, tasks only performed by a single
|
1099
|
-
# Sensu server at a time. The duties include publishing check
|
1100
|
-
# requests, monitoring for stale clients, and pruning check
|
1101
|
-
# result aggregations.
|
1102
|
-
def leader_duties
|
1103
|
-
setup_check_request_publisher
|
1104
|
-
setup_client_monitor
|
1105
|
-
setup_check_result_monitor
|
1106
|
-
end
|
1107
|
-
|
1108
1106
|
# Create a lock timestamp (integer), current time including
|
1109
|
-
# milliseconds. This method is used by Sensu server
|
1107
|
+
# milliseconds. This method is used by Sensu server task
|
1110
1108
|
# election.
|
1111
1109
|
#
|
1112
1110
|
# @return [Integer]
|
1113
1111
|
def create_lock_timestamp
|
1114
|
-
(Time.now.to_f *
|
1112
|
+
(Time.now.to_f * 10000000).to_i
|
1115
1113
|
end
|
1116
1114
|
|
1117
1115
|
# Create/return the unique Sensu server ID for the current
|
@@ -1122,122 +1120,168 @@ module Sensu
|
|
1122
1120
|
@server_id ||= random_uuid
|
1123
1121
|
end
|
1124
1122
|
|
1125
|
-
#
|
1126
|
-
#
|
1127
|
-
#
|
1128
|
-
#
|
1129
|
-
#
|
1130
|
-
#
|
1131
|
-
#
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1123
|
+
# Setup a Sensu server task. Unless the current process is
|
1124
|
+
# already responsible for the task, this method sets the tasks
|
1125
|
+
# server ID stored in Redis to the unique random server ID for
|
1126
|
+
# the process. If the tasks server ID is successfully updated,
|
1127
|
+
# the task is added to `@tasks` for tracking purposes and the
|
1128
|
+
# task setup method is called.
|
1129
|
+
#
|
1130
|
+
# @param task [String]
|
1131
|
+
# @yield callback/block called after setting up the task.
|
1132
|
+
def setup_task(task)
|
1133
|
+
unless @tasks.include?(task)
|
1134
|
+
@redis.set("task:#{task}:server", server_id) do
|
1135
|
+
@logger.info("i am now responsible for a server task", :task => task)
|
1136
|
+
@tasks << task
|
1137
|
+
self.send("setup_#{task}".to_sym)
|
1138
|
+
yield if block_given?
|
1138
1139
|
end
|
1139
1140
|
else
|
1140
|
-
@logger.debug("i am already
|
1141
|
+
@logger.debug("i am already responsible for a server task", :task => task)
|
1141
1142
|
end
|
1142
1143
|
end
|
1143
1144
|
|
1144
|
-
#
|
1145
|
-
#
|
1146
|
-
#
|
1147
|
-
#
|
1148
|
-
#
|
1149
|
-
#
|
1150
|
-
#
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1145
|
+
# Relinquish a Sensu server task. This method cancels and
|
1146
|
+
# clears the associated task timers, those with references
|
1147
|
+
# stored in the timers hash under `:tasks`, and removes the task
|
1148
|
+
# from `@tasks`. The task server ID and lock are not removed
|
1149
|
+
# from Redis, as they will be updated when another server takes
|
1150
|
+
# reponsibility for the task, this method does not need to
|
1151
|
+
# handle Redis connectivity issues.
|
1152
|
+
#
|
1153
|
+
# @param task [String]
|
1154
|
+
def relinquish_task(task)
|
1155
|
+
if @tasks.include?(task)
|
1156
|
+
@logger.warn("relinquishing server task", :task => task)
|
1157
|
+
@timers[:tasks][task.to_sym].each do |timer|
|
1155
1158
|
timer.cancel
|
1156
1159
|
end
|
1157
|
-
@timers[:
|
1158
|
-
@
|
1160
|
+
@timers[:tasks][task.to_sym].clear
|
1161
|
+
@tasks.delete(task)
|
1159
1162
|
else
|
1160
|
-
@logger.debug("not currently
|
1163
|
+
@logger.debug("not currently responsible for a server task", :task => task)
|
1161
1164
|
end
|
1162
1165
|
end
|
1163
1166
|
|
1164
|
-
#
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1167
|
+
# Relinquish all Sensu server tasks, if any.
|
1168
|
+
def relinquish_tasks
|
1169
|
+
unless @tasks.empty?
|
1170
|
+
@tasks.dup.each do |task|
|
1171
|
+
relinquish_task(task)
|
1172
|
+
end
|
1173
|
+
else
|
1174
|
+
@logger.debug("not currently responsible for a server task")
|
1175
|
+
end
|
1176
|
+
end
|
1177
|
+
|
1178
|
+
# Updates a Sensu server task lock timestamp. The current task
|
1179
|
+
# server ID is retrieved from Redis and compared with the server
|
1180
|
+
# ID of the current process to determine if it is still
|
1181
|
+
# responsible for the task. If the current process is still
|
1182
|
+
# responsible, the task lock timestamp is updated. If the
|
1183
|
+
# current process is no longer responsible, `relinquish_task()`
|
1184
|
+
# is called for cleanup.
|
1185
|
+
#
|
1186
|
+
# @param task [String]
|
1187
|
+
def update_task_lock(task)
|
1188
|
+
@redis.get("task:#{task}:server") do |current_server_id|
|
1189
|
+
if current_server_id == server_id
|
1190
|
+
@redis.set("lock:task:#{task}", create_lock_timestamp) do
|
1191
|
+
@logger.debug("updated task lock timestamp", :task => task)
|
1177
1192
|
end
|
1178
1193
|
else
|
1179
|
-
@logger.warn("another sensu server
|
1180
|
-
|
1194
|
+
@logger.warn("another sensu server is responsible for the task", :task => task)
|
1195
|
+
relinquish_task(task)
|
1181
1196
|
end
|
1182
1197
|
end
|
1183
1198
|
end
|
1184
1199
|
|
1185
|
-
#
|
1186
|
-
#
|
1187
|
-
#
|
1188
|
-
#
|
1189
|
-
#
|
1190
|
-
#
|
1191
|
-
#
|
1192
|
-
#
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
+
# Set up a Sensu server task lock updater. This method uses a
|
1201
|
+
# periodic timer to update a task lock timestamp in Redis, every
|
1202
|
+
# 10 seconds. If the current process fails to keep the lock
|
1203
|
+
# timestamp updated for a task that it is responsible for,
|
1204
|
+
# another Sensu server will claim responsibility. This method is
|
1205
|
+
# called after task setup.
|
1206
|
+
#
|
1207
|
+
# @param task [String]
|
1208
|
+
def setup_task_lock_updater(task)
|
1209
|
+
@timers[:run] << EM::PeriodicTimer.new(10) do
|
1210
|
+
update_task_lock(task)
|
1211
|
+
end
|
1212
|
+
end
|
1213
|
+
|
1214
|
+
# Request a Sensu server task election, a process to determine
|
1215
|
+
# if the current process is to be responsible for the task. A
|
1216
|
+
# Redis key/value is used as a central lock, using the "SETNX"
|
1217
|
+
# Redis command to set the key/value if it does not exist, using
|
1218
|
+
# a timestamp for the value. If the current process was able to
|
1219
|
+
# create the key/value, it is elected, and is then responsible
|
1220
|
+
# for the task. If the current process was not able to create
|
1221
|
+
# the key/value, but the current timestamp value is equal to or
|
1222
|
+
# over 30 seconds ago, the "GETSET" Redis command is used to set
|
1223
|
+
# a new timestamp and fetch the previous value to compare them,
|
1224
|
+
# to determine if it was set by the current process. If the
|
1225
|
+
# current process is able to set the timestamp value, it is
|
1226
|
+
# elected. If elected, the current process sets up the task and
|
1227
|
+
# the associated task lock updater.
|
1228
|
+
#
|
1229
|
+
# @param task [String]
|
1230
|
+
# @yield callback/block called either after being elected and
|
1231
|
+
# setting up the task, or after failing to be elected.
|
1232
|
+
def request_task_election(task, &callback)
|
1233
|
+
@redis.setnx("lock:task:#{task}", create_lock_timestamp) do |created|
|
1200
1234
|
if created
|
1201
|
-
|
1235
|
+
setup_task(task, &callback)
|
1236
|
+
setup_task_lock_updater(task)
|
1202
1237
|
else
|
1203
|
-
@redis.get("lock:
|
1238
|
+
@redis.get("lock:task:#{task}") do |current_lock_timestamp|
|
1204
1239
|
new_lock_timestamp = create_lock_timestamp
|
1205
|
-
if new_lock_timestamp - current_lock_timestamp.to_i >=
|
1206
|
-
@redis.getset("lock:
|
1240
|
+
if new_lock_timestamp - current_lock_timestamp.to_i >= 300000000
|
1241
|
+
@redis.getset("lock:task:#{task}", new_lock_timestamp) do |previous_lock_timestamp|
|
1207
1242
|
if previous_lock_timestamp == current_lock_timestamp
|
1208
|
-
|
1243
|
+
setup_task(task, &callback)
|
1244
|
+
setup_task_lock_updater(task)
|
1209
1245
|
end
|
1210
1246
|
end
|
1247
|
+
else
|
1248
|
+
yield if block_given?
|
1211
1249
|
end
|
1212
1250
|
end
|
1213
1251
|
end
|
1214
1252
|
end
|
1215
1253
|
end
|
1216
1254
|
|
1217
|
-
#
|
1218
|
-
#
|
1219
|
-
#
|
1220
|
-
#
|
1221
|
-
#
|
1222
|
-
#
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
if
|
1229
|
-
|
1255
|
+
# Request Sensu server task elections. The task list is ordered
|
1256
|
+
# by prioity. This method works through the task list serially,
|
1257
|
+
# increasing the election request delay as the current process
|
1258
|
+
# becomes responsible for one or more tasks, this is to improve
|
1259
|
+
# the initial distribution of tasks amongst Sensu servers.
|
1260
|
+
#
|
1261
|
+
# @param splay [Integer]
|
1262
|
+
def setup_task_elections(splay=10)
|
1263
|
+
tasks = TASKS.dup - @tasks
|
1264
|
+
next_task = Proc.new do
|
1265
|
+
task = tasks.shift
|
1266
|
+
if task
|
1267
|
+
delay = splay * @tasks.size
|
1268
|
+
@timers[:run] << EM::Timer.new(delay) do
|
1269
|
+
request_task_election(task, &next_task)
|
1270
|
+
end
|
1230
1271
|
else
|
1231
|
-
|
1272
|
+
@timers[:run] << EM::Timer.new(10) do
|
1273
|
+
setup_task_elections(splay)
|
1274
|
+
end
|
1232
1275
|
end
|
1233
1276
|
end
|
1277
|
+
next_task.call
|
1234
1278
|
end
|
1235
1279
|
|
1236
1280
|
# Update the Sensu server registry, stored in Redis. This method
|
1237
1281
|
# adds the local/current Sensu server info to the registry,
|
1238
|
-
# including its id, hostname, address,
|
1239
|
-
#
|
1240
|
-
#
|
1282
|
+
# including its id, hostname, address, its server tasks, and
|
1283
|
+
# some metrics. Sensu server registry entries expire in 30
|
1284
|
+
# seconds unless updated.
|
1241
1285
|
#
|
1242
1286
|
# @yield [success] passes success status to optional
|
1243
1287
|
# callback/block.
|
@@ -1250,13 +1294,19 @@ module Sensu
|
|
1250
1294
|
:id => server_id,
|
1251
1295
|
:hostname => system_hostname,
|
1252
1296
|
:address => system_address,
|
1253
|
-
:
|
1297
|
+
:tasks => @tasks,
|
1254
1298
|
:metrics => {
|
1255
1299
|
:cpu => {
|
1256
1300
|
:user => cpu_user,
|
1257
1301
|
:system => cpu_system
|
1258
1302
|
}
|
1259
1303
|
},
|
1304
|
+
:sensu => {
|
1305
|
+
:version => VERSION,
|
1306
|
+
:settings => {
|
1307
|
+
:hexdigest => @settings.hexdigest
|
1308
|
+
}
|
1309
|
+
},
|
1260
1310
|
:timestamp => Time.now.to_i
|
1261
1311
|
}
|
1262
1312
|
@redis.sadd("servers", server_id)
|
@@ -1304,13 +1354,13 @@ module Sensu
|
|
1304
1354
|
end
|
1305
1355
|
|
1306
1356
|
# Bootstrap the Sensu server process, setting up the keepalive
|
1307
|
-
# and check result consumers, and attemping to
|
1308
|
-
#
|
1309
|
-
#
|
1357
|
+
# and check result consumers, and attemping to carry out Sensu
|
1358
|
+
# server tasks. This method sets the process/daemon `@state` to
|
1359
|
+
# `:running`.
|
1310
1360
|
def bootstrap
|
1311
1361
|
setup_keepalives
|
1312
1362
|
setup_results
|
1313
|
-
|
1363
|
+
setup_task_elections
|
1314
1364
|
setup_server_registry_updater
|
1315
1365
|
@state = :running
|
1316
1366
|
end
|
@@ -1330,8 +1380,8 @@ module Sensu
|
|
1330
1380
|
# set to `:pausing`, to indicate that it's in progress. All run
|
1331
1381
|
# timers are cancelled, and the references are cleared. The
|
1332
1382
|
# Sensu server will unsubscribe from all transport
|
1333
|
-
# subscriptions,
|
1334
|
-
#
|
1383
|
+
# subscriptions, relinquish any Sensu server tasks, then set the
|
1384
|
+
# process/daemon `@state` to `:paused`.
|
1335
1385
|
def pause
|
1336
1386
|
unless @state == :pausing || @state == :paused
|
1337
1387
|
@state = :pausing
|
@@ -1340,7 +1390,7 @@ module Sensu
|
|
1340
1390
|
end
|
1341
1391
|
@timers[:run].clear
|
1342
1392
|
unsubscribe
|
1343
|
-
|
1393
|
+
relinquish_tasks
|
1344
1394
|
@state = :paused
|
1345
1395
|
end
|
1346
1396
|
end
|
data/lib/sensu/utilities.rb
CHANGED
@@ -259,9 +259,10 @@ module Sensu
|
|
259
259
|
#
|
260
260
|
# @param object [Hash]
|
261
261
|
# @param match_attributes [Object]
|
262
|
+
# @param support_eval [TrueClass, FalseClass]
|
262
263
|
# @param object_attributes [Object]
|
263
264
|
# @return [TrueClass, FalseClass]
|
264
|
-
def attributes_match?(object, match_attributes, object_attributes=nil)
|
265
|
+
def attributes_match?(object, match_attributes, support_eval=true, object_attributes=nil)
|
265
266
|
object_attributes ||= object
|
266
267
|
match_attributes.all? do |key, value_one|
|
267
268
|
value_two = object_attributes[key]
|
@@ -269,10 +270,10 @@ module Sensu
|
|
269
270
|
when value_one == value_two
|
270
271
|
true
|
271
272
|
when value_one.is_a?(Hash) && value_two.is_a?(Hash)
|
272
|
-
attributes_match?(object, value_one, value_two)
|
273
|
+
attributes_match?(object, value_one, support_eval, value_two)
|
273
274
|
when value_one.to_s == value_two.to_s
|
274
275
|
true
|
275
|
-
when value_one.is_a?(String) && value_one.start_with?(EVAL_PREFIX)
|
276
|
+
when value_one.is_a?(String) && value_one.start_with?(EVAL_PREFIX) && support_eval
|
276
277
|
eval_attribute_value(object, value_one, value_two)
|
277
278
|
else
|
278
279
|
false
|
data/sensu.gemspec
CHANGED
@@ -15,12 +15,12 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.add_dependency "eventmachine", "1.2.2"
|
16
16
|
s.add_dependency "sensu-json", "2.1.0"
|
17
17
|
s.add_dependency "sensu-logger", "1.2.1"
|
18
|
-
s.add_dependency "sensu-settings", "
|
18
|
+
s.add_dependency "sensu-settings", "10.0.0"
|
19
19
|
s.add_dependency "sensu-extension", "1.5.1"
|
20
|
-
s.add_dependency "sensu-extensions", "1.
|
20
|
+
s.add_dependency "sensu-extensions", "1.9.0"
|
21
21
|
s.add_dependency "sensu-transport", "7.0.2"
|
22
22
|
s.add_dependency "sensu-spawn", "2.2.1"
|
23
|
-
s.add_dependency "sensu-redis", "2.1.
|
23
|
+
s.add_dependency "sensu-redis", "2.1.1"
|
24
24
|
s.add_dependency "em-http-server", "0.1.8"
|
25
25
|
s.add_dependency "parse-cron", "0.1.4"
|
26
26
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.29.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Porter
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-03-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
@@ -59,14 +59,14 @@ dependencies:
|
|
59
59
|
requirements:
|
60
60
|
- - '='
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
62
|
+
version: 10.0.0
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
67
|
- - '='
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
69
|
+
version: 10.0.0
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: sensu-extension
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,14 +87,14 @@ dependencies:
|
|
87
87
|
requirements:
|
88
88
|
- - '='
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: 1.
|
90
|
+
version: 1.9.0
|
91
91
|
type: :runtime
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
95
|
- - '='
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: 1.
|
97
|
+
version: 1.9.0
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: sensu-transport
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,14 +129,14 @@ dependencies:
|
|
129
129
|
requirements:
|
130
130
|
- - '='
|
131
131
|
- !ruby/object:Gem::Version
|
132
|
-
version: 2.1.
|
132
|
+
version: 2.1.1
|
133
133
|
type: :runtime
|
134
134
|
prerelease: false
|
135
135
|
version_requirements: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
137
|
- - '='
|
138
138
|
- !ruby/object:Gem::Version
|
139
|
-
version: 2.1.
|
139
|
+
version: 2.1.1
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
141
|
name: em-http-server
|
142
142
|
requirement: !ruby/object:Gem::Requirement
|
@@ -253,8 +253,10 @@ files:
|
|
253
253
|
- lib/sensu/api/routes/request.rb
|
254
254
|
- lib/sensu/api/routes/resolve.rb
|
255
255
|
- lib/sensu/api/routes/results.rb
|
256
|
+
- lib/sensu/api/routes/settings.rb
|
256
257
|
- lib/sensu/api/routes/silenced.rb
|
257
258
|
- lib/sensu/api/routes/stashes.rb
|
259
|
+
- lib/sensu/api/utilities/filter_response_content.rb
|
258
260
|
- lib/sensu/api/utilities/publish_check_request.rb
|
259
261
|
- lib/sensu/api/utilities/publish_check_result.rb
|
260
262
|
- lib/sensu/api/utilities/resolve_event.rb
|