2024-02-15 22:47:56 +00:00
|
|
|
package config
|
2024-02-11 19:28:00 +00:00
|
|
|
|
|
|
|
import (
|
2024-02-15 17:43:35 +00:00
|
|
|
"fmt"
|
|
|
|
"log"
|
2024-02-11 19:28:00 +00:00
|
|
|
"os"
|
|
|
|
"strings"
|
2024-02-15 17:43:35 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/go-playground/validator/v10"
|
|
|
|
"github.com/spf13/viper"
|
2024-02-11 19:28:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Config struct {
|
2024-02-15 17:43:35 +00:00
|
|
|
Port string `validate:"required"`
|
|
|
|
RootUrl string `validate:"required,url"`
|
|
|
|
DatabasePath string `validate:"required"`
|
|
|
|
SessionSecret string `validate:"required"`
|
2024-02-11 19:28:00 +00:00
|
|
|
|
2024-02-15 17:43:35 +00:00
|
|
|
OAuth2 OAuth2 `validate:"required"`
|
2024-02-11 19:28:00 +00:00
|
|
|
|
2024-02-15 17:43:35 +00:00
|
|
|
Temporal Temporal `validate:"required"`
|
2024-02-13 20:52:10 +00:00
|
|
|
|
2024-02-15 17:43:35 +00:00
|
|
|
HealthChecks []Healthcheck
|
|
|
|
CronJobs []CronJob
|
|
|
|
}
|
2024-02-13 20:52:10 +00:00
|
|
|
|
2024-02-15 17:43:35 +00:00
|
|
|
type OAuth2 struct {
|
|
|
|
ClientID string `validate:"required"`
|
|
|
|
ClientSecret string `validate:"required"`
|
|
|
|
Scopes []string `validate:"required"`
|
|
|
|
EndpointTokenURL string `validate:"required"`
|
|
|
|
EndpointAuthURL string `validate:"required"`
|
|
|
|
EndpointUserInfoURL string `validate:"required"`
|
2024-02-16 12:52:27 +00:00
|
|
|
EndpointLogoutURL string // Optional as not all SSO support this.
|
2024-02-11 19:28:00 +00:00
|
|
|
}
|
|
|
|
|
2024-02-15 17:43:35 +00:00
|
|
|
type Temporal struct {
|
|
|
|
DatabasePath string `validate:"required"`
|
|
|
|
ListenAddress string `validate:"required"`
|
|
|
|
UIHost string `validate:"required"`
|
|
|
|
ServerHost string `validate:"required"`
|
2024-02-11 19:28:00 +00:00
|
|
|
}
|
|
|
|
|
2024-02-15 17:43:35 +00:00
|
|
|
type HealthCheckHTTP struct {
|
|
|
|
URL string `validate:"required,url"`
|
|
|
|
Method string `validate:"required,oneof=GET POST PUT"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type HealthCheckTCP struct {
|
|
|
|
Host string `validate:"required,hostname"`
|
|
|
|
Port int `validate:"required,gte=1,lte=65535"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Healthcheck struct {
|
|
|
|
Name string `validate:"required"`
|
|
|
|
Retries int `validate:"optional,gte=0"`
|
|
|
|
Schedule string `validate:"required,cron"`
|
|
|
|
Timeout time.Duration `validate:"required"`
|
|
|
|
|
|
|
|
HTTP HealthCheckHTTP `validate:"required"`
|
|
|
|
TCP HealthCheckTCP `validate:"required"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type CronJob struct {
|
|
|
|
Name string `validate:"required"`
|
|
|
|
Schedule string `validate:"required,cron"`
|
|
|
|
Buffer time.Duration `validate:"required"`
|
2024-02-11 19:28:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewConfig() *Config {
|
2024-02-15 17:43:35 +00:00
|
|
|
viper.SetConfigName("zdravko")
|
|
|
|
viper.SetConfigType("yaml")
|
|
|
|
viper.AddConfigPath("/etc/zdravko/")
|
|
|
|
viper.AddConfigPath("$HOME/.zdravko")
|
|
|
|
viper.AddConfigPath("$HOME/.config/zdravko")
|
|
|
|
viper.AddConfigPath("$XDG_CONFIG_HOME/zdravko")
|
|
|
|
viper.AddConfigPath(".")
|
|
|
|
|
|
|
|
// Set defaults
|
|
|
|
viper.SetDefault("port", "8000")
|
|
|
|
viper.SetDefault("rooturl", "http://localhost:8000")
|
|
|
|
viper.SetDefault("databasepath", "zdravko.db")
|
|
|
|
viper.SetDefault("oauth2.scopes", "openid profile email")
|
|
|
|
viper.SetDefault("temporal.databasepath", "temporal.db")
|
|
|
|
viper.SetDefault("temporal.listenaddress", "0.0.0.0")
|
|
|
|
viper.SetDefault("temporal.uihost", "127.0.0.1:8223")
|
|
|
|
viper.SetDefault("temporal.serverhost", "127.0.0.1:7233")
|
|
|
|
|
|
|
|
// Cant figure out the viper env, so lets just do it manually.
|
|
|
|
viper.SetDefault("sessionsecret", os.Getenv("SESSION_SECRET"))
|
|
|
|
viper.SetDefault("oauth2.clientid", os.Getenv("OAUTH2_CLIENT_ID"))
|
|
|
|
viper.SetDefault("oauth2.clientsecret", os.Getenv("OAUTH2_CLIENT_SECRET"))
|
|
|
|
viper.SetDefault("oauth2.scope", os.Getenv("OAUTH2_ENDPOINT_SCOPE"))
|
|
|
|
viper.SetDefault("oauth2.endpointtokenurl", os.Getenv("OAUTH2_ENDPOINT_TOKEN_URL"))
|
|
|
|
viper.SetDefault("oauth2.endpointauthurl", os.Getenv("OAUTH2_ENDPOINT_AUTH_URL"))
|
|
|
|
viper.SetDefault("oauth2.endpointuserinfourl", os.Getenv("OAUTH2_ENDPOINT_USER_INFO_URL"))
|
|
|
|
viper.SetDefault("oauth2.endpointlogouturl", os.Getenv("OAUTH2_ENDPOINT_LOGOUT_URL"))
|
|
|
|
|
|
|
|
err := viper.ReadInConfig()
|
|
|
|
if err != nil {
|
2024-02-15 22:47:56 +00:00
|
|
|
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
|
|
|
// ignore
|
|
|
|
} else {
|
|
|
|
log.Fatalf("Error reading config file, %s", err)
|
|
|
|
}
|
2024-02-15 17:43:35 +00:00
|
|
|
}
|
|
|
|
log.Println("Config file used: ", viper.ConfigFileUsed())
|
|
|
|
|
|
|
|
config := &Config{}
|
|
|
|
err = viper.Unmarshal(config)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Error unmarshalling config, %s", err)
|
2024-02-11 19:28:00 +00:00
|
|
|
}
|
2024-02-15 17:43:35 +00:00
|
|
|
|
|
|
|
// OAuth2 scopes are space separated
|
|
|
|
config.OAuth2.Scopes = strings.Split(viper.GetString("oauth2.scopes"), " ")
|
|
|
|
|
|
|
|
// Validate config
|
|
|
|
validate := validator.New(validator.WithRequiredStructEnabled())
|
|
|
|
err = validate.Struct(config)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Error validating config, %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("Config: %+v\n", config)
|
|
|
|
|
|
|
|
return config
|
2024-02-11 19:28:00 +00:00
|
|
|
}
|