feat: 发布权限 RBAC + PipelineEditor 修复 + 菜单优化
- 新增 DeployRBAC 页面: Jenkins-style Item Role 权限管理 - 正则匹配流水线 code,实时命中预览 - 内置用户分配面板,无需跳转系统管理 - 支持创建/编辑/删除/启用禁用 Item Role - 修复 PipelineEditor 成员管理 http 双解包 bug - 修复 PipelineManager 前端 code 路由迁移(delete/trigger/stop/loadRuns) - 新增批量删除流水线运行记录 API - Sidebar: 应用发布下新增「发布权限」, 仓库认证→发布配置, 移除用户组 - 恢复系统管理菜单(不受发布权限改动影响) - 后端 ItemRole CRUD handler + 正则匹配中间件已就绪
This commit is contained in:
1 parent
0fea0ccc20
commit
24f955832e
40 files changed
+7530
-1032
No files matched your search
@@ -4,44 +4,198 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Credential 凭据管理模型(SSH密钥/API Token/密码等统一管理)
|
||||
// Credential 凭据管理模型 — 统一管理 SSH/Docker/Token/AKSK/数据库/API 等敏感信息
|
||||
// 设计参考:opsx-web Secret 模型,按类型动态切换字段
|
||||
// 核心加密字段 content 存储类型特有数据(JSON),API 不返回
|
||||
//
|
||||
// 类型与内容 JSON 映射:
|
||||
// ssh → {"private_key":"...","public_key":"...","ssh_user":"...","ssh_port":22}
|
||||
// docker → {"server":"...","username":"...","password":"..."}
|
||||
// tls → {"cert":"...","key":"...","ca":"..."}
|
||||
// aksk → {"provider":"...","access_key":"...","secret_key":"...","region":"..."}
|
||||
// database → {"db_type":"...","host":"...","port":3306,"db_name":"...","username":"...","password":"..."}
|
||||
// api → {"key":"...","endpoint":"..."}
|
||||
// generic → {"key":"...","value":"..."}
|
||||
type Credential struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:128;not null" json:"name"` // 凭据名称
|
||||
Type string `gorm:"size:32;not null" json:"type"` // ssh_key, api_token, password, access_key
|
||||
Content string `gorm:"type:text;not null" json:"-"` // AES加密后的内容,API不返回
|
||||
Description string `gorm:"size:500" json:"description"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:128;not null" json:"name"` // 凭据名称
|
||||
VariableName string `gorm:"size:64;index" json:"variable_name,omitempty"` // 环境变量别名 e.g. MYSQL_PROD
|
||||
SecretType string `gorm:"size:32;not null;index" json:"secret_type"` // ssh/docker/tls/aksk/database/api/generic
|
||||
Summary string `gorm:"size:255" json:"summary,omitempty"` // 关键信息摘要(脱敏展示)
|
||||
Content string `gorm:"type:text;not null" json:"-"` // AES 加密后的 JSON,API 不返回
|
||||
Tags string `gorm:"type:text" json:"tags,omitempty"` // JSON 数组: ["生产环境","阿里云"]
|
||||
Description string `gorm:"size:500" json:"description,omitempty"`
|
||||
ExpiresAt *time.Time `json:"expires_at,omitempty"` // 过期时间
|
||||
IsActive bool `gorm:"default:true" json:"is_active"` // 启用/禁用
|
||||
EnvPrefix string `gorm:"size:32" json:"env_prefix,omitempty"` // 引用 ID(可复制)
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (Credential) TableName() string {
|
||||
return "iam_credentials"
|
||||
}
|
||||
|
||||
// CredentialCreateRequest 创建凭据请求
|
||||
type CredentialCreateRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Type string `json:"type" binding:"required,oneof=ssh_key api_token password access_key"`
|
||||
Content string `json:"content" binding:"required"` // 明文,后端加密存储
|
||||
Description string `json:"description"`
|
||||
// ────── 类型定义 ──────
|
||||
|
||||
// SecretType SSH 凭据 content
|
||||
type SSHSecretContent struct {
|
||||
PrivateKey string `json:"private_key"`
|
||||
PublicKey string `json:"public_key"`
|
||||
SSHUser string `json:"ssh_user"`
|
||||
SSHPort int `json:"ssh_port"`
|
||||
Password string `json:"password,omitempty"`
|
||||
}
|
||||
|
||||
// CredentialUpdateRequest 更新凭据请求
|
||||
type CredentialUpdateRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Type string `json:"type" binding:"required,oneof=ssh_key api_token password access_key"`
|
||||
Content string `json:"content"` // 空则不更新内容
|
||||
Description string `json:"description"`
|
||||
// DockerSecretContent Docker 凭据 content
|
||||
type DockerSecretContent struct {
|
||||
Server string `json:"server"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// CredentialListResponse 列表返回(内容脱敏)
|
||||
type CredentialListResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Preview string `json:"preview"` // 内容预览(前8+后4字符)
|
||||
Description string `json:"description"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
// TLSSecretContent TLS 证书凭据 content
|
||||
type TLSSecretContent struct {
|
||||
Cert string `json:"cert"`
|
||||
Key string `json:"key"`
|
||||
CA string `json:"ca"`
|
||||
}
|
||||
|
||||
// AKSKSecretContent AKSK 凭据 content
|
||||
type AKSKSecretContent struct {
|
||||
Provider string `json:"provider"`
|
||||
AccessKey string `json:"access_key"`
|
||||
SecretKey string `json:"secret_key"`
|
||||
Region string `json:"region,omitempty"`
|
||||
}
|
||||
|
||||
// DatabaseSecretContent 数据库凭据 content
|
||||
type DatabaseSecretContent struct {
|
||||
DBType string `json:"db_type"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
DBName string `json:"db_name"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// APISecretContent API 密钥凭据 content
|
||||
type APISecretContent struct {
|
||||
Key string `json:"api_key"`
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
}
|
||||
|
||||
// GenericSecretContent 通用凭据 content
|
||||
type GenericSecretContent struct {
|
||||
Key string `json:"generic_key"`
|
||||
Value string `json:"generic_value"`
|
||||
}
|
||||
|
||||
// ────── 请求/响应 ──────
|
||||
|
||||
// CreateSecretRequest 创建凭据请求
|
||||
type CreateSecretRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
VariableName string `json:"variable_name"`
|
||||
SecretType string `json:"secret_type" binding:"required,oneof=ssh docker tls aksk database api generic"`
|
||||
Tags []string `json:"tags"`
|
||||
Description string `json:"description"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
IsActive *bool `json:"is_active"`
|
||||
|
||||
// 类型特有字段(明文,后端组装成 JSON 加密存储)
|
||||
// SSH
|
||||
SSHPrivateKey string `json:"ssh_private_key,omitempty"`
|
||||
SSHPublicKey string `json:"ssh_public_key,omitempty"`
|
||||
SSHUser string `json:"ssh_user,omitempty"`
|
||||
SSHPort int `json:"ssh_port,omitempty"`
|
||||
SSHPassword string `json:"ssh_password,omitempty"`
|
||||
// Docker
|
||||
DockerServer string `json:"docker_server,omitempty"`
|
||||
DockerUsername string `json:"docker_username,omitempty"`
|
||||
DockerPassword string `json:"docker_password,omitempty"`
|
||||
// TLS
|
||||
TLSCert string `json:"tls_cert,omitempty"`
|
||||
TLSKey string `json:"tls_key,omitempty"`
|
||||
TLSCA string `json:"tls_ca,omitempty"`
|
||||
// AKSK
|
||||
AKSKProvider string `json:"aksk_provider,omitempty"`
|
||||
AKSKAccessKey string `json:"aksk_access_key,omitempty"`
|
||||
AKSKSecretKey string `json:"aksk_secret_key,omitempty"`
|
||||
AKSKRegion string `json:"aksk_region,omitempty"`
|
||||
// Database
|
||||
DBType string `json:"db_type,omitempty"`
|
||||
DBHost string `json:"db_host,omitempty"`
|
||||
DBPort int `json:"db_port,omitempty"`
|
||||
DBName string `json:"db_name,omitempty"`
|
||||
DBUsername string `json:"db_username,omitempty"`
|
||||
DBPassword string `json:"db_password,omitempty"`
|
||||
// API
|
||||
APIKey string `json:"api_key,omitempty"`
|
||||
APIEndpoint string `json:"api_endpoint,omitempty"`
|
||||
// Generic
|
||||
GenericKey string `json:"generic_key,omitempty"`
|
||||
GenericValue string `json:"generic_value,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateSecretRequest 更新凭据请求
|
||||
type UpdateSecretRequest struct {
|
||||
Name *string `json:"name"`
|
||||
VariableName *string `json:"variable_name"`
|
||||
Tags []string `json:"tags"`
|
||||
Description *string `json:"description"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
IsActive *bool `json:"is_active"`
|
||||
|
||||
// 类型特有字段 — 传了才更新
|
||||
SSHPrivateKey *string `json:"ssh_private_key,omitempty"`
|
||||
SSHPublicKey *string `json:"ssh_public_key,omitempty"`
|
||||
SSHUser *string `json:"ssh_user,omitempty"`
|
||||
SSHPort *int `json:"ssh_port,omitempty"`
|
||||
SSHPassword *string `json:"ssh_password,omitempty"`
|
||||
DockerServer *string `json:"docker_server,omitempty"`
|
||||
DockerUsername *string `json:"docker_username,omitempty"`
|
||||
DockerPassword *string `json:"docker_password,omitempty"`
|
||||
TLSCert *string `json:"tls_cert,omitempty"`
|
||||
TLSKey *string `json:"tls_key,omitempty"`
|
||||
TLSCA *string `json:"tls_ca,omitempty"`
|
||||
AKSKProvider *string `json:"aksk_provider,omitempty"`
|
||||
AKSKAccessKey *string `json:"aksk_access_key,omitempty"`
|
||||
AKSKSecretKey *string `json:"aksk_secret_key,omitempty"`
|
||||
AKSKRegion *string `json:"aksk_region,omitempty"`
|
||||
DBType *string `json:"db_type,omitempty"`
|
||||
DBHost *string `json:"db_host,omitempty"`
|
||||
DBPort *int `json:"db_port,omitempty"`
|
||||
DBName *string `json:"db_name,omitempty"`
|
||||
DBUsername *string `json:"db_username,omitempty"`
|
||||
DBPassword *string `json:"db_password,omitempty"`
|
||||
APIKey *string `json:"api_key,omitempty"`
|
||||
APIEndpoint *string `json:"api_endpoint,omitempty"`
|
||||
GenericKey *string `json:"generic_key,omitempty"`
|
||||
GenericValue *string `json:"generic_value,omitempty"`
|
||||
}
|
||||
|
||||
// SecretListResponse 列表返回(内容脱敏)
|
||||
type SecretListResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
VariableName string `json:"variable_name,omitempty"`
|
||||
SecretType string `json:"secret_type"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
ExpiresAt *time.Time `json:"expires_at,omitempty"`
|
||||
IsActive bool `json:"is_active"`
|
||||
EnvPrefix string `json:"env_prefix,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// SecretListQuery 列表查询参数
|
||||
type SecretListQuery struct {
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"page_size"`
|
||||
SecretType string `form:"secret_type"`
|
||||
Tags string `form:"tags"` // 逗号分隔
|
||||
Search string `form:"search"`
|
||||
}
|
||||
Reference in new issue
Block a user