apps.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package services
  2. import (
  3. "fmt"
  4. "git.linuxforward.com/byop/byop-engine/dbstore"
  5. "git.linuxforward.com/byop/byop-engine/models"
  6. )
  7. // AppService handles business logic for apps
  8. type AppService struct {
  9. store *dbstore.AppStore
  10. }
  11. // NewAppService creates a new AppService
  12. func NewAppService(store *dbstore.AppStore) *AppService {
  13. return &AppService{store: store}
  14. }
  15. // CreateApp creates a new deployment app
  16. func (s *AppService) CreateApp(app *models.App) error {
  17. // Validate app configuration
  18. if err := validateAppConfig(app.Config); err != nil {
  19. return fmt.Errorf("invalid app configuration: %w", err)
  20. }
  21. // Persist the app
  22. return s.store.Create(app)
  23. }
  24. // GetApp retrieves an app by ID
  25. func (s *AppService) GetApp(id int64) (*models.App, error) {
  26. app, err := s.store.GetByID(id)
  27. if err != nil {
  28. return nil, fmt.Errorf("failed to retrieve app: %w", err)
  29. }
  30. return app, nil
  31. }
  32. // UpdateApp updates an existing app
  33. func (s *AppService) UpdateApp(app *models.App) error {
  34. if app.ID == 0 {
  35. return fmt.Errorf("app ID is required for update")
  36. }
  37. // Check if app exists
  38. existingApp, err := s.store.GetByID(app.ID)
  39. if err != nil {
  40. return fmt.Errorf("failed to check if app exists: %w", err)
  41. }
  42. if existingApp == nil {
  43. return fmt.Errorf("app with ID %d not found", app.ID)
  44. }
  45. // Validate app configuration
  46. if err := validateAppConfig(app.Config); err != nil {
  47. return fmt.Errorf("invalid app configuration: %w", err)
  48. }
  49. return s.store.Update(app)
  50. }
  51. // DeleteApp deletes an app by ID
  52. func (s *AppService) DeleteApp(id int64) error {
  53. // Check if app exists
  54. app, err := s.store.GetByID(id)
  55. if err != nil {
  56. return fmt.Errorf("failed to check if app exists: %w", err)
  57. }
  58. if app == nil {
  59. return fmt.Errorf("app with ID %d not found", id)
  60. }
  61. // Check if the app has deployments
  62. appWithDeployments, err := s.store.GetAppWithDeployments(id)
  63. if err != nil {
  64. return fmt.Errorf("failed to check app deployments: %w", err)
  65. }
  66. // Don't allow deletion if there are active deployments
  67. if len(appWithDeployments.Deployments) > 0 {
  68. return fmt.Errorf("cannot delete app with active deployments")
  69. }
  70. return s.store.Delete(id)
  71. }
  72. // ListApps retrieves all apps with optional filtering
  73. func (s *AppService) ListApps(filter map[string]interface{}) ([]*models.App, error) {
  74. return s.store.List(filter)
  75. }
  76. // GetAppDeployments retrieves all deployments for an app
  77. func (s *AppService) GetAppDeployments(id int64) ([]models.Deployment, error) {
  78. // First check if the app exists
  79. app, err := s.store.GetByID(id)
  80. if err != nil {
  81. return nil, fmt.Errorf("failed to check if app exists: %w", err)
  82. }
  83. if app == nil {
  84. return nil, fmt.Errorf("app with ID %d not found", id)
  85. }
  86. // Get app with deployments
  87. appWithDeployments, err := s.store.GetAppWithDeployments(id)
  88. if err != nil {
  89. return nil, fmt.Errorf("failed to retrieve app deployments: %w", err)
  90. }
  91. return appWithDeployments.Deployments, nil
  92. }
  93. // GetAppByVersion retrieves an app by name and version
  94. func (s *AppService) GetAppByVersion(name, version string) (*models.App, error) {
  95. app, err := s.store.GetByVersion(name, version)
  96. if err != nil {
  97. return nil, fmt.Errorf("failed to retrieve app: %w", err)
  98. }
  99. return app, nil
  100. }
  101. // validateAppConfig validates the app configuration
  102. func validateAppConfig(config models.AppConfig) error {
  103. // Validate that at least one component is defined
  104. if len(config.Components) == 0 {
  105. return fmt.Errorf("app must define at least one component")
  106. }
  107. // Validate each component in the app
  108. for i, component := range config.Components {
  109. if component.Name == "" {
  110. return fmt.Errorf("component at index %d must have a name", i)
  111. }
  112. // Validate resource configuration
  113. if component.Resources.CPU == "" {
  114. return fmt.Errorf("component '%s' must specify CPU resources", component.Name)
  115. }
  116. if component.Resources.Memory == "" {
  117. return fmt.Errorf("component '%s' must specify memory resources", component.Name)
  118. }
  119. }
  120. // Add additional validation logic as needed
  121. return nil
  122. }