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()) }