Polish KarlDNS production UI and docs

This commit is contained in:
StasonJatham committed 2026-05-21 10:05:40 +02:00
1 parent ca92dc211a
commit 5beee0e5c6
61 files changed
+1566 -523

No files matched your search

+13 -12
View File
@@ -22,6 +22,7 @@ from ..schemas import (
_credentials_response,
_managed_record,
)
from .path_params import ManagementSlugPath, UpdateSlugPath
router = APIRouter(prefix="/api/v1")
@@ -30,7 +31,7 @@ router = APIRouter(prefix="/api/v1")
"/hostnames/magic",
response_model=HostnameCredentials,
status_code=status.HTTP_201_CREATED,
summary="Generate a provider-owned DynDNS hostname",
summary="Create a KarlDNS hostname",
tags=["hostnames"],
responses={500: {"model": ErrorResponse}},
)
@@ -42,12 +43,12 @@ async def create_magic_hostname(payload: MagicHostnameRequest, service: ServiceD
@router.get(
"/management/{management_slug}",
response_model=ManagedRecord,
summary="Read a hostname by magic management link",
description="Uses the secret bearer management slug. Dashboard passwords protect only the web dashboard and are not required for this JSON API route.",
summary="Read a hostname by private dashboard link",
description="Uses the private dashboard link secret. Dashboard passwords protect only the web dashboard, not this API endpoint.",
tags=["management"],
responses={404: {"model": ErrorResponse}},
)
async def read_managed_hostname(management_slug: str, store: StoreDep, service: ServiceDep) -> ManagedRecord:
async def read_managed_hostname(management_slug: ManagementSlugPath, store: StoreDep, service: ServiceDep) -> ManagedRecord:
account = await run_in_threadpool(store.get_account_by_management_slug, management_slug)
if not account or account["disabled"]:
raise HTTPException(status_code=404, detail="not found")
@@ -57,12 +58,12 @@ async def read_managed_hostname(management_slug: str, store: StoreDep, service:
@router.delete(
"/management/{management_slug}",
status_code=status.HTTP_204_NO_CONTENT,
summary="Delete a hostname by magic management link",
description="Uses the secret bearer management slug. Dashboard passwords protect only the web dashboard and are not required for this JSON API route.",
summary="Delete a hostname by private dashboard link",
description="Uses the private dashboard link secret. Dashboard passwords protect only the web dashboard, not this API endpoint.",
tags=["management"],
responses={404: {"model": ErrorResponse}, 500: {"model": ErrorResponse}},
)
async def delete_managed_hostname(management_slug: str, store: StoreDep, service: ServiceDep) -> Response:
async def delete_managed_hostname(management_slug: ManagementSlugPath, store: StoreDep, service: ServiceDep) -> Response:
account = await run_in_threadpool(store.get_account_by_management_slug, management_slug)
if not account or account["disabled"]:
raise HTTPException(status_code=404, detail="not found")
@@ -70,7 +71,7 @@ async def delete_managed_hostname(management_slug: str, store: StoreDep, service
try:
await run_in_threadpool(service.delete_account, hostname, "api")
except DnsProviderError as exc:
raise HTTPException(status_code=500, detail="DNS delete failed; hostname was not deleted") from exc
raise HTTPException(status_code=500, detail="DNS delete failed. Hostname was not deleted.") from exc
return Response(status_code=status.HTTP_204_NO_CONTENT)
@@ -116,7 +117,7 @@ async def verify_domain(payload: VerifyDomainRequest, service: ServiceDep) -> Ve
return VerifyDomainResponse(
domain=domain,
verified=True,
message="domain verified",
message="Domain verified",
claim_secret=payload.claim_secret,
)
@@ -125,7 +126,7 @@ async def verify_domain(payload: VerifyDomainRequest, service: ServiceDep) -> Ve
"/hostnames/custom",
response_model=HostnameCredentials,
status_code=status.HTTP_201_CREATED,
summary="Generate credentials for a verified custom hostname",
summary="Create a hostname for a verified domain",
tags=["hostnames"],
responses={400: {"model": ErrorResponse}, 403: {"model": ErrorResponse}, 409: {"model": ErrorResponse}},
)
@@ -147,7 +148,7 @@ async def create_custom_hostname(payload: CustomHostnameRequest, service: Servic
responses={404: {"model": ErrorResponse}, 500: {"model": ErrorResponse}},
)
async def update_hostname(
update_slug: str,
update_slug: UpdateSlugPath,
request: Request,
store: StoreDep,
service: ServiceDep,
@@ -174,6 +175,6 @@ async def update_hostname(
except BadIpError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
except DnsProviderError as exc:
raise HTTPException(status_code=500, detail="DNS publish failed") from exc
raise HTTPException(status_code=500, detail="DNS update failed") from exc
result = outcome.result
return RouterUpdateResponse(status="good" if result.changed else "nochg", hostname=hostname, ip=result.ipv4 or result.ipv6 or "")