barebones config working to load/store vals on exit

main
KeeganForelight 2 years ago
parent ebd87863bc
commit 5554d93aa1

@ -13,33 +13,22 @@ import (
"FRMS/internal/pkg/logging"
"FRMS/internal/pkg/server"
"os"
"github.com/spf13/viper"
)
type coordinator interface {
Start()
}
type Config interface {
//UpdatePort(string, int) error
Store() error
}
func NewCoordinator(ch chan error) coordinator {
return server.NewCentralCoordinator(ch)
func NewCoordinator(config *viper.Viper, ch chan error) coordinator {
return server.NewCentralCoordinator(config, ch)
}
func NewConfig(fname string) Config {
return config.NewConfig(fname)
func NewConfig(fname string) *viper.Viper {
return config.LoadConfig(fname)
}
/*
func LoadConfig(fname string) Config {
if err := config.Load(fname); err != nil {
panic(err)
}
return config.LoadConfig()
} */
func main() {
// lets get this bread
@ -49,16 +38,17 @@ func main() {
errCh := make(chan error)
//fmt.Printf("Listening on %v\n", lport)
c := NewCoordinator(errCh)
c := NewCoordinator(conf, errCh)
go c.Start()
logging.Debug(logging.DStart, "CCO 01 Server started")
logging.Debug(logging.DStart, "CCO 01 Server %s started", conf.Get("name"))
select {
case err := <-errCh: // blocking to wait for any errors and keep alive otherwise
panic(err)
case <-gracefulShutdown:
// Shutdown via INT
err := conf.Store()
if err != nil {
// storing config
fmt.Printf("\nStoring config to %s\n", conf.ConfigFileUsed())
if err := conf.WriteConfig(); err != nil {
panic(err)
}
fmt.Println("Stored config successfully. Exiting...")

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

@ -6,59 +6,31 @@ Load.go contains methods to load values from config, flags and env.
import (
"FRMS/internal/pkg/logging"
"errors"
"fmt"
"github.com/spf13/viper"
)
type Config interface {
//rip
Store() error
}
func NewConfig(name string) Config {
// returns a Config Structure of assocaited name
return LoadConfig(name)
}
func LoadConfig(fname string) Config {
func LoadConfig(fname string) *viper.Viper {
// Demarshalls a given filename into the struct
// returns nil if successful
var C Config
config := viper.New()
logging.Debug(logging.DStart, "Loading config for %s", fname)
viper.SetConfigName(fname)
viper.SetConfigType("yaml")
config.SetConfigName(fname)
config.SetConfigType("yaml")
//viper.AddConfigPath("/etc/frms/config")
viper.AddConfigPath("$HOME/FRMS/internal/configs")
config.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()
config.AutomaticEnv()
// unmarshalling
if err := viper.ReadInConfig(); err != nil {
// reading
if err := config.ReadInConfig(); err != nil {
panic(err)
}
logging.Debug(logging.DStart, "CON Loaded configs from %v", viper.ConfigFileUsed())
if err := viper.Unmarshal(C); err != nil {
logging.Debug(logging.DError, "Cannot unmarshall %v", err)
panic(err)
}
fmt.Printf("Outcome: %#v\n \n", C)
// unmarshalled at this point
return C
logging.Debug(logging.DStart, "CON Loaded configs from %v", config.ConfigFileUsed())
// returning config object
return config
}

@ -0,0 +1,10 @@
package config
// pacakge serves to provide reactor config implementation
type ReactorConfig struct {
DB DatabaseInfo `mapstructure:"db"`
Server ServerInfo `mapstructure:"server"`
Name string `mapstructure:"name"`
Id uint32 `mapstructure:"id"`
Devices map[int]DeviceConfig

@ -23,8 +23,8 @@ type ServerConfig struct {
type DatabaseInfo struct {
URL string `mapstructure:"url"`
Token string `mapstructure:"token"`
Org string `mapstructure:"org,omitempty"`
Bucket string `mapstructure:"url,omitempty"`
Org string `mapstructure:"org"`
Bucket string `mapstructure:"url"`
}
type ServerReactorConfig struct {

@ -1,3 +0,0 @@
package config
// pacakge serves to provide reactor config implementation

@ -5,13 +5,14 @@ import (
_ "fmt"
_ "github.com/influxdata/influxdb-client-go/v2"
"github.com/spf13/viper"
)
type DBClient struct {
URL string
Org string
Bucket string
Token string
URL string `mapstructure:"url"`
Org string `mapstructure:"org,omitempty`
Bucket string `mapstructure:"bucket,omitempty"`
Token string `mapstructure:"token,omitempty"`
// Client *influxdb2.Client
}
@ -20,15 +21,20 @@ type DBAdmin struct {
*DBClient
}
func NewDBClient(url, org, token string) *DBClient {
db := &DBClient{URL: url, Org: org, Token: token}
return db
func NewDBClient(conf *viper.Viper) (*DBClient, error) {
db := &DBClient{}
// grabbing config vals
err := conf.UnmarshalKey("db", db)
return db, err
}
func NewDBAdmin(url, org, token string) *DBAdmin {
func NewDBAdmin(conf *viper.Viper) (*DBAdmin, error) {
admin := &DBAdmin{}
admin.DBClient = NewDBClient(url, org, token)
return admin
var err error
// creating client
admin.DBClient, err = NewDBClient(conf)
return admin, err
}
// base level funcs
@ -36,8 +42,9 @@ func (d *DBClient) Start() {
// connect to DB
}
func (d *DBAdmin) GetReactorClient(id string) (string, string, error) {
// given an id returns associated token and bucket
func (d *DBAdmin) GetReactorClient(id int) (url, bucket, org, token string, err error) {
// given an id returns
// (url, org, bucket, token, error) for said id
/*
client := influxdb2.NewClient(d.URL, d.Token)
defer client.Close()
@ -49,5 +56,8 @@ func (d *DBAdmin) GetReactorClient(id string) (string, string, error) {
// get corresponding reactor token and bucket
}
*/
return "", "", errors.New("Unimpl")
url = d.URL
org = d.Org
err = errors.New("Unimpl")
return
}

@ -7,58 +7,38 @@ import (
"FRMS/internal/pkg/logging"
"context"
"errors"
"fmt"
"sync"
"github.com/spf13/viper"
)
// this package creates the central coordiantor and sub coordiantors for clients
// interfaces
// config interface
/*
func LoadConfig() Config {
// returns a ServerConfig that we can query and update
//return config.LoadConfig()
}
*/
type Config interface { // PROPOSED RENAMING: ServerConfig to avoid confusion w/ reactor variant
// getters
GetURL() (string, error)
GetOrg() (string, error)
GetPort(string) (int, error)
GetServerToken() (string, error)
GetReactorClient(uint32) (string, string, error) // ret (bucket, token, err)
// setters
// save on write
//UpdateURL(string) error
//UpdateOrg(string) error
//UpdateServerToken(string) error
UpdateReactorClient(uint32, string, string) error // call (id, bucket, token)
}
// db client interface
type DB interface {
// getters (all create if doesnt exist)
//GetToken() (string, error) // returns admin token (Creates if it doesnt exist)
GetReactorClient(string) (string, string, error) // returns (bucket, token, err)
GetReactorClient(int) (string, string, string, string, error) // returns (url, org, bucket, token, err)
// delete
// DeleteReactorClient(string) error // removes client token but maintains bucket
// PurgeReactorClientData(string) error // perm deletes all assocaited reactor data (token, bucket etc)
}
func NewDBAdmin(url, org, token string) DB {
return influxdb.NewDBAdmin(token, org, url)
func NewDBAdmin(config *viper.Viper) (DB, error) {
return influxdb.NewDBAdmin(config)
}
type CentralCoordinator struct {
ClientConnections *ClientPacket
//CLisPort int
*SubCoordinators
*SystemViewer
DB
Config
Err chan error
Config *viper.Viper
// from config
Ports map[string]int `mapstructure:"ports"`
Err chan error
}
type SubCoordinators struct {
@ -66,8 +46,13 @@ type SubCoordinators struct {
sync.Mutex
}
func NewCentralCoordinator(ch chan error) *CentralCoordinator {
c := &CentralCoordinator{Err: ch}
func NewCentralCoordinator(config *viper.Viper, ch chan error) *CentralCoordinator {
c := &CentralCoordinator{Err: ch, Config: config}
if err := config.UnmarshalKey("server", c); err != nil {
// report error
ch <- err
}
fmt.Printf("%+v\n", c)
c.SystemViewer = NewSystemViewer()
go c.SystemViewer.Start()
s := make(map[string]*SubCoordinator)
@ -78,36 +63,11 @@ func NewCentralCoordinator(ch chan error) *CentralCoordinator {
func (c *CentralCoordinator) Start() {
// starts up associated funcs
// begin with config and client
//c.LoadCfg()
clientChan := make(chan *ClientPacket)
l := NewListener(clientChan, c.Err)
go l.Start()
go c.ClientListener(clientChan)
}
/*
func (c *CentralCoordinator) LoadCfg() {
// loads db client info and updates if anything is missing
c.Config = LoadConfig()
_, err := c.Config.GetURL()
if err != nil {
logging.Debug(logging.DError, "CCO 01 Err: %v", err)
c.Err <- err
}
token, err := c.Config.GetServerToken()
if err != nil {
logging.Debug(logging.DError, "CCO 01 Err: %v", err)
c.Err <- err
}
org, err := c.Config.GetOrg()
if err != nil {
logging.Debug(logging.DError, "CCO 01 Err: %v", err)
c.Err <- err
}
}
*/
func (c *CentralCoordinator) ClientListener(ch chan *ClientPacket) {
for client := range ch {
@ -129,23 +89,11 @@ func (c *CentralCoordinator) ClientHandler(cl *Client) *ClientResponse {
}
go subcoord.ClientHandler(cl)
// setting up client response
var url, org, token, bucket string
var port int
var err error
if url, err = c.Config.GetURL(); err != nil {
logging.Debug(logging.DError, "Error: %v", err)
c.Err <- err
} else if org, err = c.Config.GetOrg(); err != nil {
logging.Debug(logging.DError, "Error: %v", err)
c.Err <- err
} else if bucket, token, err = c.Config.GetReactorClient(cl.Id); err != nil {
logging.Debug(logging.DError, "Error: %v", err)
c.Err <- err
} else if port, err = c.Config.GetPort(cl.Type); err != nil {
logging.Debug(logging.DError, "Error: %v", err)
url, org, token, bucket, err := c.DB.GetReactorClient(int(cl.Id))
if err != nil {
c.Err <- err
}
cr := &ClientResponse{URL: url, Org: org, Token: token, Bucket: bucket, Port: port}
cr := &ClientResponse{URL: url, Org: org, Token: token, Bucket: bucket, Port: c.Ports[cl.Type]}
return cr
}

@ -31,3 +31,6 @@
- is it even important to launch reactor managers? Wont they just be started on connection?
#### 12/06 TODO
- I think I can completely remove the old config way and just pass the viper object directly. I think its not worth the hassle of trying to keep track of a million interfaces

Loading…
Cancel
Save