package config import ( "encoding/json" "fmt" "log" "os" "reflect" "strconv" "strings" ) const configFilePath = "/etc/PixelRidge/BackGo/config.json" type LogLevel int const ( LogLevelDebug LogLevel = iota LogLevelInfo LogLevelWarning LogLevelError ) type Config struct { LogLevel LogLevel S3Enabled bool S3ConnectionAddress string S3AuthorizationInfo string S3Region string S3BucketInfo string SMBEnabled bool SMBConnectionAddress string SMBAuthorizationInfo string B2Enabled bool B2ConnectionAddress string B2AuthorizationInfo string B2BucketInfo string LocalStorageEnabled bool LocalStorageDirectory string APIServerBindAddress string APIServerPort string TransportServerBindAddress string TransportServerPort string Nodes []string } func LoadConfig() *Config { return &Config{ LogLevel: getEnvAsLogLevel("LOG_LEVEL", LogLevelInfo), S3Enabled: getEnvAsBool("S3_ENABLED", false), S3ConnectionAddress: os.Getenv("S3_CONNECTION_ADDRESS"), S3AuthorizationInfo: os.Getenv("S3_AUTHORIZATION_INFO"), S3Region: os.Getenv("S3_REGION"), S3BucketInfo: os.Getenv("S3_BUCKET_INFO"), SMBEnabled: getEnvAsBool("SMB_ENABLED", false), SMBConnectionAddress: os.Getenv("SMB_CONNECTION_ADDRESS"), SMBAuthorizationInfo: os.Getenv("SMB_AUTHORIZATION_INFO"), B2Enabled: getEnvAsBool("BACKBLAZE_B2_ENABLED", false), B2ConnectionAddress: os.Getenv("B2_CONNECTION_ADDRESS"), B2AuthorizationInfo: os.Getenv("B2_AUTHORIZATION_INFO"), B2BucketInfo: os.Getenv("BACKBLAZE_B2_BUCKET_INFO"), LocalStorageEnabled: getEnvAsBool("LOCAL_STORAGE_ENABLED", false), LocalStorageDirectory: os.Getenv("LOCAL_STORAGE_DIRECTORY"), APIServerBindAddress: os.Getenv("API_SERVER_BIND_ADDRESS"), APIServerPort: os.Getenv("API_SERVER_PORT"), TransportServerBindAddress: os.Getenv("TRANSPORT_SERVER_BIND_ADDRESS"), TransportServerPort: os.Getenv("TRANSPORT_SERVER_PORT"), Nodes: getEnvAsSlice("NODES", ",", []string{}), } } func getEnvAsBool(name string, defaultVal bool) bool { valStr := os.Getenv(name) if valStr == "" { return defaultVal } val, err := strconv.ParseBool(valStr) if err != nil { log.Printf("Error parsing boolean for %s: %v\n", name, err) return defaultVal } return val } func getEnvAsSlice(name, sep string, defaultVal []string) []string { valStr := os.Getenv(name) if valStr == "" { return defaultVal } return strings.Split(valStr, sep) } func getEnvAsLogLevel(name string, defaultVal LogLevel) LogLevel { valStr := os.Getenv(name) if valStr == "" { return defaultVal } if strings.EqualFold(valStr, "debug") { return LogLevelDebug } else if strings.EqualFold(valStr, "info") { return LogLevelInfo } else if strings.EqualFold(valStr, "warning") { return LogLevelWarning } else if strings.EqualFold(valStr, "error") { return LogLevelError } log.Printf("Unknown LOG_LEVEL '%s', defaulting to INFO.\n", valStr) return LogLevelInfo } func UpdateConfig(key, value string) error { config, err := LoadConfigFromFile() if err != nil { return fmt.Errorf("loading config: %v", err) } rConfig := reflect.ValueOf(config).Elem() field := rConfig.FieldByNameFunc(func(s string) bool { return strings.EqualFold(s, key) }) if !field.IsValid() { return fmt.Errorf("unknown configuration key: %s", key) } if !field.CanSet() { return fmt.Errorf("cannot set configuration key: %s", key) } switch field.Kind() { case reflect.String: field.SetString(value) case reflect.Bool: boolVal, err := strconv.ParseBool(value) if err != nil { return fmt.Errorf("parsing boolean value for %s: %v", key, err) } field.SetBool(boolVal) case reflect.Int: intVal, err := strconv.Atoi(value) if err != nil { return fmt.Errorf("parsing integer value for %s: %v", key, err) } field.SetInt(int64(intVal)) default: return fmt.Errorf("unsupported configuration type for: %s", key) } return SaveConfigToFile(config) } func LoadConfigFromFile() (*Config, error) { file, err := os.ReadFile(configFilePath) if err != nil { return nil, err } var config Config if err := json.Unmarshal(file, &config); err != nil { return nil, err } return &config, nil } func SaveConfigToFile(config *Config) error { data, err := json.MarshalIndent(config, "", " ") if err != nil { return err } return os.WriteFile(configFilePath, data, 0644) } func ReloadConfig() { fmt.Println("Configuration reloaded") }