[TASK] add nodelist
This commit is contained in:
parent
2cbdad54d9
commit
d1a52173c7
@ -67,6 +67,10 @@ enable = false
|
|||||||
template_path = "/var/lib/collector/html-template.tmp"
|
template_path = "/var/lib/collector/html-template.tmp"
|
||||||
output_path = "/var/www/html/index.html"
|
output_path = "/var/www/html/index.html"
|
||||||
|
|
||||||
|
[[nodes.output.nodelist]]
|
||||||
|
enable = true
|
||||||
|
path = "/var/www/html/meshviewer/data/nodelist.json"
|
||||||
|
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
# cleaning data of measurement node,
|
# cleaning data of measurement node,
|
||||||
|
@ -2,7 +2,7 @@ function ffhbCurrentStats(data) {
|
|||||||
$("#freifunk").html("
|
$("#freifunk").html("
|
||||||
<h1><a href="https://bremen.freifunk.net/" style="color: #444;">bremen.freifunk.net</a></h1>
|
<h1><a href="https://bremen.freifunk.net/" style="color: #444;">bremen.freifunk.net</a></h1>
|
||||||
<p>
|
<p>
|
||||||
Nutzer: <span id="freifunk_clients">0</span><br>
|
Nutzer: <span id="freifunk_clients">0</span><br>
|
||||||
<i style="font-style: italic;">(auf <span id="freifunk_nodes">0</span> Geräte verteilt)</i>
|
<i style="font-style: italic;">(auf <span id="freifunk_nodes">0</span> Geräte verteilt)</i>
|
||||||
</p>
|
</p>
|
||||||
<p style="text-align: right;">
|
<p style="text-align: right;">
|
||||||
|
@ -21,8 +21,7 @@ func BuildNodesV1(toFilter filter, nodes *runtime.Nodes) interface{} {
|
|||||||
Timestamp: jsontime.Now(),
|
Timestamp: jsontime.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
for nodeID := range nodes.List {
|
for nodeID, nodeOrigin := range nodes.List {
|
||||||
nodeOrigin := nodes.List[nodeID]
|
|
||||||
nodeFiltere := toFilter(nodeOrigin)
|
nodeFiltere := toFilter(nodeOrigin)
|
||||||
if nodeOrigin.Statistics == nil || nodeFiltere == nil {
|
if nodeOrigin.Statistics == nil || nodeFiltere == nil {
|
||||||
continue
|
continue
|
||||||
|
@ -20,8 +20,7 @@ func BuildNodesV2(toFilter filter, nodes *runtime.Nodes) interface{} {
|
|||||||
Timestamp: jsontime.Now(),
|
Timestamp: jsontime.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
for nodeID := range nodes.List {
|
for _, nodeOrigin := range nodes.List {
|
||||||
nodeOrigin := nodes.List[nodeID]
|
|
||||||
nodeFiltere := toFilter(nodeOrigin)
|
nodeFiltere := toFilter(nodeOrigin)
|
||||||
if nodeOrigin.Statistics == nil || nodeFiltere == nil {
|
if nodeOrigin.Statistics == nil || nodeFiltere == nil {
|
||||||
continue
|
continue
|
||||||
|
64
output/nodelist/nodelist.go
Normal file
64
output/nodelist/nodelist.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package nodelist
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/FreifunkBremen/yanic/jsontime"
|
||||||
|
"github.com/FreifunkBremen/yanic/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NodeList rewritten after: https://github.com/ffnord/ffmap-backend/blob/c33ebf62f013e18bf71b5a38bd058847340db6b7/lib/nodelist.py
|
||||||
|
type NodeList struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
Timestamp jsontime.Time `json:"updated_at"` // Timestamp of the generation
|
||||||
|
List []*Node `json:"nodes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Node struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Position *Position `json:"position,omitempty"`
|
||||||
|
Status struct {
|
||||||
|
Online bool `json:"online"`
|
||||||
|
LastContact jsontime.Time `json:"lastcontact"`
|
||||||
|
Clients uint32 `json:"clients"`
|
||||||
|
} `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Position struct {
|
||||||
|
Lat float64 `json:"lat"`
|
||||||
|
Long float64 `json:"long"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNode(n *runtime.Node) *Node {
|
||||||
|
if nodeinfo := n.Nodeinfo; nodeinfo != nil {
|
||||||
|
node := &Node{
|
||||||
|
ID: nodeinfo.NodeID,
|
||||||
|
Name: nodeinfo.Hostname,
|
||||||
|
}
|
||||||
|
if location := nodeinfo.Location; location != nil {
|
||||||
|
node.Position = &Position{Lat: location.Latitude, Long: location.Longtitude}
|
||||||
|
}
|
||||||
|
|
||||||
|
node.Status.Online = n.Online
|
||||||
|
node.Status.LastContact = n.Lastseen
|
||||||
|
if statistics := n.Statistics; statistics != nil {
|
||||||
|
node.Status.Clients = statistics.Clients.Total
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func transform(nodes *runtime.Nodes) *NodeList {
|
||||||
|
nodelist := &NodeList{
|
||||||
|
Version: "1.0.1",
|
||||||
|
Timestamp: jsontime.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, nodeOrigin := range nodes.List {
|
||||||
|
node := NewNode(nodeOrigin)
|
||||||
|
if node != nil {
|
||||||
|
nodelist.List = append(nodelist.List, node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nodelist
|
||||||
|
}
|
60
output/nodelist/nodelist_test.go
Normal file
60
output/nodelist/nodelist_test.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package nodelist
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/FreifunkBremen/yanic/data"
|
||||||
|
"github.com/FreifunkBremen/yanic/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTransform(t *testing.T) {
|
||||||
|
nodes := transform(createTestNodes())
|
||||||
|
|
||||||
|
assert := assert.New(t)
|
||||||
|
assert.Len(nodes.List, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createTestNodes() *runtime.Nodes {
|
||||||
|
nodes := runtime.NewNodes(&runtime.Config{})
|
||||||
|
|
||||||
|
nodeData := &data.ResponseData{
|
||||||
|
Statistics: &data.Statistics{
|
||||||
|
Clients: data.Clients{
|
||||||
|
Total: 23,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NodeInfo: &data.NodeInfo{
|
||||||
|
Hardware: data.Hardware{
|
||||||
|
Model: "TP-Link 841",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
nodeData.NodeInfo.Software.Firmware.Release = "2016.1.6+entenhausen1"
|
||||||
|
nodes.Update("abcdef012345", nodeData)
|
||||||
|
|
||||||
|
nodes.Update("112233445566", &data.ResponseData{
|
||||||
|
Statistics: &data.Statistics{
|
||||||
|
Clients: data.Clients{
|
||||||
|
Total: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NodeInfo: &data.NodeInfo{
|
||||||
|
Hardware: data.Hardware{
|
||||||
|
Model: "TP-Link 841",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
nodes.Update("0xdeadbeef0x", &data.ResponseData{
|
||||||
|
NodeInfo: &data.NodeInfo{
|
||||||
|
VPN: true,
|
||||||
|
Hardware: data.Hardware{
|
||||||
|
Model: "Xeon Multi-Core",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return nodes
|
||||||
|
}
|
51
output/nodelist/output.go
Normal file
51
output/nodelist/output.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package nodelist
|
||||||
|
|
||||||
|
import (
|
||||||
|
goTemplate "text/template"
|
||||||
|
|
||||||
|
"github.com/FreifunkBremen/yanic/output"
|
||||||
|
"github.com/FreifunkBremen/yanic/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Output struct {
|
||||||
|
output.Output
|
||||||
|
config Config
|
||||||
|
nodes *runtime.Nodes
|
||||||
|
template *goTemplate.Template
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config map[string]interface{}
|
||||||
|
|
||||||
|
func (c Config) Enable() bool {
|
||||||
|
return c["enable"].(bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Config) Path() string {
|
||||||
|
return c["path"].(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
output.RegisterAdapter("nodelist", Register)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Register(nodes *runtime.Nodes, configuration interface{}) (output.Output, error) {
|
||||||
|
var config Config
|
||||||
|
config = configuration.(map[string]interface{})
|
||||||
|
if !config.Enable() {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Output{
|
||||||
|
config: config,
|
||||||
|
nodes: nodes,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Output) Save() {
|
||||||
|
o.nodes.RLock()
|
||||||
|
defer o.nodes.RUnlock()
|
||||||
|
|
||||||
|
if path := o.config.Path(); path != "" {
|
||||||
|
runtime.SaveJSON(transform(o.nodes), path)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user