Files
pangolin/server/migrations/000008_provision.up.sql
T
wangjia 3d5bac66b4 feat(provision): 弹性节点基建 Terraform + 一键更换 (tsk_6u0FxmbC7Yeq)
IaC 面 (infra/) 与控制面 (server/internal/provision) 双产出,落地 doc/04 §4
「节点是牲口」弹性拓扑与 make-before-break 一键更换。

server/internal/provision:
- CloudAdapter 适配层 + Registry(首发 vultr 消耗品池 / hetzner 精品池各一);
  厂商凭证仅从 PROVISION_<VENDOR>_* env 注入,不入库不入 git。
- ProvisionService:CreateNode(幂等键重放不重复开机)、DestroyNode(幂等)、
  RotateIP(换 IP 不换机 + version bump)、ListProviders。
- Replace 一键更换:先建后拆,新机 up 先于旧机 draining(容量不下降),
  replacement_uuid 幂等键 + replacements 表分步记录,崩溃可续跑不重复。
- RotatePool:池内滚动轮换,并发度 1–2。
- cmd/nodectl CLI:create/destroy/rotate-ip/replace/rotate-pool/providers。
- 单测(mock 厂商 API + 内存 Store):幂等重放、make-before-break 时序断言、
  开机失败/探活超时→destroyed+失败计数+告警钩子、崩溃续跑、RotatePool。

infra/:
- terraform/:探针机 + 控制面基线模块化(probe / control-plane)+ README,
  低频基线进 state,节点不进 Terraform。
- cloud-init/node.yaml.tmpl:节点引导模板(注入一次性 bootstrap token,task #5)。
- identity-isolation.md:身份隔离登记表(doc/06 §2 红线,无任何凭证)。

migrations/000008:nodes 增 provider_instance_id/elastic_ip_id、node_events
增 ip_rotated、provision_idempotency / replacements 表(附加式,不动现网)。

红线:仅面向新厂商池,绝不纳管现网生产 EC2(deploy/ marzban)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 14:23:39 +08:00

38 lines
2.0 KiB
SQL
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.
-- 弹性节点基建(task #14 / tsk_6u0FxmbC7Yeq
-- 厂商 API 适配层与一键更换编排所需的最小附加结构。全部为附加式变更,
-- 不触碰现网生产 EC2deploy/ 的 marzban 机器)。
-- nodes 增补:厂商实例标识与弹性 IP 标识(销毁 / 换 IP 不换机所需)。
-- 凭证仍不入库;这里只存厂商侧的资源 ID,便于幂等地销毁与换绑。
ALTER TABLE nodes
ADD COLUMN provider_instance_id VARCHAR(128) NULL AFTER provider_id,
ADD COLUMN elastic_ip_id VARCHAR(128) NULL AFTER provider_instance_id;
-- node_events 增补 ip_rotated(换 IP 不换机的审计事件)。
ALTER TABLE node_events
MODIFY COLUMN event ENUM('provisioned','probe_pass','probe_fail','marked_up','draining',
'blocked_suspect','blocked_confirmed','replaced','destroyed','ip_rotated') NOT NULL;
-- 开退机幂等表:幂等键 → 已开机节点 uuid。重放同一幂等键不重复开机。
CREATE TABLE provision_idempotency (
idempotency_key VARCHAR(128) NOT NULL PRIMARY KEY,
node_uuid CHAR(36) NOT NULL,
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 一键更换编排记录:make-before-break 的可恢复状态机。
-- 进程崩溃后可凭 uuid 续跑,step 标记进度,不重复开机 / 不重复销毁。
CREATE TABLE replacements (
uuid CHAR(36) NOT NULL PRIMARY KEY,
old_node_id BIGINT UNSIGNED NOT NULL,
new_node_id BIGINT UNSIGNED NULL,
pool ENUM('consumable','premium') NOT NULL,
status ENUM('running','done','failed') NOT NULL DEFAULT 'running',
step VARCHAR(32) NOT NULL DEFAULT 'open_new',
detail JSON NULL,
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
INDEX idx_status (status),
INDEX idx_old_node (old_node_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;