Skip to content

Commit

Permalink
perf: Improve configuration parsing logic
Browse files Browse the repository at this point in the history
* Do not set default configuration file
* Command line flag priority

Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
  • Loading branch information
zhaojh329 committed Dec 17, 2024
1 parent b326fb9 commit 90d51a5
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 79 deletions.
197 changes: 128 additions & 69 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package config

import (
"fmt"
"os"
"strconv"
"strings"

"github.com/kylelemons/go-gypsy/yaml"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v2"
)

Expand Down Expand Up @@ -48,87 +48,146 @@ func getConfigOpt(yamlCfg *yaml.File, name string, opt interface{}) {
}
}

func parseYamlCfg(cfg *Config, conf string) error {
yamlCfg, err := yaml.ReadFile(conf)
if err != nil {
return fmt.Errorf(`read config file: %s`, err.Error())
}

getConfigOpt(yamlCfg, "addr-dev", &cfg.AddrDev)
getConfigOpt(yamlCfg, "addr-user", &cfg.AddrUser)
getConfigOpt(yamlCfg, "addr-http-proxy", &cfg.AddrHttpProxy)
getConfigOpt(yamlCfg, "disable-sign-up", &cfg.DisableSignUp)
getConfigOpt(yamlCfg, "http-proxy-redir-url", &cfg.HttpProxyRedirURL)
getConfigOpt(yamlCfg, "http-proxy-redir-domain", &cfg.HttpProxyRedirDomain)
getConfigOpt(yamlCfg, "ssl-cert", &cfg.SslCert)
getConfigOpt(yamlCfg, "ssl-key", &cfg.SslKey)
getConfigOpt(yamlCfg, "ssl-cacert", &cfg.SslCacert)
getConfigOpt(yamlCfg, "separate-ssl-config", &cfg.SeparateSslConfig)

if cfg.SeparateSslConfig {
getConfigOpt(yamlCfg, "webui-ssl-cert", &cfg.WebUISslCert)
getConfigOpt(yamlCfg, "webui-ssl-key", &cfg.WebUISslKey)
}

getConfigOpt(yamlCfg, "token", &cfg.Token)
getConfigOpt(yamlCfg, "dev-auth-url", &cfg.DevAuthUrl)
getConfigOpt(yamlCfg, "db", &cfg.DB)
getConfigOpt(yamlCfg, "local-auth", &cfg.LocalAuth)

val, err := yamlCfg.Get("white-list")
if err == nil {
if val != "*" && val != "\"*\"" {
cfg.WhiteList = make(map[string]bool)

for _, id := range strings.Fields(val) {
cfg.WhiteList[id] = true
}
}
}

return nil
}

func getFlagOpt(c *cli.Context, name string, opt interface{}) {
if !c.IsSet(name) {
return
}

switch opt := opt.(type) {
case *string:
*opt = c.String(name)
case *int:
*opt = c.Int(name)
case *bool:
*opt = c.Bool(name)
}
}

// Parse config
func Parse(c *cli.Context) *Config {
func Parse(c *cli.Context) (*Config, error) {
cfg := &Config{
AddrDev: c.String("addr-dev"),
AddrUser: c.String("addr-user"),
AddrHttpProxy: c.String("addr-http-proxy"),
DisableSignUp: c.Bool("disable-sign-up"),
HttpProxyRedirURL: c.String("http-proxy-redir-url"),
HttpProxyRedirDomain: c.String("http-proxy-redir-domain"),
SslCert: c.String("ssl-cert"),
SslKey: c.String("ssl-key"),
SslCacert: c.String("ssl-cacert"),
SeparateSslConfig: c.Bool("separate-ssl-config"),
WebUISslCert: c.String("webui-ssl-cert"),
WebUISslKey: c.String("webui-ssl-key"),
Token: c.String("token"),
DevAuthUrl: c.String("dev-auth-url"),
DB: c.String("db"),
LocalAuth: c.Bool("local-auth"),
}

cfg.WhiteList = make(map[string]bool)

whiteList := c.String("white-list")

if whiteList == "*" {
cfg.WhiteList = nil
} else {
for _, id := range strings.Fields(whiteList) {
cfg.WhiteList[id] = true
AddrDev: ":5912",
AddrUser: ":5913",
DB: "sqlite://rttys.db",
LocalAuth: true,
}

conf := c.String("conf")
if conf != "" {
err := parseYamlCfg(cfg, conf)
if err != nil {
return nil, err
}
}

yamlCfg, err := yaml.ReadFile(c.String("conf"))
if err == nil {
getConfigOpt(yamlCfg, "addr-dev", &cfg.AddrDev)
getConfigOpt(yamlCfg, "addr-user", &cfg.AddrUser)
getConfigOpt(yamlCfg, "addr-http-proxy", &cfg.AddrHttpProxy)
getConfigOpt(yamlCfg, "disable-sign-up", &cfg.DisableSignUp)
getConfigOpt(yamlCfg, "http-proxy-redir-url", &cfg.HttpProxyRedirURL)
getConfigOpt(yamlCfg, "http-proxy-redir-domain", &cfg.HttpProxyRedirDomain)
getConfigOpt(yamlCfg, "ssl-cert", &cfg.SslCert)
getConfigOpt(yamlCfg, "ssl-key", &cfg.SslKey)
getConfigOpt(yamlCfg, "ssl-cacert", &cfg.SslCacert)
getConfigOpt(yamlCfg, "separate-ssl-config", &cfg.SeparateSslConfig)
if cfg.SeparateSslConfig {
getConfigOpt(yamlCfg, "webui-ssl-cert", &cfg.WebUISslCert)
getConfigOpt(yamlCfg, "webui-ssl-key", &cfg.WebUISslKey)
getFlagOpt(c, "addr-dev", &cfg.AddrDev)
getFlagOpt(c, "addr-user", &cfg.AddrUser)
getFlagOpt(c, "addr-http-proxy", &cfg.AddrHttpProxy)
getFlagOpt(c, "http-proxy-redir-url", &cfg.HttpProxyRedirURL)
getFlagOpt(c, "http-proxy-redir-domain", &cfg.HttpProxyRedirDomain)
getFlagOpt(c, "disable-sign-up", &cfg.DisableSignUp)
getFlagOpt(c, "dev-auth-url", &cfg.DevAuthUrl)
getFlagOpt(c, "local-auth", &cfg.LocalAuth)
getFlagOpt(c, "token", &cfg.Token)
getFlagOpt(c, "db", &cfg.DB)

getFlagOpt(c, "ssl-cacert", &cfg.SslCacert)
getFlagOpt(c, "ssl-cert", &cfg.SslCert)
getFlagOpt(c, "ssl-key", &cfg.SslKey)
getFlagOpt(c, "separate-ssl-config", &cfg.SeparateSslConfig)

if cfg.SeparateSslConfig {
getFlagOpt(c, "webui-ssl-cert", &cfg.WebUISslCert)
getFlagOpt(c, "webui-ssl-key", &cfg.WebUISslKey)
} else {
cfg.WebUISslCert = cfg.SslCert
cfg.WebUISslKey = cfg.SslKey
}

if c.IsSet("white-list") {
whiteList := c.String("white-list")

if whiteList == "*" {
cfg.WhiteList = nil
} else {
cfg.WebUISslCert = cfg.SslCert
cfg.WebUISslKey = cfg.SslKey
}
getConfigOpt(yamlCfg, "token", &cfg.Token)
getConfigOpt(yamlCfg, "dev-auth-url", &cfg.DevAuthUrl)
getConfigOpt(yamlCfg, "db", &cfg.DB)
getConfigOpt(yamlCfg, "local-auth", &cfg.LocalAuth)
val, err := yamlCfg.Get("white-list")
if err == nil {
if val == "*" || val == "\"*\"" {
cfg.WhiteList = nil
} else {
for _, id := range strings.Fields(val) {
cfg.WhiteList[id] = true
}
cfg.WhiteList = make(map[string]bool)

for _, id := range strings.Fields(whiteList) {
cfg.WhiteList[id] = true
}
}
}

if cfg.SslCert != "" && cfg.SslKey != "" {
_, err := os.Lstat(cfg.SslCert)
if err != nil {
log.Error().Msg(err.Error())
cfg.SslCert = ""
if cfg.SslCacert != "" {
if _, err := os.Lstat(cfg.SslCacert); err != nil {
return nil, fmt.Errorf(`SslCacert "%s" not exist`, cfg.SslCacert)
}
}

_, err = os.Lstat(cfg.SslKey)
if err != nil {
log.Error().Msg(err.Error())
cfg.SslKey = ""
if cfg.SslCert != "" {
if _, err := os.Lstat(cfg.SslCert); err != nil {
return nil, fmt.Errorf(`SslCert "%s" not exist`, cfg.SslCert)
}
}

if cfg.SslKey != "" {
if _, err := os.Lstat(cfg.SslKey); err != nil {
return nil, fmt.Errorf(`SslKey "%s" not exist`, cfg.SslKey)
}
}

if cfg.WebUISslCert != "" {
if _, err := os.Lstat(cfg.WebUISslCert); err != nil {
return nil, fmt.Errorf(`WebUISslCert "%s" not exist`, cfg.WebUISslCert)
}
}

if cfg.WebUISslKey != "" {
if _, err := os.Lstat(cfg.WebUISslKey); err != nil {
return nil, fmt.Errorf(`WebUISslKey "%s" not exist`, cfg.WebUISslKey)
}
}

return cfg
return cfg, nil
}
19 changes: 9 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,17 @@ func initDb(cfg *config.Config) error {
return err
}

func runRttys(c *cli.Context) {
func runRttys(c *cli.Context) error {
xlog.SetPath(c.String("log"))

if c.Bool("verbose") {
xlog.Verbose()
}

cfg := config.Parse(c)
cfg, err := config.Parse(c)
if err != nil {
return err
}

log.Info().Msg("Go Version: " + runtime.Version())
log.Info().Msgf("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH)
Expand All @@ -62,10 +65,9 @@ func runRttys(c *cli.Context) {
log.Info().Msg("Build Time: " + version.BuildTime())
}

err := initDb(cfg)
err = initDb(cfg)
if err != nil {
log.Error().Msg("Init database fail:" + err.Error())
return
return fmt.Errorf(`init database: %s`, err.Error())
}

br := newBroker(cfg)
Expand Down Expand Up @@ -101,7 +103,6 @@ func main() {
&cli.StringFlag{
Name: "conf",
Aliases: []string{"c"},
Value: "./rttys.conf",
Usage: "config file to load",
},
&cli.StringFlag{
Expand Down Expand Up @@ -168,8 +169,7 @@ func main() {
},
},
Action: func(c *cli.Context) error {
runRttys(c)
return nil
return runRttys(c)
},
},
{
Expand All @@ -182,8 +182,7 @@ func main() {
},
},
Action: func(c *cli.Context) error {
c.App.Command("run").Run(c)
return nil
return c.App.Command("run").Run(c)
},
}

Expand Down

0 comments on commit 90d51a5

Please sign in to comment.