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 ✅
177 lines
5.5 KiB
Go
177 lines
5.5 KiB
Go
// Standalone script: seed K8s Pods/Deployments/Services/Ingresses for existing clusters.
|
|
// Usage: go run scripts/seed_kubernetes_resources.go
|
|
//go:build ignore
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"time"
|
|
|
|
"ezops/config"
|
|
"ezops/model"
|
|
"ezops/pkg/database"
|
|
)
|
|
|
|
func main() {
|
|
cfg := config.Load()
|
|
db, err := database.New(cfg.Database)
|
|
if err != nil {
|
|
fmt.Printf("DB connection failed: %v\n", err)
|
|
return
|
|
}
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
var clusters []model.KubernetesCluster
|
|
db.Find(&clusters)
|
|
if len(clusters) == 0 {
|
|
fmt.Println("No clusters found — run mock.go first")
|
|
return
|
|
}
|
|
|
|
depImages := []string{
|
|
"nginx:1.25.3", "redis:7.2-alpine", "mysql:8.0.35",
|
|
"kafka:3.6.0", "elasticsearch:8.11.0", "grafana/grafana:10.2.0",
|
|
"prom/prometheus:v2.48.0", "busybox:1.36", "easzlab/kubeasz:3.6.1",
|
|
}
|
|
depNames := []string{
|
|
"nginx-deploy", "redis-cluster", "mysql-master", "mysql-slave",
|
|
"kafka-broker", "es-cluster", "grafana", "prometheus",
|
|
"filebeat", "logstash", "jaeger", "zipkin",
|
|
"frontend", "backend-api", "gateway",
|
|
}
|
|
namespaces := []string{"default", "kube-system", "monitoring", "ingress-nginx", "production"}
|
|
svcTypes := []string{"ClusterIP", "NodePort", "LoadBalancer"}
|
|
svcNames := []string{
|
|
"nginx-svc", "redis-svc", "mysql-svc", "kafka-svc",
|
|
"es-svc", "grafana-svc", "prometheus-svc",
|
|
"frontend-svc", "backend-svc", "gateway-svc",
|
|
}
|
|
ingNames := []string{"main-ingress", "api-ingress", "grafana-ingress", "canary-ingress"}
|
|
podStatuses := []string{"Running", "Running", "Running", "Running", "Pending", "CrashLoopBackOff"}
|
|
|
|
for _, cluster := range clusters {
|
|
// Skip if pods already exist for this cluster
|
|
var podCount int64
|
|
db.Model(&model.KubernetesPod{}).Where("cluster_id = ?", cluster.ID).Count(&podCount)
|
|
if podCount > 0 {
|
|
fmt.Printf("Cluster %s already has %d pods, skipping\n", cluster.Name, podCount)
|
|
continue
|
|
}
|
|
|
|
numNodes := cluster.NodeCount
|
|
if numNodes == 0 {
|
|
numNodes = 3
|
|
}
|
|
|
|
// Deployments
|
|
numDeps := 5 + rand.Intn(10)
|
|
if numDeps > len(depNames) {
|
|
numDeps = len(depNames)
|
|
}
|
|
for d := 0; d < numDeps; d++ {
|
|
replicas := []int{1, 2, 3, 5}[rand.Intn(4)]
|
|
available := replicas
|
|
if rand.Intn(4) == 0 {
|
|
available = replicas - 1
|
|
}
|
|
if available < 0 {
|
|
available = 0
|
|
}
|
|
db.Create(&model.KubernetesDeployment{
|
|
ClusterID: cluster.ID,
|
|
Namespace: namespaces[rand.Intn(len(namespaces))],
|
|
Name: depNames[d],
|
|
Replicas: replicas,
|
|
AvailableReplicas: available,
|
|
ReadyReplicas: available,
|
|
Image: depImages[rand.Intn(len(depImages))],
|
|
Strategy: "RollingUpdate",
|
|
})
|
|
}
|
|
|
|
// Pods
|
|
numPods := 12 + rand.Intn(18)
|
|
for p := 0; p < numPods; p++ {
|
|
db.Create(&model.KubernetesPod{
|
|
ClusterID: cluster.ID,
|
|
Namespace: namespaces[rand.Intn(len(namespaces))],
|
|
Name: fmt.Sprintf("%s-pod-%d", cluster.Code, p+1),
|
|
Status: podStatuses[rand.Intn(len(podStatuses))],
|
|
NodeName: fmt.Sprintf("%s-node-%d", cluster.Code, rand.Intn(numNodes)+1),
|
|
IP: fmt.Sprintf("10.%d.%d.%d", rand.Intn(256), rand.Intn(256), rand.Intn(256)),
|
|
RestartCount: rand.Intn(10),
|
|
Image: depImages[rand.Intn(len(depImages))],
|
|
CPUUsage: rand.Float64() * 500,
|
|
MemoryUsage: rand.Float64() * 2048,
|
|
})
|
|
}
|
|
|
|
// Services
|
|
numSvcs := 5 + rand.Intn(5)
|
|
if numSvcs > len(svcNames) {
|
|
numSvcs = len(svcNames)
|
|
}
|
|
for s := 0; s < numSvcs; s++ {
|
|
svcType := svcTypes[rand.Intn(len(svcTypes))]
|
|
ports := "[]"
|
|
switch rand.Intn(4) {
|
|
case 0:
|
|
ports = `[{"port":80,"protocol":"TCP","targetPort":80}]`
|
|
case 1:
|
|
ports = `[{"port":443,"protocol":"TCP","targetPort":8443}]`
|
|
case 2:
|
|
ports = `[{"port":8080,"protocol":"TCP","targetPort":8080},{"port":9090,"protocol":"TCP","targetPort":9090}]`
|
|
default:
|
|
ports = `[{"port":3306,"protocol":"TCP","targetPort":3306}]`
|
|
}
|
|
svc := model.KubernetesService{
|
|
ClusterID: cluster.ID,
|
|
Namespace: namespaces[rand.Intn(len(namespaces))],
|
|
Name: svcNames[s],
|
|
Type: svcType,
|
|
ClusterIP: fmt.Sprintf("10.96.%d.%d", rand.Intn(256), rand.Intn(256)),
|
|
Ports: ports,
|
|
Selector: fmt.Sprintf(`{"app":"%s"}`, svcNames[s]),
|
|
}
|
|
if svcType == "LoadBalancer" {
|
|
svc.ExternalIP = fmt.Sprintf("203.0.113.%d", rand.Intn(256))
|
|
}
|
|
if svcType == "NodePort" {
|
|
svc.ExternalIP = fmt.Sprintf("%d-%d", 30000+rand.Intn(1000), 32767)
|
|
}
|
|
db.Create(&svc)
|
|
}
|
|
|
|
// Ingresses
|
|
numIngs := 2 + rand.Intn(3)
|
|
if numIngs > len(ingNames) {
|
|
numIngs = len(ingNames)
|
|
}
|
|
for ig := 0; ig < numIngs; ig++ {
|
|
db.Create(&model.KubernetesIngress{
|
|
ClusterID: cluster.ID,
|
|
Namespace: namespaces[rand.Intn(len(namespaces))],
|
|
Name: ingNames[ig],
|
|
Hosts: fmt.Sprintf(`["%s.ezops.local"]`, ingNames[ig]),
|
|
Backend: fmt.Sprintf("%s-svc:80", ingNames[ig]),
|
|
TLS: rand.Intn(2) == 0,
|
|
})
|
|
}
|
|
|
|
// Update cluster counts to match actual data
|
|
var depCnt, podCnt, svcCnt int64
|
|
db.Model(&model.KubernetesDeployment{}).Where("cluster_id = ?", cluster.ID).Count(&depCnt)
|
|
db.Model(&model.KubernetesPod{}).Where("cluster_id = ?", cluster.ID).Count(&podCnt)
|
|
db.Model(&model.KubernetesService{}).Where("cluster_id = ?", cluster.ID).Count(&svcCnt)
|
|
db.Model(&cluster).Updates(map[string]interface{}{
|
|
"deployment_count": depCnt,
|
|
})
|
|
|
|
fmt.Printf("Cluster %s: +%d deployments, +%d pods, +%d services, +%d ingresses\n",
|
|
cluster.Name, numDeps, numPods, numSvcs, numIngs)
|
|
}
|
|
fmt.Println("K8s resources seeded successfully!")
|
|
}
|