Zone gezielt bei Plesk erfragen statt alle Domains aufzulisten

Ein Name wie endian.fon-aria.de ist oft nur ein Record in der Zone
fon-aria.de und existiert weder als Domain noch als Abo. Ausserdem darf
nicht jeder API-User alle Domains des Servers auflisten - dann brach das
Tool mit "No domains found on the Plesk server" ab, obwohl die Zone da war.

Die Zone wird jetzt Label fuer Label von unten nach oben gezielt abgefragt
(endian.fon-aria.de -> fon-aria.de), jeweils per site.get und webspace.get
mit Namensfilter. Das Auflisten aller Domains dient nur noch der
Fehlermeldung, die jetzt auch zeigt, welche Namen probiert wurden und was
Plesk dazu gesagt hat.

- neue Option --zone, um die Zone bei Bedarf fest vorzugeben
- get_rec meldet jetzt als Warnung, wenn Plesk keine Records liefert
- run.sh baut das Image immer (Cache), damit kein alter Stand haengen bleibt
- Tests bilden den Fall nach: Zone nur als Abo auffindbar, Auflisten verboten

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
duffyduck
2026-08-13 10:14:51 +02:00
co-authored by Claude Opus 5
parent fd76c18eb0
commit 611593b5c0
7 changed files with 181 additions and 42 deletions
+32 -7
View File
@@ -42,15 +42,32 @@ ZONE.add("NS", "", "ns1.example.com.")
ZONE.add("A", "vpn", "203.0.113.1")
# Wie beim echten Server von Stefan: die Zone haengt an einem Abo (webspace),
# 'site' kennt sie nicht, und dieser API-User darf ueberhaupt nichts auflisten.
SITE_ZONES = {}
WEBSPACE_ZONES = {"example.com": "3"}
ENUMERATION_ALLOWED = False
def fake_request(self, body):
tag = body.tag
if tag == "site":
return ET.fromstring(
'<packet><site><get><result><status>ok</status><id>3</id>'
'<data><gen_info><name>example.com</name></gen_info></data></result></get></site></packet>'
)
if tag == "webspace":
return ET.fromstring('<packet><webspace><get></get></webspace></packet>')
if tag in ("site", "webspace"):
wanted = body.findtext("./get/filter/name")
if wanted is None and not ENUMERATION_ALLOWED:
# _request() wandelt einen <system>-Fehler in eine PleskError um
raise pleskmod.PleskError(f"Plesk API error 1005: Permission denied ({tag}.get)")
zones = SITE_ZONES if tag == "site" else WEBSPACE_ZONES
selected = {n: i for n, i in zones.items() if wanted is None or n == wanted}
if selected:
inner = "".join(
f"<result><status>ok</status><id>{i}</id><data><gen_info>"
f"<name>{n}</name></gen_info></data></result>"
for n, i in selected.items()
)
else:
inner = ("<result><status>error</status><errcode>1013</errcode>"
"<errtext>Object not found</errtext></result>")
return ET.fromstring(f"<packet><{tag}><get>{inner}</get></{tag}></packet>")
if body.find("get_rec") is not None:
parts = "".join(
f'<result><status>ok</status><id>{r["id"]}</id><data><site-id>3</site-id>'
@@ -151,6 +168,14 @@ rc = appmain.main(["www.example.com", "203.0.113.55", "--dns-only", "--env", "/d
assert rc == 0 and not issued
assert any(r["host"] == "www.example.com." and r["value"] == "203.0.113.55" for r in ZONE.records)
print("\n--- run 6: --zone erzwingt die Zone")
issued.clear()
rc = appmain.main(["endian.example.com", "203.0.113.77", "--zone", "example.com",
"--env", "/dev/null"])
assert rc == 0 and issued["domains"] == ["endian.example.com", "*.endian.example.com"], issued
assert any(r["host"] == "endian.example.com." and r["value"] == "203.0.113.77"
for r in ZONE.records), ZONE.records
print("\n--- error paths")
assert appmain.main(["vpn.example.com", "not-an-ip", "--env", "/dev/null"]) == 2
assert appmain.main(["vpn.otherdomain.tld", "203.0.113.1", "--env", "/dev/null"]) == 1