get server by id

This commit is contained in:
Fran Jurmanović
2025-02-13 01:09:16 +01:00
parent 6fbc718a47
commit d5140783ca
7 changed files with 165 additions and 98 deletions

View File

@@ -3,6 +3,7 @@ package controller
import ( import (
"acc-server-manager/local/service" "acc-server-manager/local/service"
"acc-server-manager/local/utl/common" "acc-server-manager/local/utl/common"
"strings"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
@@ -54,19 +55,19 @@ func (ac *ApiController) getFirst(c *fiber.Ctx) error {
// @Success 200 {array} string // @Success 200 {array} string
// @Router /v1/api/{service} [get] // @Router /v1/api/{service} [get]
func (ac *ApiController) getStatus(c *fiber.Ctx) error { func (ac *ApiController) getStatus(c *fiber.Ctx) error {
serverId, err := c.ParamsInt("serverId") service := c.Params("service")
if err != nil { if service == "" {
return c.Status(400).SendString(err.Error()) serverId, err := c.ParamsInt("service")
} if err != nil {
if serverId == 0 { return c.Status(400).SendString(err.Error())
service := c.Params("service") }
c.Locals("service", service)
} else {
c.Locals("serverId", serverId) c.Locals("serverId", serverId)
} else {
c.Locals("service", service)
} }
apiModel, err := ac.service.GetStatus(c) apiModel, err := ac.service.GetStatus(c)
if err != nil { if err != nil {
return c.Status(400).SendString(err.Error()) return c.Status(400).SendString(strings.ReplaceAll(err.Error(), "\x00", ""))
} }
return c.SendString(apiModel) return c.SendString(apiModel)
} }
@@ -88,7 +89,7 @@ func (ac *ApiController) startServer(c *fiber.Ctx) error {
c.Locals("serverId", model.ServerId) c.Locals("serverId", model.ServerId)
apiModel, err := ac.service.ApiStartServer(c) apiModel, err := ac.service.ApiStartServer(c)
if err != nil { if err != nil {
return c.Status(400).SendString(err.Error()) return c.Status(400).SendString(strings.ReplaceAll(err.Error(), "\x00", ""))
} }
return c.SendString(apiModel) return c.SendString(apiModel)
} }
@@ -110,7 +111,7 @@ func (ac *ApiController) stopServer(c *fiber.Ctx) error {
c.Locals("serverId", model.ServerId) c.Locals("serverId", model.ServerId)
apiModel, err := ac.service.ApiStopServer(c) apiModel, err := ac.service.ApiStopServer(c)
if err != nil { if err != nil {
return c.Status(400).SendString(err.Error()) return c.Status(400).SendString(strings.ReplaceAll(err.Error(), "\x00", ""))
} }
return c.SendString(apiModel) return c.SendString(apiModel)
} }
@@ -132,7 +133,7 @@ func (ac *ApiController) restartServer(c *fiber.Ctx) error {
c.Locals("serverId", model.ServerId) c.Locals("serverId", model.ServerId)
apiModel, err := ac.service.ApiRestartServer(c) apiModel, err := ac.service.ApiRestartServer(c)
if err != nil { if err != nil {
return c.Status(400).SendString(err.Error()) return c.Status(400).SendString(strings.ReplaceAll(err.Error(), "\x00", ""))
} }
return c.SendString(apiModel) return c.SendString(apiModel)
} }

View File

@@ -58,7 +58,11 @@ func (ac *ConfigController) updateConfig(c *fiber.Ctx) error {
return c.Status(400).SendString(err.Error()) return c.Status(400).SendString(err.Error())
} }
if restart { if restart {
ac.apiService.RestartServer(c) serviceName, err := ac.apiService.GetServiceName(c)
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": "Unable to restart service"})
}
ac.apiService.RestartServer(serviceName)
} }
return c.JSON(ConfigModel) return c.JSON(ConfigModel)

View File

@@ -25,6 +25,7 @@ func NewServerController(as *service.ServerService, routeGroups *common.RouteGro
} }
routeGroups.Server.Get("/", ac.getAll) routeGroups.Server.Get("/", ac.getAll)
routeGroups.Server.Get("/:id", ac.getById)
return ac return ac
} }
@@ -40,3 +41,16 @@ func (ac *ServerController) getAll(c *fiber.Ctx) error {
ServerModel := ac.service.GetAll(c) ServerModel := ac.service.GetAll(c)
return c.JSON(ServerModel) return c.JSON(ServerModel)
} }
// getById returns Servers
//
// @Summary Return Servers
// @Description Return Servers
// @Tags Server
// @Success 200 {array} string
// @Router /v1/server [get]
func (ac *ServerController) getById(c *fiber.Ctx) error {
serverID, _ := c.ParamsInt("id")
ServerModel := ac.service.GetById(c, serverID)
return c.JSON(ServerModel)
}

View File

@@ -4,76 +4,76 @@ import "time"
// Config tracks configuration modifications // Config tracks configuration modifications
type Config struct { type Config struct {
ID uint `gorm:"primaryKey"` ID uint `json:"id" gorm:"primaryKey"`
ServerID uint `gorm:"not null"` ServerID uint `json:"serverId" gorm:"not null"`
ConfigFile string `gorm:"not null"` // e.g. "settings.json" ConfigFile string `json:"configFile" gorm:"not null"` // e.g. "settings.json"
OldConfig string `gorm:"type:text"` OldConfig string `json:"oldConfig" gorm:"type:text"`
NewConfig string `gorm:"type:text"` NewConfig string `json:"newConfig" gorm:"type:text"`
ChangedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"` ChangedAt time.Time `json:"changedAt" gorm:"default:CURRENT_TIMESTAMP"`
} }
type Configurations struct { type Configurations struct {
Configuration map[string]interface{} Configuration map[string]interface{} `json:"configuration"`
Entrylist map[string]interface{} Entrylist map[string]interface{} `json:"entrylist"`
Event map[string]interface{} Event map[string]interface{} `json:"event"`
EventRules map[string]interface{} EventRules map[string]interface{} `json:"eventRules"`
Settings map[string]interface{} Settings map[string]interface{} `json:"settings"`
} }
type ServerSettings struct { type ServerSettings struct {
ServerName string `json:"serverName"` ServerName string `json:"serverName"`
AdminPassword string `json:"adminPassword"` AdminPassword string `json:"adminPassword"`
CarGroup string `json:"carGroup"` CarGroup string `json:"carGroup"`
TrackMedalsRequirement int `json:"trackMedalsRequirement"` TrackMedalsRequirement int `json:"trackMedalsRequirement"`
SafetyRatingRequirement int `json:"safetyRatingRequirement"` SafetyRatingRequirement int `json:"safetyRatingRequirement"`
RacecraftRatingRequirement int `json:"racecraftRatingRequirement"` RacecraftRatingRequirement int `json:"racecraftRatingRequirement"`
Password string `json:"password"` Password string `json:"password"`
SpectatorPassword string `json:"spectatorPassword"` SpectatorPassword string `json:"spectatorPassword"`
MaxCarSlots int `json:"maxCarSlots"` MaxCarSlots int `json:"maxCarSlots"`
DumpLeaderboards int `json:"dumpLeaderboards"` DumpLeaderboards int `json:"dumpLeaderboards"`
IsRaceLocked int `json:"isRaceLocked"` IsRaceLocked int `json:"isRaceLocked"`
RandomizeTrackWhenEmpty int `json:"randomizeTrackWhenEmpty"` RandomizeTrackWhenEmpty int `json:"randomizeTrackWhenEmpty"`
CentralEntryListPath string `json:"centralEntryListPath"` CentralEntryListPath string `json:"centralEntryListPath"`
AllowAutoDQ int `json:"allowAutoDQ"` AllowAutoDQ int `json:"allowAutoDQ"`
ShortFormationLap int `json:"shortFormationLap"` ShortFormationLap int `json:"shortFormationLap"`
FormationLapType int `json:"formationLapType"` FormationLapType int `json:"formationLapType"`
IgnorePrematureDisconnects int `json:"ignorePrematureDisconnects"` IgnorePrematureDisconnects int `json:"ignorePrematureDisconnects"`
} }
type EventConfig struct { type EventConfig struct {
Track string `json:"track"` Track string `json:"track"`
PreRaceWaitingTimeSeconds int `json:"preRaceWaitingTimeSeconds"` PreRaceWaitingTimeSeconds int `json:"preRaceWaitingTimeSeconds"`
SessionOverTimeSeconds int `json:"sessionOverTimeSeconds"` SessionOverTimeSeconds int `json:"sessionOverTimeSeconds"`
AmbientTemp int `json:"ambientTemp"` AmbientTemp int `json:"ambientTemp"`
CloudLevel float64 `json:"cloudLevel"` CloudLevel float64 `json:"cloudLevel"`
Rain float64 `json:"rain"` Rain float64 `json:"rain"`
WeatherRandomness int `json:"weatherRandomness"` WeatherRandomness int `json:"weatherRandomness"`
PostQualySeconds int `json:"postQualySeconds"` PostQualySeconds int `json:"postQualySeconds"`
PostRaceSeconds int `json:"postRaceSeconds"` PostRaceSeconds int `json:"postRaceSeconds"`
SimracerWeatherConditions int `json:"simracerWeatherConditions"` SimracerWeatherConditions int `json:"simracerWeatherConditions"`
IsFixedConditionQualification int `json:"isFixedConditionQualification"` IsFixedConditionQualification int `json:"isFixedConditionQualification"`
Sessions []Session `json:"sessions"` Sessions []Session `json:"sessions"`
} }
type Session struct { type Session struct {
HourOfDay int `json:"hourOfDay"` HourOfDay int `json:"hourOfDay"`
DayOfWeekend int `json:"dayOfWeekend"` DayOfWeekend int `json:"dayOfWeekend"`
TimeMultiplier int `json:"timeMultiplier"` TimeMultiplier int `json:"timeMultiplier"`
SessionType string `json:"sessionType"` SessionType string `json:"sessionType"`
SessionDurationMinutes int `json:"sessionDurationMinutes"` SessionDurationMinutes int `json:"sessionDurationMinutes"`
} }
type EventRules struct { type EventRules struct {
QualifyStandingType int `json:"qualifyStandingType"` QualifyStandingType int `json:"qualifyStandingType"`
PitWindowLengthSec int `json:"pitWindowLengthSec"` PitWindowLengthSec int `json:"pitWindowLengthSec"`
DriverStintTimeSec int `json:"driverStintTimeSec"` DriverStintTimeSec int `json:"driverStintTimeSec"`
MandatoryPitstopCount int `json:"mandatoryPitstopCount"` MandatoryPitstopCount int `json:"mandatoryPitstopCount"`
MaxTotalDrivingTime int `json:"maxTotalDrivingTime"` MaxTotalDrivingTime int `json:"maxTotalDrivingTime"`
IsRefuellingAllowedInRace bool `json:"isRefuellingAllowedInRace"` IsRefuellingAllowedInRace bool `json:"isRefuellingAllowedInRace"`
IsRefuellingTimeFixed bool `json:"isRefuellingTimeFixed"` IsRefuellingTimeFixed bool `json:"isRefuellingTimeFixed"`
IsMandatoryPitstopRefuellingRequired bool `json:"isMandatoryPitstopRefuellingRequired"` IsMandatoryPitstopRefuellingRequired bool `json:"isMandatoryPitstopRefuellingRequired"`
IsMandatoryPitstopTyreChangeRequired bool `json:"isMandatoryPitstopTyreChangeRequired"` IsMandatoryPitstopTyreChangeRequired bool `json:"isMandatoryPitstopTyreChangeRequired"`
IsMandatoryPitstopSwapDriverRequired bool `json:"isMandatoryPitstopSwapDriverRequired"` IsMandatoryPitstopSwapDriverRequired bool `json:"isMandatoryPitstopSwapDriverRequired"`
TyreSetCount int `json:"tyreSetCount"` TyreSetCount int `json:"tyreSetCount"`
} }

View File

@@ -2,10 +2,11 @@ package model
// Server represents an ACC server instance // Server represents an ACC server instance
type Server struct { type Server struct {
ID uint `gorm:"primaryKey"` ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"not null"` Name string `gorm:"not null" json:"name"`
IP string `gorm:"not null"` Status string `json:"status"`
Port int `gorm:"not null"` IP string `gorm:"not null" json:"-"`
ConfigPath string `gorm:"not null"` // e.g. "/acc/servers/server1/" Port int `gorm:"not null" json:"-"`
ServiceName string `gorm:"not null"` // Windows service name ConfigPath string `gorm:"not null" json:"-"` // e.g. "/acc/servers/server1/"
ServiceName string `gorm:"not null" json:"-"` // Windows service name
} }

View File

@@ -5,6 +5,7 @@ import (
"acc-server-manager/local/repository" "acc-server-manager/local/repository"
"acc-server-manager/local/utl/common" "acc-server-manager/local/utl/common"
"errors" "errors"
"strings"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
@@ -34,38 +35,65 @@ func (as ApiService) GetFirst(ctx *fiber.Ctx) *model.ApiModel {
} }
func (as ApiService) GetStatus(ctx *fiber.Ctx) (string, error) { func (as ApiService) GetStatus(ctx *fiber.Ctx) (string, error) {
return as.StatusServer(ctx) serviceName, err := as.GetServiceName(ctx)
if err != nil {
return "", err
}
status, err := as.StatusServer(serviceName)
return status, err
} }
func (as ApiService) ApiStartServer(ctx *fiber.Ctx) (string, error) { func (as ApiService) ApiStartServer(ctx *fiber.Ctx) (string, error) {
return as.StartServer(ctx) serviceName, err := as.GetServiceName(ctx)
if err != nil {
return "", err
}
return as.StartServer(serviceName)
} }
func (as ApiService) ApiStopServer(ctx *fiber.Ctx) (string, error) { func (as ApiService) ApiStopServer(ctx *fiber.Ctx) (string, error) {
return as.StopServer(ctx) serviceName, err := as.GetServiceName(ctx)
if err != nil {
return "", err
}
return as.StopServer(serviceName)
} }
func (as ApiService) ApiRestartServer(ctx *fiber.Ctx) (string, error) { func (as ApiService) ApiRestartServer(ctx *fiber.Ctx) (string, error) {
return as.RestartServer(ctx) serviceName, err := as.GetServiceName(ctx)
if err != nil {
return "", err
}
return as.RestartServer(serviceName)
} }
func (as ApiService) StatusServer(ctx *fiber.Ctx) (string, error) { func (as ApiService) StatusServer(serviceName string) (string, error) {
return as.ManageService(ctx, "status") return ManageService(serviceName, "status")
} }
func (as ApiService) StartServer(ctx *fiber.Ctx) (string, error) { func (as ApiService) StartServer(serviceName string) (string, error) {
return as.ManageService(ctx, "start") return ManageService(serviceName, "start")
} }
func (as ApiService) StopServer(ctx *fiber.Ctx) (string, error) { func (as ApiService) StopServer(serviceName string) (string, error) {
return as.ManageService(ctx, "stop") return ManageService(serviceName, "stop")
} }
func (as ApiService) RestartServer(ctx *fiber.Ctx) (string, error) { func (as ApiService) RestartServer(serviceName string) (string, error) {
return as.ManageService(ctx, "restart") return ManageService(serviceName, "restart")
} }
func (as ApiService) ManageService(ctx *fiber.Ctx, action string) (string, error) { func ManageService(serviceName string, action string) (string, error) {
output, err := common.RunElevatedCommand(action, serviceName)
if err != nil {
return "", err
}
return strings.ReplaceAll(output, "\x00", ""), nil
}
func (as ApiService) GetServiceName(ctx *fiber.Ctx) (string, error) {
var server *model.Server var server *model.Server
serviceName, ok := ctx.Locals("service").(string) serviceName, ok := ctx.Locals("service").(string)
if !ok || serviceName == "" { if !ok || serviceName == "" {
@@ -80,10 +108,5 @@ func (as ApiService) ManageService(ctx *fiber.Ctx, action string) (string, error
if server == nil { if server == nil {
return "", fiber.NewError(404, "Server not found") return "", fiber.NewError(404, "Server not found")
} }
return server.ServiceName, nil
output, err := common.RunElevatedCommand(action, server.ServiceName)
if err != nil {
return "", err
}
return output, nil
} }

View File

@@ -9,11 +9,13 @@ import (
type ServerService struct { type ServerService struct {
repository *repository.ServerRepository repository *repository.ServerRepository
apiService *ApiService
} }
func NewServerService(repository *repository.ServerRepository) *ServerService { func NewServerService(repository *repository.ServerRepository, apiService *ApiService) *ServerService {
return &ServerService{ return &ServerService{
repository: repository, repository: repository,
apiService: apiService,
} }
} }
@@ -25,5 +27,27 @@ func NewServerService(repository *repository.ServerRepository) *ServerService {
// Returns: // Returns:
// string: Application version // string: Application version
func (as ServerService) GetAll(ctx *fiber.Ctx) *[]model.Server { func (as ServerService) GetAll(ctx *fiber.Ctx) *[]model.Server {
return as.repository.GetAll(ctx.UserContext()) servers := as.repository.GetAll(ctx.UserContext())
for i, server := range *servers {
status, _ := as.apiService.StatusServer(server.ServiceName)
(*servers)[i].Status = status
}
return servers
} }
// GetById
// Gets rows by ID from Server table.
//
// Args:
// context.Context: Application context
// Returns:
// string: Application version
func (as ServerService) GetById(ctx *fiber.Ctx, serverID int) *model.Server {
server := as.repository.GetFirst(ctx.UserContext(), serverID)
server.Status, _ = as.apiService.StatusServer(server.ServiceName);
return server
}