diff --git a/backend/networking/scan.go b/backend/pb/handlers.go similarity index 53% rename from backend/networking/scan.go rename to backend/pb/handlers.go index 7ed61c62..d39821e7 100644 --- a/backend/networking/scan.go +++ b/backend/pb/handlers.go @@ -1,4 +1,4 @@ -package networking +package pb import ( "encoding/xml" @@ -9,8 +9,46 @@ import ( "github.com/labstack/echo/v5" "github.com/pocketbase/pocketbase/apis" + "github.com/pocketbase/pocketbase/models" + "github.com/seriousm4x/upsnap/backend/logger" + "github.com/seriousm4x/upsnap/backend/networking" ) +func HandlerWake(c echo.Context) error { + record, err := App.Dao().FindFirstRecordByData("devices", "id", c.PathParam("id")) + if err != nil { + return apis.NewNotFoundError("The device does not exist.", err) + } + go func(*models.Record) { + record.Set("status", "pending") + App.Dao().SaveRecord(record) + isOnline := networking.WakeDevice(record) + if isOnline { + record.Set("status", "online") + } else { + record.Set("status", "offline") + } + App.Dao().SaveRecord(record) + }(record) + return c.JSON(http.StatusOK, record) +} + +func HandlerShutdown(c echo.Context) error { + record, err := App.Dao().FindFirstRecordByData("devices", "id", c.PathParam("id")) + if err != nil { + return apis.NewNotFoundError("The device does not exist.", err) + } + shutdown_cmd := record.GetString("shutdown_cmd") + if shutdown_cmd != "" { + cmd := exec.Command(shutdown_cmd) + if err := cmd.Run(); err != nil { + logger.Error.Println(err) + return apis.NewBadRequestError(err.Error(), record) + } + } + return nil +} + type Nmaprun struct { Host []struct { Address []struct { @@ -21,7 +59,7 @@ type Nmaprun struct { } `xml:"host"` } -func ScanNetwork(c echo.Context) error { +func HandlerScan(c echo.Context) error { scanRange := os.Getenv("UPSNAP_SCAN_RANGE") _, _, err := net.ParseCIDR(scanRange) if err != nil { diff --git a/backend/pb/pb.go b/backend/pb/pb.go index 189cd2f1..09ad774c 100644 --- a/backend/pb/pb.go +++ b/backend/pb/pb.go @@ -4,130 +4,112 @@ import ( "log" "net/http" "os" - "os/exec" "github.com/labstack/echo/v5" "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/apis" "github.com/pocketbase/pocketbase/core" - "github.com/pocketbase/pocketbase/models" "github.com/pocketbase/pocketbase/plugins/migratecmd" "github.com/seriousm4x/upsnap/backend/cronjobs" "github.com/seriousm4x/upsnap/backend/logger" _ "github.com/seriousm4x/upsnap/backend/migrations" - "github.com/seriousm4x/upsnap/backend/networking" ) -var app *pocketbase.PocketBase +var App *pocketbase.PocketBase func StartPocketBase() { - app = pocketbase.New() + App = pocketbase.New() // auto migrate db - migratecmd.MustRegister(app, app.RootCmd, &migratecmd.Options{ + migratecmd.MustRegister(App, App.RootCmd, &migratecmd.Options{ Automigrate: true, }) // event hooks - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + App.OnBeforeServe().Add(func(e *core.ServeEvent) error { // set static website path e.Router.GET("/*", apis.StaticDirectoryHandler(os.DirFS("./pb_public"), true)) // add wake route to api e.Router.AddRoute(echo.Route{ - Method: http.MethodGet, - Path: "/api/upsnap/wake/:id", - Handler: func(c echo.Context) error { - record, err := app.Dao().FindFirstRecordByData("devices", "id", c.PathParam("id")) - if err != nil { - return apis.NewNotFoundError("The device does not exist.", err) - } - go func(*models.Record) { - record.Set("status", "pending") - app.Dao().SaveRecord(record) - isOnline := networking.WakeDevice(record) - if isOnline { - record.Set("status", "online") - } else { - record.Set("status", "offline") - } - app.Dao().SaveRecord(record) - }(record) - return c.JSON(http.StatusOK, record) - }, + Method: http.MethodGet, + Path: "/api/upsnap/wake/:id", + Handler: HandlerWake, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), - }, - }) - - // add shutdown route to api - e.Router.AddRoute(echo.Route{ - Method: http.MethodGet, - Path: "/api/upsnap/shutdown/:id", - Handler: func(c echo.Context) error { - record, err := app.Dao().FindFirstRecordByData("devices", "id", c.PathParam("id")) - if err != nil { - return apis.NewNotFoundError("The device does not exist.", err) - } - shutdown_cmd := record.GetString("shutdown_cmd") - if shutdown_cmd != "" { - cmd := exec.Command(shutdown_cmd) - if err := cmd.Run(); err != nil { - logger.Error.Println(err) - return apis.NewBadRequestError(err.Error(), record) - } - } - return nil + apis.ActivityLogger(App), }, }) // add shutdown route to api + e.Router.AddRoute(echo.Route{ + Method: http.MethodGet, + Path: "/api/upsnap/shutdown/:id", + Handler: HandlerShutdown, + Middlewares: []echo.MiddlewareFunc{ + apis.ActivityLogger(App), + }, + }) + + // add network scan route to api e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/upsnap/scan", - Handler: networking.ScanNetwork, + Handler: HandlerScan, + Middlewares: []echo.MiddlewareFunc{ + apis.ActivityLogger(App), + }, }) // reset device states and run ping cronjob - devices, err := app.Dao().FindRecordsByExpr("devices") - if err != nil { + if err := resetDeviceStates(); err != nil { return err } - for _, device := range devices { - device.Set("status", "offline") - if err := app.Dao().SaveRecord(device); err != nil { - return err - } - } - cronjobs.Devices = devices - go cronjobs.RunCron(app) + + // run ping cronjob + go cronjobs.RunCron(App) + return nil }) // refresh the device list on database events - app.OnModelAfterCreate().Add(func(e *core.ModelEvent) error { + App.OnModelAfterCreate().Add(func(e *core.ModelEvent) error { refreshDeviceList() return nil }) - app.OnModelAfterUpdate().Add(func(e *core.ModelEvent) error { + App.OnModelAfterUpdate().Add(func(e *core.ModelEvent) error { refreshDeviceList() return nil }) - app.OnModelAfterDelete().Add(func(e *core.ModelEvent) error { + App.OnModelAfterDelete().Add(func(e *core.ModelEvent) error { refreshDeviceList() return nil }) // start pocketbase - if err := app.Start(); err != nil { + if err := App.Start(); err != nil { log.Fatal(err) } } +func resetDeviceStates() error { + devices, err := App.Dao().FindRecordsByExpr("devices") + if err != nil { + return err + } + for _, device := range devices { + device.Set("status", "offline") + if err := App.Dao().SaveRecord(device); err != nil { + return err + } + } + cronjobs.Devices = devices + return nil +} + func refreshDeviceList() { var err error - cronjobs.Devices, err = app.Dao().FindRecordsByExpr("devices") + cronjobs.Devices, err = App.Dao().FindRecordsByExpr("devices") if err != nil { logger.Error.Println(err) }