Files
lambdaiot-core/internal/config/config.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
}