go-urlsh/internal/config/config.go

144 lines
3.6 KiB
Go

package config
import (
"net/netip"
"slices"
"strconv"
"github.com/rs/zerolog"
"github.com/spf13/viper"
)
type Config struct {
DatabaseDSN string
// panic = 5,
// fatal = 4,
// error = 3,
// warn = 2,
// info = 1,
// debug = 0,
// trace = -1
LogLevel int
HostIP netip.Addr
HostPort int
HostURL string
ProxyHeader string
AccessLog bool
}
func NewConfig(configPath string) *Config {
logger := NewLogger(zerolog.InfoLevel)
loadConfigFile(configPath, logger)
cfg := new(Config)
exit := false
// handle Database DSN
if viper.GetString("database.url") != "" {
cfg.DatabaseDSN = viper.GetString("database.url")
} else {
dsn := "postgres://"
if viper.GetString("database.username") == "" {
exit = true
logger.Error().Msg("If database.url is not set, database.username must not be empty!")
} else {
dsn = dsn + viper.GetString("database.username")
}
if viper.GetString("database.password") == "" {
exit = true
logger.Error().Msg("If database.url is not set, database.password must not be empty!")
} else {
dsn = dsn + ":" + viper.GetString("database.password")
}
if viper.GetString("database.address") == "" {
exit = true
logger.Error().Msg("If database.url is not set, database.address must not be empty!")
} else {
dsn = dsn + "@" + viper.GetString("database.address")
}
if viper.GetString("database.port") != "" {
dsn = dsn + ":" + strconv.Itoa(viper.GetInt("database.port"))
}
if viper.GetString("database.database") == "" {
exit = true
logger.Error().Msg("If database.url is not set, database.database must not be empty!")
} else {
dsn = dsn + "/" + viper.GetString("database.database")
}
if slices.Contains([]string{"disable", "require", "verify-full", ""}, viper.GetString("database.ssl-mode")) {
if viper.GetString("database.ssl-mode") == "" {
cfg.DatabaseDSN = dsn + "?sslmode=disable"
} else {
cfg.DatabaseDSN = dsn + "?sslmode=" + viper.GetString("database.ssl-mode")
}
} else {
logger.Error().Msg(`If database.url is not set, database.ssl-mode must be either "disable", "require", "verify-full" or empty!`)
}
}
// Handle Logging
switch logLevel := viper.GetString("logging.level"); logLevel {
case "panic":
cfg.LogLevel = 5
case "fatal":
cfg.LogLevel = 4
case "error":
cfg.LogLevel = 3
case "warn":
cfg.LogLevel = 2
case "info":
cfg.LogLevel = 1
case "debug":
cfg.LogLevel = 0
case "trace":
cfg.LogLevel = -1
default:
exit = true
logger.Error().Str("value", logLevel).Msg(`Value of logging.level is invalid!`)
}
cfg.HostURL = viper.GetString("application.base-url")
if viper.GetString("application.listen") != "" {
ip, err := netip.ParseAddr(viper.GetString("application.listen"))
if err != nil {
exit = true
logger.Error().Str("value", viper.GetString("application.listen")).Msg(`Value of application.listen is not a valid IP address!`)
} else {
cfg.HostIP = ip
}
} else {
cfg.HostIP = netip.MustParseAddr("127.0.0.1")
}
if viper.GetInt("application.port") != 0 {
// if port is a valid port number
if viper.GetInt("application.port") <= 65535 && viper.GetInt("application.port") > 0 {
cfg.HostPort = viper.GetInt("application.port")
} else {
logger.Error().Str("value", viper.GetString("application.port")).Msg(`Value of application.port is not a valid port number!`)
}
} else {
cfg.HostPort = 3000
}
if viper.GetString("application.proxy-header") == "" {
cfg.ProxyHeader = "X-Forwarded-For"
} else {
cfg.ProxyHeader = viper.GetString("application.proxy-header")
}
if exit {
logger.Fatal().Msg("There were errors reading the config file. See errors above!")
}
return cfg
}