2021-01-12 06:32:00 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"runtime"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/go-resty/resty/v2"
|
|
|
|
nats "github.com/nats-io/nats.go"
|
|
|
|
"github.com/ugorji/go/codec"
|
|
|
|
rmm "github.com/wh1te909/rmmagent/shared"
|
|
|
|
)
|
|
|
|
|
|
|
|
var rClient = resty.New()
|
|
|
|
|
2021-01-16 00:01:31 +00:00
|
|
|
func getAPI(apihost, natshost string) (string, string, error) {
|
|
|
|
if apihost != "" && natshost != "" {
|
|
|
|
return apihost, natshost, nil
|
2021-01-12 21:14:43 +00:00
|
|
|
}
|
|
|
|
|
2021-01-12 06:32:00 +00:00
|
|
|
f, err := os.Open(`/etc/nginx/sites-available/rmm.conf`)
|
|
|
|
if err != nil {
|
2021-01-16 00:01:31 +00:00
|
|
|
return "", "", err
|
2021-01-12 06:32:00 +00:00
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
scanner := bufio.NewScanner(f)
|
|
|
|
for scanner.Scan() {
|
|
|
|
if strings.Contains(scanner.Text(), "server_name") && !strings.Contains(scanner.Text(), "301") {
|
|
|
|
r := strings.NewReplacer("server_name", "", ";", "")
|
2021-01-16 00:01:31 +00:00
|
|
|
s := strings.ReplaceAll(r.Replace(scanner.Text()), " ", "")
|
|
|
|
return fmt.Sprintf("https://%s/natsapi", s), fmt.Sprintf("tls://%s:4222", s), nil
|
2021-01-12 06:32:00 +00:00
|
|
|
}
|
|
|
|
}
|
2021-01-16 00:01:31 +00:00
|
|
|
return "", "", errors.New("unable to parse api from nginx conf")
|
2021-01-12 06:32:00 +00:00
|
|
|
}
|
|
|
|
|
2021-01-16 00:01:31 +00:00
|
|
|
func Listen(apihost, natshost string, debug bool) {
|
|
|
|
api, natsurl, err := getAPI(apihost, natshost)
|
2021-01-12 06:32:00 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatalln(err)
|
|
|
|
}
|
2021-01-12 21:14:43 +00:00
|
|
|
|
|
|
|
if debug {
|
2021-01-16 09:41:27 +00:00
|
|
|
log.Println("Api base url: ", api)
|
|
|
|
log.Println("Nats connection url: ", natsurl)
|
2021-01-12 21:14:43 +00:00
|
|
|
}
|
|
|
|
|
2021-01-16 00:01:31 +00:00
|
|
|
rClient.SetHostURL(api)
|
2021-01-12 21:14:43 +00:00
|
|
|
rClient.SetTimeout(30 * time.Second)
|
2021-01-12 06:32:00 +00:00
|
|
|
natsinfo, err := rClient.R().SetResult(&NatsInfo{}).Get("/natsinfo/")
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln(err)
|
|
|
|
}
|
2021-01-16 09:41:27 +00:00
|
|
|
if natsinfo.IsError() {
|
|
|
|
log.Fatalln(natsinfo.String())
|
|
|
|
}
|
2021-01-12 06:32:00 +00:00
|
|
|
|
|
|
|
opts := []nats.Option{
|
|
|
|
nats.Name("TacticalRMM"),
|
|
|
|
nats.UserInfo(natsinfo.Result().(*NatsInfo).User,
|
|
|
|
natsinfo.Result().(*NatsInfo).Password),
|
|
|
|
nats.ReconnectWait(time.Second * 5),
|
|
|
|
nats.RetryOnFailedConnect(true),
|
|
|
|
nats.MaxReconnects(-1),
|
|
|
|
nats.ReconnectBufSize(-1),
|
|
|
|
}
|
|
|
|
|
2021-01-16 00:01:31 +00:00
|
|
|
nc, err := nats.Connect(natsurl, opts...)
|
2021-01-12 06:32:00 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatalln(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
nc.Subscribe("*", func(msg *nats.Msg) {
|
|
|
|
var mh codec.MsgpackHandle
|
|
|
|
mh.RawToString = true
|
|
|
|
dec := codec.NewDecoderBytes(msg.Data, &mh)
|
|
|
|
|
|
|
|
switch msg.Reply {
|
|
|
|
case "hello":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.CheckIn
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Patch("/checkin/")
|
|
|
|
}
|
|
|
|
}()
|
2021-01-19 23:43:37 +00:00
|
|
|
case "startup":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.CheckIn
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Post("/checkin/")
|
|
|
|
}
|
|
|
|
}()
|
2021-01-12 06:32:00 +00:00
|
|
|
case "osinfo":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.CheckInOS
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Put("/checkin/")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
case "winservices":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.CheckInWinServices
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Put("/checkin/")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
case "publicip":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.CheckInPublicIP
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Put("/checkin/")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
case "disks":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.CheckInDisk
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Put("/checkin/")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
case "loggedonuser":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.CheckInLoggedUser
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Put("/checkin/")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
case "software":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.CheckInSW
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Put("/checkin/")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
case "syncmesh":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.MeshNodeID
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Post("/syncmesh/")
|
|
|
|
}
|
|
|
|
}()
|
2021-01-19 00:59:38 +00:00
|
|
|
case "getwinupdates":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.WinUpdateResult
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Post("/winupdates/")
|
|
|
|
}
|
|
|
|
}()
|
2021-01-19 03:13:18 +00:00
|
|
|
case "winupdateresult":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.WinUpdateInstallResult
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Patch("/winupdates/")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
case "needsreboot":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.AgentNeedsReboot
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Put("/winupdates/")
|
|
|
|
}
|
|
|
|
}()
|
2021-01-19 23:43:37 +00:00
|
|
|
case "chocoinstall":
|
|
|
|
go func() {
|
|
|
|
var p *rmm.ChocoInstalled
|
|
|
|
if err := dec.Decode(&p); err == nil {
|
|
|
|
rClient.R().SetBody(p).Post("/choco/")
|
|
|
|
}
|
|
|
|
}()
|
2021-01-12 06:32:00 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
nc.Flush()
|
|
|
|
|
|
|
|
if err := nc.LastError(); err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
runtime.Goexit()
|
|
|
|
}
|