Create initial version of new package status

This commit is contained in:
Daniel 2018-08-14 17:09:18 +02:00
parent bdeddc41f9
commit 9cb0641f19
7 changed files with 258 additions and 0 deletions

14
status/const.go Normal file
View file

@ -0,0 +1,14 @@
package status
// Definitions of Security and Status Levels
const (
SecurityLevelOff uint8 = 0
SecurityLevelDynamic uint8 = 1
SecurityLevelSecure uint8 = 2
SecurityLevelFortress uint8 = 3
StatusOff uint8 = 0
StatusError uint8 = 1
StatusWarning uint8 = 2
StatusOk uint8 = 3
)

64
status/get.go Normal file
View file

@ -0,0 +1,64 @@
package status
import (
"sync/atomic"
"github.com/Safing/portbase/config"
)
var (
currentSecurityLevel *uint32
selectedSecurityLevel *uint32
threatLevel *uint32
portmasterStatus *uint32
gate17Status *uint32
)
func init() {
var (
currentSecurityLevelValue uint32
selectedSecurityLevelValue uint32
threatLevelValue uint32
portmasterStatusValue uint32
gate17StatusValue uint32
)
currentSecurityLevel = &currentSecurityLevelValue
selectedSecurityLevel = &selectedSecurityLevelValue
threatLevel = &threatLevelValue
portmasterStatus = &portmasterStatusValue
gate17Status = &gate17StatusValue
}
// GetCurrentSecurityLevel returns the current security level.
func GetCurrentSecurityLevel() uint8 {
return uint8(atomic.LoadUint32(currentSecurityLevel))
}
// GetSelectedSecurityLevel returns the selected security level.
func GetSelectedSecurityLevel() uint8 {
return uint8(atomic.LoadUint32(selectedSecurityLevel))
}
// GetThreatLevel returns the current threat level.
func GetThreatLevel() uint8 {
return uint8(atomic.LoadUint32(threatLevel))
}
// GetPortmasterStatus returns the current Portmaster status.
func GetPortmasterStatus() uint8 {
return uint8(atomic.LoadUint32(portmasterStatus))
}
// GetGate17Status returns the current Gate17 status.
func GetGate17Status() uint8 {
return uint8(atomic.LoadUint32(gate17Status))
}
// GetConfigByLevel returns whether the given security level dependent config option is on or off.
func GetConfigByLevel(name string) func() bool {
activatedLevel := config.GetAsInt(name, int64(SecurityLevelDynamic))
return func() bool {
return uint8(activatedLevel()) <= GetCurrentSecurityLevel()
}
}

16
status/get_test.go Normal file
View file

@ -0,0 +1,16 @@
package status
import "testing"
func TestGet(t *testing.T) {
// only test for panics
GetCurrentSecurityLevel()
GetSelectedSecurityLevel()
GetThreatLevel()
GetPortmasterStatus()
GetGate17Status()
option := GetConfigByLevel("invalid")
option()
}

65
status/set.go Normal file
View file

@ -0,0 +1,65 @@
package status
import "sync/atomic"
// SetCurrentSecurityLevel sets the current security level.
func SetCurrentSecurityLevel(level uint8) {
sysStatusLock.Lock()
defer sysStatusLock.Unlock()
sysStatus.CurrentSecurityLevel = level
atomicUpdateCurrentSecurityLevel(level)
}
// SetSelectedSecurityLevel sets the selected security level.
func SetSelectedSecurityLevel(level uint8) {
sysStatusLock.Lock()
defer sysStatusLock.Unlock()
sysStatus.SelectedSecurityLevel = level
atomicUpdateSelectedSecurityLevel(level)
}
// SetThreatLevel sets the current threat level.
func SetThreatLevel(level uint8) {
sysStatusLock.Lock()
defer sysStatusLock.Unlock()
sysStatus.ThreatLevel = level
atomicUpdateThreatLevel(level)
}
// SetPortmasterStatus sets the current Portmaster status.
func SetPortmasterStatus(status uint8) {
sysStatusLock.Lock()
defer sysStatusLock.Unlock()
sysStatus.PortmasterStatus = status
atomicUpdatePortmasterStatus(status)
}
// SetGate17Status sets the current Gate17 status.
func SetGate17Status(status uint8) {
sysStatusLock.Lock()
defer sysStatusLock.Unlock()
sysStatus.Gate17Status = status
atomicUpdateGate17Status(status)
}
// update functions for atomic stuff
func atomicUpdateCurrentSecurityLevel(level uint8) {
atomic.StoreUint32(currentSecurityLevel, uint32(level))
}
func atomicUpdateSelectedSecurityLevel(level uint8) {
atomic.StoreUint32(selectedSecurityLevel, uint32(level))
}
func atomicUpdateThreatLevel(level uint8) {
atomic.StoreUint32(threatLevel, uint32(level))
}
func atomicUpdatePortmasterStatus(status uint8) {
atomic.StoreUint32(portmasterStatus, uint32(status))
}
func atomicUpdateGate17Status(status uint8) {
atomic.StoreUint32(gate17Status, uint32(status))
}

14
status/set_test.go Normal file
View file

@ -0,0 +1,14 @@
package status
import "testing"
func TestSet(t *testing.T) {
// only test for panics
SetCurrentSecurityLevel(0)
SetSelectedSecurityLevel(0)
SetThreatLevel(0)
SetPortmasterStatus(0)
SetGate17Status(0)
}

49
status/status.go Normal file
View file

@ -0,0 +1,49 @@
package status
import "sync"
var (
sysStatusLock sync.RWMutex
sysStatus *SystemStatus
)
func init() {
sysStatus = &SystemStatus{}
}
// SystemStatus saves basic information about the current system status.
type SystemStatus struct {
// database.Base
CurrentSecurityLevel uint8
SelectedSecurityLevel uint8
ThreatLevel uint8 `json:",omitempty" bson:",omitempty"`
ThreatReason string `json:",omitempty" bson:",omitempty"`
PortmasterStatus uint8 `json:",omitempty" bson:",omitempty"`
PortmasterStatusMsg string `json:",omitempty" bson:",omitempty"`
Gate17Status uint8 `json:",omitempty" bson:",omitempty"`
Gate17StatusMsg string `json:",omitempty" bson:",omitempty"`
}
// FmtSecurityLevel returns the current security level as a string.
func FmtSecurityLevel() string {
current := GetCurrentSecurityLevel()
selected := GetSelectedSecurityLevel()
var s string
switch current {
case SecurityLevelOff:
s = "Off"
case SecurityLevelDynamic:
s = "Dynamic"
case SecurityLevelSecure:
s = "Secure"
case SecurityLevelFortress:
s = "Fortress"
}
if current != selected {
s += "*"
}
return s
}

36
status/status_test.go Normal file
View file

@ -0,0 +1,36 @@
package status
import "testing"
func TestStatus(t *testing.T) {
SetCurrentSecurityLevel(SecurityLevelOff)
SetSelectedSecurityLevel(SecurityLevelOff)
if FmtSecurityLevel() != "Off" {
t.Error("unexpected string representation")
}
SetCurrentSecurityLevel(SecurityLevelDynamic)
SetSelectedSecurityLevel(SecurityLevelDynamic)
if FmtSecurityLevel() != "Dynamic" {
t.Error("unexpected string representation")
}
SetCurrentSecurityLevel(SecurityLevelSecure)
SetSelectedSecurityLevel(SecurityLevelSecure)
if FmtSecurityLevel() != "Secure" {
t.Error("unexpected string representation")
}
SetCurrentSecurityLevel(SecurityLevelFortress)
SetSelectedSecurityLevel(SecurityLevelFortress)
if FmtSecurityLevel() != "Fortress" {
t.Error("unexpected string representation")
}
SetSelectedSecurityLevel(SecurityLevelDynamic)
if FmtSecurityLevel() != "Fortress*" {
t.Error("unexpected string representation")
}
}