Files
ocdp-go/backend/scripts/init-db.sql
Ivan087 47849042a7 feat: complete E2E deployment flow with storage layered config and values template versioning
- Instance deployment: charts browser, deploy modal, instances list
- Values Template version management (create/history/rollback)
- Storage layered config (cluster > workspace > shared priority)
- Cluster credential decryptIfNeeded for mixed encrypted/plaintext kubeconfig
- YAML syntax validation (client-side + server-side warning)
- Frontend: charts, instances, storage, templates, admin pages
- Backend: storage service, instance service, cluster service, helm client
- Multi-Tenant Kubeconfig.md: added by user
2026-04-30 16:31:00 +08:00

207 lines
8.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.

-- OCDP Backend PostgreSQL 数据库初始化脚本
-- 创建数据库和必要的表结构
-- ===== Users 表 =====
CREATE TABLE IF NOT EXISTS users (
id VARCHAR(36) PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
email VARCHAR(255),
role VARCHAR(20) NOT NULL DEFAULT 'user',
workspace_id VARCHAR(36),
is_active BOOLEAN DEFAULT TRUE,
must_change_password BOOLEAN DEFAULT FALSE,
revoked_after TIMESTAMP NOT NULL DEFAULT '1970-01-01 00:00:00',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
CREATE INDEX IF NOT EXISTS idx_users_revoked_after ON users(revoked_after);
COMMENT ON TABLE users IS '用户表';
COMMENT ON COLUMN users.id IS '用户 ID (UUID)';
COMMENT ON COLUMN users.username IS '用户名(唯一)';
COMMENT ON COLUMN users.password_hash IS '密码哈希';
COMMENT ON COLUMN users.email IS '邮箱';
-- ===== Clusters 表 =====
CREATE TABLE IF NOT EXISTS clusters (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36),
owner_id VARCHAR(36),
name VARCHAR(255) NOT NULL,
host TEXT NOT NULL,
ca_data TEXT,
cert_data TEXT,
key_data TEXT,
token TEXT,
description TEXT,
isolation_mode VARCHAR(20) DEFAULT 'namespace',
default_namespace VARCHAR(255),
is_shared BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(workspace_id, name)
);
CREATE INDEX IF NOT EXISTS idx_clusters_name ON clusters(name);
COMMENT ON TABLE clusters IS 'Kubernetes 集群表';
COMMENT ON COLUMN clusters.id IS '集群 ID (UUID)';
COMMENT ON COLUMN clusters.name IS '集群名称(唯一)';
COMMENT ON COLUMN clusters.host IS 'Kubernetes API Server URL';
COMMENT ON COLUMN clusters.ca_data IS 'CA 证书(加密存储)';
COMMENT ON COLUMN clusters.cert_data IS '客户端证书(加密存储)';
COMMENT ON COLUMN clusters.key_data IS '客户端密钥(加密存储)';
COMMENT ON COLUMN clusters.token IS 'Bearer Token加密存储';
-- ===== Registries 表 =====
CREATE TABLE IF NOT EXISTS registries (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(255) NOT NULL UNIQUE,
url TEXT NOT NULL,
description TEXT,
username VARCHAR(255),
password TEXT,
insecure BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_registries_name ON registries(name);
COMMENT ON TABLE registries IS 'OCI Registry 表';
COMMENT ON COLUMN registries.id IS 'Registry ID (UUID)';
COMMENT ON COLUMN registries.name IS 'Registry 名称(唯一)';
COMMENT ON COLUMN registries.url IS 'Registry URL';
COMMENT ON COLUMN registries.username IS '认证用户名';
COMMENT ON COLUMN registries.password IS '认证密码(加密存储)';
COMMENT ON COLUMN registries.insecure IS '是否跳过 TLS 验证';
-- ===== Instances 表 =====
CREATE TABLE IF NOT EXISTS instances (
id VARCHAR(36) PRIMARY KEY,
cluster_id VARCHAR(36) NOT NULL,
name VARCHAR(255) NOT NULL,
namespace VARCHAR(255) NOT NULL,
registry_id VARCHAR(36) NOT NULL,
repository TEXT NOT NULL,
chart VARCHAR(255) NOT NULL,
version VARCHAR(255) NOT NULL,
description TEXT,
values JSONB,
values_yaml TEXT,
status VARCHAR(50) NOT NULL,
status_reason TEXT,
last_operation VARCHAR(50),
last_error TEXT,
revision INTEGER NOT NULL DEFAULT 1,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_cluster FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE,
CONSTRAINT fk_registry FOREIGN KEY (registry_id) REFERENCES registries(id) ON DELETE CASCADE,
CONSTRAINT unique_cluster_name UNIQUE (cluster_id, name, namespace)
);
CREATE INDEX IF NOT EXISTS idx_instances_cluster ON instances(cluster_id);
CREATE INDEX IF NOT EXISTS idx_instances_registry ON instances(registry_id);
CREATE INDEX IF NOT EXISTS idx_instances_name ON instances(name);
CREATE INDEX IF NOT EXISTS idx_instances_status ON instances(status);
COMMENT ON TABLE instances IS 'Helm 应用实例表';
COMMENT ON COLUMN instances.id IS '实例 ID (UUID)';
COMMENT ON COLUMN instances.cluster_id IS '所属集群 ID';
COMMENT ON COLUMN instances.name IS 'Helm Release 名称';
COMMENT ON COLUMN instances.namespace IS 'Kubernetes 命名空间';
COMMENT ON COLUMN instances.registry_id IS '所属 Registry ID';
COMMENT ON COLUMN instances.repository IS 'OCI Repository';
COMMENT ON COLUMN instances.chart IS 'Chart 名称';
COMMENT ON COLUMN instances.version IS 'Chart 版本';
COMMENT ON COLUMN instances.values IS 'Helm Values (JSON 格式)';
COMMENT ON COLUMN instances.values_yaml IS 'Helm Values (YAML 格式)';
COMMENT ON COLUMN instances.status IS '实例状态';
COMMENT ON COLUMN instances.status_reason IS '状态说明';
COMMENT ON COLUMN instances.last_operation IS '最后一次操作类型';
COMMENT ON COLUMN instances.last_error IS '最近一次错误信息';
COMMENT ON COLUMN instances.revision IS 'Helm Release Revision';
-- ===== Workspaces 表 =====
CREATE TABLE IF NOT EXISTS workspaces (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(255) NOT NULL UNIQUE,
description TEXT,
created_by VARCHAR(36),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_workspaces_name ON workspaces(name);
-- ===== Storage Backends 表 =====
CREATE TABLE IF NOT EXISTS storage_backends (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36),
owner_id VARCHAR(36),
cluster_id VARCHAR(36),
name VARCHAR(255) NOT NULL,
type VARCHAR(50) NOT NULL,
config JSONB NOT NULL,
description TEXT,
is_default BOOLEAN DEFAULT FALSE,
is_shared BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(workspace_id, name)
);
CREATE INDEX IF NOT EXISTS idx_storage_workspace ON storage_backends(workspace_id);
CREATE INDEX IF NOT EXISTS idx_storage_cluster ON storage_backends(cluster_id);
CREATE INDEX IF NOT EXISTS idx_storage_default_cluster ON storage_backends(cluster_id, is_default) WHERE cluster_id IS NOT NULL;
-- ===== Chart References 表 =====
CREATE TABLE IF NOT EXISTS chart_references (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36),
registry_id VARCHAR(36),
repository VARCHAR(500) NOT NULL,
chart_name VARCHAR(255) NOT NULL,
description TEXT,
is_enabled BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_chart_workspace ON chart_references(workspace_id);
CREATE INDEX IF NOT EXISTS idx_chart_registry ON chart_references(registry_id);
-- ===== Values Templates 表 =====
CREATE TABLE IF NOT EXISTS values_templates (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36),
chart_reference_id VARCHAR(36),
name VARCHAR(255) NOT NULL,
description TEXT,
values_yaml TEXT NOT NULL,
version INTEGER NOT NULL DEFAULT 1,
is_default BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(workspace_id, chart_reference_id, name, version)
);
CREATE INDEX IF NOT EXISTS idx_values_template_chart ON values_templates(chart_reference_id);
CREATE INDEX IF NOT EXISTS idx_values_template_workspace ON values_templates(workspace_id);
-- ===== 数据库版本表 =====
CREATE TABLE IF NOT EXISTS schema_migrations (
version VARCHAR(50) PRIMARY KEY,
applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE schema_migrations IS '数据库迁移版本记录';
-- 插入初始版本
INSERT INTO schema_migrations (version) VALUES ('v1.0.0')
ON CONFLICT (version) DO NOTHING;