package main import ( "strings" "ezops/internal/models" "go.uber.org/zap" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" ) // seedData 初始化种子数据(admin用户 + LDAP配置 + 审批模板 + 权限角色) func seedData(db *gorm.DB) { // 1. 创建默认 admin 用户(仅首次) var userCount int64 db.Model(&models.User{}).Count(&userCount) if userCount == 0 { hashedPassword, _ := bcrypt.GenerateFromPassword([]byte("123456"), bcrypt.DefaultCost) admin := models.User{ Username: "admin", Password: string(hashedPassword), Email: "admin@ezops.local", RealName: "管理员", Status: 1, IsAdmin: true, AuthSource: "local", } if err := db.Create(&admin).Error; err != nil { zap.L().Warn("failed to seed admin user", zap.Error(err)) } else { zap.L().Info("seeded default admin user (admin/123456)") } } // 2. 创建默认 LDAP 配置 var ldapCount int64 db.Model(&models.LDAPConfig{}).Count(&ldapCount) if ldapCount == 0 { port := 389 useLDAPS := false searchFilter := "(objectClass=inetOrgPerson)" userMapping := `{"username":"uid","email":"mail","display_name":"cn"}` ldapCfg := models.LDAPConfig{ LDAPHost: "8.217.205.92", LDAPPort: &port, UseLDAPS: &useLDAPS, AdminDN: "cn=admin,dc=opsx,dc=vip", AdminPassword: "LQl2GX7EEg2N", BaseDN: "dc=opsx,dc=vip", SearchFilter: &searchFilter, UserMapping: &userMapping, } if err := db.Create(&ldapCfg).Error; err != nil { zap.L().Warn("failed to seed LDAP config", zap.Error(err)) } else { zap.L().Info("seeded default LDAP config (8.217.205.92:389)") } } // 3. 创建默认审批模板(资源申请) var tplCount int64 db.Model(&models.ApprovalTemplate{}).Count(&tplCount) if tplCount == 0 { templates := []models.ApprovalTemplate{ { Name: "云服务器申请", Code: "server_apply", Description: "申请云服务器资源(ECS/EC2),包含规格、数量、用途等信息", Type: "server_apply", FormSchema: `{ "fields": [ {"key": "provider", "label": "云厂商", "type": "select", "options": ["阿里云","腾讯云","华为云","AWS"], "required": true}, {"key": "region", "label": "地域", "type": "text", "placeholder": "如 cn-hangzhou", "required": true}, {"key": "spec", "label": "规格", "type": "select", "options": ["2C4G","4C8G","8C16G","16C32G","32C64G"], "required": true}, {"key": "disk", "label": "系统盘(GB)", "type": "number", "default": 40, "required": true}, {"key": "count", "label": "数量(台)", "type": "number", "default": 1, "required": true}, {"key": "duration", "label": "时长", "type": "select", "options": ["1个月","3个月","6个月","1年"], "required": true}, {"key": "purpose", "label": "用途说明", "type": "textarea", "required": true} ] }`, FlowConfig: `[{"name":"直接主管","approver_role":"team_lead"},{"name":"运维负责人","approver_role":"ops_manager"}]`, Enabled: true, }, { Name: "应用部署申请", Code: "app_deploy", Description: "申请新应用部署,包含 Git 地址、端口、Nacos 等配置信息", Type: "app_deploy", FormSchema: `{ "fields": [ {"key": "app_name", "label": "应用名称", "type": "text", "placeholder": "如 user-service", "required": true}, {"key": "git_url", "label": "Git 地址", "type": "text", "placeholder": "如 https://github.com/org/repo.git", "required": true}, {"key": "branch", "label": "分支", "type": "text", "default": "main", "required": true}, {"key": "language", "label": "开发语言", "type": "select", "options": ["Java","Go","Python","Node.js","C++"], "required": true}, {"key": "http_port", "label": "HTTP 端口", "type": "number", "placeholder": "如 8080", "required": false}, {"key": "grpc_port", "label": "gRPC 端口", "type": "number", "placeholder": "如 9090", "required": false}, {"key": "nacos_addr", "label": "Nacos 地址", "type": "text", "placeholder": "如 nacos.opsx.vip:8848", "required": true}, {"key": "nacos_namespace", "label": "Nacos 命名空间", "type": "text", "placeholder": "如 production", "required": false}, {"key": "env", "label": "部署环境", "type": "select", "options": ["dev","staging","prod"], "required": true}, {"key": "replicas", "label": "副本数", "type": "number", "default": 2, "required": true}, {"key": "remark", "label": "备注", "type": "textarea", "required": false} ] }`, FlowConfig: `[{"name":"技术负责人","approver_role":"tech_lead"},{"name":"运维负责人","approver_role":"ops_manager"}]`, Enabled: true, }, } if err := db.Create(&templates).Error; err != nil { zap.L().Warn("failed to seed approval templates", zap.Error(err)) } else { zap.L().Info("seeded default approval templates (server_apply + app_deploy)") } } // 4. 创建默认权限和角色权限映射 var permCount int64 db.Model(&models.Permission{}).Count(&permCount) if permCount == 0 { perms := []models.Permission{ // 资产管理 {Name: "服务器管理", Code: "server:view", Type: "menu", Sort: 1, Status: 1}, {Name: "服务器创建", Code: "server:create", Type: "button", Sort: 2, Status: 1}, {Name: "服务器编辑", Code: "server:update", Type: "button", Sort: 3, Status: 1}, {Name: "服务器删除", Code: "server:delete", Type: "button", Sort: 4, Status: 1}, {Name: "WebShell终端", Code: "server:webshell", Type: "button", Sort: 5, Status: 1}, // 云资源 {Name: "云账号管理", Code: "cloud:account", Type: "menu", Sort: 10, Status: 1}, {Name: "域名管理", Code: "cloud:domain", Type: "menu", Sort: 11, Status: 1}, {Name: "云账单", Code: "cloud:billing", Type: "menu", Sort: 12, Status: 1}, // Kubernetes {Name: "集群管理", Code: "k8s:cluster", Type: "menu", Sort: 20, Status: 1}, {Name: "节点管理", Code: "k8s:nodes", Type: "menu", Sort: 21, Status: 1}, {Name: "工作负载", Code: "k8s:workloads", Type: "menu", Sort: 22, Status: 1}, {Name: "架构拓扑", Code: "k8s:topology", Type: "menu", Sort: 23, Status: 1}, // 应用发布 {Name: "流水线", Code: "deploy:pipeline", Type: "menu", Sort: 30, Status: 1}, {Name: "应用发布", Code: "deploy:release", Type: "menu", Sort: 31, Status: 1}, // 监控告警 {Name: "告警中心", Code: "monitor:alert", Type: "menu", Sort: 40, Status: 1}, {Name: "告警规则", Code: "monitor:rule", Type: "button", Sort: 41, Status: 1}, {Name: "Agent监控", Code: "agent:monitor", Type: "menu", Sort: 42, Status: 1}, {Name: "Agent告警", Code: "agent:alert", Type: "menu", Sort: 43, Status: 1}, // 自动化运维 {Name: "定时任务", Code: "auto:cron", Type: "menu", Sort: 50, Status: 1}, {Name: "脚本管理", Code: "auto:script", Type: "menu", Sort: 51, Status: 1}, {Name: "Ansible", Code: "auto:ansible", Type: "menu", Sort: 52, Status: 1}, // AIOps {Name: "智能助手", Code: "aiops:assistant", Type: "menu", Sort: 60, Status: 1}, {Name: "告警分析", Code: "aiops:analysis", Type: "menu", Sort: 61, Status: 1}, {Name: "容量预测", Code: "aiops:forecast", Type: "menu", Sort: 62, Status: 1}, // 资源申请 {Name: "资源申请", Code: "approval:apply", Type: "menu", Sort: 70, Status: 1}, {Name: "审批管理", Code: "approval:manage", Type: "button", Sort: 71, Status: 1}, // 系统管理 {Name: "用户管理", Code: "system:user", Type: "menu", Sort: 80, Status: 1}, {Name: "角色权限", Code: "system:role", Type: "menu", Sort: 81, Status: 1}, {Name: "操作审计", Code: "system:audit", Type: "menu", Sort: 82, Status: 1}, {Name: "LDAP配置", Code: "system:ldap", Type: "menu", Sort: 83, Status: 1}, // 仪表盘 {Name: "仪表盘", Code: "dashboard:view", Type: "menu", Sort: 90, Status: 1}, } db.Create(&perms) zap.L().Info("seeded default permissions") } // 5. 创建默认角色(如果不存在) var roleCount int64 db.Model(&models.Role{}).Count(&roleCount) if roleCount == 0 { roles := []models.Role{ {Name: "管理员", Code: "admin", Description: "系统管理员,拥有全部权限", Status: 1}, {Name: "运维工程师", Code: "ops", Description: "日常运维管理", Status: 1}, {Name: "开发工程师", Code: "developer", Description: "开发人员,只读权限", Status: 1}, {Name: "只读用户", Code: "viewer", Description: "仅查看权限", Status: 1}, } db.Create(&roles) zap.L().Info("seeded default roles") // 为各角色分配权限 var allPerms []models.Permission db.Find(&allPerms) for _, role := range roles { var permIds []uint switch role.Code { case "admin": for _, p := range allPerms { permIds = append(permIds, p.ID) } case "ops": for _, p := range allPerms { if !strings.HasPrefix(p.Code, "system:") { permIds = append(permIds, p.ID) } } case "developer": devPerms := map[string]bool{ "dashboard:view": true, "server:view": true, "cloud:account": true, "cloud:domain": true, "cloud:billing": true, "k8s:cluster": true, "k8s:nodes": true, "k8s:workloads": true, "k8s:topology": true, "monitor:alert": true, "deploy:pipeline": true, "deploy:release": true, "approval:apply": true, "aiops:assistant": true, "aiops:analysis": true, "aiops:forecast": true, } for _, p := range allPerms { if devPerms[p.Code] { permIds = append(permIds, p.ID) } } case "viewer": for _, p := range allPerms { if p.Code == "dashboard:view" || p.Code == "server:view" || p.Code == "monitor:alert" { permIds = append(permIds, p.ID) } } } if len(permIds) > 0 { var rolePerms []models.Permission db.Where("id IN ?", permIds).Find(&rolePerms) db.Model(&role).Association("Permissions").Append(rolePerms) } } } }