package services import ( "fmt" "git.linuxforward.com/byop/byop-engine/dbstore" "git.linuxforward.com/byop/byop-engine/models" "github.com/google/uuid" ) // TemplateService handles business logic for templates type TemplateService struct { store *dbstore.TemplateStore } // NewTemplateService creates a new TemplateService func NewTemplateService(store *dbstore.TemplateStore) *TemplateService { return &TemplateService{store: store} } // CreateTemplate creates a new deployment template func (s *TemplateService) CreateTemplate(template *models.Template) error { // Generate UUID if not provided if template.ID == "" { template.ID = uuid.New().String() } // Validate template configuration if err := validateTemplateConfig(template.Config); err != nil { return fmt.Errorf("invalid template configuration: %w", err) } // Persist the template return s.store.Create(template) } // GetTemplate retrieves a template by ID func (s *TemplateService) GetTemplate(id string) (*models.Template, error) { template, err := s.store.GetByID(id) if err != nil { return nil, fmt.Errorf("failed to retrieve template: %w", err) } return template, nil } // UpdateTemplate updates an existing template func (s *TemplateService) UpdateTemplate(template *models.Template) error { if template.ID == "" { return fmt.Errorf("template ID is required for update") } // Check if template exists existingTemplate, err := s.store.GetByID(template.ID) if err != nil { return fmt.Errorf("failed to check if template exists: %w", err) } if existingTemplate == nil { return fmt.Errorf("template with ID %s not found", template.ID) } // Validate template configuration if err := validateTemplateConfig(template.Config); err != nil { return fmt.Errorf("invalid template configuration: %w", err) } return s.store.Update(template) } // DeleteTemplate deletes a template by ID func (s *TemplateService) DeleteTemplate(id string) error { // Check if template exists template, err := s.store.GetByID(id) if err != nil { return fmt.Errorf("failed to check if template exists: %w", err) } if template == nil { return fmt.Errorf("template with ID %s not found", id) } // Check if the template has deployments templateWithDeployments, err := s.store.GetTemplateWithDeployments(id) if err != nil { return fmt.Errorf("failed to check template deployments: %w", err) } // Don't allow deletion if there are active deployments if len(templateWithDeployments.Deployments) > 0 { return fmt.Errorf("cannot delete template with active deployments") } return s.store.Delete(id) } // ListTemplates retrieves all templates with optional filtering func (s *TemplateService) ListTemplates(filter map[string]interface{}) ([]*models.Template, error) { return s.store.List(filter) } // GetTemplateDeployments retrieves all deployments for a template func (s *TemplateService) GetTemplateDeployments(id string) ([]models.Deployment, error) { // First check if the template exists template, err := s.store.GetByID(id) if err != nil { return nil, fmt.Errorf("failed to check if template exists: %w", err) } if template == nil { return nil, fmt.Errorf("template with ID %s not found", id) } // Get template with deployments templateWithDeployments, err := s.store.GetTemplateWithDeployments(id) if err != nil { return nil, fmt.Errorf("failed to retrieve template deployments: %w", err) } return templateWithDeployments.Deployments, nil } // GetTemplateByVersion retrieves a template by name and version func (s *TemplateService) GetTemplateByVersion(name, version string) (*models.Template, error) { template, err := s.store.GetByVersion(name, version) if err != nil { return nil, fmt.Errorf("failed to retrieve template: %w", err) } return template, nil } // validateTemplateConfig validates the template configuration func validateTemplateConfig(config models.TemplateConfig) error { // Validate that at least one app is defined if len(config.Apps) == 0 { return fmt.Errorf("template must define at least one app") } // Validate each app in the template for i, app := range config.Apps { if app.Name == "" { return fmt.Errorf("app at index %d must have a name", i) } // Validate resource configuration if app.Resources.CPU == "" { return fmt.Errorf("app '%s' must specify CPU resources", app.Name) } if app.Resources.Memory == "" { return fmt.Errorf("app '%s' must specify memory resources", app.Name) } } // Add additional validation logic as needed return nil }