sensu-plugin 0.1.3 → 0.1.4.beta
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.
- data/lib/sensu-handler.rb +74 -39
- data/lib/sensu-plugin.rb +1 -1
- data/test/handle_filter_test.rb +55 -0
- metadata +72 -39
- data/lib/sensu-plugin/util/procs.rb +0 -14
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
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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 ||=
|
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']
|
51
|
-
@event['client']
|
52
|
-
rescue =>
|
53
|
-
puts '
|
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 =
|
75
|
-
|
76
|
-
|
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
|
97
|
-
refresh
|
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
|
-
|
103
|
-
|
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
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
123
|
-
api_request(:GET, '/
|
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
|
-
#
|
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 |
|
139
|
-
|
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
@@ -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
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
25
|
+
prerelease: false
|
26
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
27
|
none: false
|
18
|
-
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
hash: 3
|
32
|
+
segments:
|
33
|
+
- 0
|
34
|
+
version: "0"
|
22
35
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
26
38
|
name: mixlib-cli
|
27
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
66
|
-
|
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
|
-
|
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.
|
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
|