nodes split to meshviewernodes

This commit is contained in:
Martin Geno 2016-05-29 21:41:58 +02:00
parent bc525f2636
commit dc47ab8719
6 changed files with 178 additions and 113 deletions

View File

@ -1,11 +1,11 @@
package api package api
import ( import (
"fmt"
"net/http"
"encoding/json" "encoding/json"
"github.com/julienschmidt/httprouter" "fmt"
"github.com/FreifunkBremen/respond-collector/models" "github.com/FreifunkBremen/respond-collector/models"
"github.com/julienschmidt/httprouter"
"net/http"
) )
type ApiAliases struct { type ApiAliases struct {
@ -27,16 +27,37 @@ func NewAliases (config *models.Config, router *httprouter.Router,prefix string,
router.GET(prefix+"/alias/:nodeid", api.GetOne) router.GET(prefix+"/alias/:nodeid", api.GetOne)
router.POST(prefix+"/alias/:nodeid", BasicAuth(api.SaveOne, []byte(config.Webserver.Api.Passphrase))) router.POST(prefix+"/alias/:nodeid", BasicAuth(api.SaveOne, []byte(config.Webserver.Api.Passphrase)))
} }
// clean up the aliases by correct values in nodes // clean up the aliases by correct values in nodes
func (api *ApiAliases) cleaner() { func (api *ApiAliases) cleaner() {
for key, alias := range api.aliases.List { for key, alias := range api.aliases.List {
if node := api.nodes.List[key]; node != nil { if node := api.nodes.List[key]; node != nil {
if nodeinfo := node.Nodeinfo; nodeinfo != nil { if nodeinfo := node.Nodeinfo; nodeinfo != nil {
//counter for the diffrent attribute //counter for the diffrent attribute
count := 1 count := 3
if alias.Hostname == nodeinfo.Hostname { if alias.Hostname == nodeinfo.Hostname {
count -= 1 count -= 1
} }
if alias.Location.Latitude == nodeinfo.Location.Latitude {
count -= 1
}
if alias.Location.Longtitude == nodeinfo.Location.Longtitude {
count -= 1
}
/*
if alias.Freq24.TxPower == nodeinfo.Freq24.TxPower {
count -= 1
}
if alias.Freq24.Channel == nodeinfo.Freq24.Channel {
count -= 1
}
if alias.Freq5.TxPower == nodeinfo.Freq5.TxPower {
count -= 1
}
if alias.Freq5.Channel == nodeinfo.Freq5.Channel {
count -= 1
}
*/
//delete element //delete element
if count <= 0 { if count <= 0 {
delete(api.aliases.List, key) delete(api.aliases.List, key)

View File

@ -1,9 +1,9 @@
package api package api
import ( import (
"net/http"
"github.com/julienschmidt/httprouter"
"github.com/FreifunkBremen/respond-collector/models" "github.com/FreifunkBremen/respond-collector/models"
"github.com/julienschmidt/httprouter"
"net/http"
) )
type ApiNodes struct { type ApiNodes struct {

View File

@ -3,20 +3,31 @@ package models
import ( import (
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"sync"
"log" "log"
"sync"
"time" "time"
"github.com/FreifunkBremen/respond-collector/data"
) )
type Alias struct { type Alias struct {
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
Location *data.Location `json:"location"`
Freq24 *Frequence `json:"freq24"`
Freq5 *Frequence `json:"freq5"`
} }
type Frequence struct {
TxPower int `json:"txpower"`
Channel int `json:"channel"`
}
// Nodes struct: cache DB of Node's structs // Nodes struct: cache DB of Node's structs
type Aliases struct { type Aliases struct {
List map[string]*Alias `json:"nodes"` // the current nodemap, indexed by node ID List map[string]*Alias `json:"nodes"` // the current nodemap, indexed by node ID
config *Config config *Config
sync.Mutex sync.Mutex
} }
// NewNodes create Nodes structs // NewNodes create Nodes structs
func NewAliases(config *Config) *Aliases { func NewAliases(config *Config) *Aliases {
aliases := &Aliases{ aliases := &Aliases{

View File

@ -9,6 +9,12 @@ type Ansible struct {
type AnsibleHostVars struct { type AnsibleHostVars struct {
Address string `json:"ansible_ssh_host"` Address string `json:"ansible_ssh_host"`
Hostname string `json:"node_name"` Hostname string `json:"node_name"`
Channel24 int `json:"radio24_channel"`
TxPower24 int `json:"radio24_txpower"`
Channel5 int `json:"radio5_channel"`
TxPower5 int `json:"radio5_txpower"`
GeoLatitude float64 `json:"geo_latitude"`
GeoLongitude float64 `json:"geo_longitude"`
} }
func GenerateAnsible(nodes *Nodes, aliases map[string]*Alias) *Ansible { func GenerateAnsible(nodes *Nodes, aliases map[string]*Alias) *Ansible {
@ -21,6 +27,12 @@ func GenerateAnsible(nodes *Nodes,aliases map[string]*Alias) *Ansible{
vars := &AnsibleHostVars{ vars := &AnsibleHostVars{
Address: node.Nodeinfo.Network.Addresses[0], Address: node.Nodeinfo.Network.Addresses[0],
Hostname: alias.Hostname, Hostname: alias.Hostname,
Channel24: alias.Freq24.Channel,
Channel5: alias.Freq5.Channel,
TxPower24: alias.Freq24.TxPower,
TxPower5: alias.Freq5.TxPower,
GeoLatitude: alias.Location.Latitude,
GeoLongitude: alias.Location.Longtitude,
} }
ansible.Meta.HostVars = append(ansible.Meta.HostVars, vars) ansible.Meta.HostVars = append(ansible.Meta.HostVars, vars)

View File

@ -1,26 +0,0 @@
package models
import "github.com/FreifunkBremen/respond-collector/data"
type MeshviewerStatistics struct {
NodeId string `json:"node_id"`
Clients uint32 `json:"clients"`
RootFsUsage float64 `json:"rootfs_usage,omitempty""`
LoadAverage float64 `json:"loadavg,omitempty""`
Memory data.Memory `json:"memory,omitempty""`
Uptime float64 `json:"uptime,omitempty""`
Idletime float64 `json:"idletime,omitempty""`
Gateway string `json:"gateway,omitempty"`
Processes struct {
Total uint32 `json:"total"`
Running uint32 `json:"running"`
} `json:"processes,omitempty""`
MeshVpn *data.MeshVPN `json:"mesh_vpn,omitempty"`
Traffic struct {
Tx *data.Traffic `json:"tx"`
Rx *data.Traffic `json:"rx"`
Forward *data.Traffic `json:"forward"`
MgmtTx *data.Traffic `json:"mgmt_tx"`
MgmtRx *data.Traffic `json:"mgmt_rx"`
} `json:"traffic,omitempty""`
}

View File

@ -10,23 +10,19 @@ import (
"github.com/FreifunkBremen/respond-collector/data" "github.com/FreifunkBremen/respond-collector/data"
"github.com/FreifunkBremen/respond-collector/jsontime" "github.com/FreifunkBremen/respond-collector/jsontime"
"github.com/FreifunkBremen/respond-collector/meshviewer"
) )
// Node struct // Node struct
type Node struct { type Node struct {
Firstseen jsontime.Time `json:"firstseen"` Firstseen jsontime.Time `json:"firstseen"`
Lastseen jsontime.Time `json:"lastseen"` Lastseen jsontime.Time `json:"lastseen"`
Flags *Flags `json:"flags,omitempty"` Flags *meshviewer.Flags `json:"flags,omitempty"`
Statistics *MeshviewerStatistics `json:"statistics"` Statistics *data.Statistics `json:"statistics"`
Nodeinfo *data.NodeInfo `json:"nodeinfo"` Nodeinfo *data.NodeInfo `json:"nodeinfo"`
Neighbours *data.Neighbours `json:"-"` Neighbours *data.Neighbours `json:"-"`
} }
type Flags struct {
Online bool `json:"online"`
Gateway bool `json:"gateway"`
}
// Nodes struct: cache DB of Node's structs // Nodes struct: cache DB of Node's structs
type Nodes struct { type Nodes struct {
Version int `json:"version"` Version int `json:"version"`
@ -62,7 +58,7 @@ func (nodes *Nodes) Update(nodeID string, res *data.ResponseData) {
if node == nil { if node == nil {
node = &Node{ node = &Node{
Firstseen: now, Firstseen: now,
Flags: &Flags{ Flags: &meshviewer.Flags{
Online: true, Online: true,
Gateway: false, Gateway: false,
}, },
@ -90,21 +86,44 @@ func (nodes *Nodes) Update(nodeID string, res *data.ResponseData) {
// Update statistics // Update statistics
if val := res.Statistics; val != nil { if val := res.Statistics; val != nil {
node.Statistics = &MeshviewerStatistics{ node.Statistics = val
NodeId: val.NodeId,
Clients: 0,
Gateway: val.Gateway,
RootFsUsage: val.RootFsUsage,
LoadAverage: val.LoadAverage,
Memory: val.Memory,
Uptime: val.Uptime,
Idletime: val.Idletime,
Processes: val.Processes,
MeshVpn: val.MeshVpn,
Traffic: val.Traffic,
} }
node.Statistics.Clients = val.Clients.Total
} }
func (nodes *Nodes) GetMeshviewer() *meshviewer.Nodes {
meshviewerNodes := &meshviewer.Nodes{
Version: nodes.Version,
List: make(map[string]*meshviewer.Node),
Timestamp: nodes.Timestamp,
}
for nodeID, _ := range nodes.List {
meshviewerNodes.Lock()
node, _ := meshviewerNodes.List[nodeID]
if node == nil {
node = &meshviewer.Node{
Firstseen: nodes.List[nodeID].Firstseen,
Lastseen: nodes.List[nodeID].Lastseen,
Flags: nodes.List[nodeID].Flags,
Nodeinfo: nodes.List[nodeID].Nodeinfo,
}
meshviewerNodes.List[nodeID] = node
}
meshviewerNodes.Unlock()
node.Statistics = &meshviewer.Statistics{
NodeId: nodes.List[nodeID].Statistics.NodeId,
Clients: nodes.List[nodeID].Statistics.Clients.Total,
Gateway: nodes.List[nodeID].Statistics.Gateway,
RootFsUsage: nodes.List[nodeID].Statistics.RootFsUsage,
LoadAverage: nodes.List[nodeID].Statistics.LoadAverage,
Memory: nodes.List[nodeID].Statistics.Memory,
Uptime: nodes.List[nodeID].Statistics.Uptime,
Idletime: nodes.List[nodeID].Statistics.Idletime,
Processes: nodes.List[nodeID].Statistics.Processes,
MeshVpn: nodes.List[nodeID].Statistics.MeshVpn,
Traffic: nodes.List[nodeID].Statistics.Traffic,
}
}
return meshviewerNodes
} }
// Periodically saves the cached DB to json file // Periodically saves the cached DB to json file
@ -118,18 +137,14 @@ func (nodes *Nodes) worker() {
// //
// set node as offline (without statistics) // set node as offline (without statistics)
for _, node := range nodes.List { for _, node := range nodes.List {
if node.Statistics != nil && node.Lastseen.Unix()+int64(1000*nodes.config.Respondd.CollectInterval) < nodes.Timestamp.Unix() { if node.Statistics != nil && node.Lastseen.Unix()+int64(5*nodes.config.Respondd.CollectInterval) < nodes.Timestamp.Unix() {
node.Statistics = &MeshviewerStatistics{
NodeId: node.Statistics.NodeId,
Clients: 0,
}
if node.Flags != nil { if node.Flags != nil {
node.Flags.Online = false node.Flags.Online = false
} }
} }
} }
// serialize nodes // serialize nodes
save(nodes, nodes.config.Nodes.NodesPath) save(nodes.GetMeshviewer(), nodes.config.Nodes.NodesPath)
if path := nodes.config.Nodes.GraphsPath; path != "" { if path := nodes.config.Nodes.GraphsPath; path != "" {
save(nodes.BuildGraph(), path) save(nodes.BuildGraph(), path)
@ -143,8 +158,40 @@ func (nodes *Nodes) load() {
path := nodes.config.Nodes.NodesPath path := nodes.config.Nodes.NodesPath
log.Println("loading", path) log.Println("loading", path)
if data, err := ioutil.ReadFile(path); err == nil { if filedata, err := ioutil.ReadFile(path); err == nil {
if err := json.Unmarshal(data, nodes); err == nil { meshviewerNodes := &meshviewer.Nodes{}
if err := json.Unmarshal(filedata, meshviewerNodes); err == nil {
nodes.Version = meshviewerNodes.Version
nodes.Timestamp = meshviewerNodes.Timestamp
nodes.List = make(map[string]*Node)
for nodeID, _ := range meshviewerNodes.List {
nodes.Lock()
node, _ := nodes.List[nodeID]
if node == nil {
node = &Node{
Firstseen: meshviewerNodes.List[nodeID].Firstseen,
Lastseen: meshviewerNodes.List[nodeID].Lastseen,
Flags: meshviewerNodes.List[nodeID].Flags,
Nodeinfo: meshviewerNodes.List[nodeID].Nodeinfo,
}
nodes.List[nodeID] = node
}
nodes.Unlock()
node.Statistics = &data.Statistics{
NodeId: meshviewerNodes.List[nodeID].Statistics.NodeId,
Clients: data.Clients{Total: meshviewerNodes.List[nodeID].Statistics.Clients},
Gateway: meshviewerNodes.List[nodeID].Statistics.Gateway,
RootFsUsage: meshviewerNodes.List[nodeID].Statistics.RootFsUsage,
LoadAverage: meshviewerNodes.List[nodeID].Statistics.LoadAverage,
Memory: meshviewerNodes.List[nodeID].Statistics.Memory,
Uptime: meshviewerNodes.List[nodeID].Statistics.Uptime,
Idletime: meshviewerNodes.List[nodeID].Statistics.Idletime,
Processes: meshviewerNodes.List[nodeID].Statistics.Processes,
MeshVpn: meshviewerNodes.List[nodeID].Statistics.MeshVpn,
Traffic: meshviewerNodes.List[nodeID].Statistics.Traffic,
}
}
log.Println("loaded", len(nodes.List), "nodes") log.Println("loaded", len(nodes.List), "nodes")
} else { } else {
log.Println("failed to unmarshal nodes:", err) log.Println("failed to unmarshal nodes:", err)