2024-01-21 14:58:27 +01:00
|
|
|
// Copyright 2024 Florian Beisel
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2024-01-17 18:05:55 +01:00
|
|
|
package config
|
|
|
|
|
2024-01-18 01:04:43 +01:00
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"flag"
|
|
|
|
"os"
|
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
// You might need additional imports for file handling, etc.
|
|
|
|
)
|
|
|
|
|
|
|
|
type AppConfig struct {
|
|
|
|
JwtKey string
|
|
|
|
DatabaseFile string
|
|
|
|
}
|
|
|
|
|
|
|
|
var GlobalConfig *AppConfig
|
|
|
|
|
|
|
|
func LoadConfig() error {
|
|
|
|
GlobalConfig = &AppConfig{}
|
|
|
|
|
|
|
|
// Check command line arguments
|
|
|
|
configFile := flag.String("c", "", "path to config file")
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
if *configFile != "" {
|
|
|
|
return loadConfigFromFile(*configFile, GlobalConfig)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check environment variable for config file path
|
|
|
|
envConfigFile := os.Getenv("HS_CONFIGFILE")
|
|
|
|
if envConfigFile != "" {
|
|
|
|
return loadConfigFromFile(envConfigFile, GlobalConfig)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to load from a default config file
|
|
|
|
defaultConfigFile := "config.json" // Replace with your default config file name
|
|
|
|
if _, err := os.Stat(defaultConfigFile); err == nil {
|
|
|
|
return loadConfigFromFile(defaultConfigFile, GlobalConfig)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load config from environment variables or docker secrets
|
|
|
|
loadConfigFromEnvOrSecrets(GlobalConfig)
|
|
|
|
|
|
|
|
// Check if the configuration has been loaded successfully
|
2024-01-21 14:58:27 +01:00
|
|
|
if GlobalConfig.DatabaseFile == "" {
|
2024-01-18 01:04:43 +01:00
|
|
|
// Add more checks as necessary for other required config fields
|
|
|
|
return errors.New("failed to load configuration from any source")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func loadConfigFromFile(filePath string, config *AppConfig) error {
|
2024-01-21 14:58:27 +01:00
|
|
|
fileData, err := os.ReadFile(filePath)
|
2024-01-18 01:04:43 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = json.Unmarshal(fileData, config)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func loadConfigFromEnvOrSecrets(config *AppConfig) {
|
|
|
|
val := reflect.ValueOf(config).Elem()
|
|
|
|
typ := val.Type()
|
|
|
|
|
|
|
|
for i := 0; i < val.NumField(); i++ {
|
|
|
|
field := typ.Field(i)
|
|
|
|
envVar := "HS_CONFIG_" + strings.ToUpper(field.Name)
|
|
|
|
if value, exists := os.LookupEnv(envVar); exists {
|
|
|
|
val.Field(i).SetString(value)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handling Docker secrets (file-based secrets)
|
|
|
|
secretFileEnvVar := envVar + "_FILE"
|
|
|
|
if secretFilePath, exists := os.LookupEnv(secretFileEnvVar); exists {
|
2024-01-21 14:58:27 +01:00
|
|
|
if secretValue, err := os.ReadFile(secretFilePath); err == nil {
|
2024-01-18 01:04:43 +01:00
|
|
|
val.Field(i).SetString(string(secretValue))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|