Files

102 lines
3.1 KiB
Python
Raw Permalink 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.
"""云厂商 SDK 适配层 — 抽象基类与标准化数据结构
各云厂商适配器继承 BaseAdapter,实现统一接口,将平台特定的 API 返回
转换为标准化的资产结构(NormalizedVPS / NormalizedDomain / AccountInfo),
供同步服务写入数据库。这样上层逻辑无需关心各平台 API 差异。
"""
from abc import ABC, abstractmethod
from dataclasses import asdict, dataclass, field
from typing import Optional
@dataclass
class NormalizedVPS:
"""标准化的 VPS 实例"""
external_id: str
name: str
ip_address: Optional[str] = None
region: Optional[str] = None
os: Optional[str] = None
cpu_cores: Optional[int] = None
memory_gb: Optional[float] = None
disk_gb: Optional[int] = None
status: str = "active"
monthly_cost: Optional[float] = None
currency: str = "USD"
raw: dict = field(default_factory=dict)
def to_dict(self) -> dict:
return asdict(self)
@dataclass
class NormalizedDomain:
"""标准化的域名"""
external_id: str
domain_name: str
registrar: Optional[str] = None
expiry_date: Optional[str] = None # ISO 日期字符串 YYYY-MM-DD
status: str = "active"
raw: dict = field(default_factory=dict)
def to_dict(self) -> dict:
return asdict(self)
@dataclass
class AccountInfo:
"""标准化的账户信息"""
balance: Optional[float] = None
currency: str = "USD"
pending_charges: Optional[float] = None
raw: dict = field(default_factory=dict)
def to_dict(self) -> dict:
return asdict(self)
def _overridden(instance: "BaseAdapter", method_name: str) -> bool:
"""判断子类是否重写了某方法(用于能力探测)"""
return type(instance).__dict__.get(method_name) is not None
class BaseAdapter(ABC):
"""云厂商适配器抽象基类
子类需:
- 通过 @register("xxx-sdk") 注册到注册表
- 设置 required_config(所需凭证字段,供前端表单提示)
- 实现 test_connection;按需重写 list_vps / list_domains / get_account
"""
#: 适配器所需的配置字段名(如 ["api_key"] 或 ["access_key_id", "access_key_secret"]
required_config: list = []
def __init__(self, config: Optional[dict] = None):
self.config = config or {}
@abstractmethod
def test_connection(self) -> dict:
"""测试连接 / 凭证有效性,返回 {"ok": bool, "message": str, ...}"""
def list_vps(self) -> list:
raise NotImplementedError(f"{type(self).__name__} 未实现 list_vps")
def list_domains(self) -> list:
raise NotImplementedError(f"{type(self).__name__} 未实现 list_domains")
def get_account(self) -> AccountInfo:
raise NotImplementedError(f"{type(self).__name__} 未实现 get_account")
def capabilities(self) -> dict:
"""返回适配器实际支持的能力(是否重写了相应方法)"""
return {
"list_vps": _overridden(self, "list_vps"),
"list_domains": _overridden(self, "list_domains"),
"get_account": _overridden(self, "get_account"),
}