123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- package app
- import (
- "fmt"
- "time"
- "git.linuxforward.com/byop/byop-engine/auth"
- "git.linuxforward.com/byop/byop-engine/cloud"
- "git.linuxforward.com/byop/byop-engine/dbmanager"
- "git.linuxforward.com/byop/byop-engine/dbstore"
- "git.linuxforward.com/byop/byop-engine/handlers"
- mw "git.linuxforward.com/byop/byop-engine/middleware"
- "git.linuxforward.com/byop/byop-engine/models"
- "git.linuxforward.com/byop/byop-engine/services"
- "github.com/pkg/errors"
- "github.com/gin-gonic/gin"
- )
- func (a *App) initCommonServices() error {
- // Initialize token store
- a.tokenStore = auth.NewMemoryTokenStore(time.Duration(a.cnf.Auth.CleanupInterval))
- // Initialize authentication service
- a.authService = auth.NewJWTService(
- []byte(a.cnf.Auth.PrivateKey),
- time.Duration(a.cnf.Auth.TokenDuration),
- a.tokenStore,
- )
- // Initialize providers
- if err := a.loadProviders(); err != nil {
- return errors.Wrap(err, "load providers")
- }
- // Initialize database manager
- switch a.cnf.Database.Type {
- case "sqlite":
- var err error
- a.dbManager, err = dbmanager.NewSQLiteManager(a.cnf.Database.Sqlite.File)
- if err != nil {
- return fmt.Errorf("create sqlite manager: %w", err)
- }
- // case "postgres":
- // a.dbManager = dbmanager.NewPostgresDbManager(a.cnf.Db.Host, a.cnf.Db.Port, a.cnf.Db.User, a.cnf.Db.Password, a.cnf.Db.Name)
- // case "mysql":
- // a.dbManager = dbmanager.NewMySQLDbManager(a.cnf.Db.Host, a.cnf.Db.Port, a.cnf.Db.User, a.cnf.Db.Password, a.cnf.Db.Name)
- default:
- return fmt.Errorf("unsupported database type: %s", a.cnf.Database.Type)
- }
- if err := a.dbManager.Connect(); err != nil {
- return fmt.Errorf("connect to database: %w", err)
- }
- // Auto migrate database schema
- if err := a.dbManager.Migrate(
- &models.User{},
- &models.Client{},
- &models.Component{},
- &models.Blueprint{},
- &models.Deployment{},
- &models.DeployedComponent{},
- &models.DeployedComponentResource{},
- // Add other models here
- ); err != nil {
- return fmt.Errorf("migrate database: %w", err)
- }
- a.entry.Info("Services initialized successfully, including authentication and database manager")
- return nil
- }
- func (a *App) initHandlers() error {
- // Initialize UserModule
- userStore := dbstore.NewUserStore(a.dbManager)
- userService := services.NewUserService(userStore)
- userHandler := handlers.NewUserHandler(userService)
- a.userModule = &UserModule{
- Store: userStore,
- Service: userService,
- Handler: userHandler,
- }
- // Initialize ClientModule
- clientStore := dbstore.NewClientStore(a.dbManager)
- clientService := services.NewClientService(clientStore)
- clientHandler := handlers.NewClientHandler(clientService)
- a.clientModule = &ClientModule{
- Store: clientStore,
- Service: clientService,
- Handler: clientHandler,
- }
- // Initialize ComponentModule
- componentStore := dbstore.NewComponentStore(a.dbManager)
- componentService := services.NewComponentService(componentStore)
- componentHandler := handlers.NewComponentHandler(componentService)
- a.componentModule = &ComponentModule{
- Store: componentStore,
- Service: componentService,
- Handler: componentHandler,
- }
- // Initialize BlueprintModule
- blueprintStore := dbstore.NewBlueprintStore(a.dbManager)
- blueprintService := services.NewBlueprintService(blueprintStore)
- blueprintHandler := handlers.NewBlueprintHandler(blueprintService)
- a.blueprintModule = &BlueprintModule{
- Store: blueprintStore,
- Service: blueprintService,
- Handler: blueprintHandler,
- }
- // Initialize DeploymentModule
- deploymentStore := dbstore.NewDeploymentStore(a.dbManager)
- deploymentService := services.NewDeploymentService(
- deploymentStore,
- componentStore,
- blueprintStore,
- clientStore,
- )
- deploymentHandler := handlers.NewDeploymentHandler(deploymentService)
- a.deploymentModule = &DeploymentModule{
- Store: deploymentStore,
- Service: deploymentService,
- Handler: deploymentHandler,
- }
- // Initialize authentication handler
- a.authHandler = handlers.NewAuthHandler(a.authService, a.userModule.Store)
- // Initialize resource handlers
- a.providerHandler = handlers.NewProviderHandler()
- // Initialize other handlers...
- a.entry.Info("Handlers initialized successfully")
- return nil
- }
- // Updated loadProviders method
- func (a *App) loadProviders() error {
- for name, cnf := range a.cnf.Providers {
- // Use the new InitializeProvider function instead of GetProvider + Initialize
- err := cloud.InitializeProvider(name, cnf)
- if err != nil {
- return fmt.Errorf("initialize provider %s: %w", name, err)
- }
- a.entry.WithField("provider", name).Info("Provider initialized")
- }
- a.entry.Info("All providers loaded successfully")
- return nil
- }
- func (a *App) setupRoutes() {
- // API version group
- v1 := a.rtr.Group("/api/v1")
- // Auth routes - no middleware required
- // Public routes (no authentication required)
- public := v1.Group("/")
- public.POST("/users", a.userModule.Handler.CreateUser) // Allow user registration without authentication
- // Auth routes - no middleware required
- public.POST("/login", a.authHandler.Login) // Allow login without authentication
- public.POST("/refresh-token", a.authHandler.RefreshToken) // Allow token refresh without authentication
- public.POST("/logout", a.authHandler.Logout) // Allow logout without authentication
- public.GET("/health", func(c *gin.Context) {
- c.JSON(200, gin.H{"status": "ok"})
- })
- // Protected routes - require authentication
- protected := v1.Group("/")
- protected.Use(mw.Auth(a.authService)) // Auth middleware with service dependency
- // Register resource routes
- providers := protected.Group("/providers")
- a.providerHandler.RegisterRoutes(providers)
- // Client routes - registering both with and without trailing slash
- clients := protected.Group("/clients")
- clients.GET("", a.clientModule.Handler.ListClients) // Without trailing slash
- clients.GET("/", a.clientModule.Handler.ListClients) // With trailing slash
- clients.POST("", a.clientModule.Handler.CreateClient) // Without trailing slash
- clients.POST("/", a.clientModule.Handler.CreateClient) // With trailing slash
- clients.GET("/:id", a.clientModule.Handler.GetClient)
- clients.PUT("/:id", a.clientModule.Handler.UpdateClient)
- clients.DELETE("/:id", a.clientModule.Handler.DeleteClient)
- clients.GET("/:id/deployments", a.clientModule.Handler.GetClientDeployments)
- // User routes - registering both with and without trailing slash
- users := protected.Group("/users")
- users.GET("", a.userModule.Handler.ListUsers) // Without trailing slash
- users.GET("/", a.userModule.Handler.ListUsers) // With trailing slash
- users.GET("/:id", a.userModule.Handler.GetUser)
- users.PUT("/:id", a.userModule.Handler.UpdateUser)
- users.DELETE("/:id", a.userModule.Handler.DeleteUser)
- users.GET("/:id/deployments", a.userModule.Handler.GetUserDeployments)
- // Component routes - registering both with and without trailing slash
- components := protected.Group("/components")
- components.GET("", a.componentModule.Handler.ListComponents) // Without trailing slash
- components.GET("/", a.componentModule.Handler.ListComponents) // With trailing slash
- components.POST("", a.componentModule.Handler.CreateComponent) // Without trailing slash
- components.POST("/", a.componentModule.Handler.CreateComponent) // With trailing slash
- components.GET("/:id", a.componentModule.Handler.GetComponent)
- components.PUT("/:id", a.componentModule.Handler.UpdateComponent)
- components.DELETE("/:id", a.componentModule.Handler.DeleteComponent)
- components.GET("/:id/deployments", a.componentModule.Handler.GetComponentDeployments)
- // Blueprint routes - registering both with and without trailing slash
- blueprints := protected.Group("/blueprints")
- blueprints.GET("", a.blueprintModule.Handler.ListBlueprints) // Without trailing slash
- blueprints.GET("/", a.blueprintModule.Handler.ListBlueprints) // With trailing slash
- blueprints.POST("", a.blueprintModule.Handler.CreateBlueprint) // Without trailing slash
- blueprints.POST("/", a.blueprintModule.Handler.CreateBlueprint) // With trailing slash
- blueprints.GET("/:id", a.blueprintModule.Handler.GetBlueprint)
- blueprints.PUT("/:id", a.blueprintModule.Handler.UpdateBlueprint)
- blueprints.DELETE("/:id", a.blueprintModule.Handler.DeleteBlueprint)
- blueprints.GET("/:id/deployments", a.blueprintModule.Handler.GetBlueprintDeployments)
- // Deployment routes - need to handle both versions
- deployments := protected.Group("/deployments")
- deployments.GET("", a.deploymentModule.Handler.ListDeployments)
- deployments.GET("/", a.deploymentModule.Handler.ListDeployments)
- deployments.POST("", a.deploymentModule.Handler.CreateDeployment)
- deployments.GET("/:id", a.deploymentModule.Handler.GetDeployment)
- deployments.PUT("/:id", a.deploymentModule.Handler.UpdateDeployment)
- deployments.DELETE("/:id", a.deploymentModule.Handler.DeleteDeployment)
- deployments.PUT("/:id/status", a.deploymentModule.Handler.UpdateDeploymentStatus)
- deployments.GET("/by-client/:clientId", a.deploymentModule.Handler.GetDeploymentsByClient)
- deployments.GET("/by-blueprint/:blueprintId", a.deploymentModule.Handler.GetDeploymentsByBlueprint)
- deployments.GET("/by-user/:userId", a.deploymentModule.Handler.GetDeploymentsByUser)
- a.entry.Info("Routes configured successfully")
- }
|