sensu 0.23.3-java → 0.24.0.beta-java
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +58 -0
- data/lib/sensu/api/process.rb +184 -90
- data/lib/sensu/api/validators.rb +37 -0
- data/lib/sensu/cli.rb +3 -0
- data/lib/sensu/client/process.rb +34 -6
- data/lib/sensu/constants.rb +1 -1
- data/lib/sensu/daemon.rb +67 -30
- data/lib/sensu/server/filter.rb +2 -2
- data/lib/sensu/server/handle.rb +12 -12
- data/lib/sensu/server/mutate.rb +4 -4
- data/lib/sensu/server/process.rb +218 -213
- data/sensu.gemspec +5 -5
- metadata +13 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 922e2887ce2fcb1972a0faa2b87534d2f96ac910
|
4
|
+
data.tar.gz: 6123658a2f976bbbd9f9e9997625927e7eaae47f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b03d9bb20ba265a82404a19e8d6b9e6a8b6b39e3a893cf8ff154a662dd9da4d24910f4a5c9cb3d3342d9633856659d3deae50a6191fa4530a0d91f25a1409af
|
7
|
+
data.tar.gz: d41d20ee9937d8fe7c2f74a4927472c5c3daf743264ccf253231f14129733dd83f54c88c7a387b9224d83719a2f13d8e96708295e8db33678bd0163d6994027c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,61 @@
|
|
1
|
+
## 0.24.0 - TBD
|
2
|
+
|
3
|
+
### Important
|
4
|
+
|
5
|
+
Sensu check ["Aggregates 2.0"](https://github.com/sensu/sensu/issues/1218)
|
6
|
+
breaks the existing Sensu API aggregate endpoints.
|
7
|
+
|
8
|
+
Sensu API GET /health endpoint, failed health checks now respond with a
|
9
|
+
`412` (preconditions failed) instead of a `503`.
|
10
|
+
|
11
|
+
### Features
|
12
|
+
|
13
|
+
Persistent Sensu event IDs, event occurrences for a client/check pair will
|
14
|
+
now have the same event ID until the event is resolved.
|
15
|
+
|
16
|
+
Added a CLI option/argument to cause the Sensu service to validate its
|
17
|
+
compiled configuration settings and exit with the appropriate exit
|
18
|
+
code, e.g. `2` for invalid. The CLI option is `--validate_config`. This
|
19
|
+
feature is now used when restarting a Sensu service to first validate the
|
20
|
+
new configuration before stopping the running service.
|
21
|
+
|
22
|
+
Improved tracking of in progress check result processing, no longer
|
23
|
+
potentially losing check results when restarting the Sensu server service.
|
24
|
+
|
25
|
+
Event data check type now explicitly defaults to "standard".
|
26
|
+
|
27
|
+
Check results for proxy clients (a.k.a JIT clients) will now have a check
|
28
|
+
"origin" set to the client name of the result producer.
|
29
|
+
|
30
|
+
Configurable Sensu Spawn concurrent child process limit (checks, mutators,
|
31
|
+
& pipe handlers). The default limit is still `12` and the EventMachine
|
32
|
+
threadpool size is automatically adjusted to accommodate a larger limit.
|
33
|
+
|
34
|
+
Sensu check ["Aggregates 2.0"](https://github.com/sensu/sensu/issues/1218).
|
35
|
+
|
36
|
+
Sensu client token substitution is now supported in every check definition
|
37
|
+
attribute value, no longer just the check command.
|
38
|
+
|
39
|
+
### Other
|
40
|
+
|
41
|
+
Sensu API GET /health endpoint, failed health check now responds with a
|
42
|
+
`412` (preconditions failed) instead of a `503`.
|
43
|
+
|
44
|
+
Sensu API POST /clients endpoint can now create clients in the registry
|
45
|
+
that are expected to produce keepalives, and validates clients with the
|
46
|
+
Sensu Settings client definition validator.
|
47
|
+
|
48
|
+
Updated Thin (used by Sensu API) to the latest version, 1.6.4.
|
49
|
+
|
50
|
+
JrJackson is now used to parse JSON when Sensu is running on JRuby.
|
51
|
+
|
52
|
+
The Sensu API now listens immediately on service start, even before it has
|
53
|
+
successfully connected to Redis and the Sensu Transport. It will now
|
54
|
+
respond with a `500` response, with a descriptive error message, when it
|
55
|
+
has not yet initialized its connections or it is reconnecting to either
|
56
|
+
Redis or the Sensu Transport. The API /info and /health endpoints will
|
57
|
+
still respond normally while reconnecting.
|
58
|
+
|
1
59
|
## 0.23.3 - 2016-05-26
|
2
60
|
|
3
61
|
### Fixes
|
data/lib/sensu/api/process.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
require "sensu/daemon"
|
2
|
+
require "sensu/api/validators"
|
2
3
|
|
3
4
|
gem "sinatra", "1.4.6"
|
4
5
|
gem "async_sinatra", "1.2.0"
|
5
6
|
|
6
7
|
unless RUBY_PLATFORM =~ /java/
|
7
|
-
gem "thin", "1.6.
|
8
|
+
gem "thin", "1.6.4"
|
8
9
|
require "thin"
|
9
10
|
end
|
10
11
|
|
@@ -22,10 +23,9 @@ module Sensu
|
|
22
23
|
bootstrap(options)
|
23
24
|
setup_process(options)
|
24
25
|
EM::run do
|
25
|
-
setup_connections
|
26
|
-
|
27
|
-
|
28
|
-
end
|
26
|
+
setup_connections
|
27
|
+
start
|
28
|
+
setup_signal_traps
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -84,8 +84,8 @@ module Sensu
|
|
84
84
|
def stop
|
85
85
|
@logger.warn("stopping")
|
86
86
|
stop_server do
|
87
|
-
settings.redis.close if settings.redis
|
88
|
-
settings.transport.close if settings.transport
|
87
|
+
settings.redis.close if settings.respond_to?(:redis)
|
88
|
+
settings.transport.close if settings.respond_to?(:transport)
|
89
89
|
super
|
90
90
|
end
|
91
91
|
end
|
@@ -124,11 +124,18 @@ module Sensu
|
|
124
124
|
env["rack.input"].rewind
|
125
125
|
end
|
126
126
|
|
127
|
-
def
|
128
|
-
if settings.
|
129
|
-
|
130
|
-
|
131
|
-
|
127
|
+
def connected?
|
128
|
+
if settings.respond_to?(:redis) && settings.respond_to?(:transport)
|
129
|
+
unless ["/info", "/health"].include?(env["REQUEST_PATH"])
|
130
|
+
unless settings.redis.connected?
|
131
|
+
not_connected!("not connected to redis")
|
132
|
+
end
|
133
|
+
unless settings.transport.connected?
|
134
|
+
not_connected!("not connected to transport")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
else
|
138
|
+
not_connected!("redis and transport connections not initialized")
|
132
139
|
end
|
133
140
|
end
|
134
141
|
|
@@ -140,6 +147,22 @@ module Sensu
|
|
140
147
|
@auth.credentials == [settings.api[:user], settings.api[:password]]
|
141
148
|
end
|
142
149
|
|
150
|
+
def protected!
|
151
|
+
if settings.api[:user] && settings.api[:password]
|
152
|
+
return if authorized?
|
153
|
+
headers["WWW-Authenticate"] = 'Basic realm="Restricted Area"'
|
154
|
+
unauthorized!
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def error!(body="")
|
159
|
+
throw(:halt, [500, body])
|
160
|
+
end
|
161
|
+
|
162
|
+
def not_connected!(message)
|
163
|
+
error!(Sensu::JSON.dump(:error => message))
|
164
|
+
end
|
165
|
+
|
143
166
|
def bad_request!
|
144
167
|
ahalt 400
|
145
168
|
end
|
@@ -152,8 +175,8 @@ module Sensu
|
|
152
175
|
ahalt 404
|
153
176
|
end
|
154
177
|
|
155
|
-
def
|
156
|
-
ahalt
|
178
|
+
def precondition_failed!
|
179
|
+
ahalt 412
|
157
180
|
end
|
158
181
|
|
159
182
|
def created!(response)
|
@@ -306,6 +329,7 @@ module Sensu
|
|
306
329
|
settings.cors.each do |header, value|
|
307
330
|
headers["Access-Control-Allow-#{header}"] = value
|
308
331
|
end
|
332
|
+
connected?
|
309
333
|
protected! unless env["REQUEST_METHOD"] == "OPTIONS"
|
310
334
|
end
|
311
335
|
|
@@ -342,27 +366,27 @@ module Sensu
|
|
342
366
|
healthy << (info[:keepalives][:messages] <= max_messages)
|
343
367
|
healthy << (info[:results][:messages] <= max_messages)
|
344
368
|
end
|
345
|
-
healthy.all? ? no_content! :
|
369
|
+
healthy.all? ? no_content! : precondition_failed!
|
346
370
|
end
|
347
371
|
else
|
348
|
-
|
372
|
+
precondition_failed!
|
349
373
|
end
|
350
374
|
end
|
351
375
|
|
352
376
|
apost "/clients/?" do
|
353
|
-
|
354
|
-
:
|
355
|
-
:address => {:type => String, :nil_ok => false},
|
356
|
-
:subscriptions => {:type => Array, :nil_ok => false}
|
357
|
-
}
|
358
|
-
read_data(rules) do |data|
|
359
|
-
data[:keepalives] = false
|
377
|
+
read_data do |data|
|
378
|
+
data[:keepalives] = data.fetch(:keepalives, false)
|
360
379
|
data[:version] = VERSION
|
361
380
|
data[:timestamp] = Time.now.to_i
|
362
|
-
|
363
|
-
|
364
|
-
|
381
|
+
validator = Validators::Client.new
|
382
|
+
if validator.valid?(data)
|
383
|
+
settings.redis.set("client:#{data[:name]}", Sensu::JSON.dump(data)) do
|
384
|
+
settings.redis.sadd("clients", data[:name]) do
|
385
|
+
created!(Sensu::JSON.dump(:name => data[:name]))
|
386
|
+
end
|
365
387
|
end
|
388
|
+
else
|
389
|
+
bad_request!
|
366
390
|
end
|
367
391
|
end
|
368
392
|
end
|
@@ -582,102 +606,172 @@ module Sensu
|
|
582
606
|
end
|
583
607
|
|
584
608
|
aget "/aggregates/?" do
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
609
|
+
settings.redis.smembers("aggregates") do |aggregates|
|
610
|
+
aggregates.map! do |aggregate|
|
611
|
+
{:name => aggregate}
|
612
|
+
end
|
613
|
+
body Sensu::JSON.dump(aggregates)
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
aget %r{^/aggregates/([\w\.-]+)/?$} do |aggregate|
|
618
|
+
response = {
|
619
|
+
:clients => 0,
|
620
|
+
:checks => 0,
|
621
|
+
:results => {
|
622
|
+
:ok => 0,
|
623
|
+
:warning => 0,
|
624
|
+
:critical => 0,
|
625
|
+
:unknown => 0,
|
626
|
+
:total => 0,
|
627
|
+
:stale => 0
|
628
|
+
}
|
629
|
+
}
|
630
|
+
settings.redis.smembers("aggregates:#{aggregate}") do |aggregate_members|
|
631
|
+
unless aggregate_members.empty?
|
632
|
+
clients = []
|
633
|
+
checks = []
|
634
|
+
results = []
|
635
|
+
aggregate_members.each_with_index do |member, index|
|
636
|
+
client_name, check_name = member.split(":")
|
637
|
+
clients << client_name
|
638
|
+
checks << check_name
|
639
|
+
result_key = "result:#{client_name}:#{check_name}"
|
640
|
+
settings.redis.get(result_key) do |result_json|
|
641
|
+
unless result_json.nil?
|
642
|
+
results << Sensu::JSON.load(result_json)
|
643
|
+
else
|
644
|
+
settings.redis.srem("aggregates:#{aggregate}", member)
|
593
645
|
end
|
594
|
-
|
595
|
-
:
|
596
|
-
:
|
597
|
-
|
598
|
-
|
599
|
-
|
646
|
+
if index == aggregate_members.length - 1
|
647
|
+
response[:clients] = clients.uniq.length
|
648
|
+
response[:checks] = checks.uniq.length
|
649
|
+
max_age = integer_parameter(params[:max_age])
|
650
|
+
if max_age
|
651
|
+
result_count = results.length
|
652
|
+
timestamp = Time.now.to_i - max_age
|
653
|
+
results.reject! do |result|
|
654
|
+
result[:executed] < timestamp
|
655
|
+
end
|
656
|
+
response[:results][:stale] = result_count - results.length
|
657
|
+
end
|
658
|
+
response[:results][:total] = results.length
|
659
|
+
results.each do |result|
|
660
|
+
severity = (SEVERITIES[result[:status]] || "unknown")
|
661
|
+
response[:results][severity.to_sym] += 1
|
662
|
+
end
|
600
663
|
body Sensu::JSON.dump(response)
|
601
664
|
end
|
602
665
|
end
|
603
666
|
end
|
604
667
|
else
|
605
|
-
|
668
|
+
not_found!
|
606
669
|
end
|
607
670
|
end
|
608
671
|
end
|
609
672
|
|
610
|
-
|
611
|
-
settings.redis.smembers("aggregates
|
612
|
-
|
613
|
-
aggregates
|
614
|
-
|
615
|
-
|
616
|
-
end
|
617
|
-
age = integer_parameter(params[:age])
|
618
|
-
if age
|
619
|
-
timestamp = Time.now.to_i - age
|
620
|
-
aggregates.reject! do |issued|
|
621
|
-
issued > timestamp
|
673
|
+
adelete %r{^/aggregates/([\w\.-]+)/?$} do |aggregate|
|
674
|
+
settings.redis.smembers("aggregates") do |aggregates|
|
675
|
+
if aggregates.include?(aggregate)
|
676
|
+
settings.redis.srem("aggregates", aggregate) do
|
677
|
+
settings.redis.del("aggregates:#{aggregate}") do
|
678
|
+
no_content!
|
622
679
|
end
|
623
680
|
end
|
624
|
-
body Sensu::JSON.dump(pagination(aggregates))
|
625
681
|
else
|
626
682
|
not_found!
|
627
683
|
end
|
628
684
|
end
|
629
685
|
end
|
630
686
|
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
687
|
+
aget %r{^/aggregates/([\w\.-]+)/clients/?$} do |aggregate|
|
688
|
+
response = Array.new
|
689
|
+
settings.redis.smembers("aggregates:#{aggregate}") do |aggregate_members|
|
690
|
+
unless aggregate_members.empty?
|
691
|
+
clients = Hash.new
|
692
|
+
aggregate_members.each do |member|
|
693
|
+
client_name, check_name = member.split(":")
|
694
|
+
clients[client_name] ||= []
|
695
|
+
clients[client_name] << check_name
|
638
696
|
end
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
697
|
+
clients.each do |client_name, checks|
|
698
|
+
response << {
|
699
|
+
:name => client_name,
|
700
|
+
:checks => checks
|
701
|
+
}
|
643
702
|
end
|
703
|
+
body Sensu::JSON.dump(response)
|
644
704
|
else
|
645
705
|
not_found!
|
646
706
|
end
|
647
707
|
end
|
648
708
|
end
|
649
709
|
|
650
|
-
aget %r{^/aggregates
|
651
|
-
|
652
|
-
settings.redis.
|
653
|
-
unless
|
654
|
-
|
655
|
-
|
656
|
-
|
710
|
+
aget %r{^/aggregates/([\w\.-]+)/checks/?$} do |aggregate|
|
711
|
+
response = Array.new
|
712
|
+
settings.redis.smembers("aggregates:#{aggregate}") do |aggregate_members|
|
713
|
+
unless aggregate_members.empty?
|
714
|
+
checks = Hash.new
|
715
|
+
aggregate_members.each do |member|
|
716
|
+
client_name, check_name = member.split(":")
|
717
|
+
checks[check_name] ||= []
|
718
|
+
checks[check_name] << client_name
|
657
719
|
end
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
720
|
+
checks.each do |check_name, clients|
|
721
|
+
response << {
|
722
|
+
:name => check_name,
|
723
|
+
:clients => clients
|
724
|
+
}
|
725
|
+
end
|
726
|
+
body Sensu::JSON.dump(response)
|
727
|
+
else
|
728
|
+
not_found!
|
729
|
+
end
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
aget %r{^/aggregates/([\w\.-]+)/results/([\w\.-]+)/?$} do |aggregate, severity|
|
734
|
+
response = Array.new
|
735
|
+
if SEVERITIES.include?(severity)
|
736
|
+
settings.redis.smembers("aggregates:#{aggregate}") do |aggregate_members|
|
737
|
+
unless aggregate_members.empty?
|
738
|
+
summaries = Hash.new
|
739
|
+
max_age = integer_parameter(params[:max_age])
|
740
|
+
current_timestamp = Time.now.to_i
|
741
|
+
aggregate_members.each_with_index do |member, index|
|
742
|
+
client_name, check_name = member.split(":")
|
743
|
+
result_key = "result:#{client_name}:#{check_name}"
|
744
|
+
settings.redis.get(result_key) do |result_json|
|
745
|
+
unless result_json.nil?
|
746
|
+
result = Sensu::JSON.load(result_json)
|
747
|
+
if SEVERITIES[result[:status]] == severity &&
|
748
|
+
(max_age.nil? || result[:executed] >= (current_timestamp - max_age))
|
749
|
+
summaries[check_name] ||= {}
|
750
|
+
summaries[check_name][result[:output]] ||= {:total => 0, :clients => []}
|
751
|
+
summaries[check_name][result[:output]][:total] += 1
|
752
|
+
summaries[check_name][result[:output]][:clients] << client_name
|
753
|
+
end
|
754
|
+
end
|
755
|
+
if index == aggregate_members.length - 1
|
756
|
+
summaries.each do |check_name, outputs|
|
757
|
+
summary = outputs.map do |output, output_summary|
|
758
|
+
{:output => output}.merge(output_summary)
|
759
|
+
end
|
760
|
+
response << {
|
761
|
+
:check => check_name,
|
762
|
+
:summary => summary
|
763
|
+
}
|
764
|
+
end
|
765
|
+
body Sensu::JSON.dump(response)
|
669
766
|
end
|
670
|
-
response[:outputs] = outputs
|
671
767
|
end
|
672
768
|
end
|
673
|
-
|
674
|
-
|
675
|
-
end
|
676
|
-
body Sensu::JSON.dump(response)
|
769
|
+
else
|
770
|
+
not_found!
|
677
771
|
end
|
678
|
-
else
|
679
|
-
not_found!
|
680
772
|
end
|
773
|
+
else
|
774
|
+
bad_request!
|
681
775
|
end
|
682
776
|
end
|
683
777
|
|