freifunkmanager/runtime/node.go

136 lines
3.4 KiB
Go

package runtime
import (
"fmt"
"net"
"strings"
yanicData "github.com/FreifunkBremen/yanic/data"
"github.com/FreifunkBremen/yanic/lib/jsontime"
yanicRuntime "github.com/FreifunkBremen/yanic/runtime"
)
type Node struct {
Lastseen jsontime.Time `json:"lastseen" mapstructure:"-"`
NodeID string `json:"node_id" gorm:"primary_key" mapstructure:"node_id"`
Hostname string `json:"hostname"`
Location yanicData.Location `json:"location" gorm:"embedded;embedded_prefix:location_"`
Wireless yanicData.Wireless `json:"wireless" gorm:"embedded;embedded_prefix:wireless_"`
Owner string `json:"owner"`
Blacklist bool `json:"blacklist" gorm:"-" mapstructure:"-"`
Address string `json:"ip" mapstructure:"-"`
Stats struct {
Wireless yanicData.WirelessStatistics `json:"wireless"`
Clients yanicData.Clients `json:"clients"`
} `json:"statistics" mapstructure:"-"`
}
func NewNode(nodeOrigin *yanicRuntime.Node, ipPrefix string) *Node {
if nodeinfo := nodeOrigin.Nodeinfo; nodeinfo != nil {
node := &Node{
Hostname: nodeinfo.Hostname,
NodeID: nodeinfo.NodeID,
}
for _, ip := range nodeinfo.Network.Addresses {
if !strings.HasPrefix(ip, ipPrefix) {
continue
}
ipAddr := net.ParseIP(ip)
if node.Address == "" || ipAddr.IsGlobalUnicast() {
node.Address = ipAddr.String()
}
}
if owner := nodeinfo.Owner; owner != nil {
node.Owner = owner.Contact
}
if location := nodeinfo.Location; location != nil {
node.Location = *location
}
if wireless := nodeinfo.Wireless; wireless != nil {
node.Wireless = *wireless
}
if stats := nodeOrigin.Statistics; stats != nil {
node.Stats.Clients = stats.Clients
node.Stats.Wireless = stats.Wireless
}
return node
}
return nil
}
func (n *Node) GetAddress() net.TCPAddr {
return net.TCPAddr{IP: net.ParseIP(n.Address), Port: 22}
}
func (n *Node) Update(node *yanicRuntime.Node) {
if nodeinfo := node.Nodeinfo; nodeinfo != nil {
n.Hostname = nodeinfo.Hostname
n.NodeID = nodeinfo.NodeID
n.Address = node.Address.IP.String()
if owner := nodeinfo.Owner; owner != nil {
n.Owner = owner.Contact
}
if location := nodeinfo.Location; location != nil {
n.Location = *location
}
if wireless := nodeinfo.Wireless; wireless != nil {
n.Wireless = *wireless
}
}
}
func (n *Node) IsEqual(node *Node) bool {
if n.NodeID != node.NodeID {
return false
}
/*
if n.Address != node.Address {
return false
}
*/
if n.Hostname != node.Hostname {
return false
}
if n.Owner != node.Owner {
return false
}
if !locationEqual(n.Location, node.Location) {
return false
}
if !wirelessEqual(n.Wireless, node.Wireless) {
return false
}
return true
}
const LOCATION_EQUAL_FORMAT_STRING = "%.6f"
func locationEqual(a, b yanicData.Location) bool {
if fmt.Sprintf(LOCATION_EQUAL_FORMAT_STRING, a.Latitude) != fmt.Sprintf(LOCATION_EQUAL_FORMAT_STRING, b.Latitude) {
return false
}
if fmt.Sprintf(LOCATION_EQUAL_FORMAT_STRING, a.Longitude) != fmt.Sprintf(LOCATION_EQUAL_FORMAT_STRING, b.Longitude) {
return false
}
if a.Altitude != b.Altitude {
return false
}
return true
}
func wirelessEqual(a, b yanicData.Wireless) bool {
if a.Channel24 != b.Channel24 {
return false
}
if a.Channel5 != b.Channel5 {
return false
}
if a.TxPower24 != b.TxPower24 {
return false
}
if a.TxPower5 != b.TxPower5 {
return false
}
return true
}