organizing and refactoring
This commit is contained in:
parent
13b5474cd8
commit
6f159d4728
20 changed files with 832 additions and 488 deletions
|
|
@ -18,7 +18,6 @@ import (
|
|||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
rmm "github.com/amidaware/rmmagent/shared"
|
||||
|
|
@ -27,297 +26,9 @@ import (
|
|||
"github.com/jaypipes/ghw"
|
||||
"github.com/kardianos/service"
|
||||
"github.com/shirou/gopsutil/v3/cpu"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
psHost "github.com/shirou/gopsutil/v3/host"
|
||||
"github.com/spf13/viper"
|
||||
trmm "github.com/wh1te909/trmm-shared"
|
||||
)
|
||||
|
||||
func ShowStatus(version string) {
|
||||
fmt.Println(version)
|
||||
}
|
||||
|
||||
func (a *Agent) GetDisks() []trmm.Disk {
|
||||
ret := make([]trmm.Disk, 0)
|
||||
partitions, err := disk.Partitions(false)
|
||||
if err != nil {
|
||||
a.Logger.Debugln(err)
|
||||
return ret
|
||||
}
|
||||
|
||||
for _, p := range partitions {
|
||||
if strings.Contains(p.Device, "dev/loop") {
|
||||
continue
|
||||
}
|
||||
usage, err := disk.Usage(p.Mountpoint)
|
||||
if err != nil {
|
||||
a.Logger.Debugln(err)
|
||||
continue
|
||||
}
|
||||
|
||||
d := trmm.Disk{
|
||||
Device: p.Device,
|
||||
Fstype: p.Fstype,
|
||||
Total: ByteCountSI(usage.Total),
|
||||
Used: ByteCountSI(usage.Used),
|
||||
Free: ByteCountSI(usage.Free),
|
||||
Percent: int(usage.UsedPercent),
|
||||
}
|
||||
ret = append(ret, d)
|
||||
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (a *Agent) SystemRebootRequired() (bool, error) {
|
||||
// deb
|
||||
paths := [2]string{"/var/run/reboot-required", "/run/reboot-required"}
|
||||
for _, p := range paths {
|
||||
if trmm.FileExists(p) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
// rhel
|
||||
bins := [2]string{"/usr/bin/needs-restarting", "/bin/needs-restarting"}
|
||||
for _, bin := range bins {
|
||||
if trmm.FileExists(bin) {
|
||||
opts := a.NewCMDOpts()
|
||||
// https://man7.org/linux/man-pages/man1/needs-restarting.1.html
|
||||
// -r Only report whether a full reboot is required (exit code 1) or not (exit code 0).
|
||||
opts.Command = fmt.Sprintf("%s -r", bin)
|
||||
out := a.CmdV2(opts)
|
||||
|
||||
if out.Status.Error != nil {
|
||||
a.Logger.Debugln("SystemRebootRequired(): ", out.Status.Error.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
if out.Status.Exit == 1 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (a *Agent) LoggedOnUser() string {
|
||||
var ret string
|
||||
users, err := psHost.Users()
|
||||
if err != nil {
|
||||
return ret
|
||||
}
|
||||
|
||||
// return the first logged in user
|
||||
for _, user := range users {
|
||||
if user.User != "" {
|
||||
ret = user.User
|
||||
break
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (a *Agent) osString() string {
|
||||
h, err := psHost.Info()
|
||||
if err != nil {
|
||||
return "error getting host info"
|
||||
}
|
||||
return fmt.Sprintf("%s %s %s %s", strings.Title(h.Platform), h.PlatformVersion, h.KernelArch, h.KernelVersion)
|
||||
}
|
||||
|
||||
func NewAgentConfig() *rmm.AgentConfig {
|
||||
viper.SetConfigName("tacticalagent")
|
||||
viper.SetConfigType("json")
|
||||
viper.AddConfigPath("/etc/")
|
||||
viper.AddConfigPath(".")
|
||||
|
||||
err := viper.ReadInConfig()
|
||||
|
||||
if err != nil {
|
||||
return &rmm.AgentConfig{}
|
||||
}
|
||||
|
||||
agentpk := viper.GetString("agentpk")
|
||||
pk, _ := strconv.Atoi(agentpk)
|
||||
|
||||
ret := &rmm.AgentConfig{
|
||||
BaseURL: viper.GetString("baseurl"),
|
||||
AgentID: viper.GetString("agentid"),
|
||||
APIURL: viper.GetString("apiurl"),
|
||||
Token: viper.GetString("token"),
|
||||
AgentPK: agentpk,
|
||||
PK: pk,
|
||||
Cert: viper.GetString("cert"),
|
||||
Proxy: viper.GetString("proxy"),
|
||||
CustomMeshDir: viper.GetString("meshdir"),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (a *Agent) RunScript(code string, shell string, args []string, timeout int) (stdout, stderr string, exitcode int, e error) {
|
||||
code = removeWinNewLines(code)
|
||||
content := []byte(code)
|
||||
|
||||
f, err := createTmpFile()
|
||||
if err != nil {
|
||||
a.Logger.Errorln("RunScript createTmpFile()", err)
|
||||
return "", err.Error(), 85, err
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
if _, err := f.Write(content); err != nil {
|
||||
a.Logger.Errorln(err)
|
||||
return "", err.Error(), 85, err
|
||||
}
|
||||
|
||||
if err := f.Close(); err != nil {
|
||||
a.Logger.Errorln(err)
|
||||
return "", err.Error(), 85, err
|
||||
}
|
||||
|
||||
if err := os.Chmod(f.Name(), 0770); err != nil {
|
||||
a.Logger.Errorln(err)
|
||||
return "", err.Error(), 85, err
|
||||
}
|
||||
|
||||
opts := a.NewCMDOpts()
|
||||
opts.IsScript = true
|
||||
opts.Shell = f.Name()
|
||||
opts.Args = args
|
||||
opts.Timeout = time.Duration(timeout)
|
||||
out := a.CmdV2(opts)
|
||||
retError := ""
|
||||
if out.Status.Error != nil {
|
||||
retError += CleanString(out.Status.Error.Error())
|
||||
retError += "\n"
|
||||
}
|
||||
if len(out.Stderr) > 0 {
|
||||
retError += out.Stderr
|
||||
}
|
||||
return out.Stdout, retError, out.Status.Exit, nil
|
||||
}
|
||||
|
||||
func SetDetached() *syscall.SysProcAttr {
|
||||
return &syscall.SysProcAttr{Setpgid: true}
|
||||
}
|
||||
|
||||
func (a *Agent) AgentUpdate(url, inno, version string) {
|
||||
|
||||
self, err := os.Executable()
|
||||
if err != nil {
|
||||
a.Logger.Errorln("AgentUpdate() os.Executable():", err)
|
||||
return
|
||||
}
|
||||
|
||||
f, err := createTmpFile()
|
||||
if err != nil {
|
||||
a.Logger.Errorln("AgentUpdate createTmpFile()", err)
|
||||
return
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
a.Logger.Infof("Agent updating from %s to %s", a.Version, version)
|
||||
a.Logger.Infoln("Downloading agent update from", url)
|
||||
|
||||
rClient := resty.New()
|
||||
rClient.SetCloseConnection(true)
|
||||
rClient.SetTimeout(15 * time.Minute)
|
||||
rClient.SetDebug(a.Debug)
|
||||
if len(a.Proxy) > 0 {
|
||||
rClient.SetProxy(a.Proxy)
|
||||
}
|
||||
|
||||
r, err := rClient.R().SetOutput(f.Name()).Get(url)
|
||||
if err != nil {
|
||||
a.Logger.Errorln("AgentUpdate() download:", err)
|
||||
f.Close()
|
||||
return
|
||||
}
|
||||
if r.IsError() {
|
||||
a.Logger.Errorln("AgentUpdate() status code:", r.StatusCode())
|
||||
f.Close()
|
||||
return
|
||||
}
|
||||
|
||||
f.Close()
|
||||
os.Chmod(f.Name(), 0755)
|
||||
err = os.Rename(f.Name(), self)
|
||||
if err != nil {
|
||||
a.Logger.Errorln("AgentUpdate() os.Rename():", err)
|
||||
return
|
||||
}
|
||||
|
||||
opts := a.NewCMDOpts()
|
||||
opts.Detached = true
|
||||
opts.Command = "systemctl restart tacticalagent.service"
|
||||
a.CmdV2(opts)
|
||||
}
|
||||
|
||||
func (a *Agent) AgentUninstall(code string) {
|
||||
f, err := createTmpFile()
|
||||
if err != nil {
|
||||
a.Logger.Errorln("AgentUninstall createTmpFile():", err)
|
||||
return
|
||||
}
|
||||
|
||||
f.Write([]byte(code))
|
||||
f.Close()
|
||||
os.Chmod(f.Name(), 0770)
|
||||
|
||||
opts := a.NewCMDOpts()
|
||||
opts.IsScript = true
|
||||
opts.Shell = f.Name()
|
||||
opts.Args = []string{"uninstall"}
|
||||
opts.Detached = true
|
||||
a.CmdV2(opts)
|
||||
}
|
||||
|
||||
func (a *Agent) NixMeshNodeID() string {
|
||||
var meshNodeID string
|
||||
meshSuccess := false
|
||||
a.Logger.Debugln("Getting mesh node id")
|
||||
|
||||
if !trmm.FileExists(a.MeshSystemBin) {
|
||||
a.Logger.Debugln(a.MeshSystemBin, "does not exist. Skipping.")
|
||||
return ""
|
||||
}
|
||||
|
||||
opts := a.NewCMDOpts()
|
||||
opts.IsExecutable = true
|
||||
opts.Shell = a.MeshSystemBin
|
||||
opts.Command = "-nodeid"
|
||||
|
||||
for !meshSuccess {
|
||||
out := a.CmdV2(opts)
|
||||
meshNodeID = out.Stdout
|
||||
a.Logger.Debugln("Stdout:", out.Stdout)
|
||||
a.Logger.Debugln("Stderr:", out.Stderr)
|
||||
if meshNodeID == "" {
|
||||
time.Sleep(1 * time.Second)
|
||||
continue
|
||||
} else if strings.Contains(strings.ToLower(meshNodeID), "graphical version") || strings.Contains(strings.ToLower(meshNodeID), "zenity") {
|
||||
time.Sleep(1 * time.Second)
|
||||
continue
|
||||
}
|
||||
meshSuccess = true
|
||||
}
|
||||
return meshNodeID
|
||||
}
|
||||
|
||||
func (a *Agent) getMeshNodeID() (string, error) {
|
||||
return a.NixMeshNodeID(), nil
|
||||
}
|
||||
|
||||
func (a *Agent) RecoverMesh() {
|
||||
a.Logger.Infoln("Attempting mesh recovery")
|
||||
opts := a.NewCMDOpts()
|
||||
opts.Command = "systemctl restart meshagent.service"
|
||||
a.CmdV2(opts)
|
||||
a.SyncMeshNodeID()
|
||||
}
|
||||
|
||||
func (a *Agent) GetWMIInfo() map[string]interface{} {
|
||||
wmiInfo := make(map[string]interface{})
|
||||
ips := make([]string, 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue