sensu 0.11.3 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +18 -0
- data/lib/sensu/api.rb +95 -88
- data/lib/sensu/constants.rb +1 -1
- data/sensu.gemspec +1 -0
- metadata +37 -21
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
## 0.12.0 - 2013-10-28
|
2
|
+
|
3
|
+
### Non-backwards compatible changes
|
4
|
+
|
5
|
+
Deprecated API endpoints, `/check/request` and `/event/resolve`, have been
|
6
|
+
removed. Please use `/request` and `/resolve`.
|
7
|
+
|
8
|
+
### Features
|
9
|
+
|
10
|
+
API stashes can now expire, automatically removing themselves after `N`
|
11
|
+
seconds, eg. '{"path": "foo", "content":{"bar": "baz"}, "expire": 600}'.
|
12
|
+
|
13
|
+
### Other
|
14
|
+
|
15
|
+
Added additional AMQP library version constraints.
|
16
|
+
|
17
|
+
Improved API POST data validation.
|
18
|
+
|
1
19
|
## 0.11.3 - 2013-10-23
|
2
20
|
|
3
21
|
### Other
|
data/lib/sensu/api.rb
CHANGED
@@ -137,26 +137,6 @@ module Sensu
|
|
137
137
|
env['rack.input'].rewind
|
138
138
|
end
|
139
139
|
|
140
|
-
def integer_parameter(parameter)
|
141
|
-
parameter =~ /^[0-9]+$/ ? parameter.to_i : nil
|
142
|
-
end
|
143
|
-
|
144
|
-
def pagination(items)
|
145
|
-
limit = integer_parameter(params[:limit])
|
146
|
-
offset = integer_parameter(params[:offset]) || 0
|
147
|
-
unless limit.nil?
|
148
|
-
headers['X-Pagination'] = Oj.dump(
|
149
|
-
:limit => limit,
|
150
|
-
:offset => offset,
|
151
|
-
:total => items.size
|
152
|
-
)
|
153
|
-
paginated = items.slice(offset, limit)
|
154
|
-
Array(paginated)
|
155
|
-
else
|
156
|
-
items
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
140
|
def bad_request!
|
161
141
|
ahalt 400
|
162
142
|
end
|
@@ -188,6 +168,42 @@ module Sensu
|
|
188
168
|
body ''
|
189
169
|
end
|
190
170
|
|
171
|
+
def read_data(rules={}, &block)
|
172
|
+
begin
|
173
|
+
data = Oj.load(env['rack.input'].read)
|
174
|
+
valid = rules.all? do |key, rule|
|
175
|
+
data[key].is_a?(rule[:type]) || (rule[:nil_ok] && data[key].nil?)
|
176
|
+
end
|
177
|
+
if valid
|
178
|
+
block.call(data)
|
179
|
+
else
|
180
|
+
bad_request!
|
181
|
+
end
|
182
|
+
rescue Oj::ParseError
|
183
|
+
bad_request!
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def integer_parameter(parameter)
|
188
|
+
parameter =~ /^[0-9]+$/ ? parameter.to_i : nil
|
189
|
+
end
|
190
|
+
|
191
|
+
def pagination(items)
|
192
|
+
limit = integer_parameter(params[:limit])
|
193
|
+
offset = integer_parameter(params[:offset]) || 0
|
194
|
+
unless limit.nil?
|
195
|
+
headers['X-Pagination'] = Oj.dump(
|
196
|
+
:limit => limit,
|
197
|
+
:offset => offset,
|
198
|
+
:total => items.size
|
199
|
+
)
|
200
|
+
paginated = items.slice(offset, limit)
|
201
|
+
Array(paginated)
|
202
|
+
else
|
203
|
+
items
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
191
207
|
def rabbitmq_info(&block)
|
192
208
|
info = {
|
193
209
|
:keepalives => {
|
@@ -389,38 +405,31 @@ module Sensu
|
|
389
405
|
end
|
390
406
|
end
|
391
407
|
|
392
|
-
apost
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
subscribers.uniq.each do |exchange_name|
|
413
|
-
$amq.fanout(exchange_name).publish(Oj.dump(payload))
|
414
|
-
end
|
415
|
-
issued!
|
416
|
-
else
|
417
|
-
not_found!
|
408
|
+
apost '/request' do
|
409
|
+
rules = {
|
410
|
+
:check => {:type => String, :nil_ok => false},
|
411
|
+
:subscribers => {:type => Array, :nil_ok => true}
|
412
|
+
}
|
413
|
+
read_data(rules) do |data|
|
414
|
+
if $settings.check_exists?(data[:check])
|
415
|
+
check = $settings[:checks][data[:check]]
|
416
|
+
subscribers = data[:subscribers] || check[:subscribers] || Array.new
|
417
|
+
payload = {
|
418
|
+
:name => data[:check],
|
419
|
+
:command => check[:command],
|
420
|
+
:issued => Time.now.to_i
|
421
|
+
}
|
422
|
+
$logger.info('publishing check request', {
|
423
|
+
:payload => payload,
|
424
|
+
:subscribers => subscribers
|
425
|
+
})
|
426
|
+
subscribers.uniq.each do |exchange_name|
|
427
|
+
$amq.fanout(exchange_name).publish(Oj.dump(payload))
|
418
428
|
end
|
429
|
+
issued!
|
419
430
|
else
|
420
|
-
|
431
|
+
not_found!
|
421
432
|
end
|
422
|
-
rescue Oj::ParseError, TypeError
|
423
|
-
bad_request!
|
424
433
|
end
|
425
434
|
end
|
426
435
|
|
@@ -476,25 +485,20 @@ module Sensu
|
|
476
485
|
end
|
477
486
|
end
|
478
487
|
|
479
|
-
apost
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
end
|
488
|
+
apost '/resolve' do
|
489
|
+
rules = {
|
490
|
+
:client => {:type => String, :nil_ok => false},
|
491
|
+
:check => {:type => String, :nil_ok => false}
|
492
|
+
}
|
493
|
+
read_data(rules) do |data|
|
494
|
+
$redis.hgetall('events:' + data[:client]) do |events|
|
495
|
+
if events.include?(data[:check])
|
496
|
+
resolve_event(event_hash(events[data[:check]], data[:client], data[:check]))
|
497
|
+
issued!
|
498
|
+
else
|
499
|
+
not_found!
|
492
500
|
end
|
493
|
-
else
|
494
|
-
bad_request!
|
495
501
|
end
|
496
|
-
rescue Oj::ParseError, TypeError
|
497
|
-
bad_request!
|
498
502
|
end
|
499
503
|
end
|
500
504
|
|
@@ -504,12 +508,13 @@ module Sensu
|
|
504
508
|
unless checks.empty?
|
505
509
|
checks.each_with_index do |check_name, index|
|
506
510
|
$redis.smembers('aggregates:' + check_name) do |aggregates|
|
511
|
+
aggregates.reverse!
|
507
512
|
aggregates.map! do |issued|
|
508
513
|
issued.to_i
|
509
514
|
end
|
510
515
|
item = {
|
511
516
|
:check => check_name,
|
512
|
-
:issued => aggregates
|
517
|
+
:issued => aggregates
|
513
518
|
}
|
514
519
|
response << item
|
515
520
|
if index == checks.size - 1
|
@@ -526,6 +531,7 @@ module Sensu
|
|
526
531
|
aget %r{/aggregates/([\w\.-]+)$} do |check_name|
|
527
532
|
$redis.smembers('aggregates:' + check_name) do |aggregates|
|
528
533
|
unless aggregates.empty?
|
534
|
+
aggregates.reverse!
|
529
535
|
aggregates.map! do |issued|
|
530
536
|
issued.to_i
|
531
537
|
end
|
@@ -536,8 +542,7 @@ module Sensu
|
|
536
542
|
issued > timestamp
|
537
543
|
end
|
538
544
|
end
|
539
|
-
|
540
|
-
body Oj.dump(aggregates)
|
545
|
+
body Oj.dump(pagination(aggregates))
|
541
546
|
else
|
542
547
|
not_found!
|
543
548
|
end
|
@@ -598,15 +603,12 @@ module Sensu
|
|
598
603
|
end
|
599
604
|
|
600
605
|
apost %r{/stash(?:es)?/(.*)} do |path|
|
601
|
-
|
602
|
-
|
603
|
-
$redis.set('stash:' + path, Oj.dump(post_body)) do
|
606
|
+
read_data do |data|
|
607
|
+
$redis.set('stash:' + path, Oj.dump(data)) do
|
604
608
|
$redis.sadd('stashes', path) do
|
605
609
|
created!(Oj.dump(:path => path))
|
606
610
|
end
|
607
611
|
end
|
608
|
-
rescue Oj::ParseError
|
609
|
-
bad_request!
|
610
612
|
end
|
611
613
|
end
|
612
614
|
|
@@ -637,7 +639,6 @@ module Sensu
|
|
637
639
|
aget '/stashes' do
|
638
640
|
response = Array.new
|
639
641
|
$redis.smembers('stashes') do |stashes|
|
640
|
-
stashes = pagination(stashes)
|
641
642
|
unless stashes.empty?
|
642
643
|
stashes.each_with_index do |path, index|
|
643
644
|
$redis.get('stash:' + path) do |stash_json|
|
@@ -647,9 +648,11 @@ module Sensu
|
|
647
648
|
:content => Oj.load(stash_json)
|
648
649
|
}
|
649
650
|
response << item
|
651
|
+
else
|
652
|
+
$redis.srem('stashes', path)
|
650
653
|
end
|
651
654
|
if index == stashes.size - 1
|
652
|
-
body Oj.dump(response)
|
655
|
+
body Oj.dump(pagination(response))
|
653
656
|
end
|
654
657
|
end
|
655
658
|
end
|
@@ -660,21 +663,25 @@ module Sensu
|
|
660
663
|
end
|
661
664
|
|
662
665
|
apost '/stashes' do
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
666
|
+
rules = {
|
667
|
+
:path => {:type => String, :nil_ok => false},
|
668
|
+
:content => {:type => Hash, :nil_ok => false},
|
669
|
+
:expire => {:type => Integer, :nil_ok => true}
|
670
|
+
}
|
671
|
+
read_data(rules) do |data|
|
672
|
+
stash_key = 'stash:' + data[:path]
|
673
|
+
$redis.set(stash_key, Oj.dump(data[:content])) do
|
674
|
+
$redis.sadd('stashes', data[:path]) do
|
675
|
+
response = Oj.dump(:path => data[:path])
|
676
|
+
if data[:expire]
|
677
|
+
$redis.expire(stash_key, data[:expire]) do
|
678
|
+
created!(response)
|
679
|
+
end
|
680
|
+
else
|
681
|
+
created!(response)
|
671
682
|
end
|
672
683
|
end
|
673
|
-
else
|
674
|
-
bad_request!
|
675
684
|
end
|
676
|
-
rescue Oj::ParseError
|
677
|
-
bad_request!
|
678
685
|
end
|
679
686
|
end
|
680
687
|
end
|
data/lib/sensu/constants.rb
CHANGED
data/sensu.gemspec
CHANGED
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.add_dependency('oj', '2.0.9')
|
17
17
|
s.add_dependency('eventmachine', '1.0.3')
|
18
18
|
s.add_dependency('amq-protocol', '1.2.0')
|
19
|
+
s.add_dependency('amq-client', '1.0.2')
|
19
20
|
s.add_dependency('amqp', '1.0.0')
|
20
21
|
s.add_dependency('em-redis-unified', '0.4.2')
|
21
22
|
s.add_dependency('thin', '1.5.0')
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 47
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 12
|
9
|
+
- 0
|
10
|
+
version: 0.12.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sean Porter
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2013-10-
|
19
|
+
date: 2013-10-28 00:00:00 -07:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -68,9 +68,25 @@ dependencies:
|
|
68
68
|
type: :runtime
|
69
69
|
version_requirements: *id003
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
71
|
+
name: amq-client
|
72
72
|
prerelease: false
|
73
73
|
requirement: &id004 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - "="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 19
|
79
|
+
segments:
|
80
|
+
- 1
|
81
|
+
- 0
|
82
|
+
- 2
|
83
|
+
version: 1.0.2
|
84
|
+
type: :runtime
|
85
|
+
version_requirements: *id004
|
86
|
+
- !ruby/object:Gem::Dependency
|
87
|
+
name: amqp
|
88
|
+
prerelease: false
|
89
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
74
90
|
none: false
|
75
91
|
requirements:
|
76
92
|
- - "="
|
@@ -82,11 +98,11 @@ dependencies:
|
|
82
98
|
- 0
|
83
99
|
version: 1.0.0
|
84
100
|
type: :runtime
|
85
|
-
version_requirements: *
|
101
|
+
version_requirements: *id005
|
86
102
|
- !ruby/object:Gem::Dependency
|
87
103
|
name: em-redis-unified
|
88
104
|
prerelease: false
|
89
|
-
requirement: &
|
105
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
90
106
|
none: false
|
91
107
|
requirements:
|
92
108
|
- - "="
|
@@ -98,11 +114,11 @@ dependencies:
|
|
98
114
|
- 2
|
99
115
|
version: 0.4.2
|
100
116
|
type: :runtime
|
101
|
-
version_requirements: *
|
117
|
+
version_requirements: *id006
|
102
118
|
- !ruby/object:Gem::Dependency
|
103
119
|
name: thin
|
104
120
|
prerelease: false
|
105
|
-
requirement: &
|
121
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
106
122
|
none: false
|
107
123
|
requirements:
|
108
124
|
- - "="
|
@@ -114,11 +130,11 @@ dependencies:
|
|
114
130
|
- 0
|
115
131
|
version: 1.5.0
|
116
132
|
type: :runtime
|
117
|
-
version_requirements: *
|
133
|
+
version_requirements: *id007
|
118
134
|
- !ruby/object:Gem::Dependency
|
119
135
|
name: sinatra
|
120
136
|
prerelease: false
|
121
|
-
requirement: &
|
137
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
122
138
|
none: false
|
123
139
|
requirements:
|
124
140
|
- - "="
|
@@ -130,11 +146,11 @@ dependencies:
|
|
130
146
|
- 5
|
131
147
|
version: 1.3.5
|
132
148
|
type: :runtime
|
133
|
-
version_requirements: *
|
149
|
+
version_requirements: *id008
|
134
150
|
- !ruby/object:Gem::Dependency
|
135
151
|
name: async_sinatra
|
136
152
|
prerelease: false
|
137
|
-
requirement: &
|
153
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
138
154
|
none: false
|
139
155
|
requirements:
|
140
156
|
- - "="
|
@@ -146,11 +162,11 @@ dependencies:
|
|
146
162
|
- 0
|
147
163
|
version: 1.0.0
|
148
164
|
type: :runtime
|
149
|
-
version_requirements: *
|
165
|
+
version_requirements: *id009
|
150
166
|
- !ruby/object:Gem::Dependency
|
151
167
|
name: rake
|
152
168
|
prerelease: false
|
153
|
-
requirement: &
|
169
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
154
170
|
none: false
|
155
171
|
requirements:
|
156
172
|
- - ">="
|
@@ -160,11 +176,11 @@ dependencies:
|
|
160
176
|
- 0
|
161
177
|
version: "0"
|
162
178
|
type: :development
|
163
|
-
version_requirements: *
|
179
|
+
version_requirements: *id010
|
164
180
|
- !ruby/object:Gem::Dependency
|
165
181
|
name: rspec
|
166
182
|
prerelease: false
|
167
|
-
requirement: &
|
183
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
168
184
|
none: false
|
169
185
|
requirements:
|
170
186
|
- - ">="
|
@@ -174,11 +190,11 @@ dependencies:
|
|
174
190
|
- 0
|
175
191
|
version: "0"
|
176
192
|
type: :development
|
177
|
-
version_requirements: *
|
193
|
+
version_requirements: *id011
|
178
194
|
- !ruby/object:Gem::Dependency
|
179
195
|
name: em-http-request
|
180
196
|
prerelease: false
|
181
|
-
requirement: &
|
197
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
182
198
|
none: false
|
183
199
|
requirements:
|
184
200
|
- - ">="
|
@@ -188,7 +204,7 @@ dependencies:
|
|
188
204
|
- 0
|
189
205
|
version: "0"
|
190
206
|
type: :development
|
191
|
-
version_requirements: *
|
207
|
+
version_requirements: *id012
|
192
208
|
description: A monitoring framework that aims to be simple, malleable, and scalable. Uses the publish/subscribe model.
|
193
209
|
email:
|
194
210
|
- portertech@gmail.com
|