init.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package app
  2. import (
  3. "fmt"
  4. "time"
  5. "git.linuxforward.com/byop/byop-engine/auth"
  6. "git.linuxforward.com/byop/byop-engine/cloud"
  7. "git.linuxforward.com/byop/byop-engine/dbmanager"
  8. "git.linuxforward.com/byop/byop-engine/dbstore"
  9. "git.linuxforward.com/byop/byop-engine/handlers"
  10. mw "git.linuxforward.com/byop/byop-engine/middleware"
  11. "git.linuxforward.com/byop/byop-engine/models"
  12. "git.linuxforward.com/byop/byop-engine/services"
  13. "github.com/pkg/errors"
  14. "github.com/gin-gonic/gin"
  15. )
  16. func (a *App) initCommonServices() error {
  17. // Initialize token store
  18. a.tokenStore = auth.NewMemoryTokenStore(time.Duration(a.cnf.Auth.CleanupInterval))
  19. // Initialize authentication service
  20. a.authService = auth.NewJWTService(
  21. []byte(a.cnf.Auth.PrivateKey),
  22. time.Duration(a.cnf.Auth.TokenDuration),
  23. a.tokenStore,
  24. )
  25. // Initialize providers
  26. if err := a.loadProviders(); err != nil {
  27. return errors.Wrap(err, "load providers")
  28. }
  29. // Initialize database manager
  30. switch a.cnf.Database.Type {
  31. case "sqlite":
  32. var err error
  33. a.dbManager, err = dbmanager.NewSQLiteManager(a.cnf.Database.Sqlite.File)
  34. if err != nil {
  35. return fmt.Errorf("create sqlite manager: %w", err)
  36. }
  37. // case "postgres":
  38. // a.dbManager = dbmanager.NewPostgresDbManager(a.cnf.Db.Host, a.cnf.Db.Port, a.cnf.Db.User, a.cnf.Db.Password, a.cnf.Db.Name)
  39. // case "mysql":
  40. // a.dbManager = dbmanager.NewMySQLDbManager(a.cnf.Db.Host, a.cnf.Db.Port, a.cnf.Db.User, a.cnf.Db.Password, a.cnf.Db.Name)
  41. default:
  42. return fmt.Errorf("unsupported database type: %s", a.cnf.Database.Type)
  43. }
  44. if err := a.dbManager.Connect(); err != nil {
  45. return fmt.Errorf("connect to database: %w", err)
  46. }
  47. // Auto migrate database schema
  48. if err := a.dbManager.Migrate(
  49. &models.User{},
  50. &models.Client{},
  51. &models.Component{},
  52. &models.Blueprint{},
  53. &models.Deployment{},
  54. &models.DeployedComponent{},
  55. &models.DeployedComponentResource{},
  56. // Add other models here
  57. ); err != nil {
  58. return fmt.Errorf("migrate database: %w", err)
  59. }
  60. a.entry.Info("Services initialized successfully, including authentication and database manager")
  61. return nil
  62. }
  63. func (a *App) initHandlers() error {
  64. // Initialize UserModule
  65. userStore := dbstore.NewUserStore(a.dbManager)
  66. userService := services.NewUserService(userStore)
  67. userHandler := handlers.NewUserHandler(userService)
  68. a.userModule = &UserModule{
  69. Store: userStore,
  70. Service: userService,
  71. Handler: userHandler,
  72. }
  73. // Initialize ClientModule
  74. clientStore := dbstore.NewClientStore(a.dbManager)
  75. clientService := services.NewClientService(clientStore)
  76. clientHandler := handlers.NewClientHandler(clientService)
  77. a.clientModule = &ClientModule{
  78. Store: clientStore,
  79. Service: clientService,
  80. Handler: clientHandler,
  81. }
  82. // Initialize ComponentModule
  83. componentStore := dbstore.NewComponentStore(a.dbManager)
  84. componentService := services.NewComponentService(componentStore)
  85. componentHandler := handlers.NewComponentHandler(componentService)
  86. a.componentModule = &ComponentModule{
  87. Store: componentStore,
  88. Service: componentService,
  89. Handler: componentHandler,
  90. }
  91. // Initialize BlueprintModule
  92. blueprintStore := dbstore.NewBlueprintStore(a.dbManager)
  93. blueprintService := services.NewBlueprintService(blueprintStore)
  94. blueprintHandler := handlers.NewBlueprintHandler(blueprintService)
  95. a.blueprintModule = &BlueprintModule{
  96. Store: blueprintStore,
  97. Service: blueprintService,
  98. Handler: blueprintHandler,
  99. }
  100. // Initialize DeploymentModule
  101. deploymentStore := dbstore.NewDeploymentStore(a.dbManager)
  102. deploymentService := services.NewDeploymentService(
  103. deploymentStore,
  104. componentStore,
  105. blueprintStore,
  106. clientStore,
  107. )
  108. deploymentHandler := handlers.NewDeploymentHandler(deploymentService)
  109. a.deploymentModule = &DeploymentModule{
  110. Store: deploymentStore,
  111. Service: deploymentService,
  112. Handler: deploymentHandler,
  113. }
  114. // Initialize authentication handler
  115. a.authHandler = handlers.NewAuthHandler(a.authService, a.userModule.Store)
  116. // Initialize resource handlers
  117. a.providerHandler = handlers.NewProviderHandler()
  118. // Initialize other handlers...
  119. a.entry.Info("Handlers initialized successfully")
  120. return nil
  121. }
  122. // Updated loadProviders method
  123. func (a *App) loadProviders() error {
  124. for name, cnf := range a.cnf.Providers {
  125. // Use the new InitializeProvider function instead of GetProvider + Initialize
  126. err := cloud.InitializeProvider(name, cnf)
  127. if err != nil {
  128. return fmt.Errorf("initialize provider %s: %w", name, err)
  129. }
  130. a.entry.WithField("provider", name).Info("Provider initialized")
  131. }
  132. a.entry.Info("All providers loaded successfully")
  133. return nil
  134. }
  135. func (a *App) setupRoutes() {
  136. // API version group
  137. v1 := a.rtr.Group("/api/v1")
  138. // Auth routes - no middleware required
  139. // Public routes (no authentication required)
  140. public := v1.Group("/")
  141. public.POST("/users", a.userModule.Handler.CreateUser) // Allow user registration without authentication
  142. // Auth routes - no middleware required
  143. public.POST("/login", a.authHandler.Login) // Allow login without authentication
  144. public.POST("/refresh-token", a.authHandler.RefreshToken) // Allow token refresh without authentication
  145. public.POST("/logout", a.authHandler.Logout) // Allow logout without authentication
  146. public.GET("/health", func(c *gin.Context) {
  147. c.JSON(200, gin.H{"status": "ok"})
  148. })
  149. // Protected routes - require authentication
  150. protected := v1.Group("/")
  151. protected.Use(mw.Auth(a.authService)) // Auth middleware with service dependency
  152. // Register resource routes
  153. providers := protected.Group("/providers")
  154. a.providerHandler.RegisterRoutes(providers)
  155. // Client routes - registering both with and without trailing slash
  156. clients := protected.Group("/clients")
  157. clients.GET("", a.clientModule.Handler.ListClients) // Without trailing slash
  158. clients.GET("/", a.clientModule.Handler.ListClients) // With trailing slash
  159. clients.POST("", a.clientModule.Handler.CreateClient) // Without trailing slash
  160. clients.POST("/", a.clientModule.Handler.CreateClient) // With trailing slash
  161. clients.GET("/:id", a.clientModule.Handler.GetClient)
  162. clients.PUT("/:id", a.clientModule.Handler.UpdateClient)
  163. clients.DELETE("/:id", a.clientModule.Handler.DeleteClient)
  164. clients.GET("/:id/deployments", a.clientModule.Handler.GetClientDeployments)
  165. // User routes - registering both with and without trailing slash
  166. users := protected.Group("/users")
  167. users.GET("", a.userModule.Handler.ListUsers) // Without trailing slash
  168. users.GET("/", a.userModule.Handler.ListUsers) // With trailing slash
  169. users.GET("/:id", a.userModule.Handler.GetUser)
  170. users.PUT("/:id", a.userModule.Handler.UpdateUser)
  171. users.DELETE("/:id", a.userModule.Handler.DeleteUser)
  172. users.GET("/:id/deployments", a.userModule.Handler.GetUserDeployments)
  173. // Component routes - registering both with and without trailing slash
  174. components := protected.Group("/components")
  175. components.GET("", a.componentModule.Handler.ListComponents) // Without trailing slash
  176. components.GET("/", a.componentModule.Handler.ListComponents) // With trailing slash
  177. components.POST("", a.componentModule.Handler.CreateComponent) // Without trailing slash
  178. components.POST("/", a.componentModule.Handler.CreateComponent) // With trailing slash
  179. components.GET("/:id", a.componentModule.Handler.GetComponent)
  180. components.PUT("/:id", a.componentModule.Handler.UpdateComponent)
  181. components.DELETE("/:id", a.componentModule.Handler.DeleteComponent)
  182. components.GET("/:id/deployments", a.componentModule.Handler.GetComponentDeployments)
  183. // Blueprint routes - registering both with and without trailing slash
  184. blueprints := protected.Group("/blueprints")
  185. blueprints.GET("", a.blueprintModule.Handler.ListBlueprints) // Without trailing slash
  186. blueprints.GET("/", a.blueprintModule.Handler.ListBlueprints) // With trailing slash
  187. blueprints.POST("", a.blueprintModule.Handler.CreateBlueprint) // Without trailing slash
  188. blueprints.POST("/", a.blueprintModule.Handler.CreateBlueprint) // With trailing slash
  189. blueprints.GET("/:id", a.blueprintModule.Handler.GetBlueprint)
  190. blueprints.PUT("/:id", a.blueprintModule.Handler.UpdateBlueprint)
  191. blueprints.DELETE("/:id", a.blueprintModule.Handler.DeleteBlueprint)
  192. blueprints.GET("/:id/deployments", a.blueprintModule.Handler.GetBlueprintDeployments)
  193. // Deployment routes - need to handle both versions
  194. deployments := protected.Group("/deployments")
  195. deployments.GET("", a.deploymentModule.Handler.ListDeployments)
  196. deployments.GET("/", a.deploymentModule.Handler.ListDeployments)
  197. deployments.POST("", a.deploymentModule.Handler.CreateDeployment)
  198. deployments.GET("/:id", a.deploymentModule.Handler.GetDeployment)
  199. deployments.PUT("/:id", a.deploymentModule.Handler.UpdateDeployment)
  200. deployments.DELETE("/:id", a.deploymentModule.Handler.DeleteDeployment)
  201. deployments.PUT("/:id/status", a.deploymentModule.Handler.UpdateDeploymentStatus)
  202. deployments.GET("/by-client/:clientId", a.deploymentModule.Handler.GetDeploymentsByClient)
  203. deployments.GET("/by-blueprint/:blueprintId", a.deploymentModule.Handler.GetDeploymentsByBlueprint)
  204. deployments.GET("/by-user/:userId", a.deploymentModule.Handler.GetDeploymentsByUser)
  205. a.entry.Info("Routes configured successfully")
  206. }