polycule-connect/polyculeconnect/config/config.go
Melora Hugues c8958a8f44
All checks were successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/push/deploy Pipeline was successful
feat #44: add CLI commands to manage apps
2023-11-08 19:33:53 +01:00

169 lines
4.7 KiB
Go

package config
import (
"encoding/json"
"errors"
"fmt"
"io/fs"
"os"
"github.com/dexidp/dex/connector/oidc"
"github.com/dexidp/dex/storage"
"github.com/sirupsen/logrus"
)
type envVar string
const (
varLogLevel envVar = "LOG_LEVEL"
varServerMode envVar = "SERVER_MODE"
varServerHost envVar = "SERVER_HOST"
varServerPort envVar = "SERVER_PORT"
varServerSocket envVar = "SERVER_SOCK_PATH"
varStorageType envVar = "STORAGE_TYPE"
varStorageFile envVar = "STORAGE_FILEPATH"
varStorageHost envVar = "STORAGE_HOST"
varStoragePort envVar = "STORAGE_PORT"
varStorageDB envVar = "STORAGE_DB"
varStorageUser envVar = "STORAGE_USER"
varStoragePassword envVar = "STORAGE_PASSWORD"
varStorageSSLMode envVar = "STORAGE_SSL_MODE"
varStorageSSLCaFile envVar = "STORAGE_SSL_CA_FILE"
)
type ListeningMode string
const (
ModeUnix ListeningMode = "unix"
ModeNet ListeningMode = "net"
)
type BackendConfigType string
const (
Memory BackendConfigType = "memory"
SQLite BackendConfigType = "sqlite"
)
const (
defaultLogLevel = logrus.InfoLevel
defaultServerMode = ModeNet
defaultServerHost = "0.0.0.0"
defaultServerPort = 5000
defaultServerSocket = ""
defaultStorageType = Memory
defaultStorageFile = "./polyculeconnect.db"
defaultStorageHost = "127.0.0.1"
defaultStoragePort = 5432
defaultStorageDB = "polyculeconnect"
defaultStorageUser = "polyculeconnect"
defaultStoragePassword = "polyculeconnect"
defaultStorageSSLMode = "disable"
defaultStorageSSLCaFile = ""
)
// Deprecated: remove when we finally drop the JSON config
type BackendConfig struct {
Config *oidc.Config `json:"config"`
Name string `json:"name"`
ID string `json:"ID"`
Type BackendConfigType `json:"type"`
Local bool `json:"local"`
}
// Deprecated: remove when we finally drop the JSON config
type OpenConnectConfig struct {
ClientConfigs []*storage.Client `json:"clients"`
BackendConfigs []*BackendConfig `json:"backends"`
Issuer string `json:"issuer"`
}
type StorageConfig struct {
File string
Host string
Port int
Database string
User string
Password string
Ssl struct {
Mode string
CaFile string
}
}
type jsonConf struct {
OpenConnectConfig *OpenConnectConfig `json:"openconnect"`
}
type AppConfig struct {
LogLevel logrus.Level
ServerMode ListeningMode
Host string
Port int
SockPath string
StorageType string
StorageConfig *StorageConfig
OpenConnectConfig *OpenConnectConfig
}
func parseLevel(lvlStr string) logrus.Level {
for _, lvl := range logrus.AllLevels {
if lvl.String() == lvlStr {
return lvl
}
}
return logrus.InfoLevel
}
func (ac *AppConfig) UnmarshalJSON(data []byte) error {
var jsonConf jsonConf
if err := json.Unmarshal(data, &jsonConf); err != nil {
return fmt.Errorf("failed to read JSON: %w", err)
}
ac.OpenConnectConfig = jsonConf.OpenConnectConfig
return nil
}
func (ac *AppConfig) getConfFromEnv() {
ac.LogLevel = parseLevel(getStringFromEnv(varLogLevel, defaultLogLevel.String()))
ac.ServerMode = ListeningMode(getStringFromEnv(varServerMode, string(defaultServerMode)))
ac.Host = getStringFromEnv(varServerHost, defaultServerHost)
ac.Port = getIntFromEnv(varServerPort, defaultServerPort)
ac.SockPath = getStringFromEnv(varServerSocket, defaultServerSocket)
ac.StorageType = getStringFromEnv(varStorageType, string(defaultStorageType))
ac.StorageConfig.Database = getStringFromEnv(varStorageDB, defaultStorageDB)
ac.StorageConfig.File = getStringFromEnv(varStorageFile, defaultStorageFile)
ac.StorageConfig.Host = getStringFromEnv(varStorageHost, defaultStorageHost)
ac.StorageConfig.Port = getIntFromEnv(varStoragePort, defaultStoragePort)
ac.StorageConfig.User = getStringFromEnv(varStorageUser, defaultStorageUser)
ac.StorageConfig.Password = getStringFromEnv(varStoragePassword, defaultStoragePassword)
ac.StorageConfig.Ssl.CaFile = getStringFromEnv(varStorageSSLCaFile, defaultStorageSSLCaFile)
ac.StorageConfig.Ssl.Mode = getStringFromEnv(varStorageSSLMode, defaultStorageSSLMode)
}
func (ac *AppConfig) RedirectURI() string {
return ac.OpenConnectConfig.Issuer + "/callback"
}
func New(filepath string) (*AppConfig, error) {
var conf AppConfig
conf.StorageConfig = &StorageConfig{}
content, err := os.ReadFile(filepath)
if err != nil {
if !errors.Is(err, fs.ErrNotExist) {
return nil, fmt.Errorf("failed to read config file %q: %w", filepath, err)
}
} else {
if err := json.Unmarshal(content, &conf); err != nil {
return nil, fmt.Errorf("failed to parse config file: %w", err)
}
}
conf.getConfFromEnv()
return &conf, nil
}