fix: configuration pkg

This commit is contained in:
2019-02-17 18:23:59 +01:00
parent 60fa83244e
commit c437127531
18 changed files with 596 additions and 420 deletions

View File

@ -1,136 +1,68 @@
package config
import (
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"regexp"
"git.cryptic.systems/fh-trier/go-flucky/pkg/types"
"github.com/satori/go.uuid"
"git.cryptic.systems/fh-trier/go-flucky-server/pkg/types"
)
var configFilename = "config.json"
var humiditiesLogfileName = "humidities.log"
var temperatureLogfileName = "temperature.log"
var validUUID = regexp.MustCompile("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$")
func Create(configDir, logDir string, force bool) error {
type Config interface {
AddSensor(sensor *types.Sensor) error
AddRemote(remote *Remote) error
DisableRemote(nameOrUUID string) error
DisableSensor(nameOrUUID string) error
EnableRemote(nameOrUUID string) error
EnableSensor(nameOrUUID string) error
GetDevice() *Device
GetRemotes() []*Remote
GetSensors() []*types.Sensor
JSONDecoder(r io.Reader) error
JSONWriter(w io.Writer) error
RemoveSensor(nameOrUUID string) error
RemoveRemote(nameOrUUID string) error
SetDevice(device *Device)
ToJSON() (string, error)
}
configPath := filepath.Join(configDir, configFilename)
humiditiesLogfile := filepath.Join(logDir, humiditiesLogfileName)
temperaturLogfile := filepath.Join(logDir, temperatureLogfileName)
// Read the configuration file
func Read(configFile string) (*FluckyConfig, error) {
config := &types.Config{
DeviceID: uuid.NewV4().String(),
HumidityLogfile: humiditiesLogfile,
TemperatureLogfile: temperaturLogfile,
}
fc := &FluckyConfig{}
// If no config file exists, create a new one on the location
if !force {
if _, err := os.Stat(configPath); !os.IsNotExist(err) {
return fmt.Errorf("%v already exists. Use -f to overwrite", configPath)
}
}
if _, err := os.Stat(configPath); os.IsNotExist(err) {
err := os.MkdirAll(configDir, os.ModePerm)
if err != nil {
return fmt.Errorf("Can not create directory: %v", err)
}
}
f, err := os.Create(configPath)
f, err := os.Open(configFile)
if err != nil {
return fmt.Errorf("Can not create config: %v", err)
return nil, fmt.Errorf("Can not open file %v: %v", configFile, err)
}
defer f.Close()
config.JSONWriter(f)
err = fc.JSONDecoder(f)
if err != nil {
return nil, fmt.Errorf("Can not decode json file %v: %v", configFile, err)
}
return nil
return fc, nil
}
func DeviceName(deviceName, configDir string) error {
cnf, err := Read(configDir)
// Write the configuration into a file, specified by the configuration filepath
func Write(cfg Config, configFile string) error {
f, err := os.Create(configFile)
if err != nil {
return err
}
defer f.Close()
cnf.DeviceName = deviceName
err = Write(cnf, configDir)
if err != nil {
return err
}
return nil
}
func DeviceLocation(deviceLocation, configDir string) error {
cnf, err := Read(configDir)
if err != nil {
return err
}
cnf.DeviceLocation = deviceLocation
err = Write(cnf, configDir)
if err != nil {
return err
}
return nil
}
func Read(configDir string) (*types.Config, error) {
configPath := filepath.Join(configDir, configFilename)
var config types.Config
// If no config file exists, return an error
if _, err := os.Stat(configPath); os.IsNotExist(err) {
return nil, fmt.Errorf("Can not find config %v: %v", configPath, err)
}
// open config file
jsonFile, err := os.Open(configPath)
if err != nil {
return nil, fmt.Errorf("Can not open file %v: %v", configPath, err)
}
defer jsonFile.Close()
jsonParser := json.NewDecoder(jsonFile)
if err := jsonParser.Decode(&config); err != nil {
return nil, err
}
return &config, nil
}
func Write(config *types.Config, configDir string) error {
configPath := filepath.Join(configDir, configFilename)
// If no config file exists, return an error
if _, err := os.Stat(configPath); os.IsNotExist(err) {
return fmt.Errorf("Can not find config %v: %v", configPath, err)
}
// open config file
jsonFile, err := os.Create(configPath)
if err != nil {
return fmt.Errorf("Can not open file %v: %v", configPath, err)
}
defer jsonFile.Close()
err = config.JSONWriter(jsonFile)
err = cfg.JSONWriter(f)
if err != nil {
return err
}
return nil
}

7
pkg/config/device.go Normal file
View File

@ -0,0 +1,7 @@
package config
type Device struct {
DeviceID string `json:"device_id"`
DeviceName string `json:"device_name"`
DeviceLocation string `json:"device_location"`
}

312
pkg/config/fluckyconfig.go Normal file
View File

@ -0,0 +1,312 @@
package config
import (
"bytes"
"encoding/json"
"fmt"
"io"
"text/tabwriter"
"github.com/satori/go.uuid"
"git.cryptic.systems/fh-trier/go-flucky-server/pkg/types"
)
// FluckyConfig dasd
type FluckyConfig struct {
Device *Device `json:"device"`
Sensors []*types.Sensor `json:"sensors"`
Remotes []*Remote `json:"remotes"`
}
// AddSensor add a new sensor
func (fc *FluckyConfig) AddSensor(sensor *types.Sensor) error {
// check if sensorID is a valid UUID string
if !validUUID.MatchString(sensor.SensorID) {
sensor.SensorID = uuid.NewV4().String()
}
// check if sensor name and sensor uuid already exists
for _, s := range fc.Sensors {
if s.SensorName == sensor.SensorName {
return fmt.Errorf("Sensor %v already exists", s.SensorName)
}
if s.SensorID == sensor.SensorID {
return fmt.Errorf("Remote %v with UUID %v already exists", s.SensorName, s.SensorID)
}
}
fc.Sensors = append(fc.Sensors, sensor)
return nil
}
// AddRemote add a new remote address
func (fc *FluckyConfig) AddRemote(remote *Remote) error {
// check if remoteID is a valid UUID string
if !validUUID.MatchString(remote.RemoteID) {
remote.RemoteID = uuid.NewV4().String()
}
// check if remote name or remiteid already exists
for _, r := range fc.Remotes {
if r.Name == remote.Name {
return fmt.Errorf("Remote %v -> %v already exists", r.Name, r.Address)
}
if r.RemoteID == remote.RemoteID {
return fmt.Errorf("Remote %v with UUID %v already exists", r.Name, r.RemoteID)
}
}
fc.Remotes = append(fc.Remotes, remote)
return nil
}
// DisableRemote disables a remote address by its name or its unique UUID
func (fc *FluckyConfig) DisableRemote(nameOrUUID string) error {
found := false
for _, remote := range fc.Remotes {
// disable sensor matched after name
if !validUUID.MatchString(nameOrUUID) &&
remote.Name == nameOrUUID {
remote.Enabled = false
found = true
break
}
// remove machted uuid
if validUUID.MatchString(nameOrUUID) &&
remote.RemoteID == nameOrUUID {
remote.Enabled = false
found = true
break
}
}
if !found {
return fmt.Errorf("Can not found sensor %v", nameOrUUID)
}
return nil
}
// DisableSensor disables a sensor by its name or its unique UUID
func (fc *FluckyConfig) DisableSensor(nameOrUUID string) error {
found := false
for _, sensor := range fc.Sensors {
// disable sensor matched after name
if !validUUID.MatchString(nameOrUUID) &&
*sensor.SensorName == nameOrUUID {
*sensor.SensorEnabled = false
found = true
break
}
// remove machted uuid
if validUUID.MatchString(nameOrUUID) &&
sensor.SensorID == nameOrUUID {
*sensor.SensorEnabled = false
found = true
break
}
}
if !found {
return fmt.Errorf("Can not found sensor %v", nameOrUUID)
}
return nil
}
// EnableRemote enable a remote address by its name or its unique UUID
func (fc *FluckyConfig) EnableRemote(nameOrUUID string) error {
found := false
for _, remote := range fc.Remotes {
// disable sensor matched after name
if !validUUID.MatchString(nameOrUUID) &&
remote.Name == nameOrUUID {
remote.Enabled = true
found = true
break
}
// remove machted uuid
if validUUID.MatchString(nameOrUUID) &&
remote.RemoteID == nameOrUUID {
remote.Enabled = true
found = true
break
}
}
if !found {
return fmt.Errorf("Can not found sensor %v", nameOrUUID)
}
return nil
}
// EnableSensor enables a sensor by its name or its unique UUID
func (fc *FluckyConfig) EnableSensor(nameOrUUID string) error {
found := false
for _, sensor := range fc.Sensors {
// disable sensor matched after name
if !validUUID.MatchString(nameOrUUID) &&
*sensor.SensorName == nameOrUUID {
*sensor.SensorEnabled = true
found = true
break
}
// remove machted uuid
if validUUID.MatchString(nameOrUUID) &&
sensor.SensorID == nameOrUUID {
*sensor.SensorEnabled = true
found = true
break
}
}
if !found {
return fmt.Errorf("Can not found sensor %v", nameOrUUID)
}
return nil
}
// GetDevice returns device informations
func (fc *FluckyConfig) GetDevice() *Device {
return fc.Device
}
// GetRemotes returns an array if remote struct poniter
func (fc *FluckyConfig) GetRemotes() []*Remote {
return fc.Remotes
}
// GetSensors returns an array if remote struct poniter
func (fc *FluckyConfig) GetSensors() []*types.Sensor {
return fc.Sensors
}
// JSONDecoder decode a JSON string from a reader into a struct
func (fc *FluckyConfig) JSONDecoder(r io.Reader) error {
jsonDecoder := json.NewDecoder(r)
if err := jsonDecoder.Decode(&fc); err != nil {
return fmt.Errorf("Can not unmarshal JSON: %v", err)
}
return nil
}
// JSONWriter needs a writer to write the struct into JSON string
func (fc *FluckyConfig) JSONWriter(w io.Writer) error {
encoder := json.NewEncoder(w)
encoder.SetIndent("", " ")
err := encoder.Encode(&fc)
if err != nil {
return fmt.Errorf("Error in encoding struct to json: %v", err)
}
return nil
}
func (fc *FluckyConfig) PrintRemotes(w io.Writer) error {
tw := tabwriter.NewWriter(w, 0, 0, 3, ' ', 0)
fmt.Fprint(tw, "name\taddress\tenabled\tregistered\n")
for _, remote := range fc.Remotes {
fmt.Fprintf(tw, "%v\t%v\t%v\t%v\n", remote.Name, remote.Address, remote.Enabled, remote.Registered)
}
tw.Flush()
return nil
}
// RemoveSensor deletes a sensor by its name or its unique UUID
func (fc *FluckyConfig) RemoveSensor(nameOrUUID string) error {
found := false
for i, sensor := range fc.Sensors {
// remove machted name
if !validUUID.MatchString(nameOrUUID) &&
*sensor.SensorName == nameOrUUID {
fc.Sensors = append(fc.Sensors[:i], fc.Sensors[i+1:]...)
found = true
break
}
// remove machted uuid
if validUUID.MatchString(nameOrUUID) &&
sensor.SensorID == nameOrUUID {
fc.Sensors = append(fc.Sensors[:i], fc.Sensors[i+1:]...)
found = true
break
}
}
if !found {
return fmt.Errorf("Can not find remote %v", nameOrUUID)
}
return nil
}
// RemoveRemote deletes a remote address by its name or its unique UUID
func (fc *FluckyConfig) RemoveRemote(nameOrUUID string) error {
found := false
for i, remote := range fc.Remotes {
// remove machted name
if !validUUID.MatchString(nameOrUUID) &&
remote.Name == nameOrUUID {
fc.Remotes = append(fc.Remotes[:i], fc.Remotes[i+1:]...)
found = true
}
// remove machted uuid
if validUUID.MatchString(nameOrUUID) &&
remote.RemoteID == nameOrUUID {
fc.Remotes = append(fc.Remotes[:i], fc.Remotes[i+1:]...)
found = true
}
}
if !found {
return fmt.Errorf("Can not find remote %v", nameOrUUID)
}
return nil
}
// SetDevice informations, like device name or device location
func (fc *FluckyConfig) SetDevice(device *Device) {
fc.Device = device
}
// ToJSON returns the struct as JSON string
func (fc *FluckyConfig) ToJSON() (string, error) {
var b bytes.Buffer
err := fc.JSONWriter(&b)
if err != nil {
return "", err
}
return b.String(), nil
}

10
pkg/config/remote.go Normal file
View File

@ -0,0 +1,10 @@
package config
// Remote ...
type Remote struct {
RemoteID string `json:"remote_id"`
Name string `json:"remote_name"`
Address string `json:"remote_address"`
Registered bool `json:"remote_registered"`
Enabled bool `json:"remote_enabled"`
}