Add is_docker_or_container_network helper to detect Docker bridge, Kubernetes CNI, and loopback networks, implement cleanup_discovered_container_networks to remove container bridge IPs from discovered networks during IPAM discovery, add ip_address_payload helper to enrich IP addresses with subnet CIDR and workload details, update ProxmoxProvider to ignore guest interfaces matching common container pref
316 lines
5.9 KiB
Python
316 lines
5.9 KiB
Python
from datetime import datetime
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, ConfigDict, 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: str
|
|
password: str
|
|
|
|
|
|
class SetupStatus(BaseModel):
|
|
complete: bool
|
|
has_users: bool
|
|
has_clusters: bool
|
|
|
|
|
|
class SetupCompleteRequest(BaseModel):
|
|
admin_email: str
|
|
admin_name: str
|
|
admin_password: str = Field(min_length=12)
|
|
cluster_name: str | None = None
|
|
cluster_api_url: str | None = None
|
|
cluster_api_token: str | None = None
|
|
cluster_provider: str = "proxmox"
|
|
cluster_mode: str = "read_only"
|
|
verify_tls: bool = True
|
|
|
|
|
|
class UserRead(OrmModel):
|
|
id: str
|
|
email: str
|
|
display_name: str
|
|
is_active: bool
|
|
|
|
|
|
class UserCreate(BaseModel):
|
|
email: str
|
|
display_name: str
|
|
password: str = Field(min_length=12)
|
|
role_ids: list[str] = []
|
|
|
|
|
|
class RoleCreate(BaseModel):
|
|
name: str
|
|
permissions: list[str] = []
|
|
|
|
|
|
class RoleRead(OrmModel):
|
|
id: str
|
|
name: str
|
|
permissions: list[str]
|
|
|
|
|
|
class ClusterCreate(BaseModel):
|
|
name: str
|
|
api_url: str
|
|
api_token: str = Field(min_length=8)
|
|
provider: str = "proxmox"
|
|
mode: str = "read_only"
|
|
verify_tls: bool = True
|
|
|
|
|
|
class TenantCreate(BaseModel):
|
|
name: str
|
|
description: str | None = None
|
|
|
|
|
|
class ProjectCreate(BaseModel):
|
|
tenant_id: str
|
|
name: str
|
|
description: str | None = None
|
|
|
|
|
|
class NetworkCreate(BaseModel):
|
|
cluster_id: str
|
|
project_id: str | None = None
|
|
name: str
|
|
kind: str = "bridge"
|
|
vlan_id: int | None = None
|
|
mtu: int = 1500
|
|
gateway: str | None = None
|
|
dns: list[str] = []
|
|
dhcp_enabled: bool = False
|
|
tags: list[str] = []
|
|
description: str | None = None
|
|
|
|
|
|
class SubnetCreate(BaseModel):
|
|
network_id: str
|
|
cidr: str
|
|
gateway: str | None = None
|
|
dns: list[str] = []
|
|
dhcp_enabled: bool = False
|
|
|
|
|
|
class SecurityGroupCreate(BaseModel):
|
|
project_id: str | None = None
|
|
name: str
|
|
description: str | None = None
|
|
|
|
|
|
class SecurityRuleCreate(BaseModel):
|
|
security_group_id: str
|
|
direction: str = "ingress"
|
|
action: str = "allow"
|
|
protocol: str = "tcp"
|
|
source: str = "any"
|
|
destination: str = "any"
|
|
port: str | None = None
|
|
priority: int = 1000
|
|
logging: bool = False
|
|
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 ServiceCatalogCreate(BaseModel):
|
|
name: str
|
|
protocol: str
|
|
ports: str
|
|
editable: bool = True
|
|
|
|
|
|
class FirewallApplyRequest(BaseModel):
|
|
policy_id: str
|
|
cluster_id: str | None = None
|
|
confirm: bool = False
|
|
dry_run: bool = True
|
|
|
|
|
|
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
|
|
subnet_cidr: str | None = None
|
|
address: str
|
|
status: str
|
|
workload_id: str | None
|
|
workload_name: str | None = None
|
|
workload_external_id: str | None = 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 SecurityRuleRead(OrmModel):
|
|
id: str
|
|
security_group_id: str
|
|
direction: str
|
|
action: str
|
|
protocol: str
|
|
source: str
|
|
destination: str
|
|
port: str | None
|
|
priority: int
|
|
logging: bool
|
|
description: str | None
|
|
|
|
|
|
class PolicyRead(OrmModel):
|
|
id: str
|
|
project_id: str | None
|
|
name: str
|
|
version: int
|
|
enabled: bool
|
|
enforcement_mode: str
|
|
definition: dict[str, Any]
|
|
last_compiled: dict[str, Any] | None
|
|
|
|
|
|
class WorkloadInsight(BaseModel):
|
|
workload: WorkloadRead
|
|
assigned_ips: list[IpAddressRead]
|
|
traffic: list[dict[str, Any]]
|
|
matching_policies: list[PolicyRead]
|
|
effective_decision: str
|
|
audit_mode_notes: list[str]
|
|
|
|
|
|
class ServiceCatalogRead(OrmModel):
|
|
id: str
|
|
name: str
|
|
protocol: str
|
|
ports: str
|
|
editable: bool
|
|
|
|
|
|
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
|