Skip to content

Commit

Permalink
refactor: api server struct
Browse files Browse the repository at this point in the history
Signed-off-by: Toma Puljak <[email protected]>
  • Loading branch information
Tpuljak committed Apr 9, 2024
1 parent b75939b commit 1616320
Show file tree
Hide file tree
Showing 21 changed files with 277 additions and 145 deletions.
44 changes: 7 additions & 37 deletions cmd/daytona/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import (
"fmt"
"os"
"path/filepath"

"github.com/daytonaio/daytona/pkg/apikey"
"github.com/daytonaio/daytona/pkg/server"
)

type ServerApi struct {
Expand Down Expand Up @@ -46,6 +43,12 @@ type GitProvider struct {
Name string
}

const configDoesntExistError = "config does not exist. Run `daytona server` to create a default profile"

func IsNotExist(err error) bool {
return err.Error() == configDoesntExistError
}

func GetConfig() (*Config, error) {
configFilePath, err := getConfigPath()
if err != nil {
Expand All @@ -54,16 +57,7 @@ func GetConfig() (*Config, error) {

_, err = os.Stat(configFilePath)
if os.IsNotExist(err) {
defaultConfig, err := getDefaultConfig()
if err != nil {
return nil, err
}
err = defaultConfig.Save()
if err != nil {
return nil, err
}

return defaultConfig, nil
return nil, errors.New(configDoesntExistError)
}

if err != nil {
Expand Down Expand Up @@ -163,30 +157,6 @@ func (c *Config) GetProfile(profileId string) (Profile, error) {
return Profile{}, errors.New("profile not found")
}

func getDefaultConfig() (*Config, error) {
server := server.GetInstance(nil)

apiKey, err := server.ApiKeyService.Generate(apikey.ApiKeyTypeClient, "default")
if err != nil {
return nil, err
}

return &Config{
ActiveProfileId: "default",
DefaultIdeId: "vscode",
Profiles: []Profile{
{
Id: "default",
Name: "default",
Api: ServerApi{
Url: "http://localhost:3000",
Key: apiKey,
},
},
},
}, nil
}

func getConfigPath() (string, error) {
configDir, err := GetConfigDir()
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/util/apiclient/error_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func HandleErrorResponse(res *http.Response, requestErr error) error {

err = json.Unmarshal(body, &errResponse)
if err != nil {
return err
return errors.New(string(body))
}

return errors.New(errResponse.Error)
Expand Down
38 changes: 38 additions & 0 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"net/url"

"github.com/daytonaio/daytona/cmd/daytona/config"
"github.com/daytonaio/daytona/internal/util/apiclient"
"github.com/daytonaio/daytona/internal/util/apiclient/server"
"github.com/daytonaio/daytona/pkg/serverapiclient"
Expand All @@ -18,6 +19,11 @@ import (
func (a *Agent) Start() error {
log.Info("Starting Daytona Agent")

err := a.setDefaultConfig()
if err != nil {
return err
}

project, err := a.getProject()
if err != nil {
return err
Expand Down Expand Up @@ -124,3 +130,35 @@ func (a *Agent) getGitUser(gitProviderId string) (*serverapiclient.GitUser, erro

return userData, nil
}

func (a *Agent) setDefaultConfig() error {
existingConfig, err := config.GetConfig()
if err != nil && !config.IsNotExist(err) {
return err
}

if existingConfig != nil {
for _, profile := range existingConfig.Profiles {
if profile.Id == "default" {
return nil
}
}
}

config := &config.Config{
ActiveProfileId: "default",
DefaultIdeId: "vscode",
Profiles: []config.Profile{
{
Id: "default",
Name: "default",
Api: config.ServerApi{
Url: a.Config.Server.ApiUrl,
Key: a.Config.Server.ApiKey,
},
},
},
}

return config.Save()
}
1 change: 1 addition & 0 deletions pkg/agent/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
type DaytonaServerConfig struct {
Url string `envconfig:"DAYTONA_SERVER_URL" validate:"required"`
ApiKey string `envconfig:"DAYTONA_SERVER_API_KEY" validate:"required"`
ApiUrl string `envconfig:"DAYTONA_SERVER_API_URL" validate:"required"`
}

type Config struct {
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/controllers/workspace/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func CreateWorkspace(ctx *gin.Context) {

server := server.GetInstance(nil)

w, err := server.WorkspaceService.CreateWorkspace(createWorkspaceDto.Name, createWorkspaceDto.Target, createWorkspaceDto.Repositories)
w, err := server.WorkspaceService.CreateWorkspace(createWorkspaceDto.Id, createWorkspaceDto.Name, createWorkspaceDto.Target, createWorkspaceDto.Repositories)
if err != nil {
ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create workspace: %s", err.Error()))
return
Expand Down
1 change: 1 addition & 0 deletions pkg/api/controllers/workspace/dto/dto.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
)

type CreateWorkspace struct {
Id string
Name string
Target string
Repositories []gitprovider.GitRepository
Expand Down
3 changes: 3 additions & 0 deletions pkg/api/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,9 @@ const docTemplate = `{
"CreateWorkspace": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
Expand Down
3 changes: 3 additions & 0 deletions pkg/api/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,9 @@
"CreateWorkspace": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ definitions:
type: object
CreateWorkspace:
properties:
id:
type: string
name:
type: string
repositories:
Expand Down
63 changes: 47 additions & 16 deletions pkg/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ package api
import (
"context"
"fmt"
"net"
"net/http"
"os"
"time"
Expand All @@ -38,32 +39,45 @@ import (
ginSwagger "github.com/swaggo/gin-swagger"
)

var httpServer *http.Server
var router *gin.Engine
type ApiServerConfig struct {
ApiPort int
}

func NewApiServer(config ApiServerConfig) *ApiServer {
return &ApiServer{
apiPort: config.ApiPort,
}
}

type ApiServer struct {
apiPort int
httpServer *http.Server
router *gin.Engine
}

func GetServer(apiPort int) (*http.Server, error) {
func (a *ApiServer) Start() error {
docs.SwaggerInfo.Version = "0.1"
docs.SwaggerInfo.BasePath = "/"
docs.SwaggerInfo.Description = "Daytona Server API"
docs.SwaggerInfo.Title = "Daytona Server API"

if mode, ok := os.LookupEnv("DAYTONA_SERVER_MODE"); ok && mode == "development" {
router = gin.Default()
router.Use(cors.New(cors.Config{
a.router = gin.Default()
a.router.Use(cors.New(cors.Config{
AllowAllOrigins: true,
}))
} else {
gin.SetMode(gin.ReleaseMode)
router = gin.New()
router.Use(gin.Recovery())
a.router = gin.New()
a.router.Use(gin.Recovery())
}

router.Use(middlewares.LoggingMiddleware())
a.router.Use(middlewares.LoggingMiddleware())

public := router.Group("/")
public := a.router.Group("/")
public.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))

protected := router.Group("/")
protected := a.router.Group("/")
protected.Use(middlewares.AuthMiddleware())

project := protected.Group("/")
Expand Down Expand Up @@ -117,6 +131,7 @@ func GetServer(apiPort int) (*http.Server, error) {

gitProviderController := protected.Group("/gitprovider")
{
gitProviderController.GET("/", gitprovider.ListGitProviders)
gitProviderController.PUT("/", gitprovider.SetGitProvider)
gitProviderController.DELETE("/:gitProviderId", gitprovider.RemoveGitProvider)
gitProviderController.GET("/:gitProviderId/user", gitprovider.GetGitUser)
Expand All @@ -136,18 +151,34 @@ func GetServer(apiPort int) (*http.Server, error) {

project.GET(gitProviderController.BasePath()+"/for-url/:url", middlewares.ProjectAuthMiddleware(), gitprovider.GetGitProviderForUrl)

httpServer = &http.Server{
Addr: fmt.Sprintf(":%d", apiPort),
Handler: router,
a.httpServer = &http.Server{
Addr: fmt.Sprintf(":%d", a.apiPort),
Handler: a.router,
}

listener, err := net.Listen("tcp", a.httpServer.Addr)
if err != nil {
return err
}

log.Infof("Starting api server on port %d", a.apiPort)
return a.httpServer.Serve(listener)
}

func (a *ApiServer) HealthCheck() error {
conn, err := net.Dial("tcp", fmt.Sprintf(":%d", a.apiPort))
if err != nil {
return fmt.Errorf("API health check timed out")
}
defer conn.Close()

return httpServer, nil
return nil
}

func Stop() {
func (a *ApiServer) Stop() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := httpServer.Shutdown(ctx); err != nil {
if err := a.httpServer.Shutdown(ctx); err != nil {
log.Error(err)
}
}
Loading

0 comments on commit 1616320

Please sign in to comment.