Files
IPTables-Management/tests/mocks/iptables-mock.sh
ahdoawhfo 26fbcf3584 Mark runnable scripts executable in git
The repo was committed from WSL with core.filemode=false, so the exec
bit was never recorded. After actions/checkout the entry script comes
down as 100644 and tests/test_cli.sh fails with Permission denied.

Set mode 100755 on every script that is invoked directly (entry,
installer, test suite, mock binaries). Sourced helpers under lib/
keep 100644 per convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 13:58:42 +08:00

110 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
: "${IPTABLES_MOCK_DIR:=/tmp/iptables-mock}"
: "${IPTABLES_MOCK_LOG:=${IPTABLES_MOCK_DIR}/calls.log}"
mkdir -p "${IPTABLES_MOCK_DIR}"
touch "${IPTABLES_MOCK_LOG}"
base=$(basename -- "$0")
case ${base} in
iptables|iptables-save) family=4 ;;
ip6tables|ip6tables-save) family=6 ;;
*) family=${IPTABLES_MOCK_FAMILY:-4} ;;
esac
state_file="${IPTABLES_MOCK_DIR}/state.v${family}"
counter_file="${IPTABLES_MOCK_DIR}/add-counter"
touch "${state_file}" "${counter_file}"
serialize_args() {
local out=''
local arg
for arg in "$@"; do
out+="${arg}"$'\t'
done
printf '%s' "${out}"
}
line_key() {
local table=$1
local chain=$2
shift 2
printf '%s|%s|%s' "${table}" "${chain}" "$(serialize_args "$@")"
}
log_call() {
printf '%s %s\n' "${base}" "$*" >>"${IPTABLES_MOCK_LOG}"
}
load_rule_exists() {
local key=$1
grep -Fqx -- "${key}" "${state_file}"
}
save_emit() {
local table chain serialized
while IFS='|' read -r table chain serialized || [[ -n ${table:-} ]]; do
[[ -n ${table:-} ]] || continue
IFS=$'\t' read -r -a args <<<"${serialized}"
printf -- '-A %s' "${chain}"
local arg
for arg in "${args[@]}"; do
[[ -n ${arg} ]] || continue
printf ' %s' "${arg}"
done
printf '\n'
done <"${state_file}"
}
increment_add_counter() {
local count=0
count=$(cat "${counter_file}")
count=$((count + 1))
printf '%s\n' "${count}" >"${counter_file}"
printf '%s\n' "${count}"
}
if [[ ${base} == *save ]]; then
save_emit
exit 0
fi
log_call "$@"
table='filter'
if (($# >= 2)) && [[ $1 == -t ]]; then
table=$2
shift 2
fi
operation=${1-}
chain=${2-}
shift 2 || true
key=$(line_key "${table}" "${chain}" "$@")
case ${operation} in
-A)
current=$(increment_add_counter)
if [[ -n ${IPTABLES_MOCK_FAIL_ON_N:-} && ${current} == "${IPTABLES_MOCK_FAIL_ON_N}" ]]; then
exit 1
fi
printf '%s\n' "${key}" >>"${state_file}"
;;
-D)
if ! load_rule_exists "${key}"; then
exit 1
fi
grep -Fvx -- "${key}" "${state_file}" >"${state_file}.tmp" || true
mv "${state_file}.tmp" "${state_file}"
;;
-C)
load_rule_exists "${key}"
;;
*)
printf 'unsupported operation: %s\n' "${operation}" >&2
exit 2
;;
esac