from datetime import datetime from typing import Any from pydantic import BaseModel, ConfigDict, EmailStr, Field class OrmModel(BaseModel): model_config = ConfigDict(from_attributes=True) class TokenPair(BaseModel): access_token: str refresh_token: str token_type: str = "bearer" class LoginRequest(BaseModel): email: EmailStr password: str class UserRead(OrmModel): id: str email: EmailStr display_name: str is_active: bool class ClusterCreate(BaseModel): name: str api_url: str api_token: str = Field(min_length=8) mode: str = "read_only" verify_tls: bool = True class SecurityGroupCreate(BaseModel): project_id: str | None = None name: str description: str | None = None class PolicyCreate(BaseModel): project_id: str | None = None name: str enabled: bool = True definition: dict[str, Any] class IpReservationCreate(BaseModel): subnet_id: str address: str status: str = "reserved" note: str | None = None class ClusterRead(OrmModel): id: str name: str api_url: str provider: str mode: str last_sync_at: datetime | None last_sync_status: str | None last_sync_error: str | None class NodeRead(OrmModel): id: str cluster_id: str name: str status: str cpu_count: int memory_mb: int class WorkloadRead(OrmModel): id: str cluster_id: str node_id: str project_id: str | None external_id: str name: str kind: str status: str tags: list[str] class NetworkRead(OrmModel): id: str cluster_id: str project_id: str | None name: str kind: str vlan_id: int | None mtu: int gateway: str | None dns: list[str] dhcp_enabled: bool tags: list[str] description: str | None class SubnetRead(OrmModel): id: str network_id: str cidr: str gateway: str | None dns: list[str] dhcp_enabled: bool class IpAddressRead(OrmModel): id: str subnet_id: str address: str status: str workload_id: str | None note: str | None class TenantRead(OrmModel): id: str name: str description: str | None class ProjectRead(OrmModel): id: str tenant_id: str name: str description: str | None class SecurityGroupRead(OrmModel): id: str project_id: str | None name: str description: str | None class PolicyRead(OrmModel): id: str project_id: str | None name: str version: int enabled: bool definition: dict[str, Any] last_compiled: dict[str, Any] | None class FirewallPreview(BaseModel): policy_id: str dry_run: bool = True generated_rules: list[dict[str, Any]] warnings: list[str] conflicts: list[str] class JobRead(OrmModel): id: str kind: str status: str progress: int started_at: datetime | None finished_at: datetime | None logs: list[str] error: str | None class AuditLogRead(OrmModel): id: str created_at: datetime user_id: str | None action: str object_type: str object_id: str | None old_values: dict[str, Any] | None new_values: dict[str, Any] | None ip_address: str | None user_agent: str | None result: str error_text: str | None