2017-08-02 20:02:34 +00:00
|
|
|
package api
|
|
|
|
|
2017-10-01 18:42:17 +00:00
|
|
|
import (
|
|
|
|
"net/http"
|
2017-08-02 20:02:34 +00:00
|
|
|
|
2018-02-20 22:36:17 +00:00
|
|
|
"strconv"
|
|
|
|
|
2017-10-01 18:42:17 +00:00
|
|
|
"github.com/gin-gonic/gin"
|
2018-02-20 22:36:17 +00:00
|
|
|
"github.com/google/jsonapi"
|
2018-02-20 20:25:31 +00:00
|
|
|
"github.com/pterodactyl/wings/control"
|
2017-10-01 18:42:17 +00:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
)
|
2017-08-02 20:02:34 +00:00
|
|
|
|
2017-10-01 18:42:17 +00:00
|
|
|
// GET /servers
|
|
|
|
func handleGetServers(c *gin.Context) {
|
|
|
|
servers := control.GetServers()
|
2018-02-20 22:36:17 +00:00
|
|
|
sendData(c, servers)
|
2017-08-02 20:02:34 +00:00
|
|
|
}
|
|
|
|
|
2017-10-01 18:42:17 +00:00
|
|
|
// POST /servers
|
2017-08-02 20:02:34 +00:00
|
|
|
func handlePostServers(c *gin.Context) {
|
2017-10-01 18:42:17 +00:00
|
|
|
server := control.ServerStruct{}
|
|
|
|
if err := c.BindJSON(&server); err != nil {
|
|
|
|
log.WithField("server", server).WithError(err).Error("Failed to parse server request.")
|
2018-02-20 22:36:17 +00:00
|
|
|
sendErrors(c, http.StatusBadRequest, &jsonapi.ErrorObject{
|
|
|
|
Status: strconv.Itoa(http.StatusBadRequest),
|
|
|
|
Title: "The passed server object is invalid.",
|
|
|
|
})
|
2017-10-01 18:42:17 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
var srv control.Server
|
|
|
|
var err error
|
|
|
|
if srv, err = control.CreateServer(&server); err != nil {
|
|
|
|
if _, ok := err.(control.ErrServerExists); ok {
|
|
|
|
log.WithError(err).Error("Cannot create server, it already exists.")
|
|
|
|
c.Status(http.StatusBadRequest)
|
2018-02-20 22:36:17 +00:00
|
|
|
sendErrors(c, http.StatusConflict, &jsonapi.ErrorObject{
|
|
|
|
Status: strconv.Itoa(http.StatusConflict),
|
|
|
|
Title: "A server with this ID already exists.",
|
|
|
|
})
|
2017-10-01 18:42:17 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
log.WithField("server", server).WithError(err).Error("Failed to create server.")
|
2018-02-20 22:36:17 +00:00
|
|
|
sendInternalError(c, "Failed to create the server", "")
|
2017-10-01 18:42:17 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
go func() {
|
|
|
|
env, err := srv.Environment()
|
|
|
|
if err != nil {
|
|
|
|
log.WithField("server", srv).WithError(err).Error("Failed to get server environment.")
|
|
|
|
}
|
|
|
|
env.Create()
|
|
|
|
}()
|
2018-02-20 22:36:17 +00:00
|
|
|
sendDataStatus(c, http.StatusCreated, srv)
|
2017-08-02 20:02:34 +00:00
|
|
|
}
|
|
|
|
|
2017-10-01 18:42:17 +00:00
|
|
|
// GET /servers/:server
|
2017-08-02 20:02:34 +00:00
|
|
|
func handleGetServer(c *gin.Context) {
|
2017-10-01 18:42:17 +00:00
|
|
|
id := c.Param("server")
|
|
|
|
server := control.GetServer(id)
|
|
|
|
if server == nil {
|
2018-02-20 22:36:17 +00:00
|
|
|
sendErrors(c, http.StatusNotFound, &jsonapi.ErrorObject{
|
|
|
|
Code: strconv.Itoa(http.StatusNotFound),
|
|
|
|
Title: "Server not found.",
|
|
|
|
Detail: "The requested Server with the id " + id + " couldn't be found.",
|
|
|
|
})
|
2017-10-01 18:42:17 +00:00
|
|
|
return
|
|
|
|
}
|
2018-02-20 22:36:17 +00:00
|
|
|
sendData(c, server)
|
2017-08-02 20:02:34 +00:00
|
|
|
}
|
|
|
|
|
2017-10-01 18:42:17 +00:00
|
|
|
// PATCH /servers/:server
|
2017-08-02 20:02:34 +00:00
|
|
|
func handlePatchServer(c *gin.Context) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-10-01 18:42:17 +00:00
|
|
|
// DELETE /servers/:server
|
|
|
|
func handleDeleteServer(c *gin.Context) {
|
|
|
|
id := c.Param("server")
|
|
|
|
server := control.GetServer(id)
|
|
|
|
if server == nil {
|
|
|
|
c.Status(http.StatusNotFound)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
env, err := server.Environment()
|
|
|
|
if err != nil {
|
2018-02-20 22:36:17 +00:00
|
|
|
sendInternalError(c, "The server could not be deleted.", "")
|
|
|
|
return
|
2017-10-01 18:42:17 +00:00
|
|
|
}
|
|
|
|
if err := env.Destroy(); err != nil {
|
|
|
|
log.WithError(err).Error("Failed to delete server, the environment couldn't be destroyed.")
|
2018-02-20 22:36:17 +00:00
|
|
|
sendInternalError(c, "The server could not be deleted.", "The server environment couldn't be destroyed.")
|
|
|
|
return
|
2017-10-01 18:42:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := control.DeleteServer(id); err != nil {
|
|
|
|
log.WithError(err).Error("Failed to delete server.")
|
2018-02-20 22:36:17 +00:00
|
|
|
sendInternalError(c, "The server could not be deleted.", "")
|
2017-10-01 18:42:17 +00:00
|
|
|
return
|
|
|
|
}
|
2018-02-20 22:36:17 +00:00
|
|
|
c.Status(http.StatusNoContent)
|
2017-10-01 18:42:17 +00:00
|
|
|
}
|
|
|
|
|
2017-08-02 20:02:34 +00:00
|
|
|
func handlePostServerReinstall(c *gin.Context) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func handlePostServerPassword(c *gin.Context) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func handlePostServerRebuild(c *gin.Context) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-10-01 18:42:17 +00:00
|
|
|
// POST /servers/:server/power
|
|
|
|
func handlePostServerPower(c *gin.Context) {
|
|
|
|
server := getServerFromContext(c)
|
|
|
|
if server == nil {
|
|
|
|
c.Status(http.StatusNotFound)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
auth := GetContextAuthManager(c)
|
|
|
|
if auth == nil {
|
2018-02-20 22:36:17 +00:00
|
|
|
sendInternalError(c, "An internal error occured.", "")
|
2017-10-01 18:42:17 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
switch c.Query("action") {
|
|
|
|
case "start":
|
|
|
|
{
|
|
|
|
if !auth.HasPermission("s:power:start") {
|
2018-02-20 22:36:17 +00:00
|
|
|
sendForbidden(c)
|
2017-10-01 18:42:17 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
server.Start()
|
|
|
|
}
|
|
|
|
case "stop":
|
|
|
|
{
|
|
|
|
if !auth.HasPermission("s:power:stop") {
|
2018-02-20 22:36:17 +00:00
|
|
|
sendForbidden(c)
|
2017-10-01 18:42:17 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
server.Stop()
|
|
|
|
}
|
|
|
|
case "restart":
|
|
|
|
{
|
|
|
|
if !auth.HasPermission("s:power:restart") {
|
2018-02-20 22:36:17 +00:00
|
|
|
sendForbidden(c)
|
2017-10-01 18:42:17 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
server.Restart()
|
|
|
|
}
|
|
|
|
case "kill":
|
|
|
|
{
|
|
|
|
if !auth.HasPermission("s:power:kill") {
|
2018-02-20 22:36:17 +00:00
|
|
|
sendForbidden(c)
|
2017-10-01 18:42:17 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
server.Kill()
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
c.Status(http.StatusBadRequest)
|
|
|
|
}
|
|
|
|
}
|
2017-08-02 20:02:34 +00:00
|
|
|
}
|
|
|
|
|
2017-10-01 18:42:17 +00:00
|
|
|
// POST /servers/:server/command
|
2017-08-02 20:02:34 +00:00
|
|
|
func handlePostServerCommand(c *gin.Context) {
|
2017-10-01 18:42:17 +00:00
|
|
|
server := getServerFromContext(c)
|
|
|
|
cmd := c.Query("command")
|
|
|
|
server.Exec(cmd)
|
2018-02-20 22:36:17 +00:00
|
|
|
c.Status(204)
|
|
|
|
}
|
|
|
|
|
|
|
|
func handleGetConsole(c *gin.Context) {
|
|
|
|
server := getServerFromContext(c)
|
|
|
|
server.Websockets().Upgrade(c.Writer, c.Request)
|
2017-08-02 20:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func handlePostServerSuspend(c *gin.Context) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func handlePostServerUnsuspend(c *gin.Context) {
|
|
|
|
|
|
|
|
}
|