sensu-plugin 0.1.3 → 0.1.4.beta

Sign up to get free protection for your applications and to get access to all the features.
data/lib/sensu-handler.rb CHANGED
@@ -2,6 +2,14 @@ require 'net/http'
2
2
  require 'json'
3
3
 
4
4
  module Sensu
5
+
6
+ NET_HTTP_REQ_CLASS = {
7
+ 'GET' => Net::HTTP::Get,
8
+ 'POST' => Net::HTTP::Post,
9
+ 'DELETE' => Net::HTTP::Delete,
10
+ 'PUT' => Net::HTTP::Put,
11
+ }
12
+
5
13
  class Handler
6
14
 
7
15
  # Implementing classes should override this.
@@ -15,8 +23,9 @@ module Sensu
15
23
 
16
24
  def filter
17
25
  filter_disabled
18
- filter_repeated unless @event['action'] == 'resolve'
26
+ filter_repeated
19
27
  filter_silenced
28
+ filter_dependencies
20
29
  end
21
30
 
22
31
  # This works just like Plugin::CLI's autorun.
@@ -30,27 +39,30 @@ module Sensu
30
39
  end
31
40
  end
32
41
 
33
- # Unfortunately, we need to reimplement config loading. I'm not sure there's
34
- # a good way to allow overriding these paths.
35
-
36
- CONFIGS = ['/etc/sensu/config.json'] + Dir['/etc/sensu/conf.d/*.json']
42
+ def config_files
43
+ if ENV['SENSU_CONFIG_FILES']
44
+ ENV['SENSU_CONFIG_FILES'].split(':')
45
+ else
46
+ ['/etc/sensu/config.json'] + Dir['/etc/sensu/conf.d/*.json']
47
+ end
48
+ end
37
49
 
38
50
  def load_config(filename)
39
51
  JSON.parse(File.open(filename, 'r').read) rescue Hash.new
40
52
  end
41
53
 
42
54
  def settings
43
- @settings ||= CONFIGS.map {|f| load_config(f) }.reduce {|a, b| a.deep_merge(b) }
55
+ @settings ||= config_files.map {|f| load_config(f) }.reduce {|a, b| a.deep_merge(b) }
44
56
  end
45
57
 
46
58
  def read_event(file)
47
59
  begin
48
60
  @event = ::JSON.parse(file.read)
49
61
  @event['occurrences'] ||= 1
50
- @event['check'] ||= Hash.new
51
- @event['client'] ||= Hash.new
52
- rescue => e
53
- puts 'Error reading event: ' + e.message
62
+ @event['check'] ||= Hash.new
63
+ @event['client'] ||= Hash.new
64
+ rescue => error
65
+ puts 'error reading event: ' + error.message
54
66
  exit 0
55
67
  end
56
68
  end
@@ -62,7 +74,7 @@ module Sensu
62
74
  handler.handle
63
75
  end
64
76
 
65
- # Helpers and filters
77
+ # Helpers and filters.
66
78
 
67
79
  def bail(msg)
68
80
  puts msg + ': ' + @event['client']['name'] + '/' + @event['check']['name']
@@ -71,15 +83,9 @@ module Sensu
71
83
 
72
84
  def api_request(method, path, &blk)
73
85
  http = Net::HTTP.new(settings['api']['host'], settings['api']['port'])
74
- req = case method.to_s.upcase
75
- when 'GET'
76
- Net::HTTP::Get.new(path)
77
- when 'POST'
78
- Net::HTTP::Post.new(path)
79
- when 'DELETE'
80
- Net::HTTP::Delete.new(path)
81
- when 'PUT'
82
- Net::HTTP::Put.new(path)
86
+ req = NET_HTTP_REQ_CLASS[method.to_s.upcase].new(path)
87
+ if settings['api']['user'] && settings['api']['password']
88
+ req.basic_auth(settings['api']['user'], settings['api']['password'])
83
89
  end
84
90
  yield(req) if block_given?
85
91
  http.request(req)
@@ -93,50 +99,79 @@ module Sensu
93
99
 
94
100
  def filter_repeated
95
101
  occurrences = @event['check']['occurrences'] || 1
96
- interval = @event['check']['interval'] || 30
97
- refresh = @event['check']['refresh'] || 1800
102
+ interval = @event['check']['interval'] || 30
103
+ refresh = @event['check']['refresh'] || 1800
98
104
  if @event['occurrences'] < occurrences
99
105
  bail 'not enough occurrences'
100
106
  end
101
- if @event['occurrences'] > occurrences
102
- n = refresh.fdiv(interval).to_i
103
- bail 'only repeating alert every ' + n.to_s + ' occurrences' unless @event['occurrences'] % n == 0
107
+ if @event['occurrences'] > occurrences && @event['action'] == 'create'
108
+ number = refresh.fdiv(interval).to_i
109
+ unless @event['occurrences'] % number == 0
110
+ bail 'only handling every ' + number.to_s + ' occurrences'
111
+ end
104
112
  end
105
113
  end
106
114
 
115
+ def stash_exists?(path)
116
+ api_request(:GET, '/stash' + path).code == '200'
117
+ end
118
+
107
119
  def filter_silenced
108
- begin
109
- timeout(3) do
110
- if stash_exists?('/silence/' + @event['client']['name'])
111
- bail 'client alerts silenced'
112
- end
113
- if stash_exists?('/silence/' + @event['client']['name'] + '/' + @event['check']['name'])
114
- bail 'check alerts silenced'
120
+ stashes = {
121
+ 'client' => '/silence/' + @event['client']['name'],
122
+ 'check' => '/silence/' + @event['client']['name'] + '/' + @event['check']['name']
123
+ }
124
+ stashes.each do |scope, path|
125
+ begin
126
+ timeout(2) do
127
+ if stash_exists?(path)
128
+ bail scope + ' alerts silenced'
129
+ end
115
130
  end
131
+ rescue Timeout::Error
132
+ puts 'timed out while attempting to query the sensu api for a stash'
116
133
  end
117
- rescue Timeout::Error
118
- puts 'Timed out while attempting to query the Sensu API for stashes'
119
134
  end
120
135
  end
121
136
 
122
- def stash_exists?(path)
123
- api_request(:GET, '/stash' + path).code == '200'
137
+ def event_exists?(client, check)
138
+ api_request(:GET, '/event/' + client + '/' + check).code == '200'
139
+ end
140
+
141
+ def filter_dependencies
142
+ if @event['check'].has_key?('dependencies')
143
+ if @event['check']['dependencies'].is_a?(Array)
144
+ @event['check']['dependencies'].each do |check|
145
+ begin
146
+ timeout(2) do
147
+ if event_exists?(@event['client']['name'], check)
148
+ bail 'check dependency event exists'
149
+ end
150
+ end
151
+ rescue Timeout::Error
152
+ puts 'timed out while attempting to query the sensu api for an event'
153
+ end
154
+ end
155
+ end
156
+ end
124
157
  end
125
158
 
126
159
  end
160
+
127
161
  end
128
162
 
129
- # Copied from Sensu (0.9.3)
163
+ # Monkey Patching.
130
164
 
131
165
  class Array
132
166
  def deep_merge(other_array, &merger)
133
167
  concat(other_array).uniq
134
168
  end
135
169
  end
170
+
136
171
  class Hash
137
172
  def deep_merge(other_hash, &merger)
138
- merger ||= proc do |k, oldval, newval|
139
- oldval.deep_merge(newval, &merger) rescue newval
173
+ merger ||= proc do |key, old_value, new_value|
174
+ old_value.deep_merge(new_value, &merger) rescue new_value
140
175
  end
141
176
  merge(other_hash, &merger)
142
177
  end
data/lib/sensu-plugin.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Sensu
2
2
  module Plugin
3
- VERSION = "0.1.3"
3
+ VERSION = "0.1.4.beta"
4
4
  EXIT_CODES = {
5
5
  'OK' => 0,
6
6
  'WARNING' => 1,
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'minitest/autorun'
3
+ require 'json'
4
+
5
+ class TestFilterExternal < MiniTest::Unit::TestCase
6
+ include SensuPluginTestHelper
7
+
8
+ def setup
9
+ set_script 'external/handle-filter'
10
+ end
11
+
12
+ def test_resolve_not_enough_occurrences
13
+ event = {
14
+ 'client' => { 'name' => 'test' },
15
+ 'check' => { 'name' => 'test', 'occurrences' => 2},
16
+ 'occurrences' => 1
17
+ }
18
+ output = run_script_with_input(JSON.generate(event))
19
+ assert_equal(0, $?.exitstatus)
20
+ assert_match(/^not enough occurrences/, output)
21
+ end
22
+
23
+ def test_resolve_enough_occurrences
24
+ event = {
25
+ 'client' => { 'name' => 'test' },
26
+ 'check' => { 'name' => 'test', 'occurrences' => 2},
27
+ 'occurrences' => 3
28
+ }
29
+ output = run_script_with_input(JSON.generate(event))
30
+ assert_equal(0, $?.exitstatus)
31
+ assert_match(/^Event:/, output)
32
+ end
33
+
34
+ def test_resolve_enough_occurrences_exactly
35
+ event = {
36
+ 'client' => { 'name' => 'test' },
37
+ 'check' => { 'name' => 'test', 'occurrences' => 2},
38
+ 'occurrences' => 2
39
+ }
40
+ output = run_script_with_input(JSON.generate(event))
41
+ assert_equal(0, $?.exitstatus)
42
+ assert_match(/^Event:/, output)
43
+ end
44
+
45
+ def test_dependency_event_exists
46
+ event = {
47
+ 'client' => { 'name' => 'test' },
48
+ 'check' => { 'name' => 'test', 'dependencies' => ['foo', 'bar'] },
49
+ 'occurrences' => 1
50
+ }
51
+ output = run_script_with_input(JSON.generate(event))
52
+ assert_equal(0, $?.exitstatus)
53
+ assert_match(/dependency event exists/, output)
54
+ end
55
+ end
metadata CHANGED
@@ -1,82 +1,115 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: sensu-plugin
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.3
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31098201
5
+ prerelease: true
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 4
10
+ - beta
11
+ version: 0.1.4.beta
6
12
  platform: ruby
7
- authors:
13
+ authors:
8
14
  - Decklin Foster
15
+ - Sean Porter
9
16
  autorequire:
10
17
  bindir: bin
11
18
  cert_chain: []
12
- date: 2012-02-10 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
19
+
20
+ date: 2012-07-09 00:00:00 -07:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
15
24
  name: json
16
- requirement: &70113831789080 !ruby/object:Gem::Requirement
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
17
27
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ hash: 3
32
+ segments:
33
+ - 0
34
+ version: "0"
22
35
  type: :runtime
23
- prerelease: false
24
- version_requirements: *70113831789080
25
- - !ruby/object:Gem::Dependency
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
26
38
  name: mixlib-cli
27
- requirement: &70113831788560 !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
28
41
  none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 19
46
+ segments:
47
+ - 1
48
+ - 1
49
+ - 0
32
50
  version: 1.1.0
33
51
  type: :runtime
34
- prerelease: false
35
- version_requirements: *70113831788560
52
+ version_requirements: *id002
36
53
  description: Plugins and helper libraries for Sensu, a monitoring framework
37
- email:
54
+ email:
38
55
  - decklin@red-bean.com
56
+ - portertech@gmail.com
39
57
  executables: []
58
+
40
59
  extensions: []
60
+
41
61
  extra_rdoc_files: []
42
- files:
62
+
63
+ files:
43
64
  - lib/sensu-handler.rb
44
65
  - lib/sensu-plugin/check/cli.rb
45
66
  - lib/sensu-plugin/cli.rb
46
67
  - lib/sensu-plugin/metric/cli.rb
47
- - lib/sensu-plugin/util/procs.rb
48
68
  - lib/sensu-plugin.rb
49
69
  - test/external_check_test.rb
50
70
  - test/external_handler_test.rb
51
71
  - test/external_metric_test.rb
72
+ - test/handle_filter_test.rb
52
73
  - test/helper.rb
74
+ has_rdoc: true
53
75
  homepage: https://github.com/sonian/sensu-plugin
54
- licenses:
76
+ licenses:
55
77
  - MIT
56
78
  post_install_message:
57
79
  rdoc_options: []
58
- require_paths:
80
+
81
+ require_paths:
59
82
  - lib
60
- required_ruby_version: !ruby/object:Gem::Requirement
83
+ required_ruby_version: !ruby/object:Gem::Requirement
61
84
  none: false
62
- requirements:
63
- - - ! '>='
64
- - !ruby/object:Gem::Version
65
- version: '0'
66
- required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
93
  none: false
68
- requirements:
69
- - - ! '>='
70
- - !ruby/object:Gem::Version
71
- version: '0'
94
+ requirements:
95
+ - - ">"
96
+ - !ruby/object:Gem::Version
97
+ hash: 25
98
+ segments:
99
+ - 1
100
+ - 3
101
+ - 1
102
+ version: 1.3.1
72
103
  requirements: []
104
+
73
105
  rubyforge_project:
74
- rubygems_version: 1.8.11
106
+ rubygems_version: 1.3.7
75
107
  signing_key:
76
108
  specification_version: 3
77
109
  summary: Sensu Plugins
78
- test_files:
110
+ test_files:
79
111
  - test/external_check_test.rb
80
112
  - test/external_handler_test.rb
81
113
  - test/external_metric_test.rb
114
+ - test/handle_filter_test.rb
82
115
  - test/helper.rb
@@ -1,14 +0,0 @@
1
- require 'sensu-plugin/check/cli'
2
-
3
- module Sensu
4
- module Plugin
5
- module Util
6
- module Procs
7
-
8
- class << self
9
- end
10
-
11
- end
12
- end
13
- end
14
- end