sensu 0.23.3-java → 0.24.0.beta-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9f197ec03894f0815699318f4128a805ac1a9441
4
- data.tar.gz: 3964f6784af42fcf1f5084f386f776b850602eb1
3
+ metadata.gz: 922e2887ce2fcb1972a0faa2b87534d2f96ac910
4
+ data.tar.gz: 6123658a2f976bbbd9f9e9997625927e7eaae47f
5
5
  SHA512:
6
- metadata.gz: 5d5d12a58075b3be711fe37ee87f05c87c54909c81bb90fc6cc9e26db6d2dac107097e5ce87e7d7ff284c3a6c8f297dd2e15ae33d707b0a2aa27d86cccdd35b4
7
- data.tar.gz: a9414e45ee80bc22632b470eb464e3a312716b10774003406d14453f548a25fc3420db3a44f6090b31bf16b22018e26c04107cef722cd79b764d1ab3f0bf92b5
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
@@ -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.3"
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 do
26
- start
27
- setup_signal_traps
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 protected!
128
- if settings.api[:user] && settings.api[:password]
129
- return if !(settings.api[:user] && settings.api[:password]) || authorized?
130
- headers["WWW-Authenticate"] = 'Basic realm="Restricted Area"'
131
- unauthorized!
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 unavailable!
156
- ahalt 503
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! : unavailable!
369
+ healthy.all? ? no_content! : precondition_failed!
346
370
  end
347
371
  else
348
- unavailable!
372
+ precondition_failed!
349
373
  end
350
374
  end
351
375
 
352
376
  apost "/clients/?" do
353
- rules = {
354
- :name => {:type => String, :nil_ok => false, :regex => /\A[\w\.-]+\z/},
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
- settings.redis.set("client:#{data[:name]}", Sensu::JSON.dump(data)) do
363
- settings.redis.sadd("clients", data[:name]) do
364
- created!(Sensu::JSON.dump(:name => data[:name]))
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
- response = Array.new
586
- settings.redis.smembers("aggregates") do |checks|
587
- unless checks.empty?
588
- checks.each_with_index do |check_name, index|
589
- settings.redis.smembers("aggregates:#{check_name}") do |aggregates|
590
- aggregates.reverse!
591
- aggregates.map! do |issued|
592
- issued.to_i
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
- item = {
595
- :check => check_name,
596
- :issued => aggregates
597
- }
598
- response << item
599
- if index == checks.length - 1
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
- body Sensu::JSON.dump(response)
668
+ not_found!
606
669
  end
607
670
  end
608
671
  end
609
672
 
610
- aget %r{^/aggregates/([\w\.-]+)/?$} do |check_name|
611
- settings.redis.smembers("aggregates:#{check_name}") do |aggregates|
612
- unless aggregates.empty?
613
- aggregates.reverse!
614
- aggregates.map! do |issued|
615
- issued.to_i
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
- adelete %r{^/aggregates/([\w\.-]+)/?$} do |check_name|
632
- settings.redis.smembers("aggregates:#{check_name}") do |aggregates|
633
- unless aggregates.empty?
634
- aggregates.each do |check_issued|
635
- result_set = "#{check_name}:#{check_issued}"
636
- settings.redis.del("aggregation:#{result_set}")
637
- settings.redis.del("aggregate:#{result_set}")
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
- settings.redis.del("aggregates:#{check_name}") do
640
- settings.redis.srem("aggregates", check_name) do
641
- no_content!
642
- end
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?/([\w\.-]+)/([\w\.-]+)/?$} do |check_name, check_issued|
651
- result_set = "#{check_name}:#{check_issued}"
652
- settings.redis.hgetall("aggregate:#{result_set}") do |aggregate|
653
- unless aggregate.empty?
654
- response = aggregate.inject(Hash.new) do |totals, (status, count)|
655
- totals[status] = Integer(count)
656
- totals
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
- settings.redis.hgetall("aggregation:#{result_set}") do |results|
659
- parsed_results = results.inject(Array.new) do |parsed, (client_name, check_json)|
660
- check = Sensu::JSON.load(check_json)
661
- parsed << check.merge(:client => client_name)
662
- end
663
- if params[:summarize]
664
- options = params[:summarize].split(",")
665
- if options.include?("output")
666
- outputs = Hash.new(0)
667
- parsed_results.each do |result|
668
- outputs[result[:output]] += 1
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
- if params[:results]
674
- response[:results] = parsed_results
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