ElasticWriter: Add basic auth support for Elasticsearch behind an HTTP proxy

refs #5538
This commit is contained in:
Michael Friedrich 2017-09-11 17:00:33 +02:00 committed by Gunnar Beutner
parent 344b047ea0
commit 95fbd75df8
3 changed files with 28 additions and 1 deletions

View File

@ -1000,6 +1000,8 @@ Configuration Attributes:
enable_send_perfdata | **Optional.** Send parsed performance data metrics for check results. Defaults to `false`.
flush_interval | **Optional.** How long to buffer data points before transfering to Elasticsearch. Defaults to `10`.
flush_threshold | **Optional.** How many data points to buffer before forcing a transfer to Elasticsearch. Defaults to `1024`.
username | **Optional.** Basic auth username if Elasticsearch is hidden behind an HTTP proxy.
password | **Optional.** Basic auth password if Elasticsearch is hidden behind an HTTP proxy.
Note: If `flush_threshold` is set too low, this will force the feature to flush all data to Elasticsearch too often.
Experiment with the setting, if you are processing more than 1024 metrics per second or similar.

View File

@ -27,6 +27,7 @@
#include "icinga/checkcommand.hpp"
#include "base/tcpsocket.hpp"
#include "base/stream.hpp"
#include "base/base64.hpp"
#include "base/json.hpp"
#include "base/utility.hpp"
#include "base/networkstream.hpp"
@ -422,12 +423,19 @@ void ElasticWriter::SendRequest(const String& body)
req.AddHeader("Accept", "application/json");
req.AddHeader("Content-Type", "application/json");
/* Send authentication if configured. */
String username = GetUsername();
String password = GetPassword();
if (!username.IsEmpty() && !password.IsEmpty())
req.AddHeader("Authorization", "Basic " + Base64::Encode(username + ":" + password));
req.RequestMethod = "POST";
req.RequestUrl = url;
#ifdef I2_DEBUG /* I2_DEBUG */
Log(LogDebug, "ElasticWriter")
<< "Sending body: " << body;
<< "Sending request" << ((!username.IsEmpty() && !password.IsEmpty()) ? " with basic auth " : "" ) << body;
#endif /* I2_DEBUG */
try {
@ -451,6 +459,20 @@ void ElasticWriter::SendRequest(const String& body)
}
if (resp.StatusCode > 299) {
if (resp.StatusCode == 401) {
/* More verbose error logging with Elasticsearch is hidden behind a proxy. */
if (!username.IsEmpty() && !password.IsEmpty()) {
Log(LogCritical, "ElasticWriter")
<< "401 Unauthorized. Please ensure that the user '" << username
<< "' is able to authenticate against the HTTP API/Proxy.";
} else {
Log(LogCritical, "ElasticWriter")
<< "401 Unauthorized. The HTTP API requires authentication but no username/password has been configured.";
}
return;
}
Log(LogWarning, "ElasticWriter")
<< "Unexpected response code " << resp.StatusCode;
@ -459,6 +481,7 @@ void ElasticWriter::SendRequest(const String& body)
resp.Parse(context, true);
String contentType = resp.Headers->Get("content-type");
if (contentType != "application/json") {
Log(LogWarning, "ElasticWriter")
<< "Unexpected Content-Type: " << contentType;

View File

@ -19,6 +19,8 @@ class ElasticWriter : ConfigObject
[config] bool enable_send_perfdata {
default {{{ return false; }}}
};
[config] String username;
[config] String password;
[config] int flush_interval {
default {{{ return 10; }}}