This repository has been archived on 2026-08-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Proxmox-VPS-Panel-secure/backend/app/models.py
T

100 lines
3.7 KiB
Python

from datetime import datetime, timezone
from enum import Enum
from sqlalchemy import Boolean, DateTime, Enum as SqlEnum, ForeignKey, Integer, String, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from .database import Base
class UserRole(str, Enum):
"""Роли пользователей панели."""
admin = "admin"
client = "client"
class GuestType(str, Enum):
"""Тип виртуализированной системы."""
vm = "vm"
lxc = "lxc"
class InstanceStatus(str, Enum):
"""Состояние инстанса в панели."""
creating = "creating"
running = "running"
stopped = "stopped"
error = "error"
deleting = "deleting"
deleted = "deleted"
class User(Base):
"""Пользователь панели с Argon2id-хешем пароля."""
__tablename__ = "users"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
email: Mapped[str] = mapped_column(String(320), unique=True, index=True)
password_hash: Mapped[str] = mapped_column(String(512))
role: Mapped[UserRole] = mapped_column(
SqlEnum(UserRole), default=UserRole.client, nullable=False
)
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=lambda: datetime.now(timezone.utc),
nullable=False,
)
instances: Mapped[list["Instance"]] = relationship(back_populates="owner")
class Template(Base):
"""Тарифный шаблон VM или LXC, доступный клиентам."""
__tablename__ = "templates"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
name: Mapped[str] = mapped_column(String(64), unique=True, index=True)
description: Mapped[str] = mapped_column(Text, default="")
guest_type: Mapped[GuestType] = mapped_column(SqlEnum(GuestType), nullable=False)
source_vmid: Mapped[int | None] = mapped_column(Integer, nullable=True)
source_template: Mapped[str | None] = mapped_column(String(512), nullable=True)
cores: Mapped[int] = mapped_column(Integer, default=1, nullable=False)
memory_mb: Mapped[int] = mapped_column(Integer, default=1024, nullable=False)
disk_gb: Mapped[int] = mapped_column(Integer, default=10, nullable=False)
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=lambda: datetime.now(timezone.utc),
nullable=False,
)
instances: Mapped[list["Instance"]] = relationship(back_populates="template")
class Instance(Base):
"""Инстанс VM/LXC, принадлежащий пользователю."""
__tablename__ = "instances"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
name: Mapped[str] = mapped_column(String(63))
vmid: Mapped[int | None] = mapped_column(Integer, unique=True, nullable=True)
node: Mapped[str] = mapped_column(String(64))
guest_type: Mapped[GuestType] = mapped_column(SqlEnum(GuestType), nullable=False)
status: Mapped[InstanceStatus] = mapped_column(
SqlEnum(InstanceStatus), default=InstanceStatus.creating, nullable=False
)
owner_id: Mapped[int] = mapped_column(ForeignKey("users.id"), index=True)
template_id: Mapped[int] = mapped_column(ForeignKey("templates.id"), index=True)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=lambda: datetime.now(timezone.utc),
nullable=False,
)
owner: Mapped[User] = relationship(back_populates="instances")
template: Mapped[Template] = relationship(back_populates="instances")