128 lines
2.8 KiB
Go
128 lines
2.8 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
|
|
"github.com/joho/godotenv"
|
|
"github.com/pelletier/go-toml/v2"
|
|
)
|
|
|
|
// Config holds application configuration loaded from TOML
|
|
type Config struct {
|
|
Server ServerConfig `toml:"server"`
|
|
MQTT MQTTConfig `toml:"mqtt"`
|
|
Database DatabaseConfig `toml:"database"`
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
Address string `toml:"address"`
|
|
Port int `toml:"port"`
|
|
JWTSecret string `toml:"jwt_secret"`
|
|
}
|
|
|
|
type MQTTConfig struct {
|
|
Broker string `toml:"broker"`
|
|
ClientID string `toml:"client_id"`
|
|
Username string `toml:"username"`
|
|
Password string `toml:"password"`
|
|
Topic string `toml:"topic"`
|
|
}
|
|
|
|
type DatabaseConfig struct {
|
|
Host string `toml:"host"`
|
|
Port int `toml:"port"`
|
|
User string `toml:"user"`
|
|
Password string `toml:"password"`
|
|
Name string `toml:"name"`
|
|
}
|
|
|
|
// Load loads configuration from the given path. If path is empty, it tries
|
|
// to load ./config.toml or falls back to environment defaults.
|
|
func Load(path string) (*Config, error) {
|
|
cfg := &Config{
|
|
Server: ServerConfig{
|
|
Address: "0.0.0.0",
|
|
Port: 8080,
|
|
JWTSecret: "secret",
|
|
},
|
|
MQTT: MQTTConfig{
|
|
Broker: "tcp://localhost:1883",
|
|
ClientID: "lambda-iot-core",
|
|
Topic: "lambda/iot",
|
|
},
|
|
Database: DatabaseConfig{
|
|
Host: "localhost",
|
|
Port: 3306,
|
|
User: "root",
|
|
Name: "lambdaiot",
|
|
},
|
|
}
|
|
|
|
// try to load TOML if provided or present
|
|
if path == "" {
|
|
path = "config.toml"
|
|
}
|
|
if _, err := os.Stat(path); err == nil {
|
|
f, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err := toml.Unmarshal(f, cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// load .env (if present) so env vars are populated for overrides
|
|
_ = godotenv.Load()
|
|
|
|
// environment overrides (common for Docker/.env)
|
|
if v := os.Getenv("SERVER_ADDRESS"); v != "" {
|
|
cfg.Server.Address = v
|
|
}
|
|
if v := os.Getenv("SERVER_PORT"); v != "" {
|
|
if p, err := strconv.Atoi(v); err == nil {
|
|
cfg.Server.Port = p
|
|
}
|
|
}
|
|
if v := os.Getenv("JWT_SECRET"); v != "" {
|
|
cfg.Server.JWTSecret = v
|
|
}
|
|
|
|
if v := os.Getenv("MQTT_BROKER"); v != "" {
|
|
cfg.MQTT.Broker = v
|
|
}
|
|
if v := os.Getenv("MQTT_CLIENT_ID"); v != "" {
|
|
cfg.MQTT.ClientID = v
|
|
}
|
|
if v := os.Getenv("MQTT_USERNAME"); v != "" {
|
|
cfg.MQTT.Username = v
|
|
}
|
|
if v := os.Getenv("MQTT_PASSWORD"); v != "" {
|
|
cfg.MQTT.Password = v
|
|
}
|
|
if v := os.Getenv("MQTT_TOPIC"); v != "" {
|
|
cfg.MQTT.Topic = v
|
|
}
|
|
|
|
if v := os.Getenv("DB_HOST"); v != "" {
|
|
cfg.Database.Host = v
|
|
}
|
|
if v := os.Getenv("DB_PORT"); v != "" {
|
|
if p, err := strconv.Atoi(v); err == nil {
|
|
cfg.Database.Port = p
|
|
}
|
|
}
|
|
if v := os.Getenv("DB_USER"); v != "" {
|
|
cfg.Database.User = v
|
|
}
|
|
if v := os.Getenv("DB_PASSWORD"); v != "" {
|
|
cfg.Database.Password = v
|
|
}
|
|
if v := os.Getenv("DB_NAME"); v != "" {
|
|
cfg.Database.Name = v
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|