diff --git a/internal/api/handlers/cloning_handler.go b/internal/api/handlers/cloning_handler.go index b3d5bf6..18ef89e 100644 --- a/internal/api/handlers/cloning_handler.go +++ b/internal/api/handlers/cloning_handler.go @@ -314,7 +314,14 @@ func (ch *CloningHandler) GetPodsHandler(c *gin.Context) { // Loop through the user's deployed pods and add template information for i := range pods { - templateName := strings.Replace(strings.ToLower(pods[i].Name[5:]), fmt.Sprintf("_%s", strings.ToLower(username)), "", 1) + deploymentName, ok := cloning.PodPoolDeploymentName(pods[i].Name) + if !ok { + log.Printf("Error parsing pod name %s", pods[i].Name) + c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse pod name", "details": fmt.Sprintf("Pod %s has an invalid name", pods[i].Name)}) + return + } + + templateName := strings.Replace(strings.ToLower(deploymentName), fmt.Sprintf("_%s", strings.ToLower(username)), "", 1) templateInfo, err := ch.Service.DatabaseService.GetTemplateInfo(templateName) if err != nil { log.Printf("Error retrieving template info for pod %s: %v", pods[i].Name, err) diff --git a/internal/api/handlers/dashboard_handler.go b/internal/api/handlers/dashboard_handler.go index 62321b5..3f0b88e 100644 --- a/internal/api/handlers/dashboard_handler.go +++ b/internal/api/handlers/dashboard_handler.go @@ -6,6 +6,7 @@ import ( "net/http" "strings" + "github.com/cpp-cyber/proclone/internal/cloning" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" ) @@ -91,7 +92,14 @@ func (dh *DashboardHandler) GetUserDashboardStatsHandler(c *gin.Context) { // Loop through the user's deployed pods and add template information for i := range pods { - templateName := strings.Replace(strings.ToLower(pods[i].Name[5:]), fmt.Sprintf("_%s", strings.ToLower(username)), "", 1) + deploymentName, ok := cloning.PodPoolDeploymentName(pods[i].Name) + if !ok { + log.Printf("Error parsing pod name %s", pods[i].Name) + c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse pod name", "details": fmt.Sprintf("Pod %s has an invalid name", pods[i].Name)}) + return + } + + templateName := strings.Replace(strings.ToLower(deploymentName), fmt.Sprintf("_%s", strings.ToLower(username)), "", 1) templateInfo, err := dh.cloningHandler.Service.DatabaseService.GetTemplateInfo(templateName) if err != nil { log.Printf("Error retrieving template info for pod %s: %v", pods[i].Name, err) diff --git a/internal/cloning/pods.go b/internal/cloning/pods.go index 7a8a87a..1522508 100644 --- a/internal/cloning/pods.go +++ b/internal/cloning/pods.go @@ -3,11 +3,25 @@ package cloning import ( "fmt" "regexp" + "strconv" "strings" "github.com/cpp-cyber/proclone/internal/proxmox" ) +func PodPoolDeploymentName(poolName string) (string, bool) { + name := strings.TrimPrefix(poolName, "pod_") + if len(name) < 5 || name[4] != '_' { + return "", false + } + + if _, err := strconv.Atoi(name[:4]); err != nil { + return "", false + } + + return name[5:], true +} + func (cs *CloningService) GetPods(username string) ([]Pod, error) { // Get User DN userDN, err := cs.LDAPService.GetUserDN(username) @@ -23,7 +37,10 @@ func (cs *CloningService) GetPods(username string) ([]Pod, error) { // Build regex pattern to match username or any of their group names groupsWithUser := append(groups, username) - regexPattern := fmt.Sprintf(`(?i)1[0-9]{3}_.*_(%s)$`, strings.Join(groupsWithUser, "|")) + for i := range groupsWithUser { + groupsWithUser[i] = regexp.QuoteMeta(groupsWithUser[i]) + } + regexPattern := fmt.Sprintf(`(?i)^(?:pod_)?1[0-9]{3}_.*_(%s)$`, strings.Join(groupsWithUser, "|")) // Get pods based on regex pattern pods, err := cs.MapVirtualResourcesToPods(regexPattern) @@ -34,7 +51,7 @@ func (cs *CloningService) GetPods(username string) ([]Pod, error) { } func (cs *CloningService) AdminGetPods() ([]Pod, error) { - pods, err := cs.MapVirtualResourcesToPods(`1[0-9]{3}_.*`) + pods, err := cs.MapVirtualResourcesToPods(`(?i)^(?:pod_)?1[0-9]{3}_.*`) if err != nil { return nil, err } @@ -87,7 +104,12 @@ func (cs *CloningService) ValidateCloneRequest(templateName string, username str for _, pod := range podPools { // Remove the Pod ID number and _ to compare - if !alreadyDeployed && strings.EqualFold(pod.Name[5:], templateName) { + deploymentName, ok := PodPoolDeploymentName(pod.Name) + if !ok { + continue + } + + if !alreadyDeployed && strings.EqualFold(deploymentName, templateName) { alreadyDeployed = true } diff --git a/internal/proxmox/pools.go b/internal/proxmox/pools.go index 4ca9038..69f1259 100644 --- a/internal/proxmox/pools.go +++ b/internal/proxmox/pools.go @@ -127,6 +127,20 @@ func (s *ProxmoxService) GetTemplatePools() ([]string, error) { return templatePools, nil } +func parsePodIDFromPoolName(poolName string) (int, bool) { + name := strings.TrimPrefix(poolName, "pod_") + if len(name) < 4 { + return 0, false + } + + id, err := strconv.Atoi(name[:4]) + if err != nil { + return 0, false + } + + return id, true +} + func (s *ProxmoxService) IsPoolEmpty(poolName string) (bool, error) { poolVMs, err := s.GetPoolVMs(poolName) if err != nil { @@ -187,12 +201,8 @@ func (s *ProxmoxService) GetNextPodID(minPodID int, maxPodID int) (string, int, // Extract pod IDs from existing pools var usedIDs []int for _, pool := range poolsResponse { - if len(pool.PoolID) >= 4 { - if id, err := strconv.Atoi(pool.PoolID[:4]); err == nil { - if id >= minPodID && id <= maxPodID { - usedIDs = append(usedIDs, id) - } - } + if id, ok := parsePodIDFromPoolName(pool.PoolID); ok && id >= minPodID && id <= maxPodID { + usedIDs = append(usedIDs, id) } } @@ -226,12 +236,8 @@ func (s *ProxmoxService) GetNextPodIDs(minPodID int, maxPodID int, num int) ([]s // Extract pod IDs from existing pools var usedIDs []int for _, pool := range poolsResponse { - if len(pool.PoolID) >= 4 { - if id, err := strconv.Atoi(pool.PoolID[:4]); err == nil { - if id >= minPodID && id <= maxPodID { - usedIDs = append(usedIDs, id) - } - } + if id, ok := parsePodIDFromPoolName(pool.PoolID); ok && id >= minPodID && id <= maxPodID { + usedIDs = append(usedIDs, id) } }