portertech-sensu 1.10.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.
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,201 @@
1
+ require "sensu/server/socket"
2
+
3
+ module Sensu
4
+ module Server
5
+ module Handle
6
+ # Create a handler error callback, for logging the error and
7
+ # decrementing the `@in_progress[:events]` by `1`.
8
+ #
9
+ # @param handler [Object]
10
+ # @param event_data [Object]
11
+ # @param event_id [String] event UUID
12
+ # @return [Proc] error callback.
13
+ def handler_error(handler, event_data, event_id)
14
+ Proc.new do |error|
15
+ @logger.error("handler error", {
16
+ :handler => handler,
17
+ :event => {
18
+ :id => event_id
19
+ },
20
+ :event_data => event_data,
21
+ :error => error.to_s
22
+ })
23
+ @in_progress[:events] -= 1 if @in_progress
24
+ end
25
+ end
26
+
27
+ # Execute a pipe event handler, using the defined handler
28
+ # command to spawn a process, passing it event data via STDIN.
29
+ # Log the handler output lines and decrement the
30
+ # `@in_progress[:events]` by `1` when the handler executes
31
+ # successfully.
32
+ #
33
+ # When the spawned process exits with status 0, its output is
34
+ # logged at :info level. Otherwise, its output is logged at
35
+ # :error level.
36
+ #
37
+ # @param handler [Hash] definition.
38
+ # @param event_data [Object] provided to the spawned handler
39
+ # process via STDIN.
40
+ # @param event_id [String] event UUID
41
+ def pipe_handler(handler, event_data, event_id)
42
+ options = {:data => event_data, :timeout => handler[:timeout]}
43
+ Spawn.process(handler[:command], options) do |output, status|
44
+ log_level = status == 0 ? :info : :error
45
+ @logger.send(log_level, "handler output", {
46
+ :handler => handler,
47
+ :event => {
48
+ :id => event_id
49
+ },
50
+ :output => output.split("\n+")
51
+ })
52
+ @in_progress[:events] -= 1 if @in_progress
53
+ end
54
+ end
55
+
56
+ # Connect to a TCP socket and transmit event data to it, then
57
+ # close the connection. The `Sensu::Server::Socket` connection
58
+ # handler is used for the socket. The socket timeouts are
59
+ # configurable via the handler definition, `:timeout`. The
60
+ # `handler_error()` method is used to create the `on_error`
61
+ # callback for the connection handler. The `on_error` callback
62
+ # is call in the event of any error(s). The
63
+ # `@in_progress[:events]` is decremented by `1` when the data is
64
+ # transmitted successfully, `on_success`.
65
+ #
66
+ # @param handler [Hash] definition.
67
+ # @param event_data [Object] to transmit to the TCP socket.
68
+ # @param event_id [String] event UUID
69
+ def tcp_handler(handler, event_data, event_id)
70
+ unless event_data.nil? || event_data.empty?
71
+ on_error = handler_error(handler, event_data, event_id)
72
+ begin
73
+ EM::connect(handler[:socket][:host], handler[:socket][:port], Socket) do |socket|
74
+ socket.on_success = Proc.new do
75
+ @in_progress[:events] -= 1 if @in_progress
76
+ end
77
+ socket.on_error = on_error
78
+ timeout = handler[:timeout] || 10
79
+ socket.set_timeout(timeout)
80
+ socket.send_data(event_data.to_s)
81
+ socket.close_connection_after_writing
82
+ end
83
+ rescue => error
84
+ on_error.call(error)
85
+ end
86
+ else
87
+ @logger.debug("not connecting to tcp socket due to empty event data", {
88
+ :handler => handler,
89
+ :event => {
90
+ :id => event_id
91
+ }
92
+ })
93
+ @in_progress[:events] -= 1 if @in_progress
94
+ end
95
+ end
96
+
97
+ # Transmit event data to a UDP socket, then close the
98
+ # connection. The `@in_progress[:events]` is decremented by `1`
99
+ # when the data is assumed to have been transmitted.
100
+ #
101
+ # @param handler [Hash] definition.
102
+ # @param event_data [Object] to transmit to the UDP socket.
103
+ # @param event_id [String] event UUID
104
+ def udp_handler(handler, event_data, event_id)
105
+ begin
106
+ EM::open_datagram_socket("0.0.0.0", 0, nil) do |socket|
107
+ socket.send_datagram(event_data.to_s, handler[:socket][:host], handler[:socket][:port])
108
+ socket.close_connection_after_writing
109
+ @in_progress[:events] -= 1 if @in_progress
110
+ end
111
+ rescue => error
112
+ handler_error(handler, event_data, event_id).call(error)
113
+ end
114
+ end
115
+
116
+ # Publish event data to a Sensu transport pipe. Event data that
117
+ # is `nil` or empty will not be published, to prevent transport
118
+ # errors. The `@in_progress[:events]` is decremented by `1`,
119
+ # even if the event data is not published.
120
+ #
121
+ # @param handler [Hash] definition.
122
+ # @param event_data [Object] to publish to the transport pipe.
123
+ # @param event_id [String] event UUID
124
+ def transport_handler(handler, event_data, event_id)
125
+ unless event_data.nil? || event_data.empty?
126
+ pipe = handler[:pipe]
127
+ pipe_options = pipe[:options] || {}
128
+ @transport.publish(pipe[:type].to_sym, pipe[:name], event_data, pipe_options) do |info|
129
+ if info[:error]
130
+ handler_error(handler, event_data, event_id).call(info[:error])
131
+ end
132
+ end
133
+ end
134
+ @in_progress[:events] -= 1 if @in_progress
135
+ end
136
+
137
+ # Run a handler extension, within the Sensu EventMachine reactor
138
+ # (event loop). The extension API `safe_run()` method is used to
139
+ # guard against most errors. The `safe_run()` callback is always
140
+ # called, logging the extension run output and status, and
141
+ # decrementing the `@in_progress[:events]` by `1`.
142
+ #
143
+ # @param handler [Hash] definition.
144
+ # @param event_data [Object] to pass to the handler extension.
145
+ # @param event_id [String] event UUID
146
+ def handler_extension(handler, event_data, event_id)
147
+ handler.safe_run(event_data) do |output, status|
148
+ log_level = (output.empty? && status.zero?) ? :debug : :info
149
+ @logger.send(log_level, "handler extension output", {
150
+ :extension => handler.definition,
151
+ :event => {
152
+ :id => event_id
153
+ },
154
+ :output => output,
155
+ :status => status
156
+ })
157
+ @in_progress[:events] -= 1 if @in_progress
158
+ end
159
+ end
160
+
161
+ # Route the event data to the appropriate handler type method.
162
+ # Routing is done using the handler definition, `:type`.
163
+ #
164
+ # @param handler [Hash] definition.
165
+ # @param event_data [Object] to pass to the handler type method.
166
+ # @param event_id [String] event UUID
167
+ def handler_type_router(handler, event_data, event_id)
168
+ case handler[:type]
169
+ when "pipe"
170
+ pipe_handler(handler, event_data, event_id)
171
+ when "tcp"
172
+ tcp_handler(handler, event_data, event_id)
173
+ when "udp"
174
+ udp_handler(handler, event_data, event_id)
175
+ when "transport"
176
+ transport_handler(handler, event_data, event_id)
177
+ when "extension"
178
+ handler_extension(handler, event_data, event_id)
179
+ end
180
+ end
181
+
182
+ # Handle an event, providing event data to an event handler.
183
+ # This method logs event data and the handler definition at the
184
+ # debug log level, then calls the `handler_type_router()`
185
+ # method.
186
+ #
187
+ # @param handler [Hash] definition.
188
+ # @param event_data [Object] to pass to an event handler.
189
+ # @param event_id [String] event UUID
190
+ def handle_event(handler, event_data, event_id)
191
+ definition = handler.is_a?(Hash) ? handler : handler.definition
192
+ @logger.debug("handling event", {
193
+ :event_data => event_data,
194
+ :event => { :id => event_id },
195
+ :handler => definition
196
+ })
197
+ handler_type_router(handler, event_data, event_id)
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,92 @@
1
+ module Sensu
2
+ module Server
3
+ module Mutate
4
+ # Create a mutator callback (Proc). A mutator callback takes two
5
+ # parameters, for the mutator output and status code. The
6
+ # created callback can be used for standard mutators and mutator
7
+ # extensions. The provided callback will only be called when the
8
+ # mutator status is `0` (OK). If the status is not `0`, an error
9
+ # is logged, and the `@in_progress[:events]` is decremented by
10
+ # `1`.
11
+ #
12
+ # @param mutator [Object] definition or extension.
13
+ # @param event [Hash] data.
14
+ # @param callback [Proc] to call when the mutator status is `0`.
15
+ # @return [Proc] mutator callback.
16
+ def mutator_callback(mutator, event, &callback)
17
+ Proc.new do |output, status|
18
+ if status == 0
19
+ callback.call(output)
20
+ else
21
+ definition = mutator.is_a?(Hash) ? mutator : mutator.definition
22
+ @logger.error("mutator error", {
23
+ :mutator => definition,
24
+ :event => event,
25
+ :output => output,
26
+ :status => status
27
+ })
28
+ @in_progress[:events] -= 1 if @in_progress
29
+ end
30
+ end
31
+ end
32
+
33
+ # Execute a standard mutator (pipe), spawn a process using the
34
+ # mutator command and pipe the event data to it via STDIN. The
35
+ # `mutator_callback()` method is used to create the mutator
36
+ # callback, wrapping the provided callback (event handler).
37
+ #
38
+ # @param mutator [Hash] definition.
39
+ # @param event [Hash] data.
40
+ # @param callback [Proc] to call when the mutator executes
41
+ # successfully.
42
+ def pipe_mutator(mutator, event, &callback)
43
+ options = {:data => Sensu::JSON.dump(event), :timeout => mutator[:timeout]}
44
+ block = mutator_callback(mutator, event, &callback)
45
+ Spawn.process(mutator[:command], options, &block)
46
+ end
47
+
48
+ # Run a mutator extension, within the Sensu EventMachine reactor
49
+ # (event loop). The `mutator_callback()` method is used to
50
+ # create the mutator callback, wrapping the provided callback
51
+ # (event handler).
52
+ #
53
+ # @param mutator [Object] extension.
54
+ # @param event [Hash] data.
55
+ # @param callback [Proc] to call when the mutator runs
56
+ # successfully.
57
+ def mutator_extension(mutator, event, &callback)
58
+ block = mutator_callback(mutator, event, &callback)
59
+ mutator.safe_run(event, &block)
60
+ end
61
+
62
+ # Mutate event data for a handler. By default, the "json"
63
+ # mutator is used, unless the handler specifies another mutator.
64
+ # If a mutator does not exist, not defined or a missing
65
+ # extension, an error will be logged and the
66
+ # `@in_progress[:events]` is decremented by `1`. This method
67
+ # first checks for the existence of a standard mutator, then
68
+ # checks for an extension if a standard mutator is not defined.
69
+ #
70
+ # @param handler [Hash] definition.
71
+ # @param event [Hash] data.
72
+ # @param callback [Proc] to call when the mutator executes/runs
73
+ # successfully (event handler).
74
+ def mutate_event(handler, event, &callback)
75
+ mutator_name = handler[:mutator] || "json"
76
+ case
77
+ when @settings.mutator_exists?(mutator_name)
78
+ mutator = @settings[:mutators][mutator_name]
79
+ pipe_mutator(mutator, event, &callback)
80
+ when @extensions.mutator_exists?(mutator_name)
81
+ mutator = @extensions[:mutators][mutator_name]
82
+ mutator_extension(mutator, event, &callback)
83
+ else
84
+ @logger.error("unknown mutator", {
85
+ :mutator_name => mutator_name
86
+ })
87
+ @in_progress[:events] -= 1 if @in_progress
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end