diff --git a/client/client.go b/client/client.go index 1fbf6e2..9773612 100644 --- a/client/client.go +++ b/client/client.go @@ -63,6 +63,49 @@ func StatusThread(host string) { state.State.Mutex.Unlock() } +func Command(command string) { + for host := range config.Config.Hosts { + state.State.Mutex.Lock() + state.State.Machines[host] = state.Machine{ + State: state.Working, + JobStart: time.Now(), + } + state.State.Mutex.Unlock() + go CommandThread(host, command) + } + DisplayState() +} + +func CommandThread(host string, command string) { + base, err := url.Parse("http://" + config.Config.Hosts[host] + constants.HostEndpoint) + utils.CheckError(err) + base.Path += "command" + params := url.Values{} + params.Add("token", auth.CreateToken()) + params.Add("command", command) + base.RawQuery = params.Encode() + client := http.Client{ + Timeout: config.Config.CommandTimeout, + } + resp, err := client.Get(base.String()) + if utils.JobFailed(err, host) { + return + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if utils.JobFailed(err, host) { + return + } + state.State.Mutex.Lock() + state.State.Machines[host] = state.Machine{ + State: state.Completed, + JobStart: state.State.Machines[host].JobStart, + JobEnd: time.Now(), + Message: string(body), + } + state.State.Mutex.Unlock() +} + func DisplayState() { finished := false for !finished { diff --git a/config/config.go b/config/config.go index 4be96d5..7f9e695 100644 --- a/config/config.go +++ b/config/config.go @@ -1,20 +1,31 @@ package config +import "time" + type ConfigStruct struct { - Hosts map[string]string + Hosts map[string]string + Commands map[string][]string + CommandTimeout time.Duration } var Config = ConfigStruct{ Hosts: map[string]string{ - "alpha": "127.0.0.1", - "beta": "127.0.0.1", + "alpha": "127.0.0.1", + /*"beta": "127.0.0.1", "gamma": "127.0.0.1", "delta": "127.0.0.1", "epsilon": "127.0.0.1", "zeta": "127.0.0.1", "eta": "127.0.0.1", - "omega": "127.0.0.1", + "omega": "127.0.0.1",*/ }, + Commands: map[string][]string{ + "update": {"yes", "|", "sudo", "pacman", "-Syyu"}, + "neofetch": {"neofetch"}, + "uptime": {"uptime"}, + "uname": {"uname", "-A"}, + }, + CommandTimeout: 20 * time.Minute, } var AuthSecret = []byte("ChangeMe!") diff --git a/kon b/kon index eadd339..e9bc322 100755 Binary files a/kon and b/kon differ diff --git a/main.go b/main.go index d3f5a6e..b638ccb 100644 --- a/main.go +++ b/main.go @@ -25,6 +25,14 @@ func main() { log.Fatal("Cannot find command.") } + } else if len(args) == 3 { + switch args[1] { + case "command": + client.Command(args[2]) + default: + log.Fatal("Cannot find command.") + } + } else { log.Fatal("Too many arguments.") } diff --git a/pon/middlewares/middlewares.go b/pon/middlewares/middlewares.go index d2cc2db..7be63a1 100644 --- a/pon/middlewares/middlewares.go +++ b/pon/middlewares/middlewares.go @@ -3,9 +3,11 @@ package middlewares import ( "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" + "github.com/gofiber/fiber/v2/middleware/recover" ) func Init(app *fiber.App) { + app.Use(recover.New()) app.Use(logger.New(logger.Config{ TimeFormat: "2006-01-02 15:04:05", })) diff --git a/pon/paths/command/command.go b/pon/paths/command/command.go new file mode 100644 index 0000000..c5b418c --- /dev/null +++ b/pon/paths/command/command.go @@ -0,0 +1,31 @@ +package command + +import ( + "kon/auth" + "kon/config" + "kon/utils" + "os/exec" + + "github.com/gofiber/fiber/v2" +) + +func HandleFunc(c *fiber.Ctx) error { + queryValue := c.Query("token") + command := c.Query("command") + if auth.VerifyToken(queryValue) { + val, ok := config.Config.Commands[command] + if !ok { + return c.SendString("Command not found.") + } else { + cmd := exec.Command(val[0]) + if len(val) > 1 { + cmd = exec.Command(val[0], val[1:]...) + } + err := cmd.Run() + utils.CheckError(err) + return c.SendString("Command was run successfully!") + } + } else { + return c.SendString("Auth failed!") + } +} diff --git a/pon/paths/paths.go b/pon/paths/paths.go index b8a40a4..b606f31 100644 --- a/pon/paths/paths.go +++ b/pon/paths/paths.go @@ -1,6 +1,7 @@ package paths import ( + "kon/pon/paths/command" "kon/pon/paths/status" "github.com/gofiber/fiber/v2" @@ -8,4 +9,5 @@ import ( func Init(app *fiber.App) { app.Get("/status", status.HandleFunc) + app.Get("/command", command.HandleFunc) } diff --git a/pon/paths/status/status.go b/pon/paths/status/status.go index cd37090..e8b8d89 100644 --- a/pon/paths/status/status.go +++ b/pon/paths/status/status.go @@ -42,6 +42,6 @@ func HandleFunc(c *fiber.Ctx) error { utils.CheckError(err) return c.SendString(string(statusJSON)) } else { - return c.SendString("no") + return c.SendString("Auth failed!") } }