diff --git a/api/aliases.go b/api/aliases.go index 90f19cf..85eb1bd 100644 --- a/api/aliases.go +++ b/api/aliases.go @@ -8,9 +8,8 @@ import ( "net/http" ) -// 7 nachkommerstellen sollten genug sein (7cm genau) +// GEOROUND : 7 nachkommerstellen sollten genug sein (7cm genau) // http://blog.3960.org/post/7309573249/genauigkeit-bei-geo-koordinaten - const GEOROUND = 0.0000001 func geoEqual(a, b float64) bool { @@ -20,29 +19,33 @@ func geoEqual(a, b float64) bool { return false } -type ApiAliases struct { +// AliasesAPI struct for API +type AliasesAPI struct { aliases *models.Aliases config *models.Config nodes *models.Nodes } +// NewAliases Bind to API func NewAliases(config *models.Config, router *httprouter.Router, prefix string, nodes *models.Nodes) { - api := &ApiAliases{ + api := &AliasesAPI{ aliases: models.NewAliases(config), nodes: nodes, config: config, } router.GET(prefix, api.GetAll) - router.GET(prefix+"/ansible", api.AnsibleDiff) + router.GET(prefix+"/ansible", api.Ansible) 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))) } -func (api *ApiAliases) GetAll(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { +// GetAll request for get all aliases +func (api *AliasesAPI) GetAll(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { jsonOutput(w, r, api.aliases.List) } -func (api *ApiAliases) GetOne(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { +// GetOne request for get one alias +func (api *AliasesAPI) GetOne(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { if alias := api.aliases.List[ps.ByName("nodeid")]; alias != nil { jsonOutput(w, r, alias) return @@ -50,7 +53,8 @@ func (api *ApiAliases) GetOne(w http.ResponseWriter, r *http.Request, ps httprou fmt.Fprint(w, "Not found: ", ps.ByName("nodeid"), "\n") } -func (api *ApiAliases) SaveOne(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { +// SaveOne request for save a alias +func (api *AliasesAPI) SaveOne(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { var alias models.Alias err := json.NewDecoder(r.Body).Decode(&alias) @@ -63,7 +67,9 @@ func (api *ApiAliases) SaveOne(w http.ResponseWriter, r *http.Request, ps httpro fmt.Print("[api] node updated '", ps.ByName("nodeid"), "'\n") jsonOutput(w, r, alias) } -func (api *ApiAliases) AnsibleDiff(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + +// Ansible json output +func (api *AliasesAPI) Ansible(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Print("[api] ansible\n") jsonOutput(w, r, models.GenerateAnsible(api.nodes, api.aliases.List)) } diff --git a/api/lib.go b/api/lib.go index 727be05..2cc434e 100644 --- a/api/lib.go +++ b/api/lib.go @@ -2,15 +2,15 @@ package api import ( "bytes" - "strings" - "net/http" - "encoding/json" "encoding/base64" + "encoding/json" + "net/http" + "strings" "github.com/julienschmidt/httprouter" ) -func jsonOutput(w http.ResponseWriter, r *http.Request,data interface{}){ +func jsonOutput(w http.ResponseWriter, r *http.Request, data interface{}) { js, err := json.Marshal(data) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) @@ -22,40 +22,42 @@ func jsonOutput(w http.ResponseWriter, r *http.Request,data interface{}){ w.Header().Set("Access-Control-Allow-Origin", origin) } w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") - w.Header().Set("Access-Control-Allow-Headers","Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") + w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") w.Header().Set("Access-Control-Allow-Credentials", "true") w.Write(js) } + +// BasicAuth for API request func BasicAuth(h httprouter.Handle, pass []byte) httprouter.Handle { - return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { - if origin := r.Header.Get("Origin"); origin != "" { - w.Header().Set("Access-Control-Allow-Origin", origin) - } - w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") - w.Header().Set("Access-Control-Allow-Headers","Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") - w.Header().Set("Access-Control-Allow-Credentials", "true") - - const basicAuthPrefix string = "Basic " - - // Get the Basic Authentication credentials - auth := r.Header.Get("Authorization") - if strings.HasPrefix(auth, basicAuthPrefix) { - // Check credentials - payload, err := base64.StdEncoding.DecodeString(auth[len(basicAuthPrefix):]) - if err == nil { - pair := bytes.SplitN(payload, []byte(":"), 2) - if len(pair) == 2 && - bytes.Equal(pair[1], pass) { - - // Delegate request to the given handle - h(w, r, ps) - return - } - } - } - - // Request Basic Authentication otherwise - w.Header().Set("WWW-Authenticate", "Basic realm=Restricted") - http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + if origin := r.Header.Get("Origin"); origin != "" { + w.Header().Set("Access-Control-Allow-Origin", origin) } + w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") + w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") + w.Header().Set("Access-Control-Allow-Credentials", "true") + + const basicAuthPrefix string = "Basic " + + // Get the Basic Authentication credentials + auth := r.Header.Get("Authorization") + if strings.HasPrefix(auth, basicAuthPrefix) { + // Check credentials + payload, err := base64.StdEncoding.DecodeString(auth[len(basicAuthPrefix):]) + if err == nil { + pair := bytes.SplitN(payload, []byte(":"), 2) + if len(pair) == 2 && + bytes.Equal(pair[1], pass) { + + // Delegate request to the given handle + h(w, r, ps) + return + } + } + } + + // Request Basic Authentication otherwise + w.Header().Set("WWW-Authenticate", "Basic realm=Restricted") + http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + } } diff --git a/api/nodes.go b/api/nodes.go index bc02a5d..c0c3586 100644 --- a/api/nodes.go +++ b/api/nodes.go @@ -6,19 +6,22 @@ import ( "net/http" ) -type ApiNodes struct { +// NodesAPI struct for API +type NodesAPI struct { config *models.Config nodes *models.Nodes } +// NewNodes Bind to API func NewNodes(config *models.Config, router *httprouter.Router, prefix string, nodes *models.Nodes) { - api := &ApiNodes{ + api := &NodesAPI{ nodes: nodes, config: config, } router.GET(prefix, api.GetAll) } -func (api *ApiNodes) GetAll(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { +// GetAll request for get all nodes +func (api *NodesAPI) GetAll(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { jsonOutput(w, r, api.nodes.List) } diff --git a/cmd/respond-collector/main.go b/cmd/respond-collector/main.go index 7d2d33b..ef0f1f5 100644 --- a/cmd/respond-collector/main.go +++ b/cmd/respond-collector/main.go @@ -57,11 +57,11 @@ func main() { if config.Webserver.Enable { router := httprouter.New() - if config.Webserver.Api.NewNodes { + if config.Webserver.API.NewNodes { api.NewNodes(config, router, "/api/nodes", nodes) log.Println("api nodes started") } - if config.Webserver.Api.Aliases { + if config.Webserver.API.Aliases { api.NewAliases(config, router, "/api/aliases", nodes) log.Println("api aliases started") } diff --git a/data/airtime.go b/data/airtime.go index 0c8ef3b..6533963 100644 --- a/data/airtime.go +++ b/data/airtime.go @@ -4,6 +4,7 @@ import ( "math" ) +// Wireless struct type Wireless struct { TxPower24 uint32 `json:"txpower24,omitempty"` Channel24 uint32 `json:"channel24,omitempty"` @@ -11,30 +12,32 @@ type Wireless struct { Channel5 uint32 `json:"channel5,omitempty"` } +// WirelessStatistics struct type WirelessStatistics []*WirelessAirtime +// WirelessAirtime struct type WirelessAirtime struct { ChanUtil float32 // Channel utilization RxUtil float32 // Receive utilization TxUtil float32 // Transmit utilization - Active_time uint64 `json:"active"` - Busy_time uint64 `json:"busy"` - Rx_time uint64 `json:"rx"` - Tx_time uint64 `json:"tx"` - Noise uint32 `json:"noise"` - Frequency uint32 `json:"frequency"` + ActiveTime uint64 `json:"active"` + BusyTime uint64 `json:"busy"` + RxTime uint64 `json:"rx"` + TxTime uint64 `json:"tx"` + Noise uint32 `json:"noise"` + Frequency uint32 `json:"frequency"` } +// FrequencyName to 11g or 11a func (airtime WirelessAirtime) FrequencyName() string { if airtime.Frequency < 5000 { return "11g" - } else { - return "11a" } + return "11a" } -// Calculates the utilization values in regard to the previous values +// SetUtilization Calculates the utilization values in regard to the previous values func (current WirelessStatistics) SetUtilization(previous WirelessStatistics) { for _, c := range current { for _, p := range previous { @@ -45,21 +48,21 @@ func (current WirelessStatistics) SetUtilization(previous WirelessStatistics) { } } -// Calculates the utilization values in regard to the previous values -func (cur *WirelessAirtime) SetUtilization(prev *WirelessAirtime) { - if cur.Active_time <= prev.Active_time { +// SetUtilization Calculates the utilization values in regard to the previous values +func (airtime *WirelessAirtime) SetUtilization(prev *WirelessAirtime) { + if airtime.ActiveTime <= prev.ActiveTime { return } - active := float64(cur.Active_time) - float64(prev.Active_time) - busy := float64(cur.Busy_time) - float64(prev.Busy_time) - rx := float64(cur.Tx_time) - float64(prev.Tx_time) - tx := float64(cur.Rx_time) - float64(prev.Rx_time) + active := float64(airtime.ActiveTime) - float64(prev.ActiveTime) + busy := float64(airtime.BusyTime) - float64(prev.BusyTime) + rx := float64(airtime.TxTime) - float64(prev.TxTime) + tx := float64(airtime.RxTime) - float64(prev.RxTime) // Calculate utilizations if active > 0 { - cur.ChanUtil = float32(math.Min(100, 100*(busy+rx+tx)/active)) - cur.RxUtil = float32(math.Min(100, 100*rx/active)) - cur.TxUtil = float32(math.Min(100, 100*tx/active)) + airtime.ChanUtil = float32(math.Min(100, 100*(busy+rx+tx)/active)) + airtime.RxUtil = float32(math.Min(100, 100*rx/active)) + airtime.TxUtil = float32(math.Min(100, 100*tx/active)) } } diff --git a/data/airtime_test.go b/data/airtime_test.go index ed00cd1..e5ecfb7 100644 --- a/data/airtime_test.go +++ b/data/airtime_test.go @@ -18,22 +18,22 @@ func TestUtilization(t *testing.T) { assert := assert.New(t) t1 := &WirelessAirtime{ - Active_time: 20, - Busy_time: 0, - Tx_time: 5, - Rx_time: 0, + ActiveTime: 20, + BusyTime: 0, + TxTime: 5, + RxTime: 0, } t2 := &WirelessAirtime{ - Active_time: 120, - Busy_time: 10, - Tx_time: 25, - Rx_time: 15, + ActiveTime: 120, + BusyTime: 10, + TxTime: 25, + RxTime: 15, } t3 := &WirelessAirtime{ - Active_time: 200, - Busy_time: 40, - Tx_time: 35, - Rx_time: 15, + ActiveTime: 200, + BusyTime: 40, + TxTime: 35, + RxTime: 15, } t1.SetUtilization(t2) @@ -58,23 +58,23 @@ func TestWirelessStatistics(t *testing.T) { stats := WirelessStatistics([]*WirelessAirtime{{ Frequency: 2400, - Active_time: 20, - Tx_time: 10, + ActiveTime: 20, + TxTime: 10, }}) // Different Frequency, should not change anything stats.SetUtilization([]*WirelessAirtime{{ Frequency: 5000, - Active_time: 15, - Tx_time: 1, + ActiveTime: 15, + TxTime: 1, }}) assert.EqualValues(0, stats[0].ChanUtil) // Same Frequency, should set the utilization stats.SetUtilization([]*WirelessAirtime{{ Frequency: 2400, - Active_time: 10, - Tx_time: 5, + ActiveTime: 10, + TxTime: 5, }}) assert.EqualValues(50, stats[0].ChanUtil) } diff --git a/data/neighbours.go b/data/neighbours.go index ffe4086..08fd0d2 100644 --- a/data/neighbours.go +++ b/data/neighbours.go @@ -1,34 +1,41 @@ package data +// Neighbours struct type Neighbours struct { Batadv map[string]BatadvNeighbours `json:"batadv"` LLDP map[string]LLDPNeighbours `json:"lldp"` //WifiNeighbours map[string]WifiNeighbours `json:"wifi"` - NodeId string `json:"node_id"` + NodeID string `json:"node_id"` } +// WifiLink struct type WifiLink struct { Inactive int `json:"inactive"` Noise int `json:"nois"` Signal int `json:"signal"` } +// BatmanLink struct type BatmanLink struct { Lastseen float64 `json:"lastseen"` Tq int `json:"tq"` } +// LLDPLink struct type LLDPLink struct { Name string `json:"name"` Description string `json:"descr"` } +// BatadvNeighbours struct type BatadvNeighbours struct { Neighbours map[string]BatmanLink `json:"neighbours"` } +// WifiNeighbours struct type WifiNeighbours struct { Neighbours map[string]WifiLink `json:"neighbours"` } +// LLDPNeighbours struct type LLDPNeighbours map[string]LLDPLink diff --git a/data/nodeinfo.go b/data/nodeinfo.go index 0421cf0..e202857 100644 --- a/data/nodeinfo.go +++ b/data/nodeinfo.go @@ -1,7 +1,8 @@ package data +// NodeInfo struct type NodeInfo struct { - NodeId string `json:"node_id"` + NodeID string `json:"node_id"` Network Network `json:"network"` Owner *Owner `json:"-"` // Removed for privacy reasons System System `json:"system"` @@ -12,6 +13,8 @@ type NodeInfo struct { VPN bool `json:"vpn"` Wireless *Wireless `json:"wireless,omitempty"` } + +// BatInterface struct type BatInterface struct { Interfaces struct { Wireless []string `json:"wireless,omitempty"` @@ -20,6 +23,7 @@ type BatInterface struct { } `json:"interfaces"` } +// Network struct type Network struct { Mac string `json:"mac"` Addresses []string `json:"addresses"` @@ -27,20 +31,24 @@ type Network struct { MeshInterfaces []string `json:"mesh_interfaces"` } +// Owner struct type Owner struct { Contact string `json:"contact"` } +// System struct type System struct { SiteCode string `json:"site_code"` } +// Location struct type Location struct { Longtitude float64 `json:"longitude"` Latitude float64 `json:"latitude"` Altitude float64 `json:"altitude,omitempty"` } +// Software struct type Software struct { Autoupdater struct { Enabled bool `json:"enabled,omitempty"` @@ -59,10 +67,11 @@ type Software struct { Release string `json:"release,omitempty"` } `json:"firmware,omitempty"` StatusPage struct { - Api int `json:"api"` + API int `json:"api"` } `json:"status-page,omitempty"` } +// Hardware struct type Hardware struct { Nproc int `json:"nproc"` Model string `json:"model"` diff --git a/data/response.go b/data/response.go index be9231d..502d7d2 100644 --- a/data/response.go +++ b/data/response.go @@ -1,5 +1,6 @@ package data +// ResponseData struct type ResponseData struct { Neighbours *Neighbours `json:"neighbours"` NodeInfo *NodeInfo `json:"nodeinfo"` diff --git a/data/statistics.go b/data/statistics.go index a97c63d..30e08bf 100644 --- a/data/statistics.go +++ b/data/statistics.go @@ -5,8 +5,9 @@ package data They always return float. */ +//Statistics struct type Statistics struct { - NodeId string `json:"node_id"` + NodeID string `json:"node_id"` Clients Clients `json:"clients"` RootFsUsage float64 `json:"rootfs_usage,omitempty"` LoadAverage float64 `json:"loadavg,omitempty"` @@ -30,25 +31,30 @@ type Statistics struct { Wireless WirelessStatistics `json:"wireless,omitempty"` } +// MeshVPNPeerLink struct type MeshVPNPeerLink struct { Established float64 `json:"established"` } +// MeshVPNPeerGroup struct type MeshVPNPeerGroup struct { Peers map[string]*MeshVPNPeerLink `json:"peers"` Groups map[string]*MeshVPNPeerGroup `json:"groups"` } +// MeshVPN struct type MeshVPN struct { Groups map[string]*MeshVPNPeerGroup `json:"groups,omitempty"` } +// Traffic struct type Traffic struct { Bytes float64 `json:"bytes,omitempty"` Packets float64 `json:"packets,omitempty"` Dropped float64 `json:"dropped,omitempty"` } +// Clients struct type Clients struct { Wifi uint32 `json:"wifi"` Wifi24 uint32 `json:"wifi24"` @@ -56,6 +62,7 @@ type Clients struct { Total uint32 `json:"total"` } +// Memory struct type Memory struct { Cached uint32 `json:"cached"` Total uint32 `json:"total"` @@ -63,6 +70,7 @@ type Memory struct { Free uint32 `json:"free"` } +// SwitchPort struct type SwitchPort struct { Speed uint32 `json:"speed"` } diff --git a/data/statistics_test.go b/data/statistics_test.go index fc95f28..c323266 100644 --- a/data/statistics_test.go +++ b/data/statistics_test.go @@ -13,7 +13,7 @@ func TestStatistics(t *testing.T) { obj := &Statistics{} testfile("statistics.json", obj) - assert.Equal("f81a67a601ea", obj.NodeId) + assert.Equal("f81a67a601ea", obj.NodeID) assert.Equal("52:54:00:a9:f7:6e", obj.Gateway) assert.Equal(float64(57861871176), obj.Traffic.Rx.Bytes) assert.Equal(uint32(35), obj.Clients.Total) diff --git a/database/database.go b/database/database.go index 01b9724..6b87adb 100644 --- a/database/database.go +++ b/database/database.go @@ -85,11 +85,12 @@ func (db *DB) AddCounterMap(name string, m models.CounterMap) { } // Add data for a single node -func (db *DB) Add(nodeId string, node *models.Node) { +func (db *DB) Add(nodeID string, node *models.Node) { tags, fields := node.ToInflux() db.AddPoint(MeasurementNode, tags, fields, time.Now()) } +// Close all connection and clean up func (db *DB) Close() { close(db.quit) close(db.points) diff --git a/jsontime/jsontime.go b/jsontime/jsontime.go index fb97f5c..12baa32 100644 --- a/jsontime/jsontime.go +++ b/jsontime/jsontime.go @@ -5,21 +5,26 @@ import ( "time" ) +// TimeFormat of JSONTime const TimeFormat = "2006-01-02T15:04:05-0700" +//Time struct of JSONTime type Time struct { time time.Time } +// Now current Time func Now() Time { return Time{time.Now()} } +//MarshalJSON to bytearray func (t Time) MarshalJSON() ([]byte, error) { stamp := `"` + t.time.Format(TimeFormat) + `"` return []byte(stamp), nil } +// UnmarshalJSON from bytearray func (t *Time) UnmarshalJSON(data []byte) (err error) { if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' { return errors.New("invalid jsontime") @@ -29,24 +34,33 @@ func (t *Time) UnmarshalJSON(data []byte) (err error) { } return } + +// GetTime normal func (t Time) GetTime() time.Time { return t.time } + +// Unix of this time func (t Time) Unix() int64 { return t.time.Unix() } +// IsZero is time zero? func (t Time) IsZero() bool { return t.time.IsZero() } +// Add given Duration to this time func (t Time) Add(d time.Duration) Time { return Time{time: t.time.Add(d)} } + +// After is this time after the given? func (t Time) After(u Time) bool { return t.time.After(u.GetTime()) } +// Before is this time before the given? func (t Time) Before(u Time) bool { return t.time.Before(u.GetTime()) } diff --git a/meshviewer/meshviewer.go b/meshviewer/meshviewer.go index a1249dc..ff1135e 100644 --- a/meshviewer/meshviewer.go +++ b/meshviewer/meshviewer.go @@ -15,6 +15,7 @@ type Node struct { Neighbours *data.Neighbours `json:"-"` } +// Flags status of node set by collector for the meshviewer type Flags struct { Online bool `json:"online"` Gateway bool `json:"gateway"` @@ -36,8 +37,9 @@ type NodesV2 struct { List []*Node `json:"nodes"` // the current nodemap, as array } +// Statistics a meshviewer spezifisch struct, diffrent from respondd type Statistics struct { - NodeId string `json:"node_id"` + NodeID string `json:"node_id"` Clients uint32 `json:"clients"` RootFsUsage float64 `json:"rootfs_usage,omitempty"` LoadAverage float64 `json:"loadavg,omitempty"` @@ -59,18 +61,19 @@ type Statistics struct { } `json:"traffic,omitempty"` } +// NewStatistics transform respond Statistics to meshviewer Statistics func NewStatistics(stats *data.Statistics) *Statistics { total := stats.Clients.Total if total == 0 { total = stats.Clients.Wifi24 + stats.Clients.Wifi5 } /* The Meshviewer could not handle absolute memory output - * calc the used memory as a float witch 100% equal 1.0 - */ + * calc the used memory as a float witch 100% equal 1.0 + */ memoryUsage := (float64(stats.Memory.Total) - float64(stats.Memory.Free)) / float64(stats.Memory.Total) return &Statistics{ - NodeId: stats.NodeId, + NodeID: stats.NodeID, Gateway: stats.Gateway, RootFsUsage: stats.RootFsUsage, LoadAverage: stats.LoadAverage, diff --git a/models/aliases.go b/models/aliases.go index 21aa4d9..b263821 100644 --- a/models/aliases.go +++ b/models/aliases.go @@ -10,6 +10,7 @@ import ( "github.com/FreifunkBremen/respond-collector/data" ) +// Alias a change request for other nodes type Alias struct { Hostname string `json:"hostname,omitempty"` Location *data.Location `json:"location,omitempty"` @@ -17,14 +18,14 @@ type Alias struct { Owner string `json:"owner,omitempty"` } -// Nodes struct: cache DB of Node's structs +// Aliases struct: cache DB of Node's structs type Aliases struct { List map[string]*Alias `json:"nodes"` // the current nodemap, indexed by node ID config *Config sync.Mutex } -// NewNodes create Nodes structs +// NewAliases create Nodes structs func NewAliases(config *Config) *Aliases { aliases := &Aliases{ List: make(map[string]*Alias), @@ -39,6 +40,7 @@ func NewAliases(config *Config) *Aliases { return aliases } +// Update a alias in aliases cache func (e *Aliases) Update(nodeID string, newalias *Alias) { e.Lock() e.List[nodeID] = newalias @@ -51,7 +53,7 @@ func (e *Aliases) load() { log.Println("loading", path) if data, err := ioutil.ReadFile(path); err == nil { - if err := json.Unmarshal(data, e); err == nil { + if err = json.Unmarshal(data, e); err == nil { log.Println("loaded", len(e.List), "aliases") } else { log.Println("failed to unmarshal nodes:", err) diff --git a/models/ansible.go b/models/ansible.go index f418c30..0d774fb 100644 --- a/models/ansible.go +++ b/models/ansible.go @@ -1,11 +1,14 @@ package models +// Ansible struct type Ansible struct { Nodes []string `json:"nodes"` Meta struct { HostVars map[string]*AnsibleHostVars `json:"hostvars,omitempty"` } `json:"_meta"` } + +// AnsibleHostVars new values for a node type AnsibleHostVars struct { Address string `json:"ansible_ssh_host"` Hostname string `json:"node_name,omitempty"` @@ -18,6 +21,7 @@ type AnsibleHostVars struct { GeoLongitude float64 `json:"geo_longitude,omitempty"` } +// GenerateAnsible but nodes and aliases together to a ansible change output func GenerateAnsible(nodes *Nodes, aliases map[string]*Alias) *Ansible { ansible := &Ansible{Nodes: make([]string, 0)} ansible.Meta.HostVars = make(map[string]*AnsibleHostVars) diff --git a/models/config.go b/models/config.go index 1b24c87..c20efce 100644 --- a/models/config.go +++ b/models/config.go @@ -19,7 +19,7 @@ type Config struct { Port string `yaml:"port"` Address string `yaml:"address"` Webroot string `yaml:"webroot"` - Api struct { + API struct { Passphrase string `yaml:"passphrase"` NewNodes bool `yaml:"newnodes"` Aliases bool `yaml:"aliases"` @@ -47,7 +47,7 @@ type Config struct { } } -// reads a config models by path to a yml file +// ReadConfigFile reads a config model from path of a yml file func ReadConfigFile(path string) *Config { config := &Config{} file, _ := ioutil.ReadFile(path) diff --git a/models/graph.go b/models/graph.go index 3fb35f2..45d7cd4 100644 --- a/models/graph.go +++ b/models/graph.go @@ -5,6 +5,7 @@ import ( "strings" ) +// Graph a struct for all links between the nodes type Graph struct { Version int `json:"version"` Batadv struct { @@ -15,10 +16,13 @@ type Graph struct { } `json:"batadv"` } +// GraphNode small struct of a node for the graph struct type GraphNode struct { ID string `json:"id"` NodeID string `json:"node_id"` } + +// GraphLink a struct for the link between two nodes type GraphLink struct { Source int `json:"source"` Target int `json:"target"` @@ -27,14 +31,16 @@ type GraphLink struct { Bidirect bool `json:"bidirect"` } -type GraphBuilder struct { +// GraphBuilder a temporaty struct during fill the graph from the node neighbours +type graphBuilder struct { macToID map[string]string // mapping from MAC address to node id links map[string]*GraphLink // mapping from $idA-$idB to existing link vpn map[string]interface{} // IDs/addresses of VPN servers } +// BuildGraph transform from nodes (Neighbours) to Graph func (nodes *Nodes) BuildGraph() *Graph { - builder := &GraphBuilder{ + builder := &graphBuilder{ macToID: make(map[string]string), links: make(map[string]*GraphLink), vpn: make(map[string]interface{}), @@ -44,11 +50,11 @@ func (nodes *Nodes) BuildGraph() *Graph { graph := &Graph{Version: 1} graph.Batadv.Directed = false - graph.Batadv.Nodes, graph.Batadv.Links = builder.Extract() + graph.Batadv.Nodes, graph.Batadv.Links = builder.extract() return graph } -func (builder *GraphBuilder) readNodes(nodes map[string]*Node) { +func (builder *graphBuilder) readNodes(nodes map[string]*Node) { // Fill mac->id map for sourceID, node := range nodes { if nodeinfo := node.Nodeinfo; nodeinfo != nil { @@ -70,7 +76,7 @@ func (builder *GraphBuilder) readNodes(nodes map[string]*Node) { // Iterate over local MAC addresses from LLDP if neighbours := node.Neighbours; neighbours != nil { - for sourceAddr, _ := range neighbours.LLDP { + for sourceAddr := range neighbours.LLDP { builder.macToID[sourceAddr] = sourceID } } @@ -90,7 +96,7 @@ func (builder *GraphBuilder) readNodes(nodes map[string]*Node) { } // LLDP for _, neighbours := range neighbours.LLDP { - for targetAddress, _ := range neighbours { + for targetAddress := range neighbours { if targetID, found := builder.macToID[targetAddress]; found { builder.addLink(targetID, sourceID, 255) } @@ -101,7 +107,7 @@ func (builder *GraphBuilder) readNodes(nodes map[string]*Node) { } } -func (builder *GraphBuilder) Extract() ([]*GraphNode, []*GraphLink) { +func (builder *graphBuilder) extract() ([]*GraphNode, []*GraphLink) { links := make([]*GraphLink, len(builder.links)) nodes := make([]*GraphNode, len(builder.macToID)) idToIndex := make(map[string]int) @@ -131,7 +137,7 @@ func (builder *GraphBuilder) Extract() ([]*GraphNode, []*GraphLink) { return nodes, links } -func (builder *GraphBuilder) isVPN(ids ...string) bool { +func (builder *graphBuilder) isVPN(ids ...string) bool { for _, id := range ids { if _, found := builder.vpn[id]; found { return true @@ -140,7 +146,7 @@ func (builder *GraphBuilder) isVPN(ids ...string) bool { return false } -func (builder *GraphBuilder) addLink(targetID string, sourceID string, linkTq int) { +func (builder *graphBuilder) addLink(targetID string, sourceID string, linkTq int) { // Sort IDs to generate the key var key string if strings.Compare(sourceID, targetID) > 0 { diff --git a/models/node.go b/models/node.go index 31427f1..004af52 100644 --- a/models/node.go +++ b/models/node.go @@ -22,7 +22,7 @@ type Node struct { func (node *Node) ToInflux() (tags imodels.Tags, fields imodels.Fields) { stats := node.Statistics - tags.SetString("nodeid", stats.NodeId) + tags.SetString("nodeid", stats.NodeID) fields = map[string]interface{}{ "load": stats.LoadAverage, diff --git a/models/nodes.go b/models/nodes.go index e964801..f09d4ba 100644 --- a/models/nodes.go +++ b/models/nodes.go @@ -31,14 +31,15 @@ func NewNodes(config *Config) *Nodes { if config.Nodes.NodesDynamicPath != "" { nodes.load() } - /** - * Version '-1' because the nodes.json would not be defined, - * it would be change with the change of the respondd application on gluon - */ + /** + * Version '-1' because the nodes.json would not be defined, + * it would be change with the change of the respondd application on gluon + */ nodes.Version = -1 return nodes } +//Start all services to manage Nodes func (nodes *Nodes) Start() { go nodes.worker() } @@ -180,7 +181,7 @@ func (nodes *Nodes) load() { path := nodes.config.Nodes.NodesDynamicPath if f, err := os.Open(path); err == nil { // transform data to legacy meshviewer - if err := json.NewDecoder(f).Decode(nodes); err == nil { + if err = json.NewDecoder(f).Decode(nodes); err == nil { log.Println("loaded", len(nodes.List), "nodes") } else { log.Println("failed to unmarshal nodes:", err) diff --git a/models/nodes_test.go b/models/nodes_test.go index 165056d..af88e7a 100644 --- a/models/nodes_test.go +++ b/models/nodes_test.go @@ -79,7 +79,7 @@ func TestToInflux(t *testing.T) { node := Node{ Statistics: &data.Statistics{ - NodeId: "foobar", + NodeID: "foobar", LoadAverage: 0.5, }, Nodeinfo: &data.NodeInfo{ diff --git a/models/stats.go b/models/stats.go index 8fb9166..e045c6f 100644 --- a/models/stats.go +++ b/models/stats.go @@ -1,7 +1,9 @@ package models +// CounterMap to manage multiple values type CounterMap map[string]uint32 +// GlobalStats struct type GlobalStats struct { Clients uint32 ClientsWifi uint32 @@ -14,7 +16,7 @@ type GlobalStats struct { Models CounterMap } -// Returns global statistics for InfluxDB +//NewGlobalStats returns global statistics for InfluxDB func NewGlobalStats(nodes *Nodes) (result *GlobalStats) { result = &GlobalStats{ Firmwares: make(CounterMap), @@ -24,7 +26,7 @@ func NewGlobalStats(nodes *Nodes) (result *GlobalStats) { nodes.Lock() for _, node := range nodes.List { if node.Flags.Online { - result.Nodes += 1 + result.Nodes++ if stats := node.Statistics; stats != nil { result.Clients += stats.Clients.Total result.ClientsWifi24 += stats.Clients.Wifi24 @@ -32,7 +34,7 @@ func NewGlobalStats(nodes *Nodes) (result *GlobalStats) { result.ClientsWifi += stats.Clients.Wifi } if node.Flags.Gateway { - result.Gateways += 1 + result.Gateways++ } if info := node.Nodeinfo; info != nil { result.Models.Increment(info.Hardware.Model) @@ -53,7 +55,7 @@ func (m CounterMap) Increment(key string) { } } -// Returns fields for InfluxDB +// Fields returns fields for InfluxDB func (stats *GlobalStats) Fields() map[string]interface{} { return map[string]interface{}{ "nodes": stats.Nodes, diff --git a/respond/collector.go b/respond/collector.go index c2c4959..e30422b 100644 --- a/respond/collector.go +++ b/respond/collector.go @@ -28,7 +28,7 @@ type Collector struct { stop chan interface{} } -// Creates a Collector struct +// NewCollector creates a Collector struct func NewCollector(db *database.DB, nodes *models.Nodes, iface string) *Collector { // Parse address addr, err := net.ResolveUDPAddr("udp", "[::]:0") @@ -140,24 +140,24 @@ func (res *Response) parse() (*data.ResponseData, error) { func (coll *Collector) saveResponse(addr net.UDPAddr, res *data.ResponseData) { // Search for NodeID - var nodeId string + var nodeID string if val := res.NodeInfo; val != nil { - nodeId = val.NodeId + nodeID = val.NodeID } else if val := res.Neighbours; val != nil { - nodeId = val.NodeId + nodeID = val.NodeID } else if val := res.Statistics; val != nil { - nodeId = val.NodeId + nodeID = val.NodeID } // Updates nodes if NodeID found - if len(nodeId) != 12 { - log.Printf("invalid NodeID '%s' from %s", nodeId, addr.String()) + if len(nodeID) != 12 { + log.Printf("invalid NodeID '%s' from %s", nodeID, addr.String()) return } - node := coll.nodes.Update(nodeId, res) + node := coll.nodes.Update(nodeID, res) if coll.db != nil && node.Statistics != nil { - coll.db.Add(nodeId, node) + coll.db.Add(nodeID, node) } } diff --git a/respond/collector_test.go b/respond/collector_test.go index beffc93..f95f13d 100644 --- a/respond/collector_test.go +++ b/respond/collector_test.go @@ -23,5 +23,5 @@ func TestParse(t *testing.T) { assert.NoError(err) assert.NotNil(data) - assert.Equal("f81a67a5e9c1", data.NodeInfo.NodeId) + assert.Equal("f81a67a5e9c1", data.NodeInfo.NodeID) }