Initial commit: Vultr API v2 Python wrapper with FastAPI server
- vultr_api/: Python library wrapping Vultr API v2 - 17 resource modules (instances, dns, firewall, vpc, etc.) - Pagination support, error handling - server/: FastAPI REST server - All API endpoints exposed via HTTP - X-API-Key header authentication - Swagger docs at /docs - Podman quadlet config for systemd deployment Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
155
server/routers/dns.py
Normal file
155
server/routers/dns.py
Normal file
@@ -0,0 +1,155 @@
|
||||
"""DNS router"""
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from typing import Optional
|
||||
from pydantic import BaseModel
|
||||
|
||||
from vultr_api import VultrClient
|
||||
from deps import get_client
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
class CreateDomainRequest(BaseModel):
|
||||
domain: str
|
||||
ip: Optional[str] = None
|
||||
|
||||
|
||||
class CreateRecordRequest(BaseModel):
|
||||
type: str
|
||||
name: str
|
||||
data: str
|
||||
ttl: Optional[int] = 300
|
||||
priority: Optional[int] = None
|
||||
|
||||
|
||||
class UpdateRecordRequest(BaseModel):
|
||||
name: Optional[str] = None
|
||||
data: Optional[str] = None
|
||||
ttl: Optional[int] = None
|
||||
priority: Optional[int] = None
|
||||
|
||||
|
||||
@router.get("/domains")
|
||||
async def list_domains(
|
||||
per_page: int = Query(25, le=500),
|
||||
cursor: Optional[str] = None,
|
||||
client: VultrClient = Depends(get_client)
|
||||
):
|
||||
"""List all DNS domains"""
|
||||
return client.dns.list_domains(per_page=per_page, cursor=cursor)
|
||||
|
||||
|
||||
@router.get("/domains/all")
|
||||
async def list_all_domains(client: VultrClient = Depends(get_client)):
|
||||
"""List all DNS domains (auto-paginated)"""
|
||||
return {"domains": client.dns.list_all_domains()}
|
||||
|
||||
|
||||
@router.get("/domains/{domain}")
|
||||
async def get_domain(domain: str, client: VultrClient = Depends(get_client)):
|
||||
"""Get DNS domain details"""
|
||||
return client.dns.get_domain(domain)
|
||||
|
||||
|
||||
@router.post("/domains")
|
||||
async def create_domain(req: CreateDomainRequest, client: VultrClient = Depends(get_client)):
|
||||
"""Create a DNS domain"""
|
||||
return client.dns.create_domain(req.domain, ip=req.ip)
|
||||
|
||||
|
||||
@router.delete("/domains/{domain}")
|
||||
async def delete_domain(domain: str, client: VultrClient = Depends(get_client)):
|
||||
"""Delete a DNS domain"""
|
||||
return client.dns.delete_domain(domain)
|
||||
|
||||
|
||||
@router.get("/domains/{domain}/soa")
|
||||
async def get_soa(domain: str, client: VultrClient = Depends(get_client)):
|
||||
"""Get SOA record for a domain"""
|
||||
return client.dns.get_soa(domain)
|
||||
|
||||
|
||||
@router.get("/domains/{domain}/dnssec")
|
||||
async def get_dnssec(domain: str, client: VultrClient = Depends(get_client)):
|
||||
"""Get DNSSEC info for a domain"""
|
||||
return client.dns.get_dnssec(domain)
|
||||
|
||||
|
||||
# Records
|
||||
@router.get("/domains/{domain}/records")
|
||||
async def list_records(
|
||||
domain: str,
|
||||
per_page: int = Query(25, le=500),
|
||||
cursor: Optional[str] = None,
|
||||
client: VultrClient = Depends(get_client)
|
||||
):
|
||||
"""List DNS records for a domain"""
|
||||
return client.dns.list_records(domain, per_page=per_page, cursor=cursor)
|
||||
|
||||
|
||||
@router.get("/domains/{domain}/records/all")
|
||||
async def list_all_records(domain: str, client: VultrClient = Depends(get_client)):
|
||||
"""List all DNS records (auto-paginated)"""
|
||||
return {"records": client.dns.list_all_records(domain)}
|
||||
|
||||
|
||||
@router.get("/domains/{domain}/records/{record_id}")
|
||||
async def get_record(domain: str, record_id: str, client: VultrClient = Depends(get_client)):
|
||||
"""Get a DNS record"""
|
||||
return client.dns.get_record(domain, record_id)
|
||||
|
||||
|
||||
@router.post("/domains/{domain}/records")
|
||||
async def create_record(domain: str, req: CreateRecordRequest, client: VultrClient = Depends(get_client)):
|
||||
"""Create a DNS record"""
|
||||
return client.dns.create_record(
|
||||
domain,
|
||||
type=req.type,
|
||||
name=req.name,
|
||||
data=req.data,
|
||||
ttl=req.ttl,
|
||||
priority=req.priority
|
||||
)
|
||||
|
||||
|
||||
@router.patch("/domains/{domain}/records/{record_id}")
|
||||
async def update_record(domain: str, record_id: str, req: UpdateRecordRequest, client: VultrClient = Depends(get_client)):
|
||||
"""Update a DNS record"""
|
||||
return client.dns.update_record(domain, record_id, **req.model_dump(exclude_none=True))
|
||||
|
||||
|
||||
@router.delete("/domains/{domain}/records/{record_id}")
|
||||
async def delete_record(domain: str, record_id: str, client: VultrClient = Depends(get_client)):
|
||||
"""Delete a DNS record"""
|
||||
return client.dns.delete_record(domain, record_id)
|
||||
|
||||
|
||||
# Convenience endpoints
|
||||
@router.post("/domains/{domain}/records/a")
|
||||
async def create_a_record(domain: str, name: str, ip: str, ttl: int = 300, client: VultrClient = Depends(get_client)):
|
||||
"""Create an A record"""
|
||||
return client.dns.create_a_record(domain, name, ip, ttl)
|
||||
|
||||
|
||||
@router.post("/domains/{domain}/records/aaaa")
|
||||
async def create_aaaa_record(domain: str, name: str, ip: str, ttl: int = 300, client: VultrClient = Depends(get_client)):
|
||||
"""Create an AAAA record"""
|
||||
return client.dns.create_aaaa_record(domain, name, ip, ttl)
|
||||
|
||||
|
||||
@router.post("/domains/{domain}/records/cname")
|
||||
async def create_cname_record(domain: str, name: str, target: str, ttl: int = 300, client: VultrClient = Depends(get_client)):
|
||||
"""Create a CNAME record"""
|
||||
return client.dns.create_cname_record(domain, name, target, ttl)
|
||||
|
||||
|
||||
@router.post("/domains/{domain}/records/txt")
|
||||
async def create_txt_record(domain: str, name: str, data: str, ttl: int = 300, client: VultrClient = Depends(get_client)):
|
||||
"""Create a TXT record"""
|
||||
return client.dns.create_txt_record(domain, name, data, ttl)
|
||||
|
||||
|
||||
@router.post("/domains/{domain}/records/mx")
|
||||
async def create_mx_record(domain: str, name: str, data: str, priority: int = 10, ttl: int = 300, client: VultrClient = Depends(get_client)):
|
||||
"""Create an MX record"""
|
||||
return client.dns.create_mx_record(domain, name, data, priority, ttl)
|
||||
Reference in New Issue
Block a user