starting to reconfig config

main
KeeganForelight 2 years ago
parent c4fecc7eeb
commit ebd87863bc

@ -5,8 +5,6 @@ import (
_ "net/http" _ "net/http"
_ "net/http/pprof" _ "net/http/pprof"
"os/signal" "os/signal"
"strconv"
"strings"
"syscall" "syscall"
//"flag" //"flag"
@ -21,61 +19,34 @@ type coordinator interface {
Start() Start()
} }
// NewCoordinator creates a new coordinator that runs on the central server type Config interface {
// The coordinator is given an error channel to feed errors back to the main process should any arise //UpdatePort(string, int) error
// The zero value for a new coordinator is ready to start Store() error
}
func NewCoordinator(ch chan error) coordinator { func NewCoordinator(ch chan error) coordinator {
return server.NewCentralCoordinator(ch) return server.NewCentralCoordinator(ch)
} }
// LoadConfig loads a given config based on a string lookup func NewConfig(fname string) Config {
// Used to load the associated settings for a coordinator such as port and IP address as well as database settings return config.NewConfig(fname)
// LoadConfig expects the returned config to satisfy the interface }
/*
func LoadConfig(fname string) Config { func LoadConfig(fname string) Config {
if err := config.Load(fname); err != nil { if err := config.Load(fname); err != nil {
panic(err) panic(err)
} }
return config.LoadConfig() return config.LoadConfig()
} } */
// Basic functions expected to be provided by the config structure
type Config interface {
UpdatePort(string, int) error
Store() error
}
func main() { func main() {
// lets get this bread // lets get this bread
// go func() {
// fmt.Println(http.ListenAndServe("localhost:6060",nil))
// }()
gracefulShutdown := make(chan os.Signal, 1) gracefulShutdown := make(chan os.Signal, 1)
signal.Notify(gracefulShutdown, syscall.SIGINT, syscall.SIGTERM) signal.Notify(gracefulShutdown, syscall.SIGINT, syscall.SIGTERM)
conf := LoadConfig("server") conf := NewConfig("server")
errCh := make(chan error) errCh := make(chan error)
// checking env
envVars := os.Environ()
// I can put this is a seperate func
for _, envString := range envVars {
// looping over set ports
initSplt := strings.Split(envString, "=")
key := initSplt[0]
val := initSplt[1]
if strings.Contains(key, "PORT") {
// parsing out correct port to update
splt := strings.Split(key, "_") // LIS_PORT -> LIS, PORT
portName := strings.ToLower(splt[0]) // LIS -> lis
port, err := strconv.Atoi(val)
if err != nil {
panic(err)
}
if err := conf.UpdatePort(portName, port); err != nil {
panic(err)
}
}
}
//fmt.Printf("Listening on %v\n", lport) //fmt.Printf("Listening on %v\n", lport)
c := NewCoordinator(errCh) c := NewCoordinator(errCh)
@ -85,6 +56,7 @@ func main() {
case err := <-errCh: // blocking to wait for any errors and keep alive otherwise case err := <-errCh: // blocking to wait for any errors and keep alive otherwise
panic(err) panic(err)
case <-gracefulShutdown: case <-gracefulShutdown:
// Shutdown via INT
err := conf.Store() err := conf.Store()
if err != nil { if err != nil {
panic(err) panic(err)

@ -1,17 +1,16 @@
server: db:
name: "Rack Server" org: ForeLight
db-url: "http://192.168.100.2:8086" token: ""
db-org: "ForeLight" url: http://192.168.100.2:8086
db-token: "" name: Rack Server
ports: ports:
lis: 2022 db: 8086
lis: 20000
reactor: 2023 reactor: 2023
tui: 2024 tui: 2024
db: 8086
reactors: reactors:
10002123: "10002123":
name: "Beaglebone Black" db:
db-token: "" bucket: test
db-bucket: "" token: ""
name: Beaglebone Black

@ -8,166 +8,57 @@ import (
"FRMS/internal/pkg/logging" "FRMS/internal/pkg/logging"
"errors" "errors"
"fmt" "fmt"
"strconv"
"strings"
"github.com/spf13/viper" "github.com/spf13/viper"
//"os"
//"log"
//"os/exec"
//"bytes"
) )
func NewConfig(name string) (Config, error) { type Config interface {
// returns a Config Structure of assocaited name //rip
return C, Load(name) Store() error
} }
type ConfigStruct interface { func NewConfig(name string) Config {
// structure to do demarshall config into // returns a Config Structure of assocaited name
LoadFile(string) error return LoadConfig(name)
} }
func LoadConfigFile(fname string, strct ConfigStruct) error { func LoadConfig(fname string) Config {
// Demarshalls a given filename into the struct // Demarshalls a given filename into the struct
// returns nil if successful // returns nil if successful
var C Config
logging.Debug(logging.DStart, "Loading config for %s", fname) logging.Debug(logging.DStart, "Loading config for %s", fname)
viper.SetConfigName(fname) viper.SetConfigName(fname)
viper.SetConfigType("yaml") viper.SetConfigType("yaml")
viper.AddConfigPath("/etc/frms/config") //viper.AddConfigPath("/etc/frms/config")
viper.AddConfigPath("$HOME/FRMS/internal/configs")
// struct and env vars
switch fname {
case "server":
C = &ServerConfig{}
case "reactor":
panic(errors.New("f"))
//C = &ReactorConf{}
default:
panic(errors.New(fmt.Sprintf("%s not recognized", fname)))
}
// Sets env vars
viper.AutomaticEnv()
// unmarshalling // unmarshalling
if err := viper.ReadInConfig(); err != nil { if err := viper.ReadInConfig(); err != nil {
return err panic(err)
} }
logging.Debug(logging.DStart, "CON Loaded configs from %v", viper.ConfigFileUsed()) logging.Debug(logging.DStart, "CON Loaded configs from %v", viper.ConfigFileUsed())
if err = viper.Unmarshal(strct); err != nil {
if err := viper.Unmarshal(C); err != nil {
logging.Debug(logging.DError, "Cannot unmarshall %v", err) logging.Debug(logging.DError, "Cannot unmarshall %v", err)
return err panic(err)
} }
fmt.Printf("Outcome: %#v\n \n", C) fmt.Printf("Outcome: %#v\n \n", C)
// unmarshalled at this point // unmarshalled at this point
}
////
func LoadConfig() Config {
return C return C
}
func (c *ServerConf) GetURL() (string, error) {
c.RLock()
defer c.RUnlock()
return C.Server.URL, nil
}
func (c *ServerConf) GetOrg() (string, error) {
c.RLock()
defer c.RUnlock()
return c.Server.Orginization, nil
}
func (c *ServerConf) GetPort(port string) (int, error) {
c.RLock()
defer c.RUnlock()
portString, ok := c.Server.Ports[port]
if !ok {
portEnv := strings.ToUpper(port) + "_PORT"
return 0, fmt.Errorf("%s port doesnt exist! Please set using env %s=####", port, portEnv)
}
// returns int, err
//return strconv.Atoi(portString)
return portString, nil
}
func (c *ServerConf) GetServerToken() (string, error) {
c.RLock()
defer c.RUnlock()
return c.Server.Token, nil
}
func (c *ServerConf) GetReactorClient(id uint32) (string, string, error) {
c.RLock()
defer c.RUnlock()
idString := strconv.FormatUint(uint64(id), 10)
if r, ok := c.Reactors[idString]; ok {
return r.Bucket, r.Token, nil
}
return "", "", fmt.Errorf("reactor %v config doesnt exist", id)
}
// setters
func (c *ServerConf) UpdateURL(url string) error {
c.Lock()
defer c.Unlock()
if url == "" {
return errors.New("string cannot be empty")
}
c.Server.URL = url
viper.Set("server.db-url", url)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdateOrg(org string) error {
c.Lock()
defer c.Unlock()
if org == "" {
return errors.New("string cannot be empty")
}
c.Server.Orginization = org
viper.Set("server.db-org", org)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdatePort(pName string, port int) error {
c.Lock()
defer c.Unlock()
if port < 1024 || port > 65535 {
// OOB
return fmt.Errorf("Port %d out of bounds! [1024,65535]", port)
}
if c.Server.Ports == nil {
c.Server.Ports = make(map[string]int)
}
c.Server.Ports[pName] = port
pname := fmt.Sprintf("server.ports.%s", pName)
viper.Set(pname, port)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdateServerToken(token string) error {
c.Lock()
defer c.Unlock()
if token == "" {
return errors.New("String cannot be empty!")
}
c.Server.Token = token
viper.Set("server.token", token)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdateReactorClient(id uint32, bucket, token string) error {
c.Lock()
c.Unlock()
sid := strconv.FormatUint(uint64(id), 10)
if token == "" || bucket == "" {
return errors.New("String cannot be empty!")
}
if reactor, ok := c.Reactors[sid]; !ok {
c.Reactors[sid] = ReactorConfig{Token: token, Bucket: bucket, Id: id}
} else {
reactor.Bucket = bucket
reactor.Token = token
c.Reactors[sid] = reactor
}
reactorbucket := fmt.Sprintf("%s.db-bucket", id)
reactortoken := fmt.Sprintf("%s.db-token", id)
viper.Set(reactorbucket, bucket)
viper.Set(reactortoken, token)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) Store() error {
return viper.WriteConfigAs(viper.ConfigFileUsed())
} }

@ -0,0 +1,5 @@
package config
/*
Package provides a way to update current config based on values passed in flags
*/

@ -0,0 +1,173 @@
package config
/*
Load.go contains methods to load values from config, flags and env.
*/
import (
"FRMS/internal/pkg/logging"
"errors"
"fmt"
"strconv"
"strings"
"github.com/spf13/viper"
//"os"
//"log"
//"os/exec"
//"bytes"
)
func NewConfig(name string) (Config, error) {
// returns a Config Structure of assocaited name
return C, Load(name)
}
type ConfigStruct interface {
// structure to do demarshall config into
LoadFile(string) error
}
func LoadConfigFile(fname string, strct ConfigStruct) error {
// Demarshalls a given filename into the struct
// returns nil if successful
logging.Debug(logging.DStart, "Loading config for %s", fname)
viper.SetConfigName(fname)
viper.SetConfigType("yaml")
viper.AddConfigPath("/etc/frms/config")
// unmarshalling
if err := viper.ReadInConfig(); err != nil {
return err
}
logging.Debug(logging.DStart, "CON Loaded configs from %v", viper.ConfigFileUsed())
if err = viper.Unmarshal(strct); err != nil {
logging.Debug(logging.DError, "Cannot unmarshall %v", err)
return err
}
fmt.Printf("Outcome: %#v\n \n", C)
// unmarshalled at this point
}
////
func LoadConfig() Config {
return C
}
func (c *ServerConf) GetURL() (string, error) {
c.RLock()
defer c.RUnlock()
return C.Server.URL, nil
}
func (c *ServerConf) GetOrg() (string, error) {
c.RLock()
defer c.RUnlock()
return c.Server.Orginization, nil
}
func (c *ServerConf) GetPort(port string) (int, error) {
c.RLock()
defer c.RUnlock()
portString, ok := c.Server.Ports[port]
if !ok {
portEnv := strings.ToUpper(port) + "_PORT"
return 0, fmt.Errorf("%s port doesnt exist! Please set using env %s=####", port, portEnv)
}
// returns int, err
//return strconv.Atoi(portString)
return portString, nil
}
func (c *ServerConf) GetServerToken() (string, error) {
c.RLock()
defer c.RUnlock()
return c.Server.Token, nil
}
func (c *ServerConf) GetReactorClient(id uint32) (string, string, error) {
c.RLock()
defer c.RUnlock()
idString := strconv.FormatUint(uint64(id), 10)
if r, ok := c.Reactors[idString]; ok {
return r.Bucket, r.Token, nil
}
return "", "", fmt.Errorf("reactor %v config doesnt exist", id)
}
// setters
func (c *ServerConf) UpdateURL(url string) error {
c.Lock()
defer c.Unlock()
if url == "" {
return errors.New("string cannot be empty")
}
c.Server.URL = url
viper.Set("server.db-url", url)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdateOrg(org string) error {
c.Lock()
defer c.Unlock()
if org == "" {
return errors.New("string cannot be empty")
}
c.Server.Orginization = org
viper.Set("server.db-org", org)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdatePort(pName string, port int) error {
c.Lock()
defer c.Unlock()
if port < 1024 || port > 65535 {
// OOB
return fmt.Errorf("Port %d out of bounds! [1024,65535]", port)
}
if c.Server.Ports == nil {
c.Server.Ports = make(map[string]int)
}
c.Server.Ports[pName] = port
pname := fmt.Sprintf("server.ports.%s", pName)
viper.Set(pname, port)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdateServerToken(token string) error {
c.Lock()
defer c.Unlock()
if token == "" {
return errors.New("String cannot be empty!")
}
c.Server.Token = token
viper.Set("server.token", token)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdateReactorClient(id uint32, bucket, token string) error {
c.Lock()
c.Unlock()
sid := strconv.FormatUint(uint64(id), 10)
if token == "" || bucket == "" {
return errors.New("String cannot be empty!")
}
if reactor, ok := c.Reactors[sid]; !ok {
c.Reactors[sid] = ReactorConfig{Token: token, Bucket: bucket, Id: id}
} else {
reactor.Bucket = bucket
reactor.Token = token
c.Reactors[sid] = reactor
}
reactorbucket := fmt.Sprintf("%s.db-bucket", id)
reactortoken := fmt.Sprintf("%s.db-token", id)
viper.Set(reactorbucket, bucket)
viper.Set(reactortoken, token)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) Store() error {
return viper.WriteConfigAs(viper.ConfigFileUsed())
}

@ -0,0 +1,180 @@
package config
// package serves to implement config interface for server
import (
"FRMS/internal/pkg/logging"
"errors"
"fmt"
"strconv"
"strings"
"github.com/spf13/viper"
//"os"
//"log"
//"os/exec"
//"bytes"
)
type Config interface {
Store() error
}
var C Config
func Load(fname string) error {
// read stored configs
//C = &ServerConf{}
switch fname {
case "server":
C = &ServerConf{}
case "reactor":
C = &ReactorConf{}
default:
return fmt.Errorf("%s not recognized", fname)
}
logging.Debug(logging.DStart, "Loading config for %s", fname)
viper.SetConfigName(fname)
viper.SetConfigType("yaml")
viper.AddConfigPath("/etc/frms/config")
// defaults which we don't want to set nessecarily
//viper.SetDefault("server.db-org", "ForeLight")
//viper.SetDefault("server.db-url", "http://192.168.100.2:8086")
//viper.SetDefault("reactor.db-url", "http://192.168.100.2:8086")
// unmarshalling
err := viper.ReadInConfig() // the fact i never did this is infuriating
if err != nil {
panic(err)
}
logging.Debug(logging.DStart, "CON Loaded configs from %v", viper.ConfigFileUsed())
err = viper.Unmarshal(C)
if err != nil {
logging.Debug(logging.DError, "Cannot unmarshall Server! %v", err)
panic(err)
}
fmt.Printf("Outcome: %#v\n \n", C)
//fmt.Printf("%v\n",C)
// unmarshalled at this point
}
func LoadConfig() Config {
return C
}
func (c *ServerConf) Load()
func (c *ServerConf) GetURL() (string, error) {
c.RLock()
defer c.RUnlock()
return C.Server.URL, nil
}
func (c *ServerConf) GetOrg() (string, error) {
c.RLock()
defer c.RUnlock()
return c.Server.Orginization, nil
}
func (c *ServerConf) GetPort(port string) (int, error) {
c.RLock()
defer c.RUnlock()
portString, ok := c.Server.Ports[port]
if !ok {
portEnv := strings.ToUpper(port) + "_PORT"
return 0, fmt.Errorf("%s port doesnt exist! Please set using env %s=####", port, portEnv)
}
// returns int, err
//return strconv.Atoi(portString)
return portString, nil
}
func (c *ServerConf) GetServerToken() (string, error) {
c.RLock()
defer c.RUnlock()
return c.Server.Token, nil
}
func (c *ServerConf) GetReactorClient(id uint32) (string, string, error) {
c.RLock()
defer c.RUnlock()
idString := strconv.FormatUint(uint64(id), 10)
if r, ok := c.Reactors[idString]; ok {
return r.Bucket, r.Token, nil
}
return "", "", fmt.Errorf("reactor %v config doesnt exist", id)
}
// setters
func (c *ServerConf) UpdateURL(url string) error {
c.Lock()
defer c.Unlock()
if url == "" {
return errors.New("string cannot be empty")
}
c.Server.URL = url
viper.Set("server.db-url", url)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdateOrg(org string) error {
c.Lock()
defer c.Unlock()
if org == "" {
return errors.New("string cannot be empty")
}
c.Server.Orginization = org
viper.Set("server.db-org", org)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdatePort(pName string, port int) error {
c.Lock()
defer c.Unlock()
if port < 1024 || port > 65535 {
// OOB
return fmt.Errorf("Port %d out of bounds! [1024,65535]", port)
}
if c.Server.Ports == nil {
c.Server.Ports = make(map[string]int)
}
c.Server.Ports[pName] = port
pname := fmt.Sprintf("server.ports.%s", pName)
viper.Set(pname, port)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdateServerToken(token string) error {
c.Lock()
defer c.Unlock()
if token == "" {
return errors.New("String cannot be empty!")
}
c.Server.Token = token
viper.Set("server.token", token)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) UpdateReactorClient(id uint32, bucket, token string) error {
c.Lock()
c.Unlock()
sid := strconv.FormatUint(uint64(id), 10)
if token == "" || bucket == "" {
return errors.New("String cannot be empty!")
}
if reactor, ok := c.Reactors[sid]; !ok {
c.Reactors[sid] = ReactorConfig{Token: token, Bucket: bucket, Id: id}
} else {
reactor.Bucket = bucket
reactor.Token = token
c.Reactors[sid] = reactor
}
reactorbucket := fmt.Sprintf("%s.db-bucket", id)
reactortoken := fmt.Sprintf("%s.db-token", id)
viper.Set(reactorbucket, bucket)
viper.Set(reactortoken, token)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *ServerConf) Store() error {
return viper.WriteConfigAs(viper.ConfigFileUsed())
}

@ -3,82 +3,52 @@ package config
// package serves to implement config interface for server // package serves to implement config interface for server
import ( import (
"FRMS/internal/pkg/logging"
"errors" "errors"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
"sync"
"github.com/spf13/viper" "github.com/spf13/viper"
//"os"
//"log"
//"os/exec"
//"bytes"
) )
type Config interface { type ServerConfig struct {
Store() error DB DatabaseInfo `mapstructure:"db"`
Ports map[string]int `mapstructure:"ports"`
Name string `mapstructure:"name"`
Reactors map[string]ServerReactorConfig `mapstructure:"reactors"`
sync.RWMutex
} }
var C Config type DatabaseInfo struct {
URL string `mapstructure:"url"`
func Load(fname string) error { Token string `mapstructure:"token"`
// read stored configs Org string `mapstructure:"org,omitempty"`
//C = &ServerConf{} Bucket string `mapstructure:"url,omitempty"`
switch fname {
case "server":
C = &ServerConf{}
case "reactor":
C = &ReactorConf{}
default:
return fmt.Errorf("%s not recognized", fname)
}
logging.Debug(logging.DStart, "Loading config for %s", fname)
viper.SetConfigName(fname)
viper.SetConfigType("yaml")
viper.AddConfigPath("/etc/frms/config")
// defaults which we don't want to set nessecarily
//viper.SetDefault("server.db-org", "ForeLight")
//viper.SetDefault("server.db-url", "http://192.168.100.2:8086")
//viper.SetDefault("reactor.db-url", "http://192.168.100.2:8086")
// unmarshalling
err := viper.ReadInConfig() // the fact i never did this is infuriating
if err != nil {
panic(err)
}
logging.Debug(logging.DStart, "CON Loaded configs from %v", viper.ConfigFileUsed())
err = viper.Unmarshal(C)
if err != nil {
logging.Debug(logging.DError, "Cannot unmarshall Server! %v", err)
panic(err)
}
fmt.Printf("Outcome: %#v\n \n", C)
//fmt.Printf("%v\n",C)
// unmarshalled at this point
} }
func LoadConfig() Config { type ServerReactorConfig struct {
return C DB DatabaseInfo `mapstructure:"db"`
Name string `mapstructure:"name"`
Id string
} }
func (c *ServerConf) Load() func (c *ServerConfig) GetURL() (string, error) {
func (c *ServerConf) GetURL() (string, error) {
c.RLock() c.RLock()
defer c.RUnlock() defer c.RUnlock()
return C.Server.URL, nil return c.DB.URL, nil
} }
func (c *ServerConf) GetOrg() (string, error) { func (c *ServerConfig) GetOrg() (string, error) {
c.RLock() c.RLock()
defer c.RUnlock() defer c.RUnlock()
return c.Server.Orginization, nil return c.DB.Org, nil
} }
func (c *ServerConf) GetPort(port string) (int, error) { func (c *ServerConfig) GetPort(port string) (int, error) {
c.RLock() c.RLock()
defer c.RUnlock() defer c.RUnlock()
portString, ok := c.Server.Ports[port] portString, ok := c.Ports[port]
if !ok { if !ok {
portEnv := strings.ToUpper(port) + "_PORT" portEnv := strings.ToUpper(port) + "_PORT"
return 0, fmt.Errorf("%s port doesnt exist! Please set using env %s=####", port, portEnv) return 0, fmt.Errorf("%s port doesnt exist! Please set using env %s=####", port, portEnv)
@ -88,93 +58,96 @@ func (c *ServerConf) GetPort(port string) (int, error) {
return portString, nil return portString, nil
} }
func (c *ServerConf) GetServerToken() (string, error) { func (c *ServerConfig) GetServerToken() (string, error) {
c.RLock() c.RLock()
defer c.RUnlock() defer c.RUnlock()
return c.Server.Token, nil return c.DB.Token, nil
} }
func (c *ServerConf) GetReactorClient(id uint32) (string, string, error) { func (c *ServerConfig) GetReactorClient(id uint32) (string, string, error) {
c.RLock() c.RLock()
defer c.RUnlock() defer c.RUnlock()
idString := strconv.FormatUint(uint64(id), 10) idString := strconv.FormatUint(uint64(id), 10)
if r, ok := c.Reactors[idString]; ok { if r, ok := c.Reactors[idString]; ok {
return r.Bucket, r.Token, nil return r.DB.Bucket, r.DB.Token, nil
} }
return "", "", fmt.Errorf("reactor %v config doesnt exist", id) return "", "", fmt.Errorf("reactor %v config doesnt exist", id)
} }
// setters // setters
func (c *ServerConf) UpdateURL(url string) error { func (c *ServerConfig) UpdateURL(url string) error {
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
if url == "" { if url == "" {
return errors.New("string cannot be empty") return errors.New("string cannot be empty")
} }
c.Server.URL = url c.DB.URL = url
viper.Set("server.db-url", url) viper.Set("db.url", url)
return viper.WriteConfigAs(viper.ConfigFileUsed()) return viper.WriteConfigAs(viper.ConfigFileUsed())
} }
func (c *ServerConf) UpdateOrg(org string) error { func (c *ServerConfig) UpdateOrg(org string) error {
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
if org == "" { if org == "" {
return errors.New("string cannot be empty") return errors.New("string cannot be empty")
} }
c.Server.Orginization = org c.DB.Org = org
viper.Set("server.db-org", org) viper.Set("db.org", org)
return viper.WriteConfigAs(viper.ConfigFileUsed()) return viper.WriteConfigAs(viper.ConfigFileUsed())
} }
func (c *ServerConf) UpdatePort(pName string, port int) error { func (c *ServerConfig) UpdatePort(pName string, port int) error {
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
if port < 1024 || port > 65535 { if port < 1024 || port > 65535 {
// OOB // OOB
return fmt.Errorf("Port %d out of bounds! [1024,65535]", port) return fmt.Errorf("Port %d out of bounds! [1024,65535]", port)
} }
if c.Server.Ports == nil { if c.Ports == nil {
c.Server.Ports = make(map[string]int) c.Ports = make(map[string]int)
} }
c.Server.Ports[pName] = port c.Ports[pName] = port
pname := fmt.Sprintf("server.ports.%s", pName) pname := fmt.Sprintf("ports.%s", pName)
viper.Set(pname, port) viper.Set(pname, port)
return viper.WriteConfigAs(viper.ConfigFileUsed()) return viper.WriteConfigAs(viper.ConfigFileUsed())
} }
func (c *ServerConf) UpdateServerToken(token string) error { func (c *ServerConfig) UpdateServerToken(token string) error {
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
if token == "" { if token == "" {
return errors.New("String cannot be empty!") return errors.New("String cannot be empty!")
} }
c.Server.Token = token c.DB.Token = token
viper.Set("server.token", token) viper.Set("db.token", token)
return viper.WriteConfigAs(viper.ConfigFileUsed()) return viper.WriteConfigAs(viper.ConfigFileUsed())
} }
func (c *ServerConf) UpdateReactorClient(id uint32, bucket, token string) error { func (c *ServerConfig) UpdateReactorClient(id uint32, bucket, token string) error {
c.Lock() c.Lock()
c.Unlock() c.Unlock()
/*
sid := strconv.FormatUint(uint64(id), 10) sid := strconv.FormatUint(uint64(id), 10)
if token == "" || bucket == "" { if token == "" || bucket == "" {
return errors.New("String cannot be empty!") return errors.New("String cannot be empty!")
} }
if reactor, ok := c.Reactors[sid]; !ok { if reactor, ok := c.Reactors[sid]; !ok {
c.Reactors[sid] = ReactorConfig{Token: token, Bucket: bucket, Id: id} c.Reactors[sid] = ServerReactorConfig{Token: token, Bucket: bucket, Id: id}
} else { } else {
reactor.Bucket = bucket reactor.Bucket = bucket
reactor.Token = token reactor.Token = token
c.Reactors[sid] = reactor c.Reactors[sid] = reactor
} }
reactorbucket := fmt.Sprintf("%s.db-bucket", id) //reactorbucket := fmt.Sprintf("reactors.%s.db-bucket", id)
reactortoken := fmt.Sprintf("%s.db-token", id) //reactortoken := fmt.Sprintf("reactors.%s.db-token", id)
viper.Set(reactorbucket, bucket) viper.Set(fmt.Sprintf("reactors.%s.db-bucket", id), bucket)
viper.Set(reactortoken, token) viper.Set(fmt.Sprintf("reactors.%s.db-token", id), token)
return viper.WriteConfigAs(viper.ConfigFileUsed()) return viper.WriteConfigAs(viper.ConfigFileUsed())
*/
return errors.New("Unimpl")
} }
func (c *ServerConf) Store() error { func (c *ServerConfig) Store() error {
return viper.WriteConfigAs(viper.ConfigFileUsed()) return viper.WriteConfigAs(viper.ConfigFileUsed())
} }

@ -1,7 +1,9 @@
package influxdb package influxdb
import ( import (
"errors"
_ "fmt" _ "fmt"
_ "github.com/influxdata/influxdb-client-go/v2" _ "github.com/influxdata/influxdb-client-go/v2"
) )
@ -19,7 +21,7 @@ type DBAdmin struct {
} }
func NewDBClient(url, org, token string) *DBClient { func NewDBClient(url, org, token string) *DBClient {
db := &DBClient{URL:url, Org:org, Token:token} db := &DBClient{URL: url, Org: org, Token: token}
return db return db
} }
@ -36,11 +38,16 @@ func (d *DBClient) Start() {
func (d *DBAdmin) GetReactorClient(id string) (string, string, error) { func (d *DBAdmin) GetReactorClient(id string) (string, string, error) {
// given an id returns associated token and bucket // given an id returns associated token and bucket
client := influxdb2.NewClient(d.URL,d.Token) /*
client := influxdb2.NewClient(d.URL, d.Token)
defer client.Close() defer client.Close()
bucket, err := client.BucketsAPI().FindBucketByName(context.Background(),id) bucket, err := client.BucketsAPI().FindBucketByName(context.Background(), id)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
if d.ReactorExists(id) { if d.ReactorExists(id) {
// get corresponding reactor token and bucket // get corresponding reactor token and bucket
}
*/
return "", "", errors.New("Unimpl")
}

@ -1,28 +1,25 @@
package server package server
import ( import (
"FRMS/internal/pkg/config"
pb "FRMS/internal/pkg/grpc" pb "FRMS/internal/pkg/grpc"
"FRMS/internal/pkg/influxdb" "FRMS/internal/pkg/influxdb"
_ "FRMS/internal/pkg/influxdb" _ "FRMS/internal/pkg/influxdb"
"FRMS/internal/pkg/logging" "FRMS/internal/pkg/logging"
"context" "context"
"errors" "errors"
"fmt"
"net"
"sync" "sync"
"google.golang.org/grpc"
) )
// this package creates the central coordiantor and sub coordiantors for clients // this package creates the central coordiantor and sub coordiantors for clients
// interfaces // interfaces
// config interface // config interface
/*
func LoadConfig() Config { func LoadConfig() Config {
// returns a ServerConfig that we can query and update // returns a ServerConfig that we can query and update
return config.LoadConfig() //return config.LoadConfig()
} }
*/
type Config interface { // PROPOSED RENAMING: ServerConfig to avoid confusion w/ reactor variant type Config interface { // PROPOSED RENAMING: ServerConfig to avoid confusion w/ reactor variant
@ -46,8 +43,8 @@ type DB interface {
//GetToken() (string, error) // returns admin token (Creates if it doesnt exist) //GetToken() (string, error) // returns admin token (Creates if it doesnt exist)
GetReactorClient(string) (string, string, error) // returns (bucket, token, err) GetReactorClient(string) (string, string, error) // returns (bucket, token, err)
// delete // delete
DeleteReactorClient(string) error // removes client token but maintains bucket // DeleteReactorClient(string) error // removes client token but maintains bucket
PurgeReactorClientData(string) error // perm deletes all assocaited reactor data (token, bucket etc) // PurgeReactorClientData(string) error // perm deletes all assocaited reactor data (token, bucket etc)
} }
func NewDBAdmin(url, org, token string) DB { func NewDBAdmin(url, org, token string) DB {
@ -82,7 +79,7 @@ func NewCentralCoordinator(ch chan error) *CentralCoordinator {
func (c *CentralCoordinator) Start() { func (c *CentralCoordinator) Start() {
// starts up associated funcs // starts up associated funcs
// begin with config and client // begin with config and client
c.LoadCfg() //c.LoadCfg()
clientChan := make(chan *ClientPacket) clientChan := make(chan *ClientPacket)
l := NewListener(clientChan, c.Err) l := NewListener(clientChan, c.Err)
go l.Start() go l.Start()
@ -90,6 +87,7 @@ func (c *CentralCoordinator) Start() {
} }
/*
func (c *CentralCoordinator) LoadCfg() { func (c *CentralCoordinator) LoadCfg() {
// loads db client info and updates if anything is missing // loads db client info and updates if anything is missing
c.Config = LoadConfig() c.Config = LoadConfig()
@ -109,6 +107,7 @@ func (c *CentralCoordinator) LoadCfg() {
c.Err <- err c.Err <- err
} }
} }
*/
func (c *CentralCoordinator) ClientListener(ch chan *ClientPacket) { func (c *CentralCoordinator) ClientListener(ch chan *ClientPacket) {
for client := range ch { for client := range ch {
@ -259,7 +258,8 @@ func (r *reactorCoordinator) NewManager(cl *Client, sys *SystemViewer, err chan
} }
func (r *reactorCoordinator) Register() { func (r *reactorCoordinator) Register() {
conf := LoadConfig() //conf := LoadConfig()
/*
port, err := conf.GetPort("reactor") port, err := conf.GetPort("reactor")
if err != nil { if err != nil {
panic(err) panic(err)
@ -272,6 +272,7 @@ func (r *reactorCoordinator) Register() {
pb.RegisterMonitoringServer(grpcServer, r) pb.RegisterMonitoringServer(grpcServer, r)
go grpcServer.Serve(lis) go grpcServer.Serve(lis)
logging.Debug(logging.DClient, "RCO ready for client requests") logging.Debug(logging.DClient, "RCO ready for client requests")
*/
} }
func (r *reactorCoordinator) ReactorStatusHandler(ctx context.Context, req *pb.ReactorStatusPing) (*pb.ReactorStatusResponse, error) { func (r *reactorCoordinator) ReactorStatusHandler(ctx context.Context, req *pb.ReactorStatusPing) (*pb.ReactorStatusResponse, error) {
@ -286,7 +287,7 @@ func (r *reactorCoordinator) ReactorStatusHandler(ctx context.Context, req *pb.R
return rm.ReactorStatusHandler(ctx, req) return rm.ReactorStatusHandler(ctx, req)
} }
//tui coordinator // tui coordinator
type tuiCoordinator struct { type tuiCoordinator struct {
*Managers // by embedding general struct we allow coordinator to still call general funcs *Managers // by embedding general struct we allow coordinator to still call general funcs
pb.UnimplementedManagementServer pb.UnimplementedManagementServer
@ -302,6 +303,7 @@ func (t *tuiCoordinator) NewManager(cl *Client, sys *SystemViewer, err chan erro
} }
func (t *tuiCoordinator) Register() { func (t *tuiCoordinator) Register() {
/*
conf := LoadConfig() conf := LoadConfig()
port, err := conf.GetPort("tui") port, err := conf.GetPort("tui")
if err != nil { if err != nil {
@ -315,6 +317,7 @@ func (t *tuiCoordinator) Register() {
pb.RegisterManagementServer(grpcServer, t) pb.RegisterManagementServer(grpcServer, t)
go grpcServer.Serve(lis) go grpcServer.Serve(lis)
logging.Debug(logging.DClient, "TCO ready for client requests") logging.Debug(logging.DClient, "TCO ready for client requests")
*/
} }
func (t *tuiCoordinator) GetDevices(ctx context.Context, req *pb.GetDevicesRequest) (*pb.GetDevicesResponse, error) { func (t *tuiCoordinator) GetDevices(ctx context.Context, req *pb.GetDevicesRequest) (*pb.GetDevicesResponse, error) {

@ -2,13 +2,10 @@ package server
import ( import (
//"log" //"log"
"fmt"
"net"
"context" "context"
// "FRMS/internal/pkg/system" // "FRMS/internal/pkg/system"
"FRMS/internal/pkg/logging"
"google.golang.org/grpc"
pb "FRMS/internal/pkg/grpc" pb "FRMS/internal/pkg/grpc"
"FRMS/internal/pkg/logging"
) )
/* /*
@ -44,7 +41,7 @@ type ClientResponse struct {
} }
func NewListener(cch chan *ClientPacket, ech chan error) *Listener { func NewListener(cch chan *ClientPacket, ech chan error) *Listener {
l := &Listener{Err:ech,ClientConnections:cch} l := &Listener{Err: ech, ClientConnections: cch}
return l return l
} }
@ -53,11 +50,12 @@ func (l *Listener) Start() {
if err := l.Register(); err != nil { if err := l.Register(); err != nil {
l.Err <- err l.Err <- err
} }
logging.Debug(logging.DStart,"LIS 01 Started client listener") logging.Debug(logging.DStart, "LIS 01 Started client listener")
} }
func (l *Listener) Register() error { func (l *Listener) Register() error {
// creates a gRPC service and binds it to our handler // creates a gRPC service and binds it to our handler
/*
conf := LoadConfig() conf := LoadConfig()
port, err := conf.GetPort("lis") port, err := conf.GetPort("lis")
if err != nil { if err != nil {
@ -71,19 +69,20 @@ func (l *Listener) Register() error {
pb.RegisterHandshakeServer(grpcServer, l) pb.RegisterHandshakeServer(grpcServer, l)
go grpcServer.Serve(lis) go grpcServer.Serve(lis)
logging.Debug(logging.DStart, "LIS 01 Registered on port %v", port) logging.Debug(logging.DStart, "LIS 01 Registered on port %v", port)
*/
return nil return nil
} }
func (l *Listener) ClientDiscoveryHandler(ctx context.Context, ping *pb.ClientRequest) (*pb.ClientResponse, error) { func (l *Listener) ClientDiscoveryHandler(ctx context.Context, ping *pb.ClientRequest) (*pb.ClientResponse, error) {
// incoming reactor ping need to spawn coord // incoming reactor ping need to spawn coord
c := &Client{Id:ping.GetClientId(),Type:ping.GetClientType()} c := &Client{Id: ping.GetClientId(), Type: ping.GetClientType()}
logging.Debug(logging.DClient, "LIS %v %v has connected\n",c.Type,c.Id) logging.Debug(logging.DClient, "LIS %v %v has connected\n", c.Type, c.Id)
ch := make(chan *ClientResponse) ch := make(chan *ClientResponse)
p := &ClientPacket{Response:ch} p := &ClientPacket{Response: ch}
p.Client = c p.Client = c
l.ClientConnections <-p l.ClientConnections <- p
resp := <-ch resp := <-ch
// return the port for the incoming requests // return the port for the incoming requests
db := &pb.Database{URL:resp.URL,ORG:resp.Org,Token:resp.Token,Bucket:resp.Bucket} db := &pb.Database{URL: resp.URL, ORG: resp.Org, Token: resp.Token, Bucket: resp.Bucket}
return &pb.ClientResponse{ClientId:c.Id,ServerPort:uint32(resp.Port),Database:db}, nil return &pb.ClientResponse{ClientId: c.Id, ServerPort: uint32(resp.Port), Database: db}, nil
} }

@ -16,8 +16,7 @@
*I need to put the whole docker thing on the back burner for now. It isn't that important when it comes to immediate goals.* *I need to put the whole docker thing on the back burner for now. It isn't that important when it comes to immediate goals.*
**12/05** #### 12/05 TODO
#### TODO
- Cleanup server side config stuff to make it coherent - Cleanup server side config stuff to make it coherent
- Reflect changes to reactor side startup - Reflect changes to reactor side startup
- Boil down interface to address core issues - Boil down interface to address core issues
@ -26,6 +25,9 @@
2) Overwrite any previous settings with the flags 2) Overwrite any previous settings with the flags
3) Intelligently translate config into action 3) Intelligently translate config into action
4) launch coordinator and start up existing reactor managers 4) launch coordinator and start up existing reactor managers
- Config Structure:
- Wrap viper functions in config struct methods to be used thrtugh interfaces
- minimize the reliance on viper so we can sub in othermethods
- is it even important to launch reactor managers? Wont they just be started on connection? - is it even important to launch reactor managers? Wont they just be started on connection?

Loading…
Cancel
Save