Files
vultr-api/server/routers/vpc.py
HWANG BYUNGHA 184054c6c1 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>
2026-01-22 01:08:17 +09:00

137 lines
3.9 KiB
Python

"""VPC router"""
from fastapi import APIRouter, Depends, Query
from typing import Optional, List
from pydantic import BaseModel
from vultr_api import VultrClient
from deps import get_client
router = APIRouter()
class CreateVPCRequest(BaseModel):
region: str
description: Optional[str] = None
v4_subnet: Optional[str] = None
v4_subnet_mask: Optional[int] = None
class UpdateVPCRequest(BaseModel):
description: str
class CreateVPC2Request(BaseModel):
region: str
description: Optional[str] = None
ip_block: Optional[str] = None
prefix_length: Optional[int] = None
class AttachVPC2Request(BaseModel):
nodes: List[dict] # [{"id": "instance_id", "ip_address": "10.0.0.1"}, ...]
# VPC 1.0
@router.get("")
async def list_vpcs(
per_page: int = Query(25, le=500),
cursor: Optional[str] = None,
client: VultrClient = Depends(get_client)
):
"""List all VPCs"""
return client.vpc.list(per_page=per_page, cursor=cursor)
@router.get("/all")
async def list_all_vpcs(client: VultrClient = Depends(get_client)):
"""List all VPCs (auto-paginated)"""
return {"vpcs": client.vpc.list_all()}
@router.get("/{vpc_id}")
async def get_vpc(vpc_id: str, client: VultrClient = Depends(get_client)):
"""Get VPC details"""
return client.vpc.get(vpc_id)
@router.post("")
async def create_vpc(req: CreateVPCRequest, client: VultrClient = Depends(get_client)):
"""Create a VPC"""
return client.vpc.create(**req.model_dump(exclude_none=True))
@router.patch("/{vpc_id}")
async def update_vpc(vpc_id: str, req: UpdateVPCRequest, client: VultrClient = Depends(get_client)):
"""Update a VPC"""
return client.vpc.update(vpc_id, description=req.description)
@router.delete("/{vpc_id}")
async def delete_vpc(vpc_id: str, client: VultrClient = Depends(get_client)):
"""Delete a VPC"""
return client.vpc.delete(vpc_id)
# VPC 2.0
@router.get("/v2/list")
async def list_vpc2s(
per_page: int = Query(25, le=500),
cursor: Optional[str] = None,
client: VultrClient = Depends(get_client)
):
"""List all VPC 2.0 networks"""
return client.vpc.list_vpc2(per_page=per_page, cursor=cursor)
@router.get("/v2/all")
async def list_all_vpc2s(client: VultrClient = Depends(get_client)):
"""List all VPC 2.0 networks (auto-paginated)"""
return {"vpcs": client.vpc.list_all_vpc2()}
@router.get("/v2/{vpc_id}")
async def get_vpc2(vpc_id: str, client: VultrClient = Depends(get_client)):
"""Get VPC 2.0 details"""
return client.vpc.get_vpc2(vpc_id)
@router.post("/v2")
async def create_vpc2(req: CreateVPC2Request, client: VultrClient = Depends(get_client)):
"""Create a VPC 2.0 network"""
return client.vpc.create_vpc2(**req.model_dump(exclude_none=True))
@router.patch("/v2/{vpc_id}")
async def update_vpc2(vpc_id: str, description: str, client: VultrClient = Depends(get_client)):
"""Update a VPC 2.0 network"""
return client.vpc.update_vpc2(vpc_id, description=description)
@router.delete("/v2/{vpc_id}")
async def delete_vpc2(vpc_id: str, client: VultrClient = Depends(get_client)):
"""Delete a VPC 2.0 network"""
return client.vpc.delete_vpc2(vpc_id)
@router.get("/v2/{vpc_id}/nodes")
async def list_vpc2_nodes(
vpc_id: str,
per_page: int = Query(25, le=500),
cursor: Optional[str] = None,
client: VultrClient = Depends(get_client)
):
"""List nodes attached to a VPC 2.0"""
return client.vpc.list_vpc2_nodes(vpc_id, per_page=per_page, cursor=cursor)
@router.post("/v2/{vpc_id}/nodes/attach")
async def attach_vpc2_nodes(vpc_id: str, req: AttachVPC2Request, client: VultrClient = Depends(get_client)):
"""Attach nodes to a VPC 2.0"""
return client.vpc.attach_vpc2_nodes(vpc_id, nodes=req.nodes)
@router.post("/v2/{vpc_id}/nodes/detach")
async def detach_vpc2_nodes(vpc_id: str, req: AttachVPC2Request, client: VultrClient = Depends(get_client)):
"""Detach nodes from a VPC 2.0"""
return client.vpc.detach_vpc2_nodes(vpc_id, nodes=req.nodes)