mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
Because ctrld needs to query custom client mapping from it. While at it, also make the error message clearer when initializing ubios discover failed, by attaching the command output to returned error.
80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
package clientinfo
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"os/exec"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/Control-D-Inc/ctrld/internal/router"
|
|
"github.com/Control-D-Inc/ctrld/internal/router/ubios"
|
|
)
|
|
|
|
// ubiosDiscover provides client discovery functionality on Ubios routers.
|
|
type ubiosDiscover struct {
|
|
hostname sync.Map // mac => hostname
|
|
}
|
|
|
|
// refresh reloads unifi devices from database.
|
|
func (u *ubiosDiscover) refresh() error {
|
|
if router.Name() != ubios.Name {
|
|
return nil
|
|
}
|
|
return u.refreshDevices()
|
|
}
|
|
|
|
// LookupHostnameByIP returns hostname for given IP.
|
|
func (u *ubiosDiscover) LookupHostnameByIP(ip string) string {
|
|
return ""
|
|
}
|
|
|
|
// LookupHostnameByMac returns unifi device custom hostname for the given MAC address.
|
|
func (u *ubiosDiscover) LookupHostnameByMac(mac string) string {
|
|
val, ok := u.hostname.Load(mac)
|
|
if !ok {
|
|
return ""
|
|
}
|
|
return val.(string)
|
|
}
|
|
|
|
// refreshDevices updates unifi devices name from local mongodb.
|
|
func (u *ubiosDiscover) refreshDevices() error {
|
|
cmd := exec.Command("/usr/bin/mongo", "localhost:27117/ace", "--quiet", "--eval", `
|
|
DBQuery.shellBatchSize = 256;
|
|
db.user.find({name: {$exists: true, $ne: ""}}, {_id:0, mac:1, name:1});`)
|
|
b, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
return fmt.Errorf("out: %s, err: %w", string(b), err)
|
|
}
|
|
return u.storeDevices(bytes.NewReader(b))
|
|
}
|
|
|
|
// storeDevices saves unifi devices name for caching.
|
|
func (u *ubiosDiscover) storeDevices(r io.Reader) error {
|
|
decoder := json.NewDecoder(r)
|
|
device := struct {
|
|
MAC string
|
|
Name string
|
|
}{}
|
|
for {
|
|
err := decoder.Decode(&device)
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
mac := strings.ToLower(device.MAC)
|
|
u.hostname.Store(mac, normalizeHostname(device.Name))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// String returns human-readable format of ubiosDiscover.
|
|
func (u *ubiosDiscover) String() string {
|
|
return "ubios"
|
|
}
|