adds more tests, help and some fixes

This commit is contained in:
Holger Cremer
2018-01-04 21:57:57 +01:00
parent 2e48c808b9
commit ac4d0a24ca
14 changed files with 150 additions and 24 deletions

View File

@@ -1,28 +1,68 @@
package main
import (
"fmt"
"os"
"github.com/ktt-ol/spaceDevices/conf"
"github.com/ktt-ol/spaceDevices/db"
"github.com/ktt-ol/spaceDevices/mqtt"
"github.com/ktt-ol/spaceDevices/webService"
log "github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
)
const CONFIG_FILE = "config.toml"
func main() {
log.SetLevel(log.DebugLevel)
log.SetFormatter(&log.TextFormatter{DisableColors: true})
config := conf.LoadConfig(CONFIG_FILE)
setupLogging(config.Misc)
//spaceDevices.EnableMqttDebugLogging()
userDb := db.NewUserDb(config.MacDb)
masterDb := db.NewMasterDb(config.MacDb)
mqttHandler := mqtt.NewMqttHandler(config.Mqtt)
data := mqtt.NewDeviceData(mqttHandler, masterDb, userDb)
data := mqtt.NewDeviceData(config.Locations, mqttHandler, masterDb, userDb)
webService.StartWebService(config.Server, data, userDb)
}
type StdErrLogHook struct {
}
func (h *StdErrLogHook) Levels() []logrus.Level {
return []logrus.Level{logrus.WarnLevel, logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel}
}
func (h *StdErrLogHook) Fire(entry *logrus.Entry) error {
line, err := entry.String()
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
return err
}
fmt.Fprintf(os.Stderr, line)
return nil
}
func setupLogging(config conf.MiscConf) {
logrus.SetFormatter(&logrus.TextFormatter{DisableColors: true})
if config.DebugLogging {
logrus.SetLevel(logrus.DebugLevel)
} else {
logrus.SetLevel(logrus.InfoLevel)
}
if config.Logfile == "" {
logrus.SetOutput(os.Stdout)
} else {
// https://github.com/sirupsen/logrus/issues/227
file, err := os.OpenFile(config.Logfile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
if err == nil {
logrus.SetOutput(file)
} else {
logrus.Warnf("Failed to log to file '%s', using default stderr.", config.Logfile)
}
logrus.AddHook(&StdErrLogHook{})
}
}

View File

@@ -16,12 +16,18 @@ func LoadConfig(configFile string) TomlConfig {
}
type TomlConfig struct {
Misc MiscConf
Server ServerConf
MacDb MacDbConf
Mqtt MqttConf
Locations []Location `toml:"location"`
}
type MiscConf struct {
DebugLogging bool
Logfile string
}
type ServerConf struct {
Host string
Port int

View File

@@ -11,6 +11,8 @@ func Test_exampleConfig(t *testing.T) {
assert := assert.New(t)
config := conf.LoadConfig("../config.example.toml")
assert.Equal(false, config.Misc.DebugLogging)
assert.Equal("", config.Misc.Logfile)
assert.Equal(2, len(config.Locations))
assert.Equal("Bar", config.Locations[0].Name)
assert.Equal(2, len(config.Locations[0].Ids))

View File

@@ -1,4 +1,8 @@
# COPY THIS TO config.toml
[misc]
debugLogging = false
# if enabled, all logging goes to the file. Warn and up goes to stderr, too.
# logfile = "/var/log/spaceDevices2.log"
[server]
host = "0.0.0.0"

View File

@@ -9,4 +9,6 @@ func Test_IsMacLocallyAdministered(t *testing.T) {
assert.True(t, IsMacLocallyAdministered("06:00:00:00:00:00"))
assert.True(t, IsMacLocallyAdministered("62:01:0f:b5:f2:d9"))
assert.False(t, IsMacLocallyAdministered("20:c9:d0:7a:fa:31"))
assert.True(t, IsMacLocallyAdministered("d4:38:9c:01:dd:03"))
}

3
do.sh
View File

@@ -15,6 +15,9 @@ while (( "$#" )); do
build-linux)
env GOOS=linux GOARCH=amd64 go build cmd/spaceDevices.go
;;
test-sync)
rsync -n -avzi --delete spaceDevices webUI root@spacegate:/home/status/spaceDevices2/
;;
sync)
rsync -avzi --delete spaceDevices webUI root@spacegate:/home/status/spaceDevices2/
;;

View File

@@ -2,12 +2,15 @@ package mqtt
import (
"encoding/json"
"fmt"
"github.com/ktt-ol/spaceDevices/conf"
"github.com/ktt-ol/spaceDevices/db"
"github.com/sirupsen/logrus"
"crypto/md5"
"fmt"
"bytes"
"sort"
)
var ignoredVisibility = [...]db.Visibility{db.VisibilityCriticalInfrastructure, db.VisibilityImportantInfrastructure,
@@ -27,6 +30,9 @@ type DeviceData struct {
masterDb db.MasterDb
userDb db.UserDb
wifiSessionList []WifiSession
lastSentHash []byte
// more to come, e.g. LanSessions
}
@@ -44,12 +50,32 @@ func NewDeviceData(locations []conf.Location, mqttHandler *MqttHandler, masterDb
}
func (d *DeviceData) newData(data []byte) {
fmt.Println("got data, len ", len(data))
sessionsList, peopleAndDevices, ok := d.parseWifiSessions(data)
if ok {
d.wifiSessionList = sessionsList
fmt.Printf("peopleAndDevices: %+v\n", peopleAndDevices)
d.mqttHandler.SendPeopleAndDevices(peopleAndDevices)
if ddLogger.Logger.Level >= logrus.DebugLevel {
people := make(map[string]interface{})
for _, p := range peopleAndDevices.People {
people[p.Name] = nil
}
peopleList := make([]string, len(people))
for k, _ := range people {
peopleList = append(peopleList, k)
}
sort.Strings(peopleList)
ddLogger.Debugf("PeopleCount: %d, DeviceCount: %d, UnknownDevicesCount: %d, Persons: %s",
peopleAndDevices.PeopleCount, peopleAndDevices.DeviceCount, peopleAndDevices.UnknownDevicesCount, peopleList)
}
h := md5.New()
s := fmt.Sprintf("%v", peopleAndDevices)
hash := h.Sum([]byte(s))
if bytes.Equal(hash, d.lastSentHash) {
ddLogger.Debug("Nothing changed in people count, skipping mqtt")
} else {
d.mqttHandler.SendPeopleAndDevices(peopleAndDevices)
d.lastSentHash = hash
}
}
}
@@ -139,11 +165,13 @@ SESSION_LOOP:
var person Person
if devicesEntry.showDevices {
person = Person{Name: username, Devices: devicesEntry.devices}
sort.Sort(DevicesSorter(person.Devices))
} else {
person = Person{Name: username}
}
peopleAndDevices.People = append(peopleAndDevices.People, person)
}
sort.Sort(PersonSorter(peopleAndDevices.People))
success = true
return

View File

@@ -189,10 +189,21 @@ func Test_peopleCalculation(t *testing.T) {
entry.Visibility = db.VisibilityCriticalInfrastructure
masterMap["00:00:00:00:00:05"] = entry
_, peopleAndDevices, _ = dd.parseWifiSessions(testData)
fmt.Printf("peopleAndDevices: %+v\n", peopleAndDevices)
assertPeopleAndDevices(assert, 2, 3, 5, 0, peopleAndDevices)
t.Fail()
// add a second device for olaf
testData = newSessionTestData(stt("1", "01"), stt("2", "02"), stt("3", "03"), stt("4", "04"), stt("5", "05"), stt("6", "06"))
userMap["00:00:00:00:00:06"] = db.UserDbEntry{Name: "olaf", DeviceName: "mac", Visibility: db.VisibilityAll}
_, peopleAndDevices, _ = dd.parseWifiSessions(testData)
fmt.Printf("peopleAndDevices: %+v\n", peopleAndDevices)
assertPeopleAndDevices(assert, 2, 3, 6, 0, peopleAndDevices)
for _, p := range peopleAndDevices.People {
if p.Name == "olaf" {
assert.Equal(2, len(p.Devices))
} else {
assert.Equal(0, len(p.Devices))
}
}
}
func assertPeopleAndDevices(assert *assert.Assertions, peopleArrayCount int, peopleCount uint, deviceCount uint, unknownDevicesCount uint, test PeopleAndDevices) {

View File

@@ -16,7 +16,8 @@ const CLIENT_ID = "spaceDevices2"
const TOPIC_SESSIONS = "/net/wlan-sessions"
// ATTENTION: test topic!
const TOPIC_DEVICES = "/test/net_devices"
//const TOPIC_DEVICES = "/test/net_devices"
const TOPIC_DEVICES = "/net/devices"
var mqttLogger = log.WithField("where", "mqtt")
@@ -108,7 +109,7 @@ func (h *MqttHandler) onConnect(client mqtt.Client) {
err := subscribe(client, TOPIC_SESSIONS,
func(client mqtt.Client, message mqtt.Message) {
mqttLogger.Debug("new wifi sessions")
/*
///*
mock := []byte(`{ "38134": {
"last-auth": 1509211121,
"vlan": "default",
@@ -126,7 +127,7 @@ func (h *MqttHandler) onConnect(client mqtt.Client) {
"last-snr": 47,
"last-rate-mbits": "6",
"ap": 1,
"mac": "10:68:3f:bb:bb:bb",
"mac": "d4:38:9c:01:dd:03",
"radio": 2,
"userinfo": {
"name": "Holger",
@@ -137,10 +138,10 @@ func (h *MqttHandler) onConnect(client mqtt.Client) {
"last-rssi-dbm": -48,
"last-activity": 1509211584
}}`)
*/
//*/
select {
// case h.newDataChan <- mock:
case h.newDataChan <- message.Payload():
case h.newDataChan <- mock:
//case h.newDataChan <- message.Payload():
break
default:
mqttLogger.Println("No one receives the message.")

View File

@@ -1,5 +1,9 @@
package mqtt
import (
"strings"
)
type WifiSession struct {
Ip string
Mac string
@@ -12,14 +16,38 @@ type Devices struct {
Location string `json:"location"`
}
type DevicesSorter []Devices
func (s DevicesSorter) Len() int {
return len(s)
}
func (s DevicesSorter) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s DevicesSorter) Less(i, j int) bool {
return strings.Compare(s[i].Name, s[j].Name) < 0
}
type Person struct {
Name string `json:"name"`
Devices []Devices `json:"devices"`
}
type PersonSorter []Person
func (s PersonSorter) Len() int {
return len(s)
}
func (s PersonSorter) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s PersonSorter) Less(i, j int) bool {
return strings.Compare(s[i].Name, s[j].Name) < 0
}
type PeopleAndDevices struct {
People []Person `json:"people"`
PeopleCount uint `json:"peopleCount"`
DeviceCount uint `json:"deviceCount"`
UnknownDevicesCount uint `json:"unknownDevicesCount"`
PeopleCount uint16 `json:"peopleCount"`
DeviceCount uint16 `json:"deviceCount"`
UnknownDevicesCount uint16 `json:"unknownDevicesCount"`
}

View File

@@ -60,12 +60,12 @@ func overviewPageHandler(c *gin.Context) {
isLocallyAdministered := false
macNotFound := false
if info, ok := devices.GetByIp(ip); ok {
mac = info.Mac
isLocallyAdministered = db.IsMacLocallyAdministered(mac)
if userInfo, ok := macDb.Get(info.Mac); ok {
mac = info.Mac
name = userInfo.Name
deviceName = userInfo.DeviceName
visibility = userInfo.Visibility
isLocallyAdministered = db.IsMacLocallyAdministered(mac)
}
} else {
macNotFound = true

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -25,11 +25,12 @@
von der <a href="https://status.kreativitaet-trifft-technik.de">Status</a> Seite.
<div class="img-responsive screenshot">
<img src="assets/images/screenshot.png" class="img-thumbnail" />
<img src="assets/images/example.jpg" class="img-thumbnail" />
</div>
<ul>
<li>Mit "Mit Name/Alias anzeigen." wirst du in <span class="legend">A</span> angezeigt.</li>
<li>Mit "Alles anzeigen, d.h. Name/Alias und Gerätename." wirst du in <span class="legend">A1</span> und <span class="legend">A2</span> angezeigt.</li>
<li>Mit "Mit Name/Alias anzeigen." wirst du nur in <span class="legend">A1</span> angezeigt.</li>
<li>Mit "Als anonyme Person anzeigen." wirst du in <span class="legend">B</span> angezeigt.</li>
<li>Wenn du noch gar nichts eingetragen hast oder "Eintrag löschen" gewählt hast, dann wirst du in <span class="legend">C</span> angezeigt.
</li>