Skip to content
Open
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
1 change: 1 addition & 0 deletions plugins/out_azure_logs_ingestion/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(src
azure_logs_ingestion.c
azure_logs_ingestion_conf.c
azure_logs_ingestion_msiauth.c
)

FLB_PLUGIN(out_azure_logs_ingestion "${src}" "")
86 changes: 54 additions & 32 deletions plugins/out_azure_logs_ingestion/azure_logs_ingestion.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include "azure_logs_ingestion.h"
#include "azure_logs_ingestion_conf.h"
#include "azure_logs_ingestion_msiauth.h"

static int cb_azure_logs_ingestion_init(struct flb_output_instance *ins,
struct flb_config *config, void *data)
Expand Down Expand Up @@ -170,48 +171,63 @@ flb_sds_t get_az_li_token(struct flb_az_li *ctx)
flb_plg_error(ctx->ins, "error locking mutex");
return NULL;
}

/* Retrieve access token only if expired */
if (flb_oauth2_token_expired(ctx->u_auth) == FLB_TRUE) {
flb_plg_debug(ctx->ins, "token expired. getting new token");
/* Clear any previous oauth2 payload content */
flb_oauth2_payload_clear(ctx->u_auth);

ret = flb_oauth2_payload_append(ctx->u_auth, "grant_type", 10,
"client_credentials", 18);
if (ret == -1) {
flb_plg_error(ctx->ins, "error appending oauth2 params");
goto token_cleanup;

if (ctx->auth_type == FLB_AZ_LI_AUTH_MANAGED_IDENTITY_SYSTEM ||
ctx->auth_type == FLB_AZ_LI_AUTH_MANAGED_IDENTITY_USER) {
/* Use MSI authentication */
token = flb_azure_li_msiauth_token_get(ctx->u_auth);
if (!token) {
flb_plg_error(ctx->ins, "error retrieving MSI access token");
goto token_cleanup;
}
flb_plg_debug(ctx->ins, "got azure MSI token");
}
else {
/* Use service principal authentication */
/* Clear any previous oauth2 payload content */
flb_oauth2_payload_clear(ctx->u_auth);

ret = flb_oauth2_payload_append(ctx->u_auth, "grant_type", 10,
"client_credentials", 18);
if (ret == -1) {
flb_plg_error(ctx->ins, "error appending oauth2 params");
goto token_cleanup;
}

ret = flb_oauth2_payload_append(ctx->u_auth, "scope", 5, FLB_AZ_LI_AUTH_SCOPE,
sizeof(FLB_AZ_LI_AUTH_SCOPE) - 1);
if (ret == -1) {
flb_plg_error(ctx->ins, "error appending oauth2 params");
goto token_cleanup;
}
ret = flb_oauth2_payload_append(ctx->u_auth, "scope", 5, FLB_AZ_LI_AUTH_SCOPE,
sizeof(FLB_AZ_LI_AUTH_SCOPE) - 1);
if (ret == -1) {
flb_plg_error(ctx->ins, "error appending oauth2 params");
goto token_cleanup;
}

ret = flb_oauth2_payload_append(ctx->u_auth, "client_id", 9,
ctx->client_id, -1);
if (ret == -1) {
flb_plg_error(ctx->ins, "error appending oauth2 params");
goto token_cleanup;
}
ret = flb_oauth2_payload_append(ctx->u_auth, "client_id", 9,
ctx->client_id, -1);
if (ret == -1) {
flb_plg_error(ctx->ins, "error appending oauth2 params");
goto token_cleanup;
}

ret = flb_oauth2_payload_append(ctx->u_auth, "client_secret", 13,
ctx->client_secret, -1);
if (ret == -1) {
flb_plg_error(ctx->ins, "error appending oauth2 params");
goto token_cleanup;
}
ret = flb_oauth2_payload_append(ctx->u_auth, "client_secret", 13,
ctx->client_secret, -1);
if (ret == -1) {
flb_plg_error(ctx->ins, "error appending oauth2 params");
goto token_cleanup;
}

token = flb_oauth2_token_get(ctx->u_auth);
token = flb_oauth2_token_get(ctx->u_auth);

/* Copy string to prevent race conditions */
if (!token) {
flb_plg_error(ctx->ins, "error retrieving oauth2 access token");
goto token_cleanup;
/* Copy string to prevent race conditions */
if (!token) {
flb_plg_error(ctx->ins, "error retrieving oauth2 access token");
goto token_cleanup;
}
flb_plg_debug(ctx->ins, "got azure token");
}
flb_plg_debug(ctx->ins, "got azure token");
}

/* Reached this code-block means, got new token or token not expired */
Expand Down Expand Up @@ -393,6 +409,12 @@ static struct flb_config_map config_map[] = {
0, FLB_TRUE, offsetof(struct flb_az_li, client_secret),
"Set the client secret of the AAD application"
},
{
FLB_CONFIG_MAP_STR, "auth_type", "service_principal",
0, FLB_TRUE, offsetof(struct flb_az_li, auth_type_str),
"Set the authentication type: 'service_principal' or 'managed_identity'. "
"For managed_identity, use 'system' as client_id for system-assigned identity, or specify the managed identity's client ID"
},
{
FLB_CONFIG_MAP_STR, "dce_url", (char *)NULL,
0, FLB_TRUE, offsetof(struct flb_az_li, dce_url),
Expand Down
11 changes: 11 additions & 0 deletions plugins/out_azure_logs_ingestion/azure_logs_ingestion.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
/* refresh token every 60 minutes */
#define FLB_AZ_LI_TOKEN_TIMEOUT 3600

/* Authentication types */
typedef enum {
FLB_AZ_LI_AUTH_SERVICE_PRINCIPAL = 0, /* Client ID + Client Secret */
FLB_AZ_LI_AUTH_MANAGED_IDENTITY_SYSTEM, /* System-assigned managed identity */
FLB_AZ_LI_AUTH_MANAGED_IDENTITY_USER /* User-assigned managed identity */
} flb_az_li_auth_type;

#include <fluent-bit/flb_info.h>
#include <fluent-bit/flb_output.h>
#include <fluent-bit/flb_sds.h>
Expand All @@ -48,6 +55,10 @@ struct flb_az_li {
flb_sds_t dcr_id;
flb_sds_t table_name;

/* Authentication */
int auth_type;
char *auth_type_str;

/* time_generated: on/off */
int time_generated;
/* time key name */
Expand Down
89 changes: 65 additions & 24 deletions plugins/out_azure_logs_ingestion/azure_logs_ingestion_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include "azure_logs_ingestion.h"
#include "azure_logs_ingestion_conf.h"
#include "azure_logs_ingestion_msiauth.h"

struct flb_az_li* flb_az_li_ctx_create(struct flb_output_instance *ins,
struct flb_config *config)
Expand Down Expand Up @@ -54,21 +55,34 @@ struct flb_az_li* flb_az_li_ctx_create(struct flb_output_instance *ins,
return NULL;
}

/* config: 'client_id' */
if (!ctx->client_id) {
flb_plg_error(ins, "property 'client_id' is not defined");
flb_az_li_ctx_destroy(ctx);
return NULL;
}
/* config: 'tenant_id' */
if (!ctx->tenant_id) {
flb_plg_error(ins, "property 'tenant_id' is not defined");
flb_az_li_ctx_destroy(ctx);
return NULL;
}
/* config: 'client_secret' */
if (!ctx->client_secret) {
flb_plg_error(ins, "property 'client_secret' is not defined");
/* Auth method validation and setup */
if (strcasecmp(ctx->auth_type_str, "service_principal") == 0) {
ctx->auth_type = FLB_AZ_LI_AUTH_SERVICE_PRINCIPAL;

/* Verify required parameters for Service Principal auth */
if (!ctx->tenant_id || !ctx->client_id || !ctx->client_secret) {
flb_plg_error(ins, "When using service_principal auth, tenant_id, client_id, and client_secret are required");
flb_az_li_ctx_destroy(ctx);
return NULL;
}
}
Comment on lines +58 to +68
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Defensive default for auth_type_str and avoid stale ins->context on early returns

  • Add a NULL/empty guard so strcasecmp never derefs NULL if the config map fails to populate the default.
  • Today ins->context is set before validation; on any “return NULL” below, the instance may keep a dangling pointer. Set the context only after successful init (see snippet).

Apply this minimal guard:

-    /* Auth method validation and setup */
-    if (strcasecmp(ctx->auth_type_str, "service_principal") == 0) {
+    /* Auth method validation and setup */
+    if (!ctx->auth_type_str || ctx->auth_type_str[0] == '\0') {
+        ctx->auth_type_str = "service_principal";
+    }
+    if (strcasecmp(ctx->auth_type_str, "service_principal") == 0) {

Outside this hunk, move the context assignment to the end (right before returning ctx) instead of early:

/* remove this early assignment */
// flb_output_set_context(ins, ctx);

/* ... after successful setup (e.g., after flb_output_upstream_set) */
flb_output_set_context(ins, ctx);
return ctx;
🤖 Prompt for AI Agents
In plugins/out_azure_logs_ingestion/azure_logs_ingestion_conf.c around lines 58
to 68, add a NULL/empty guard before calling strcasecmp on ctx->auth_type_str
(e.g., treat NULL or empty as a default string or skip comparison) so strcasecmp
never dereferences NULL, and remove the early flb_output_set_context(ins, ctx)
assignment so ins->context is not set on partial failures; instead move
flb_output_set_context(ins, ctx) to the very end of the initialization sequence
(after all validation and flb_output_upstream_set succeed) and only then return
ctx.

else if (strcasecmp(ctx->auth_type_str, "managed_identity") == 0) {
/* Check if client_id indicates system-assigned or user-assigned managed identity */
if (!ctx->client_id) {
flb_plg_error(ins, "When using managed_identity auth, client_id must be set to 'system' for system-assigned or the managed identity client ID");
flb_az_li_ctx_destroy(ctx);
return NULL;
}

if (strcasecmp(ctx->client_id, "system") == 0) {
ctx->auth_type = FLB_AZ_LI_AUTH_MANAGED_IDENTITY_SYSTEM;
} else {
ctx->auth_type = FLB_AZ_LI_AUTH_MANAGED_IDENTITY_USER;
}
}
else {
flb_plg_error(ins, "Invalid auth_type '%s'. Valid options are: 'service_principal' or 'managed_identity'",
ctx->auth_type_str);
flb_az_li_ctx_destroy(ctx);
return NULL;
}
Expand All @@ -91,16 +105,43 @@ struct flb_az_li* flb_az_li_ctx_create(struct flb_output_instance *ins,
return NULL;
}

/* Allocate and set auth url */
ctx->auth_url = flb_sds_create_size(sizeof(FLB_AZ_LI_AUTH_URL_TMPLT) - 1 +
flb_sds_len(ctx->tenant_id));
if (!ctx->auth_url) {
flb_errno();
flb_az_li_ctx_destroy(ctx);
return NULL;
/* Allocate and set auth url based on authentication method */
if (ctx->auth_type == FLB_AZ_LI_AUTH_MANAGED_IDENTITY_SYSTEM) {
/* System-assigned managed identity */
ctx->auth_url = flb_sds_create_size(sizeof(FLB_AZ_LI_MSIAUTH_URL_TEMPLATE) - 1);
if (!ctx->auth_url) {
flb_errno();
flb_az_li_ctx_destroy(ctx);
return NULL;
}
flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
FLB_AZ_LI_MSIAUTH_URL_TEMPLATE, "", "");
}
Comment on lines +108 to +119
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Check flb_sds_snprintf return; bail out on failure

Pre-sizing is fine, but flb_sds_snprintf can fail (returns -1). Handle it to avoid using an uninitialized URL.

-        flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
-                        FLB_AZ_LI_MSIAUTH_URL_TEMPLATE, "", "");
+        ret = flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
+                               FLB_AZ_LI_MSIAUTH_URL_TEMPLATE, "", "");
+        if (ret < 0) {
+            flb_plg_error(ins, "failed composing MSI auth_url (system-assigned)");
+            flb_az_li_ctx_destroy(ctx);
+            return NULL;
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/* Allocate and set auth url based on authentication method */
if (ctx->auth_type == FLB_AZ_LI_AUTH_MANAGED_IDENTITY_SYSTEM) {
/* System-assigned managed identity */
ctx->auth_url = flb_sds_create_size(sizeof(FLB_AZ_LI_MSIAUTH_URL_TEMPLATE) - 1);
if (!ctx->auth_url) {
flb_errno();
flb_az_li_ctx_destroy(ctx);
return NULL;
}
flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
FLB_AZ_LI_MSIAUTH_URL_TEMPLATE, "", "");
}
/* Allocate and set auth url based on authentication method */
if (ctx->auth_type == FLB_AZ_LI_AUTH_MANAGED_IDENTITY_SYSTEM) {
/* System-assigned managed identity */
ctx->auth_url = flb_sds_create_size(sizeof(FLB_AZ_LI_MSIAUTH_URL_TEMPLATE) - 1);
if (!ctx->auth_url) {
flb_errno();
flb_az_li_ctx_destroy(ctx);
return NULL;
}
- flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
ret = flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
FLB_AZ_LI_MSIAUTH_URL_TEMPLATE, "", "");
if (ret < 0) {
flb_plg_error(ins, "failed composing MSI auth_url (system-assigned)");
flb_az_li_ctx_destroy(ctx);
return NULL;
}
}
🤖 Prompt for AI Agents
In plugins/out_azure_logs_ingestion/azure_logs_ingestion_conf.c around lines 108
to 119, the call to flb_sds_snprintf when building ctx->auth_url can fail
(returns -1) and the code currently ignores that; update the code to check the
return value of flb_sds_snprintf, and if it returns a negative value free the
allocated SDS (or call flb_az_li_ctx_destroy(ctx) if that frees it), log the
error (e.g., flb_errno() or a process logger), and return NULL to avoid using an
uninitialized auth_url.

else if (ctx->auth_type == FLB_AZ_LI_AUTH_MANAGED_IDENTITY_USER) {
/* User-assigned managed identity */
ctx->auth_url = flb_sds_create_size(sizeof(FLB_AZ_LI_MSIAUTH_URL_TEMPLATE) - 1 +
sizeof("&client_id=") - 1 +
flb_sds_len(ctx->client_id));
if (!ctx->auth_url) {
flb_errno();
flb_az_li_ctx_destroy(ctx);
return NULL;
}
flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
FLB_AZ_LI_MSIAUTH_URL_TEMPLATE, "&client_id=", ctx->client_id);
}
Comment on lines +120 to +132
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Validate/encode client_id for user-assigned MSI and check snprintf return

  • If client_id can ever be non-GUID (e.g., resource ID or contains special chars), it must be URL-encoded before embedding in the query string.
  • Also check flb_sds_snprintf return.
-        flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
-                        FLB_AZ_LI_MSIAUTH_URL_TEMPLATE, "&client_id=", ctx->client_id);
+        ret = flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
+                               FLB_AZ_LI_MSIAUTH_URL_TEMPLATE, "&client_id=", ctx->client_id);
+        if (ret < 0) {
+            flb_plg_error(ins, "failed composing MSI auth_url (user-assigned)");
+            flb_az_li_ctx_destroy(ctx);
+            return NULL;
+        }

If client_id is not guaranteed to be a bare GUID, confirm and we can add a URL-encode step before formatting it into the URL.


🏁 Script executed:

#!/bin/bash
# Search for MSI auth URL template definition
echo "== FLB_AZ_LI_MSIAUTH_URL_TEMPLATE definition =="
rg -n "FLB_AZ_LI_MSIAUTH_URL_TEMPLATE" -C3 plugins/out_azure_logs_ingestion

echo ""
# Locate client_id declaration, assignment, and config mapping
echo "== client_id occurrences in azure_logs_ingestion_conf.c =="
rg -n "client_id" -C5 plugins/out_azure_logs_ingestion/azure_logs_ingestion_conf.c

echo ""
# Inspect flb_sds_snprintf signature to confirm its return semantics
echo "== flb_sds_snprintf signature and context =="
rg -n "flb_sds_snprintf" -C3 .

Length of output: 36494


Check snprintf return and validate/URL-encode client_id

  • In azure_logs_ingestion_conf.c (around lines 130–132), capture the return value of flb_sds_snprintf(…) into a ret variable; if ret < 0, log an error, destroy the context and return NULL.
  • client_id must be a bare GUID (safe in URLs). If you plan to accept arbitrary resource IDs or other characters, apply URL-encoding or enforce GUID-only input before embedding.

else {
/* Service principal authentication */
ctx->auth_url = flb_sds_create_size(sizeof(FLB_AZ_LI_AUTH_URL_TMPLT) - 1 +
flb_sds_len(ctx->tenant_id));
if (!ctx->auth_url) {
flb_errno();
flb_az_li_ctx_destroy(ctx);
return NULL;
}
flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
FLB_AZ_LI_AUTH_URL_TMPLT, ctx->tenant_id);
}
Comment on lines +133 to 144
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Also check snprintf return for service principal auth_url

Same robustness as MSI paths.

-        flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
-                        FLB_AZ_LI_AUTH_URL_TMPLT, ctx->tenant_id);
+        ret = flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
+                               FLB_AZ_LI_AUTH_URL_TMPLT, ctx->tenant_id);
+        if (ret < 0) {
+            flb_plg_error(ins, "failed composing SP auth_url");
+            flb_az_li_ctx_destroy(ctx);
+            return NULL;
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
else {
/* Service principal authentication */
ctx->auth_url = flb_sds_create_size(sizeof(FLB_AZ_LI_AUTH_URL_TMPLT) - 1 +
flb_sds_len(ctx->tenant_id));
if (!ctx->auth_url) {
flb_errno();
flb_az_li_ctx_destroy(ctx);
return NULL;
}
flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
FLB_AZ_LI_AUTH_URL_TMPLT, ctx->tenant_id);
}
else {
/* Service principal authentication */
ctx->auth_url = flb_sds_create_size(sizeof(FLB_AZ_LI_AUTH_URL_TMPLT) - 1 +
flb_sds_len(ctx->tenant_id));
if (!ctx->auth_url) {
flb_errno();
flb_az_li_ctx_destroy(ctx);
return NULL;
}
- flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
ret = flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
FLB_AZ_LI_AUTH_URL_TMPLT, ctx->tenant_id);
if (ret < 0) {
flb_plg_error(ins, "failed composing SP auth_url");
flb_az_li_ctx_destroy(ctx);
return NULL;
}
}
🤖 Prompt for AI Agents
In plugins/out_azure_logs_ingestion/azure_logs_ingestion_conf.c around lines 133
to 144, the flb_sds_snprintf call that builds ctx->auth_url for
service-principal auth is not checked for failure/overflow; mirror the MSI-path
robustness by capturing the flb_sds_snprintf return value, verify it succeeded
(check for negative return or size >= flb_sds_alloc(ctx->auth_url) as
appropriate), and on failure call flb_errno(), clean up (destroy/free ctx and
ctx->auth_url), and return NULL so you don't proceed with a malformed auth_url.

flb_sds_snprintf(&ctx->auth_url, flb_sds_alloc(ctx->auth_url),
FLB_AZ_LI_AUTH_URL_TMPLT, ctx->tenant_id);

/* Allocate and set dce full url */
ctx->dce_u_url = flb_sds_create_size(sizeof(FLB_AZ_LI_DCE_URL_TMPLT) - 1 +
Expand Down
99 changes: 99 additions & 0 deletions plugins/out_azure_logs_ingestion/azure_logs_ingestion_msiauth.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/* Fluent Bit
* ==========
* Copyright (C) 2015-2024 The Fluent Bit Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <fluent-bit/flb_info.h>
#include <fluent-bit/flb_mem.h>
#include <fluent-bit/flb_log.h>
#include <fluent-bit/flb_utils.h>
#include <fluent-bit/flb_oauth2.h>
#include <fluent-bit/flb_upstream.h>
#include <fluent-bit/flb_http_client.h>

#include "azure_logs_ingestion_msiauth.h"

char *flb_azure_li_msiauth_token_get(struct flb_oauth2 *ctx)
{
int ret;
size_t b_sent;
time_t now;
struct flb_connection *u_conn;
struct flb_http_client *c;

now = time(NULL);
if (ctx->access_token) {
/* validate unexpired token */
if (ctx->expires > now && flb_sds_len(ctx->access_token) > 0) {
return ctx->access_token;
}
}

/* Get Token and store it in the context */
u_conn = flb_upstream_conn_get(ctx->u);
if (!u_conn) {
flb_error("[azure li msi auth] could not get an upstream connection to %s:%i",
ctx->u->tcp_host, ctx->u->tcp_port);
return NULL;
}

/* Create HTTP client context */
c = flb_http_client(u_conn, FLB_HTTP_GET, ctx->uri,
NULL, 0,
ctx->host, atoi(ctx->port),
NULL, 0);
if (!c) {
flb_error("[azure li msi auth] error creating HTTP client context");
flb_upstream_conn_release(u_conn);
return NULL;
}

/* Append HTTP Header */
flb_http_add_header(c, "Metadata", 8, "true", 4);

/* Issue request */
ret = flb_http_do(c, &b_sent);
if (ret != 0) {
flb_warn("[azure li msi auth] cannot issue request, http_do=%i", ret);
}
else {
flb_info("[azure li msi auth] HTTP Status=%i", c->resp.status);
if (c->resp.payload_size > 0 && c->resp.status != 200) {
flb_info("[azure li msi auth] payload:\n%s", c->resp.payload);
}
}

/* Extract token */
if (c->resp.payload_size > 0 && c->resp.status == 200) {
ret = flb_oauth2_parse_json_response(c->resp.payload,
c->resp.payload_size, ctx);
if (ret == 0) {
flb_info("[azure li msi auth] access token from '%s:%s' retrieved",
ctx->host, ctx->port);
flb_http_client_destroy(c);
flb_upstream_conn_release(u_conn);
ctx->issued = time(NULL);
ctx->expires = ctx->issued + ctx->expires_in;
return ctx->access_token;
}
}

flb_http_client_destroy(c);
flb_upstream_conn_release(u_conn);

return NULL;
}
27 changes: 27 additions & 0 deletions plugins/out_azure_logs_ingestion/azure_logs_ingestion_msiauth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/* Fluent Bit
* ==========
* Copyright (C) 2015-2024 The Fluent Bit Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <fluent-bit/flb_info.h>

/* MSI authorization URL template */
#define FLB_AZ_LI_MSIAUTH_URL_TEMPLATE \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2021-02-01%s%s&resource=https://monitor.azure.com"

char *flb_azure_li_msiauth_token_get(struct flb_oauth2 *ctx);
int flb_azure_kusto_conf_destroy(struct flb_az_li *ctx);
1 change: 1 addition & 0 deletions tests/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ if(FLB_IN_LIB)
FLB_RT_TEST(FLB_OUT_LIB "config_map_opts.c")
FLB_RT_TEST(FLB_OUT_COUNTER "out_counter.c")
FLB_RT_TEST(FLB_OUT_AZURE_KUSTO "out_azure_kusto.c")
FLB_RT_TEST(FLB_OUT_AZURE_LOGS_INGESTION "out_azure_logs_ingestion.c")
FLB_RT_TEST(FLB_OUT_DATADOG "out_datadog.c")
FLB_RT_TEST(FLB_OUT_SKYWALKING "out_skywalking.c")
FLB_RT_TEST(FLB_OUT_ES "out_elasticsearch.c")
Expand Down
Loading