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 ListeningMode int64 func (lm ListeningMode) String() string { mapping := map[ListeningMode]string{ ModeNet: "net", ModeUnix: "unix", } val := mapping[lm] return val } func listeningModeFromString(rawVal string) (ListeningMode, error) { mapping := map[string]ListeningMode{ "unix": ModeUnix, "net": ModeNet, } if typedVal, ok := mapping[rawVal]; !ok { return ModeNet, fmt.Errorf("invalid listening mode %s", rawVal) } else { return typedVal, nil } } const ( ModeUnix ListeningMode = iota ModeNet ) type BackendConfig struct { Config *oidc.Config `json:"config"` Name string `json:"name"` ID string `json:"ID"` Type string `json:"type"` Local bool `json:"local"` } type OpenConnectConfig struct { ClientConfigs []*storage.Client `json:"clients"` BackendConfigs []*BackendConfig `json:"backends"` Issuer string `json:"issuer"` } type StorageConfigConfig struct { Host string `json:"host"` Port int `json:"port"` Database string `json:"database"` User string `json:"user"` Password string `json:"password"` Ssl struct { Mode string `json:"mode"` CaFile string `json:"caFile"` } `json:"ssl"` } type jsonConf struct { Log struct { Level string `json:"level"` } `json:"log"` Server struct { Host string `json:"host"` Port int `json:"port"` Mode string `json:"mode"` SockPath string `json:"sock"` } `json:"server"` Storage struct { StorageType string `json:"type"` StorageConfig *StorageConfigConfig `json:"config"` } `json:"storage"` OpenConnectConfig *OpenConnectConfig `json:"openconnect"` } type AppConfig struct { LogLevel logrus.Level ServerMode ListeningMode Host string Port int SockPath string StorageType string StorageConfig *StorageConfigConfig 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.LogLevel = parseLevel(jsonConf.Log.Level) lm, err := listeningModeFromString(jsonConf.Server.Mode) if err != nil { return fmt.Errorf("failed to parse server listening mode: %w", err) } ac.ServerMode = lm ac.SockPath = jsonConf.Server.SockPath ac.Host = jsonConf.Server.Host ac.Port = jsonConf.Server.Port ac.OpenConnectConfig = jsonConf.OpenConnectConfig ac.StorageType = jsonConf.Storage.StorageType ac.StorageConfig = jsonConf.Storage.StorageConfig return nil } var defaultConfig AppConfig = AppConfig{ LogLevel: logrus.InfoLevel, ServerMode: ModeNet, Host: "0.0.0.0", Port: 5000, StorageType: "memory", } func New(filepath string) (*AppConfig, error) { content, err := os.ReadFile(filepath) if err != nil { if errors.Is(err, fs.ErrNotExist) { conf := defaultConfig return &conf, nil } return nil, fmt.Errorf("failed to read config file %q: %w", filepath, err) } var conf AppConfig if err := json.Unmarshal(content, &conf); err != nil { return nil, fmt.Errorf("failed to parse config file: %w", err) } fmt.Printf(conf.StorageType) return &conf, nil }