taskcafe/internal/config/config.go
Jordan Knott 64093e19f6 redesign
2022-05-06 16:44:31 -05:00

227 lines
5.5 KiB
Go

package config
import (
"context"
"errors"
"fmt"
"strings"
"time"
"github.com/go-redis/redis/v8"
mConfig "github.com/RichardKnop/machinery/v1/config"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
)
const (
ServerHostname = "server.hostname"
DatabaseHost = "database.host"
DatabaseName = "database.name"
DatabaseUser = "database.user"
DatabasePassword = "database.password"
DatabasePort = "database.port"
DatabaseSslMode = "database.ssl_mode"
SecurityTokenExpiration = "security.token_expiration"
SecuritySecret = "security.secret"
JobEnabled = "job.enabled"
JobBroker = "job.broker"
JobStore = "job.store"
JobQueueName = "job.queue_name"
MessageQueue = "message.queue"
SmtpFrom = "smtp.from"
SmtpHost = "smtp.host"
SmtpPort = "smtp.port"
SmtpUsername = "smtp.username"
SmtpPassword = "smtp.password"
SmtpSkipVerify = "false"
)
var defaults = map[string]interface{}{
ServerHostname: "0.0.0.0:3333",
DatabaseHost: "127.0.0.1",
DatabaseName: "taskcafe",
DatabaseUser: "taskcafe",
DatabasePassword: "taskcafe_test",
DatabasePort: "5432",
DatabaseSslMode: "disable",
SecurityTokenExpiration: "15m",
SecuritySecret: "",
MessageQueue: "localhost:6379",
JobEnabled: false,
JobBroker: "redis://localhost:6379",
JobStore: "redis://localhost:6379",
JobQueueName: "taskcafe_tasks",
SmtpFrom: "no-reply@example.com",
SmtpHost: "localhost",
SmtpPort: "587",
SmtpUsername: "",
SmtpPassword: "",
SmtpSkipVerify: false,
}
func InitDefaults() {
for key, value := range defaults {
viper.SetDefault(key, value)
}
}
type AppConfig struct {
Email EmailConfig
Security SecurityConfig
Database DatabaseConfig
Job JobConfig
MessageQueue MessageQueueConfig
}
type MessageQueueConfig struct {
URI string
}
type JobConfig struct {
Enabled bool
Broker string
QueueName string
Store string
}
func GetJobConfig() JobConfig {
return JobConfig{
Enabled: viper.GetBool(JobEnabled),
Broker: viper.GetString(JobBroker),
QueueName: viper.GetString(JobQueueName),
Store: viper.GetString(JobStore),
}
}
func (cfg *JobConfig) GetJobConfig() mConfig.Config {
return mConfig.Config{
Broker: cfg.Broker,
DefaultQueue: cfg.QueueName,
ResultBackend: cfg.Store,
/*
AMQP: &mConfig.AMQPConfig{
Exchange: "machinery_exchange",
ExchangeType: "direct",
BindingKey: "machinery_task",
} */
}
}
type EmailConfig struct {
Host string
Port int
From string
Username string
Password string
SiteURL string
InsecureSkipVerify bool
}
type DatabaseConfig struct {
Host string
Port string
Name string
Username string
Password string
SslMode string
}
func (cfg DatabaseConfig) GetDatabaseStandardUri() string {
return fmt.Sprintf("postgresql://%s:%s@%s:%s/%s",
cfg.Username,
cfg.Password,
cfg.Host,
cfg.Port,
cfg.Name,
)
}
func (cfg DatabaseConfig) GetDatabaseConnectionUri() string {
connection := fmt.Sprintf("user=%s password=%s host=%s dbname=%s port=%s sslmode=%s",
cfg.Username,
cfg.Password,
cfg.Host,
cfg.Name,
cfg.Port,
cfg.SslMode,
)
return connection
}
type SecurityConfig struct {
AccessTokenExpiration time.Duration
Secret []byte
}
func GetAppConfig() (AppConfig, error) {
secret := viper.GetString(SecuritySecret)
if strings.TrimSpace(secret) == "" {
log.Warn("server.secret is not set, generating a random secret")
secret = uuid.New().String()
}
securityCfg, err := GetSecurityConfig(viper.GetString(SecurityTokenExpiration), []byte(secret))
if err != nil {
return AppConfig{}, err
}
jobCfg := GetJobConfig()
databaseCfg := GetDatabaseConfig()
emailCfg := GetEmailConfig()
messageCfg := MessageQueueConfig{URI: viper.GetString("message.queue")}
return AppConfig{
Email: emailCfg,
Security: securityCfg,
Database: databaseCfg,
Job: jobCfg,
MessageQueue: messageCfg,
}, err
}
func GetSecurityConfig(accessTokenExp string, secret []byte) (SecurityConfig, error) {
exp, err := time.ParseDuration(accessTokenExp)
if err != nil {
log.WithError(err).Error("issue parsing duration")
return SecurityConfig{}, err
}
return SecurityConfig{AccessTokenExpiration: exp, Secret: secret}, nil
}
func (c MessageQueueConfig) GetMessageQueueClient() (*redis.Client, error) {
client := redis.NewClient(&redis.Options{
Addr: c.URI,
})
_, err := client.Ping(context.Background()).Result()
if !errors.Is(err, nil) {
return nil, err
}
return client, nil
}
func GetEmailConfig() EmailConfig {
return EmailConfig{
From: viper.GetString(SmtpFrom),
Host: viper.GetString(SmtpHost),
Port: viper.GetInt(SmtpPort),
Username: viper.GetString(SmtpUsername),
Password: viper.GetString(SmtpPassword),
InsecureSkipVerify: viper.GetBool(SmtpSkipVerify),
}
}
func GetDatabaseConfig() DatabaseConfig {
return DatabaseConfig{
Username: viper.GetString(DatabaseUser),
Password: viper.GetString(DatabasePassword),
Port: viper.GetString(DatabasePort),
SslMode: viper.GetString(DatabaseSslMode),
Name: viper.GetString(DatabaseName),
Host: viper.GetString(DatabaseHost),
}
}