sensu 0.20.6 → 0.21.0

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: 8db94deef76774c21c9200b21055c0cedc6c1907
4
- data.tar.gz: 067c5f4dedbb6315d62c77a1dbe769bd18b6442d
3
+ metadata.gz: e7241998f1b395c09ed021c94e1391de71b1a1b3
4
+ data.tar.gz: 8ed7240bf31290a27826d17584a6e13f3ebe1e56
5
5
  SHA512:
6
- metadata.gz: 0a620e6977eabe3657cfa23409f5732fe9d7a79985752290eafd939b5f0966b3885ded2d47c14c9a9ade611a464cd9ff483fa8f79e14d5ccdd64ddb124c7b01a
7
- data.tar.gz: 4d40cdcb998419822642090121c34aded2a47e7c094c4b084516ff0ad7893701ff0598cdaa6a0a5c4922bf686b099086bb9db7f3e739d52a11d7d090fd86a085
6
+ metadata.gz: 46e0e42fb84c441414534f9f40fd2074cc90ee66964ebef97c72184b2af6c034244686f89d914ef21b70c527638dac7163f2e2049d760f28ef807152d8400dea
7
+ data.tar.gz: f9effb8a3907bf25952761c07a058e2df972c43454fe1256086e5c41e11266e4736e9c0a454d70934b00acb55499192632245096764314c968b6e4412f39ad97
@@ -1,7 +1,56 @@
1
+ ## 0.21.0 - 2015-11-13
2
+
3
+ ### Features
4
+
5
+ Added a Sensu plugin installation tool, `sensu-install`, making it easier
6
+ to install Sensu community plugins. The `sensu-install` tool will use the
7
+ appropriate Ruby when installing plugins. The tool aims to produce verbose
8
+ and useful output to help when debugging plugin installation issues.
9
+
10
+ Added the Sensu API DELETE /results/:client/:check endpoint, supporting
11
+ check result deletion via the Sensu API. This feature allows users to
12
+ clean up "stale" check result data for checks that have been removed.
13
+
14
+ Added the Sensu API POST /results endpoint, supporting check result input
15
+ via the Sensu API. The JIT client feature added in 0.20 enabled this
16
+ functionality. Services that do not have access to a local Sensu client
17
+ socket can make use of this feature.
18
+
19
+ ### Other
20
+
21
+ Improved the Sensu test suite to reduce the number of timeout triggered
22
+ failures. These changes make Sensu development much more pleasant.
23
+
24
+ Fixed a few inline documentation typos, e.g. sbuded -> subdued.
25
+
26
+ Moved the Sensu bins (e.g. `sensu-client`) from `bin` to `exe` to avoid
27
+ the conflict with Ruby bundler bin stubs.
28
+
29
+ Fixed Sensu API and client socket input validation, no longer accepting
30
+ multi-line values.
31
+
32
+ Fixed check request publishing for checks that make use of check
33
+ extensions, e.g. `"extension": "check_http_endpoints`.
34
+
35
+ Fixed the handler `"filters"` bug that caused Sensu to mutate handler
36
+ definitions, removing filters for successive executions.
37
+
38
+ Fixed Sensu API POST /request endpoint check request publishing to
39
+ round-robin client subscriptions.
40
+
41
+ Fixed the Windows job handle leak when spawning processes for checks.
42
+
43
+ Updated the Redis client library (em-redis-unified) to remove duplicate
44
+ Ruby hash key warnings.
45
+
1
46
  ## 0.20.6 - 2015-09-22
2
47
 
3
48
  ### Other
4
49
 
50
+ Removed the use of `EM::Iterator` from event filtering, replacing it with
51
+ `Proc` and `EM::next_tick`. `EM::Iterator` creates anonymous classes that
52
+ cannot be garbage collected on JRuby.
53
+
5
54
  Removed sensu-em as a dependency, now using upstream EventMachine 1.0.8.
6
55
 
7
56
  The Sensu API will remove a client immediately if there are no current
File without changes
File without changes
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "optparse"
4
+
5
+ module Sensu
6
+ class Install
7
+ class << self
8
+ def cli_options(arguments=ARGV)
9
+ options = {
10
+ :verbose => false,
11
+ :plugins => []
12
+ }
13
+ optparse = OptionParser.new do |opts|
14
+ opts.on("-h", "--help", "Display this message") do
15
+ puts opts
16
+ exit
17
+ end
18
+ opts.on("-v", "--verbose", "Enable verbose logging") do
19
+ options[:verbose] = true
20
+ end
21
+ opts.on("-p", "--plugin PLUGIN", "Install a Sensu PLUGIN") do |plugin|
22
+ options[:plugins] << plugin
23
+ end
24
+ opts.on("-P", "--plugins PLUGIN[,PLUGIN]", "PLUGIN or comma-delimited list of Sensu plugins to install") do |plugins|
25
+ options[:plugins].concat(plugins.split(","))
26
+ end
27
+ opts.on("-s", "--source SOURCE", "Install Sensu plugins from a custom SOURCE") do |source|
28
+ options[:source] = source
29
+ end
30
+ end
31
+ optparse.parse!(arguments)
32
+ options
33
+ end
34
+
35
+ def log(message)
36
+ puts "[SENSU-INSTALL] #{message}"
37
+ end
38
+
39
+ def install_plugins(plugins, options={})
40
+ log "installing Sensu plugins ..."
41
+ log "provided Sensu plugins: #{plugins}" if options[:verbose]
42
+ gems = plugins.map do |plugin|
43
+ if plugin.start_with?("sensu-plugins-")
44
+ plugin
45
+ else
46
+ "sensu-plugins-#{plugin}"
47
+ end
48
+ end
49
+ log "Sensu plugin gems to be installed: #{gems}" if options[:verbose]
50
+ gem_options = "--no-ri --no-rdoc"
51
+ gem_options << " --verbose" if options[:verbose]
52
+ gem_options << " --source #{options[:source]}" if options[:source]
53
+ gems.each do |gem|
54
+ log "installing Sensu plugin gem: #{gem}"
55
+ gem_command = "gem install #{gem} #{gem_options}"
56
+ log gem_command if options[:verbose]
57
+ unless system(gem_command)
58
+ log "failed to install Sensu plugin gem: #{gem}"
59
+ log "you can run the sensu-install command again with --verbose for more info" unless options[:verbose]
60
+ log "please take note of any failure messages above"
61
+ log "make sure you have build tools installed (e.g. gcc)"
62
+ log "trying to determine Sensu plugin homepage for #{gem} ..."
63
+ clean_gem = gem.split(":").first
64
+ system("gem specification #{clean_gem} -r | grep homepage")
65
+ exit 2
66
+ end
67
+ end
68
+ log "successfully install Sensu plugins: #{plugins}"
69
+ end
70
+
71
+ def run
72
+ options = cli_options
73
+ unless options[:plugins].empty?
74
+ install_plugins(options[:plugins], options)
75
+ else
76
+ log "nothing to do"
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ Sensu::Install.run
File without changes
@@ -177,7 +177,8 @@ module Sensu
177
177
  valid = rules.all? do |key, rule|
178
178
  value = data[key]
179
179
  (value.is_a?(rule[:type]) || (rule[:nil_ok] && value.nil?)) &&
180
- rule[:regex].nil? || (rule[:regex] && (value =~ rule[:regex]) == 0)
180
+ (value.nil? || rule[:regex].nil?) ||
181
+ (rule[:regex] && (value =~ rule[:regex]) == 0)
181
182
  end
182
183
  if valid
183
184
  callback.call(data)
@@ -190,7 +191,7 @@ module Sensu
190
191
  end
191
192
 
192
193
  def integer_parameter(parameter)
193
- parameter =~ /^[0-9]+$/ ? parameter.to_i : nil
194
+ parameter =~ /\A[0-9]+\z/ ? parameter.to_i : nil
194
195
  end
195
196
 
196
197
  def pagination(items)
@@ -234,18 +235,12 @@ module Sensu
234
235
  end
235
236
  end
236
237
 
237
- def resolve_event(event_json)
238
- event = MultiJson.load(event_json)
239
- check = event[:check].merge(
240
- :output => "Resolving on request of the API",
241
- :status => 0,
242
- :issued => Time.now.to_i,
243
- :executed => Time.now.to_i,
244
- :force_resolve => true
245
- )
246
- check.delete(:history)
238
+ def publish_check_result(client_name, check)
239
+ check[:issued] = Time.now.to_i
240
+ check[:executed] = Time.now.to_i
241
+ check[:status] ||= 0
247
242
  payload = {
248
- :client => event[:client][:name],
243
+ :client => client_name,
249
244
  :check => check
250
245
  }
251
246
  settings.logger.info("publishing check result", :payload => payload)
@@ -258,6 +253,47 @@ module Sensu
258
253
  end
259
254
  end
260
255
  end
256
+
257
+ def resolve_event(event_json)
258
+ event = MultiJson.load(event_json)
259
+ check = event[:check].merge(
260
+ :output => "Resolving on request of the API",
261
+ :status => 0,
262
+ :force_resolve => true
263
+ )
264
+ check.delete(:history)
265
+ publish_check_result(event[:client][:name], check)
266
+ end
267
+
268
+ def transport_publish_options(subscription, message)
269
+ _, raw_type = subscription.split(":", 2).reverse
270
+ case raw_type
271
+ when "direct", "roundrobin"
272
+ [:direct, subscription, message]
273
+ else
274
+ [:fanout, subscription, message]
275
+ end
276
+ end
277
+
278
+ def publish_check_request(check)
279
+ payload = check.merge(:issued => Time.now.to_i)
280
+ settings.logger.info("publishing check request", {
281
+ :payload => payload,
282
+ :subscribers => check[:subscribers]
283
+ })
284
+ check[:subscribers].each do |subscription|
285
+ options = transport_publish_options(subscription.to_s, MultiJson.dump(payload))
286
+ settings.transport.publish(*options) do |info|
287
+ if info[:error]
288
+ settings.logger.error("failed to publish check request", {
289
+ :subscription => subscription,
290
+ :payload => payload,
291
+ :error => info[:error].to_s
292
+ })
293
+ end
294
+ end
295
+ end
296
+ end
261
297
  end
262
298
 
263
299
  before do
@@ -311,7 +347,7 @@ module Sensu
311
347
 
312
348
  apost "/clients/?" do
313
349
  rules = {
314
- :name => {:type => String, :nil_ok => false, :regex => /^[\w\.-]+$/},
350
+ :name => {:type => String, :nil_ok => false, :regex => /\A[\w\.-]+\z/},
315
351
  :address => {:type => String, :nil_ok => false},
316
352
  :subscriptions => {:type => Array, :nil_ok => false}
317
353
  }
@@ -459,28 +495,11 @@ module Sensu
459
495
  }
460
496
  read_data(rules) do |data|
461
497
  if settings.checks[data[:check]]
462
- check = settings.checks[data[:check]]
463
- subscribers = data[:subscribers] || check[:subscribers] || Array.new
464
- payload = {
465
- :name => data[:check],
466
- :command => check[:command],
467
- :issued => Time.now.to_i
468
- }
469
- settings.logger.info("publishing check request", {
470
- :payload => payload,
471
- :subscribers => subscribers
472
- })
473
- subscribers.uniq.each do |exchange_name|
474
- settings.transport.publish(:fanout, exchange_name.to_s, MultiJson.dump(payload)) do |info|
475
- if info[:error]
476
- settings.logger.error("failed to publish check request", {
477
- :exchange_name => exchange_name,
478
- :payload => payload,
479
- :error => info[:error].to_s
480
- })
481
- end
482
- end
483
- end
498
+ check = settings.checks[data[:check]].dup
499
+ check[:name] = data[:check]
500
+ check[:subscribers] ||= Array.new
501
+ check[:subscribers] = data[:subscribers] if data[:subscribers]
502
+ publish_check_request(check)
484
503
  issued!
485
504
  else
486
505
  not_found!
@@ -743,6 +762,19 @@ module Sensu
743
762
  end
744
763
  end
745
764
 
765
+ apost "/results/?" do
766
+ rules = {
767
+ :name => {:type => String, :nil_ok => false, :regex => /\A[\w\.-]+\z/},
768
+ :output => {:type => String, :nil_ok => false},
769
+ :status => {:type => Integer, :nil_ok => true},
770
+ :source => {:type => String, :nil_ok => true, :regex => /\A[\w\.-]+\z/}
771
+ }
772
+ read_data(rules) do |data|
773
+ publish_check_result("sensu-api", data)
774
+ issued!
775
+ end
776
+ end
777
+
746
778
  aget "/results/?" do
747
779
  response = Array.new
748
780
  settings.redis.smembers("clients") do |clients|
@@ -807,6 +839,21 @@ module Sensu
807
839
  end
808
840
  end
809
841
  end
842
+
843
+ adelete %r{^/results?/([\w\.-]+)/([\w\.-]+)/?$} do |client_name, check_name|
844
+ result_key = "result:#{client_name}:#{check_name}"
845
+ settings.redis.exists(result_key) do |result_exists|
846
+ if result_exists
847
+ settings.redis.srem("result:#{client_name}", check_name) do
848
+ settings.redis.del(result_key) do |result_json|
849
+ no_content!
850
+ end
851
+ end
852
+ else
853
+ not_found!
854
+ end
855
+ end
856
+ end
810
857
  end
811
858
  end
812
859
  end
@@ -116,10 +116,10 @@ module Sensu
116
116
  #
117
117
  # @param [Hash] check result to validate.
118
118
  def validate_check_result(check)
119
- unless check[:name] =~ /^[\w\.-]+$/
119
+ unless check[:name] =~ /\A[\w\.-]+\z/
120
120
  raise DataError, "check name must be a string and cannot contain spaces or special characters"
121
121
  end
122
- unless check[:source].nil? || check[:source] =~ /^[\w\.-]+$/
122
+ unless check[:source].nil? || check[:source] =~ /\A[\w\.-]+\z/
123
123
  raise DataError, "check source must be a string and cannot contain spaces or special characters"
124
124
  end
125
125
  unless check[:output].is_a?(String)
@@ -1,7 +1,7 @@
1
1
  module Sensu
2
2
  unless defined?(Sensu::VERSION)
3
3
  # Sensu release version.
4
- VERSION = "0.20.6"
4
+ VERSION = "0.21.0"
5
5
 
6
6
  # Sensu check severities.
7
7
  SEVERITIES = %w[ok warning critical unknown]
@@ -5,10 +5,10 @@ gem "eventmachine", "1.0.8"
5
5
 
6
6
  gem "sensu-logger", "1.1.0"
7
7
  gem "sensu-settings", "3.1.0"
8
- gem "sensu-extension", "1.2.0"
9
- gem "sensu-extensions", "1.3.0"
8
+ gem "sensu-extension", "1.3.0"
9
+ gem "sensu-extensions", "1.4.0"
10
10
  gem "sensu-transport", "3.3.0"
11
- gem "sensu-spawn", "1.5.0"
11
+ gem "sensu-spawn", "1.6.0"
12
12
 
13
13
  require "time"
14
14
  require "uri"
@@ -1,4 +1,4 @@
1
- gem "em-redis-unified", "1.0.0"
1
+ gem "em-redis-unified", "1.0.1"
2
2
 
3
3
  require "em-redis-unified"
4
4
 
@@ -179,7 +179,7 @@ module Sensu
179
179
  # @return [TrueClass, FalseClass]
180
180
  def eval_attribute_value(raw_eval_string, value)
181
181
  begin
182
- eval_string = raw_eval_string.gsub(/^eval:(\s+)?/, "")
182
+ eval_string = raw_eval_string.gsub(/\Aeval:(\s+)?/, "")
183
183
  !!Sandbox.eval(eval_string, value)
184
184
  rescue => error
185
185
  @logger.error("filter attribute eval error", {
@@ -258,7 +258,7 @@ module Sensu
258
258
  # @param callback [Proc]
259
259
  def event_filtered?(handler, event, &callback)
260
260
  if handler.has_key?(:filters) || handler.has_key?(:filter)
261
- filter_list = Array(handler[:filters] || handler[:filter])
261
+ filter_list = Array(handler[:filters] || handler[:filter]).dup
262
262
  filter = Proc.new do |filter_list|
263
263
  filter_name = filter_list.shift
264
264
  if filter_name.nil?
@@ -278,7 +278,7 @@ module Sensu
278
278
  # Attempt to filter an event for a handler. This method will
279
279
  # check to see if handling is disabled, if the event action is
280
280
  # handled, if the event check severity is handled, if the
281
- # handler is sbuded, and if the event is filtered by any of the
281
+ # handler is subdued, and if the event is filtered by any of the
282
282
  # filters specified in the handler definition.
283
283
  #
284
284
  # @param handler [Hash] definition.
@@ -483,12 +483,12 @@ module Sensu
483
483
  end
484
484
 
485
485
  # Publish a check request to the transport. A check request is
486
- # composted of a check `:name`, an `:issued` timestamp, and a
487
- # check `:command` if available. The check request is published
488
- # to a transport pipe, for each of the check `:subscribers` in
489
- # its definition, eg. "webserver". JSON serialization is used
490
- # when publishing the check request payload to the transport
491
- # pipes. Transport errors are logged.
486
+ # composed of a check `:name`, an `:issued` timestamp, a check
487
+ # `:command` if available, and a check `:extension if available.
488
+ # The check request is published to a transport pipe, for each
489
+ # of the check `:subscribers` in its definition, eg. "webserver".
490
+ # JSON serialization is used when publishing the check request
491
+ # payload to the transport pipes. Transport errors are logged.
492
492
  #
493
493
  # @param check [Hash] definition.
494
494
  def publish_check_request(check)
@@ -498,6 +498,7 @@ module Sensu
498
498
  }
499
499
  payload[:command] = check[:command] if check.has_key?(:command)
500
500
  payload[:source] = check[:source] if check.has_key?(:source)
501
+ payload[:extension] = check[:extension] if check.has_key?(:extension)
501
502
  @logger.info("publishing check request", {
502
503
  :payload => payload,
503
504
  :subscribers => check[:subscribers]
@@ -19,11 +19,11 @@ Gem::Specification.new do |s|
19
19
  s.add_dependency "eventmachine", "1.0.8"
20
20
  s.add_dependency "sensu-logger", "1.1.0"
21
21
  s.add_dependency "sensu-settings", "3.1.0"
22
- s.add_dependency "sensu-extension", "1.2.0"
23
- s.add_dependency "sensu-extensions", "1.3.0"
22
+ s.add_dependency "sensu-extension", "1.3.0"
23
+ s.add_dependency "sensu-extensions", "1.4.0"
24
24
  s.add_dependency "sensu-transport", "3.3.0"
25
- s.add_dependency "sensu-spawn", "1.5.0"
26
- s.add_dependency "em-redis-unified", "1.0.0"
25
+ s.add_dependency "sensu-spawn", "1.6.0"
26
+ s.add_dependency "em-redis-unified", "1.0.1"
27
27
  s.add_dependency "sinatra", "1.4.6"
28
28
  s.add_dependency "async_sinatra", "1.2.0"
29
29
  s.add_dependency "thin", "1.6.3" unless RUBY_PLATFORM =~ /java/
@@ -32,7 +32,8 @@ Gem::Specification.new do |s|
32
32
  s.add_development_dependency "rspec", "~> 3.0.0"
33
33
  s.add_development_dependency "em-http-request", "~> 1.1"
34
34
 
35
- s.files = Dir.glob("{bin,lib}/**/*") + %w[sensu.gemspec README.md CHANGELOG.md MIT-LICENSE.txt]
36
- s.executables = Dir.glob("bin/**/*").map { |file| File.basename(file) }
35
+ s.files = Dir.glob("{exe,lib}/**/*") + %w[sensu.gemspec README.md CHANGELOG.md MIT-LICENSE.txt]
36
+ s.executables = s.files.grep(%r{^exe/}) { |file| File.basename(file) }
37
+ s.bindir = "exe"
37
38
  s.require_paths = ["lib"]
38
39
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.6
4
+ version: 0.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Porter
8
8
  - Justin Kolberg
9
9
  autorequire:
10
- bindir: bin
10
+ bindir: exe
11
11
  cert_chain: []
12
- date: 2015-09-22 00:00:00.000000000 Z
12
+ date: 2015-11-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
@@ -87,28 +87,28 @@ dependencies:
87
87
  requirements:
88
88
  - - '='
89
89
  - !ruby/object:Gem::Version
90
- version: 1.2.0
90
+ version: 1.3.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.2.0
97
+ version: 1.3.0
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: sensu-extensions
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
102
  - - '='
103
103
  - !ruby/object:Gem::Version
104
- version: 1.3.0
104
+ version: 1.4.0
105
105
  type: :runtime
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - '='
110
110
  - !ruby/object:Gem::Version
111
- version: 1.3.0
111
+ version: 1.4.0
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: sensu-transport
114
114
  requirement: !ruby/object:Gem::Requirement
@@ -129,28 +129,28 @@ dependencies:
129
129
  requirements:
130
130
  - - '='
131
131
  - !ruby/object:Gem::Version
132
- version: 1.5.0
132
+ version: 1.6.0
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: 1.5.0
139
+ version: 1.6.0
140
140
  - !ruby/object:Gem::Dependency
141
141
  name: em-redis-unified
142
142
  requirement: !ruby/object:Gem::Requirement
143
143
  requirements:
144
144
  - - '='
145
145
  - !ruby/object:Gem::Version
146
- version: 1.0.0
146
+ version: 1.0.1
147
147
  type: :runtime
148
148
  prerelease: false
149
149
  version_requirements: !ruby/object:Gem::Requirement
150
150
  requirements:
151
151
  - - '='
152
152
  - !ruby/object:Gem::Version
153
- version: 1.0.0
153
+ version: 1.0.1
154
154
  - !ruby/object:Gem::Dependency
155
155
  name: sinatra
156
156
  requirement: !ruby/object:Gem::Requirement
@@ -240,18 +240,20 @@ email:
240
240
  - portertech@gmail.com
241
241
  - amdprophet@gmail.com
242
242
  executables:
243
- - sensu-server
244
- - sensu-client
245
243
  - sensu-api
244
+ - sensu-client
245
+ - sensu-install
246
+ - sensu-server
246
247
  extensions: []
247
248
  extra_rdoc_files: []
248
249
  files:
249
250
  - CHANGELOG.md
250
251
  - MIT-LICENSE.txt
251
252
  - README.md
252
- - bin/sensu-api
253
- - bin/sensu-client
254
- - bin/sensu-server
253
+ - exe/sensu-api
254
+ - exe/sensu-client
255
+ - exe/sensu-install
256
+ - exe/sensu-server
255
257
  - lib/sensu.rb
256
258
  - lib/sensu/api/process.rb
257
259
  - lib/sensu/cli.rb
@@ -288,9 +290,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
288
290
  version: '0'
289
291
  requirements: []
290
292
  rubyforge_project:
291
- rubygems_version: 2.2.2
293
+ rubygems_version: 2.4.5.1
292
294
  signing_key:
293
295
  specification_version: 4
294
296
  summary: A monitoring framework
295
297
  test_files: []
296
- has_rdoc: false