kon/client/client.go

142 lines
3.6 KiB
Go

package client
import (
"encoding/json"
"fmt"
"io"
"kon/auth"
"kon/banner"
"kon/client/state"
"kon/config"
"kon/constants"
"kon/pon/paths/status"
"kon/utils"
"net/http"
"net/url"
"sort"
"time"
"github.com/fatih/color"
)
func Status() {
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 StatusThread(host)
}
DisplayState()
}
func StatusThread(host string) {
base, err := url.Parse("http://" + config.Config.Hosts[host] + constants.HostEndpoint)
utils.CheckError(err)
base.Path += "status"
params := url.Values{}
params.Add("token", auth.CreateToken())
base.RawQuery = params.Encode()
resp, err := http.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
}
var status status.Status
err = json.Unmarshal(body, &status)
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: fmt.Sprintf("[RAM: %0.2f%%] [Uptime: %s]", float64(status.MemUsed)/float64(status.MemTotal)*100.0, time.Duration(float64(status.Uptime)*float64(time.Second))),
}
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 {
finished = true
currentString := banner.FormatBanner() + "\n\n"
state.State.Mutex.RLock()
keys := make([]string, 0, len(state.State.Machines))
for key := range state.State.Machines {
keys = append(keys, key)
}
sort.Strings(keys)
for _, host := range keys {
line := ""
switch state.State.Machines[host].State {
case state.Working:
finished = false
d := color.New(color.FgHiYellow, color.Bold)
line = d.Sprintf(" - [✸] %-15s %15s\n", host, time.Since(state.State.Machines[host].JobStart))
case state.Error:
d := color.New(color.FgHiRed, color.Bold)
line = d.Sprintf(" - [✗] %-15s %15s %s\n", host, state.State.Machines[host].JobEnd.Sub(state.State.Machines[host].JobStart), state.State.Machines[host].Message)
case state.Completed:
d := color.New(color.FgHiGreen, color.Bold)
line = d.Sprintf(" - [✔] %-15s %15s %s\n", host, state.State.Machines[host].JobEnd.Sub(state.State.Machines[host].JobStart), state.State.Machines[host].Message)
}
currentString += line
}
state.State.Mutex.RUnlock()
print("\033[H\033[2J")
println(currentString)
}
println("")
}