2
0

more consistent behavior of --config and --timeout

This commit is contained in:
Tilman Kranz 2021-11-25 15:32:28 +01:00
parent 9f05043a32
commit 5834235d3c
2 changed files with 75 additions and 30 deletions

View File

@ -1,28 +1,38 @@
# Usage # Usage
``` ```
nft-edit-ruleset [--config [CONFIG_FILE]] [--fail] [--timeout SECONDS] [--yes] nft-edit-ruleset [--config [CONFIG_FILE]] [--fail] [--timeout SECONDS] [--yes]
``` ```
# Description # Description
Interactively edit the current nftables ruleset using the editor specified Interactively edit the current nftables ruleset using the editor specified by
by environment variable EDITOR (defaulting to vim). Optionally, revert environment variable EDITOR (defaulting to vim). Optionally, revert changes
changes after a timeout given in seconds. after a timeout given in seconds.
# Options # Options
- `-c`, `--config [CONFIG_FILE]`: On successfully applying the - `-c`, `--config [CONFIG_FILE]`:
changes, save ruleset to `CONFIG_FILE` (default: /etc/nftables.conf). If set, on successfully applying changes, save the resulting ruleset to
- `-f`, `--fail`: Exit unsuccessfully if changes fail to apply. `CONFIG_FILE` (if `CONFIG_FILE` is not specified, it defaults to
- `-h`, `--help`: Display this message and exit. /etc/nftables.conf).
- `-t NUM`, `--timeout NUM`: Revert changes after NUM seconds. This option is mutually exclusive with option `--timeout`.
- `-y`, `--yes`: No confirmation before applying changes. - `-f`, `--fail`:
Exit on changes failing to apply instead of prompting the user for re-edit.
- `-h`, `--help`:
Display this message and exit.
- `-t NUM`, `--timeout NUM`:
Revert any changes NUM seconds after they have been applied. This is
implemented with a systemd timer that remains active after the program
has ended.
This option is mutually exclusive with option `--config`.
- `-y`, `--yes`:
Do not prompt for confirmation before applying changes.
# Exit Codes # Exit Codes
* 0: Success: No changes to apply or changes applied successfully. - 0: Success: No changes to apply or changes applied successfully.
* 1: Error: Usage error or failed or aborted changes. - 1: Error: Usage error or failed or aborted changes.
# Author and License # Author and License

View File

@ -43,12 +43,24 @@ set_timeout() {
local ruleset=$1 local ruleset=$1
local seconds=$2 local seconds=$2
systemd-run \ if test -z "$(command -v systemd-run)" ; then
--description="Reverting nftables ruleset changes by $0 (PID=$$)" \ echo "ERROR: Setting undo timeout failed (systemd-run not found)" >&2
return 1
fi
if systemd-run \
--unit="nft-edit-ruleset-revert-changes" \
--description="reverting nftables ruleset changes by $0 (PID=$$)" \
--on-active="$seconds" \ --on-active="$seconds" \
--timer-property=AccuracySec=100ms \ --timer-property=AccuracySec=100ms \
--quiet \ --quiet \
bash -c "nft -f '$ruleset' ; rm -f '$ruleset'" bash -c "nft -f '$ruleset' ; rm -f '$ruleset'"
then
return 0
else
echo "ERROR: Setting undo timeout failed (already running?)" >&2
return 1
fi
} }
store_config() { store_config() {
@ -90,15 +102,21 @@ after a timeout given in seconds.
# OPTIONS # OPTIONS
- \`-c\`, \`--config [CONFIG_FILE]\`: - \`-c\`, \`--config [CONFIG_FILE]\`:
On success, save ruleset to \`CONFIG_FILE\` (default: $default_config_file). If set, on successfully applying changes, save the resulting ruleset to
\`CONFIG_FILE\` (if \`CONFIG_FILE\` is not specified, it defaults to
$default_config_file).
This option is mutually exclusive with option \`--timeout\`.
- \`-f\`, \`--fail\`: - \`-f\`, \`--fail\`:
Exit unsuccessfully if changes fail to apply. Exit on changes failing to apply instead of prompting the user for re-edit.
- \`-h\`, \`--help\`: - \`-h\`, \`--help\`:
Display this message and exit. Display this message and exit.
- \`-t NUM\`, \`--timeout NUM\`: - \`-t NUM\`, \`--timeout NUM\`:
Revert changes after NUM seconds. Revert any changes NUM seconds after they have been applied. This is
implemented with a systemd timer that remains active after the program
has ended.
This option is mutually exclusive with option \`--config\`.
- \`-y\`, \`--yes\`: - \`-y\`, \`--yes\`:
No confirmation before applying changes. Do not prompt for confirmation before applying changes.
# EXIT CODES # EXIT CODES
- 0: Success: No changes to apply or changes applied successfully. - 0: Success: No changes to apply or changes applied successfully.
@ -130,12 +148,16 @@ EOF
-c|--config) -c|--config)
config=true config=true
if test "$#" -gt 0 && { test -w "$2" || test -w "$(dirname "$2")" ; } ; then if \
test "$#" -gt 0 && \
! [[ "$2" =~ ^- ]] && \
{ test -w "$2" || test -w "$(dirname "$2")" ; }
then
shift 1 shift 1
config_file=$1 config_file=$1
elif test -z "$default_config_file" ; then elif test -z "$default_config_file" ; then
echo \ echo \
"ERROR: Option \`--config\` was used without an argument," \ "ERROR: Option \`--config\` was used without a valid argument," \
"but no default location of a file \"nftables.conf\" could be found" \ "but no default location of a file \"nftables.conf\" could be found" \
"(use \`--config CONFIG_FILE\` to specify a location); aborted." >&2 "(use \`--config CONFIG_FILE\` to specify a location); aborted." >&2
exit 1 exit 1
@ -159,6 +181,11 @@ EOF
fi fi
done done
if "$config" && "$timeout" ; then
echo "ERROR: Options \`--config\` and \`--timeout\` are mutually exclusive; aborted." >&2
exit 1
fi
## ##
# Main Program # Main Program
@ -179,6 +206,8 @@ nft list ruleset >> "$tmp"
cat "$tmp" > "$tmp_old" cat "$tmp" > "$tmp_old"
rv=0
while true ; do while true ; do
editor=${EDITOR:-vim} editor=${EDITOR:-vim}
@ -192,7 +221,8 @@ while true ; do
echo "Stored unchanged ruleset to config_file=\"$config_file\"." echo "Stored unchanged ruleset to config_file=\"$config_file\"."
else else
echo "ERROR: Storing unchanged ruleset to config_file=\"$config_file\" failed." >&2 echo "ERROR: Storing unchanged ruleset to config_file=\"$config_file\" failed." >&2
exit 1 rv=1
break
fi fi
fi fi
@ -207,36 +237,39 @@ while true ; do
;; ;;
*) *)
echo "Aborting (user request)." echo "Aborting (user request)."
exit 1 rv=1
break
;; ;;
esac esac
fi fi
if ! nft -c -f "$tmp" ; then if ! nft -c -f "$tmp" ; then
if "$fail" ; then if "$fail" ; then
exit 1 rv=1
break
else else
read -p "Errors in changes detected (Ctrl-c to abort, ENTER to continue editing)" -r answer read -p "Errors in changes detected (Ctrl-c to abort, ENTER to continue editing)" -r answer
fi fi
elif ! nft -f "$tmp" ; then elif ! nft -f "$tmp" ; then
if "$fail" ; then if "$fail" ; then
exit 1 rv=1
break
else else
read -p "Errors when applying changes (Ctrl-c to abort, ENTER to continue editing)" -r answer read -p "Errors when applying changes (Ctrl-c to abort, ENTER to continue editing)" -r answer
fi fi
else else
if "$timeout" ; then
set_timeout "$tmp_old" "$timeout_secs"
fi
echo "Changes applied successfully." echo "Changes applied successfully."
if "$config" ; then if "$timeout" ; then
if ! set_timeout "$tmp_old" "$timeout_secs" ; then
rv=1
fi
elif "$config" ; then
if store_config "$tmp" "$config_file" ; then if store_config "$tmp" "$config_file" ; then
echo "Stored changed ruleset to config_file=\"$config_file\"." echo "Stored changed ruleset to config_file=\"$config_file\"."
else else
echo "ERROR: Storing changed ruleset to config_file=\"$config_file\" failed." >&2 echo "ERROR: Storing changed ruleset to config_file=\"$config_file\" failed." >&2
exit 1 rv=1
fi fi
fi fi
@ -245,6 +278,8 @@ while true ; do
fi fi
done done
exit $rv
## ##
# Exit Codes # Exit Codes
# - 0: Success: No changes to apply or changes applied successfully. # - 0: Success: No changes to apply or changes applied successfully.