collect host localtion for graph

This commit is contained in:
abhishek9686 2025-06-12 15:47:24 +05:30
parent 8fc489b5a6
commit d978de08d0
7 changed files with 59 additions and 1 deletions

View file

@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"os"
"sort"
"sync"
@ -30,6 +31,8 @@ var (
ErrInvalidHostID error = errors.New("invalid host id")
)
var GetHostLocInfo = func(ip, token string) string { return "" }
func getHostsFromCache() (hosts []models.Host) {
hostCacheMutex.RLock()
for _, host := range hostsCacheMap {
@ -235,6 +238,11 @@ func CreateHost(h *models.Host) error {
} else {
h.DNS = "no"
}
if h.EndpointIP != nil {
h.Location = GetHostLocInfo(h.EndpointIP.String(), os.Getenv("IP_INFO_TOKEN"))
} else if h.EndpointIPv6 != nil {
h.Location = GetHostLocInfo(h.EndpointIPv6.String(), os.Getenv("IP_INFO_TOKEN"))
}
checkForZombieHosts(h)
return UpsertHost(h)
}

View file

@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"log"
"os"
"time"
"golang.org/x/exp/slog"
@ -204,6 +205,16 @@ func updateHosts() {
}
logic.UpsertHost(&host)
}
if servercfg.IsPro && host.Location == "" {
if host.EndpointIP != nil {
host.Location = logic.GetHostLocInfo(host.EndpointIP.String(), os.Getenv("IP_INFO_TOKEN"))
} else if host.EndpointIPv6 != nil {
host.Location = logic.GetHostLocInfo(host.EndpointIPv6.String(), os.Getenv("IP_INFO_TOKEN"))
}
if host.Location != "" {
logic.UpsertHost(&host)
}
}
}
}

View file

@ -32,6 +32,7 @@ type ApiHost struct {
PersistentKeepalive int `json:"persistentkeepalive" yaml:"persistentkeepalive"`
AutoUpdate bool `json:"autoupdate" yaml:"autoupdate"`
DNS string `json:"dns" yaml:"dns"`
Location string `json:"location"`
}
// ApiIface - the interface struct for API usage
@ -80,6 +81,7 @@ func (h *Host) ConvertNMHostToAPI() *ApiHost {
a.PersistentKeepalive = int(h.PersistentKeepalive.Seconds())
a.AutoUpdate = h.AutoUpdate
a.DNS = h.DNS
a.Location = h.Location
return &a
}
@ -126,5 +128,6 @@ func (a *ApiHost) ConvertAPIHostToNMHost(currentHost *Host) *Host {
h.PersistentKeepalive = time.Duration(a.PersistentKeepalive) * time.Second
h.AutoUpdate = a.AutoUpdate
h.DNS = strings.ToLower(a.DNS)
h.Location = currentHost.Location
return &h
}

View file

@ -73,6 +73,7 @@ type Host struct {
NatType string `json:"nat_type,omitempty" yaml:"nat_type,omitempty"`
TurnEndpoint *netip.AddrPort `json:"turn_endpoint,omitempty" yaml:"turn_endpoint,omitempty"`
PersistentKeepalive time.Duration `json:"persistentkeepalive" swaggertype:"primitive,integer" format:"int64" yaml:"persistentkeepalive"`
Location string `json:"location"` // Format: "lat,lon"
}
// FormatBool converts a boolean to a [yes|no] string

View file

@ -2,6 +2,7 @@ package mq
import (
"encoding/json"
"os"
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/google/uuid"
@ -280,7 +281,13 @@ func HandleHostCheckin(h, currentHost *models.Host) bool {
(h.ListenPort != 0 && h.ListenPort != currentHost.ListenPort) ||
(h.WgPublicListenPort != 0 && h.WgPublicListenPort != currentHost.WgPublicListenPort) || (!h.EndpointIPv6.Equal(currentHost.EndpointIPv6))
if ifaceDelta { // only save if something changes
if !h.EndpointIP.Equal(currentHost.EndpointIP) || !h.EndpointIPv6.Equal(currentHost.EndpointIPv6) {
if h.EndpointIP != nil {
h.Location = logic.GetHostLocInfo(h.EndpointIP.String(), os.Getenv("IP_INFO_TOKEN"))
} else if h.EndpointIPv6 != nil {
h.Location = logic.GetHostLocInfo(h.EndpointIPv6.String(), os.Getenv("IP_INFO_TOKEN"))
}
}
currentHost.EndpointIP = h.EndpointIP
currentHost.EndpointIPv6 = h.EndpointIPv6
currentHost.Interfaces = h.Interfaces

View file

@ -162,6 +162,7 @@ func InitPro() {
logic.IsNodeAllowedToCommunicate = proLogic.IsNodeAllowedToCommunicate
logic.GetFwRulesForNodeAndPeerOnGw = proLogic.GetFwRulesForNodeAndPeerOnGw
logic.GetFwRulesForUserNodesOnGw = proLogic.GetFwRulesForUserNodesOnGw
logic.GetHostLocInfo = proLogic.GetHostLocInfo
}

View file

@ -2,6 +2,7 @@ package logic
import (
"encoding/json"
"net/http"
"sync"
"time"
@ -237,3 +238,29 @@ func updateNodeMetrics(currentNode *models.Node, newMetrics *models.Metrics) {
slog.Debug("[metrics] node metrics data", "node ID", currentNode.ID, "metrics", newMetrics)
}
func GetHostLocInfo(ip, token string) string {
url := "https://ipinfo.io/"
if ip != "" {
url += ip
}
url += "/json"
if token != "" {
url += "?token=" + token
}
client := http.Client{Timeout: 3 * time.Second}
resp, err := client.Get(url)
if err != nil {
return ""
}
defer resp.Body.Close()
var data struct {
Loc string `json:"loc"` // Format: "lat,lon"
}
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return ""
}
return data.Loc
}