portertech-sensu 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +961 -0
  3. data/MIT-LICENSE.txt +20 -0
  4. data/README.md +65 -0
  5. data/exe/sensu-api +10 -0
  6. data/exe/sensu-client +10 -0
  7. data/exe/sensu-install +195 -0
  8. data/exe/sensu-server +10 -0
  9. data/lib/sensu/api/http_handler.rb +434 -0
  10. data/lib/sensu/api/process.rb +79 -0
  11. data/lib/sensu/api/routes/aggregates.rb +196 -0
  12. data/lib/sensu/api/routes/checks.rb +44 -0
  13. data/lib/sensu/api/routes/clients.rb +171 -0
  14. data/lib/sensu/api/routes/events.rb +86 -0
  15. data/lib/sensu/api/routes/health.rb +45 -0
  16. data/lib/sensu/api/routes/info.rb +37 -0
  17. data/lib/sensu/api/routes/request.rb +44 -0
  18. data/lib/sensu/api/routes/resolve.rb +32 -0
  19. data/lib/sensu/api/routes/results.rb +153 -0
  20. data/lib/sensu/api/routes/settings.rb +23 -0
  21. data/lib/sensu/api/routes/silenced.rb +182 -0
  22. data/lib/sensu/api/routes/stashes.rb +107 -0
  23. data/lib/sensu/api/routes.rb +88 -0
  24. data/lib/sensu/api/utilities/filter_response_content.rb +44 -0
  25. data/lib/sensu/api/utilities/publish_check_request.rb +107 -0
  26. data/lib/sensu/api/utilities/publish_check_result.rb +39 -0
  27. data/lib/sensu/api/utilities/resolve_event.rb +29 -0
  28. data/lib/sensu/api/utilities/servers_info.rb +43 -0
  29. data/lib/sensu/api/utilities/transport_info.rb +43 -0
  30. data/lib/sensu/api/validators/check.rb +55 -0
  31. data/lib/sensu/api/validators/client.rb +35 -0
  32. data/lib/sensu/api/validators/invalid.rb +8 -0
  33. data/lib/sensu/cli.rb +69 -0
  34. data/lib/sensu/client/http_socket.rb +217 -0
  35. data/lib/sensu/client/process.rb +655 -0
  36. data/lib/sensu/client/socket.rb +207 -0
  37. data/lib/sensu/client/utils.rb +53 -0
  38. data/lib/sensu/client/validators/check.rb +53 -0
  39. data/lib/sensu/constants.rb +17 -0
  40. data/lib/sensu/daemon.rb +396 -0
  41. data/lib/sensu/sandbox.rb +19 -0
  42. data/lib/sensu/server/filter.rb +227 -0
  43. data/lib/sensu/server/handle.rb +201 -0
  44. data/lib/sensu/server/mutate.rb +92 -0
  45. data/lib/sensu/server/process.rb +1646 -0
  46. data/lib/sensu/server/socket.rb +54 -0
  47. data/lib/sensu/server/tessen.rb +170 -0
  48. data/lib/sensu/utilities.rb +398 -0
  49. data/lib/sensu.rb +3 -0
  50. data/sensu.gemspec +36 -0
  51. metadata +322 -0
@@ -0,0 +1,44 @@
1
+ module Sensu
2
+ module API
3
+ module Routes
4
+ module Checks
5
+ CHECKS_URI = /^\/checks$/
6
+ CHECK_URI = /^\/checks\/([\w\.-]+)$/
7
+
8
+ # GET /checks
9
+ def get_checks
10
+ checks = @settings.checks.reject { |check| check[:standalone] }
11
+ @response_content = pagination(checks)
12
+ respond
13
+ end
14
+
15
+ # GET /checks/:check_name
16
+ def get_check
17
+ check_name = parse_uri(CHECK_URI).first
18
+ if @settings[:checks][check_name] && !@settings[:checks][check_name][:standalone]
19
+ @response_content = @settings[:checks][check_name].merge(:name => check_name)
20
+ respond
21
+ else
22
+ not_found!
23
+ end
24
+ end
25
+
26
+ # DELETE /checks/:check_name
27
+ def delete_check
28
+ check_name = parse_uri(CHECK_URI).first
29
+ @redis.smembers("clients") do |clients|
30
+ result_keys = clients.map {|client_name| "result:#{client_name}:#{check_name}"}
31
+ history_keys = clients.map {|client_name| "history:#{client_name}:#{check_name}"}
32
+ last_ok_keys = clients.map {|client_name| "history:#{client_name}:#{check_name}:last_ok"}
33
+ keys = result_keys.concat(history_keys).concat(last_ok_keys)
34
+ keys.each do |key|
35
+ @redis.del(key)
36
+ end
37
+ end
38
+ @response_content = {:issued => Time.now.to_i}
39
+ accepted!
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,171 @@
1
+ require "sensu/api/validators/client"
2
+ require "sensu/api/utilities/resolve_event"
3
+
4
+ module Sensu
5
+ module API
6
+ module Routes
7
+ module Clients
8
+ include Utilities::ResolveEvent
9
+
10
+ CLIENTS_URI = /^\/clients$/
11
+ CLIENT_URI = /^\/clients\/([\w\.-]+)$/
12
+ CLIENT_HISTORY_URI = /^\/clients\/([\w\.-]+)\/history$/
13
+
14
+ # POST /clients
15
+ def post_clients
16
+ read_data do |client|
17
+ client[:keepalives] = client.fetch(:keepalives, false)
18
+ client[:version] = VERSION
19
+ client[:timestamp] = Time.now.to_i
20
+ client[:subscriptions] ||= []
21
+ validator = Validators::Client.new
22
+ if validator.valid?(client)
23
+ client[:subscriptions] = (client[:subscriptions] + ["client:#{client[:name]}"]).uniq
24
+ @redis.set("client:#{client[:name]}", Sensu::JSON.dump(client)) do
25
+ @redis.sadd("clients", client[:name]) do
26
+ @response_content = {:name => client[:name]}
27
+ created!
28
+ end
29
+ end
30
+ else
31
+ bad_request!
32
+ end
33
+ end
34
+ end
35
+
36
+ # GET /clients
37
+ def get_clients
38
+ @response_content = []
39
+ @redis.smembers("clients") do |clients|
40
+ clients = pagination(clients)
41
+ unless clients.empty?
42
+ clients.each_with_index do |client_name, index|
43
+ @redis.get("client:#{client_name}") do |client_json|
44
+ unless client_json.nil?
45
+ client = Sensu::JSON.load(client_json)
46
+ @response_content << redact_sensitive(client, client[:redact])
47
+ else
48
+ @logger.error("client data missing from registry", :client_name => client_name)
49
+ @redis.srem("clients", client_name)
50
+ end
51
+ if index == clients.length - 1
52
+ respond
53
+ end
54
+ end
55
+ end
56
+ else
57
+ respond
58
+ end
59
+ end
60
+ end
61
+
62
+ # GET /clients/:client_name
63
+ def get_client
64
+ client_name = parse_uri(CLIENT_URI).first
65
+ @redis.get("client:#{client_name}") do |client_json|
66
+ unless client_json.nil?
67
+ client = Sensu::JSON.load(client_json)
68
+ @response_content = redact_sensitive(client, client[:redact])
69
+ respond
70
+ else
71
+ not_found!
72
+ end
73
+ end
74
+ end
75
+
76
+ # GET /clients/:client_name/history
77
+ def get_client_history
78
+ client_name = parse_uri(CLIENT_HISTORY_URI).first
79
+ @response_content = []
80
+ @redis.smembers("result:#{client_name}") do |checks|
81
+ unless checks.empty?
82
+ checks.each_with_index do |check_name, index|
83
+ result_key = "#{client_name}:#{check_name}"
84
+ history_key = "history:#{result_key}"
85
+ @redis.lrange(history_key, -21, -1) do |history|
86
+ history.map! do |status|
87
+ status.to_i
88
+ end
89
+ @redis.get("result:#{result_key}") do |result_json|
90
+ unless result_json.nil?
91
+ result = Sensu::JSON.load(result_json)
92
+ last_execution = result[:executed]
93
+ unless history.empty? || last_execution.nil?
94
+ item = {
95
+ :check => check_name,
96
+ :history => history,
97
+ :last_execution => last_execution.to_i,
98
+ :last_status => history.last,
99
+ :last_result => result
100
+ }
101
+ @response_content << item
102
+ end
103
+ end
104
+ if index == checks.length - 1
105
+ respond
106
+ end
107
+ end
108
+ end
109
+ end
110
+ else
111
+ respond
112
+ end
113
+ end
114
+ end
115
+
116
+ # DELETE /clients/:client_name
117
+ def delete_client
118
+ client_name = parse_uri(CLIENT_URI).first
119
+ client_key = "client:#{client_name}"
120
+ signature_key = "#{client_key}:signature"
121
+ @redis.get(client_key) do |client_json|
122
+ unless client_json.nil?
123
+ @redis.set(signature_key, "invalidated") if @params[:invalidate]
124
+ @redis.hgetall("events:#{client_name}") do |events|
125
+ events.each do |check_name, event_json|
126
+ resolve_event(event_json)
127
+ end
128
+ delete_client = Proc.new do |attempts|
129
+ attempts += 1
130
+ @redis.hgetall("events:#{client_name}") do |events|
131
+ if events.empty? || attempts == 5
132
+ @logger.info("deleting client from registry", :client_name => client_name)
133
+ @redis.srem("clients", client_name) do
134
+ @redis.del(client_key)
135
+ invalidate_expire = integer_parameter(@params[:invalidate_expire])
136
+ if @params[:invalidate] && invalidate_expire
137
+ @redis.expire(signature_key, invalidate_expire)
138
+ else
139
+ @redis.del(signature_key)
140
+ end
141
+ @redis.del("events:#{client_name}")
142
+ @redis.smembers("result:#{client_name}") do |checks|
143
+ checks.each do |check_name|
144
+ result_key = "#{client_name}:#{check_name}"
145
+ @redis.del("result:#{result_key}")
146
+ @redis.del("history:#{result_key}")
147
+ @redis.del("history:#{result_key}:last_ok")
148
+ end
149
+ @redis.del("result:#{client_name}")
150
+ end
151
+ end
152
+ else
153
+ EM::Timer.new(1) do
154
+ delete_client.call(attempts)
155
+ end
156
+ end
157
+ end
158
+ end
159
+ delete_client.call(0)
160
+ @response_content = {:issued => Time.now.to_i}
161
+ accepted!
162
+ end
163
+ else
164
+ not_found!
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,86 @@
1
+ require "sensu/api/utilities/resolve_event"
2
+
3
+ module Sensu
4
+ module API
5
+ module Routes
6
+ module Events
7
+ include Utilities::ResolveEvent
8
+
9
+ EVENTS_URI = /^\/(?:events|incidents)$/
10
+ EVENTS_CLIENT_URI = /^\/(?:events|incidents)\/([\w\.-]+)$/
11
+ EVENT_URI = /^\/(?:events|incidents)\/([\w\.-]+)\/([\w\.-]+)$/
12
+
13
+ # GET /events
14
+ def get_events
15
+ @response_content = []
16
+ raw_event_json = []
17
+ @redis.smembers("clients") do |clients|
18
+ unless clients.empty?
19
+ clients.each_with_index do |client_name, index|
20
+ @redis.hgetall("events:#{client_name}") do |events|
21
+ events.each do |check_name, event_json|
22
+ raw_event_json << event_json
23
+ end
24
+ if index == clients.length - 1
25
+ raw_event_json = pagination(raw_event_json)
26
+ raw_event_json.each do |event_json|
27
+ @response_content << Sensu::JSON.load(event_json)
28
+ end
29
+ respond
30
+ end
31
+ end
32
+ end
33
+ else
34
+ respond
35
+ end
36
+ end
37
+ end
38
+
39
+ # GET /events/:client_name
40
+ def get_events_client
41
+ client_name = parse_uri(EVENTS_CLIENT_URI).first
42
+ @response_content = []
43
+ raw_event_json = []
44
+ @redis.hgetall("events:#{client_name}") do |events|
45
+ events.each do |check_name, event_json|
46
+ raw_event_json << event_json
47
+ end
48
+ raw_event_json = pagination(raw_event_json)
49
+ raw_event_json.each do |event_json|
50
+ @response_content << Sensu::JSON.load(event_json)
51
+ end
52
+ respond
53
+ end
54
+ end
55
+
56
+ # GET /events/:client_name/:check_name
57
+ def get_event
58
+ client_name, check_name = parse_uri(EVENT_URI)
59
+ @redis.hgetall("events:#{client_name}") do |events|
60
+ event_json = events[check_name]
61
+ unless event_json.nil?
62
+ @response_content = Sensu::JSON.load(event_json)
63
+ respond
64
+ else
65
+ not_found!
66
+ end
67
+ end
68
+ end
69
+
70
+ # DELETE /events/:client_name/:check_name
71
+ def delete_event
72
+ client_name, check_name = parse_uri(EVENT_URI)
73
+ @redis.hgetall("events:#{client_name}") do |events|
74
+ if events.include?(check_name)
75
+ resolve_event(events[check_name])
76
+ @response_content = {:issued => Time.now.to_i}
77
+ accepted!
78
+ else
79
+ not_found!
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,45 @@
1
+ require "sensu/api/utilities/transport_info"
2
+
3
+ module Sensu
4
+ module API
5
+ module Routes
6
+ module Health
7
+ include Utilities::TransportInfo
8
+
9
+ HEALTH_URI = /^\/health$/
10
+
11
+ # GET /health
12
+ def get_health
13
+ @response_content = []
14
+ if @redis.connected? && @transport.connected?
15
+ min_consumers = integer_parameter(@params[:consumers])
16
+ max_messages = integer_parameter(@params[:messages])
17
+ transport_info do |info|
18
+ if min_consumers
19
+ if info[:keepalives][:consumers] < min_consumers
20
+ @response_content << "keepalive consumers (#{info[:keepalives][:consumers]}) less than min_consumers (#{min_consumers})"
21
+ end
22
+ if info[:results][:consumers] < min_consumers
23
+ @response_content << "result consumers (#{info[:results][:consumers]}) less than min_consumers (#{min_consumers})"
24
+ end
25
+ end
26
+ if max_messages
27
+ if info[:keepalives][:messages] > max_messages
28
+ @response_content << "keepalive messages (#{info[:keepalives][:messages]}) greater than max_messages (#{max_messages})"
29
+ end
30
+ if info[:results][:messages] > max_messages
31
+ @response_content << "result messages (#{info[:results][:messages]}) greater than max_messages (#{max_messages})"
32
+ end
33
+ end
34
+ @response_content.empty? ? no_content! : precondition_failed!
35
+ end
36
+ else
37
+ @response_content << "not connected to redis" unless @redis.connected?
38
+ @response_content << "not connected to transport" unless @transport.connected?
39
+ precondition_failed!
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,37 @@
1
+ require "sensu/api/utilities/transport_info"
2
+ require "sensu/api/utilities/servers_info"
3
+
4
+ module Sensu
5
+ module API
6
+ module Routes
7
+ module Info
8
+ include Utilities::TransportInfo
9
+ include Utilities::ServersInfo
10
+
11
+ INFO_URI = /^\/info$/
12
+
13
+ # GET /info
14
+ def get_info
15
+ transport_info do |transport|
16
+ servers_info do |servers|
17
+ sensu = RELEASE_INFO.merge(
18
+ :settings => {
19
+ :hexdigest => @settings.hexdigest
20
+ }
21
+ )
22
+ @response_content = {
23
+ :sensu => sensu,
24
+ :transport => transport,
25
+ :redis => {
26
+ :connected => @redis.connected?
27
+ },
28
+ :servers => servers
29
+ }
30
+ respond
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,44 @@
1
+ require "sensu/api/utilities/publish_check_request"
2
+
3
+ module Sensu
4
+ module API
5
+ module Routes
6
+ module Request
7
+ include Utilities::PublishCheckRequest
8
+
9
+ REQUEST_URI = /^\/request$/
10
+
11
+ # POST /request
12
+ def post_request
13
+ rules = {
14
+ :check => {:type => String, :nil_ok => false},
15
+ :subscribers => {:type => Array, :nil_ok => true},
16
+ :reason => {:type => String, :nil_ok => true},
17
+ :creator => {:type => String, :nil_ok => true}
18
+ }
19
+ read_data(rules) do |data|
20
+ if @settings[:checks][data[:check]]
21
+ check = @settings[:checks][data[:check]].dup
22
+ check[:name] = data[:check]
23
+ check[:subscribers] ||= Array.new
24
+ check[:subscribers] = data[:subscribers] if data[:subscribers]
25
+ check[:api_requested] = {
26
+ :reason => data[:reason],
27
+ :creator => data[:creator]
28
+ }
29
+ if check[:proxy_requests]
30
+ publish_proxy_check_requests(check)
31
+ else
32
+ publish_check_request(check)
33
+ end
34
+ @response_content = {:issued => Time.now.to_i}
35
+ accepted!
36
+ else
37
+ not_found!
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,32 @@
1
+ require "sensu/api/utilities/resolve_event"
2
+
3
+ module Sensu
4
+ module API
5
+ module Routes
6
+ module Resolve
7
+ include Utilities::ResolveEvent
8
+
9
+ RESOLVE_URI = /^\/resolve$/
10
+
11
+ # POST /resolve
12
+ def post_resolve
13
+ rules = {
14
+ :client => {:type => String, :nil_ok => false},
15
+ :check => {:type => String, :nil_ok => false}
16
+ }
17
+ read_data(rules) do |data|
18
+ @redis.hgetall("events:#{data[:client]}") do |events|
19
+ if events.include?(data[:check])
20
+ resolve_event(events[data[:check]])
21
+ @response_content = {:issued => Time.now.to_i}
22
+ accepted!
23
+ else
24
+ not_found!
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,153 @@
1
+ require "sensu/api/validators/check"
2
+ require "sensu/api/utilities/publish_check_result"
3
+
4
+ module Sensu
5
+ module API
6
+ module Routes
7
+ module Results
8
+ include Utilities::PublishCheckResult
9
+
10
+ RESULTS_URI = /^\/results$/
11
+ RESULTS_CLIENT_URI = /^\/results\/([\w\.-]+)$/
12
+ RESULT_URI = /^\/results\/([\w\.-]+)\/([\w\.-]+)$/
13
+
14
+ # POST /results
15
+ def post_results
16
+ read_data do |check|
17
+ check[:status] ||= 0
18
+ check[:executed] ||= Time.now.to_i
19
+ validator = Validators::Check.new
20
+ if validator.valid?(check)
21
+ publish_check_result("sensu-api", check)
22
+ @response_content = {:issued => Time.now.to_i}
23
+ accepted!
24
+ else
25
+ bad_request!
26
+ end
27
+ end
28
+ end
29
+
30
+ # GET /results
31
+ def get_results
32
+ @response_content = []
33
+ @redis.smembers("clients") do |clients|
34
+ unless clients.empty?
35
+ result_keys = []
36
+ clients.each_with_index do |client_name, client_index|
37
+ @redis.smembers("result:#{client_name}") do |checks|
38
+ checks.each do |check_name|
39
+ result_keys << "result:#{client_name}:#{check_name}"
40
+ end
41
+ if client_index == clients.length - 1
42
+ result_keys = pagination(result_keys)
43
+ unless result_keys.empty?
44
+ result_keys.each_with_index do |result_key, result_key_index|
45
+ @redis.get(result_key) do |result_json|
46
+ history_key = result_key.sub(/^result:/, "history:")
47
+ @redis.lrange(history_key, -21, -1) do |history|
48
+ history.map! do |status|
49
+ status.to_i
50
+ end
51
+ unless result_json.nil?
52
+ client_name = history_key.split(":")[1]
53
+ check = Sensu::JSON.load(result_json)
54
+ check[:history] = history
55
+ @response_content << {:client => client_name, :check => check}
56
+ end
57
+ if result_key_index == result_keys.length - 1
58
+ respond
59
+ end
60
+ end
61
+ end
62
+ end
63
+ else
64
+ respond
65
+ end
66
+ end
67
+ end
68
+ end
69
+ else
70
+ respond
71
+ end
72
+ end
73
+ end
74
+
75
+ # GET /results/:client_name
76
+ def get_results_client
77
+ client_name = parse_uri(RESULTS_CLIENT_URI).first
78
+ @response_content = []
79
+ @redis.smembers("result:#{client_name}") do |checks|
80
+ checks = pagination(checks)
81
+ unless checks.empty?
82
+ checks.each_with_index do |check_name, check_index|
83
+ result_key = "result:#{client_name}:#{check_name}"
84
+ @redis.get(result_key) do |result_json|
85
+ history_key = "history:#{client_name}:#{check_name}"
86
+ @redis.lrange(history_key, -21, -1) do |history|
87
+ history.map! do |status|
88
+ status.to_i
89
+ end
90
+ unless result_json.nil?
91
+ check = Sensu::JSON.load(result_json)
92
+ check[:history] = history
93
+ @response_content << {:client => client_name, :check => check}
94
+ end
95
+ if check_index == checks.length - 1
96
+ respond
97
+ end
98
+ end
99
+ end
100
+ end
101
+ else
102
+ respond
103
+ end
104
+ end
105
+ end
106
+
107
+ # GET /results/:client_name/:check_name
108
+ def get_result
109
+ client_name, check_name = parse_uri(RESULT_URI)
110
+ result_key = "result:#{client_name}:#{check_name}"
111
+ @redis.get(result_key) do |result_json|
112
+ unless result_json.nil?
113
+ history_key = "history:#{client_name}:#{check_name}"
114
+ @redis.lrange(history_key, -21, -1) do |history|
115
+ history.map! do |status|
116
+ status.to_i
117
+ end
118
+ check = Sensu::JSON.load(result_json)
119
+ check[:history] = history
120
+ @response_content = {:client => client_name, :check => check}
121
+ respond
122
+ end
123
+ else
124
+ not_found!
125
+ end
126
+ end
127
+ end
128
+
129
+ # DELETE /results/:client_name/:check_name
130
+ def delete_result
131
+ client_name, check_name = parse_uri(RESULT_URI)
132
+ result_key = "result:#{client_name}:#{check_name}"
133
+ @redis.exists(result_key) do |result_exists|
134
+ if result_exists
135
+ @redis.srem("result:#{client_name}", check_name) do
136
+ @redis.del(result_key) do
137
+ history_key = "history:#{client_name}:#{check_name}"
138
+ @redis.del(history_key) do
139
+ @redis.del("#{history_key}:last_ok") do
140
+ no_content!
141
+ end
142
+ end
143
+ end
144
+ end
145
+ else
146
+ not_found!
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,23 @@
1
+ require "sensu/utilities"
2
+
3
+ module Sensu
4
+ module API
5
+ module Routes
6
+ module Settings
7
+ include Utilities
8
+
9
+ SETTINGS_URI = /^\/settings$/
10
+
11
+ # GET /settings
12
+ def get_settings
13
+ if @params[:redacted] == "false"
14
+ @response_content = @settings.to_hash
15
+ else
16
+ @response_content = redact_sensitive(@settings.to_hash)
17
+ end
18
+ respond
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end