init.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package app
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "time"
  7. "git.linuxforward.com/byop/byop-engine/auth"
  8. "git.linuxforward.com/byop/byop-engine/cloud"
  9. "git.linuxforward.com/byop/byop-engine/dbstore"
  10. "git.linuxforward.com/byop/byop-engine/handlers"
  11. mw "git.linuxforward.com/byop/byop-engine/middleware"
  12. "git.linuxforward.com/byop/byop-engine/services"
  13. "github.com/pkg/errors"
  14. "github.com/sirupsen/logrus"
  15. "github.com/gin-gonic/gin"
  16. )
  17. func (a *App) initCommonServices() error {
  18. // Initialize database
  19. db, err := dbstore.NewSQLiteStore(a.cnf.Database.DSN)
  20. if err != nil {
  21. return errors.Wrap(err, "initialize database")
  22. }
  23. a.database = db
  24. // Initialize token store
  25. a.tokenStore = auth.NewMemoryTokenStore(time.Duration(a.cnf.Auth.CleanupInterval))
  26. // Initialize authentication service
  27. a.authService = auth.NewJWTService(
  28. []byte(a.cnf.Auth.PrivateKey),
  29. time.Duration(a.cnf.Auth.TokenDuration),
  30. a.tokenStore,
  31. a.database, // Added database argument
  32. )
  33. // Initialize providers
  34. if err := a.loadProviders(); err != nil {
  35. return errors.Wrap(err, "load providers")
  36. }
  37. // If debug mode, create default admin user
  38. if a.cnf.Debug {
  39. db.CreateDefaultAdmin(context.Background()) // Added context argument
  40. a.entry.Info("Debug mode enabled, default admin user created")
  41. // Output the admin credentials
  42. a.entry.WithFields(logrus.Fields{
  43. "email": "admin@byop.local",
  44. "password": "admin123",
  45. }).Info("Default admin credentials")
  46. }
  47. // Get Ovh provider
  48. ovhProvider, _ := cloud.GetProvider("ovh")
  49. a.previewService = services.NewPreviewService(a.database, ovhProvider, a.cnf, a.registryClient, a.cnf.ReistryUrl, "", "")
  50. a.builderService = services.NewBuilderService(a.database, a.buildkitClient, a.registryClient, 5)
  51. a.appImporter = services.NewAppImporter(a.database, a.builderService, a.cnf.ReistryUrl)
  52. a.entry.Info("Services initialized successfully, including authentication and database manager")
  53. return nil
  54. }
  55. func (a *App) initHandlers() error {
  56. // Initialize UserModule
  57. a.userHandler = handlers.NewUserHandler(a.database)
  58. // Initialize ClientModule
  59. a.clientHandler = handlers.NewClientHandler(a.database)
  60. // Initialize ComponentModule
  61. a.componentHandler = handlers.NewComponentHandler(a.database, a.builderService, a.cnf.ReistryUrl)
  62. // Initialize AppModule
  63. a.appHandler = handlers.NewAppsHandler(a.database, a.previewService, a.appImporter)
  64. // Initialize DeploymentModule
  65. a.deploymentHandler = handlers.NewDeploymentHandler(a.database)
  66. // Initialize authentication handler
  67. a.authHandler = handlers.NewAuthHandler(a.authService, a.database)
  68. // Initialize resource handlers
  69. a.providerHandler = handlers.NewProviderHandler()
  70. // Initialize PreviewHandler
  71. a.previewHandler = handlers.NewPreviewHandler(a.previewService, a.database)
  72. a.entry.Info("Handlers initialized successfully")
  73. return nil
  74. }
  75. // Updated loadProviders method
  76. func (a *App) loadProviders() error {
  77. for name, cnf := range a.cnf.Providers {
  78. // Use the new InitializeProvider function instead of GetProvider + Initialize
  79. err := cloud.InitializeProvider(name, cnf)
  80. if err != nil {
  81. return fmt.Errorf("initialize provider %s: %w", name, err)
  82. }
  83. a.entry.WithField("provider", name).Info("Provider initialized")
  84. }
  85. a.entry.Info("All providers loaded successfully")
  86. return nil
  87. }
  88. func (a *App) setupRoutes() {
  89. // Add CORS middleware to handle all cross-origin requests
  90. a.rtr.Use(func(c *gin.Context) {
  91. c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
  92. c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
  93. c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
  94. c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
  95. // Allow redirects
  96. c.Writer.Header().Set("Access-Control-Expose-Headers", "Location")
  97. c.Writer.Header().Set("Access-Control-Max-Age", "86400") // Cache preflight response for 24 hours
  98. c.Writer.Header().Set("Content-Type", "application/json; charset=utf-8")
  99. // Handle preflight OPTIONS requests
  100. if c.Request.Method == http.MethodOptions {
  101. c.AbortWithStatus(http.StatusNoContent)
  102. return
  103. }
  104. c.Next()
  105. })
  106. // API version group
  107. v1 := a.rtr.Group("/api/v1")
  108. // Auth routes - no middleware required
  109. // Public routes (no authentication required)
  110. public := v1.Group("/")
  111. public.POST("/users", a.userHandler.CreateUser) // Allow user registration without authentication
  112. // Auth routes - no middleware required
  113. public.POST("/login", a.authHandler.Login) // Allow login without authentication
  114. public.POST("/refresh-token", a.authHandler.RefreshToken) // Allow token refresh without authentication
  115. public.POST("/logout", a.authHandler.Logout) // Allow logout without authentication
  116. public.GET("/health", func(c *gin.Context) {
  117. c.JSON(200, gin.H{"status": "ok"})
  118. })
  119. // Protected routes - require authentication
  120. protected := v1.Group("/")
  121. protected.Use(mw.Auth(a.authService)) // Auth middleware with service dependency
  122. // Register resource routes
  123. providers := protected.Group("/providers")
  124. a.providerHandler.RegisterRoutes(providers)
  125. // Client routes - registering both with and without trailing slash
  126. clients := protected.Group("/clients")
  127. clients.GET("", a.clientHandler.ListClients)
  128. clients.POST("", a.clientHandler.CreateClient)
  129. clients.GET("/:id", a.clientHandler.GetClient)
  130. clients.PUT("/:id", a.clientHandler.UpdateClient)
  131. clients.DELETE("/:id", a.clientHandler.DeleteClient)
  132. clients.GET("/:id/deployments", a.clientHandler.GetClientDeployments)
  133. // User routes - registering both with and without trailing slash
  134. users := protected.Group("/users")
  135. users.GET("", a.userHandler.ListUsers)
  136. users.GET("/:id", a.userHandler.GetUser)
  137. users.PUT("/:id", a.userHandler.UpdateUser)
  138. users.DELETE("/:id", a.userHandler.DeleteUser)
  139. users.GET("/:id/deployments", a.userHandler.GetUserDeployments)
  140. // Component routes (formerly Apps)
  141. components := protected.Group("/components")
  142. components.GET("", a.componentHandler.ListComponents)
  143. components.POST("", a.componentHandler.CreateComponent)
  144. components.GET("/:id", a.componentHandler.GetComponent)
  145. components.PUT("/:id", a.componentHandler.UpdateComponent)
  146. components.DELETE("/:id", a.componentHandler.DeleteComponent)
  147. components.GET("/:id/deployments", a.componentHandler.GetComponentDeployments)
  148. // App routes (formerly Templates)
  149. apps := protected.Group("/apps")
  150. apps.GET("", a.appHandler.ListApps)
  151. apps.POST("", a.appHandler.CreateApp)
  152. apps.GET("/:id", a.appHandler.GetApp)
  153. apps.PUT("/:id", a.appHandler.UpdateApp)
  154. apps.DELETE("/:id", a.appHandler.DeleteApp)
  155. apps.GET("/:id/deployments", a.appHandler.GetAppDeployments)
  156. // App preview route
  157. apps.POST("/:id/preview", a.appHandler.CreateAppPreview)
  158. apps.GET("/:id/preview", a.appHandler.GetAppPreview)
  159. apps.DELETE("/:id/preview", a.appHandler.DeleteAppPreview)
  160. // App import routes
  161. apps.POST("/import/review", a.appHandler.ImportReview)
  162. apps.POST("/import/create", a.appHandler.ImportCreate)
  163. // Deployment routes - need to handle both versions
  164. deployments := protected.Group("/deployments")
  165. deployments.GET("", a.deploymentHandler.ListDeployments)
  166. deployments.POST("", a.deploymentHandler.CreateDeployment)
  167. deployments.GET("/:id", a.deploymentHandler.GetDeployment)
  168. deployments.PUT("/:id", a.deploymentHandler.UpdateDeployment)
  169. deployments.DELETE("/:id", a.deploymentHandler.DeleteDeployment)
  170. deployments.PUT("/:id/status", a.deploymentHandler.UpdateDeploymentStatus)
  171. // deployments.GET("/by-client/:clientId", a.deploymentHandler.GetDeploymentsByClient)
  172. // deployments.GET("/by-app/:appId", a.deploymentHandler.GetDeploymentsByTemplate) // Was by-template
  173. // deployments.GET("/by-user/:userId", a.deploymentHandler.GetDeploymentsByUser)
  174. // // Add other resource routes as needed
  175. a.entry.Info("Routes configured successfully")
  176. }