Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion plugins/out_es/es.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include <fluent-bit/flb_record_accessor.h>
#include <fluent-bit/flb_ra_key.h>
#include <fluent-bit/flb_log_event_decoder.h>
#include <fluent-bit/flb_log.h>
#include <fluent-bit/flb_sds.h>
#include <msgpack.h>

#include <time.h>
Expand Down Expand Up @@ -822,6 +824,7 @@ static void cb_es_flush(struct flb_event_chunk *event_chunk,
struct flb_http_client *c;
flb_sds_t signature = NULL;
int compressed = FLB_FALSE;
flb_sds_t header_line = NULL;

/* Get upstream connection */
u_conn = flb_upstream_conn_get(ctx->u);
Expand Down Expand Up @@ -885,6 +888,23 @@ static void cb_es_flush(struct flb_event_chunk *event_chunk,
else if (ctx->cloud_user && ctx->cloud_passwd) {
flb_http_basic_auth(c, ctx->cloud_user, ctx->cloud_passwd);
}
else if (ctx->http_api_key) {
header_line = flb_sds_printf(NULL, "ApiKey %s", ctx->http_api_key);
if (header_line == NULL) {
flb_plg_error(ctx->ins, "failed to format API key auth header");
goto retry;
}

if (flb_http_add_header(c,
FLB_HTTP_HEADER_AUTH, strlen(FLB_HTTP_HEADER_AUTH),
header_line, flb_sds_len(header_line)) != 0) {
flb_plg_error(ctx->ins, "failed to add API key auth header");
flb_sds_destroy(header_line);
goto retry;
}

flb_sds_destroy(header_line);
}

#ifdef FLB_HAVE_AWS
if (ctx->has_aws_auth == FLB_TRUE) {
Expand Down Expand Up @@ -1099,6 +1119,11 @@ static struct flb_config_map config_map[] = {
0, FLB_TRUE, offsetof(struct flb_elasticsearch, http_passwd),
"Password for user defined in HTTP_User"
},
{
FLB_CONFIG_MAP_STR, "http_api_key", NULL,
0, FLB_TRUE, offsetof(struct flb_elasticsearch, http_api_key),
"Base-64 encoded API key credential for Elasticsearch"
},

/* HTTP Compression */
{
Expand Down Expand Up @@ -1288,7 +1313,6 @@ static struct flb_config_map config_map[] = {
0, FLB_TRUE, offsetof(struct flb_elasticsearch, trace_error),
"When enabled print the Elasticsearch exception to stderr (for diag only)"
},

/* EOF */
{0}
};
Expand Down
1 change: 1 addition & 0 deletions plugins/out_es/es.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct flb_elasticsearch {
/* HTTP Auth */
char *http_user;
char *http_passwd;
char *http_api_key;

/* Elastic Cloud Auth */
char *cloud_user;
Expand Down
61 changes: 61 additions & 0 deletions tests/runtime/out_elasticsearch.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@
#include "data/es/json_es.h" /* JSON_ES */


static void cb_check_http_api_key(void *ctx, int ffd,
int res_ret, void *res_data,
size_t res_size, void *data)
{
char *api_key = data;

TEST_CHECK(api_key != NULL);
TEST_CHECK(strlen(api_key) > 0);

TEST_CHECK(strcmp(api_key, "my-api-key-for-elasticsearch") == 0);

flb_free(res_data);
}


static void cb_check_write_op_index(void *ctx, int ffd,
int res_ret, void *res_data,
size_t res_size, void *data)
Expand Down Expand Up @@ -722,6 +737,51 @@ void flb_test_div0()
flb_destroy(ctx);
}

void flb_test_http_api_key()
{
int ret;
int size = sizeof(JSON_ES) - 1;
flb_ctx_t *ctx;
int in_ffd;
int out_ffd;
char *api_key = "my-api-key-for-elasticsearch";

/* Create context, flush every second (some checks omitted here) */
ctx = flb_create();
flb_service_set(ctx, "flush", "1", "grace", "1", NULL);

/* Lib input mode */
in_ffd = flb_input(ctx, (char *) "lib", NULL);
flb_input_set(ctx, in_ffd, "tag", "test", NULL);

/* Elasticsearch output */
out_ffd = flb_output(ctx, (char *) "es", NULL);
flb_output_set(ctx, out_ffd,
"match", "test",
NULL);

/* Configure http_api_key */
flb_output_set(ctx, out_ffd,
"http_api_key", api_key,
NULL);

/* Enable test mode */
ret = flb_output_set_test(ctx, out_ffd, "formatter",
cb_check_http_api_key,
Copy link
Contributor

@mabrarov mabrarov Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test seems to be meaningless. It compares value provided in api_key variable (and passed to cb_check_http_api_key callback as data parameter) with hard-coded value instead of extracting API key from Elasticsearch request (somehow) and comparing it with value given in api_key variable. If lines 764-766 are removed (i.e. if HTTP_API_Key configuration option is not set) then test still passes successfully (because of wrong cb_check_http_api_key callback not performing real validation).

api_key, NULL);

/* Start */
ret = flb_start(ctx);
TEST_CHECK(ret == 0);

/* Ingest data sample */
flb_lib_push(ctx, in_ffd, (char *) JSON_ES, size);

sleep(2);
flb_stop(ctx);
flb_destroy(ctx);
}


static void cb_check_long_index(void *ctx, int ffd,
int res_ret, void *res_data, size_t res_size,
Expand Down Expand Up @@ -1012,6 +1072,7 @@ TEST_LIST = {
{"tag_key" , flb_test_tag_key },
{"replace_dots" , flb_test_replace_dots },
{"id_key" , flb_test_id_key },
{"http_api_key" , flb_test_http_api_key },
{"logstash_prefix_separator" , flb_test_logstash_prefix_separator },
{"response_success" , flb_test_response_success },
{"response_successes", flb_test_response_successes },
Expand Down
Loading