Implement iptables forward manager core
This commit is contained in:
109
tests/mocks/iptables-mock.sh
Normal file
109
tests/mocks/iptables-mock.sh
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user