2017-05-07 03:37:30 +02:00
package runtime
import (
"bytes"
"fmt"
"net"
"github.com/FreifunkBremen/freifunkmanager/ssh"
"github.com/FreifunkBremen/yanic/data"
2017-05-12 21:32:10 +02:00
"github.com/FreifunkBremen/yanic/jsontime"
2017-05-07 03:37:30 +02:00
yanicRuntime "github.com/FreifunkBremen/yanic/runtime"
)
const (
SSHUpdateHostname = "uci set system.@system[0].hostname='%s';uci commit system;echo $(uci get system.@system[0].hostname) > /proc/sys/kernel/hostname"
SSHUpdateOwner = "uci set gluon-node-info.@owner[0].contact='%s';uci commit gluon-node-info;"
2017-05-15 21:59:48 +02:00
SSHUpdateLocation = "uci set gluon-node-info.@location[0].latitude='%f';uci set gluon-node-info.@location[0].longitude='%f';uci set gluon-node-info.@location[0].share_location=1;uci commit gluon-node-info;"
SSHUpdateWifiFreq = "wifi"
2017-05-07 03:37:30 +02:00
)
type Node struct {
2017-05-12 21:32:10 +02:00
Lastseen jsontime . Time ` json:"lastseen" `
2017-05-07 03:37:30 +02:00
NodeID string ` json:"node_id" `
Hostname string ` json:"hostname" `
Location data . Location ` json:"location" `
Wireless data . Wireless ` json:"wireless" `
Owner string ` json:"owner" `
Address net . IP ` json:"address" `
2017-05-08 19:49:18 +02:00
Stats struct {
Wireless data . WirelessStatistics ` json:"wireless" `
Clients data . Clients ` json:"clients" `
} ` json:"statistics" `
2017-05-07 03:37:30 +02:00
}
2017-05-08 19:49:18 +02:00
func NewNode ( nodeOrigin * yanicRuntime . Node ) * Node {
if nodeinfo := nodeOrigin . Nodeinfo ; nodeinfo != nil {
2017-05-07 03:37:30 +02:00
node := & Node {
Hostname : nodeinfo . Hostname ,
NodeID : nodeinfo . NodeID ,
2017-05-08 19:49:18 +02:00
Address : nodeOrigin . Address ,
2017-05-07 03:37:30 +02:00
}
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
}
2017-05-08 19:49:18 +02:00
if stats := nodeOrigin . Statistics ; stats != nil {
node . Stats . Clients = stats . Clients
node . Stats . Wireless = stats . Wireless
}
2017-05-07 03:37:30 +02:00
return node
}
return nil
}
func ( n * Node ) SSHUpdate ( ssh * ssh . Manager , iface string , oldnode * Node ) {
2017-05-08 19:13:29 +02:00
if oldnode == nil {
return
}
2017-05-07 03:37:30 +02:00
addr := n . GetAddress ( iface )
if n . Hostname != oldnode . Hostname {
ssh . ExecuteOn ( addr , fmt . Sprintf ( SSHUpdateHostname , n . Hostname ) )
}
if n . Owner != oldnode . Owner {
ssh . ExecuteOn ( addr , fmt . Sprintf ( SSHUpdateOwner , n . Owner ) )
}
if ! locationEqual ( & n . Location , & oldnode . Location ) {
ssh . ExecuteOn ( addr , fmt . Sprintf ( SSHUpdateLocation , n . Location . Latitude , n . Location . Longtitude ) )
}
}
func ( n * Node ) SSHSet ( ssh * ssh . Manager , iface string ) {
n . SSHUpdate ( ssh , iface , nil )
}
func ( n * Node ) GetAddress ( iface string ) net . TCPAddr {
return net . TCPAddr { IP : n . Address , Port : 22 , Zone : iface }
}
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
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 ! bytes . Equal ( 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
}
func ( n * Node ) IsEqualNode ( node * yanicRuntime . Node ) bool {
nodeinfo := node . Nodeinfo
if nodeinfo == nil {
return false
}
owner := nodeinfo . Owner
if owner == nil {
return false
}
if n . NodeID != nodeinfo . NodeID {
return false
}
if ! bytes . Equal ( n . Address , node . Address ) {
return false
}
if n . Hostname != nodeinfo . Hostname {
return false
}
if n . Owner != owner . Contact {
return false
}
if ! locationEqual ( & n . Location , nodeinfo . Location ) {
return false
}
if ! wirelessEqual ( & n . Wireless , nodeinfo . Wireless ) {
return false
}
return true
}
func locationEqual ( a , b * data . Location ) bool {
if a == nil || b == nil {
return false
}
if a . Latitude != b . Latitude {
return false
}
if a . Longtitude != b . Longtitude {
return false
}
if a . Altitude != b . Altitude {
return false
}
return true
}
func wirelessEqual ( a , b * data . Wireless ) bool {
if a == nil || b == nil {
return false
}
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
}