Class: Sensu::Client::HTTPSocket
- Inherits:
-
EM::HttpServer::Server
- Object
- EM::HttpServer::Server
- Sensu::Client::HTTPSocket
- Includes:
- API::Utilities::TransportInfo, CheckUtils, Utilities
- Defined in:
- lib/sensu/client/http_socket.rb
Overview
EventMachine connection handler for the Sensu HTTP client’s socket.
The Sensu client listens on localhost, port 3031 (by default), for TCP HTTP connections. This allows software running on the host to push check results (that may contain metrics) into Sensu, without needing to know anything about Sensu’s internal implementation.
All requests and responses expect a json-encoded body (if a body is expected at all).
This socket requires receiving a proper HTTP request to any of the following endpoints:
GET /info
This endpoint returns 200 OK with some basic Sensu info
POST /results
This endpoint expects application/json body with a check result
GET /settings
This endpoint responds with 200 OK and the Sensu configuration
GET /brew
This endpoint gets you some fresh coffee
Constant Summary
Constants included from Utilities
Instance Attribute Summary collapse
-
#logger ⇒ Object
Returns the value of attribute logger.
-
#settings ⇒ Object
Returns the value of attribute settings.
-
#transport ⇒ Object
Returns the value of attribute transport.
Instance Method Summary collapse
- #authorized? ⇒ Boolean
- #http_request_errback(error) ⇒ Object
-
#initialize ⇒ HTTPSocket
constructor
A new instance of HTTPSocket.
-
#process_http_request ⇒ Object
This method is called to process HTTP requests.
- #process_request_info ⇒ Object
- #process_request_results ⇒ Object
- #process_request_settings ⇒ Object
- #send_response(status, status_string, content) ⇒ Object
- #unauthorized_response ⇒ Object
Methods included from CheckUtils
#process_check_result, #publish_check_result, #validate_check_result
Methods included from Utilities
#attributes_match?, #check_subdued?, #deep_merge, #determine_check_cron_time, #eval_attribute_value, #find_attribute_value, #in_time_window?, #in_time_windows?, #object_substitute_tokens, #process_cpu_times, #process_eval_string, #random_uuid, #redact_sensitive, #retry_until_true, #substitute_tokens, #system_address, #system_hostname, #testing?
Methods included from API::Utilities::TransportInfo
Constructor Details
#initialize ⇒ HTTPSocket
Returns a new instance of HTTPSocket.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/sensu/client/http_socket.rb', line 41 def initialize super @endpoints = { "/info" => { "methods" => { "GET" => method(:process_request_info) }, "help" => "Sensu client information" }, "/results" => { "methods" => { "POST" => method(:process_request_results) }, "help" => "Send check JSON results here" }, "/settings" => { "methods" => { "GET" => method(:process_request_settings) }, "help" => "Get redacted Sensu settings (requires basic auth). Use ?redacted=false if you want the setting unredacted." }, "/brew" => { "methods" => { "GET" => Proc.new { |response| send_response(418, "I'm a teapot", { :response => "I'm a teapot!" }) } }, "help" => "Ask Sensu to brew a cup of joe (try it!)" } } @response = nil end |
Instance Attribute Details
#logger ⇒ Object
Returns the value of attribute logger.
39 40 41 |
# File 'lib/sensu/client/http_socket.rb', line 39 def logger @logger end |
#settings ⇒ Object
Returns the value of attribute settings.
39 40 41 |
# File 'lib/sensu/client/http_socket.rb', line 39 def settings @settings end |
#transport ⇒ Object
Returns the value of attribute transport.
39 40 41 |
# File 'lib/sensu/client/http_socket.rb', line 39 def transport @transport end |
Instance Method Details
#authorized? ⇒ Boolean
76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/sensu/client/http_socket.rb', line 76 def = @settings[:client][:http_socket] || Hash.new if [:user] and [:password] if @http[:authorization] scheme, base64 = @http[:authorization].split("\s") if scheme == "Basic" user, password = Base64.decode64(base64).split(":") return (user == [:user] && password == [:password]) end end end false end |
#http_request_errback(error) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/sensu/client/http_socket.rb', line 153 def http_request_errback(error) @logger.error("http socket error while processing request", { :error => error.to_s, :backtrace => error.backtrace }) @response = EM::DelegatedHttpResponse.new(self) @response.content_type "application/json" send_response(500, "Internal Server Error", { "response" => "Internal Server Error: Check your Sensu logs for error details" }) end |
#process_http_request ⇒ Object
This method is called to process HTTP requests
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/sensu/client/http_socket.rb', line 166 def process_http_request @logger.debug("http socket processing", { :http_request_method => @http_request_method, :http_request_uri => @http_request_uri }) @response = EM::DelegatedHttpResponse.new(self) @response.content_type "application/json" endpoint = @endpoints[@http_request_uri] if endpoint @logger.debug("http socket endpoint found", { :http_request_uri => @http_request_uri, :accepted_methods => endpoint["methods"].keys }) method_name = @http_request_method.upcase method_handler = endpoint["methods"][method_name] if method_handler @logger.debug("http socket executing handler", { :method_name => method_name, :http_request_uri => @http_request_uri }) method_handler.call else @logger.debug("http socket method is not allowed for endpoint", { :method_name => method_name, :http_request_uri => @http_request_uri }) send_response(405, "Method Not Allowed", { :response => "Valid methods for this endpoint: #{endpoint['methods'].keys}" }) end else @logger.warn("http socket unknown endpoint requested", :http_request_uri => @http_request_uri) help_response = { :endpoints => {} } @endpoints.each do |key, value| help_response[:endpoints][key] ||= Hash.new help_response[:endpoints][key]["help"] = value["help"] help_response[:endpoints][key]["methods"] = value["methods"].keys end send_response(404, "Not Found", help_response) end end |
#process_request_info ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/sensu/client/http_socket.rb', line 110 def process_request_info if @settings[:client][:http_socket] && @settings[:client][:http_socket][:protect_all_endpoints] return unless end transport_info do |info| send_response(200, "OK", { :sensu => { :version => VERSION }, :transport => info }) end end |
#process_request_results ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/sensu/client/http_socket.rb', line 125 def process_request_results if @settings[:client][:http_socket] && @settings[:client][:http_socket][:protect_all_endpoints] return unless end if @http[:content_type] and @http[:content_type].include?("application/json") and @http_content begin check = Sensu::JSON::load(@http_content) process_check_result(check) send_response(202, "OK", {:response => "ok"}) rescue Sensu::JSON::ParseError, ArgumentError send_response(400, "Failed to parse JSON body", {:response => "Failed to parse JSON body"}) end else send_response(415, "Only application/json content type accepted", {:response => "Invalid content type"}) end end |
#process_request_settings ⇒ Object
143 144 145 146 147 148 149 150 151 |
# File 'lib/sensu/client/http_socket.rb', line 143 def process_request_settings return unless @logger.info("http socket responding to request for configuration settings") if @http_query_string and @http_query_string.downcase.include?("redacted=false") send_response(200, "OK", @settings.to_hash) else send_response(200, "OK", redact_sensitive(@settings.to_hash)) end end |
#send_response(status, status_string, content) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/sensu/client/http_socket.rb', line 98 def send_response(status, status_string, content) @logger.debug("http socket sending response", { :status => status, :status_string => status_string, :content => content }) @response.status = status @response.status_string = status_string @response.content = Sensu::JSON::dump(content) @response.send_response end |
#unauthorized_response ⇒ Object
90 91 92 93 94 95 96 |
# File 'lib/sensu/client/http_socket.rb', line 90 def @logger.warn("http socket refusing to serve unauthorized request") @response.headers["WWW-Authenticate"] = 'Basic realm="Sensu Client Restricted Area"' send_response(401, "Unauthorized", { :response => "You must be authenticated using your http_options user and password settings" }) end |