Remove all of the remaining API logic and port it all to the remote.Client type
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/pterodactyl/wings/config"
|
||||
"github.com/pterodactyl/wings/remote"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
"github.com/pterodactyl/wings/server/filesystem"
|
||||
)
|
||||
@@ -168,6 +169,15 @@ func AttachServerManager(m *server.Manager) gin.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// AttachApiClient attaches the application API client which allows routes to
|
||||
// access server resources from the Panel easily.
|
||||
func AttachApiClient(client remote.Client) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Set("api_client", client)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// CaptureAndAbort aborts the request and attaches the provided error to the gin
|
||||
// context so it can be reported properly. If the error is missing a stacktrace
|
||||
// at the time it is called the stack will be attached.
|
||||
@@ -327,6 +337,14 @@ func ExtractServer(c *gin.Context) *server.Server {
|
||||
return v.(*server.Server)
|
||||
}
|
||||
|
||||
// ExtractApiClient returns the API client defined for the routes.
|
||||
func ExtractApiClient(c *gin.Context) remote.Client {
|
||||
if v, ok := c.Get("api_client"); ok {
|
||||
return v.(remote.Client)
|
||||
}
|
||||
panic("middleware/middlware: cannot extract api clinet: not present in context")
|
||||
}
|
||||
|
||||
// ExtractManager returns the server manager instance set on the request context.
|
||||
func ExtractManager(c *gin.Context) *server.Manager {
|
||||
if v, ok := c.Get("manager"); ok {
|
||||
|
||||
@@ -3,18 +3,19 @@ package router
|
||||
import (
|
||||
"github.com/apex/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pterodactyl/wings/remote"
|
||||
"github.com/pterodactyl/wings/router/middleware"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
)
|
||||
|
||||
// Configure configures the routing infrastructure for this daemon instance.
|
||||
func Configure(m *server.Manager) *gin.Engine {
|
||||
func Configure(m *server.Manager, client remote.Client) *gin.Engine {
|
||||
gin.SetMode("release")
|
||||
|
||||
router := gin.New()
|
||||
router.Use(gin.Recovery())
|
||||
router.Use(middleware.AttachRequestID(), middleware.CaptureErrors(), middleware.SetAccessControlHeaders())
|
||||
router.Use(middleware.AttachServerManager(m))
|
||||
router.Use(middleware.AttachServerManager(m), middleware.AttachApiClient(client))
|
||||
// @todo log this into a different file so you can setup IP blocking for abusive requests and such.
|
||||
// This should still dump requests in debug mode since it does help with understanding the request
|
||||
// lifecycle and quickly seeing what was called leading to the logs. However, it isn't feasible to mix
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
// provided backup adapter.
|
||||
func postServerBackup(c *gin.Context) {
|
||||
s := middleware.ExtractServer(c)
|
||||
client := middleware.ExtractApiClient(c)
|
||||
logger := middleware.ExtractLogger(c)
|
||||
var data struct {
|
||||
Adapter backup.AdapterType `json:"adapter"`
|
||||
@@ -30,9 +31,9 @@ func postServerBackup(c *gin.Context) {
|
||||
var adapter backup.BackupInterface
|
||||
switch data.Adapter {
|
||||
case backup.LocalBackupAdapter:
|
||||
adapter = backup.NewLocal(data.Uuid, data.Ignore)
|
||||
adapter = backup.NewLocal(client, data.Uuid, data.Ignore)
|
||||
case backup.S3BackupAdapter:
|
||||
adapter = backup.NewS3(data.Uuid, data.Ignore)
|
||||
adapter = backup.NewS3(client, data.Uuid, data.Ignore)
|
||||
default:
|
||||
middleware.CaptureAndAbort(c, errors.New("router/backups: provided adapter is not valid: "+string(data.Adapter)))
|
||||
return
|
||||
@@ -65,6 +66,7 @@ func postServerBackup(c *gin.Context) {
|
||||
// TODO: stop the server if it is running; internally mark it as suspended
|
||||
func postServerRestoreBackup(c *gin.Context) {
|
||||
s := middleware.ExtractServer(c)
|
||||
client := middleware.ExtractApiClient(c)
|
||||
logger := middleware.ExtractLogger(c)
|
||||
|
||||
var data struct {
|
||||
@@ -94,7 +96,7 @@ func postServerRestoreBackup(c *gin.Context) {
|
||||
// Now that we've cleaned up the data directory if necessary, grab the backup file
|
||||
// and attempt to restore it into the server directory.
|
||||
if data.Adapter == backup.LocalBackupAdapter {
|
||||
b, _, err := backup.LocateLocal(c.Param("backup"))
|
||||
b, _, err := backup.LocateLocal(client, c.Param("backup"))
|
||||
if err != nil {
|
||||
middleware.CaptureAndAbort(c, err)
|
||||
return
|
||||
@@ -114,7 +116,7 @@ func postServerRestoreBackup(c *gin.Context) {
|
||||
|
||||
// Since this is not a local backup we need to stream the archive and then
|
||||
// parse over the contents as we go in order to restore it to the server.
|
||||
client := http.Client{}
|
||||
httpClient := http.Client{}
|
||||
logger.Info("downloading backup from remote location...")
|
||||
// TODO: this will hang if there is an issue. We can't use c.Request.Context() (or really any)
|
||||
// since it will be canceled when the request is closed which happens quickly since we push
|
||||
@@ -127,7 +129,7 @@ func postServerRestoreBackup(c *gin.Context) {
|
||||
middleware.CaptureAndAbort(c, err)
|
||||
return
|
||||
}
|
||||
res, err := client.Do(req)
|
||||
res, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
middleware.CaptureAndAbort(c, err)
|
||||
return
|
||||
@@ -143,7 +145,7 @@ func postServerRestoreBackup(c *gin.Context) {
|
||||
|
||||
go func(s *server.Server, uuid string, logger *log.Entry) {
|
||||
logger.Info("starting restoration process for server backup using S3 driver")
|
||||
if err := s.RestoreBackup(backup.NewS3(uuid, ""), res.Body); err != nil {
|
||||
if err := s.RestoreBackup(backup.NewS3(client, uuid, ""), res.Body); err != nil {
|
||||
logger.WithField("error", errors.WithStack(err)).Error("failed to restore remote S3 backup to server")
|
||||
}
|
||||
s.Events().Publish(server.DaemonMessageEvent, "Completed server restoration from S3 backup.")
|
||||
@@ -159,7 +161,7 @@ func postServerRestoreBackup(c *gin.Context) {
|
||||
// endpoint can make its own decisions as to how it wants to handle that
|
||||
// response.
|
||||
func deleteServerBackup(c *gin.Context) {
|
||||
b, _, err := backup.LocateLocal(c.Param("backup"))
|
||||
b, _, err := backup.LocateLocal(middleware.ExtractApiClient(c), c.Param("backup"))
|
||||
if err != nil {
|
||||
// Just return from the function at this point if the backup was not located.
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
|
||||
@@ -34,10 +34,11 @@ func getAllServers(c *gin.Context) {
|
||||
// Creates a new server on the wings daemon and begins the installation process
|
||||
// for it.
|
||||
func postCreateServer(c *gin.Context) {
|
||||
manager := middleware.ExtractManager(c)
|
||||
buf := bytes.Buffer{}
|
||||
buf.ReadFrom(c.Request.Body)
|
||||
|
||||
install, err := installer.New(buf.Bytes())
|
||||
install, err := installer.New(c.Request.Context(), manager, buf.Bytes())
|
||||
if err != nil {
|
||||
if installer.IsValidationError(err) {
|
||||
c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{
|
||||
@@ -52,7 +53,6 @@ func postCreateServer(c *gin.Context) {
|
||||
|
||||
// Plop that server instance onto the request so that it can be referenced in
|
||||
// requests from here-on out.
|
||||
manager := middleware.ExtractManager(c)
|
||||
manager.Add(install.Server())
|
||||
|
||||
// Begin the installation process in the background to not block the request
|
||||
|
||||
@@ -2,6 +2,7 @@ package router
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
@@ -22,9 +23,9 @@ import (
|
||||
"github.com/juju/ratelimit"
|
||||
"github.com/mholt/archiver/v3"
|
||||
"github.com/mitchellh/colorstring"
|
||||
"github.com/pterodactyl/wings/api"
|
||||
"github.com/pterodactyl/wings/config"
|
||||
"github.com/pterodactyl/wings/installer"
|
||||
"github.com/pterodactyl/wings/remote"
|
||||
"github.com/pterodactyl/wings/router/middleware"
|
||||
"github.com/pterodactyl/wings/router/tokens"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
@@ -109,10 +110,10 @@ func getServerArchive(c *gin.Context) {
|
||||
}
|
||||
|
||||
func postServerArchive(c *gin.Context) {
|
||||
s := ExtractServer(c)
|
||||
s := middleware.ExtractServer(c)
|
||||
manager := middleware.ExtractManager(c)
|
||||
|
||||
go func(s *server.Server) {
|
||||
r := api.New()
|
||||
l := log.WithField("server", s.Id())
|
||||
|
||||
// This function automatically adds the Source Node prefix and Timestamp to the log
|
||||
@@ -133,12 +134,11 @@ func postServerArchive(c *gin.Context) {
|
||||
|
||||
// Mark the server as not being transferred so it can actually be used.
|
||||
s.SetTransferring(false)
|
||||
|
||||
s.Events().Publish(server.TransferStatusEvent, "failure")
|
||||
|
||||
sendTransferLog("Attempting to notify panel of archive failure..")
|
||||
if err := r.SendArchiveStatus(s.Id(), false); err != nil {
|
||||
if !api.IsRequestError(err) {
|
||||
if err := manager.Client().SetArchiveStatus(s.Context(), s.Id(), false); err != nil {
|
||||
if !remote.IsRequestError(err) {
|
||||
sendTransferLog("Failed to notify panel of archive failure: " + err.Error())
|
||||
l.WithField("error", err).Error("failed to notify panel of failed archive status")
|
||||
return
|
||||
@@ -174,8 +174,8 @@ func postServerArchive(c *gin.Context) {
|
||||
sendTransferLog("Successfully created archive, attempting to notify panel..")
|
||||
l.Info("successfully created server transfer archive, notifying panel..")
|
||||
|
||||
if err := r.SendArchiveStatus(s.Id(), true); err != nil {
|
||||
if !api.IsRequestError(err) {
|
||||
if err := manager.Client().SetArchiveStatus(s.Context(), s.Id(), true); err != nil {
|
||||
if !remote.IsRequestError(err) {
|
||||
sendTransferLog("Failed to notify panel of archive success: " + err.Error())
|
||||
l.WithField("error", err).Error("failed to notify panel of successful archive status")
|
||||
return
|
||||
@@ -275,10 +275,10 @@ func (str serverTransferRequest) verifyChecksum(matches string) (bool, string, e
|
||||
}
|
||||
|
||||
// Sends a notification to the Panel letting it know what the status of this transfer is.
|
||||
func (str serverTransferRequest) sendTransferStatus(successful bool) error {
|
||||
func (str serverTransferRequest) sendTransferStatus(client remote.Client, successful bool) error {
|
||||
lg := str.log().WithField("transfer_successful", successful)
|
||||
lg.Info("notifying Panel of server transfer state")
|
||||
if err := api.New().SendTransferStatus(str.ServerID, successful); err != nil {
|
||||
if err := client.SetTransferStatus(context.Background(), str.ServerID, successful); err != nil {
|
||||
lg.WithField("error", err).Error("error notifying panel of transfer state")
|
||||
return err
|
||||
}
|
||||
@@ -294,6 +294,7 @@ func postTransfer(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
manager := middleware.ExtractManager(c)
|
||||
u, err := uuid.Parse(data.ServerID)
|
||||
if err != nil {
|
||||
WithError(c, err)
|
||||
@@ -310,9 +311,9 @@ func postTransfer(c *gin.Context) {
|
||||
|
||||
// Create a new server installer. This will only configure the environment and not
|
||||
// run the installer scripts.
|
||||
i, err := installer.New(data.Server)
|
||||
i, err := installer.New(context.Background(), manager, data.Server)
|
||||
if err != nil {
|
||||
_ = data.sendTransferStatus(false)
|
||||
_ = data.sendTransferStatus(manager.Client(), false)
|
||||
data.log().WithField("error", err).Error("failed to validate received server data")
|
||||
return
|
||||
}
|
||||
@@ -324,7 +325,6 @@ func postTransfer(c *gin.Context) {
|
||||
i.Server().Events().Publish(server.TransferLogsEvent, output)
|
||||
}
|
||||
|
||||
manager := middleware.ExtractManager(c)
|
||||
// Mark the server as transferring to prevent problems later on during the process and
|
||||
// then push the server into the global server collection for this instance.
|
||||
i.Server().SetTransferring(true)
|
||||
@@ -332,7 +332,7 @@ func postTransfer(c *gin.Context) {
|
||||
defer func(s *server.Server) {
|
||||
// In the event that this transfer call fails, remove the server from the global
|
||||
// server tracking so that we don't have a dangling instance.
|
||||
if err := data.sendTransferStatus(!hasError); hasError || err != nil {
|
||||
if err := data.sendTransferStatus(manager.Client(), !hasError); hasError || err != nil {
|
||||
sendTransferLog("Server transfer failed, check Wings logs for additional information.")
|
||||
s.Events().Publish(server.TransferStatusEvent, "failure")
|
||||
manager.Remove(func(match *server.Server) bool {
|
||||
|
||||
Reference in New Issue
Block a user