From 0f77ac174b4ed4caabb4a9cb58db0653e0907807 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 28 Apr 2026 21:55:16 +0200 Subject: [PATCH] list und add gehen --- hosting.kdbx | Bin 0 -> 2309 bytes inwx_add_record.py | 104 +++++++++++++++++++++++++++++++++++++++++++++ inwx_list.py | 78 ++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 hosting.kdbx create mode 100644 inwx_add_record.py create mode 100644 inwx_list.py diff --git a/hosting.kdbx b/hosting.kdbx new file mode 100644 index 0000000000000000000000000000000000000000..33451184d2910adb6917e4243b88509a05d3e003 GIT binary patch literal 2309 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 literal 0 HcmV?d00001 diff --git a/inwx_add_record.py b/inwx_add_record.py new file mode 100644 index 0000000..9c88037 --- /dev/null +++ b/inwx_add_record.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +import sys +import os +import subprocess + +# Import-Fix für die Library-Struktur +try: + from INWX.Domrobot import ApiClient +except ImportError: + from inwx.Domrobot import ApiClient + +# --- KONFIGURATION --- +API_URL = 'https://api.domrobot.com' +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +KP_DB_PATH = os.path.join(BASE_DIR, "hosting.kdbx") +KP_ENTRY_NAME = "inwx" + +# Daten für den neuen Record +DOMAIN = "ma151.de" +NEW_NAME = "srv1" # Subdomain +NEW_TYPE = "A" # Record-Typ +NEW_VALUE = "167.86.90.246" +NEW_TTL = 3600 # Time to Live in Sekunden + +def get_creds(): + """Liest User/Passwort sicher aus KeePassXC.""" + try: + cmd = ["keepassxc-cli", "show", "-s", KP_DB_PATH, KP_ENTRY_NAME] + output = subprocess.check_output(cmd, text=True) + creds = {} + for line in output.splitlines(): + if ":" in line: + k, v = line.split(":", 1) + creds[k.strip().lower()] = v.strip() + return creds.get("username") or creds.get("benutzername"), creds.get("password") or creds.get("passwort") + except Exception as e: + print(f"❌ KeePass-Fehler: {e}") + return None, None + +def main(): + user, password = get_creds() + if not user or not password: + sys.exit(1) + + api = ApiClient(api_url=API_URL) + + # 1. Login + login_res = api.login(user, password) + if login_res['code'] != 1000: + print(f"❌ Login fehlgeschlagen: {login_res['msg']}") + sys.exit(1) + + print(f"✅ Login erfolgreich. Prüfe Record: {NEW_NAME}.{DOMAIN} ({NEW_TYPE} -> {NEW_VALUE})") + + # 2. Prüfen, ob der Record bereits existiert + # Wir rufen alle Records der Domain ab + info_res = api.call_api('nameserver.info', {'domain': DOMAIN}) + + if info_res['code'] != 1000: + print(f"❌ Fehler beim Abrufen der Domain-Info: {info_res['msg']}") + api.logout() + sys.exit(1) + + records = info_res['resData'].get('record', []) + + # Den FQDN (Full Qualified Domain Name) zusammenbauen, wie INWX ihn speichert + full_name = f"{NEW_NAME}.{DOMAIN}" + + # Suche nach Dubletten + already_exists = False + for rec in records: + # INWX gibt Namen oft mit oder ohne Punkt am Ende zurück, wir prüfen beides + rec_name = rec['name'].rstrip('.') + if (rec_name == full_name and + rec['type'] == NEW_TYPE and + rec['content'] == NEW_VALUE): + already_exists = True + break + + if already_exists: + print(f"ℹ️ Record existiert bereits exakt so. Keine Änderung nötig.") + else: + print(f"🚀 Record nicht gefunden. Erstelle {full_name}...") + + # 3. Record erstellen + create_params = { + 'domain': DOMAIN, + 'name': NEW_NAME, + 'type': NEW_TYPE, + 'content': NEW_VALUE, + 'ttl': NEW_TTL + } + + create_res = api.call_api('nameserver.createRecord', create_params) + + if create_res['code'] == 1000: + print(f"✅ Erfolg! Record wurde mit ID {create_res['resData']['id']} angelegt.") + else: + print(f"❌ Fehler beim Erstellen: {create_res['msg']} (Code: {create_res['code']})") + + api.logout() + +if __name__ == "__main__": + main() diff --git a/inwx_list.py b/inwx_list.py new file mode 100644 index 0000000..0686d3e --- /dev/null +++ b/inwx_list.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +import sys +import os +import subprocess + +# Import-Fix für Linux/Mac +try: + from INWX.Domrobot import ApiClient +except ImportError: + from inwx.Domrobot import ApiClient + +# --- KONFIGURATION --- +API_URL = 'https://api.domrobot.com' +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +KP_DB_PATH = os.path.join(BASE_DIR, "hosting.kdbx") +KP_ENTRY_NAME = "inwx" +DOMAIN = "ma151.de" + +def get_creds(): + """Holt die echten Daten (inkl. Passwort) aus KeePassXC.""" + try: + # -s sorgt dafür, dass das Passwort nicht als 'PROTECTED' ausgegeben wird + cmd = ["keepassxc-cli", "show", "-s", KP_DB_PATH, KP_ENTRY_NAME] + output = subprocess.check_output(cmd, text=True) + + creds = {} + for line in output.splitlines(): + if ":" in line: + k, v = line.split(":", 1) + creds[k.strip().lower()] = v.strip() + + user = creds.get("username") or creds.get("benutzername") or creds.get("user") + password = creds.get("password") or creds.get("passwort") + + return user, password + except Exception as e: + print(f"❌ KeePass-Fehler: {e}") + return None, None + +def main(): + user, password = get_creds() + if not user or not password: + sys.exit(1) + + # ApiClient mit der korrekten URL (Library fügt /xmlrpc/ an) + api = ApiClient(api_url=API_URL) + + print(f"Versuche Login für: {user}") + + # Login + login_res = api.login(user, password) + + if login_res['code'] == 1000: + print("✅ Login erfolgreich!") + print(f"Rufe Records für {DOMAIN} ab...") + + try: + # Deine Library-Version nutzt laut DEBUG 'call_api' + res = api.call_api('nameserver.info', {'domain': DOMAIN}) + + if res['code'] == 1000: + records = res['resData']['record'] + print(f"\n{'TYP':<8} {'NAME':<35} {'WERT'}") + print("-" * 75) + for rec in records: + print(f"{rec['type']:<8} {rec['name']:<35} {rec['content']}") + else: + print(f"❌ API Fehler: {res['msg']} (Code: {res['code']})") + + except Exception as e: + print(f"❌ Fehler beim Abruf mit call_api: {e}") + + api.logout() + else: + print(f"❌ Login fehlgeschlagen: {login_res['msg']} (Code: {login_res['code']})") + +if __name__ == "__main__": + main()