Files
tomswallapi/internal/config/config.go
T
2026-07-19 13:31:14 +10:00

70 lines
1.9 KiB
Go

// Package config loads tomswallapi runtime configuration from the environment.
package config
import (
"fmt"
"net/url"
"os"
)
// Config holds all runtime configuration, sourced from environment variables.
type Config struct {
ListenAddr string
DBHost string
DBPort string
DBUser string
DBPassword string
DBName string
DBSSLMode string
// WriteToken guards all mutating API endpoints (used by the Terraform provider).
WriteToken string
// AgentToken guards the per-device config endpoint (used by tomswall agents).
AgentToken string
// IPLocateAPIKey is used to expand ASN address groups into prefixes.
IPLocateAPIKey string
}
// Load reads configuration from the environment, applying defaults.
func Load() (*Config, error) {
c := &Config{
ListenAddr: env("TOMSWALLAPI_LISTEN_ADDR", ":8000"),
DBHost: env("TOMSWALLAPI_DB_HOST", "localhost"),
DBPort: env("TOMSWALLAPI_DB_PORT", "5432"),
DBUser: env("TOMSWALLAPI_DB_USER", "tomswallapi"),
DBPassword: os.Getenv("TOMSWALLAPI_DB_PASSWORD"),
DBName: env("TOMSWALLAPI_DB_NAME", "tomswallapi"),
DBSSLMode: env("TOMSWALLAPI_DB_SSLMODE", "disable"),
WriteToken: os.Getenv("TOMSWALLAPI_WRITE_TOKEN"),
AgentToken: os.Getenv("TOMSWALLAPI_AGENT_TOKEN"),
IPLocateAPIKey: os.Getenv("TOMSWALLAPI_IPLOCATE_API_KEY"),
}
if c.DBName == "" {
return nil, fmt.Errorf("TOMSWALLAPI_DB_NAME must not be empty")
}
return c, nil
}
// DatabaseDSN builds a libpq-style connection string.
func (c *Config) DatabaseDSN() string {
u := url.URL{
Scheme: "postgres",
User: url.UserPassword(c.DBUser, c.DBPassword),
Host: fmt.Sprintf("%s:%s", c.DBHost, c.DBPort),
Path: c.DBName,
}
q := u.Query()
q.Set("sslmode", c.DBSSLMode)
u.RawQuery = q.Encode()
return u.String()
}
func env(key, def string) string {
if v := os.Getenv(key); v != "" {
return v
}
return def
}