node-api/main.go

288 lines
7.3 KiB
Go
Raw Normal View History

2020-07-08 22:09:19 +00:00
package main
import (
2020-07-11 21:14:45 +00:00
"log"
2020-07-08 22:09:19 +00:00
"net/http"
"github.com/labstack/echo"
2020-07-13 22:01:42 +00:00
"github.com/rosti-cz/node-api/apps"
"github.com/rosti-cz/node-api/common"
"github.com/rosti-cz/node-api/docker"
"github.com/rosti-cz/node-api/nodes"
2020-07-08 22:09:19 +00:00
)
// JSONIndent Indendation of JSON output format
const JSONIndent = " "
func main() {
// Close database at the end
db := common.GetDBConnection()
2020-07-11 11:04:37 +00:00
// db.AutoMigrate(apps.Label{})
// db.AutoMigrate(apps.App{})
2020-07-08 22:09:19 +00:00
defer db.Close()
2020-07-13 22:01:42 +00:00
// Templating
t := &Template{}
2020-07-08 22:09:19 +00:00
// API
e := echo.New()
2020-07-13 22:01:42 +00:00
e.Renderer = t
// e.Use(TokenMiddleware)
2020-07-08 22:09:19 +00:00
// Returns list of apps
2020-07-13 22:01:42 +00:00
e.GET("/", func(c echo.Context) error {
return c.Render(http.StatusOK, "index.html", "")
})
2020-07-08 22:09:19 +00:00
e.GET("/v1/apps", func(c echo.Context) error {
2020-07-11 21:14:45 +00:00
applications, err := apps.List()
2020-07-08 22:09:19 +00:00
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
2020-07-15 21:32:28 +00:00
return c.JSON(http.StatusOK, applications)
2020-07-08 22:09:19 +00:00
})
// Returns one app
e.GET("/v1/apps/:name", func(c echo.Context) error {
name := c.Param("name")
app, err := apps.Get(name)
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
return c.JSON(http.StatusOK, app)
})
// Create a new app
e.POST("/v1/apps", func(c echo.Context) error {
app := apps.App{}
err := c.Bind(&app)
if err != nil {
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
}
err = apps.New(app.Name, app.SSHPort, app.HTTPPort, app.Image, app.CPU, app.Memory)
if err != nil {
2020-07-09 22:27:23 +00:00
if validationError, ok := err.(apps.ValidationError); ok {
return c.JSONPretty(http.StatusBadRequest, Message{Errors: validationError.Errors}, JSONIndent)
}
2020-07-08 22:09:19 +00:00
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
2020-07-11 11:04:37 +00:00
container := docker.Container{
2020-07-11 21:14:45 +00:00
App: &app,
2020-07-11 11:04:37 +00:00
}
err = container.Create()
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
err = container.Start()
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
return c.JSON(http.StatusOK, Message{Message: "ok"})
2020-07-08 22:09:19 +00:00
})
// Update existing app
e.PUT("/v1/apps/:name", func(c echo.Context) error {
name := c.Param("name")
app := apps.App{}
err := c.Bind(&app)
if err != nil {
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
}
2020-07-11 11:04:37 +00:00
appPointer, err := apps.Update(name, app.SSHPort, app.HTTPPort, app.Image, app.CPU, app.Memory)
2020-07-08 22:09:19 +00:00
if err != nil {
2020-07-09 22:27:23 +00:00
if validationError, ok := err.(apps.ValidationError); ok {
return c.JSONPretty(http.StatusBadRequest, Message{Errors: validationError.Errors}, JSONIndent)
}
2020-07-08 22:09:19 +00:00
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
2020-07-11 11:04:37 +00:00
app = *appPointer
container := docker.Container{
2020-07-11 21:14:45 +00:00
App: &app,
2020-07-11 11:04:37 +00:00
}
err = container.Destroy()
2020-07-14 21:40:47 +00:00
if err != nil && err.Error() == "no container found" {
// We don't care if the container didn't exist anyway
err = nil
2020-07-11 11:04:37 +00:00
}
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
2020-07-14 21:40:47 +00:00
err = container.Create()
2020-07-11 11:04:37 +00:00
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
2020-07-14 21:40:47 +00:00
return c.JSON(http.StatusOK, Message{Message: "ok"})
2020-07-08 22:09:19 +00:00
})
// Stop existing app
e.PUT("/v1/apps/:name/stop", func(c echo.Context) error {
2020-07-11 21:14:45 +00:00
name := c.Param("name")
app, err := apps.Get(name)
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
container := docker.Container{
App: app,
}
err = container.Stop()
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
return c.JSON(http.StatusOK, Message{Message: "ok"})
2020-07-08 22:09:19 +00:00
})
// Start existing app
e.PUT("/v1/apps/:name/start", func(c echo.Context) error {
2020-07-11 11:04:37 +00:00
name := c.Param("name")
app, err := apps.Get(name)
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
container := docker.Container{
2020-07-11 21:14:45 +00:00
App: app,
2020-07-11 11:04:37 +00:00
}
err = container.Start()
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
return c.JSON(http.StatusOK, Message{Message: "ok"})
2020-07-08 22:09:19 +00:00
})
// Stop existing app
e.PUT("/v1/apps/:name/restart", func(c echo.Context) error {
2020-07-11 21:14:45 +00:00
name := c.Param("name")
app, err := apps.Get(name)
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
container := docker.Container{
App: app,
}
err = container.Restart()
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
return c.JSON(http.StatusOK, Message{Message: "ok"})
})
// Stats for existing app
e.GET("/v1/apps/:name/stats", func(c echo.Context) error {
name := c.Param("name")
app, err := apps.Get(name)
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
container := docker.Container{
App: app,
}
cpu, memory, err := container.ResourceUsage()
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
log.Println("DEBUG", cpu, memory)
return c.JSON(http.StatusOK, Message{Message: "ok"})
2020-07-08 22:09:19 +00:00
})
// Rebuilds existing app, it keeps the data but created the container again
e.PUT("/v1/apps/:name/rebuild", func(c echo.Context) error {
2020-07-11 21:14:45 +00:00
name := c.Param("name")
app, err := apps.Get(name)
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
container := docker.Container{
App: app,
}
err = container.Destroy()
2020-07-13 22:01:42 +00:00
if err != nil && err.Error() == "no container found" {
// We don't care if the container didn't exist anyway
err = nil
}
2020-07-11 21:14:45 +00:00
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
err = container.Create()
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
return c.JSON(http.StatusOK, Message{Message: "ok"})
2020-07-08 22:09:19 +00:00
})
// Delete one app
e.DELETE("/v1/apps/:name", func(c echo.Context) error {
name := c.Param("name")
2020-07-11 21:14:45 +00:00
app, err := apps.Get(name)
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
container := docker.Container{
App: app,
}
err = container.Delete()
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
err = apps.Delete(name)
2020-07-08 22:09:19 +00:00
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
return c.JSON(http.StatusOK, Message{Message: "deleted"})
})
2020-07-13 22:01:42 +00:00
// Orphans returns directories in /srv that doesn't match any hosted application
e.GET("/v1/orphans", func(c echo.Context) error {
return c.JSON(http.StatusOK, []string{})
})
2020-07-08 22:09:19 +00:00
// Return info about the node including performance index
e.GET("/v1/node", func(c echo.Context) error {
node := nodes.GetNodeInfo()
return c.JSON(http.StatusOK, node)
})
e.Logger.Fatal(e.Start(":1323"))
}