feat(audit): F1+F2 告警静默规则标记完成 + 审计日志CSV导出实现
F1 告警静默规则 [done]: - 后端 alert_silence.go: CRUD + Toggle (onetime/daily/weekly 三模式) - 告警引擎 isSilenced 集成 (alert_engine.go) - 前端 SilenceRuleTab + SilenceDialog - 路由 /alerts/silences 已注册 F2 审计日志导出 [done]: - 重写 ExportAuditLogs: 真正的 CSV 导出 (encoding/csv + UTF-8 BOM) - 支持 module/action/username/startTime/endTime 筛选 - 导出限制 10000 条防溢出,自动记录审计日志 - JSON 格式向后兼容 (format=json) - 前端 exportLogs 传递查询参数 同时包含累积的前期工作: - 目录重构 internal/ -> controller/model/router (v0.55-v0.57) - 后端分层架构 dto/repository/service/utils - 审计模块全功能 (终端审计/操作审计/登录日志) - asciicast v2 录制格式 - SFTP 文件浏览器 - StatStrip 紧凑统计条 - 在线会话自动刷新 - LiveMonitor WebSocket 诊断修复 验证: go build ✅ | npm run build ✅ | Docker 部署 ✅ | 10 回归端点 ✅ | CSV 导出 ✅ | 静默 CRUD ✅
This commit is contained in:
1 parent
e57718998a
commit
77c234b060
314 files changed
+10050
-4065
No files matched your search
@@ -0,0 +1,217 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// AgentReport Agent 上报的原始指标数据 // Logan.Li
|
||||
type AgentReport struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Hostname string `gorm:"size:255;index;not null" json:"hostname"`
|
||||
CPUUsage float64 `gorm:"type:decimal(6,2)" json:"cpu_usage"`
|
||||
CPUIOwait float64 `gorm:"type:decimal(6,2)" json:"cpu_iowait"`
|
||||
CPUCores int `json:"cpu_cores"`
|
||||
Load1 float64 `gorm:"type:decimal(8,2)" json:"load1"`
|
||||
Load5 float64 `gorm:"type:decimal(8,2)" json:"load5"`
|
||||
Load15 float64 `gorm:"type:decimal(8,2)" json:"load15"`
|
||||
MemTotal float64 `gorm:"type:decimal(10,2)" json:"mem_total"`
|
||||
MemUsed float64 `gorm:"type:decimal(10,2)" json:"mem_used"`
|
||||
MemUsage float64 `gorm:"type:decimal(6,2)" json:"mem_usage"`
|
||||
MemAvailable float64 `gorm:"type:decimal(10,2)" json:"mem_available"`
|
||||
MemSwapUsed float64 `gorm:"type:decimal(10,2)" json:"mem_swap_used"`
|
||||
DiskInfo string `gorm:"type:text" json:"disk_info"`
|
||||
PortInfo string `gorm:"type:text" json:"port_info"`
|
||||
NetInfo string `gorm:"type:text" json:"net_info"`
|
||||
DiskIOInfo string `gorm:"type:text" json:"disk_io_info"`
|
||||
// ──── v2.0 新增字段 ────
|
||||
SwapInfo string `gorm:"type:text" json:"swap_info"` // Swap JSON
|
||||
ProcessTopInfo string `gorm:"type:text" json:"process_top_info"` // 进程 TOP JSON
|
||||
FDInfo string `gorm:"type:text" json:"fd_info"` // FD 句柄 JSON
|
||||
CSInfo string `gorm:"type:text" json:"cs_info"` // 上下文切换 JSON
|
||||
HeartbeatInfo string `gorm:"type:text" json:"heartbeat_info"` // Agent 心跳 JSON
|
||||
// ──────────────────────────
|
||||
ReportTime time.Time `json:"report_time"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (AgentReport) TableName() string {
|
||||
return "monitor_agent_reports"
|
||||
}
|
||||
|
||||
// AgentLatestResponse Agent 最新状态(含服务器元信息)
|
||||
type AgentLatestResponse struct {
|
||||
ServerID uint `json:"server_id"`
|
||||
Hostname string `json:"hostname"`
|
||||
IP string `json:"ip"`
|
||||
CPUUsage float64 `json:"cpu_usage"`
|
||||
CPUCores int `json:"cpu_cores"`
|
||||
MemUsage float64 `json:"mem_usage"`
|
||||
MemTotal float64 `json:"mem_total"`
|
||||
MemUsed float64 `json:"mem_used"`
|
||||
DiskUsage float64 `json:"disk_usage"`
|
||||
DiskTotal int64 `json:"disk_total"`
|
||||
DiskInfo string `json:"disk_info"`
|
||||
PortInfo string `json:"port_info"`
|
||||
NetInfo string `json:"net_info"`
|
||||
DiskIOInfo string `json:"disk_io_info"`
|
||||
// ──── v2.0 新增 ────
|
||||
SwapInfo string `json:"swap_info"`
|
||||
ProcessTopInfo string `json:"process_top_info"`
|
||||
FDInfo string `json:"fd_info"`
|
||||
CSInfo string `json:"cs_info"`
|
||||
HeartbeatInfo string `json:"heartbeat_info"`
|
||||
// ─────────────────
|
||||
ReportTime string `json:"report_time"`
|
||||
AgentVersion string `json:"agent_version"`
|
||||
AgentStatus string `json:"agent_status"`
|
||||
OS string `json:"os"`
|
||||
Kernel string `json:"kernel"`
|
||||
Uptime int64 `json:"uptime"`
|
||||
Region string `json:"region"`
|
||||
HasAuth bool `json:"has_auth"`
|
||||
}
|
||||
|
||||
// AgentReportRequest Agent 上报请求体
|
||||
type AgentReportRequest struct {
|
||||
Hostname string `json:"hostname" binding:"required"`
|
||||
IP string `json:"ip"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
AgentVersion string `json:"agent_version"`
|
||||
CPU CPUMetric `json:"cpu"`
|
||||
Memory MemMetric `json:"memory"`
|
||||
Swap *SwapMetric `json:"swap,omitempty"`
|
||||
Disks []DiskMetric `json:"disks"`
|
||||
Ports []PortMetric `json:"ports"`
|
||||
Network NetworkStatModel `json:"network"`
|
||||
DiskIO DiskIOStatModel `json:"disk_io"`
|
||||
System *SystemStatModel `json:"system,omitempty"`
|
||||
// ──── v2.0 新增 ────
|
||||
ProcessTop []ProcessMetric `json:"process_top,omitempty"`
|
||||
FD *FDMetric `json:"fd,omitempty"`
|
||||
ContextSwitches *CSMetric `json:"context_switches,omitempty"`
|
||||
Heartbeat HeartbeatMetric `json:"heartbeat"`
|
||||
ProbeResults []HealthProbeResult `json:"probe_results,omitempty"` // v2.1 健康探针结果
|
||||
}
|
||||
|
||||
// ──── v2.0 新增上报类型 ────
|
||||
|
||||
type SwapMetric struct {
|
||||
TotalGB float64 `json:"total_gb"`
|
||||
UsedGB float64 `json:"used_gb"`
|
||||
UsagePercent float64 `json:"usage_percent"`
|
||||
}
|
||||
|
||||
type ProcessMetric struct {
|
||||
PID int `json:"pid"`
|
||||
Name string `json:"name"`
|
||||
Cmdline string `json:"cmdline"`
|
||||
User string `json:"user"`
|
||||
CPUPct float64 `json:"cpu_pct"`
|
||||
MemPct float64 `json:"mem_pct"`
|
||||
MemoryMB float64 `json:"memory_mb"`
|
||||
FDCount int `json:"fd_count"`
|
||||
Threads int `json:"threads"`
|
||||
}
|
||||
|
||||
type FDMetric struct {
|
||||
Allocated int `json:"allocated"`
|
||||
Max int64 `json:"max"`
|
||||
UsagePct float64 `json:"usage_pct"`
|
||||
}
|
||||
|
||||
type CSMetric struct {
|
||||
CTXPerSec float64 `json:"ctx_per_sec"`
|
||||
IRQPerSec float64 `json:"irq_per_sec"`
|
||||
}
|
||||
|
||||
type HeartbeatMetric struct {
|
||||
Version string `json:"version"`
|
||||
UptimeSec int64 `json:"uptime_sec"`
|
||||
LastErr string `json:"last_err,omitempty"`
|
||||
SelfCPU float64 `json:"self_cpu_pct"`
|
||||
SelfRSSMB float64 `json:"self_rss_mb"`
|
||||
ReportSeq uint64 `json:"report_seq"`
|
||||
}
|
||||
|
||||
// ──── 已有类型 ────
|
||||
|
||||
type SystemStatModel struct {
|
||||
OSVersion string `json:"os_version"`
|
||||
Kernel string `json:"kernel"`
|
||||
Uptime int64 `json:"uptime"`
|
||||
}
|
||||
|
||||
type CPUMetric struct {
|
||||
UsagePercent float64 `json:"usage_percent"`
|
||||
IOWait float64 `json:"iowait"`
|
||||
CoreCount int `json:"core_count"`
|
||||
Load1 float64 `json:"load1"`
|
||||
Load5 float64 `json:"load5"`
|
||||
Load15 float64 `json:"load15"`
|
||||
}
|
||||
|
||||
type MemMetric struct {
|
||||
TotalGB float64 `json:"total_gb"`
|
||||
UsedGB float64 `json:"used_gb"`
|
||||
CachedGB float64 `json:"cached_gb"`
|
||||
AvailableGB float64 `json:"available_gb"`
|
||||
SwapUsedGB float64 `json:"swap_used_gb"`
|
||||
UsagePercent float64 `json:"usage_percent"`
|
||||
}
|
||||
|
||||
type DiskMetric struct {
|
||||
Mount string `json:"mount"`
|
||||
Device string `json:"device"`
|
||||
TotalGB float64 `json:"total_gb"`
|
||||
UsedGB float64 `json:"used_gb"`
|
||||
UsagePercent float64 `json:"usage_percent"`
|
||||
InodeUsagePct float64 `json:"inode_usage_pct"`
|
||||
}
|
||||
|
||||
type PortMetric struct {
|
||||
Port int `json:"port"`
|
||||
Protocol string `json:"protocol"`
|
||||
Process string `json:"process"`
|
||||
PID int `json:"pid"`
|
||||
}
|
||||
|
||||
type NetworkStatModel struct {
|
||||
TCPEstablished int `json:"tcp_established"`
|
||||
TCPTimeWait int `json:"tcp_time_wait"`
|
||||
TCPCloseWait int `json:"tcp_close_wait"`
|
||||
TCPTotal int `json:"tcp_total"`
|
||||
NicName string `json:"nic_name"`
|
||||
NetRxBPS float64 `json:"net_rx_bps"`
|
||||
NetTxBPS float64 `json:"net_tx_bps"`
|
||||
NetRxErrors int64 `json:"net_rx_errors"`
|
||||
NetTxErrors int64 `json:"net_tx_errors"`
|
||||
}
|
||||
|
||||
type DiskIOStatModel struct {
|
||||
ReadBPS float64 `json:"read_bps"`
|
||||
WriteBPS float64 `json:"write_bps"`
|
||||
ReadIOPS float64 `json:"read_iops"`
|
||||
WriteIOPS float64 `json:"write_iops"`
|
||||
Util float64 `json:"util"`
|
||||
}
|
||||
|
||||
// AgentPortPolicy 主机端口监控策略 // Logan.Li
|
||||
type AgentPortPolicy struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Hostname string `gorm:"size:255;uniqueIndex;not null" json:"hostname"`
|
||||
PortFilterMode string `gorm:"size:20;default:whitelist;not null" json:"port_filter_mode"` // whitelist / blacklist
|
||||
PortWhitelist string `gorm:"type:text" json:"port_whitelist"` // JSON 数组,如 [80,443,3306,6379]
|
||||
}
|
||||
|
||||
func (AgentPortPolicy) TableName() string {
|
||||
return "monitor_agent_port_policy"
|
||||
}
|
||||
|
||||
// AgentPortPolicyDTO 前端交互用的端口策略格式(含已解析的数组)
|
||||
type AgentPortPolicyDTO struct {
|
||||
Hostname string `json:"hostname"`
|
||||
PortFilterMode string `json:"port_filter_mode"`
|
||||
PortWhitelist []int `json:"port_whitelist"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
// AgentTask Agent 远程任务 // Logan.Li
|
||||
type AgentTask struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
TaskID string `gorm:"size:36;uniqueIndex;not null" json:"task_id"` // UUID
|
||||
Hostname string `gorm:"size:255;index;not null" json:"hostname"` // 目标主机
|
||||
Type string `gorm:"size:32;not null" json:"type"` // command / script / file
|
||||
Command string `gorm:"type:text" json:"command"` // 命令或脚本内容
|
||||
Timeout int `gorm:"default:60" json:"timeout"` // 超时秒数
|
||||
Status string `gorm:"size:20;default:pending;index" json:"status"` // pending/running/success/failed/timeout
|
||||
Result string `gorm:"type:text" json:"result"` // 执行输出
|
||||
ExitCode int `gorm:"default:-1" json:"exit_code"` // 退出码
|
||||
CreatedBy string `gorm:"size:255" json:"created_by"` // 创建人
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
PickedAt *time.Time `json:"picked_at"` // Agent 拉取时间
|
||||
FinishedAt *time.Time `json:"finished_at"` // 完成时间
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (AgentTask) TableName() string {
|
||||
return "monitor_agent_tasks"
|
||||
}
|
||||
|
||||
// AgentRule 告警规则(基于 Agent 数据) // Logan.Li
|
||||
type AgentRule struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:255;not null" json:"name"`
|
||||
Hostname string `gorm:"size:255" json:"hostname"` // 空表示全部主机
|
||||
Metric string `gorm:"size:32;not null" json:"metric"` // cpu/mem/disk/offline/port_down/tcp_time_wait/tcp_close_wait/service_process/fd
|
||||
Operator string `gorm:"size:10;default:>" json:"operator"` // > >= < <= ==
|
||||
Threshold float64 `gorm:"type:decimal(10,2)" json:"threshold"`
|
||||
Port int `json:"port"` // port_down 专用
|
||||
Enabled bool `gorm:"default:true" json:"enabled"`
|
||||
LastTriggered *time.Time `json:"last_triggered"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (AgentRule) TableName() string {
|
||||
return "monitor_agent_rules"
|
||||
}
|
||||
|
||||
// AgentAlert Agent 告警事件 // Logan.Li
|
||||
type AgentAlert struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
RuleName string `gorm:"size:255" json:"rule_name"`
|
||||
Hostname string `gorm:"size:255;index" json:"hostname"`
|
||||
Metric string `gorm:"size:32" json:"metric"`
|
||||
Severity string `gorm:"size:20;default:warning" json:"severity"` // critical/warning/info
|
||||
Message string `gorm:"type:text" json:"message"`
|
||||
Value float64 `gorm:"type:decimal(10,2)" json:"value"`
|
||||
Threshold float64 `gorm:"type:decimal(10,2)" json:"threshold"`
|
||||
Resolved bool `gorm:"default:false;index" json:"resolved"`
|
||||
ResolvedAt *time.Time `json:"resolved_at"`
|
||||
CreatedAt time.Time `gorm:"index" json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (AgentAlert) TableName() string {
|
||||
return "monitor_agent_alerts"
|
||||
}
|
||||
@@ -0,0 +1,503 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ============================================
|
||||
// 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;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"`
|
||||
}
|
||||
|
||||
func (AlertRule) TableName() string {
|
||||
return "monitor_alert_rules"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// AlertEvent 告警事件(增强版 — 合并原V2特性)
|
||||
// ============================================
|
||||
|
||||
// AlertEventStatus 告警事件状态
|
||||
type AlertEventStatus string
|
||||
|
||||
const (
|
||||
AlertEventFiring AlertEventStatus = "firing"
|
||||
AlertEventResolved AlertEventStatus = "resolved"
|
||||
AlertEventSilenced AlertEventStatus = "silenced"
|
||||
)
|
||||
|
||||
// AlertEvent 告警事件(增强版)
|
||||
type AlertEvent struct {
|
||||
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" gorm:"foreignKey:RuleID"`
|
||||
}
|
||||
|
||||
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"`
|
||||
Name string `gorm:"size:64;not null" json:"name"`
|
||||
Type string `gorm:"size:32;not null" json:"type"` // email, sms, webhook, dingtalk, wechat
|
||||
Config string `gorm:"type:text" json:"config"` // JSON
|
||||
Enabled bool `gorm:"default:true" json:"enabled"`
|
||||
TestStatus string `gorm:"size:32" json:"test_status"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (NotifyChannel) TableName() string {
|
||||
return "monitor_notify_channels"
|
||||
}
|
||||
|
||||
// MetricData 监控指标数据
|
||||
type MetricData struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
ServerID *uint `json:"server_id"`
|
||||
ClusterID *uint `json:"cluster_id"`
|
||||
Name string `gorm:"size:64" json:"name"`
|
||||
Value float64 `json:"value"`
|
||||
Labels string `gorm:"type:text" json:"labels"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (MetricData) TableName() string {
|
||||
return "monitor_metric_data"
|
||||
}
|
||||
|
||||
// CreateAlertRuleRequest 创建告警规则请求
|
||||
type CreateAlertRuleRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
Type string `json:"type" binding:"required,oneof=metric log event"`
|
||||
Source string `json:"source" binding:"required"`
|
||||
Expression string `json:"expression" binding:"required"`
|
||||
Severity string `json:"severity" binding:"omitempty,oneof=info warning critical"`
|
||||
Duration int `json:"duration"`
|
||||
Labels string `json:"labels"`
|
||||
Annotations string `json:"annotations"`
|
||||
NotifyChannels []string `json:"notify_channels"`
|
||||
}
|
||||
|
||||
// UpdateAlertRuleRequest 更新告警规则请求
|
||||
type UpdateAlertRuleRequest struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Expression string `json:"expression"`
|
||||
Severity string `json:"severity" binding:"omitempty,oneof=info warning critical"`
|
||||
Duration int `json:"duration"`
|
||||
Enabled *bool `json:"enabled"`
|
||||
Labels string `json:"labels"`
|
||||
Annotations string `json:"annotations"`
|
||||
NotifyChannels []string `json:"notify_channels"`
|
||||
}
|
||||
|
||||
// AlertStats 告警统计
|
||||
type AlertStats struct {
|
||||
Total int64 `json:"total"`
|
||||
Firing int64 `json:"firing"`
|
||||
Resolved int64 `json:"resolved"`
|
||||
Critical int64 `json:"critical"`
|
||||
Warning int64 `json:"warning"`
|
||||
Info int64 `json:"info"`
|
||||
TodayCount int64 `json:"today_count"`
|
||||
WeekCount int64 `json:"week_count"`
|
||||
}
|
||||
|
||||
// AcknowledgeAlertRequest 确认告警请求
|
||||
type AcknowledgeAlertRequest struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// AlertContact 报警联系人
|
||||
// ============================================
|
||||
|
||||
type AlertContact struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
Name string `gorm:"type:varchar(128);not null;comment:联系人姓名" json:"name"`
|
||||
Phone string `gorm:"type:varchar(32);comment:手机号" json:"phone,omitempty"`
|
||||
Email string `gorm:"type:varchar(128);comment:邮箱" json:"email,omitempty"`
|
||||
ChannelType string `gorm:"type:varchar(32);default:'feishu';comment:渠道类型: feishu/dingtalk/wechat/webhook" json:"channel_type,omitempty"`
|
||||
WebhookURL string `gorm:"type:varchar(512);comment:Webhook地址" json:"webhook_url,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"`
|
||||
}
|
||||
|
||||
func (AlertContact) TableName() string {
|
||||
return "monitor_alert_contacts"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// AlertContactGroup 报警联系组
|
||||
// ============================================
|
||||
|
||||
type AlertContactGroup struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
GroupName string `gorm:"type:varchar(128);not null;comment:组名称" json:"group_name"`
|
||||
Notes string `gorm:"type:varchar(500);comment:备注" json:"notes,omitempty"`
|
||||
ContactIDs string `gorm:"type:text;comment:联系人ID列表JSON" json:"contact_ids,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"`
|
||||
}
|
||||
|
||||
func (AlertContactGroup) TableName() string {
|
||||
return "monitor_alert_contact_groups"
|
||||
}
|
||||
|
||||
// CreateContactRequest 创建联系人请求
|
||||
type CreateContactRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
ChannelType string `json:"channel_type" binding:"required,oneof=feishu dingtalk wechat webhook"`
|
||||
WebhookURL string `json:"webhook_url" binding:"required"`
|
||||
}
|
||||
|
||||
// UpdateContactRequest 更新联系人请求
|
||||
type UpdateContactRequest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
ChannelType string `json:"channel_type,omitempty" binding:"omitempty,oneof=feishu dingtalk wechat webhook"`
|
||||
WebhookURL string `json:"webhook_url,omitempty"`
|
||||
}
|
||||
|
||||
// CreateContactGroupRequest 创建联系组请求
|
||||
type CreateContactGroupRequest struct {
|
||||
GroupName string `json:"group_name" binding:"required"`
|
||||
Notes string `json:"notes,omitempty"`
|
||||
ContactIDs []uint `json:"contact_ids"`
|
||||
}
|
||||
|
||||
// UpdateContactGroupRequest 更新联系组请求
|
||||
type UpdateContactGroupRequest struct {
|
||||
GroupName string `json:"group_name,omitempty"`
|
||||
Notes string `json:"notes,omitempty"`
|
||||
ContactIDs []uint `json:"contact_ids,omitempty"`
|
||||
}
|
||||
|
||||
// CreateNotifyChannelRequest 创建通知渠道请求
|
||||
type CreateNotifyChannelRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Type string `json:"type" binding:"required,oneof=email sms webhook dingtalk wechat feishu"`
|
||||
Config string `json:"config"`
|
||||
}
|
||||
|
||||
// UpdateNotifyChannelRequest 更新通知渠道请求
|
||||
type UpdateNotifyChannelRequest struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type" binding:"omitempty,oneof=email sms webhook dingtalk wechat feishu"`
|
||||
Config string `json:"config"`
|
||||
Enabled *bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// FeishuWebhookConfig 飞书 Webhook 配置
|
||||
type FeishuWebhookConfig struct {
|
||||
URL string `json:"url"` // 飞书机器人 webhook 地址
|
||||
Secret string `json:"secret"` // 可选:签名密钥
|
||||
}
|
||||
|
||||
// FeishuCardMessage 飞书卡片消息
|
||||
type FeishuCardMessage struct {
|
||||
MsgType string `json:"msg_type"`
|
||||
Content FeishuCardContent `json:"content"`
|
||||
}
|
||||
|
||||
type FeishuCardContent struct {
|
||||
Title string `json:"title"`
|
||||
Content [][]FeishuCardElement `json:"content"`
|
||||
}
|
||||
// FeishuCardElement 飞书卡片元素
|
||||
type FeishuCardElement struct {
|
||||
Tag string `json:"tag"`
|
||||
Text string `json:"text,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
// ApprovalTemplate 审批模板模型
|
||||
type ApprovalTemplate 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"`
|
||||
Description string `gorm:"size:500" json:"description"`
|
||||
Type string `gorm:"size:32;not null" json:"type"` // release, server_apply, app_deploy, permission_request
|
||||
FormSchema string `gorm:"type:text" json:"form_schema"` // JSON form fields config
|
||||
FlowConfig string `gorm:"type:text" json:"flow_config"` // JSON approval flow steps
|
||||
Category string `gorm:"size:32;default:resource" json:"category"` // resource, app, permission
|
||||
Enabled bool `gorm:"default:true" json:"enabled"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (ApprovalTemplate) TableName() string {
|
||||
return "sys_approval_templates"
|
||||
}
|
||||
|
||||
// ApprovalProcess 审批流程模型
|
||||
type ApprovalProcess struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
TemplateID uint `json:"template_id"`
|
||||
Title string `gorm:"size:255;not null" json:"title"`
|
||||
Applicant uint `json:"applicant"`
|
||||
Status string `gorm:"size:32;default:pending" json:"status"` // pending, approved, rejected
|
||||
FormData string `gorm:"type:text" json:"form_data"` // JSON
|
||||
CurrentStep int `gorm:"default:0" json:"current_step"`
|
||||
TotalSteps int `json:"total_steps"`
|
||||
ApprovedAt *time.Time `json:"approved_at"`
|
||||
RejectedAt *time.Time `json:"rejected_at"`
|
||||
RejectReason string `gorm:"size:500" json:"reject_reason"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Template *ApprovalTemplate `gorm:"foreignKey:TemplateID" json:"template,omitempty"`
|
||||
ApplicantUser *User `gorm:"foreignKey:Applicant" json:"applicant_user,omitempty"`
|
||||
Steps []ApprovalStep `gorm:"foreignKey:ProcessID" json:"steps,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (ApprovalProcess) TableName() string {
|
||||
return "approval_processes"
|
||||
}
|
||||
|
||||
// ApprovalStep 审批步骤模型
|
||||
type ApprovalStep struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
ProcessID uint `json:"process_id"`
|
||||
Step int `json:"step"`
|
||||
Approver uint `json:"approver"`
|
||||
Status string `gorm:"size:32;default:pending" json:"status"` // pending, approved, rejected
|
||||
Comment string `gorm:"size:500" json:"comment"`
|
||||
ApprovedAt *time.Time `json:"approved_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
ApproverUser *User `gorm:"foreignKey:Approver" json:"approver_user,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (ApprovalStep) TableName() string {
|
||||
return "approval_steps"
|
||||
}
|
||||
|
||||
// CreateApprovalTemplateRequest 创建审批模板请求
|
||||
type CreateApprovalTemplateRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Code string `json:"code" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
Type string `json:"type" binding:"required,oneof=server_apply app_deploy permission_request"`
|
||||
Category string `json:"category"` // resource, app, permission
|
||||
FormSchema string `json:"form_schema"`
|
||||
FlowConfig string `json:"flow_config"`
|
||||
}
|
||||
|
||||
// CreateApprovalProcessRequest 创建审批流程请求
|
||||
type CreateApprovalProcessRequest struct {
|
||||
TemplateID uint `json:"template_id" binding:"required"`
|
||||
Title string `json:"title" binding:"required"`
|
||||
FormData string `json:"form_data"`
|
||||
}
|
||||
|
||||
// ApproveRequest 审批请求
|
||||
type ApproveRequest struct {
|
||||
Status string `json:"status"`
|
||||
Comment string `json:"comment"`
|
||||
}
|
||||
|
||||
// ApprovalStats 审批统计
|
||||
type ApprovalStats struct {
|
||||
Pending int64 `json:"pending"`
|
||||
Approved int64 `json:"approved"`
|
||||
Rejected int64 `json:"rejected"`
|
||||
Total int64 `json:"total"`
|
||||
MyPending int64 `json:"my_pending"`
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// AuditLog 审计日志模型
|
||||
type AuditLog struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
UserID *uint `json:"user_id"`
|
||||
Username string `gorm:"size:64" json:"username"`
|
||||
IP string `gorm:"size:64" json:"ip"`
|
||||
UserAgent string `gorm:"size:500" json:"user_agent"`
|
||||
Module string `gorm:"size:64" json:"module"`
|
||||
Action string `gorm:"size:64" json:"action"`
|
||||
Resource string `gorm:"size:128" json:"resource"`
|
||||
ResourceID string `gorm:"size:64" json:"resource_id"`
|
||||
Request string `gorm:"type:text" json:"request"`
|
||||
Response string `gorm:"type:text" json:"response"`
|
||||
Status int `json:"status"`
|
||||
Duration int `json:"duration"` // ms
|
||||
Error string `gorm:"type:text" json:"error"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (AuditLog) TableName() string {
|
||||
return "sys_audit_logs"
|
||||
}
|
||||
|
||||
// AuditLogQuery 审计日志查询
|
||||
type AuditLogQuery struct {
|
||||
UserID *uint `form:"user_id"`
|
||||
Username string `form:"username"`
|
||||
Module string `form:"module"`
|
||||
Action string `form:"action"`
|
||||
StartTime string `form:"start_time"`
|
||||
EndTime string `form:"end_time"`
|
||||
Page int `form:"page,default=1"`
|
||||
PageSize int `form:"page_size,default=20"`
|
||||
}
|
||||
|
||||
// AuditLogListResponse 审计日志列表响应
|
||||
type AuditLogListResponse struct {
|
||||
List []AuditLog `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
// AuditStats 审计统计
|
||||
type AuditStats struct {
|
||||
TodayCount int64 `json:"today_count"`
|
||||
WeekCount int64 `json:"week_count"`
|
||||
MonthCount int64 `json:"month_count"`
|
||||
TopModules []ModuleStat `json:"top_modules"`
|
||||
TopUsers []UserStat `json:"top_users"`
|
||||
}
|
||||
|
||||
// ModuleStat 模块统计
|
||||
type ModuleStat struct {
|
||||
Module string `json:"module"`
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
|
||||
// UserStat 用户统计
|
||||
type UserStat struct {
|
||||
Username string `json:"username"`
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
// CronJob 定时任务模型
|
||||
type CronJob struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:128;not null" json:"name"`
|
||||
Description string `gorm:"size:500" json:"description"`
|
||||
CronExpr string `gorm:"size:64;not null" json:"cron_expr"`
|
||||
Type string `gorm:"size:32;not null" json:"type"` // shell, python, command
|
||||
Content string `gorm:"type:text" json:"content"`
|
||||
ScriptID *uint `json:"script_id"`
|
||||
TargetType string `gorm:"size:32;default:server" json:"target_type"` // server, group, tag
|
||||
Targets string `gorm:"type:text" json:"targets"` // JSON
|
||||
Timeout int `gorm:"default:300" json:"timeout"`
|
||||
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"`
|
||||
NotifyOn string `gorm:"size:32;default:failure" json:"notify_on"` // always, failure, success
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Script *Script `json:"script,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (CronJob) TableName() string {
|
||||
return "ops_cron_jobs"
|
||||
}
|
||||
|
||||
// Script 脚本库模型
|
||||
type Script 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"`
|
||||
Description string `gorm:"size:500" json:"description"`
|
||||
Type string `gorm:"size:32;default:shell" json:"type"` // shell, python
|
||||
Content string `gorm:"type:text;not null" json:"content"`
|
||||
Params string `gorm:"type:text" json:"params"` // JSON
|
||||
Timeout int `gorm:"default:300" json:"timeout"`
|
||||
Version int `gorm:"default:1" json:"version"`
|
||||
RunCount int `gorm:"default:0" json:"run_count"`
|
||||
CreatedBy uint `json:"created_by"`
|
||||
UpdatedBy uint `json:"updated_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (Script) TableName() string {
|
||||
return "ops_scripts"
|
||||
}
|
||||
|
||||
// TaskExecution 任务执行记录(cron / script,不含 Ansible;Ansible 走 AnsibleJob)
|
||||
type TaskExecution struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
TaskType string `gorm:"size:32;not null" json:"task_type"` // cron, script
|
||||
TaskID uint `json:"task_id"`
|
||||
TaskName string `gorm:"size:128" json:"task_name"`
|
||||
Status string `gorm:"size:32;default:pending" json:"status"` // pending, running, success, failed, cancelled
|
||||
TargetType string `gorm:"size:32" json:"target_type"`
|
||||
Targets string `gorm:"type:text" json:"targets"`
|
||||
Output string `gorm:"type:longtext" json:"output"`
|
||||
Error string `gorm:"type:text" json:"error"`
|
||||
Duration int `json:"duration"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
FinishedAt *time.Time `json:"finished_at"`
|
||||
CreatedBy uint `json:"created_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (TaskExecution) TableName() string {
|
||||
return "ops_task_executions"
|
||||
}
|
||||
|
||||
// CreateCronJobRequest 创建定时任务请求
|
||||
type CreateCronJobRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
CronExpr string `json:"cron_expr" binding:"required"`
|
||||
Type string `json:"type" binding:"required,oneof=shell python command"`
|
||||
Content string `json:"content"`
|
||||
ScriptID *uint `json:"script_id"`
|
||||
TargetType string `json:"target_type" binding:"omitempty,oneof=server group tag"`
|
||||
Targets []uint `json:"targets"`
|
||||
Timeout int `json:"timeout"`
|
||||
NotifyOn string `json:"notify_on" binding:"omitempty,oneof=always failure success"`
|
||||
}
|
||||
|
||||
// CreateScriptRequest 创建脚本请求
|
||||
type CreateScriptRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Code string `json:"code" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
Type string `json:"type" binding:"omitempty,oneof=shell python"`
|
||||
Content string `json:"content" binding:"required"`
|
||||
Params string `json:"params"`
|
||||
Timeout int `json:"timeout"`
|
||||
}
|
||||
|
||||
// ExecuteScriptRequest 执行脚本请求
|
||||
type ExecuteScriptRequest struct {
|
||||
TargetType string `json:"target_type" binding:"required,oneof=server group tag"`
|
||||
Targets []uint `json:"targets" binding:"required"`
|
||||
Params map[string]string `json:"params"`
|
||||
}
|
||||
|
||||
// AutomationStats 自动化统计
|
||||
type AutomationStats struct {
|
||||
CronJobCount int64 `json:"cron_job_count"`
|
||||
ScriptCount int64 `json:"script_count"`
|
||||
PlaybookCount int64 `json:"playbook_count"`
|
||||
TodayExecutions int64 `json:"today_executions"`
|
||||
SuccessRate float64 `json:"success_rate"`
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
// CloudBilling 云账单模型 - 每日成本记录
|
||||
type CloudBilling struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
CloudAccountID *uint `gorm:"index" json:"cloud_account_id"`
|
||||
AccountName string `gorm:"size:128" json:"account_name"`
|
||||
Provider string `gorm:"size:64;index" json:"provider"` // aliyun, tencent, aws, huawei, azure
|
||||
BillingDate string `gorm:"size:10;index;not null" json:"billing_date"` // YYYY-MM-DD
|
||||
Cost float64 `gorm:"type:decimal(12,2);default:0" json:"cost"` // 费用(元)
|
||||
Currency string `gorm:"size:8;default:CNY" json:"currency"` // CNY, USD
|
||||
Service string `gorm:"size:128" json:"service"` // ECS, RDS, OSS, CDN 等
|
||||
Region string `gorm:"size:64" json:"region"`
|
||||
Tags string `gorm:"type:text" json:"tags"` // JSON
|
||||
Description string `gorm:"size:500" json:"description"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (CloudBilling) TableName() string {
|
||||
return "asset_cloud_billings"
|
||||
}
|
||||
|
||||
// BillingAlertRule 账单预警规则
|
||||
type BillingAlertRule struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:128;not null" json:"name"`
|
||||
Provider string `gorm:"size:64" json:"provider"` // 空=所有云厂商
|
||||
CloudAccountID *uint `gorm:"index" json:"cloud_account_id"` // 空=所有账号
|
||||
Metric string `gorm:"size:32;default:daily" json:"metric"` // daily, monthly
|
||||
Threshold float64 `gorm:"type:decimal(12,2)" json:"threshold"` // 阈值(元)
|
||||
Operator string `gorm:"size:8;default:>" json:"operator"` // >, >=, <, <=
|
||||
Enabled bool `gorm:"default:true" json:"enabled"`
|
||||
LastTriggered *time.Time `json:"last_triggered"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (BillingAlertRule) TableName() string {
|
||||
return "monitor_billing_alert_rules"
|
||||
}
|
||||
|
||||
// BillingStats 账单统计
|
||||
type BillingStats struct {
|
||||
TodayCost float64 `json:"today_cost"`
|
||||
MonthCost float64 `json:"month_cost"`
|
||||
YearCost float64 `json:"year_cost"`
|
||||
YesterdayCost float64 `json:"yesterday_cost"`
|
||||
MonthTrend []DailyCost `json:"month_trend"`
|
||||
ProviderDist []ProviderCost `json:"provider_dist"`
|
||||
Alerts []BillingAlert `json:"alerts"`
|
||||
}
|
||||
|
||||
// DailyCost 每日成本
|
||||
type DailyCost struct {
|
||||
Date string `json:"date"`
|
||||
Cost float64 `json:"cost"`
|
||||
}
|
||||
|
||||
// ProviderCost 厂商成本分布
|
||||
type ProviderCost struct {
|
||||
Provider string `json:"provider"`
|
||||
Cost float64 `json:"cost"`
|
||||
Percent float64 `json:"percent"`
|
||||
}
|
||||
|
||||
// BillingAlert 账单预警
|
||||
type BillingAlert struct {
|
||||
RuleID uint `json:"rule_id"`
|
||||
RuleName string `json:"rule_name"`
|
||||
Provider string `json:"provider"`
|
||||
Current float64 `json:"current"`
|
||||
Threshold float64 `json:"threshold"`
|
||||
Metric string `json:"metric"`
|
||||
Operator string `json:"operator"`
|
||||
}
|
||||
|
||||
// CreateBillingRequest 创建账单记录请求
|
||||
type CreateBillingRequest struct {
|
||||
CloudAccountID *uint `json:"cloud_account_id"`
|
||||
AccountName string `json:"account_name"`
|
||||
Provider string `json:"provider" binding:"required"`
|
||||
BillingDate string `json:"billing_date" binding:"required"`
|
||||
Cost float64 `json:"cost" binding:"required"`
|
||||
Currency string `json:"currency"`
|
||||
Service string `json:"service"`
|
||||
Region string `json:"region"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// CreateBillingAlertRequest 创建预警规则请求
|
||||
type CreateBillingAlertRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Provider string `json:"provider"`
|
||||
CloudAccountID *uint `json:"cloud_account_id"`
|
||||
Metric string `json:"metric"`
|
||||
Threshold float64 `json:"threshold" binding:"required"`
|
||||
Operator string `json:"operator"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
// Pipeline CI/CD流水线模型
|
||||
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仓库地址
|
||||
Branch string `gorm:"size:64;default:main" json:"branch"`
|
||||
Dockerfile string `gorm:"size:255" json:"dockerfile"`
|
||||
Stages string `gorm:"type:text" json:"stages"` // JSON
|
||||
Variables string `gorm:"type:text" json:"variables"` // JSON
|
||||
Enabled bool `gorm:"default:true" json:"enabled"`
|
||||
|
||||
// 部署模式
|
||||
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"`
|
||||
|
||||
// 并发控制
|
||||
MaxExecutors int `gorm:"default:2;comment:最大并发执行数(1=串行,默认2)" json:"max_executors"`
|
||||
|
||||
// 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 表名
|
||||
func (Pipeline) TableName() string {
|
||||
return "ops_pipelines"
|
||||
}
|
||||
|
||||
// PipelineRun 流水线运行记录(CI 执行)
|
||||
type PipelineRun struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
PipelineID uint `gorm:"not null" json:"pipeline_id"`
|
||||
BuildNumber int `json:"build_number"`
|
||||
Status string `gorm:"size:32;default:pending" json:"status"` // pending, running, success, failed, cancelled
|
||||
Branch string `gorm:"size:64" json:"branch"`
|
||||
CommitID string `gorm:"size:64" json:"commit_id"`
|
||||
CommitMsg string `gorm:"size:500" json:"commit_msg"`
|
||||
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"`
|
||||
TriggeredBy string `gorm:"size:64" json:"triggered_by"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
FinishedAt *time.Time `json:"finished_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Pipeline *Pipeline `json:"pipeline,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (PipelineRun) TableName() string {
|
||||
return "ops_pipeline_runs"
|
||||
}
|
||||
|
||||
// AppRelease 应用发布模型(CD:从 CI 产物部署到目标环境)
|
||||
type AppRelease struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
PipelineID *uint `json:"pipeline_id"` // 来源流水线
|
||||
PipelineRunID *uint `json:"pipeline_run_id"` // 来源 CI 执行记录
|
||||
AppName string `gorm:"size:128;not null" json:"app_name"`
|
||||
Version string `gorm:"size:64;not null" json:"version"`
|
||||
Environment string `gorm:"size:32;not null" json:"environment"` // dev, test, staging, prod
|
||||
DeployType string `gorm:"size:32;default:server" json:"deploy_type"` // server, kubernetes
|
||||
Status string `gorm:"size:32;default:pending" json:"status"` // pending, approved, rejected, deploying, success, failed, rolled_back
|
||||
CommitID string `gorm:"size:64" json:"commit_id"`
|
||||
CommitMsg string `gorm:"size:500" json:"commit_msg"`
|
||||
Author string `gorm:"size:64" json:"author"`
|
||||
Approver string `gorm:"size:64" json:"approver"`
|
||||
ApprovedAt *time.Time `json:"approved_at"`
|
||||
DeployedAt *time.Time `json:"deployed_at"`
|
||||
RollbackAt *time.Time `json:"rollback_at"`
|
||||
Duration int `json:"duration"`
|
||||
ImageTag string `gorm:"size:255" json:"image_tag"` // 构建产物镜像标签
|
||||
K8sClusterID *uint `json:"k8s_cluster_id"` // Kubernetes 部署目标集群
|
||||
K8sNamespace string `gorm:"size:128" json:"k8s_namespace"` // Kubernetes 部署目标命名空间
|
||||
Servers string `gorm:"type:text" json:"servers"` // JSON(传统服务器部署目标)
|
||||
Description string `gorm:"size:500" json:"description"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (AppRelease) TableName() string {
|
||||
return "deploy_app_releases"
|
||||
}
|
||||
|
||||
// CreatePipelineRequest 创建流水线请求
|
||||
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"`
|
||||
Branch string `json:"branch"`
|
||||
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"`
|
||||
|
||||
// 并发控制
|
||||
MaxExecutors int `json:"max_executors"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
|
||||
// 并发控制
|
||||
MaxExecutors int `json:"max_executors"`
|
||||
}
|
||||
|
||||
// TriggerPipelineRequest 触发流水线请求
|
||||
type TriggerPipelineRequest struct {
|
||||
Branch string `json:"branch"`
|
||||
Tag string `json:"tag"` // 发布 Tag
|
||||
Variables map[string]string `json:"variables"`
|
||||
}
|
||||
|
||||
// CreateAppReleaseRequest 创建应用发布请求
|
||||
type CreateAppReleaseRequest struct {
|
||||
PipelineID *uint `json:"pipeline_id"`
|
||||
PipelineRunID *uint `json:"pipeline_run_id"`
|
||||
AppName string `json:"app_name" binding:"required"`
|
||||
Version string `json:"version" binding:"required"`
|
||||
Environment string `json:"environment" binding:"required,oneof=dev test staging prod"`
|
||||
DeployType string `json:"deploy_type" binding:"omitempty,oneof=server kubernetes"`
|
||||
CommitID string `json:"commit_id"`
|
||||
CommitMsg string `json:"commit_msg"`
|
||||
ImageTag string `json:"image_tag"`
|
||||
K8sClusterID *uint `json:"k8s_cluster_id"`
|
||||
K8sNamespace string `json:"k8s_namespace"`
|
||||
Servers []uint `json:"servers"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// PipelineStats 流水线统计
|
||||
type PipelineStats struct {
|
||||
Total int64 `json:"total"`
|
||||
Success int64 `json:"success"`
|
||||
Failed int64 `json:"failed"`
|
||||
Running int64 `json:"running"`
|
||||
TodayCount int64 `json:"today_count"`
|
||||
SuccessRate float64 `json:"success_rate"`
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package model
|
||||
|
||||
// Response 通用响应
|
||||
type Response struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// ListResponse 列表响应
|
||||
type ListResponse struct {
|
||||
List interface{} `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
// PageQuery 分页查询
|
||||
type PageQuery struct {
|
||||
Page int `form:"page,default=1"`
|
||||
PageSize int `form:"page_size,default=20"`
|
||||
Keyword string `form:"keyword"`
|
||||
Sort string `form:"sort"`
|
||||
Order string `form:"order,default=desc"`
|
||||
}
|
||||
|
||||
// GetOffset 获取偏移量
|
||||
func (p *PageQuery) GetOffset() int {
|
||||
if p.Page < 1 {
|
||||
p.Page = 1
|
||||
}
|
||||
return (p.Page - 1) * p.GetLimit()
|
||||
}
|
||||
|
||||
// GetLimit 获取每页数量
|
||||
func (p *PageQuery) GetLimit() int {
|
||||
if p.PageSize < 1 {
|
||||
p.PageSize = 20
|
||||
}
|
||||
if p.PageSize > 100 {
|
||||
p.PageSize = 100
|
||||
}
|
||||
return p.PageSize
|
||||
}
|
||||
|
||||
// IDRequest ID请求
|
||||
type IDRequest struct {
|
||||
ID uint `uri:"id" binding:"required"`
|
||||
}
|
||||
|
||||
// IDsRequest IDs请求
|
||||
type IDsRequest struct {
|
||||
IDs []uint `json:"ids" binding:"required"`
|
||||
}
|
||||
|
||||
// StatusRequest 状态请求
|
||||
type StatusRequest struct {
|
||||
Status int `json:"status" binding:"required,oneof=0 1"`
|
||||
}
|
||||
|
||||
// DashboardStats 仪表盘统计
|
||||
type DashboardStats struct {
|
||||
ServerStats ServerStats `json:"server_stats"`
|
||||
K8sStats KubernetesClusterStats `json:"kubernetes_stats"`
|
||||
AlertStats AlertStats `json:"alert_stats"`
|
||||
PipelineStats PipelineStats `json:"pipeline_stats"`
|
||||
CostStats CostStats `json:"cost_stats"`
|
||||
TopResourceUsage TopResourceUsage `json:"top_resource_usage"`
|
||||
ExpiringCerts []DomainCert `json:"expiring_certs"`
|
||||
}
|
||||
|
||||
// CostStats 成本统计
|
||||
type CostStats struct {
|
||||
TotalCost float64 `json:"total_cost"`
|
||||
MonthCost float64 `json:"month_cost"`
|
||||
CloudCosts []CloudCost `json:"cloud_costs"`
|
||||
MonthTrend []MonthTrend `json:"month_trend"`
|
||||
}
|
||||
|
||||
// CloudCost 云平台成本
|
||||
type CloudCost struct {
|
||||
Cloud string `json:"cloud"`
|
||||
Cost float64 `json:"cost"`
|
||||
}
|
||||
|
||||
// MonthTrend 月度趋势
|
||||
type MonthTrend struct {
|
||||
Month string `json:"month"`
|
||||
Cost float64 `json:"cost"`
|
||||
}
|
||||
|
||||
// TopResourceUsage Top资源使用
|
||||
type TopResourceUsage struct {
|
||||
CPU []ServerResource `json:"cpu"`
|
||||
Memory []ServerResource `json:"memory"`
|
||||
Disk []ServerResource `json:"disk"`
|
||||
}
|
||||
|
||||
// ServerResource 服务器资源
|
||||
type ServerResource struct {
|
||||
ID uint `json:"id"`
|
||||
Hostname string `json:"hostname"`
|
||||
IP string `json:"ip"`
|
||||
Usage float64 `json:"usage"`
|
||||
}
|
||||
|
||||
// DomainCert 域名证书
|
||||
type DomainCert struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ExpireDate string `json:"expire_date"`
|
||||
DaysUntilExpiry int `json:"days_until_expiry"`
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// 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"` // 凭据名称
|
||||
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"
|
||||
}
|
||||
|
||||
// ────── 类型定义 ──────
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
||||
// DockerSecretContent Docker 凭据 content
|
||||
type DockerSecretContent struct {
|
||||
Server string `json:"server"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
package model
|
||||
|
||||
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"
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// ============================================
|
||||
// DeployTool 工具配置(懒加载/预装/禁用)
|
||||
// 按 deploy_ 前缀,与 PipelineRepo/Registry 同属发布配置域
|
||||
// ============================================
|
||||
|
||||
// ToolInstallMethod 安装方式
|
||||
type ToolInstallMethod string
|
||||
|
||||
const (
|
||||
ToolPreinstall ToolInstallMethod = "preinstall" // 预装在 Dockerfile 中
|
||||
ToolLazy ToolInstallMethod = "lazy" // 懒加载:首次使用时自动下载
|
||||
ToolDisabled ToolInstallMethod = "disabled" // 禁用:不安装
|
||||
)
|
||||
|
||||
// ToolStatus 安装状态
|
||||
type ToolStatus string
|
||||
|
||||
const (
|
||||
ToolNotInstalled ToolStatus = "not_installed" // 未安装
|
||||
ToolInstalling ToolStatus = "installing" // 安装中
|
||||
ToolInstalled ToolStatus = "installed" // 已安装
|
||||
ToolFailed ToolStatus = "failed" // 安装失败
|
||||
)
|
||||
|
||||
// DeployTool 工具配置表
|
||||
type DeployTool struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
Name string `gorm:"type:varchar(64);uniqueIndex;not null;comment:工具名称(英文标识)" json:"name"`
|
||||
DisplayName string `gorm:"type:varchar(128);not null;comment:显示名称" json:"display_name"`
|
||||
Description string `gorm:"type:varchar(256);comment:工具描述" json:"description,omitempty"`
|
||||
Category string `gorm:"type:varchar(32);default:other;comment:分类: k8s/build/deploy/automation" json:"category"`
|
||||
InstallMethod ToolInstallMethod `gorm:"type:varchar(16);default:lazy;comment:安装方式: preinstall/lazy/disabled" json:"install_method"`
|
||||
CheckCommand string `gorm:"type:varchar(256);comment:检测命令(如 kubectl version --client)" json:"check_command,omitempty"`
|
||||
BinaryName string `gorm:"type:varchar(64);comment:二进制文件名(如 kubectl/mvn/node)" json:"binary_name,omitempty"`
|
||||
InstallPath string `gorm:"type:varchar(256);comment:安装目标路径(如 /usr/local/bin)" json:"install_path,omitempty"`
|
||||
DownloadURL string `gorm:"type:varchar(512);comment:下载地址模板(支持 {version})" json:"download_url,omitempty"`
|
||||
VersionURL string `gorm:"type:varchar(512);comment:版本查询地址(如 stable.txt)" json:"version_url,omitempty"`
|
||||
InstallScript string `gorm:"type:text;comment:自定义安装脚本(Shell)" json:"install_script,omitempty"`
|
||||
DefaultVersion string `gorm:"type:varchar(32);comment:默认版本号" json:"default_version,omitempty"`
|
||||
Status ToolStatus `gorm:"type:varchar(16);default:not_installed;comment:当前安装状态" json:"status"`
|
||||
InstalledVer string `gorm:"type:varchar(128);comment:已安装版本号" json:"installed_version,omitempty"`
|
||||
LastCheck *time.Time `gorm:"comment:最后检测时间" json:"last_check,omitempty"`
|
||||
ErrorMsg string `gorm:"type:varchar(512);comment:安装失败原因" json:"error_msg,omitempty"`
|
||||
Enabled bool `gorm:"default:true;comment:是否启用" json:"enabled"`
|
||||
SortOrder int `gorm:"default:0;comment:排序" json:"sort_order"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (DeployTool) TableName() string {
|
||||
return "deploy_tools"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 预置工具定义(Seeder)— 精简版 v2
|
||||
// 移除: kubectl(Dockerfile 预装)、helm(非核心)
|
||||
// 新增: nvm(管理 Node 版本)、jdk(Java 构建)
|
||||
// ============================================
|
||||
|
||||
// PredefinedTools 返回系统预置的工具配置列表
|
||||
func PredefinedTools() []DeployTool {
|
||||
return []DeployTool{
|
||||
// ──── JDK — Java 构建 // Logan.Li ────
|
||||
{
|
||||
Name: "jdk",
|
||||
DisplayName: "JDK (Java)",
|
||||
Description: "Java 开发工具包,流水线 Java/Maven 构建阶段使用",
|
||||
Category: "build",
|
||||
InstallMethod: ToolLazy,
|
||||
BinaryName: "java",
|
||||
InstallPath: "/usr/local/bin/java",
|
||||
CheckCommand: "java -version 2>&1 | head -1",
|
||||
VersionURL: "https://api.adoptium.net/v3/info/release_versions?heap_size=normal&image_type=jdk&page=0&page_size=1&project=jdk&release_type=ga&semver=false&sort_method=DEFAULT&sort_order=DESC&version=%5B17%2C99%5D",
|
||||
DownloadURL: "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-{version}/OpenJDK17U-jdk_x64_linux_hotspot_{version}.tar.gz",
|
||||
DefaultVersion: "17.0.13+7",
|
||||
InstallScript: `#!/bin/sh
|
||||
# JDK lazy install — Temurin OpenJDK
|
||||
JDK_VERSION="${TOOL_VERSION:-17.0.13+7}"
|
||||
JDK_MAJOR=$(echo "$JDK_VERSION" | cut -d. -f1)
|
||||
JDK_URL="https://github.com/adoptium/temurin${JDK_MAJOR}-binaries/releases/download/jdk-${JDK_VERSION}/OpenJDK${JDK_MAJOR}U-jdk_x64_linux_hotspot_${JDK_VERSION}.tar.gz"
|
||||
echo "[JDK] Downloading ${JDK_VERSION}..."
|
||||
cd /tmp
|
||||
curl -sL "$JDK_URL" -o jdk.tar.gz
|
||||
tar xzf jdk.tar.gz
|
||||
mkdir -p /usr/local/share
|
||||
mv jdk-${JDK_VERSION} /usr/local/share/jdk
|
||||
ln -sf /usr/local/share/jdk/bin/java /usr/local/bin/java
|
||||
ln -sf /usr/local/share/jdk/bin/javac /usr/local/bin/javac
|
||||
ln -sf /usr/local/share/jdk/bin/jar /usr/local/bin/jar
|
||||
rm -f jdk.tar.gz
|
||||
echo "[JDK] Installed: $(java -version 2>&1 | head -1)"
|
||||
`,
|
||||
SortOrder: 1,
|
||||
},
|
||||
// ──── Maven — Java 构建 // Logan.Li ────
|
||||
{
|
||||
Name: "maven",
|
||||
DisplayName: "Maven",
|
||||
Description: "Java 项目构建工具,流水线 Java 构建阶段使用(依赖 JDK)",
|
||||
Category: "build",
|
||||
InstallMethod: ToolLazy,
|
||||
BinaryName: "mvn",
|
||||
InstallPath: "/usr/local/bin/mvn",
|
||||
CheckCommand: "mvn --version 2>/dev/null",
|
||||
DownloadURL: "https://dlcdn.apache.org/maven/maven-3/{version}/binaries/apache-maven-{version}-bin.tar.gz",
|
||||
VersionURL: "https://dlcdn.apache.org/maven/maven-3/",
|
||||
DefaultVersion: "3.9.9",
|
||||
InstallScript: `#!/bin/sh
|
||||
# Maven lazy install — download & extract
|
||||
MAVEN_VERSION="${TOOL_VERSION:-3.9.9}"
|
||||
MAVEN_URL="https://dlcdn.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz"
|
||||
echo "[Maven] Downloading ${MAVEN_VERSION}..."
|
||||
cd /tmp
|
||||
curl -sL "$MAVEN_URL" -o maven.tar.gz
|
||||
tar xzf maven.tar.gz
|
||||
mkdir -p /usr/local/share
|
||||
mv apache-maven-${MAVEN_VERSION} /usr/local/share/maven
|
||||
ln -sf /usr/local/share/maven/bin/mvn /usr/local/bin/mvn
|
||||
rm -f maven.tar.gz
|
||||
echo "[Maven] Installed: $(mvn --version 2>&1 | head -1)"
|
||||
`,
|
||||
SortOrder: 2,
|
||||
},
|
||||
// ──── NVM — Node Version Manager // Logan.Li ────
|
||||
{
|
||||
Name: "nvm",
|
||||
DisplayName: "NVM (Node 版本管理)",
|
||||
Description: "Node 版本管理器,流水线 Node.js 构建阶段使用(node 依赖此工具)",
|
||||
Category: "build",
|
||||
InstallMethod: ToolLazy,
|
||||
BinaryName: "nvm",
|
||||
InstallPath: "/usr/local/share/nvm/nvm.sh",
|
||||
CheckCommand: "source /usr/local/share/nvm/nvm.sh 2>/dev/null && nvm --version 2>/dev/null",
|
||||
VersionURL: "https://api.github.com/repos/nvm-sh/nvm/releases/latest",
|
||||
DefaultVersion: "0.40.1",
|
||||
InstallScript: `#!/bin/sh
|
||||
# NVM lazy install
|
||||
NVM_VERSION="${TOOL_VERSION:-0.40.1}"
|
||||
NVM_DIR="/usr/local/share/nvm"
|
||||
echo "[NVM] Downloading ${NVM_VERSION}..."
|
||||
mkdir -p "$NVM_DIR"
|
||||
curl -sL "https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh" | NVM_DIR="$NVM_DIR" bash
|
||||
# Make available system-wide via profile.d
|
||||
cat > /etc/profile.d/nvm.sh << 'NVM_PROFILE'
|
||||
export NVM_DIR="/usr/local/share/nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
|
||||
NVM_PROFILE
|
||||
chmod +x /etc/profile.d/nvm.sh
|
||||
echo "[NVM] Installed: v${NVM_VERSION}"
|
||||
`,
|
||||
SortOrder: 3,
|
||||
},
|
||||
// ──── Node.js — 通过 NVM 安装 // Logan.Li ────
|
||||
{
|
||||
Name: "nodejs",
|
||||
DisplayName: "Node.js + npm",
|
||||
Description: "前端构建工具,流水线 npm install/build 阶段使用(通过 NVM 安装)",
|
||||
Category: "build",
|
||||
InstallMethod: ToolLazy,
|
||||
BinaryName: "node",
|
||||
InstallPath: "/usr/local/bin/node",
|
||||
CheckCommand: "node --version 2>/dev/null",
|
||||
DefaultVersion: "v22.14.0",
|
||||
InstallScript: `#!/bin/sh
|
||||
# Node.js via NVM install
|
||||
NODE_VERSION="${TOOL_VERSION:-v22.14.0}"
|
||||
echo "[Node.js] Installing via NVM ${NODE_VERSION}..."
|
||||
export NVM_DIR="/usr/local/share/nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
if ! command -v nvm >/dev/null 2>&1; then
|
||||
# NVM not found — install it first
|
||||
echo "[Node.js] NVM not found, installing NVM first..."
|
||||
curl -sL "https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh" | NVM_DIR="$NVM_DIR" bash
|
||||
\. "$NVM_DIR/nvm.sh"
|
||||
fi
|
||||
nvm install "${NODE_VERSION#v}"
|
||||
nvm alias default "${NODE_VERSION#v}"
|
||||
nvm use "${NODE_VERSION#v}"
|
||||
# Symlink for system-wide access
|
||||
ln -sf "$NVM_DIR/versions/node/$(nvm version)/bin/node" /usr/local/bin/node
|
||||
ln -sf "$NVM_DIR/versions/node/$(nvm version)/bin/npm" /usr/local/bin/npm
|
||||
ln -sf "$NVM_DIR/versions/node/$(nvm version)/bin/npx" /usr/local/bin/npx
|
||||
npm config set registry https://registry.npmmirror.com
|
||||
echo "[Node.js] Installed: $(node --version) / npm $(npm --version)"
|
||||
`,
|
||||
SortOrder: 4,
|
||||
},
|
||||
// ──── Git — 版本控制(预装)// Logan.Li ────
|
||||
{
|
||||
Name: "git",
|
||||
DisplayName: "Git",
|
||||
Description: "版本控制工具,流水线代码拉取使用",
|
||||
Category: "build",
|
||||
InstallMethod: ToolPreinstall,
|
||||
BinaryName: "git",
|
||||
InstallPath: "/usr/bin/git",
|
||||
CheckCommand: "git --version 2>/dev/null",
|
||||
SortOrder: 5,
|
||||
},
|
||||
// ──── Docker CLI — 容器构建(预装)// Logan.Li ────
|
||||
{
|
||||
Name: "docker-cli",
|
||||
DisplayName: "Docker CLI",
|
||||
Description: "Docker 命令行工具,流水线镜像构建/推送使用",
|
||||
Category: "deploy",
|
||||
InstallMethod: ToolPreinstall,
|
||||
BinaryName: "docker",
|
||||
InstallPath: "/usr/bin/docker",
|
||||
CheckCommand: "docker --version 2>/dev/null",
|
||||
SortOrder: 6,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
// KubernetesCluster K8s集群模型
|
||||
type KubernetesCluster 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"`
|
||||
Version string `gorm:"size:32" json:"version"`
|
||||
Status string `gorm:"size:32;default:healthy" json:"status"` // healthy, warning, error
|
||||
ConfigType int `gorm:"default:1" json:"config_type"` // 0=token, 1=kubeconfig
|
||||
APIServer string `gorm:"size:255" json:"api_server"`
|
||||
APIEndpoint string `gorm:"size:255" json:"api_endpoint"`
|
||||
Token string `gorm:"type:text" json:"-"`
|
||||
KubeConfig string `gorm:"type:text" json:"-"`
|
||||
NodeCount int `gorm:"default:0" json:"node_count"`
|
||||
PodCount int `gorm:"default:0" json:"pod_count"`
|
||||
ServiceCount int `gorm:"default:0" json:"service_count"`
|
||||
DeploymentCount int `gorm:"default:0" json:"deployment_count"`
|
||||
CPUUsage float64 `json:"cpu_usage"`
|
||||
MemoryUsage float64 `json:"memory_usage"`
|
||||
Description string `gorm:"size:500" json:"description"`
|
||||
Labels string `gorm:"type:text" json:"labels"` // JSON
|
||||
LastSyncAt *time.Time `json:"last_sync_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (KubernetesCluster) TableName() string {
|
||||
return "kubernetes_clusters"
|
||||
}
|
||||
|
||||
// KubernetesNode K8s节点模型
|
||||
type KubernetesNode struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
ClusterID uint `gorm:"not null" json:"cluster_id"`
|
||||
Name string `gorm:"size:128;not null" json:"name"`
|
||||
IP string `gorm:"size:64" json:"ip"`
|
||||
Role string `gorm:"size:32" json:"role"` // master, worker
|
||||
Status string `gorm:"size:32" json:"status"`
|
||||
OS string `gorm:"size:64" json:"os"`
|
||||
KubeletVer string `gorm:"size:32" json:"kubelet_version"`
|
||||
CPU int `json:"cpu"`
|
||||
Memory int64 `json:"memory"`
|
||||
Disk int64 `json:"disk"`
|
||||
CPUUsage float64 `json:"cpu_usage"`
|
||||
MemoryUsage float64 `json:"memory_usage"`
|
||||
DiskUsage float64 `json:"disk_usage"`
|
||||
PodCount int `json:"pod_count"`
|
||||
MaxPods int `json:"max_pods"`
|
||||
Labels string `gorm:"type:text" json:"labels"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Cluster *KubernetesCluster `json:"cluster,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (KubernetesNode) TableName() string {
|
||||
return "kubernetes_nodes"
|
||||
}
|
||||
|
||||
// KubernetesPod K8s Pod模型
|
||||
type KubernetesPod struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
ClusterID uint `gorm:"not null" json:"cluster_id"`
|
||||
Namespace string `gorm:"size:64;not null" json:"namespace"`
|
||||
Name string `gorm:"size:128;not null" json:"name"`
|
||||
Status string `gorm:"size:32" json:"status"` // Running, Pending, Succeeded, Failed
|
||||
NodeName string `gorm:"size:128" json:"node_name"`
|
||||
IP string `gorm:"size:64" json:"ip"`
|
||||
RestartCount int `json:"restart_count"`
|
||||
Image string `gorm:"size:255" json:"image"`
|
||||
CPUUsage float64 `json:"cpu_usage"`
|
||||
MemoryUsage float64 `json:"memory_usage"`
|
||||
Labels string `gorm:"type:text" json:"labels"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Cluster *KubernetesCluster `json:"cluster,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (KubernetesPod) TableName() string {
|
||||
return "kubernetes_pods"
|
||||
}
|
||||
|
||||
// KubernetesDeployment K8s Deployment模型
|
||||
type KubernetesDeployment struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
ClusterID uint `gorm:"not null" json:"cluster_id"`
|
||||
Namespace string `gorm:"size:64;not null" json:"namespace"`
|
||||
Name string `gorm:"size:128;not null" json:"name"`
|
||||
Replicas int `json:"replicas"`
|
||||
AvailableReplicas int `json:"available_replicas"`
|
||||
ReadyReplicas int `json:"ready_replicas"`
|
||||
Image string `gorm:"size:255" json:"image"`
|
||||
Strategy string `gorm:"size:32" json:"strategy"`
|
||||
Labels string `gorm:"type:text" json:"labels"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Cluster *KubernetesCluster `json:"cluster,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (KubernetesDeployment) TableName() string {
|
||||
return "kubernetes_deployments"
|
||||
}
|
||||
|
||||
// KubernetesService K8s Service模型
|
||||
type KubernetesService struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
ClusterID uint `gorm:"not null" json:"cluster_id"`
|
||||
Namespace string `gorm:"size:64;not null" json:"namespace"`
|
||||
Name string `gorm:"size:128;not null" json:"name"`
|
||||
Type string `gorm:"size:32" json:"type"` // ClusterIP, NodePort, LoadBalancer
|
||||
ClusterIP string `gorm:"size:64" json:"cluster_ip"`
|
||||
ExternalIP string `gorm:"size:255" json:"external_ip"`
|
||||
Ports string `gorm:"type:text" json:"ports"` // JSON
|
||||
Selector string `gorm:"type:text" json:"selector"`
|
||||
Labels string `gorm:"type:text" json:"labels"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Cluster *KubernetesCluster `json:"cluster,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (KubernetesService) TableName() string {
|
||||
return "kubernetes_services"
|
||||
}
|
||||
|
||||
// KubernetesIngress K8s Ingress模型
|
||||
type KubernetesIngress struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
ClusterID uint `gorm:"not null" json:"cluster_id"`
|
||||
Namespace string `gorm:"size:64;not null" json:"namespace"`
|
||||
Name string `gorm:"size:128;not null" json:"name"`
|
||||
Hosts string `gorm:"type:text" json:"hosts"` // JSON
|
||||
Backend string `gorm:"size:255" json:"backend"`
|
||||
TLS bool `json:"tls"`
|
||||
TLSHosts string `gorm:"type:text" json:"tls_hosts"`
|
||||
Labels string `gorm:"type:text" json:"labels"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Cluster *KubernetesCluster `json:"cluster,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (KubernetesIngress) TableName() string {
|
||||
return "kubernetes_ingresses"
|
||||
}
|
||||
|
||||
// CreateKubernetesClusterRequest 创建K8s集群请求
|
||||
type CreateKubernetesClusterRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Code string `json:"code" binding:"required"`
|
||||
Version string `json:"version"`
|
||||
ConfigType int `json:"config_type"` // 0=token, 1=kubeconfig
|
||||
APIServer string `json:"api_server"`
|
||||
APIEndpoint string `json:"api_endpoint"`
|
||||
Token string `json:"token"`
|
||||
KubeConfig string `json:"kube_config"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// KubernetesClusterStats K8s集群统计
|
||||
type KubernetesClusterStats struct {
|
||||
Total int64 `json:"total"`
|
||||
Healthy int64 `json:"healthy"`
|
||||
Warning int64 `json:"warning"`
|
||||
Error int64 `json:"error"`
|
||||
TotalNodes int64 `json:"total_nodes"`
|
||||
TotalPods int64 `json:"total_pods"`
|
||||
TotalServices int64 `json:"total_services"`
|
||||
}
|
||||
|
||||
// TopologyLayout 拓扑布局(保存节点位置 + 自定义节点 + 自定义连线) // Logan.Li
|
||||
type TopologyLayout struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
ClusterID uint `gorm:"uniqueIndex;not null" json:"cluster_id"`
|
||||
LayoutData string `gorm:"type:text" json:"layout_data"` // JSON: {positions, customNodes, customEdges}
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (TopologyLayout) TableName() string {
|
||||
return "kubernetes_topology_layouts"
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// LLMConfig 大语言模型配置(单行配置,类似 LDAPConfig) // Logan.Li
|
||||
// 支持 OpenAI 兼容接口(OpenAI / DeepSeek / 通义千问 / Moonshot / Ollama / 自定义)
|
||||
type LLMConfig struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Provider string `gorm:"size:50;not null;default:openai" json:"provider"` // openai/deepseek/qwen/moonshot/ollama/custom
|
||||
Model string `gorm:"size:100;not null;default:gpt-4o-mini" json:"model"` // 模型名,如 gpt-4o-mini / deepseek-chat
|
||||
APIKey string `gorm:"size:500" json:"api_key"` // API Key(GET 时会被脱敏)
|
||||
Endpoint string `gorm:"size:500" json:"endpoint"` // 基础地址,如 https://api.openai.com/v1
|
||||
Temperature float64 `gorm:"default:0.7" json:"temperature"` // 采样温度 0-2
|
||||
MaxTokens int `gorm:"default:2000" json:"max_tokens"` // 最大输出 token
|
||||
SystemPrompt string `gorm:"type:text" json:"system_prompt"` // 系统提示词(AIOps 运维助手角色)
|
||||
Enabled bool `gorm:"default:false" json:"enabled"` // 是否启用
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名 // Logan.Li
|
||||
func (LLMConfig) TableName() string { return "ai_llm_configs" }
|
||||
|
||||
// SaveLLMConfigRequest 保存 LLM 配置请求 // Logan.Li
|
||||
type SaveLLMConfigRequest struct {
|
||||
Provider string `json:"provider"`
|
||||
Model string `json:"model"`
|
||||
APIKey string `json:"api_key"` // 若为脱敏值(含 ****)则后端保留原值
|
||||
Endpoint string `json:"endpoint"`
|
||||
Temperature float64 `json:"temperature"`
|
||||
MaxTokens int `json:"max_tokens"`
|
||||
SystemPrompt string `json:"system_prompt"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// ChatMessage 对话消息 // Logan.Li
|
||||
type ChatMessage struct {
|
||||
Role string `json:"role"` // system / user / assistant
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// ChatRequest AI 对话请求 // Logan.Li
|
||||
type ChatRequest struct {
|
||||
Messages []ChatMessage `json:"messages" binding:"required,min=1,dive"`
|
||||
SessionID string `json:"session_id"` // 前端生成,用于隔离多轮对话
|
||||
}
|
||||
|
||||
// ChatResponse AI 对话响应 // Logan.Li
|
||||
type ChatResponse struct {
|
||||
Content string `json:"content"`
|
||||
Model string `json:"model"`
|
||||
TokensUsed int `json:"tokens_used"`
|
||||
}
|
||||
|
||||
// ChatHistory 对话历史记录(按用户隔离,session_id 区分多轮对话) // Logan.Li
|
||||
// 仅持久化成功完成的对话(用户消息 + 助手回复成对写入),错误气泡为瞬时 UI 不入库
|
||||
type ChatHistory struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
UserID uint `gorm:"index;not null" json:"user_id"` // 所属用户(JWT 中间件注入)
|
||||
SessionID string `gorm:"size:64;index;not null;default:''" json:"session_id"` // 对话会话 ID(前端 UUID)
|
||||
Role string `gorm:"size:16;not null" json:"role"` // user / assistant
|
||||
Content string `gorm:"type:text;not null" json:"content"` // 消息内容
|
||||
Model string `gorm:"size:100" json:"model"` // 生成回复所用模型(仅 assistant 行有意义)
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// TableName 表名 // Logan.Li
|
||||
func (ChatHistory) TableName() string { return "ai_chat_histories" }
|
||||
@@ -0,0 +1,34 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// LoginLog 登录日志(参考 JumpServer / opsx-web-lite) // Logan.Li
|
||||
type LoginLog struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
UserID *uint `json:"user_id"`
|
||||
Username string `gorm:"size:64;index" json:"username"`
|
||||
IP string `gorm:"size:64" json:"ip"`
|
||||
Location string `gorm:"size:128" json:"location"` // IP 归属地
|
||||
Browser string `gorm:"size:128" json:"browser"` // 浏览器
|
||||
OS string `gorm:"size:128" json:"os"` // 操作系统
|
||||
LoginType string `gorm:"size:32;default:password" json:"login_type"` // password / ldap
|
||||
UserAgent string `gorm:"size:500" json:"user_agent"`
|
||||
Status string `gorm:"size:32" json:"status"` // success, failed
|
||||
FailReason string `gorm:"size:255" json:"fail_reason"`
|
||||
LoginAt time.Time `gorm:"index" json:"login_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (LoginLog) TableName() string {
|
||||
return "sys_login_logs"
|
||||
}
|
||||
|
||||
// LoginLogQuery 登录日志查询
|
||||
type LoginLogQuery struct {
|
||||
Username string `form:"username"`
|
||||
Status string `form:"status"`
|
||||
StartTime string `form:"start_time"`
|
||||
EndTime string `form:"end_time"`
|
||||
Page int `form:"page,default=1"`
|
||||
PageSize int `form:"page_size,default=20"`
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// MetricsAggregate 指标聚合数据(Redis 热数据 → MySQL 时序聚合)// Logan.Li
|
||||
// 替代旧名 MetricsKline,OHLC 对监控无意义,改用 max/min/avg/p95
|
||||
type MetricsAggregate struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Hostname string `gorm:"size:255;index:idx_agg;not null" json:"hostname"`
|
||||
Metric string `gorm:"size:32;index:idx_agg;not null" json:"metric"` // cpu / mem / load1 / disk / net_rx / net_tx
|
||||
Interval string `gorm:"size:8;index:idx_agg;not null" json:"interval"` // 1m / 5m / 1h / 6h / 1d
|
||||
Avg float64 `gorm:"type:decimal(10,2)" json:"avg"`
|
||||
MaxV float64 `gorm:"column:max_v;type:decimal(10,2)" json:"max"`
|
||||
MinV float64 `gorm:"column:min_v;type:decimal(10,2)" json:"min"`
|
||||
P95 float64 `gorm:"type:decimal(10,2)" json:"p95"`
|
||||
Count int `json:"count"`
|
||||
BucketTime time.Time `gorm:"index:idx_agg;not null" json:"bucket_time"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (MetricsAggregate) TableName() string {
|
||||
return "monitor_metrics_aggregate"
|
||||
}
|
||||
|
||||
// AggregateReq 聚合触发请求
|
||||
type AggregateReq struct {
|
||||
Hostname string `json:"hostname" binding:"required"`
|
||||
Metric string `json:"metric" binding:"required"` // cpu / mem / load1
|
||||
}
|
||||
|
||||
// AggregateQueryReq 聚合查询参数
|
||||
type AggregateQueryReq struct {
|
||||
Hostname string `form:"hostname" binding:"required"`
|
||||
Metric string `form:"metric" binding:"required"`
|
||||
Interval string `form:"interval" binding:"required"`
|
||||
From string `form:"from" binding:"required"` // RFC3339
|
||||
To string `form:"to" binding:"required"` // RFC3339
|
||||
}
|
||||
@@ -0,0 +1,425 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// ============================================
|
||||
// MonitorTarget 监控目标(主机/中间件/设备/站点)
|
||||
// ============================================
|
||||
|
||||
// TargetType 监控目标类型
|
||||
type TargetType string
|
||||
|
||||
const (
|
||||
TargetTypeHost TargetType = "host" // 主机
|
||||
TargetTypeMiddleware TargetType = "middleware" // 中间件
|
||||
TargetTypeDevice TargetType = "device" // 网络设备
|
||||
TargetTypeSite TargetType = "site" // 站点
|
||||
TargetTypeDatabase TargetType = "database" // 数据库
|
||||
TargetTypeContainer TargetType = "container" // 容器
|
||||
)
|
||||
|
||||
// TargetStatus 监控目标状态
|
||||
type TargetStatus string
|
||||
|
||||
const (
|
||||
TargetStatusOnline TargetStatus = "online" // 在线
|
||||
TargetStatusOffline TargetStatus = "offline" // 离线
|
||||
TargetStatusUnknown TargetStatus = "unknown" // 未知
|
||||
)
|
||||
|
||||
// MonitorTarget 监控目标表
|
||||
// 存储所有被监控的对象,包括主机、中间件、网络设备、站点等
|
||||
type MonitorTarget struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
Name string `gorm:"type:varchar(128);not null;index;comment:目标名称" json:"name"`
|
||||
Type TargetType `gorm:"type:varchar(32);not null;index;comment:目标类型" json:"type"`
|
||||
Status TargetStatus `gorm:"type:varchar(16);default:'unknown';index;comment:状态" json:"status"`
|
||||
IP string `gorm:"type:varchar(64);comment:IP地址" json:"ip,omitempty"`
|
||||
Port int `gorm:"default:0;comment:端口" json:"port,omitempty"`
|
||||
AgentID string `gorm:"type:varchar(64);index;comment:Agent标识" json:"agent_id,omitempty"`
|
||||
OS string `gorm:"type:varchar(64);comment:操作系统" json:"os,omitempty"`
|
||||
OSVersion string `gorm:"type:varchar(64);comment:OS版本" json:"os_version,omitempty"`
|
||||
Arch string `gorm:"type:varchar(16);comment:系统架构" json:"arch,omitempty"`
|
||||
Kernel string `gorm:"type:varchar(64);comment:内核版本" json:"kernel,omitempty"`
|
||||
HostGroupID uint `gorm:"index;comment:主机组ID" json:"host_group_id,omitempty"`
|
||||
Tags string `gorm:"type:varchar(512);comment:标签JSON" json:"tags,omitempty"`
|
||||
CollectMode string `gorm:"type:varchar(16);default:'agent';comment:采集模式:agent/snmp/api" json:"collect_mode"`
|
||||
SNMPConfig string `gorm:"type:text;comment:SNMP配置JSON" json:"snmp_config,omitempty"`
|
||||
APIConfig string `gorm:"type:text;comment:API配置JSON" json:"api_config,omitempty"`
|
||||
Address string `gorm:"type:varchar(255);comment:监控地址(IP或域名)" json:"address,omitempty"`
|
||||
Protocol string `gorm:"type:varchar(32);comment:协议类型(http/https/tcp/udp/icmp/snmp)" json:"protocol,omitempty"`
|
||||
Timeout int `gorm:"default:30;comment:超时时间(秒)" json:"timeout,omitempty"`
|
||||
Config string `gorm:"type:text;comment:通用配置JSON" json:"config,omitempty"`
|
||||
Interval int `gorm:"default:60;comment:采集间隔(秒)" json:"interval"`
|
||||
Labels string `gorm:"type:varchar(512);comment:标签JSON" json:"labels,omitempty"`
|
||||
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
|
||||
CreatedAt time.Time `gorm:"not null;index;comment:创建时间" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
||||
DeletedAt *time.Time `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
|
||||
LastSeenAt *time.Time `gorm:"index;comment:最后在线时间" json:"last_seen_at,omitempty"`
|
||||
|
||||
// 关联关系
|
||||
HostGroup *HostGroup `gorm:"foreignKey:HostGroupID" json:"host_group,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (MonitorTarget) TableName() string {
|
||||
return "monitor_targets"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// MonitorMetric 监控指标定义
|
||||
// ============================================
|
||||
|
||||
// MetricType 指标类型
|
||||
type MetricType string
|
||||
|
||||
const (
|
||||
MetricTypeGauge MetricType = "gauge" // 瞬时值
|
||||
MetricTypeCounter MetricType = "counter" // 计数器
|
||||
MetricTypeSummary MetricType = "summary" // 摘要
|
||||
)
|
||||
|
||||
// DataSourceType 数据来源类型
|
||||
type DataSourceType string
|
||||
|
||||
const (
|
||||
DataSourceAgent DataSourceType = "agent" // Agent采集
|
||||
DataSourceSNMP DataSourceType = "snmp" // SNMP采集
|
||||
DataSourceAPI DataSourceType = "api" // API采集
|
||||
DataSourcePrometheus DataSourceType = "prometheus" // Prometheus
|
||||
DataSourceZabbix DataSourceType = "zabbix" // Zabbix
|
||||
)
|
||||
|
||||
// MonitorMetric 监控指标定义表
|
||||
// 定义系统中所有可采集的监控指标元数据
|
||||
type MonitorMetric struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
Name string `gorm:"type:varchar(128);not null;uniqueIndex:uk_metric_name;comment:指标名称" json:"name"`
|
||||
DisplayName string `gorm:"type:varchar(128);not null;comment:显示名称" json:"display_name"`
|
||||
Description string `gorm:"type:varchar(256);comment:指标描述" json:"description,omitempty"`
|
||||
MetricType MetricType `gorm:"type:varchar(16);not null;comment:指标类型: gauge/counter/summary" json:"metric_type"`
|
||||
Unit string `gorm:"type:varchar(32);comment:单位" json:"unit,omitempty"`
|
||||
DataSource DataSourceType `gorm:"type:varchar(16);not null;comment:数据来源" json:"data_source"`
|
||||
CollectExpr string `gorm:"type:varchar(256);comment:采集表达式/OID/PromQL" json:"collect_expr,omitempty"`
|
||||
Interval int `gorm:"default:60;comment:采集间隔(秒)" json:"interval"`
|
||||
Labels string `gorm:"type:varchar(512);comment:指标标签定义JSON" json:"labels,omitempty"`
|
||||
ValueType string `gorm:"type:varchar(16);default:'float64';comment:值类型" json:"value_type"`
|
||||
Category string `gorm:"type:varchar(64);comment:指标分类" json:"category,omitempty"`
|
||||
IsDefault bool `gorm:"default:true;comment:是否默认启用" json:"is_default"`
|
||||
IsInternal bool `gorm:"default:false;comment:是否内置指标" json:"is_internal"`
|
||||
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
|
||||
Icon string `gorm:"type:varchar(64);comment:图标" json:"icon,omitempty"`
|
||||
SortOrder int `gorm:"default:0;comment:排序" json:"sort_order"`
|
||||
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 (MonitorMetric) TableName() string {
|
||||
return "monitor_metrics"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// MetricValue 指标值(时序数据)
|
||||
// ============================================
|
||||
|
||||
// MetricValue 指标值表(按时间分区的时序数据)
|
||||
// 存储采集到的实际指标数值,支持高并发写入和时序查询
|
||||
type MetricValue struct {
|
||||
ID uint64 `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
MetricID uint `gorm:"not null;index:idx_metric_time;comment:指标ID" json:"metric_id"`
|
||||
TargetID uint `gorm:"not null;index:idx_target_metric;comment:目标ID" json:"target_id"`
|
||||
Instance string `gorm:"type:varchar(128);index;comment:实例标识" json:"instance,omitempty"`
|
||||
Value float64 `gorm:"not null;comment:指标值" json:"value"`
|
||||
RawValue string `gorm:"type:text;comment:原始值(用于字符串类型)" json:"raw_value,omitempty"`
|
||||
Labels string `gorm:"type:varchar(512);index;comment:标签JSON" json:"labels,omitempty"`
|
||||
Timestamp int64 `gorm:"not null;index:idx_metric_time;comment:时间戳(秒)" json:"timestamp"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
|
||||
// 关联关系
|
||||
Metric *MonitorMetric `gorm:"foreignKey:MetricID" json:"metric,omitempty"`
|
||||
Target *MonitorTarget `gorm:"foreignKey:TargetID" json:"target,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (MetricValue) TableName() string {
|
||||
return "metric_values"
|
||||
}
|
||||
|
||||
// MetricHistory 指标历史数据(简化版,供监控查询使用)
|
||||
type MetricHistory struct {
|
||||
ID uint64 `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
TargetID uint `gorm:"index;not null" json:"target_id"`
|
||||
MetricName string `gorm:"type:varchar(128);index" json:"metric_name"`
|
||||
Value float64 `json:"value"`
|
||||
Timestamp int64 `gorm:"index;not null" json:"timestamp"`
|
||||
}
|
||||
|
||||
func (MetricHistory) TableName() string {
|
||||
return "monitor_metric_histories"
|
||||
}
|
||||
|
||||
// MetricValueQuery 指标值查询参数
|
||||
type MetricValueQuery struct {
|
||||
MetricID uint `json:"metric_id" form:"metric_id"`
|
||||
TargetID uint `json:"target_id" form:"target_id"`
|
||||
Instance string `json:"instance" form:"instance"`
|
||||
StartTime int64 `json:"start_time" form:"start_time"`
|
||||
EndTime int64 `json:"end_time" form:"end_time"`
|
||||
Step int `json:"step" form:"step"` // 聚合步长(秒)
|
||||
Limit int `json:"limit" form:"limit"`
|
||||
}
|
||||
|
||||
// MetricAggResult 指标聚合结果
|
||||
type MetricAggResult struct {
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Value float64 `json:"value"`
|
||||
Count int64 `json:"count,omitempty"`
|
||||
Min float64 `json:"min,omitempty"`
|
||||
Max float64 `json:"max,omitempty"`
|
||||
Avg float64 `json:"avg,omitempty"`
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// MetricTag 指标标签
|
||||
// ============================================
|
||||
|
||||
// MetricTag 指标标签定义表
|
||||
// 定义指标维度标签,用于多维数据分析和过滤
|
||||
type MetricTag struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
MetricID uint `gorm:"not null;index:idx_metric_tag;comment:指标ID" json:"metric_id"`
|
||||
TagKey string `gorm:"type:varchar(64);not null;index:idx_metric_tag;comment:标签键" json:"tag_key"`
|
||||
TagValue string `gorm:"type:varchar(128);index;comment:标签值" json:"tag_value"`
|
||||
Description string `gorm:"type:varchar(128);comment:描述" json:"description,omitempty"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (MetricTag) TableName() string {
|
||||
return "monitor_metric_tags"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// MonitorDashboard 监控大屏配置
|
||||
// ============================================
|
||||
|
||||
// DashboardType 大屏类型
|
||||
type DashboardType string
|
||||
|
||||
const (
|
||||
DashboardTypeSystem DashboardType = "system" // 系统内置
|
||||
DashboardTypeCustom DashboardType = "custom" // 自定义
|
||||
DashboardTypeShared DashboardType = "shared" // 共享
|
||||
)
|
||||
|
||||
// MonitorDashboard 监控大屏配置表
|
||||
// 定义监控大屏的元数据配置
|
||||
type MonitorDashboard struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
Name string `gorm:"type:varchar(128);not null;comment:大屏名称" json:"name"`
|
||||
Type DashboardType `gorm:"type:varchar(16);default:'custom';comment:大屏类型" json:"type"`
|
||||
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
|
||||
Layout string `gorm:"type:text;comment:布局配置JSON" json:"layout,omitempty"`
|
||||
Theme string `gorm:"type:varchar(32);default:'dark';comment:主题: dark/light" json:"theme"`
|
||||
RefreshRate int `gorm:"default:30;comment:自动刷新间隔(秒)" json:"refresh_rate"`
|
||||
IsDefault bool `gorm:"default:false;comment:是否默认大屏" json:"is_default"`
|
||||
IsPublic bool `gorm:"default:false;comment:是否公开" json:"is_public"`
|
||||
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
|
||||
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
|
||||
SortOrder int `gorm:"default:0;comment:排序" json:"sort_order"`
|
||||
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"`
|
||||
|
||||
// 关联关系
|
||||
Panels []DashboardPanel `gorm:"foreignKey:DashboardID" json:"panels,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (MonitorDashboard) TableName() string {
|
||||
return "monitor_dashboards"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// DashboardPanel 大屏面板
|
||||
// ============================================
|
||||
|
||||
// PanelType 面板类型
|
||||
type PanelType string
|
||||
|
||||
const (
|
||||
PanelTypeChart PanelType = "chart" // 图表
|
||||
PanelTypeGauge PanelType = "gauge" // 仪表盘
|
||||
PanelTypeCounter PanelType = "counter" // 计数器
|
||||
PanelTypeTable PanelType = "table" // 表格
|
||||
PanelTypeStatus PanelType = "status" // 状态
|
||||
PanelTypeTopology PanelType = "topology" // 拓扑
|
||||
PanelTypeLog PanelType = "log" // 日志
|
||||
PanelTypeAlertList PanelType = "alert_list" // 告警列表
|
||||
PanelTypeHeatmap PanelType = "heatmap" // 热力图
|
||||
PanelTypeText PanelType = "text" // 文本
|
||||
)
|
||||
|
||||
// ChartType 图表类型
|
||||
type ChartType string
|
||||
|
||||
const (
|
||||
ChartTypeLine ChartType = "line" // 折线
|
||||
ChartTypeBar ChartType = "bar" // 柱状
|
||||
ChartTypeArea ChartType = "area" // 面积
|
||||
ChartTypePie ChartType = "pie" // 饼图
|
||||
ChartTypeScatter ChartType = "scatter" // 散点
|
||||
)
|
||||
|
||||
// DashboardPanel 大屏面板配置表
|
||||
// 定义监控大屏中的各个面板配置
|
||||
type DashboardPanel struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
DashboardID uint `gorm:"not null;index;comment:大屏ID" json:"dashboard_id"`
|
||||
Title string `gorm:"type:varchar(128);not null;comment:面板标题" json:"title"`
|
||||
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
|
||||
PanelType PanelType `gorm:"type:varchar(16);not null;comment:面板类型" json:"panel_type"`
|
||||
ChartType ChartType `gorm:"type:varchar(16);comment:图表类型" json:"chart_type,omitempty"`
|
||||
// 位置布局配置
|
||||
X int `gorm:"default:0;comment:网格X坐标" json:"x"`
|
||||
Y int `gorm:"default:0;comment:网格Y坐标" json:"y"`
|
||||
Width int `gorm:"default:6;comment:宽度(网格列数)" json:"width"`
|
||||
Height int `gorm:"default:4;comment:高度(网格行数)" json:"height"`
|
||||
// 数据源配置
|
||||
DataSource string `gorm:"type:varchar(16);comment:数据源类型" json:"data_source,omitempty"`
|
||||
MetricID uint `gorm:"comment:关联指标ID" json:"metric_id,omitempty"`
|
||||
TargetID uint `gorm:"comment:关联目标ID" json:"target_id,omitempty"`
|
||||
QueryExpr string `gorm:"type:text;comment:查询表达式" json:"query_expr,omitempty"`
|
||||
QueryConfig string `gorm:"type:text;comment:查询配置JSON" json:"query_config,omitempty"`
|
||||
// 展示配置
|
||||
TimeRange string `gorm:"type:varchar(16);default:'1h';comment:时间范围" json:"time_range"`
|
||||
RefreshRate int `gorm:"default:0;comment:刷新间隔(秒),0表示继承大屏" json:"refresh_rate"`
|
||||
Thresholds string `gorm:"type:text;comment:阈值配置JSON" json:"thresholds,omitempty"`
|
||||
Colors string `gorm:"type:text;comment:颜色配置JSON" json:"colors,omitempty"`
|
||||
Legend string `gorm:"type:varchar(64);comment:图例配置" json:"legend,omitempty"`
|
||||
Unit string `gorm:"type:varchar(32);comment:显示单位" json:"unit,omitempty"`
|
||||
Decimals int `gorm:"default:2;comment:小数位数" json:"decimals"`
|
||||
// 状态
|
||||
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
|
||||
SortOrder int `gorm:"default:0;comment:排序" json:"sort_order"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (DashboardPanel) TableName() string {
|
||||
return "dashboard_panels"
|
||||
}
|
||||
|
||||
// PanelQueryConfig 面板查询配置
|
||||
type PanelQueryConfig struct {
|
||||
Metrics []string `json:"metrics"` // 指标名称列表
|
||||
Targets []uint `json:"targets"` // 目标ID列表
|
||||
Instances []string `json:"instances"` // 实例列表
|
||||
Aggregations []string `json:"aggregations"` // 聚合函数
|
||||
GroupBy []string `json:"group_by"` // 分组标签
|
||||
Filters map[string]string `json:"filters"` // 过滤条件
|
||||
Step int `json:"step"` // 步长
|
||||
LegendFormat string `json:"legend_format"` // 图例格式
|
||||
}
|
||||
|
||||
// ThresholdConfig 阈值配置
|
||||
type ThresholdConfig struct {
|
||||
Critical float64 `json:"critical"` // 严重
|
||||
Warning float64 `json:"warning"` // 警告
|
||||
Info float64 `json:"info"` // 提示
|
||||
Unit string `json:"unit"` // 单位
|
||||
}
|
||||
|
||||
// HostGroup 主机组
|
||||
type HostGroup struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
Name string `gorm:"type:varchar(128);not null;uniqueIndex;comment:组名称" json:"name"`
|
||||
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
|
||||
ParentID uint `gorm:"index;comment:父组ID" json:"parent_id,omitempty"`
|
||||
SortOrder int `gorm:"default:0;comment:排序" json:"sort_order"`
|
||||
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 (HostGroup) TableName() string {
|
||||
return "asset_host_groups"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// HealthProbe 健康探针配置(Agent 本地执行)
|
||||
// ============================================
|
||||
|
||||
// ProbeType 探针类型
|
||||
type ProbeType string
|
||||
|
||||
const (
|
||||
ProbeTypeHTTP ProbeType = "http_get" // HTTP GET 探测
|
||||
ProbeTypeTCP ProbeType = "tcp_socket" // TCP 端口连接探测
|
||||
ProbeTypeExec ProbeType = "exec_command" // 命令执行探测
|
||||
)
|
||||
|
||||
// ProbeStatus 探针结果状态
|
||||
type ProbeStatus string
|
||||
|
||||
const (
|
||||
ProbeStatusUp ProbeStatus = "up" // 健康
|
||||
ProbeStatusDown ProbeStatus = "down" // 异常
|
||||
)
|
||||
|
||||
// HealthProbe 健康探针配置表
|
||||
// 存储在平台 DB,Agent 拉取配置后在目标主机本地执行,结果随心跳上报
|
||||
type HealthProbe struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
Name string `gorm:"type:varchar(128);not null;index" json:"name"`
|
||||
Hostname string `gorm:"type:varchar(255);index;not null" json:"hostname"`
|
||||
ProbeType ProbeType `gorm:"type:varchar(32);not null" json:"probe_type"`
|
||||
// HTTP 探针配置
|
||||
HTTPURL string `gorm:"type:varchar(512)" json:"http_url,omitempty"`
|
||||
HTTPMethod string `gorm:"type:varchar(10);default:GET" json:"http_method,omitempty"`
|
||||
HTTPHeaders string `gorm:"type:text" json:"http_headers,omitempty"`
|
||||
HTTPExpectCode int `gorm:"default:200" json:"http_expect_code,omitempty"`
|
||||
HTTPExpectBody string `gorm:"type:varchar(256)" json:"http_expect_body,omitempty"`
|
||||
// TCP 探针配置
|
||||
TCPHost string `gorm:"type:varchar(255)" json:"tcp_host,omitempty"`
|
||||
TCPPort int `json:"tcp_port,omitempty"`
|
||||
// Exec 探针配置
|
||||
ExecCommand string `gorm:"type:text" json:"exec_command,omitempty"`
|
||||
// 通用配置
|
||||
Timeout int `gorm:"default:10" json:"timeout"`
|
||||
Interval int `gorm:"default:60" json:"interval"`
|
||||
Enabled bool `gorm:"default:true;index" json:"enabled"`
|
||||
LastStatus ProbeStatus `gorm:"type:varchar(8);default:''" json:"last_status,omitempty"`
|
||||
LastCheckedAt *time.Time `json:"last_checked_at,omitempty"`
|
||||
LastLatencyMs int `json:"last_latency_ms"`
|
||||
FailCount int `json:"fail_count"`
|
||||
Description string `gorm:"type:varchar(256)" json:"description,omitempty"`
|
||||
CreatedAt time.Time `gorm:"not null" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`
|
||||
DeletedAt *time.Time `gorm:"index" json:"deleted_at,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (HealthProbe) TableName() string {
|
||||
return "monitor_health_probes"
|
||||
}
|
||||
|
||||
// HealthProbeResult Agent 上报的探针执行结果(作为心跳的一部分)
|
||||
type HealthProbeResult struct {
|
||||
ProbeID uint `json:"probe_id"`
|
||||
Name string `json:"name"`
|
||||
ProbeType string `json:"probe_type"`
|
||||
Status ProbeStatus `json:"status"` // up / down
|
||||
LatencyMs int `json:"latency_ms"` // 响应延迟(ms)
|
||||
StatusCode int `json:"status_code,omitempty"` // HTTP 状态码
|
||||
Message string `json:"message,omitempty"` // 错误/附加信息
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
// NavigationGroup 导航分组模型
|
||||
type NavigationGroup 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"`
|
||||
Description string `gorm:"size:255" json:"description"`
|
||||
Icon string `gorm:"size:64" json:"icon"`
|
||||
Sort int `gorm:"default:0" json:"sort"`
|
||||
Enabled bool `gorm:"default:true" json:"enabled"`
|
||||
LinkCount int `gorm:"default:0" json:"link_count"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (NavigationGroup) TableName() string {
|
||||
return "sys_navigation_groups"
|
||||
}
|
||||
|
||||
// NavigationLink 导航链接模型
|
||||
type NavigationLink struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
GroupID uint `json:"group_id"`
|
||||
Name string `gorm:"size:128;not null" json:"name"`
|
||||
URL string `gorm:"size:500;not null" json:"url"`
|
||||
Description string `gorm:"size:255" json:"description"`
|
||||
Icon string `gorm:"size:64" json:"icon"`
|
||||
Tags string `gorm:"type:text" json:"tags"` // JSON
|
||||
IsFavorite bool `gorm:"default:false" json:"is_favorite"`
|
||||
Sort int `gorm:"default:0" json:"sort"`
|
||||
Enabled bool `gorm:"default:true" json:"enabled"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Group *NavigationGroup `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (NavigationLink) TableName() string {
|
||||
return "navigation_links"
|
||||
}
|
||||
|
||||
// CreateNavigationGroupRequest 创建导航分组请求
|
||||
type CreateNavigationGroupRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Code string `json:"code" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
Icon string `json:"icon"`
|
||||
Sort int `json:"sort"`
|
||||
}
|
||||
|
||||
// UpdateNavigationGroupRequest 更新导航分组请求
|
||||
type UpdateNavigationGroupRequest struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Icon string `json:"icon"`
|
||||
Sort int `json:"sort"`
|
||||
Enabled *bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// CreateNavigationLinkRequest 创建导航链接请求
|
||||
type CreateNavigationLinkRequest struct {
|
||||
GroupID uint `json:"group_id" binding:"required"`
|
||||
Name string `json:"name" binding:"required"`
|
||||
URL string `json:"url" binding:"required,url"`
|
||||
Description string `json:"description"`
|
||||
Icon string `json:"icon"`
|
||||
Tags []string `json:"tags"`
|
||||
Sort int `json:"sort"`
|
||||
}
|
||||
|
||||
// UpdateNavigationLinkRequest 更新导航链接请求
|
||||
type UpdateNavigationLinkRequest struct {
|
||||
GroupID uint `json:"group_id"`
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url" binding:"omitempty,url"`
|
||||
Description string `json:"description"`
|
||||
Icon string `json:"icon"`
|
||||
Tags []string `json:"tags"`
|
||||
Sort int `json:"sort"`
|
||||
Enabled *bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// ToggleFavoriteRequest 切换收藏请求
|
||||
type ToggleFavoriteRequest struct {
|
||||
IsFavorite bool `json:"is_favorite"`
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
// AnsiblePlaybook Playbook 模型 // Logan.Li
|
||||
type AnsiblePlaybook struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:255;not null" json:"name"`
|
||||
Description string `gorm:"type:text" json:"description"`
|
||||
Content string `gorm:"type:text;not null" json:"content"` // YAML 内容
|
||||
Tags string `gorm:"size:500" json:"tags"` // 逗号分隔
|
||||
Category string `gorm:"size:100" json:"category"` // deployment/maintenance/etc
|
||||
CreatedBy string `gorm:"size:255" json:"created_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (AnsiblePlaybook) TableName() string { return "ops_ansible_playbooks" }
|
||||
|
||||
// AnsibleJob 执行任务记录 // Logan.Li
|
||||
type AnsibleJob struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
PlaybookID uint `gorm:"not null" json:"playbook_id"`
|
||||
PlaybookName string `gorm:"size:255" json:"playbook_name"`
|
||||
Status string `gorm:"size:20;default:pending" json:"status"` // pending/running/success/failed
|
||||
TargetHosts string `gorm:"type:text" json:"target_hosts"` // JSON 数组
|
||||
Variables string `gorm:"type:text" json:"variables"` // JSON
|
||||
Output string `gorm:"type:text" json:"output"`
|
||||
Duration int64 `gorm:"default:0" json:"duration"` // 毫秒
|
||||
TriggeredBy string `gorm:"size:255" json:"triggered_by"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
CompletedAt *time.Time `json:"completed_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (AnsibleJob) TableName() string { return "ops_ansible_jobs" }
|
||||
|
||||
// AnsibleInventory 主机清单 // Logan.Li
|
||||
type AnsibleInventory struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:255;not null" json:"name"`
|
||||
Description string `gorm:"type:text" json:"description"`
|
||||
Hosts string `gorm:"type:text" json:"hosts"` // JSON 数组 [{name,ip,port,user,os}]
|
||||
CreatedBy string `gorm:"size:255" json:"created_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (AnsibleInventory) TableName() string { return "ops_ansible_inventories" }
|
||||
|
||||
// LogSource 日志源 // Logan.Li
|
||||
type LogSource struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:255;not null" json:"name"`
|
||||
Type string `gorm:"size:50;not null" json:"type"` // application/syslog/docker/kubernetes
|
||||
Status string `gorm:"size:20;default:active" json:"status"`
|
||||
Config string `gorm:"type:text" json:"config"` // JSON {path/pattern}
|
||||
LogCount int64 `gorm:"default:0" json:"log_count"`
|
||||
LastSeen *time.Time `json:"last_seen"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (LogSource) TableName() string { return "sys_log_sources" }
|
||||
|
||||
// LogEntry 日志条目 // Logan.Li
|
||||
type LogEntry struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
SourceID uint `gorm:"index" json:"source_id"`
|
||||
Timestamp time.Time `gorm:"index" json:"timestamp"`
|
||||
Level string `gorm:"size:20;index" json:"level"` // error/warn/info/debug
|
||||
Service string `gorm:"size:255;index" json:"service"`
|
||||
Host string `gorm:"size:255;index" json:"host"`
|
||||
Message string `gorm:"type:text" json:"message"`
|
||||
TraceID string `gorm:"size:100;index" json:"trace_id"`
|
||||
Raw string `gorm:"type:text" json:"raw"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (LogEntry) TableName() string { return "sys_log_entries" }
|
||||
@@ -0,0 +1,117 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// PrometheusDataSource Prometheus 数据源配置(参考 Grafana 界面设计) // Logan.Li
|
||||
type PrometheusDataSource struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
Name string `gorm:"type:varchar(128);not null;uniqueIndex;comment:数据源名称" json:"name"`
|
||||
URL string `gorm:"type:varchar(512);not null;comment:Prometheus 服务地址" json:"url"`
|
||||
Access string `gorm:"type:varchar(16);default:'server';comment:访问模式: server/proxy" json:"access"`
|
||||
|
||||
// Basic Auth
|
||||
BasicAuth bool `gorm:"default:false;comment:启用基础认证" json:"basic_auth"`
|
||||
BasicAuthUser string `gorm:"type:varchar(128);comment:认证用户名" json:"basic_auth_user,omitempty"`
|
||||
BasicAuthPass string `gorm:"type:varchar(256);comment:认证密码" json:"basic_auth_pass,omitempty"`
|
||||
WithCredentials bool `gorm:"default:false;comment:携带凭证" json:"with_credentials"`
|
||||
|
||||
// TLS Client Auth
|
||||
TLSClientAuth bool `gorm:"default:false;comment:启用TLS客户端认证" json:"tls_client_auth"`
|
||||
WithCACert bool `gorm:"default:false;comment:携带CA证书" json:"with_ca_cert"`
|
||||
CACert string `gorm:"type:text;comment:CA证书内容(PEM)" json:"ca_cert,omitempty"`
|
||||
SkipTLSVerify bool `gorm:"default:false;comment:跳过TLS验证" json:"skip_tls_verify"`
|
||||
|
||||
// Custom HTTP Headers (JSON array of {header, value})
|
||||
CustomHeaders string `gorm:"type:text;comment:自定义HTTP头(JSON)" json:"custom_headers,omitempty"`
|
||||
|
||||
// Alerting
|
||||
EnableAlerting bool `gorm:"default:true;comment:启用告警管理" json:"enable_alerting"`
|
||||
AlertmanagerDS string `gorm:"type:varchar(128);comment:Alertmanager数据源" json:"alertmanager_ds,omitempty"`
|
||||
|
||||
// 采集与查询
|
||||
ScrapeInterval int `gorm:"default:15;comment:采集间隔(秒)" json:"scrape_interval"`
|
||||
QueryTimeout int `gorm:"default:60;comment:查询超时(秒)" json:"query_timeout"`
|
||||
HTTPMethod string `gorm:"type:varchar(8);default:'POST';comment:HTTP方法" json:"http_method"`
|
||||
|
||||
// 杂项
|
||||
DisableMetricsLookup bool `gorm:"default:false;comment:禁用指标查找" json:"disable_metrics_lookup"`
|
||||
CustomQueryParams string `gorm:"type:text;comment:自定义查询参数(JSON)" json:"custom_query_params,omitempty"`
|
||||
|
||||
// 状态
|
||||
IsDefault bool `gorm:"default:false;index;comment:是否默认数据源" json:"is_default"`
|
||||
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
|
||||
|
||||
// 时间戳
|
||||
CreatedAt time.Time `gorm:"not null;index;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 (PrometheusDataSource) TableName() string {
|
||||
return "monitor_prometheus_datasources"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 请求/响应 struct
|
||||
// ============================================
|
||||
|
||||
// CreatePromDSReq 创建数据源请求
|
||||
type CreatePromDSReq struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
URL string `json:"url" binding:"required"`
|
||||
Access string `json:"access"`
|
||||
BasicAuth bool `json:"basic_auth"`
|
||||
BasicAuthUser string `json:"basic_auth_user"`
|
||||
BasicAuthPass string `json:"basic_auth_pass"`
|
||||
WithCredentials bool `json:"with_credentials"`
|
||||
TLSClientAuth bool `json:"tls_client_auth"`
|
||||
WithCACert bool `json:"with_ca_cert"`
|
||||
CACert string `json:"ca_cert"`
|
||||
SkipTLSVerify bool `json:"skip_tls_verify"`
|
||||
CustomHeaders string `json:"custom_headers"`
|
||||
EnableAlerting *bool `json:"enable_alerting"`
|
||||
AlertmanagerDS string `json:"alertmanager_ds"`
|
||||
ScrapeInterval int `json:"scrape_interval"`
|
||||
QueryTimeout int `json:"query_timeout"`
|
||||
HTTPMethod string `json:"http_method"`
|
||||
DisableMetricsLookup bool `json:"disable_metrics_lookup"`
|
||||
CustomQueryParams string `json:"custom_query_params"`
|
||||
IsDefault bool `json:"is_default"`
|
||||
}
|
||||
|
||||
// UpdatePromDSReq 更新数据源请求
|
||||
type UpdatePromDSReq struct {
|
||||
Name *string `json:"name"`
|
||||
URL *string `json:"url"`
|
||||
Access *string `json:"access"`
|
||||
BasicAuth *bool `json:"basic_auth"`
|
||||
BasicAuthUser *string `json:"basic_auth_user"`
|
||||
BasicAuthPass *string `json:"basic_auth_pass"`
|
||||
WithCredentials *bool `json:"with_credentials"`
|
||||
TLSClientAuth *bool `json:"tls_client_auth"`
|
||||
WithCACert *bool `json:"with_ca_cert"`
|
||||
CACert *string `json:"ca_cert"`
|
||||
SkipTLSVerify *bool `json:"skip_tls_verify"`
|
||||
CustomHeaders *string `json:"custom_headers"`
|
||||
EnableAlerting *bool `json:"enable_alerting"`
|
||||
AlertmanagerDS *string `json:"alertmanager_ds"`
|
||||
ScrapeInterval *int `json:"scrape_interval"`
|
||||
QueryTimeout *int `json:"query_timeout"`
|
||||
HTTPMethod *string `json:"http_method"`
|
||||
DisableMetricsLookup *bool `json:"disable_metrics_lookup"`
|
||||
CustomQueryParams *string `json:"custom_query_params"`
|
||||
IsDefault *bool `json:"is_default"`
|
||||
Status *int `json:"status"`
|
||||
}
|
||||
|
||||
// TestPromDSReq 测试数据源连接请求
|
||||
type TestPromDSReq struct {
|
||||
URL string `json:"url" binding:"required"`
|
||||
BasicAuth bool `json:"basic_auth"`
|
||||
BasicAuthUser string `json:"basic_auth_user"`
|
||||
BasicAuthPass string `json:"basic_auth_pass"`
|
||||
SkipTLSVerify bool `json:"skip_tls_verify"`
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
// ResourceModel 资源模型 (CMDB 模型定义)
|
||||
type ResourceModel 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"`
|
||||
Description string `gorm:"size:500" json:"description"`
|
||||
Type string `gorm:"size:32;default:normal" json:"type"` // normal, parent
|
||||
Attributes string `gorm:"type:text" json:"attributes"` // JSON 数组
|
||||
Icon string `gorm:"size:64" json:"icon"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (ResourceModel) TableName() string {
|
||||
return "asset_resource_models"
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
// Server 服务器模型
|
||||
type Server struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Hostname string `gorm:"size:128;not null" json:"hostname"`
|
||||
IP string `gorm:"size:64;not null" json:"ip"`
|
||||
PublicIP string `gorm:"size:64" json:"public_ip"`
|
||||
Port int `gorm:"default:22" json:"port"`
|
||||
Username string `gorm:"size:64;default:root" json:"username"`
|
||||
Password string `gorm:"size:255" json:"-"`
|
||||
SSHKey string `gorm:"type:text" json:"-"`
|
||||
AuthType string `gorm:"size:32;default:password" json:"auth_type"` // password, key
|
||||
OS string `gorm:"size:64" json:"os"`
|
||||
Kernel string `gorm:"size:64" json:"kernel"`
|
||||
OSVersion string `gorm:"size:64" json:"os_version"`
|
||||
Arch string `gorm:"size:32" json:"arch"`
|
||||
CPU int `json:"cpu"`
|
||||
Memory int64 `json:"memory"` // MB
|
||||
Disk int64 `json:"disk"` // GB
|
||||
Status string `gorm:"size:32;default:stopped" json:"status"` // running, stopped, maintenance, error
|
||||
CPUUsage float64 `json:"cpu_usage"`
|
||||
MemoryUsage float64 `json:"memory_usage"`
|
||||
DiskUsage float64 `json:"disk_usage"`
|
||||
Uptime int64 `json:"uptime"` // seconds
|
||||
AgentVersion string `gorm:"size:32" json:"agent_version"`
|
||||
AgentStatus string `gorm:"size:32;default:offline" json:"agent_status"` // online, offline
|
||||
HasAuth bool `gorm:"-" json:"has_auth"` // 是否有认证凭据(密码或SSH密钥) — 不存DB,handler 计算后返回 // Logan.Li
|
||||
RegionID *uint `json:"region_id"`
|
||||
CloudID *uint `json:"cloud_id"`
|
||||
Tags string `gorm:"type:text" json:"tags"` // JSON
|
||||
Description string `gorm:"size:500" json:"description"`
|
||||
LastCheckAt *time.Time `json:"last_check_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Region *Region `json:"region,omitempty"`
|
||||
Cloud *Cloud `json:"cloud,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (Server) TableName() string {
|
||||
return "asset_servers"
|
||||
}
|
||||
|
||||
// Cloud 云平台模型
|
||||
type Cloud 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"`
|
||||
Type string `gorm:"size:32;default:public" json:"type"` // public, private, hybrid
|
||||
Status string `gorm:"size:32;default:active" json:"status"`
|
||||
Website string `gorm:"size:255" json:"website"`
|
||||
Description string `gorm:"size:500" json:"description"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (Cloud) TableName() string {
|
||||
return "asset_clouds"
|
||||
}
|
||||
|
||||
// CloudAccount 云账号模型
|
||||
type CloudAccount struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:128;not null" json:"name"`
|
||||
Provider string `gorm:"size:64;not null" json:"provider"` // aws, aliyun, tencent, huawei, azure
|
||||
AccessKey string `gorm:"size:255;not null" json:"-"`
|
||||
SecretKey string `gorm:"size:255;not null" json:"-"`
|
||||
Status string `gorm:"size:32;default:active" json:"status"` // active, inactive, error
|
||||
RegionCount int `gorm:"default:0" json:"region_count"`
|
||||
ServerCount int `gorm:"default:0" json:"server_count"`
|
||||
MonthlyCost float64 `gorm:"default:0" json:"monthly_cost"` // 月费用(元),驱动仪表盘成本统计
|
||||
LastSyncAt *time.Time `json:"last_sync_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (CloudAccount) TableName() string {
|
||||
return "asset_cloud_accounts"
|
||||
}
|
||||
|
||||
// Region 区域模型
|
||||
type Region 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"`
|
||||
Provider string `gorm:"size:64;not null" json:"provider"`
|
||||
Location string `gorm:"size:128" json:"location"`
|
||||
Status string `gorm:"size:32;default:active" json:"status"`
|
||||
Endpoint string `gorm:"size:255" json:"endpoint"`
|
||||
VPCCount int `gorm:"default:0" json:"vpc_count"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (Region) TableName() string {
|
||||
return "asset_regions"
|
||||
}
|
||||
|
||||
// Domain 域名模型
|
||||
type Domain struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:255;uniqueIndex;not null" json:"name"`
|
||||
Registrar string `gorm:"size:128" json:"registrar"`
|
||||
Status string `gorm:"size:32;default:active" json:"status"` // active, expired, pending
|
||||
ExpireDate *time.Time `json:"expire_date"`
|
||||
DNSProvider string `gorm:"size:128" json:"dns_provider"`
|
||||
RecordCount int `gorm:"default:0" json:"record_count"`
|
||||
SSLEnabled bool `gorm:"default:false" json:"ssl_enabled"`
|
||||
SSLExpireDate *time.Time `json:"ssl_expire_date"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (Domain) TableName() string {
|
||||
return "asset_domains"
|
||||
}
|
||||
|
||||
// CreateServerRequest 创建服务器请求
|
||||
type CreateServerRequest struct {
|
||||
Hostname string `json:"hostname" binding:"required"`
|
||||
IP string `json:"ip" binding:"required,ip"`
|
||||
PublicIP string `json:"public_ip" binding:"omitempty,ip"`
|
||||
Port int `json:"port" binding:"omitempty,min=1,max=65535"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
SSHKey string `json:"ssh_key"`
|
||||
AuthType string `json:"auth_type" binding:"omitempty,oneof=password key"`
|
||||
OS string `json:"os"`
|
||||
CPU int `json:"cpu"`
|
||||
Memory int64 `json:"memory"`
|
||||
Disk int64 `json:"disk"`
|
||||
Status string `json:"status" binding:"omitempty,oneof=running stopped maintenance error"`
|
||||
RegionID *uint `json:"region_id"`
|
||||
CloudID *uint `json:"cloud_id"`
|
||||
Tags string `json:"tags"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// UpdateServerRequest 更新服务器请求
|
||||
type UpdateServerRequest struct {
|
||||
Hostname string `json:"hostname"`
|
||||
IP string `json:"ip" binding:"omitempty,ip"`
|
||||
PublicIP string `json:"public_ip" binding:"omitempty,ip"`
|
||||
Port int `json:"port" binding:"omitempty,min=1,max=65535"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
SSHKey string `json:"ssh_key"`
|
||||
AuthType string `json:"auth_type" binding:"omitempty,oneof=password key"`
|
||||
OS string `json:"os"`
|
||||
CPU int `json:"cpu"`
|
||||
Memory int64 `json:"memory"`
|
||||
Disk int64 `json:"disk"`
|
||||
Status string `json:"status" binding:"omitempty,oneof=running stopped maintenance error"`
|
||||
RegionID *uint `json:"region_id"`
|
||||
CloudID *uint `json:"cloud_id"`
|
||||
Tags string `json:"tags"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// BatchServerItem 批量导入单条服务器 // Logan.Li
|
||||
type BatchServerItem struct {
|
||||
Hostname string `json:"hostname"`
|
||||
IP string `json:"ip"`
|
||||
Port int `json:"port"`
|
||||
Username string `json:"username"`
|
||||
OS string `json:"os"`
|
||||
CPU int `json:"cpu"`
|
||||
Memory int64 `json:"memory"` // GB(后端转 MB 存储)
|
||||
Disk int64 `json:"disk"` // GB
|
||||
Tags string `json:"tags"`
|
||||
}
|
||||
|
||||
// BatchCreateServerRequest 批量导入服务器请求 // Logan.Li
|
||||
type BatchCreateServerRequest struct {
|
||||
Servers []BatchServerItem `json:"servers"`
|
||||
RegionID *uint `json:"region_id"`
|
||||
AuthType string `json:"auth_type"`
|
||||
CredentialID *uint `json:"credential_id"` // 凭据ID,非空则解密后写入每台服务器
|
||||
}
|
||||
|
||||
// BatchCreateResult 批量导入结果 // Logan.Li
|
||||
type BatchCreateResult struct {
|
||||
Success int `json:"success"`
|
||||
Skipped int `json:"skipped"`
|
||||
Failed int `json:"failed"`
|
||||
Errors []string `json:"errors"`
|
||||
}
|
||||
|
||||
// ServerListResponse 服务器列表响应
|
||||
type ServerListResponse struct {
|
||||
List []Server `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
// ServerStats 服务器统计
|
||||
type ServerStats struct {
|
||||
Total int64 `json:"total"`
|
||||
Running int64 `json:"running"`
|
||||
Stopped int64 `json:"stopped"`
|
||||
Maintenance int64 `json:"maintenance"`
|
||||
Error int64 `json:"error"`
|
||||
AvgCPU float64 `json:"avg_cpu"`
|
||||
AvgMemory float64 `json:"avg_memory"`
|
||||
AvgDisk float64 `json:"avg_disk"`
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// SessionCommand 会话命令记录(JumpServer 式命令审计) // Logan.Li
|
||||
type SessionCommand struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
SessionID uint `gorm:"index" json:"session_id"` // 关联终端会话
|
||||
UserID *uint `json:"user_id"`
|
||||
Username string `gorm:"size:64" json:"username"`
|
||||
ServerID uint `json:"server_id"`
|
||||
ServerName string `gorm:"size:128" json:"server_name"`
|
||||
Command string `gorm:"type:text" json:"command"` // 执行的原始命令
|
||||
Timestamp time.Time `json:"timestamp"` // 命令执行时间
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (SessionCommand) TableName() string {
|
||||
return "sys_session_commands"
|
||||
}
|
||||
|
||||
// SessionCommandQuery 会话命令查询
|
||||
type SessionCommandQuery struct {
|
||||
SessionID uint `form:"session_id"`
|
||||
Username string `form:"username"`
|
||||
ServerID uint `form:"server_id"`
|
||||
Command string `form:"command"`
|
||||
Page int `form:"page,default=1"`
|
||||
PageSize int `form:"page_size,default=20"`
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// ============================================
|
||||
// SiteTask 拨测任务
|
||||
// ============================================
|
||||
|
||||
// SiteTaskType 拨测任务类型
|
||||
type SiteTaskType string
|
||||
|
||||
const (
|
||||
SiteTaskTypeHTTP SiteTaskType = "http" // HTTP/HTTPS拨测
|
||||
SiteTaskTypeTCP SiteTaskType = "tcp" // TCP拨测
|
||||
SiteTaskTypePing SiteTaskType = "ping" // ICMP Ping拨测
|
||||
SiteTaskTypeDNS SiteTaskType = "dns" // DNS拨测
|
||||
SiteTaskTypeUDP SiteTaskType = "udp" // UDP拨测
|
||||
SiteTaskTypeFTP SiteTaskType = "ftp" // FTP拨测
|
||||
SiteTaskTypeSMTP SiteTaskType = "smtp" // SMTP拨测
|
||||
SiteTaskTypeTraceroute SiteTaskType = "traceroute" // 路由追踪
|
||||
)
|
||||
|
||||
// SiteTaskMethod HTTP请求方法
|
||||
type SiteTaskMethod string
|
||||
|
||||
const (
|
||||
SiteTaskMethodGET SiteTaskMethod = "GET"
|
||||
SiteTaskMethodPOST SiteTaskMethod = "POST"
|
||||
SiteTaskMethodHEAD SiteTaskMethod = "HEAD"
|
||||
)
|
||||
|
||||
// SiteTaskStatus 拨测任务状态
|
||||
type SiteTaskStatus string
|
||||
|
||||
const (
|
||||
SiteTaskStatusRunning SiteTaskStatus = "running" // 运行中
|
||||
SiteTaskStatusPaused SiteTaskStatus = "paused" // 已暂停
|
||||
SiteTaskStatusError SiteTaskStatus = "error" // 异常
|
||||
)
|
||||
|
||||
// SiteTask 站点拨测任务表
|
||||
// 定义对网站、服务等进行主动拨测的任务配置
|
||||
type SiteTask struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
Name string `gorm:"type:varchar(128);not null;comment:任务名称" json:"name"`
|
||||
URL string `gorm:"type:varchar(512);not null;comment:拨测URL/地址" json:"url"`
|
||||
TaskType SiteTaskType `gorm:"type:varchar(16);not null;comment:拨测类型" json:"task_type"`
|
||||
Method SiteTaskMethod `gorm:"type:varchar(8);default:'GET';comment:HTTP方法" json:"method"`
|
||||
// HTTP 拨测配置
|
||||
Headers string `gorm:"type:text;comment:请求头JSON" json:"headers,omitempty"`
|
||||
Body string `gorm:"type:text;comment:请求体" json:"body,omitempty"`
|
||||
Timeout int `gorm:"default:10;comment:超时时间(秒)" json:"timeout"`
|
||||
FollowRedirect bool `gorm:"default:true;comment:是否跟随重定向" json:"follow_redirect"`
|
||||
VerifySSL bool `gorm:"default:true;comment:是否验证SSL证书" json:"verify_ssl"`
|
||||
// 期望响应配置
|
||||
ExpectedStatus int `gorm:"default:200;comment:期望状态码" json:"expected_status"`
|
||||
ExpectedContent string `gorm:"type:text;comment:期望响应内容(支持正则)" json:"expected_content,omitempty"`
|
||||
ExpectedLength int `gorm:"default:0;comment:期望响应长度(0表示不检查)" json:"expected_length"`
|
||||
// 执行配置
|
||||
Frequency int `gorm:"default:60;comment:拨测频率(秒)" json:"frequency"`
|
||||
Nodes string `gorm:"type:varchar(256);comment:执行节点列表JSON" json:"nodes,omitempty"`
|
||||
// DNS 配置
|
||||
DNSResolver string `gorm:"type:varchar(64);comment:DNS解析服务器" json:"dns_resolver,omitempty"`
|
||||
// 状态
|
||||
Status SiteTaskStatus `gorm:"type:varchar(16);default:'running';comment:任务状态" json:"status"`
|
||||
LastResult string `gorm:"type:varchar(16);comment:最近结果: success/fail" json:"last_result,omitempty"`
|
||||
LastCheckAt *time.Time `gorm:"comment:最近检查时间" json:"last_check_at,omitempty"`
|
||||
SuccessRate float64 `gorm:"type:decimal(5,2);default:100.00;comment:成功率(%)" json:"success_rate"`
|
||||
AvgResponse float64 `gorm:"comment:平均响应时间(ms)" json:"avg_response,omitempty"`
|
||||
Description string `gorm:"type:varchar(256);comment:描述" json:"description,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"`
|
||||
|
||||
// 关联关系
|
||||
Results []SiteResult `gorm:"foreignKey:TaskID" json:"results,omitempty"`
|
||||
Alerts []SiteAlert `gorm:"foreignKey:TaskID" json:"alerts,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SiteTask) TableName() string {
|
||||
return "ops_site_tasks"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// SiteResult 拨测结果
|
||||
// ============================================
|
||||
|
||||
// SiteResultStatus 拨测结果状态
|
||||
type SiteResultStatus string
|
||||
|
||||
const (
|
||||
SiteResultSuccess SiteResultStatus = "success" // 成功
|
||||
SiteResultFail SiteResultStatus = "fail" // 失败
|
||||
SiteResultTimeout SiteResultStatus = "timeout" // 超时
|
||||
)
|
||||
|
||||
// SiteResult 拨测结果表
|
||||
// 存储每次拨测的详细结果数据
|
||||
type SiteResult struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
TaskID uint `gorm:"not null;index:idx_task_time;comment:任务ID" json:"task_id"`
|
||||
Status SiteResultStatus `gorm:"type:varchar(16);not null;comment:结果状态" json:"status"`
|
||||
HTTPStatusCode int `gorm:"comment:HTTP状态码" json:"http_status_code,omitempty"`
|
||||
// 时间指标
|
||||
DNSTime float64 `gorm:"comment:DNS解析时间(ms)" json:"dns_time,omitempty"`
|
||||
ConnectTime float64 `gorm:"comment:连接时间(ms)" json:"connect_time,omitempty"`
|
||||
TLSTime float64 `gorm:"comment:TLS握手时间(ms)" json:"tls_time,omitempty"`
|
||||
TTFB float64 `gorm:"comment:首字节时间(ms)" json:"ttfb,omitempty"`
|
||||
ResponseTime float64 `gorm:"comment:响应时间(ms)" json:"response_time,omitempty"`
|
||||
TotalTime float64 `gorm:"not null;comment:总耗时(ms)" json:"total_time"`
|
||||
// 响应信息
|
||||
ResponseSize int `gorm:"comment:响应大小(bytes)" json:"response_size,omitempty"`
|
||||
ResponseBody string `gorm:"type:text;comment:响应内容摘要" json:"response_body,omitempty"`
|
||||
// 网络信息
|
||||
RemoteIP string `gorm:"type:varchar(64);comment:远端IP" json:"remote_ip,omitempty"`
|
||||
LocalNode string `gorm:"type:varchar(64);comment:执行节点" json:"local_node,omitempty"`
|
||||
// 错误信息
|
||||
ErrorMessage string `gorm:"type:text;comment:错误信息" json:"error_message,omitempty"`
|
||||
ErrorDetail string `gorm:"type:text;comment:错误详情" json:"error_detail,omitempty"`
|
||||
// SSL 证书信息
|
||||
SSLCertExpiry *time.Time `gorm:"comment:SSL证书过期时间" json:"ssl_cert_expiry,omitempty"`
|
||||
SSLCertIssuer string `gorm:"type:varchar(256);comment:SSL证书签发者" json:"ssl_cert_issuer,omitempty"`
|
||||
SSLCertSubject string `gorm:"type:varchar(256);comment:SSL证书主题" json:"ssl_cert_subject,omitempty"`
|
||||
SSLDaysRemaining int `gorm:"comment:SSL证书剩余天数" json:"ssl_days_remaining,omitempty"`
|
||||
// 检查内容匹配
|
||||
ContentMatch bool `gorm:"comment:内容匹配结果" json:"content_match,omitempty"`
|
||||
// 时间戳
|
||||
CheckedAt time.Time `gorm:"not null;index:idx_task_time;comment:拨测时间" json:"checked_at"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
|
||||
// 关联关系
|
||||
Task *SiteTask `gorm:"foreignKey:TaskID" json:"task,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SiteResult) TableName() string {
|
||||
return "ops_site_results"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// SiteAlert 拨测告警
|
||||
// ============================================
|
||||
|
||||
// SiteAlertStatus 拨测告警状态
|
||||
type SiteAlertStatus string
|
||||
|
||||
const (
|
||||
SiteAlertStatusActive SiteAlertStatus = "active" // 活跃
|
||||
SiteAlertStatusResolved SiteAlertStatus = "resolved" // 已恢复
|
||||
SiteAlertStatusMuted SiteAlertStatus = "muted" // 已静默
|
||||
)
|
||||
|
||||
// SiteAlertSeverity 拨测告警级别
|
||||
type SiteAlertSeverity string
|
||||
|
||||
const (
|
||||
SiteAlertCritical SiteAlertSeverity = "critical" // 严重
|
||||
SiteAlertWarning SiteAlertSeverity = "warning" // 警告
|
||||
SiteAlertInfo SiteAlertSeverity = "info" // 通知
|
||||
)
|
||||
|
||||
// SiteAlert 拨测告警表
|
||||
// 记录拨测任务触发的告警事件
|
||||
type SiteAlert struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
TaskID uint `gorm:"not null;index;comment:任务ID" json:"task_id"`
|
||||
Severity SiteAlertSeverity `gorm:"type:varchar(16);not null;comment:告警级别" json:"severity"`
|
||||
Status SiteAlertStatus `gorm:"type:varchar(16);default:'active';index;comment:告警状态" json:"status"`
|
||||
Title string `gorm:"type:varchar(256);not null;comment:告警标题" json:"title"`
|
||||
Message string `gorm:"type:text;comment:告警详情" json:"message,omitempty"`
|
||||
// 触发条件
|
||||
TriggerType string `gorm:"type:varchar(32);comment:触发类型: timeout/status_error/response_time/ssl_expiry" json:"trigger_type"`
|
||||
TriggerValue string `gorm:"type:varchar(128);comment:触发值" json:"trigger_value,omitempty"`
|
||||
Threshold float64 `gorm:"comment:阈值" json:"threshold,omitempty"`
|
||||
// 响应信息
|
||||
ResponseTime float64 `gorm:"comment:响应时间(ms)" json:"response_time,omitempty"`
|
||||
HTTPStatus int `gorm:"comment:HTTP状态码" json:"http_status,omitempty"`
|
||||
ErrorMessage string `gorm:"type:text;comment:错误信息" json:"error_message,omitempty"`
|
||||
// 状态变化
|
||||
StartedAt time.Time `gorm:"not null;comment:告警开始时间" json:"started_at"`
|
||||
ResolvedAt *time.Time `gorm:"comment:告警恢复时间" json:"resolved_at,omitempty"`
|
||||
Duration int `gorm:"comment:持续时间(秒)" json:"duration,omitempty"`
|
||||
NotifyCount int `gorm:"default:0;comment:通知次数" json:"notify_count"`
|
||||
LastNotifyAt *time.Time `gorm:"comment:最近通知时间" json:"last_notify_at,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"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
||||
|
||||
// 关联关系
|
||||
Task *SiteTask `gorm:"foreignKey:TaskID" json:"task,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SiteAlert) TableName() string {
|
||||
return "ops_site_alerts"
|
||||
}
|
||||
|
||||
// SiteTaskCreateRequest 拨测任务创建请求
|
||||
type SiteTaskCreateRequest struct {
|
||||
Name string `json:"name" binding:"required,max=128"`
|
||||
URL string `json:"url" binding:"required,max=512,url"`
|
||||
TaskType SiteTaskType `json:"task_type" binding:"required"`
|
||||
Method SiteTaskMethod `json:"method"`
|
||||
Headers string `json:"headers"`
|
||||
Body string `json:"body"`
|
||||
Timeout int `json:"timeout"`
|
||||
FollowRedirect bool `json:"follow_redirect"`
|
||||
VerifySSL bool `json:"verify_ssl"`
|
||||
ExpectedStatus int `json:"expected_status"`
|
||||
ExpectedContent string `json:"expected_content"`
|
||||
ExpectedLength int `json:"expected_length"`
|
||||
Frequency int `json:"frequency"`
|
||||
Nodes []string `json:"nodes"`
|
||||
DNSResolver string `json:"dns_resolver"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// SiteTaskUpdateRequest 拨测任务更新请求
|
||||
type SiteTaskUpdateRequest struct {
|
||||
Name string `json:"name" binding:"max=128"`
|
||||
URL string `json:"url" binding:"max=512,url"`
|
||||
Method SiteTaskMethod `json:"method"`
|
||||
Headers string `json:"headers"`
|
||||
Body string `json:"body"`
|
||||
Timeout int `json:"timeout"`
|
||||
FollowRedirect bool `json:"follow_redirect"`
|
||||
VerifySSL bool `json:"verify_ssl"`
|
||||
ExpectedStatus int `json:"expected_status"`
|
||||
ExpectedContent string `json:"expected_content"`
|
||||
Frequency int `json:"frequency"`
|
||||
Nodes []string `json:"nodes"`
|
||||
Status SiteTaskStatus `json:"status"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// SiteTaskStatistics 拨测任务统计
|
||||
type SiteTaskStatistics struct {
|
||||
TaskID uint `json:"task_id"`
|
||||
TotalChecks int64 `json:"total_checks"`
|
||||
SuccessCount int64 `json:"success_count"`
|
||||
FailCount int64 `json:"fail_count"`
|
||||
TimeoutCount int64 `json:"timeout_count"`
|
||||
SuccessRate float64 `json:"success_rate"`
|
||||
AvgResponseTime float64 `json:"avg_response_time"`
|
||||
MinResponseTime float64 `json:"min_response_time"`
|
||||
MaxResponseTime float64 `json:"max_response_time"`
|
||||
Last24hUptime float64 `json:"last_24h_uptime"`
|
||||
Last7dUptime float64 `json:"last_7d_uptime"`
|
||||
Last30dUptime float64 `json:"last_30d_uptime"`
|
||||
}
|
||||
|
||||
// SiteResultQuery 拨测结果查询参数
|
||||
type SiteResultQuery struct {
|
||||
TaskID uint `json:"task_id" form:"task_id"`
|
||||
Status string `json:"status" form:"status"`
|
||||
StartTime int64 `json:"start_time" form:"start_time"`
|
||||
EndTime int64 `json:"end_time" form:"end_time"`
|
||||
Limit int `json:"limit" form:"limit"`
|
||||
Offset int `json:"offset" form:"offset"`
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// ============================================
|
||||
// SNMPDevice SNMP设备
|
||||
// ============================================
|
||||
|
||||
// SNMPVersion SNMP协议版本
|
||||
type SNMPVersion string
|
||||
|
||||
const (
|
||||
SNMPVersionV1 SNMPVersion = "v1" // SNMP v1
|
||||
SNMPVersionV2c SNMPVersion = "v2c" // SNMP v2c
|
||||
SNMPVersionV3 SNMPVersion = "v3" // SNMP v3
|
||||
)
|
||||
|
||||
// SNMPAuthProtocol SNMP v3 认证协议
|
||||
type SNMPAuthProtocol string
|
||||
|
||||
const (
|
||||
SNMPAuthMD5 SNMPAuthProtocol = "MD5" // MD5认证
|
||||
SNMPAuthSHA SNMPAuthProtocol = "SHA" // SHA认证
|
||||
SNMPAuthSHAAES SNMPAuthProtocol = "SHA-AES" // SHA+AES
|
||||
)
|
||||
|
||||
// SNMPPrivProtocol SNMP v3 加密协议
|
||||
type SNMPPrivProtocol string
|
||||
|
||||
const (
|
||||
SNMPPrivDES SNMPPrivProtocol = "DES" // DES加密
|
||||
SNMPPrivAES SNMPPrivProtocol = "AES" // AES加密
|
||||
SNMPPrivAES256 SNMPPrivProtocol = "AES256" // AES256加密
|
||||
)
|
||||
|
||||
// SNMPDeviceStatus SNMP设备状态
|
||||
type SNMPDeviceStatus string
|
||||
|
||||
const (
|
||||
SNMPDeviceOnline SNMPDeviceStatus = "online" // 在线
|
||||
SNMPDeviceOffline SNMPDeviceStatus = "offline" // 离线
|
||||
SNMPDeviceError SNMPDeviceStatus = "error" // 错误
|
||||
)
|
||||
|
||||
// SNMPDevice SNMP设备表
|
||||
// 存储通过SNMP协议监控的网络设备信息
|
||||
type SNMPDevice struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
Name string `gorm:"type:varchar(128);not null;comment:设备名称" json:"name"`
|
||||
IP string `gorm:"type:varchar(64);not null;index;comment:设备IP地址" json:"ip"`
|
||||
Port int `gorm:"default:161;comment:SNMP端口" json:"port"`
|
||||
Version SNMPVersion `gorm:"type:varchar(4);default:'v2c';comment:SNMP版本: v1/v2c/v3" json:"version"`
|
||||
Community string `gorm:"type:varchar(64);comment:共同体字符串(v1/v2c)" json:"community,omitempty"`
|
||||
// SNMP v3 安全参数
|
||||
Username string `gorm:"type:varchar(64);comment:v3用户名" json:"username,omitempty"`
|
||||
AuthProtocol SNMPAuthProtocol `gorm:"type:varchar(16);comment:v3认证协议" json:"auth_protocol,omitempty"`
|
||||
AuthPassword string `gorm:"type:varchar(128);comment:v3认证密码" json:"auth_password,omitempty"`
|
||||
PrivProtocol SNMPPrivProtocol `gorm:"type:varchar(16);comment:v3加密协议" json:"priv_protocol,omitempty"`
|
||||
PrivPassword string `gorm:"type:varchar(128);comment:v3加密密码" json:"priv_password,omitempty"`
|
||||
SecurityLevel string `gorm:"type:varchar(16);comment:v3安全级别: noAuthNoPriv/authNoPriv/authPriv" json:"security_level,omitempty"`
|
||||
// 设备信息
|
||||
DeviceType string `gorm:"type:varchar(64);comment:设备类型: switch/router/firewall/printer/server" json:"device_type"`
|
||||
Vendor string `gorm:"type:varchar(64);comment:厂商" json:"vendor,omitempty"`
|
||||
Model string `gorm:"type:varchar(64);comment:型号" json:"model,omitempty"`
|
||||
SysDescr string `gorm:"type:text;comment:系统描述" json:"sys_descr,omitempty"`
|
||||
SysObjectID string `gorm:"type:varchar(128);comment:系统OID" json:"sys_object_id,omitempty"`
|
||||
SysUptime uint64 `gorm:"comment:系统运行时间(百分之一秒)" json:"sys_uptime,omitempty"`
|
||||
SysContact string `gorm:"type:varchar(128);comment:系统联系人" json:"sys_contact,omitempty"`
|
||||
SysName string `gorm:"type:varchar(128);comment:系统名称" json:"sys_name,omitempty"`
|
||||
SysLocation string `gorm:"type:varchar(128);comment:系统位置" json:"sys_location,omitempty"`
|
||||
// 采集配置
|
||||
TemplateID uint `gorm:"index;comment:OID模板ID" json:"template_id,omitempty"`
|
||||
CollectInterval int `gorm:"default:300;comment:采集间隔(秒)" json:"collect_interval"`
|
||||
Timeout int `gorm:"default:10;comment:超时时间(秒)" json:"timeout"`
|
||||
Retries int `gorm:"default:3;comment:重试次数" json:"retries"`
|
||||
MaxRepetitions uint32 `gorm:"default:25;comment:BulkWalk最大重复数" json:"max_repetitions"`
|
||||
// 状态
|
||||
Status SNMPDeviceStatus `gorm:"type:varchar(16);default:'offline';index;comment:状态" json:"status"`
|
||||
LastCollectAt *time.Time `gorm:"comment:最后采集时间" json:"last_collect_at,omitempty"`
|
||||
LastError string `gorm:"type:text;comment:最后错误信息" json:"last_error,omitempty"`
|
||||
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
|
||||
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"`
|
||||
|
||||
// 关联关系
|
||||
Template *SNMPTemplate `gorm:"foreignKey:TemplateID" json:"template,omitempty"`
|
||||
Metrics []SNMPMetric `gorm:"foreignKey:DeviceID" json:"metrics,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SNMPDevice) TableName() string {
|
||||
return "ops_snmp_devices"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// SNMPTemplate OID模板
|
||||
// ============================================
|
||||
|
||||
// SNMPTemplate OID模板表
|
||||
// 预定义的OID模板,用于快速配置同类设备的监控
|
||||
type SNMPTemplate 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"`
|
||||
DeviceType string `gorm:"type:varchar(64);comment:适用设备类型" json:"device_type,omitempty"`
|
||||
Vendor string `gorm:"type:varchar(64);comment:适用厂商" json:"vendor,omitempty"`
|
||||
IsDefault bool `gorm:"default:false;comment:是否默认模板" json:"is_default"`
|
||||
IsSystem bool `gorm:"default:false;comment:是否系统模板" json:"is_system"`
|
||||
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
|
||||
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"`
|
||||
|
||||
// 关联关系
|
||||
OIDs []SNMPTemplateOID `gorm:"foreignKey:TemplateID" json:"oids,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SNMPTemplate) TableName() string {
|
||||
return "ops_snmp_templates"
|
||||
}
|
||||
|
||||
// SNMPTemplateOID OID模板条目表
|
||||
// 模板中具体的OID定义
|
||||
type SNMPTemplateOID struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
TemplateID uint `gorm:"not null;index;comment:模板ID" json:"template_id"`
|
||||
Name string `gorm:"type:varchar(64);not null;comment:OID名称" json:"name"`
|
||||
OID string `gorm:"type:varchar(256);not null;comment:OID字符串" json:"oid"`
|
||||
Description string `gorm:"type:varchar(128);comment:描述" json:"description,omitempty"`
|
||||
DataType string `gorm:"type:varchar(16);comment:数据类型: integer/counter/gauge/string" json:"data_type"`
|
||||
Unit string `gorm:"type:varchar(32);comment:单位" json:"unit,omitempty"`
|
||||
IsIndex bool `gorm:"default:false;comment:是否索引OID" json:"is_index"`
|
||||
Conversion string `gorm:"type:varchar(64);comment:转换公式" json:"conversion,omitempty"`
|
||||
SortOrder int `gorm:"default:0;comment:排序" json:"sort_order"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SNMPTemplateOID) TableName() string {
|
||||
return "ops_snmp_template_oids"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// SNMPMetric SNMP采集指标
|
||||
// ============================================
|
||||
|
||||
// SNMPMetric SNMP采集指标表
|
||||
// 存储从SNMP设备采集到的指标数据
|
||||
type SNMPMetric struct {
|
||||
ID uint64 `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
DeviceID uint `gorm:"not null;index:idx_device_metric;comment:设备ID" json:"device_id"`
|
||||
Name string `gorm:"type:varchar(64);not null;index;comment:指标名称" json:"name"`
|
||||
OID string `gorm:"type:varchar(256);not null;comment:OID" json:"oid"`
|
||||
Index string `gorm:"type:varchar(128);index;comment:索引值(如接口名)" json:"index,omitempty"`
|
||||
Value float64 `gorm:"comment:数值" json:"value"`
|
||||
RawValue string `gorm:"type:text;comment:原始字符串值" json:"raw_value,omitempty"`
|
||||
Unit string `gorm:"type:varchar(32);comment:单位" json:"unit,omitempty"`
|
||||
DataType string `gorm:"type:varchar(16);comment:数据类型" json:"data_type"`
|
||||
Timestamp int64 `gorm:"not null;index:idx_device_metric;comment:采集时间戳" json:"timestamp"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
|
||||
// 关联关系
|
||||
Device *SNMPDevice `gorm:"foreignKey:DeviceID" json:"device,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SNMPMetric) TableName() string {
|
||||
return "ops_snmp_metrics"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// SNMPInterface 网络接口信息
|
||||
// ============================================
|
||||
|
||||
// SNMPInterface SNMP接口信息表
|
||||
// 存储网络设备的接口详细信息
|
||||
type SNMPInterface struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
DeviceID uint `gorm:"not null;index;comment:设备ID" json:"device_id"`
|
||||
IfIndex int `gorm:"not null;comment:接口索引" json:"if_index"`
|
||||
IfDescr string `gorm:"type:varchar(128);comment:接口描述" json:"if_descr,omitempty"`
|
||||
IfName string `gorm:"type:varchar(64);comment:接口名称" json:"if_name,omitempty"`
|
||||
IfAlias string `gorm:"type:varchar(128);comment:接口别名" json:"if_alias,omitempty"`
|
||||
IfType int `gorm:"comment:接口类型" json:"if_type,omitempty"`
|
||||
IfSpeed uint64 `gorm:"comment:接口速率(bps)" json:"if_speed,omitempty"`
|
||||
IfPhysAddr string `gorm:"type:varchar(32);comment:物理地址(MAC)" json:"if_phys_addr,omitempty"`
|
||||
IfAdminStatus int `gorm:"comment:管理状态: 1=up 2=down 3=testing" json:"if_admin_status,omitempty"`
|
||||
IfOperStatus int `gorm:"comment:操作状态: 1=up 2=down 3=testing" json:"if_oper_status,omitempty"`
|
||||
IfHighSpeed uint32 `gorm:"comment:高速接口速率(Mbps)" json:"if_high_speed,omitempty"`
|
||||
Status int `gorm:"default:1;comment:状态" json:"status"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SNMPInterface) TableName() string {
|
||||
return "ops_snmp_interfaces"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// SNMPHistory SNMP采集历史
|
||||
// ============================================
|
||||
|
||||
// SNMPHistory SNMP采集历史表(按时间分区)
|
||||
// 存储SNMP指标的时序历史数据,用于趋势分析和报表
|
||||
type SNMPHistory struct {
|
||||
ID uint64 `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
DeviceID uint `gorm:"not null;index:idx_snmp_history;comment:设备ID" json:"device_id"`
|
||||
MetricID uint `gorm:"not null;index;comment:指标定义ID" json:"metric_id"`
|
||||
Name string `gorm:"type:varchar(64);not null;comment:指标名称" json:"name"`
|
||||
Index string `gorm:"type:varchar(128);index;comment:索引值" json:"index,omitempty"`
|
||||
Value float64 `gorm:"not null;comment:采集值" json:"value"`
|
||||
Unit string `gorm:"type:varchar(32);comment:单位" json:"unit,omitempty"`
|
||||
Timestamp int64 `gorm:"not null;index:idx_snmp_history;comment:时间戳" json:"timestamp"`
|
||||
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (SNMPHistory) TableName() string {
|
||||
return "snmp_history"
|
||||
}
|
||||
|
||||
// SNMPWalkResult SNMP Walk 结果
|
||||
type SNMPWalkResult struct {
|
||||
OID string `json:"oid"`
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
Index string `json:"index,omitempty"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
}
|
||||
|
||||
// SNMPConnectionConfig SNMP连接配置
|
||||
type SNMPConnectionConfig struct {
|
||||
IP string `json:"ip"`
|
||||
Port int `json:"port"`
|
||||
Version SNMPVersion `json:"version"`
|
||||
Community string `json:"community,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
AuthProtocol SNMPAuthProtocol `json:"auth_protocol,omitempty"`
|
||||
AuthPassword string `json:"auth_password,omitempty"`
|
||||
PrivProtocol SNMPPrivProtocol `json:"priv_protocol,omitempty"`
|
||||
PrivPassword string `json:"priv_password,omitempty"`
|
||||
SecurityLevel string `json:"security_level,omitempty"`
|
||||
Timeout int `json:"timeout"`
|
||||
Retries int `json:"retries"`
|
||||
MaxRepetitions uint32 `json:"max_repetitions"`
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// TerminalSession SSH终端会话记录(JumpServer 式终端审计) // Logan.Li
|
||||
type TerminalSession struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
UserID *uint `json:"user_id"`
|
||||
Username string `gorm:"size:64" json:"username"`
|
||||
ServerID uint `json:"server_id"`
|
||||
ServerName string `gorm:"size:128" json:"server_name"`
|
||||
ServerIP string `gorm:"size:64" json:"server_ip"`
|
||||
ServerPort int `json:"server_port"`
|
||||
ClientIP string `gorm:"size:64" json:"client_ip"`
|
||||
Status string `gorm:"size:32" json:"status"` // active, closed, failed
|
||||
Duration int `json:"duration"` // seconds
|
||||
RecordData string `gorm:"type:mediumtext" json:"-"` // 终端录制原始输出(asciicast v2 格式,max 16MB)
|
||||
RecordSize int `json:"record_size"` // 录制字节数
|
||||
StartTime time.Time `json:"start_time"`
|
||||
EndTime *time.Time `json:"end_time"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (TerminalSession) TableName() string {
|
||||
return "sys_terminal_sessions"
|
||||
}
|
||||
|
||||
// TerminalSessionQuery 终端会话查询
|
||||
type TerminalSessionQuery struct {
|
||||
ServerID uint `form:"server_id"`
|
||||
Username string `form:"username"`
|
||||
Status string `form:"status"`
|
||||
Page int `form:"page,default=1"`
|
||||
PageSize int `form:"page_size,default=20"`
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
)
|
||||
|
||||
// User 用户模型
|
||||
type User struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Username string `gorm:"size:64;uniqueIndex;not null" json:"username"`
|
||||
Password string `gorm:"size:255;not null" json:"-"`
|
||||
Email string `gorm:"size:128" json:"email"`
|
||||
Phone string `gorm:"size:32" json:"phone"`
|
||||
RealName string `gorm:"size:64" json:"real_name"`
|
||||
Avatar string `gorm:"size:255" json:"avatar"`
|
||||
Status int `gorm:"default:1" json:"status"` // 0:禁用 1:启用
|
||||
IsAdmin bool `gorm:"default:false" json:"is_admin"`
|
||||
AuthSource string `gorm:"size:20;default:'local'" json:"auth_source"` // local / ldap
|
||||
LastLogin *time.Time `json:"last_login"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Roles []Role `gorm:"many2many:user_roles;" json:"roles,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (User) TableName() string {
|
||||
return "iam_users"
|
||||
}
|
||||
|
||||
// Role 角色模型
|
||||
type Role struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:64;uniqueIndex;not null" json:"name"`
|
||||
Code string `gorm:"size:64;uniqueIndex;not null" json:"code"`
|
||||
Description string `gorm:"size:255" json:"description"`
|
||||
Status int `gorm:"default:1" json:"status"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 关联
|
||||
Permissions []Permission `gorm:"many2many:role_permissions;" json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (Role) TableName() string {
|
||||
return "iam_roles"
|
||||
}
|
||||
|
||||
// Permission 权限模型
|
||||
type Permission struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:64;not null" json:"name"`
|
||||
Code string `gorm:"size:128;uniqueIndex;not null" json:"code"`
|
||||
Type string `gorm:"size:32" json:"type"` // menu, button, api
|
||||
Path string `gorm:"size:255" json:"path"`
|
||||
Method string `gorm:"size:32" json:"method"`
|
||||
ParentID *uint `json:"parent_id"`
|
||||
Sort int `gorm:"default:0" json:"sort"`
|
||||
Status int `gorm:"default:1" json:"status"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
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"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
|
||||
// LoginResponse 登录响应
|
||||
type LoginResponse struct {
|
||||
Token string `json:"token"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
User *User `json:"user"`
|
||||
}
|
||||
|
||||
// CreateUserRequest 创建用户请求
|
||||
type CreateUserRequest struct {
|
||||
Username string `json:"username" binding:"required,min=3,max=64"`
|
||||
Password string `json:"password" binding:"required,min=6,max=32"`
|
||||
Email string `json:"email" binding:"required,email"`
|
||||
Phone string `json:"phone"`
|
||||
RealName string `json:"real_name"`
|
||||
RoleIDs []uint `json:"role_ids"`
|
||||
}
|
||||
|
||||
// UpdateUserRequest 更新用户请求
|
||||
type UpdateUserRequest struct {
|
||||
Email string `json:"email" binding:"omitempty,email"`
|
||||
Phone string `json:"phone"`
|
||||
RealName string `json:"real_name"`
|
||||
Status *int `json:"status"`
|
||||
RoleIDs []uint `json:"role_ids"`
|
||||
}
|
||||
|
||||
// CreateRoleRequest 创建角色请求 // Logan.Li
|
||||
type CreateRoleRequest struct {
|
||||
Name string `json:"name" binding:"required,min=1,max=64"`
|
||||
Code string `json:"code" binding:"required,min=1,max=64"`
|
||||
Description string `json:"description"`
|
||||
PermissionIDs []uint `json:"permission_ids"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
Description *string `json:"description"`
|
||||
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 修改密码请求
|
||||
type ChangePasswordRequest struct {
|
||||
OldPassword string `json:"old_password" binding:"required"`
|
||||
NewPassword string `json:"new_password" binding:"required,min=6,max=32"`
|
||||
}
|
||||
|
||||
// LDAPConfig LDAP配置
|
||||
type LDAPConfig struct {
|
||||
ID int `gorm:"primarykey" json:"id"`
|
||||
LDAPHost string `gorm:"size:200;not null" json:"ldap_host"`
|
||||
LDAPPort *int `json:"ldap_port"`
|
||||
UseLDAPS *bool `json:"use_ldaps"`
|
||||
AdminDN string `gorm:"size:500;not null" json:"admin_dn"`
|
||||
AdminPassword string `gorm:"size:500;not null" json:"admin_password"`
|
||||
SearchFilter *string `gorm:"size:500" json:"search_filter"`
|
||||
BaseDN string `gorm:"size:500;not null" json:"base_dn"`
|
||||
UserMapping *string `gorm:"type:text" json:"user_mapping"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (LDAPConfig) TableName() string { return "iam_ldap_configs" }
|
||||
@@ -0,0 +1,82 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// ZabbixDataSource Zabbix 数据源配置(参考 Grafana 界面设计) // Logan.Li
|
||||
type ZabbixDataSource struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
||||
Name string `gorm:"type:varchar(128);not null;uniqueIndex;comment:数据源名称" json:"name"`
|
||||
URL string `gorm:"type:varchar(512);not null;comment:Zabbix API地址" json:"url"`
|
||||
Username string `gorm:"type:varchar(128);not null;comment:用户名" json:"username"`
|
||||
Password string `gorm:"type:varchar(256);not null;comment:密码" json:"password,omitempty"`
|
||||
|
||||
// Trends 设置
|
||||
TrendsAfter int `gorm:"default:0;comment:趋势数据起始时间(天前)" json:"trends_after"`
|
||||
TrendsRange int `gorm:"default:0;comment:趋势数据范围(秒)" json:"trends_range"`
|
||||
TrendsCacheTTL int `gorm:"default:3600;comment:趋势缓存TTL(秒)" json:"trends_cache_ttl"`
|
||||
TrendsTimeout int `gorm:"default:30;comment:趋势查询超时(秒)" json:"trends_timeout"`
|
||||
|
||||
// Direct DB Connection
|
||||
DirectDB bool `gorm:"default:false;comment:启用直连数据库" json:"direct_db"`
|
||||
|
||||
// Other
|
||||
DisableAcknowledges bool `gorm:"default:false;comment:只读用户禁用确认" json:"disable_acknowledges"`
|
||||
DisableDataAlignment bool `gorm:"default:false;comment:禁用数据对齐" json:"disable_data_alignment"`
|
||||
|
||||
// 状态
|
||||
IsDefault bool `gorm:"default:false;index;comment:是否默认数据源" json:"is_default"`
|
||||
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
|
||||
|
||||
CreatedAt time.Time `gorm:"not null;index;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 (ZabbixDataSource) TableName() string {
|
||||
return "monitor_zabbix_datasources"
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 请求/响应 struct
|
||||
// ============================================
|
||||
|
||||
// CreateZabbixDSReq 创建 Zabbix 数据源请求
|
||||
type CreateZabbixDSReq struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
URL string `json:"url" binding:"required"`
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
TrendsAfter int `json:"trends_after"`
|
||||
TrendsRange int `json:"trends_range"`
|
||||
TrendsCacheTTL int `json:"trends_cache_ttl"`
|
||||
TrendsTimeout int `json:"trends_timeout"`
|
||||
DirectDB bool `json:"direct_db"`
|
||||
DisableAcknowledges bool `json:"disable_acknowledges"`
|
||||
DisableDataAlignment bool `json:"disable_data_alignment"`
|
||||
IsDefault bool `json:"is_default"`
|
||||
}
|
||||
|
||||
// UpdateZabbixDSReq 更新 Zabbix 数据源请求
|
||||
type UpdateZabbixDSReq struct {
|
||||
Name *string `json:"name"`
|
||||
URL *string `json:"url"`
|
||||
Username *string `json:"username"`
|
||||
Password *string `json:"password"`
|
||||
TrendsAfter *int `json:"trends_after"`
|
||||
TrendsRange *int `json:"trends_range"`
|
||||
TrendsCacheTTL *int `json:"trends_cache_ttl"`
|
||||
TrendsTimeout *int `json:"trends_timeout"`
|
||||
DirectDB *bool `json:"direct_db"`
|
||||
DisableAcknowledges *bool `json:"disable_acknowledges"`
|
||||
DisableDataAlignment *bool `json:"disable_data_alignment"`
|
||||
IsDefault *bool `json:"is_default"`
|
||||
Status *int `json:"status"`
|
||||
}
|
||||
|
||||
// TestZabbixDSReq 测试 Zabbix 连接请求
|
||||
type TestZabbixDSReq struct {
|
||||
URL string `json:"url" binding:"required"`
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
Reference in new issue
Block a user