// Standalone script: seed K8s Pods/Deployments/Services/Ingresses for existing clusters. // Usage: go run scripts/seed_k8s_resources.go //go:build ignore package main import ( "fmt" "math/rand" "time" "ezops/internal/config" "ezops/internal/models" "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 []models.K8sCluster 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(&models.K8sPod{}).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(&models.K8sDeployment{ 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(&models.K8sPod{ 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 := models.K8sService{ 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(&models.K8sIngress{ 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(&models.K8sDeployment{}).Where("cluster_id = ?", cluster.ID).Count(&depCnt) db.Model(&models.K8sPod{}).Where("cluster_id = ?", cluster.ID).Count(&podCnt) db.Model(&models.K8sService{}).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!") }