mirror of
https://github.com/ngoduykhanh/wireguard-ui.git
synced 2025-05-24 00:24:06 +03:00
Implements Wake On Lan and management features (#164)
This commit is contained in:
parent
037a6c56d3
commit
0224e1f137
12 changed files with 638 additions and 21 deletions
171
handler/routes_wake_on_lan.go
Normal file
171
handler/routes_wake_on_lan.go
Normal file
|
@ -0,0 +1,171 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/gommon/log"
|
||||
"github.com/ngoduykhanh/wireguard-ui/model"
|
||||
"github.com/ngoduykhanh/wireguard-ui/store"
|
||||
"github.com/sabhiram/go-wol/wol"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type WakeOnLanHostSavePayload struct {
|
||||
Name string `json:"name"`
|
||||
MacAddress string `json:"mac_address"`
|
||||
OldMacAddress string `json:"old_mac_address"`
|
||||
}
|
||||
|
||||
func createError(c echo.Context, err error, msg string) error {
|
||||
log.Error(msg, err)
|
||||
return c.JSON(
|
||||
http.StatusInternalServerError,
|
||||
jsonHTTPResponse{
|
||||
false,
|
||||
msg})
|
||||
}
|
||||
|
||||
func GetWakeOnLanHosts(db store.IStore) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
var err error
|
||||
|
||||
hosts, err := db.GetWakeOnLanHosts()
|
||||
if err != nil {
|
||||
return createError(c, err, fmt.Sprintf("wake_on_lan_hosts database error: %s", err))
|
||||
}
|
||||
|
||||
err = c.Render(http.StatusOK, "wake_on_lan_hosts.html", map[string]interface{}{
|
||||
"baseData": model.BaseData{Active: "wake_on_lan_hosts", CurrentUser: currentUser(c)},
|
||||
"hosts": hosts,
|
||||
"error": "",
|
||||
})
|
||||
if err != nil {
|
||||
return createError(c, err, fmt.Sprintf("wake_on_lan_hosts.html render error: %s", err))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func SaveWakeOnLanHost(db store.IStore) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
var payload WakeOnLanHostSavePayload
|
||||
err := c.Bind(&payload)
|
||||
if err != nil {
|
||||
log.Error("Wake On Host Save Payload Bind Error: ", err)
|
||||
return c.JSON(http.StatusInternalServerError, payload)
|
||||
}
|
||||
|
||||
var host = model.WakeOnLanHost{
|
||||
MacAddress: payload.MacAddress,
|
||||
Name: payload.Name,
|
||||
}
|
||||
if len(payload.OldMacAddress) != 0 { // Edit
|
||||
if payload.OldMacAddress != payload.MacAddress { // modified mac address
|
||||
oldHost, err := db.GetWakeOnLanHost(payload.OldMacAddress)
|
||||
if err != nil {
|
||||
return createError(c, err, fmt.Sprintf("Wake On Host Update Err: %s", err))
|
||||
}
|
||||
|
||||
if payload.OldMacAddress != payload.MacAddress {
|
||||
existHost, _ := db.GetWakeOnLanHost(payload.MacAddress)
|
||||
if existHost != nil {
|
||||
return createError(c, nil, "Mac Address already exists.")
|
||||
}
|
||||
}
|
||||
|
||||
err = db.DeleteWakeOnHostLanHost(payload.OldMacAddress)
|
||||
if err != nil {
|
||||
return createError(c, err, fmt.Sprintf("Wake On Host Update Err: %s", err))
|
||||
}
|
||||
host.LatestUsed = oldHost.LatestUsed
|
||||
}
|
||||
err = db.SaveWakeOnLanHost(host)
|
||||
} else { // new
|
||||
existHost, _ := db.GetWakeOnLanHost(payload.MacAddress)
|
||||
if existHost != nil {
|
||||
return createError(c, nil, "Mac Address already exists.")
|
||||
}
|
||||
|
||||
err = db.SaveWakeOnLanHost(host)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return createError(c, err, fmt.Sprintf("Wake On Host Save Error: %s", err))
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, host)
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteWakeOnHost(db store.IStore) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
var macAddress = c.Param("mac_address")
|
||||
var host, err = db.GetWakeOnLanHost(macAddress)
|
||||
|
||||
if err != nil {
|
||||
log.Error("Wake On Host Delete Error: ", err)
|
||||
return createError(c, err, fmt.Sprintf("Wake On Host Delete Error: %s", macAddress))
|
||||
}
|
||||
|
||||
err = db.DeleteWakeOnHost(*host)
|
||||
if err != nil {
|
||||
return createError(c, err, fmt.Sprintf("Wake On Host Delete Error: %s", macAddress))
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func WakeOnHost(db store.IStore) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
macAddress := c.Param("mac_address")
|
||||
host, err := db.GetWakeOnLanHost(macAddress)
|
||||
|
||||
now := time.Now().UTC()
|
||||
host.LatestUsed = &now
|
||||
err = db.SaveWakeOnLanHost(*host)
|
||||
if err != nil {
|
||||
return createError(c, err, fmt.Sprintf("Latest Used Update Error: %s", macAddress))
|
||||
}
|
||||
|
||||
magicPacket, err := wol.New(macAddress)
|
||||
if err != nil {
|
||||
return createError(c, err, fmt.Sprintf("Magic Packet Create Error: %s", macAddress))
|
||||
}
|
||||
|
||||
bytes, err := magicPacket.Marshal()
|
||||
if err != nil {
|
||||
return createError(c, err, fmt.Sprintf("Magic Packet Bytestream Error: %s", macAddress))
|
||||
}
|
||||
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", "255.255.255.255:0")
|
||||
if err != nil {
|
||||
return createError(c, err, fmt.Sprintf("ResolveUDPAddr Error: %s", macAddress))
|
||||
}
|
||||
|
||||
// Grab a UDP connection to send our packet of bytes.
|
||||
conn, err := net.DialUDP("udp", nil, udpAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(conn *net.UDPConn) {
|
||||
err := conn.Close()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}(conn)
|
||||
|
||||
n, err := conn.Write(bytes)
|
||||
if err == nil && n != 102 {
|
||||
return createError(c, nil, fmt.Sprintf("magic packet sent was %d bytes (expected 102 bytes sent)", n))
|
||||
}
|
||||
if err != nil {
|
||||
return createError(c, err, fmt.Sprintf("Network Send Error: %s", macAddress))
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, host.LatestUsed)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue