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:
attacker committed 2026-06-21 05:26:01 +00:00
1 parent 0fea0ccc20
commit 24f955832e
40 files changed
+7530 -1032

No files matched your search

+297 -35
View File
@@ -3,59 +3,321 @@ package models
import (
"time"
"gorm.io/gorm"
)
// AlertRule 告警规则模型
// ============================================
// AlertRule 告警规则(增强版 — 合并原V2特性)
// ============================================
// AlertRuleStatus 告警规则状态
type AlertRuleStatus string
const (
AlertRuleEnabled AlertRuleStatus = "enabled"
AlertRuleDisabled AlertRuleStatus = "disabled"
)
// AlertSeverity 告警级别
type AlertSeverity string
const (
AlertSeverityCritical AlertSeverity = "critical"
AlertSeverityWarning AlertSeverity = "warning"
AlertSeverityNotice AlertSeverity = "notice"
AlertSeverityInfo AlertSeverity = "info"
)
// AggFunction 聚合函数
type AggFunction string
const (
AggFunctionAvg AggFunction = "avg"
AggFunctionMin AggFunction = "min"
AggFunctionMax AggFunction = "max"
AggFunctionSum AggFunction = "sum"
AggFunctionCount AggFunction = "count"
AggFunctionLast AggFunction = "last"
AggFunctionP95 AggFunction = "p95"
AggFunctionP99 AggFunction = "p99"
)
// Operator 比较运算符
type Operator string
const (
OperatorGT Operator = ">"
OperatorGTE Operator = ">="
OperatorLT Operator = "<"
OperatorLTE Operator = "<="
OperatorEQ Operator = "=="
OperatorNE Operator = "!="
)
// AlertRule 告警规则(增强版)
type AlertRule struct {
ID uint `gorm:"primarykey" json:"id"`
Name string `gorm:"size:128;not null" json:"name"`
Description string `gorm:"size:500" json:"description"`
Type string `gorm:"size:32;not null" json:"type"` // metric, log, event
Source string `gorm:"size:64;not null" json:"source"` // prometheus, zabbix, custom
Expression string `gorm:"type:text;not null" json:"expression"`
Severity string `gorm:"size:32;default:warning" json:"severity"` // info, warning, critical
Duration int `json:"duration"` // 持续时间(秒)
Enabled bool `gorm:"default:true" json:"enabled"`
Labels string `gorm:"type:text" json:"labels"` // JSON
Annotations string `gorm:"type:text" json:"annotations"` // JSON
NotifyChannels string `gorm:"type:text" json:"notify_channels"` // JSON
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:规则名称" json:"name"`
Description string `gorm:"type:varchar(500);comment:规则描述" json:"description,omitempty"`
// ====== 原 V1 兼容字段 ======
Type string `gorm:"type:varchar(32);comment:规则类型: metric/log/event" json:"type,omitempty"`
Source string `gorm:"type:varchar(64);comment:数据源: prometheus/zabbix/custom" json:"source,omitempty"`
Expression string `gorm:"type:text;comment:PromQL/Zabbix表达式" json:"expression,omitempty"`
Severity string `gorm:"type:varchar(32);default:'warning';comment:告警级别" json:"severity"`
Duration int `gorm:"comment:持续时间(秒)" json:"duration,omitempty"`
Enabled bool `gorm:"default:true;comment:是否启用" json:"enabled"`
// ====== V2 增强字段 ======
Status AlertRuleStatus `gorm:"type:varchar(16);default:'enabled';comment:规则状态" json:"status,omitempty"`
TargetType string `gorm:"type:varchar(32);comment:目标类型" json:"target_type,omitempty"`
TargetID uint `gorm:"index;comment:目标ID(0表示全部)" json:"target_id,omitempty"`
TargetTags string `gorm:"type:varchar(256);comment:目标标签筛选" json:"target_tags,omitempty"`
Conditions string `gorm:"type:text;comment:触发条件JSON数组" json:"conditions,omitempty"`
AggWindow int `gorm:"default:300;comment:聚合窗口(秒)" json:"agg_window,omitempty"`
AggFunction string `gorm:"type:varchar(16);default:'avg';comment:聚合函数" json:"agg_function,omitempty"`
RecoverCount int `gorm:"default:1;comment:恢复次数" json:"recover_count,omitempty"`
RecoverWindow int `gorm:"default:300;comment:恢复检查窗口(秒)" json:"recover_window,omitempty"`
Interval int `gorm:"default:60;comment:评估间隔(秒)" json:"interval,omitempty"`
CheckTimes int `gorm:"default:1;comment:连续触发次数" json:"check_times,omitempty"`
NotifyMode string `gorm:"type:varchar(16);default:'every';comment:通知模式: every/once/upgrade" json:"notify_mode,omitempty"`
ChannelIDs string `gorm:"type:varchar(256);comment:通知渠道ID列表JSON" json:"channel_ids,omitempty"`
NotifyChannels string `gorm:"type:text;comment:通知渠道JSON(兼容V1)" json:"notify_channels,omitempty"`
TemplateID uint `gorm:"comment:通知模板ID" json:"template_id,omitempty"`
UpgradeID uint `gorm:"comment:升级策略ID" json:"upgrade_id,omitempty"`
SilenceID uint `gorm:"comment:静默规则ID" json:"silence_id,omitempty"`
Labels string `gorm:"type:text;comment:标签JSON" json:"labels,omitempty"`
Annotations string `gorm:"type:text;comment:注释JSON" json:"annotations,omitempty"`
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by,omitempty"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
}
// TableName 表名
func (AlertRule) TableName() string {
return "monitor_alert_rules"
}
// AlertEvent 告警事件模型
// ============================================
// AlertEvent 告警事件(增强版 — 合并原V2特性)
// ============================================
// AlertEventStatus 告警事件状态
type AlertEventStatus string
const (
AlertEventFiring AlertEventStatus = "firing"
AlertEventResolved AlertEventStatus = "resolved"
AlertEventSilenced AlertEventStatus = "silenced"
)
// AlertEvent 告警事件(增强版)
type AlertEvent struct {
ID uint `gorm:"primarykey" json:"id"`
RuleID uint `json:"rule_id"`
RuleName string `gorm:"size:128" json:"rule_name"`
Severity string `gorm:"size:32" json:"severity"`
Status string `gorm:"size:32;default:firing" json:"status"` // firing, resolved
Target string `gorm:"size:255" json:"target"`
Message string `gorm:"type:text" json:"message"`
Value float64 `json:"value"`
Labels string `gorm:"type:text" json:"labels"`
StartedAt time.Time `json:"started_at"`
ResolvedAt *time.Time `json:"resolved_at"`
Acknowledged bool `json:"acknowledged"`
AcknowledgedBy *uint `json:"acknowledged_by"`
AcknowledgedAt *time.Time `json:"acknowledged_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
RuleID uint `gorm:"not null;index:idx_rule_time;comment:规则ID" json:"rule_id"`
RuleName string `gorm:"type:varchar(128);comment:规则名称" json:"rule_name,omitempty"`
Severity string `gorm:"type:varchar(32);comment:告警级别" json:"severity,omitempty"`
Status string `gorm:"type:varchar(32);default:'firing';comment:事件状态" json:"status"`
// ====== 原V1兼容字段 ======
Target string `gorm:"type:varchar(255);comment:目标标签" json:"target,omitempty"`
Message string `gorm:"type:text;comment:告警详情" json:"message,omitempty"`
Value float64 `gorm:"comment:触发值" json:"value,omitempty"`
// ====== V2增强字段 ======
TargetID uint `gorm:"index;comment:目标ID" json:"target_id,omitempty"`
TargetName string `gorm:"type:varchar(128);comment:目标名称" json:"target_name,omitempty"`
TargetIP string `gorm:"type:varchar(64);comment:目标IP" json:"target_ip,omitempty"`
Title string `gorm:"type:varchar(256);comment:告警标题" json:"title,omitempty"`
MetricName string `gorm:"type:varchar(64);comment:指标名称" json:"metric_name,omitempty"`
Threshold float64 `gorm:"comment:阈值" json:"threshold,omitempty"`
Operator string `gorm:"type:varchar(8);comment:运算符" json:"operator,omitempty"`
Unit string `gorm:"type:varchar(32);comment:单位" json:"unit,omitempty"`
Labels string `gorm:"type:text;comment:标签JSON" json:"labels,omitempty"`
Annotations string `gorm:"type:text;comment:注释JSON" json:"annotations,omitempty"`
StartedAt time.Time `gorm:"not null;index:idx_rule_time;comment:触发时间" json:"started_at"`
ResolvedAt *time.Time `gorm:"comment:恢复时间" json:"resolved_at,omitempty"`
Duration int `gorm:"comment:持续时间(秒)" json:"duration,omitempty"`
LastEvalAt time.Time `gorm:"comment:最后评估时间" json:"last_eval_at,omitempty"`
NotifyCount int `gorm:"default:0;comment:通知次数" json:"notify_count,omitempty"`
LastNotifyAt *time.Time `gorm:"comment:最近通知时间" json:"last_notify_at,omitempty"`
UpgradeLevel int `gorm:"default:0;comment:当前升级级别" json:"upgrade_level,omitempty"`
Acknowledged bool `gorm:"default:false;comment:是否已确认" json:"acknowledged"`
AcknowledgedBy *uint `gorm:"comment:确认人ID" json:"acknowledged_by,omitempty"`
AcknowledgedAt *time.Time `gorm:"comment:确认时间" json:"acknowledged_at,omitempty"`
AckComment string `gorm:"type:varchar(256);comment:确认备注" json:"ack_comment,omitempty"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
// 关联
Rule *AlertRule `json:"rule,omitempty"`
Rule *AlertRule `json:"rule,omitempty" gorm:"foreignKey:RuleID"`
}
// TableName 表名
func (AlertEvent) TableName() string {
return "monitor_alert_events"
}
// ============================================
// AlertCondition 告警条件定义
// ============================================
type AlertCondition struct {
Metric string `json:"metric"`
Operator Operator `json:"operator"`
Threshold float64 `json:"threshold"`
Unit string `json:"unit,omitempty"`
Index string `json:"index,omitempty"`
LogicOp string `json:"logic_op,omitempty"`
AggFunc AggFunction `json:"agg_func,omitempty"`
Window int `json:"window,omitempty"`
}
func (AlertCondition) TableName() string {
return "monitor_alert_conditions"
}
type AlertConditionGroup struct {
Conditions []AlertCondition `json:"conditions"`
LogicOp string `json:"logic_op"`
}
// ============================================
// AlertNotifyTemplate 告警通知模板
// ============================================
type AlertNotifyTemplate struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:模板名称" json:"name"`
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
ChannelType string `gorm:"type:varchar(32);not null;comment:适用渠道类型: email/sms/webhook/dingtalk/wecom/feishu" json:"channel_type"`
TitleTemplate string `gorm:"type:varchar(256);comment:标题模板" json:"title_template,omitempty"`
BodyTemplate string `gorm:"type:text;comment:正文模板" json:"body_template,omitempty"`
Variables string `gorm:"type:text;comment:可用变量说明JSON" json:"variables,omitempty"`
RecoverTitleTemplate string `gorm:"type:varchar(256);comment:恢复标题模板" json:"recover_title_template,omitempty"`
RecoverBodyTemplate string `gorm:"type:text;comment:恢复正文模板" json:"recover_body_template,omitempty"`
IsDefault bool `gorm:"default:false;comment:是否默认模板" json:"is_default"`
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
}
func (AlertNotifyTemplate) TableName() string {
return "monitor_alert_notify_templates"
}
type TemplateVariable struct {
Name string `json:"name"`
Description string `json:"description"`
Example string `json:"example"`
}
var DefaultTemplateVariables = []TemplateVariable{
{Name: "{{.RuleName}}", Description: "规则名称", Example: "CPU使用率告警"},
{Name: "{{.TargetName}}", Description: "目标名称", Example: "WebServer-01"},
{Name: "{{.TargetIP}}", Description: "目标IP", Example: "192.168.1.10"},
{Name: "{{.Severity}}", Description: "告警级别", Example: "critical"},
{Name: "{{.MetricName}}", Description: "指标名称", Example: "cpu_usage"},
{Name: "{{.Value}}", Description: "当前值", Example: "95.2"},
{Name: "{{.Threshold}}", Description: "阈值", Example: "90"},
{Name: "{{.Operator}}", Description: "运算符", Example: ">"},
{Name: "{{.Time}}", Description: "触发时间", Example: "2024-01-15 10:30:00"},
{Name: "{{.Duration}}", Description: "持续时间", Example: "5m"},
{Name: "{{.Description}}", Description: "规则描述", Example: "CPU使用率超过阈值"},
{Name: "{{.URL}}", Description: "详情链接", Example: "https://ezops.io/alerts/123"},
}
// ============================================
// AlertUpgrade + AlertUpgradeRecord 告警升级
// ============================================
type AlertUpgrade struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:策略名称" json:"name"`
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
Rules string `gorm:"type:text;comment:升级规则JSON数组" json:"rules,omitempty"`
MaxLevel int `gorm:"default:3;comment:最大升级级别" json:"max_level"`
IsDefault bool `gorm:"default:false;comment:是否默认策略" json:"is_default"`
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
}
func (AlertUpgrade) TableName() string {
return "monitor_alert_upgrades"
}
type AlertUpgradeRule struct {
Level int `json:"level"`
Duration int `json:"duration"`
Severity string `json:"severity"`
ChannelIDs []string `json:"channel_ids"`
NotifyUsers []uint `json:"notify_users"`
RepeatInterval int `json:"repeat_interval"`
}
type AlertUpgradeRecord struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
AlertID uint `gorm:"not null;index;comment:告警ID" json:"alert_id"`
RuleID uint `gorm:"not null;comment:规则ID" json:"rule_id"`
FromLevel int `gorm:"comment:原级别" json:"from_level"`
ToLevel int `gorm:"comment:升级后级别" json:"to_level"`
UpgradedAt time.Time `gorm:"not null;comment:升级时间" json:"upgraded_at"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
}
func (AlertUpgradeRecord) TableName() string {
return "monitor_alert_upgrade_records"
}
// ============================================
// AlertSilence 告警静默规则
// ============================================
type AlertSilenceType string
const (
AlertSilenceOneTime AlertSilenceType = "onetime"
AlertSilenceDaily AlertSilenceType = "daily"
AlertSilenceWeekly AlertSilenceType = "weekly"
)
type AlertSilence struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:静默规则名称" json:"name"`
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
RuleIDs string `gorm:"type:varchar(256);comment:匹配的告警规则ID列表JSON" json:"rule_ids,omitempty"`
TargetIDs string `gorm:"type:varchar(256);comment:匹配的目标ID列表JSON" json:"target_ids,omitempty"`
Matchers string `gorm:"type:text;comment:标签匹配条件JSON" json:"matchers,omitempty"`
SilenceType AlertSilenceType `gorm:"type:varchar(16);default:'onetime';comment:静默类型" json:"silence_type"`
StartTime time.Time `gorm:"not null;comment:开始时间" json:"start_time"`
EndTime time.Time `gorm:"not null;comment:结束时间" json:"end_time"`
Timezone string `gorm:"type:varchar(32);default:'Asia/Shanghai';comment:时区" json:"timezone"`
Weekdays string `gorm:"type:varchar(64);comment:生效星期(0-6)JSON数组" json:"weekdays,omitempty"`
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
}
func (AlertSilence) TableName() string {
return "monitor_alert_silences"
}
type AlertSilenceMatcher struct {
Name string `json:"name"`
Value string `json:"value"`
IsRegex bool `json:"is_regex"`
}
type AlertSilenceCheckResult struct {
IsSilenced bool `json:"is_silenced"`
SilenceID uint `json:"silence_id,omitempty"`
SilenceName string `json:"silence_name,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
}
// NotifyChannel 通知渠道模型
type NotifyChannel struct {
ID uint `gorm:"primarykey" json:"id"`
-405
View File
@@ -1,405 +0,0 @@
package models
import (
"time"
)
// ============================================
// AlertRuleV2 增强告警规则
// ============================================
// AlertRuleV2Status 告警规则状态
type AlertRuleV2Status string
const (
AlertRuleV2Enabled AlertRuleV2Status = "enabled" // 启用
AlertRuleV2Disabled AlertRuleV2Status = "disabled" // 禁用
)
// AlertSeverity 告警级别
type AlertSeverity string
const (
AlertSeverityCritical AlertSeverity = "critical" // 严重
AlertSeverityWarning AlertSeverity = "warning" // 警告
AlertSeverityNotice AlertSeverity = "notice" // 通知
AlertSeverityInfo AlertSeverity = "info" // 信息
)
// AggFunction 聚合函数
type AggFunction string
const (
AggFunctionAvg AggFunction = "avg" // 平均值
AggFunctionMin AggFunction = "min" // 最小值
AggFunctionMax AggFunction = "max" // 最大值
AggFunctionSum AggFunction = "sum" // 求和
AggFunctionCount AggFunction = "count" // 计数
AggFunctionLast AggFunction = "last" // 最新值
AggFunctionP95 AggFunction = "p95" // 95分位
AggFunctionP99 AggFunction = "p99" // 99分位
)
// Operator 比较运算符
type Operator string
const (
OperatorGT Operator = ">" // 大于
OperatorGTE Operator = ">=" // 大于等于
OperatorLT Operator = "<" // 小于
OperatorLTE Operator = "<=" // 小于等于
OperatorEQ Operator = "==" // 等于
OperatorNE Operator = "!=" // 不等于
)
// AlertRuleV2 增强告警规则表
// 支持多条件组合、聚合函数、静默期等高级特性
type AlertRuleV2 struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:规则名称" json:"name"`
Description string `gorm:"type:varchar(256);comment:规则描述" json:"description,omitempty"`
Severity AlertSeverity `gorm:"type:varchar(16);not null;comment:告警级别" json:"severity"`
Status AlertRuleV2Status `gorm:"type:varchar(16);default:'enabled';comment:规则状态" json:"status"`
// 关联目标
TargetType string `gorm:"type:varchar(32);comment:目标类型" json:"target_type,omitempty"`
TargetID uint `gorm:"index;comment:目标ID(0表示全部)" json:"target_id,omitempty"`
TargetTags string `gorm:"type:varchar(256);comment:目标标签筛选" json:"target_tags,omitempty"`
// 触发条件(JSON存储支持多条件)
Conditions string `gorm:"type:text;comment:触发条件JSON数组" json:"conditions,omitempty"`
// 聚合配置
AggWindow int `gorm:"default:300;comment:聚合窗口(秒)" json:"agg_window"`
AggFunction AggFunction `gorm:"type:varchar(16);default:'avg';comment:聚合函数" json:"agg_function"`
// 恢复配置
RecoverCount int `gorm:"default:1;comment:恢复次数(连续N次低于阈值触发恢复)" json:"recover_count"`
RecoverWindow int `gorm:"default:300;comment:恢复检查窗口(秒)" json:"recover_window"`
// 执行配置
Interval int `gorm:"default:60;comment:评估间隔(秒)" json:"interval"`
CheckTimes int `gorm:"default:1;comment:连续触发次数" json:"check_times"`
NotifyMode string `gorm:"type:varchar(16);default:'every';comment:通知模式: every/once/upgrade" json:"notify_mode"`
// 通知渠道
ChannelIDs string `gorm:"type:varchar(256);comment:通知渠道ID列表JSON" json:"channel_ids,omitempty"`
TemplateID uint `gorm:"comment:通知模板ID" json:"template_id,omitempty"`
// 升级策略
UpgradeID uint `gorm:"comment:升级策略ID" json:"upgrade_id,omitempty"`
// 静默策略
SilenceID uint `gorm:"comment:静默规则ID" json:"silence_id,omitempty"`
// 标签和注释
Labels string `gorm:"type:varchar(512);comment:标签JSON" json:"labels,omitempty"`
Annotations string `gorm:"type:text;comment:注释JSON(用于通知内容模板)" json:"annotations,omitempty"`
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
DeletedAt *time.Time `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
}
// TableName 指定表名
func (AlertRuleV2) TableName() string {
return "monitor_alert_rules_v2"
}
// AlertCondition 告警条件定义
type AlertCondition struct {
Metric string `json:"metric"` // 指标名称
Operator Operator `json:"operator"` // 比较运算符
Threshold float64 `json:"threshold"` // 阈值
Unit string `json:"unit"` // 单位
Index string `json:"index"` // 实例索引
LogicOp string `json:"logic_op"` // 逻辑关系: AND/OR
AggFunc AggFunction `json:"agg_func"` // 条件级聚合函数
Window int `json:"window"` // 条件级聚合窗口
}
// TableName 指定表名
func (AlertCondition) TableName() string {
return "monitor_alert_conditions"
}
// AlertConditionGroup 告警条件组
type AlertConditionGroup struct {
Conditions []AlertCondition `json:"conditions"` // 条件列表
LogicOp string `json:"logic_op"` // 组间逻辑: AND/OR
}
// RecoverConfig 告警恢复配置
type RecoverConfig struct {
Count int `json:"count"` // 连续恢复次数
Window int `json:"window"` // 恢复检查窗口(秒)
}
// NotifyMode 通知模式
type NotifyMode string
const (
NotifyModeEvery NotifyMode = "every" // 每次都通知
NotifyModeOnce NotifyMode = "once" // 仅通知一次
NotifyModeUpgrade NotifyMode = "upgrade" // 升级通知
)
// ============================================
// AlertNotifyTemplate 告警通知模板
// ============================================
// AlertNotifyTemplate 告警通知模板表
// 定义告警通知的内容模板,支持变量替换
type AlertNotifyTemplate struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:模板名称" json:"name"`
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
ChannelType string `gorm:"type:varchar(32);not null;comment:适用渠道类型: email/sms/webhook/dingtalk/wecom/feishu" json:"channel_type"`
// 模板内容
TitleTemplate string `gorm:"type:varchar(256);comment:标题模板" json:"title_template,omitempty"`
BodyTemplate string `gorm:"type:text;comment:正文模板" json:"body_template,omitempty"`
// 变量定义
Variables string `gorm:"type:text;comment:可用变量说明JSON" json:"variables,omitempty"`
// 恢复通知模板
RecoverTitleTemplate string `gorm:"type:varchar(256);comment:恢复标题模板" json:"recover_title_template,omitempty"`
RecoverBodyTemplate string `gorm:"type:text;comment:恢复正文模板" json:"recover_body_template,omitempty"`
IsDefault bool `gorm:"default:false;comment:是否默认模板" json:"is_default"`
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
DeletedAt *time.Time `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
}
// TableName 指定表名
func (AlertNotifyTemplate) TableName() string {
return "monitor_alert_notify_templates"
}
// TemplateVariable 模板变量定义
type TemplateVariable struct {
Name string `json:"name"` // 变量名
Description string `json:"description"` // 描述
Example string `json:"example"` // 示例
}
// DefaultTemplateVariables 默认模板变量
var DefaultTemplateVariables = []TemplateVariable{
{Name: "{{.RuleName}}", Description: "规则名称", Example: "CPU使用率告警"},
{Name: "{{.TargetName}}", Description: "目标名称", Example: "WebServer-01"},
{Name: "{{.TargetIP}}", Description: "目标IP", Example: "192.168.1.10"},
{Name: "{{.Severity}}", Description: "告警级别", Example: "critical"},
{Name: "{{.MetricName}}", Description: "指标名称", Example: "cpu_usage"},
{Name: "{{.Value}}", Description: "当前值", Example: "95.2"},
{Name: "{{.Threshold}}", Description: "阈值", Example: "90"},
{Name: "{{.Operator}}", Description: "运算符", Example: ">"},
{Name: "{{.Time}}", Description: "触发时间", Example: "2024-01-15 10:30:00"},
{Name: "{{.Duration}}", Description: "持续时间", Example: "5m"},
{Name: "{{.Description}}", Description: "规则描述", Example: "CPU使用率超过阈值"},
{Name: "{{.URL}}", Description: "详情链接", Example: "https://ezops.io/alerts/123"},
}
// ============================================
// AlertUpgrade 告警升级策略
// ============================================
// AlertUpgrade 告警升级策略表
// 定义告警在不同阶段的升级策略
type AlertUpgrade struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:策略名称" json:"name"`
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
// 升级规则(JSON存储支持多级升级)
Rules string `gorm:"type:text;comment:升级规则JSON数组" json:"rules,omitempty"`
// 执行配置
MaxLevel int `gorm:"default:3;comment:最大升级级别" json:"max_level"`
IsDefault bool `gorm:"default:false;comment:是否默认策略" json:"is_default"`
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
DeletedAt *time.Time `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
}
// TableName 指定表名
func (AlertUpgrade) TableName() string {
return "monitor_alert_upgrades"
}
// AlertUpgradeRule 告警升级规则
type AlertUpgradeRule struct {
Level int `json:"level"` // 升级级别
Duration int `json:"duration"` // 触发升级的持续时长(秒)
Severity string `json:"severity"` // 升级后的级别
ChannelIDs []string `json:"channel_ids"` // 升级后通知渠道
NotifyUsers []uint `json:"notify_users"` // 升级后通知用户
RepeatInterval int `json:"repeat_interval"` // 重复通知间隔(秒)
}
// AlertUpgradeRecord 告警升级记录
type AlertUpgradeRecord struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
AlertID uint `gorm:"not null;index;comment:告警ID" json:"alert_id"`
RuleID uint `gorm:"not null;comment:规则ID" json:"rule_id"`
FromLevel int `gorm:"comment:原级别" json:"from_level"`
ToLevel int `gorm:"comment:升级后级别" json:"to_level"`
UpgradedAt time.Time `gorm:"not null;comment:升级时间" json:"upgraded_at"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
}
// TableName 指定表名
func (AlertUpgradeRecord) TableName() string {
return "monitor_alert_upgrade_records"
}
// ============================================
// AlertSilence 告警静默规则
// ============================================
// AlertSilenceType 静默类型
type AlertSilenceType string
const (
AlertSilenceOneTime AlertSilenceType = "onetime" // 一次性静默
AlertSilenceDaily AlertSilenceType = "daily" // 每日重复
AlertSilenceWeekly AlertSilenceType = "weekly" // 每周重复
)
// AlertSilence 告警静默规则表
// 定义告警静默策略,支持一次性、周期性静默
type AlertSilence struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:静默规则名称" json:"name"`
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
// 匹配条件
RuleIDs string `gorm:"type:varchar(256);comment:匹配的告警规则ID列表JSON" json:"rule_ids,omitempty"`
TargetIDs string `gorm:"type:varchar(256);comment:匹配的目标ID列表JSON" json:"target_ids,omitempty"`
Matchers string `gorm:"type:text;comment:标签匹配条件JSON" json:"matchers,omitempty"`
// 时间配置
SilenceType AlertSilenceType `gorm:"type:varchar(16);default:'onetime';comment:静默类型" json:"silence_type"`
StartTime time.Time `gorm:"not null;comment:开始时间" json:"start_time"`
EndTime time.Time `gorm:"not null;comment:结束时间" json:"end_time"`
Timezone string `gorm:"type:varchar(32);default:'Asia/Shanghai';comment:时区" json:"timezone"`
// 周期性配置
Weekdays string `gorm:"type:varchar(64);comment:生效星期(0-6)JSON数组" json:"weekdays,omitempty"`
// 状态
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
DeletedAt *time.Time `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
}
// TableName 指定表名
func (AlertSilence) TableName() string {
return "monitor_alert_silences"
}
// AlertSilenceMatcher 静默匹配条件
type AlertSilenceMatcher struct {
Name string `json:"name"` // 标签名
Value string `json:"value"` // 标签值
IsRegex bool `json:"is_regex"` // 是否正则匹配
}
// AlertSilenceCheckResult 静默检查结果
type AlertSilenceCheckResult struct {
IsSilenced bool `json:"is_silenced"`
SilenceID uint `json:"silence_id,omitempty"`
SilenceName string `json:"silence_name,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
}
// ============================================
// AlertEventV2 增强告警事件
// ============================================
// AlertEventV2Status 告警事件状态
type AlertEventV2Status string
const (
AlertEventV2Firing AlertEventV2Status = "firing" // 触发中
AlertEventV2Resolved AlertEventV2Status = "resolved" // 已恢复
AlertEventV2Silenced AlertEventV2Status = "silenced" // 已静默
)
// AlertEventV2 增强告警事件表
// 记录告警触发和恢复的全过程
type AlertEventV2 struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
RuleID uint `gorm:"not null;index:idx_rule_time;comment:规则ID" json:"rule_id"`
TargetID uint `gorm:"not null;index;comment:目标ID" json:"target_id"`
TargetName string `gorm:"type:varchar(128);comment:目标名称" json:"target_name,omitempty"`
TargetIP string `gorm:"type:varchar(64);comment:目标IP" json:"target_ip,omitempty"`
Severity AlertSeverity `gorm:"type:varchar(16);not null;index;comment:告警级别" json:"severity"`
Status AlertEventV2Status `gorm:"type:varchar(16);default:'firing';index;comment:事件状态" json:"status"`
Title string `gorm:"type:varchar(256);not null;comment:告警标题" json:"title"`
Message string `gorm:"type:text;comment:告警详情" json:"message,omitempty"`
// 触发值信息
MetricName string `gorm:"type:varchar(64);comment:指标名称" json:"metric_name,omitempty"`
Value float64 `gorm:"comment:触发值" json:"value,omitempty"`
Threshold float64 `gorm:"comment:阈值" json:"threshold,omitempty"`
Operator string `gorm:"type:varchar(8);comment:运算符" json:"operator,omitempty"`
Unit string `gorm:"type:varchar(32);comment:单位" json:"unit,omitempty"`
// 标签和注释
Labels string `gorm:"type:varchar(512);comment:标签JSON" json:"labels,omitempty"`
Annotations string `gorm:"type:text;comment:注释JSON" json:"annotations,omitempty"`
// 时间信息
StartedAt time.Time `gorm:"not null;index:idx_rule_time;comment:触发时间" json:"started_at"`
ResolvedAt *time.Time `gorm:"comment:恢复时间" json:"resolved_at,omitempty"`
Duration int `gorm:"comment:持续时间(秒)" json:"duration,omitempty"`
LastEvalAt time.Time `gorm:"comment:最后评估时间" json:"last_eval_at,omitempty"`
NotifyCount int `gorm:"default:0;comment:通知次数" json:"notify_count"`
LastNotifyAt *time.Time `gorm:"comment:最近通知时间" json:"last_notify_at,omitempty"`
UpgradeLevel int `gorm:"default:0;comment:当前升级级别" json:"upgrade_level"`
// 确认信息
Acknowledged bool `gorm:"default:false;comment:是否已确认" json:"acknowledged"`
AcknowledgedBy uint `gorm:"comment:确认人ID" json:"acknowledged_by,omitempty"`
AcknowledgedAt *time.Time `gorm:"comment:确认时间" json:"acknowledged_at,omitempty"`
AckComment string `gorm:"type:varchar(256);comment:确认备注" json:"ack_comment,omitempty"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
}
// TableName 指定表名
func (AlertEventV2) TableName() string {
return "monitor_alert_events_v2"
}
// AlertRuleV2CreateRequest 告警规则创建请求
type AlertRuleV2CreateRequest struct {
Name string `json:"name" binding:"required,max=128"`
Description string `json:"description"`
Severity AlertSeverity `json:"severity" binding:"required"`
TargetType string `json:"target_type"`
TargetID uint `json:"target_id"`
TargetTags string `json:"target_tags"`
Conditions []AlertCondition `json:"conditions" binding:"required,min=1"`
AggWindow int `json:"agg_window"`
AggFunction AggFunction `json:"agg_function"`
RecoverCount int `json:"recover_count"`
Interval int `json:"interval"`
CheckTimes int `json:"check_times"`
NotifyMode string `json:"notify_mode"`
ChannelIDs []string `json:"channel_ids"`
TemplateID uint `json:"template_id"`
UpgradeID uint `json:"upgrade_id"`
SilenceID uint `json:"silence_id"`
Labels map[string]string `json:"labels"`
Annotations map[string]string `json:"annotations"`
}
// AlertRuleV2UpdateRequest 告警规则更新请求
type AlertRuleV2UpdateRequest struct {
Name string `json:"name" binding:"max=128"`
Description string `json:"description"`
Severity AlertSeverity `json:"severity"`
Status AlertRuleV2Status `json:"status"`
TargetType string `json:"target_type"`
TargetID uint `json:"target_id"`
TargetTags string `json:"target_tags"`
Conditions []AlertCondition `json:"conditions"`
AggWindow int `json:"agg_window"`
AggFunction AggFunction `json:"agg_function"`
RecoverCount int `json:"recover_count"`
Interval int `json:"interval"`
CheckTimes int `json:"check_times"`
NotifyMode string `json:"notify_mode"`
ChannelIDs []string `json:"channel_ids"`
TemplateID uint `json:"template_id"`
UpgradeID uint `json:"upgrade_id"`
SilenceID uint `json:"silence_id"`
Labels map[string]string `json:"labels"`
Annotations map[string]string `json:"annotations"`
}
+107 -8
View File
@@ -10,6 +10,7 @@ type Pipeline struct {
ID uint `gorm:"primarykey" json:"id"`
Name string `gorm:"size:128;not null" json:"name"`
Code string `gorm:"size:64;uniqueIndex;not null" json:"code"`
JobName string `gorm:"size:128;uniqueIndex;comment:Job名称(webhook URL标识, 如 cex-admin-server)" json:"job_name,omitempty"`
Description string `gorm:"size:500" json:"description"`
Type string `gorm:"size:32;default:deploy" json:"type"` // build, deploy, test
Source string `gorm:"size:255" json:"source"` // Git仓库地址
@@ -18,13 +19,51 @@ type Pipeline struct {
Stages string `gorm:"type:text" json:"stages"` // JSON
Variables string `gorm:"type:text" json:"variables"` // JSON
Enabled bool `gorm:"default:true" json:"enabled"`
LastRunAt *time.Time `json:"last_run_at"`
LastStatus string `gorm:"size:32" json:"last_status"`
RunCount int `gorm:"default:0" json:"run_count"`
SuccessCount int `gorm:"default:0" json:"success_count"`
FailCount int `gorm:"default:0" json:"fail_count"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 部署模式
DeployMode string `gorm:"size:16;default:branch;comment:部署模式 branch/tag" json:"deploy_mode"`
DeployTarget string `gorm:"size:16;default:ssh;comment:部署目标 ssh/k8s" json:"deploy_target"`
// SSH 部署目标服务器 (JSON: [1,2,3])
ServerIDs string `gorm:"type:text;comment:SSH服务器ID列表(JSON)" json:"server_ids,omitempty"`
// K8s 部署目标
K8sClusterID *uint `json:"k8s_cluster_id,omitempty"` // FK → kubernetes_clusters
K8sNamespace string `gorm:"size:128;comment:K8s部署命名空间" json:"k8s_namespace,omitempty"`
// 仓库和镜像仓库关联(旧字段,待废弃)
RepoID *uint `json:"repo_id"` // FK → deploy_pipeline_repos
RegistryID *uint `json:"registry_id"` // FK → deploy_pipeline_registries
// 凭证关联(直接关联凭证 ID)
GitCredentialID *uint `json:"git_credential_id"` // FK → iam_credentials (Git Token)
RegistryCredentialID *uint `json:"registry_credential_id"` // FK → iam_credentials (Docker Password)
// 环境分组
EnvironmentID *uint `json:"environment_id"` // FK → deploy_environments
// 触发配置
TriggerMode string `gorm:"type:varchar(32);default:'manual';comment:触发方式: git_push/cron/webhook/manual" json:"trigger_mode"`
WatchBranches string `gorm:"type:varchar(256);comment:监听分支(逗号分隔, 支持通配)" json:"watch_branches,omitempty"`
ExcludeBranch string `gorm:"type:varchar(256);comment:排除分支" json:"exclude_branch,omitempty"`
CronExpr string `gorm:"type:varchar(64);comment:Cron 表达式" json:"cron_expr,omitempty"`
WebhookToken string `gorm:"type:varchar(128);comment:Webhook 签名 Token" json:"webhook_token,omitempty"`
// 缓存配置
CachePaths string `gorm:"type:text;comment:缓存路径(逗号分隔)" json:"cache_paths,omitempty"`
LastRunAt *time.Time `json:"last_run_at"`
LastStatus string `gorm:"size:32" json:"last_status"`
RunCount int `gorm:"default:0" json:"run_count"`
SuccessCount int `gorm:"default:0" json:"success_count"`
FailCount int `gorm:"default:0" json:"fail_count"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 关联
Repo *PipelineRepo `json:"repo,omitempty" gorm:"foreignKey:RepoID"`
Registry *PipelineRegistry `json:"registry,omitempty" gorm:"foreignKey:RegistryID"`
Environment *DeployEnvironment `json:"environment,omitempty" gorm:"foreignKey:EnvironmentID"`
}
// TableName 表名
@@ -44,6 +83,7 @@ type PipelineRun struct {
Author string `gorm:"size:64" json:"author"`
ImageTag string `gorm:"size:255" json:"image_tag"` // 构建产物镜像标签
ArtifactURL string `gorm:"size:500" json:"artifact_url"` // 构建产物地址
WorkspacePath string `gorm:"size:500" json:"workspace_path"` // 工作区路径
Duration int `json:"duration"` // 秒
Stages string `gorm:"type:text" json:"stages"` // JSON
Logs string `gorm:"type:longtext" json:"logs"`
@@ -98,6 +138,7 @@ func (AppRelease) TableName() string {
type CreatePipelineRequest struct {
Name string `json:"name" binding:"required"`
Code string `json:"code" binding:"required"`
JobName string `json:"job_name"` // Webhook Job名称
Description string `json:"description"`
Type string `json:"type" binding:"omitempty,oneof=build deploy test"`
Source string `json:"source"`
@@ -105,11 +146,69 @@ type CreatePipelineRequest struct {
Dockerfile string `json:"dockerfile"`
Stages string `json:"stages"`
Variables string `json:"variables"`
// 部署模式
DeployMode string `json:"deploy_mode"` // branch / tag
DeployTarget string `json:"deploy_target"` // ssh / k8s
ServerIDs string `json:"server_ids"` // SSH 服务器ID JSON [1,2,3]
K8sClusterID *uint `json:"k8s_cluster_id"`
K8sNamespace string `json:"k8s_namespace"`
RepoID *uint `json:"repo_id"`
RegistryID *uint `json:"registry_id"`
// 凭证关联
GitCredentialID *uint `json:"git_credential_id"`
RegistryCredentialID *uint `json:"registry_credential_id"`
EnvironmentID *uint `json:"environment_id"`
// 触发配置
TriggerMode string `json:"trigger_mode"`
WatchBranches string `json:"watch_branches"`
ExcludeBranch string `json:"exclude_branch"`
CronExpr string `json:"cron_expr"`
WebhookToken string `json:"webhook_token"`
// 缓存路径
CachePaths string `json:"cache_paths"`
}
// UpdatePipelineRequest 更新流水线请求
type UpdatePipelineRequest struct {
Name string `json:"name"`
JobName string `json:"job_name"`
Description string `json:"description"`
Type string `json:"type"`
Source string `json:"source"`
Branch string `json:"branch"`
Dockerfile string `json:"dockerfile"`
Stages string `json:"stages"`
Variables string `json:"variables"`
DeployMode string `json:"deploy_mode"`
DeployTarget string `json:"deploy_target"`
ServerIDs string `json:"server_ids"`
K8sClusterID *uint `json:"k8s_cluster_id"`
K8sNamespace string `json:"k8s_namespace"`
RepoID *uint `json:"repo_id"`
RegistryID *uint `json:"registry_id"`
// 凭证关联
GitCredentialID *uint `json:"git_credential_id"`
RegistryCredentialID *uint `json:"registry_credential_id"`
EnvironmentID *uint `json:"environment_id"`
// 触发配置
TriggerMode string `json:"trigger_mode"`
WatchBranches string `json:"watch_branches"`
ExcludeBranch string `json:"exclude_branch"`
CronExpr string `json:"cron_expr"`
WebhookToken string `json:"webhook_token"`
// 缓存
CachePaths string `json:"cache_paths"`
Enabled *bool `json:"enabled"`
}
// TriggerPipelineRequest 触发流水线请求
type TriggerPipelineRequest struct {
Branch string `json:"branch"`
Branch string `json:"branch"`
Tag string `json:"tag"` // 发布 Tag
Variables map[string]string `json:"variables"`
}
+183 -29
View File
@@ -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"`
}
+193
View File
@@ -0,0 +1,193 @@
package models
import "time"
// ============================================
// PipelineRepo Git 仓库认证配置
// ============================================
// RepoAuthType 仓库认证方式
type RepoAuthType string
const (
RepoAuthToken RepoAuthType = "token" // Personal Access Token
RepoAuthSSH RepoAuthType = "ssh" // SSH Key
RepoAuthPassword RepoAuthType = "password" // 用户名+密码
)
// PipelineRepo Git 仓库认证配置表
type PipelineRepo struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:配置名称" json:"name"`
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
URL string `gorm:"type:varchar(512);not null;comment:仓库 URL" json:"url"`
AuthType RepoAuthType `gorm:"type:varchar(16);default:'token';comment:认证方式: token/ssh/password" json:"auth_type"`
CredentialID *uint `gorm:"index;comment:凭据ID(关联 iam_credentials)" json:"credential_id,omitempty"`
Enabled bool `gorm:"default:true;comment:是否启用" json:"enabled"`
CreatedBy string `gorm:"type:varchar(64);comment:创建人" json:"created_by,omitempty"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
}
// TableName 表名
func (PipelineRepo) TableName() string {
return "deploy_pipeline_repos"
}
// ============================================
// PipelineRegistry 镜像仓库认证配置
// ============================================
// RegistryAuthType 镜像仓库认证方式
type RegistryAuthType string
const (
RegistryAuthToken RegistryAuthType = "token" // Access Token
RegistryAuthPassword RegistryAuthType = "password" // 用户名+密码
)
// PipelineRegistry 镜像仓库认证配置表
type PipelineRegistry struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(128);not null;comment:配置名称" json:"name"`
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
RegistryURL string `gorm:"type:varchar(512);not null;comment:镜像仓库地址" json:"registry_url"`
Namespace string `gorm:"type:varchar(128);comment:默认命名空间" json:"namespace,omitempty"`
AuthType RegistryAuthType `gorm:"type:varchar(16);default:'password';comment:认证方式: token/password" json:"auth_type"`
CredentialID *uint `gorm:"index;comment:凭据ID(关联 iam_credentials)" json:"credential_id,omitempty"`
Enabled bool `gorm:"default:true;comment:是否启用" json:"enabled"`
CreatedBy string `gorm:"type:varchar(64);comment:创建人" json:"created_by,omitempty"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
}
// TableName 表名
func (PipelineRegistry) TableName() string {
return "deploy_pipeline_registries"
}
// ============================================
// PipelineStage 流水线阶段定义(JSON)
// ============================================
// PipelineStage 一个阶段包含多个任务
type PipelineStage struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"` // source/build/deploy/test/custom
Tasks []PipelineTask `json:"tasks"`
}
// PipelineTask 阶段内的任务
type PipelineTask struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"` // build/deploy/test/custom
Icon string `json:"icon,omitempty"`
Config map[string]string `json:"config,omitempty"`
Script string `json:"script,omitempty"`
ScriptType string `json:"script_type,omitempty"` // shell/python
}
// ============================================
// DeployEnvironment 发布环境分组
// ============================================
type EnvironmentType string
const (
EnvProduction EnvironmentType = "production"
EnvStaging EnvironmentType = "staging"
EnvTesting EnvironmentType = "testing"
EnvDev EnvironmentType = "development"
)
// DeployEnvironment 环境分组表(生产/测试/预发布/开发)
type DeployEnvironment struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(64);not null;uniqueIndex;comment:环境名称" json:"name"`
DisplayName string `gorm:"type:varchar(128);not null;comment:显示名称" json:"display_name"`
Type EnvironmentType `gorm:"type:varchar(16);not null;index;comment:环境类型: production/staging/testing/development" json:"type"`
Color string `gorm:"type:varchar(16);default:'#3B82F6';comment:标识颜色" json:"color"`
SortOrder int `gorm:"default:0;comment:排序" json:"sort_order"`
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
Enabled bool `gorm:"default:true;comment:是否启用" json:"enabled"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
}
func (DeployEnvironment) TableName() string {
return "deploy_environments"
}
// ============================================
// DeployPipelineMember 流水线成员
// ============================================
type MemberRole string
const (
MemberOwner MemberRole = "owner" // 拥有者
MemberEditor MemberRole = "editor" // 编辑者
MemberViewer MemberRole = "viewer" // 查看者
)
// DeployPipelineMember 流水线成员表
// 支持两种授权方式:直接用户授权(username 非空)和用户组授权(group_id 非空)
type DeployPipelineMember struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
PipelineID uint `gorm:"index:idx_pipeline_user,unique,priority:1;index:idx_pipeline_group,unique,priority:1;not null;comment:流水线ID" json:"pipeline_id"`
Username *string `gorm:"type:varchar(64);index:idx_pipeline_user,unique,priority:2;comment:用户名(直接授权)" json:"username,omitempty"`
GroupID *uint `gorm:"index:idx_pipeline_group,unique,priority:2;comment:用户组ID(组授权)" json:"group_id,omitempty"`
Role MemberRole `gorm:"type:varchar(16);default:'editor';comment:角色: owner/editor/viewer" json:"role"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
// 关联
Pipeline *Pipeline `json:"pipeline,omitempty" gorm:"foreignKey:PipelineID"`
Group *DeployUserGroup `json:"group,omitempty" gorm:"foreignKey:GroupID"`
}
func (DeployPipelineMember) TableName() string {
return "deploy_pipeline_members"
}
// ============================================
// DeployUserGroup 发布系统用户组
// ============================================
// DeployUserGroup 用户组(用于流水线权限分组授权)
type DeployUserGroup struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
Name string `gorm:"type:varchar(64);uniqueIndex;not null;comment:组名称" json:"name"`
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
CreatedBy string `gorm:"type:varchar(64);comment:创建人" json:"created_by,omitempty"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
// 关联
Members []DeployUserGroupMember `json:"members,omitempty" gorm:"foreignKey:GroupID"`
}
func (DeployUserGroup) TableName() string {
return "deploy_user_groups"
}
// ============================================
// DeployUserGroupMember 用户组成员
// ============================================
// DeployUserGroupMember 用户组成员关联表
type DeployUserGroupMember struct {
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
GroupID uint `gorm:"uniqueIndex:idx_group_user;not null;comment:组ID" json:"group_id"`
Username string `gorm:"type:varchar(64);uniqueIndex:idx_group_user;not null;comment:用户名" json:"username"`
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
// 关联
Group *DeployUserGroup `json:"group,omitempty" gorm:"foreignKey:GroupID"`
}
func (DeployUserGroupMember) TableName() string {
return "deploy_user_group_members"
}
+63 -4
View File
@@ -69,6 +69,40 @@ func (Permission) TableName() string {
return "iam_permissions"
}
// ItemRole Jenkins-style Item Role — regex pipeline code matching
type ItemRole struct {
ID uint `gorm:"primarykey" json:"id"`
Name string `gorm:"size:64;not null" json:"name"`
Code string `gorm:"size:64;uniqueIndex;not null" json:"code"`
Pattern string `gorm:"size:255;not null;comment:正则表达式匹配流水线code" json:"pattern"`
Role string `gorm:"size:16;default:'editor';comment:角色owner/editor/viewer" json:"role"`
Description string `gorm:"size:255" json:"description"`
Status int `gorm:"default:1;comment:0禁用1启用" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// TableName 表名
func (ItemRole) TableName() string {
return "iam_item_roles"
}
// UserItemRole user ↔ item_role association
type UserItemRole struct {
ID uint `gorm:"primarykey" json:"id"`
UserID uint `gorm:"uniqueIndex:idx_user_item_role;not null" json:"user_id"`
ItemRoleID uint `gorm:"uniqueIndex:idx_user_item_role;not null" json:"item_role_id"`
CreatedAt time.Time `json:"created_at"`
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
ItemRole *ItemRole `json:"item_role,omitempty" gorm:"foreignKey:ItemRoleID"`
}
// TableName 表名
func (UserItemRole) TableName() string {
return "iam_user_item_roles"
}
// LoginRequest 登录请求
type LoginRequest struct {
Username string `json:"username" binding:"required"`
@@ -111,11 +145,36 @@ type CreateRoleRequest struct {
// UpdateRoleRequest 更新角色请求 // Logan.Li
type UpdateRoleRequest struct {
Name string `json:"name" binding:"omitempty,min=1,max=64"`
Code string `json:"code" binding:"omitempty,min=1,max=64"`
Name string `json:"name" binding:"omitempty,min=1,max=64"`
Code string `json:"code" binding:"omitempty,min=1,max=64"`
Description *string `json:"description"`
Status *int `json:"status"`
PermissionIDs []uint `json:"permission_ids"`
Status *int `json:"status"`
PermissionIDs []uint `json:"permission_ids"`
}
// CreateItemRoleRequest 创建Item Role请求
type CreateItemRoleRequest struct {
Name string `json:"name" binding:"required,min=1,max=64"`
Code string `json:"code" binding:"required,min=1,max=64"`
Pattern string `json:"pattern" binding:"required,max=255"`
Role string `json:"role" binding:"oneof=owner editor viewer"`
Description string `json:"description"`
}
// UpdateItemRoleRequest 更新Item Role请求
type UpdateItemRoleRequest struct {
Name string `json:"name" binding:"omitempty,min=1,max=64"`
Code string `json:"code" binding:"omitempty,min=1,max=64"`
Pattern string `json:"pattern" binding:"omitempty,max=255"`
Role string `json:"role" binding:"omitempty,oneof=owner editor viewer"`
Description string `json:"description"`
Status *int `json:"status"`
}
// AssignItemRoleRequest 分配Item Role给用户
type AssignItemRoleRequest struct {
UserID uint `json:"user_id" binding:"required"`
ItemRoleID uint `json:"item_role_id" binding:"required"`
}
// ChangePasswordRequest 修改密码请求