Files
vps-manager/app/models/asset.py
T

153 lines
6.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""资产数据库模型
包含四种核心资产模型:
- Asset: 资产主表(统一登记 VPS/域名/AI 账号/Cloudflare 等一切资产)
- VPSDetail: VPS 资产详情(与 Asset 一对一关联)
- DomainDetail: 域名资产详情(与 Asset 一对一关联)
- AIAccount: AI Agent 账号详情(与 Asset 一对一关联)
"""
from datetime import date, datetime
from enum import Enum
from typing import Optional
from sqlmodel import Field, SQLModel
class AssetType(str, Enum):
"""资产类型"""
VPS = "vps" # 云服务器
DOMAIN = "domain" # 域名
AI_AGENT = "ai_agent" # AI Agent 账号(OpenAI/Kimi/DeepSeek 等)
CLOUDFLARE = "cloudflare" # Cloudflare 账号/子资产(DNS/Workers/R2/Tunnel
OTHER = "other" # 其他
class AssetStatus(str, Enum):
"""资产运行状态"""
ACTIVE = "active" # 正常使用中
EXPIRED = "expired" # 已过期
STOPPED = "stopped" # 已停止(不再使用)
CANCELLED = "cancelled" # 已注销
UNKNOWN = "unknown" # 未知(待确认)
class Asset(SQLModel, table=True):
"""资产主表:所有资产在此统一登记,用于续费提醒与状态总览"""
__tablename__ = "assets"
id: Optional[int] = Field(default=None, primary_key=True)
name: str = Field(index=True, description="资产名称,如:博客主站 VPS")
asset_type: AssetType = Field(index=True, description="资产类型")
provider: str = Field(index=True, description="服务商 slug,如 aliyun/vultr/namesilo/openai")
provider_id: Optional[int] = Field(
default=None, foreign_key="providers.id", index=True, description="关联平台 ID"
)
renewal_cycle: Optional[str] = Field(
default=None, description="续费周期:monthly/quarterly/yearly"
)
account: Optional[str] = Field(
default=None, description="所属账号标识(如 Cloudflare 账号邮箱)"
)
expiry_date: Optional[date] = Field(
default=None, index=True, description="到期/续费日期,用于续费提醒"
)
auto_renew: bool = Field(default=False, description="是否自动续费")
cost: float = Field(default=0, description="单次续费费用")
currency: str = Field(default="USD", description="币种(USD/CNY/JPY")
status: AssetStatus = Field(default=AssetStatus.ACTIVE, index=True, description="运行状态")
is_archived: bool = Field(
default=False, description="已归档:不再使用但可能仍在续费,需重点排查"
)
remark: Optional[str] = Field(default=None, description="备注")
created_at: datetime = Field(default_factory=datetime.utcnow, description="创建时间")
updated_at: datetime = Field(
default_factory=datetime.utcnow,
sa_column_kwargs={"onupdate": datetime.utcnow},
description="更新时间",
)
class VPSDetail(SQLModel, table=True):
"""VPS 资产详情(一对一关联 Asset"""
__tablename__ = "vps_details"
id: Optional[int] = Field(default=None, primary_key=True)
asset_id: int = Field(
foreign_key="assets.id", unique=True, index=True, description="关联资产 ID"
)
ip_address: str = Field(index=True, description="公网 IP")
tailscale_ip: Optional[str] = Field(default=None, description="Tailscale 内网 IP")
region: Optional[str] = Field(default=None, description="机房区域,如 Japan/US West")
os: Optional[str] = Field(default=None, description="操作系统,如 Debian 12")
cpu_cores: int = Field(default=1, description="CPU 核数")
memory_gb: float = Field(default=1, description="内存大小(GB")
disk_gb: int = Field(default=20, description="磁盘大小(GB")
bandwidth_gb: Optional[int] = Field(default=None, description="月流量配额(GB")
ssh_port: int = Field(default=22, description="SSH 端口")
panel_url: Optional[str] = Field(default=None, description="服务商管理面板 URL")
ssh_user: Optional[str] = Field(default=None, description="SSH 登录用户,如 root")
login_method: Optional[str] = Field(
default="key", description="登录方式:key/password/other"
)
ssh_key_encrypted: Optional[str] = Field(default=None, description="加密的 SSH 私钥")
password_encrypted: Optional[str] = Field(default=None, description="加密的登录密码")
purpose: Optional[str] = Field(default=None, description="用途 / 运行的项目")
class DomainDetail(SQLModel, table=True):
"""域名资产详情(一对一关联 Asset"""
__tablename__ = "domain_details"
id: Optional[int] = Field(default=None, primary_key=True)
asset_id: int = Field(
foreign_key="assets.id", unique=True, index=True, description="关联资产 ID"
)
domain_name: str = Field(index=True, description="域名,如 example.com")
registrar: Optional[str] = Field(
default=None, description="注册商:namesilo/新网/腾讯/阿里/dynadot/cloudflare"
)
dns_provider: Optional[str] = Field(
default=None, description="DNS 托管商:cloudflare/阿里云/注册商默认"
)
cloudflare_account: Optional[str] = Field(
default=None, description="归属的 Cloudflare 账号标识"
)
is_using: bool = Field(default=True, description="是否仍在实际使用")
redirect_target: Optional[str] = Field(
default=None, description="若为跳转用途域名,填写目标地址"
)
bind_asset_id: Optional[int] = Field(
default=None, index=True, description="绑定的资产 ID(如关联的 VPS/项目)"
)
class AIAccount(SQLModel, table=True):
"""AI Agent 账号资产详情(一对一关联 Asset"""
__tablename__ = "ai_accounts"
id: Optional[int] = Field(default=None, primary_key=True)
asset_id: int = Field(
foreign_key="assets.id", unique=True, index=True, description="关联资产 ID"
)
provider: str = Field(
index=True, description="服务商:openai/minimax/kimi/agnes/deepseek"
)
api_key: Optional[str] = Field(
default=None, description="API Key(后续版本将改为加密存储)"
)
plan: Optional[str] = Field(default=None, description="订阅计划,如 ChatGPT Plus")
balance: Optional[float] = Field(default=None, description="当前余额")
currency: str = Field(default="USD", description="币种")
monthly_usage: Optional[float] = Field(default=None, description="本月用量")
monthly_limit: Optional[float] = Field(default=None, description="月度限额")
last_synced_at: Optional[datetime] = Field(
default=None, description="最近一次自动同步余额/用量的时间"
)