init.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. package app
  2. import (
  3. "fmt"
  4. "net/http"
  5. "time"
  6. "git.linuxforward.com/byop/byop-engine/auth"
  7. "git.linuxforward.com/byop/byop-engine/cloud"
  8. "git.linuxforward.com/byop/byop-engine/dbmanager"
  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/models"
  13. "git.linuxforward.com/byop/byop-engine/services"
  14. "github.com/pkg/errors"
  15. "github.com/gin-gonic/gin"
  16. )
  17. func (a *App) initCommonServices() error {
  18. // Initialize token store
  19. a.tokenStore = auth.NewMemoryTokenStore(time.Duration(a.cnf.Auth.CleanupInterval))
  20. // Initialize authentication service
  21. a.authService = auth.NewJWTService(
  22. []byte(a.cnf.Auth.PrivateKey),
  23. time.Duration(a.cnf.Auth.TokenDuration),
  24. a.tokenStore,
  25. )
  26. // Initialize providers
  27. if err := a.loadProviders(); err != nil {
  28. return errors.Wrap(err, "load providers")
  29. }
  30. // Initialize database manager
  31. switch a.cnf.Database.Type {
  32. case "sqlite":
  33. var err error
  34. a.dbManager, err = dbmanager.NewSQLiteManager(a.cnf.Database.Sqlite.File)
  35. if err != nil {
  36. return fmt.Errorf("create sqlite manager: %w", err)
  37. }
  38. // case "postgres":
  39. // a.dbManager = dbmanager.NewPostgresDbManager(a.cnf.Db.Host, a.cnf.Db.Port, a.cnf.Db.User, a.cnf.Db.Password, a.cnf.Db.Name)
  40. // case "mysql":
  41. // a.dbManager = dbmanager.NewMySQLDbManager(a.cnf.Db.Host, a.cnf.Db.Port, a.cnf.Db.User, a.cnf.Db.Password, a.cnf.Db.Name)
  42. default:
  43. return fmt.Errorf("unsupported database type: %s", a.cnf.Database.Type)
  44. }
  45. if err := a.dbManager.Connect(); err != nil {
  46. return fmt.Errorf("connect to database: %w", err)
  47. }
  48. // Auto migrate database schema
  49. if err := a.dbManager.Migrate(
  50. &models.User{},
  51. &models.Client{},
  52. &models.Component{}, // Renamed from App
  53. &models.App{}, // Renamed from Template
  54. &models.Deployment{},
  55. &models.DeployedApp{},
  56. &models.DeployedAppResource{},
  57. // Add other models here
  58. ); err != nil {
  59. return fmt.Errorf("migrate database: %w", err)
  60. }
  61. a.entry.Info("Services initialized successfully, including authentication and database manager")
  62. return nil
  63. }
  64. func (a *App) initHandlers() error {
  65. // Initialize UserModule
  66. userStore := dbstore.NewUserStore(a.dbManager)
  67. userService := services.NewUserService(userStore)
  68. userHandler := handlers.NewUserHandler(userService)
  69. a.userModule = &UserModule{
  70. Store: userStore,
  71. Service: userService,
  72. Handler: userHandler,
  73. }
  74. // Initialize ClientModule
  75. clientStore := dbstore.NewClientStore(a.dbManager)
  76. clientService := services.NewClientService(clientStore)
  77. clientHandler := handlers.NewClientHandler(clientService)
  78. a.clientModule = &ClientModule{
  79. Store: clientStore,
  80. Service: clientService,
  81. Handler: clientHandler,
  82. }
  83. // Initialize ComponentModule (formerly AppModule)
  84. componentStore := dbstore.NewComponentStore(a.dbManager)
  85. componentService := services.NewComponentService(componentStore)
  86. componentHandler := handlers.NewComponentHandler(componentService)
  87. a.componentModule = &ComponentModule{
  88. Store: componentStore,
  89. Service: componentService,
  90. Handler: componentHandler,
  91. }
  92. // Initialize AppModule (formerly TemplateModule)
  93. appStore := dbstore.NewAppStore(a.dbManager)
  94. appService := services.NewAppService(appStore)
  95. appsHandler := handlers.NewAppsHandler(appService)
  96. a.appModule = &AppModule{
  97. Store: appStore,
  98. Service: appService,
  99. Handler: appsHandler,
  100. }
  101. // Initialize DeploymentModule
  102. deploymentStore := dbstore.NewDeploymentStore(a.dbManager)
  103. deploymentService := services.NewDeploymentService(
  104. deploymentStore,
  105. componentStore,
  106. appStore,
  107. clientStore,
  108. )
  109. deploymentHandler := handlers.NewDeploymentHandler(deploymentService)
  110. a.deploymentModule = &DeploymentModule{
  111. Store: deploymentStore,
  112. Service: deploymentService,
  113. Handler: deploymentHandler,
  114. }
  115. // Initialize authentication handler
  116. a.authHandler = handlers.NewAuthHandler(a.authService, a.userModule.Store)
  117. // Initialize resource handlers
  118. a.providerHandler = handlers.NewProviderHandler()
  119. // Initialize other handlers...
  120. a.entry.Info("Handlers initialized successfully")
  121. return nil
  122. }
  123. func (a *App) loadProviders() error {
  124. for name, config := range a.cnf.Providers {
  125. provider, ok := cloud.GetProvider(name)
  126. if !ok {
  127. return fmt.Errorf("provider %s not found", name)
  128. }
  129. err := provider.Initialize(config)
  130. if err != nil {
  131. return fmt.Errorf("initialize provider %s: %w", name, err)
  132. }
  133. a.entry.WithField("provider", name).Info("Provider initialized")
  134. }
  135. a.entry.Info("All providers loaded successfully")
  136. return nil
  137. }
  138. func (a *App) setupRoutes() {
  139. // Add CORS middleware to handle all cross-origin requests
  140. a.rtr.Use(func(c *gin.Context) {
  141. c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
  142. c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
  143. c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
  144. c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
  145. // Allow redirects
  146. c.Writer.Header().Set("Access-Control-Expose-Headers", "Location")
  147. c.Writer.Header().Set("Access-Control-Max-Age", "86400") // Cache preflight response for 24 hours
  148. c.Writer.Header().Set("Content-Type", "application/json; charset=utf-8")
  149. // Handle preflight OPTIONS requests
  150. if c.Request.Method == http.MethodOptions {
  151. c.AbortWithStatus(http.StatusNoContent)
  152. return
  153. }
  154. c.Next()
  155. })
  156. // API version group
  157. v1 := a.rtr.Group("/api/v1")
  158. // Auth routes - no middleware required
  159. // Public routes (no authentication required)
  160. public := v1.Group("/")
  161. public.POST("/users", a.userModule.Handler.CreateUser) // Allow user registration without authentication
  162. // Auth routes - no middleware required
  163. public.POST("/login", a.authHandler.Login) // Allow login without authentication
  164. public.POST("/refresh-token", a.authHandler.RefreshToken) // Allow token refresh without authentication
  165. public.POST("/logout", a.authHandler.Logout) // Allow logout without authentication
  166. public.GET("/health", func(c *gin.Context) {
  167. c.JSON(200, gin.H{"status": "ok"})
  168. })
  169. // Protected routes - require authentication
  170. protected := v1.Group("/")
  171. protected.Use(mw.Auth(a.authService)) // Auth middleware with service dependency
  172. // Register resource routes
  173. providers := protected.Group("/providers")
  174. a.providerHandler.RegisterRoutes(providers)
  175. // Client routes
  176. clients := protected.Group("/clients")
  177. clients.GET("", a.clientModule.Handler.ListClients)
  178. clients.POST("", a.clientModule.Handler.CreateClient)
  179. clients.GET("/:id", a.clientModule.Handler.GetClient)
  180. clients.PUT("/:id", a.clientModule.Handler.UpdateClient)
  181. clients.DELETE("/:id", a.clientModule.Handler.DeleteClient)
  182. clients.GET("/:id/deployments", a.clientModule.Handler.GetClientDeployments)
  183. // User routes
  184. users := protected.Group("/users")
  185. users.GET("", a.userModule.Handler.ListUsers)
  186. users.GET("/:id", a.userModule.Handler.GetUser)
  187. users.PUT("/:id", a.userModule.Handler.UpdateUser)
  188. users.DELETE("/:id", a.userModule.Handler.DeleteUser)
  189. users.GET("/:id/deployments", a.userModule.Handler.GetUserDeployments)
  190. // Component routes (formerly Apps)
  191. components := protected.Group("/components")
  192. components.GET("", a.componentModule.Handler.ListComponents)
  193. components.POST("", a.componentModule.Handler.CreateComponent)
  194. components.GET("/:id", a.componentModule.Handler.GetComponent)
  195. components.PUT("/:id", a.componentModule.Handler.UpdateComponent)
  196. components.DELETE("/:id", a.componentModule.Handler.DeleteComponent)
  197. components.GET("/:id/deployments", a.componentModule.Handler.GetComponentDeployments)
  198. // App routes (formerly Templates)
  199. apps := protected.Group("/apps")
  200. apps.GET("", a.appModule.Handler.ListApps)
  201. apps.POST("", a.appModule.Handler.CreateApp)
  202. apps.GET("/:id", a.appModule.Handler.GetApp)
  203. apps.PUT("/:id", a.appModule.Handler.UpdateApp)
  204. apps.DELETE("/:id", a.appModule.Handler.DeleteApp)
  205. apps.GET("/:id/deployments", a.appModule.Handler.GetAppDeployments)
  206. // Deployment routes
  207. deployments := protected.Group("/deployments")
  208. deployments.GET("", a.deploymentModule.Handler.ListDeployments)
  209. deployments.POST("", a.deploymentModule.Handler.CreateDeployment)
  210. deployments.GET("/:id", a.deploymentModule.Handler.GetDeployment)
  211. deployments.PUT("/:id", a.deploymentModule.Handler.UpdateDeployment)
  212. deployments.DELETE("/:id", a.deploymentModule.Handler.DeleteDeployment)
  213. deployments.PUT("/:id/status", a.deploymentModule.Handler.UpdateDeploymentStatus)
  214. // deployments.GET("/by-client/:clientId", a.deploymentModule.Handler.GetDeploymentsByClient)
  215. // deployments.GET("/by-app/:appId", a.deploymentModule.Handler.GetDeploymentsByTemplate) // Was by-template
  216. // deployments.GET("/by-user/:userId", a.deploymentModule.Handler.GetDeploymentsByUser)
  217. // // Add other resource routes as needed
  218. a.entry.Info("Routes configured successfully")
  219. }