rsyslog/tests/omazuredce-interrupt.sh
Jan Kängsepp 0006fffe0d Add azure Monitor API ingestion module
add initial tests

omazuredce: add Azure Monitor output module

This adds a documented Azure Monitor output path so rsyslog can
ship events to Azure-hosted observability workflows. It also makes
the module easier to review and iterate on as a project feature.

Impact: adds a new output module, config parameters, docs, and tests.

Before: rsyslog had no native Azure Monitor DCE output module.
After: rsyslog can batch and send records to Azure Monitor via
omazuredce.

The change adds a new omazuredce plugin and wires it into the
build system and module map. The module obtains Azure tokens,
renders payloads from templates, batches records by size, and
flushes them through the existing action queue model.

The patch also documents the module and its parameters so the
feature is usable without external notes. Supporting config and
build integration are included so the module can be compiled and
packaged consistently with the rest of the tree.

AI-Agent: Codex 2025-06
With the help of AI-Agents: Codex

add tests and address issues

address issues

more issues

more issues

more issues

issues

issues

fix issues

fixfix

fixy

fix

fix fixy fix pants

fix fixy fix pants2

redo the doc
2026-03-17 23:02:51 +02:00

190 lines
5.8 KiB
Bash
Executable File

#!/bin/bash
# This file is part of the rsyslog project, released under ASL 2.0
echo This test must be run as root [connection interruption requires iptables]
echo "For variables to be passed use --preserve-env=AZURE_DCE_CLIENT_ID,AZURE_DCE_CLIENT_SECRET,AZURE_DCE_TENANT_ID,AZURE_DCE_URL,AZURE_DCE_DCR_ID,AZURE_DCE_TABLE_NAME"
if [ "$EUID" -ne 0 ]; then
exit 77
fi
. ${srcdir:=.}/diag.sh init
. ${srcdir:=.}/omazuredce-env.sh
require_plugin "omazuredce"
omazuredce_require_env
if ! command -v iptables >/dev/null 2>&1; then
echo "SKIP: iptables command not available - SKIPPING"
exit 77
fi
if ! command -v ip6tables >/dev/null 2>&1; then
ip6tables=
fi
export NUMMESSAGES=400
export interrupt_port="$(omazuredce_url_port)"
export TEST_TIMEOUT_WAIT=180
interrupt_status_file="$RSYSLOG_DYNNAME.interrupt.status"
interrupt_detail_file="$RSYSLOG_DYNNAME.interrupt.detail"
interrupt_ipv4_hosts="$(omazuredce_url_ips_v4)"
interrupt_ipv6_hosts="$(omazuredce_url_ips_v6)"
if [[ -z "$interrupt_ipv4_hosts" && -z "$interrupt_ipv6_hosts" ]]; then
echo "SKIP: unable to resolve AZURE_DCE_URL host to an IP address - SKIPPING"
exit 77
fi
if [[ -n "$interrupt_ipv6_hosts" && -z "${ip6tables:-}" ]]; then
if [[ -n "$interrupt_ipv4_hosts" ]]; then
echo "NOTICE: ip6tables command not available, skipping IPv6 interruption targets"
interrupt_ipv6_hosts=
else
echo "SKIP: ip6tables command not available for IPv6-only interruption target - SKIPPING"
exit 77
fi
fi
omazuredce_post_count() {
if [ -f "$RSYSLOG_OUT_LOG" ]; then
grep -c -F "omazuredce: posted batch records=" < "$RSYSLOG_OUT_LOG"
else
echo 0
fi
}
omazuredce_fail_count() {
if [ -f "$RSYSLOG_OUT_LOG" ]; then
grep -c -F "omazuredce: batch post failed:" < "$RSYSLOG_OUT_LOG"
else
echo 0
fi
}
omazuredce_add_reject_rules() {
local host
for host in $interrupt_ipv4_hosts; do
iptables -I OUTPUT -d "$host" -p tcp --dport "$interrupt_port" -j REJECT --reject-with tcp-reset || return 1
iptables -I INPUT -s "$host" -p tcp --sport "$interrupt_port" -j REJECT --reject-with tcp-reset || return 1
done
for host in $interrupt_ipv6_hosts; do
ip6tables -I OUTPUT -d "$host" -p tcp --dport "$interrupt_port" -j REJECT --reject-with tcp-reset || return 1
ip6tables -I INPUT -s "$host" -p tcp --sport "$interrupt_port" -j REJECT --reject-with tcp-reset || return 1
done
}
omazuredce_del_reject_rules() {
local host
for host in $interrupt_ipv4_hosts; do
iptables -D OUTPUT -d "$host" -p tcp --dport "$interrupt_port" -j REJECT --reject-with tcp-reset 2>/dev/null || true
iptables -D INPUT -s "$host" -p tcp --sport "$interrupt_port" -j REJECT --reject-with tcp-reset 2>/dev/null || true
done
for host in $interrupt_ipv6_hosts; do
ip6tables -D OUTPUT -d "$host" -p tcp --dport "$interrupt_port" -j REJECT --reject-with tcp-reset 2>/dev/null || true
ip6tables -D INPUT -s "$host" -p tcp --sport "$interrupt_port" -j REJECT --reject-with tcp-reset 2>/dev/null || true
done
}
omazuredce_cleanup_interrupt() {
if [ -n "${interrupt_bg_pid:-}" ]; then
kill "$interrupt_bg_pid" 2>/dev/null || true
wait "$interrupt_bg_pid" 2>/dev/null || true
fi
omazuredce_del_reject_rules
}
omazuredce_interrupt_traffic() {
local tries
: >"$interrupt_status_file"
tries=0
while [ "$tries" -lt 8 ]; do
if [ "$(omazuredce_post_count)" -ge 2 ]; then
echo "Injecting temporary iptables reject for port ${interrupt_port}"
if ! omazuredce_add_reject_rules; then
echo "skip" >"$interrupt_status_file"
echo "unable to insert iptables/ip6tables reject rules" >"$interrupt_detail_file"
omazuredce_del_reject_rules
return
fi
$TESTTOOL_DIR/msleep 750
omazuredce_del_reject_rules
if [ "$(omazuredce_fail_count)" -gt 0 ]; then
echo "done" >"$interrupt_status_file"
return
fi
tries=$((tries + 1))
else
$TESTTOOL_DIR/msleep 100
fi
done
echo "done" >"$interrupt_status_file"
}
trap omazuredce_cleanup_interrupt EXIT
generate_conf
add_conf '
global(processInternalMessages="on" internalmsg.severity="info")
module(load="../plugins/omazuredce/.libs/omazuredce")
template(name="tplAzureDceInterrupt" type="list" option.jsonftree="on") {
property(outname="TimeGenerated" name="timereported" dateFormat="rfc3339" format="jsonf")
property(outname="host" name="hostname" format="jsonf")
property(outname="message" name="msg" format="jsonf")
}
local4.* action(
type="omazuredce"
template="tplAzureDceInterrupt"
client_id="'$AZURE_DCE_CLIENT_ID'"
client_secret=`echo $AZURE_DCE_CLIENT_SECRET`
tenant_id="'$AZURE_DCE_TENANT_ID'"
dce_url="'$AZURE_DCE_URL'"
dcr_id="'$AZURE_DCE_DCR_ID'"
table_name="'$AZURE_DCE_TABLE_NAME'"
max_batch_bytes="4096"
flush_timeout_ms="0"
queue.type="FixedArray"
queue.size="20000"
queue.dequeueBatchSize="64"
queue.minDequeueBatchSize="32"
queue.minDequeueBatchSize.timeout="1000"
queue.workerThreads="1"
queue.workerThreadMinimumMessages="32"
queue.timeoutWorkerthreadShutdown="60000"
queue.timeoutEnqueue="2000"
queue.timeoutshutdown="1000"
action.resumeInterval="1"
action.resumeRetryCount="-1"
)
action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
'
startup
injectmsg 0 $NUMMESSAGES
omazuredce_interrupt_traffic &
interrupt_bg_pid=$!
wait_file_lines --count-function omazuredce_post_count "$RSYSLOG_OUT_LOG" 5 "$TEST_TIMEOUT_WAIT"
wait "$interrupt_bg_pid"
interrupt_bg_pid=
if [[ -f "$interrupt_status_file" && "$(cat "$interrupt_status_file")" == "skip" ]]; then
echo "SKIP: $(cat "$interrupt_detail_file") - SKIPPING"
exit 77
fi
shutdown_when_empty
wait_shutdown
content_check "omazuredce: batch post failed:"
content_check "omazuredce: posted batch records="
post_count=$(grep -c -F "omazuredce: posted batch records=" < "$RSYSLOG_OUT_LOG")
if [ "${post_count:=0}" -lt 2 ]; then
echo "FAIL: expected multiple successful omazuredce batch posts after interruption, got $post_count"
cat -n "$RSYSLOG_OUT_LOG"
error_exit 1
fi
exit_test