sensu 0.11.3 → 0.12.0
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/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
|