"""Gateway-related Pydantic schemas.""" from datetime import datetime from pydantic import BaseModel, Field, field_validator import ipaddress from ..models.gateway import RouterType, ProvisioningMethod class GatewayBase(BaseModel): """Base gateway schema.""" name: str = Field(..., min_length=2, max_length=255) description: str | None = None location: str | None = None router_type: RouterType firmware_version: str | None = None vpn_subnet: str | None = Field(None, description="Network behind gateway, e.g., 10.0.0.0/24") @field_validator('vpn_subnet') @classmethod def validate_subnet(cls, v: str | None) -> str | None: if v is None or v == "" or v == "None": return None try: ipaddress.ip_network(v, strict=False) return v except ValueError as e: raise ValueError(f"Invalid subnet format: {e}") class GatewayCreate(GatewayBase): """Schema for creating a gateway.""" serial_number: str | None = None provisioning_method: ProvisioningMethod = ProvisioningMethod.ATV_FILE class GatewayUpdate(BaseModel): """Schema for updating a gateway.""" name: str | None = Field(None, min_length=2, max_length=255) description: str | None = None location: str | None = None serial_number: str | None = None firmware_version: str | None = None vpn_subnet: str | None = None provisioning_method: ProvisioningMethod | None = None @field_validator('vpn_subnet') @classmethod def validate_subnet(cls, v: str | None) -> str | None: if v is None or v == "" or v == "None": return None try: ipaddress.ip_network(v, strict=False) return v except ValueError as e: raise ValueError(f"Invalid subnet format: {e}") class GatewayResponse(GatewayBase): """Schema for gateway response.""" id: int tenant_id: int serial_number: str | None provisioning_method: ProvisioningMethod vpn_ip: str | None vpn_cert_cn: str | None is_online: bool is_provisioned: bool last_seen: datetime | None created_at: datetime updated_at: datetime | None class Config: from_attributes = True class GatewayStatus(BaseModel): """Schema for gateway online status.""" id: int name: str is_online: bool last_seen: datetime | None vpn_ip: str | None