extract-fw-host-vars.py: write host_vars/<host>/<short>-ipt-server.yml by default.

Without -o the script now writes the standard host_vars file (relative to
the script, independent of the cwd). An existing file is only overwritten
with --force; this is checked before connecting to the host. -o - prints
to stdout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-03 01:28:00 +01:00
co-authored by Claude Opus 5.5
parent b585f3c122
commit 0499706703
2 changed files with 40 additions and 16 deletions
+32 -10
View File
@@ -3,13 +3,17 @@
Extract ipt-firewall configuration from a host and generate host_vars YAML. Extract ipt-firewall configuration from a host and generate host_vars YAML.
Reads /etc/ipt-firewall/{interfaces,main}_ipv{4,6}.conf via SSH, Reads /etc/ipt-firewall/{interfaces,main}_ipv{4,6}.conf via SSH,
maps all variables to Ansible fw_* names, and writes a host_vars file. maps all variables to Ansible fw_* names, and writes a host_vars file
(default: host_vars/<hostname>/<short-hostname>-ipt-server.yml next to this
script; an existing file is only overwritten with --force).
Usage: Usage:
./extract-fw-host-vars.py <hostname> [--user USER] [--port PORT] [--sudo] [--from-dir DIR] [--output FILE] [--dry-run] ./extract-fw-host-vars.py <hostname> [--user USER] [--port PORT] [--sudo] [--from-dir DIR]
[--output FILE|-] [--force] [--dry-run]
Example: Example:
./extract-fw-host-vars.py cl-01.oopen.de ./extract-fw-host-vars.py cl-01.oopen.de # -> host_vars/cl-01.oopen.de/cl-01-ipt-server.yml
./extract-fw-host-vars.py cl-01.oopen.de -o - # print to stdout
./extract-fw-host-vars.py cl-01.oopen.de --user root --dry-run ./extract-fw-host-vars.py cl-01.oopen.de --user root --dry-run
""" """
@@ -746,7 +750,10 @@ def main():
parser.add_argument("hostname", help="Target hostname (must be in SSH config or known_hosts)") parser.add_argument("hostname", help="Target hostname (must be in SSH config or known_hosts)")
parser.add_argument("--user", "-u", default="chris", help="SSH user (default: chris)") parser.add_argument("--user", "-u", default="chris", help="SSH user (default: chris)")
parser.add_argument("--port", "-p", type=int, default=None, help="SSH port (default: 22)") parser.add_argument("--port", "-p", type=int, default=None, help="SSH port (default: 22)")
parser.add_argument("--output", "-o", default=None, help="Output file (default: stdout)") parser.add_argument("--output", "-o", default=None,
help="Output file, '-' for stdout "
"(default: host_vars/<hostname>/<short-hostname>-ipt-server.yml)")
parser.add_argument("--force", "-f", action="store_true", help="Overwrite an existing output file")
parser.add_argument("--sudo", "-s", action="store_true", parser.add_argument("--sudo", "-s", action="store_true",
help="Read files via sudo (prompts for sudo password once)") help="Read files via sudo (prompts for sudo password once)")
parser.add_argument("--from-dir", "-d", default=None, parser.add_argument("--from-dir", "-d", default=None,
@@ -770,6 +777,21 @@ def main():
print(f"ssh {args.user}@{hostname} {cmd} {path}") print(f"ssh {args.user}@{hostname} {cmd} {path}")
return return
# Determine the output file first, so an existing file aborts before any SSH
out_path = None
if args.output != "-":
if args.output:
out_path = Path(args.output)
else:
# Same as ${HOSTNAME%.*.*} in the docs: a.mx.oopen.de -> a.mx
short = hostname.rsplit(".", 2)[0] if hostname.count(".") >= 2 else hostname
out_path = Path(__file__).resolve().parent / "host_vars" / hostname / f"{short}-ipt-server.yml"
if out_path.exists() and not args.force:
print(f"ERROR: {out_path} already exists — use --force to overwrite "
"or -o - to print to stdout", file=sys.stderr)
sys.exit(1)
contents = {} contents = {}
if args.from_dir: if args.from_dir:
for key, path in files.items(): for key, path in files.items():
@@ -814,13 +836,13 @@ def main():
yaml_text = render_yaml(hostname, host_vars, all_warnings) yaml_text = render_yaml(hostname, host_vars, all_warnings)
if args.output: if out_path is None:
out_path = Path(args.output)
out_path.parent.mkdir(parents=True, exist_ok=True)
out_path.write_text(yaml_text)
print(f"Written to {out_path}", file=sys.stderr)
else:
print(yaml_text) print(yaml_text)
return
out_path.parent.mkdir(parents=True, exist_ok=True)
out_path.write_text(yaml_text)
print(f"Written to {out_path}", file=sys.stderr)
if __name__ == "__main__": if __name__ == "__main__":
+8 -6
View File
@@ -56,12 +56,15 @@ mappt alle Variablen auf die `fw_*`-Ansible-Variablen und schreibt eine fertige
cd /path/to/ansible/oopen-server cd /path/to/ansible/oopen-server
HOSTNAME=<hostname> HOSTNAME=<hostname>
./extract-fw-host-vars.py ${HOSTNAME} --sudo \ ./extract-fw-host-vars.py ${HOSTNAME} --sudo
-o host_vars/${HOSTNAME}/${HOSTNAME%.*.*}-ipt-server.yml
``` ```
Das Skript fragt einmalig nach dem `sudo`-Passwort. Kann eine der Dateien nicht Das Skript fragt einmalig nach dem `sudo`-Passwort und schreibt nach
gelesen werden, bricht es ab, ohne etwas zu schreiben. `host_vars/${HOSTNAME}/${HOSTNAME%.*.*}-ipt-server.yml`. Eine vorhandene Datei
wird nur mit `--force` überschrieben (dabei wird `fw_manage_config` wieder
`false`); mit `-o -` geht die Ausgabe nach stdout, mit `-o DATEI` in eine
andere Datei. Kann eine der Conf-Dateien nicht gelesen werden, bricht das
Skript ab, ohne etwas zu schreiben.
Alternativ ohne Passwortabfrage (sudo über `ansible_become_password` aus dem Vault): Alternativ ohne Passwortabfrage (sudo über `ansible_become_password` aus dem Vault):
die Dateien mit Ansible holen und lokal einlesen: die Dateien mit Ansible holen und lokal einlesen:
@@ -71,8 +74,7 @@ for f in interfaces_ipv4 interfaces_ipv6 main_ipv4 main_ipv6 ; do
ansible ${HOSTNAME} -b -m fetch \ ansible ${HOSTNAME} -b -m fetch \
-a "src=/etc/ipt-firewall/${f}.conf dest=/tmp/fw-${HOSTNAME}/ flat=yes" -a "src=/etc/ipt-firewall/${f}.conf dest=/tmp/fw-${HOSTNAME}/ flat=yes"
done done
./extract-fw-host-vars.py ${HOSTNAME} --from-dir /tmp/fw-${HOSTNAME} \ ./extract-fw-host-vars.py ${HOSTNAME} --from-dir /tmp/fw-${HOSTNAME}
-o host_vars/${HOSTNAME}/${HOSTNAME%.*.*}-ipt-server.yml
rm -rf /tmp/fw-${HOSTNAME} rm -rf /tmp/fw-${HOSTNAME}
``` ```