forked from sourcenetwork/defradb
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: Make config internal to CLI (sourcenetwork#2310)
## Relevant issue(s) Resolves sourcenetwork#2257 ## Description This PR refactors the config into a simpler implementation that exists within the `cli` package. Notable changes: - ~~`datastore.store` config key has been replaced with `datastore.badger.inMemory`~~ - ~~`--store` cli flag has been replaced with `--in-memory`~~ - `log.overrides` config map has been added. (contains same keys as `log` but for individual loggers) - `--logger` cli flag has been temporarily removed (will be replaced in upcoming log library) - `init` command has been removed. (can be replaced with `rm -rf ~/.defradb` or similar) ## Tasks - [x] I made sure the code is well commented, particularly hard-to-understand areas. - [x] I made sure the repository-held documentation is changed accordingly. - [x] I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in [tools/configs/chglog/config.yml](tools/configs/chglog/config.yml)). - [x] I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ... ## How has this been tested? `make test` Specify the platform(s) on which this was tested: - MacOS
- Loading branch information
Showing
65 changed files
with
596 additions
and
2,385 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
// Copyright 2024 Democratized Data Foundation | ||
// | ||
// Use of this software is governed by the Business Source License | ||
// included in the file licenses/BSL.txt. | ||
// | ||
// As of the Change Date specified in that file, in accordance with | ||
// the Business Source License, use of this software will be governed | ||
// by the Apache License, Version 2.0, included in the file | ||
// licenses/APL.txt. | ||
|
||
package cli | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/spf13/pflag" | ||
"github.com/spf13/viper" | ||
|
||
"github.com/sourcenetwork/defradb/logging" | ||
) | ||
|
||
const ( | ||
configStoreBadger = "badger" | ||
configStoreMemory = "memory" | ||
configLogFormatJSON = "json" | ||
configLogFormatCSV = "csv" | ||
configLogLevelInfo = "info" | ||
configLogLevelDebug = "debug" | ||
configLogLevelError = "error" | ||
configLogLevelFatal = "fatal" | ||
) | ||
|
||
// configPaths are config keys that will be made relative to the rootdir | ||
var configPaths = []string{ | ||
"datastore.badger.path", | ||
"api.pubkeypath", | ||
"api.privkeypath", | ||
} | ||
|
||
// configFlags is a mapping of config keys to cli flags to bind to. | ||
var configFlags = map[string]string{ | ||
"log.level": "loglevel", | ||
"log.output": "logoutput", | ||
"log.format": "logformat", | ||
"log.stacktrace": "logtrace", | ||
"log.nocolor": "lognocolor", | ||
"api.address": "url", | ||
"datastore.maxtxnretries": "max-txn-retries", | ||
"datastore.store": "store", | ||
"datastore.badger.valuelogfilesize": "valuelogfilesize", | ||
"net.peers": "peers", | ||
"net.p2paddresses": "p2paddr", | ||
"net.p2pdisabled": "no-p2p", | ||
"api.allowed-origins": "allowed-origins", | ||
"api.pubkeypath": "pubkeypath", | ||
"api.privkeypath": "privkeypath", | ||
} | ||
|
||
// defaultConfig returns a new config with default values. | ||
func defaultConfig() *viper.Viper { | ||
cfg := viper.New() | ||
|
||
cfg.AutomaticEnv() | ||
cfg.SetEnvPrefix("DEFRA") | ||
cfg.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) | ||
|
||
cfg.SetConfigName("config") | ||
cfg.SetConfigType("yaml") | ||
|
||
cfg.SetDefault("datastore.badger.path", "data") | ||
cfg.SetDefault("net.pubSubEnabled", true) | ||
cfg.SetDefault("net.relay", false) | ||
cfg.SetDefault("log.caller", false) | ||
|
||
return cfg | ||
} | ||
|
||
// createConfig writes the default config file if one does not exist. | ||
func createConfig(rootdir string, flags *pflag.FlagSet) error { | ||
cfg := defaultConfig() | ||
cfg.AddConfigPath(rootdir) | ||
|
||
if err := bindConfigFlags(cfg, flags); err != nil { | ||
return err | ||
} | ||
// make sure rootdir exists | ||
if err := os.MkdirAll(rootdir, 0755); err != nil { | ||
return err | ||
} | ||
err := cfg.SafeWriteConfig() | ||
// error type is known and shouldn't be wrapped | ||
// | ||
//nolint:errorlint | ||
if _, ok := err.(viper.ConfigFileAlreadyExistsError); ok { | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
// loadConfig returns a new config with values from the config in the given rootdir. | ||
func loadConfig(rootdir string, flags *pflag.FlagSet) (*viper.Viper, error) { | ||
cfg := defaultConfig() | ||
cfg.AddConfigPath(rootdir) | ||
|
||
// attempt to read the existing config | ||
err := cfg.ReadInConfig() | ||
// error type is known and shouldn't be wrapped | ||
// | ||
//nolint:errorlint | ||
if _, ok := err.(viper.ConfigFileNotFoundError); err != nil && !ok { | ||
return nil, err | ||
} | ||
// bind cli flags to config keys | ||
if err := bindConfigFlags(cfg, flags); err != nil { | ||
return nil, err | ||
} | ||
|
||
// make paths relative to the rootdir | ||
for _, key := range configPaths { | ||
path := cfg.GetString(key) | ||
if path != "" && !filepath.IsAbs(path) { | ||
cfg.Set(key, filepath.Join(rootdir, path)) | ||
} | ||
} | ||
|
||
logCfg := loggingConfig(cfg.Sub("log")) | ||
logCfg.OverridesByLoggerName = make(map[string]logging.Config) | ||
|
||
// apply named logging overrides | ||
for key := range cfg.GetStringMap("log.overrides") { | ||
logCfg.OverridesByLoggerName[key] = loggingConfig(cfg.Sub("log.overrides." + key)) | ||
} | ||
logging.SetConfig(logCfg) | ||
|
||
return cfg, nil | ||
} | ||
|
||
// bindConfigFlags binds the set of cli flags to config values. | ||
func bindConfigFlags(cfg *viper.Viper, flags *pflag.FlagSet) error { | ||
for key, flag := range configFlags { | ||
err := cfg.BindPFlag(key, flags.Lookup(flag)) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// loggingConfig returns a new logging config from the given config. | ||
func loggingConfig(cfg *viper.Viper) logging.Config { | ||
var level int8 | ||
switch value := cfg.GetString("level"); value { | ||
case configLogLevelDebug: | ||
level = logging.Debug | ||
case configLogLevelInfo: | ||
level = logging.Info | ||
case configLogLevelError: | ||
level = logging.Error | ||
case configLogLevelFatal: | ||
level = logging.Fatal | ||
default: | ||
level = logging.Info | ||
} | ||
|
||
var format logging.EncoderFormat | ||
switch value := cfg.GetString("format"); value { | ||
case configLogFormatJSON: | ||
format = logging.JSON | ||
case configLogFormatCSV: | ||
format = logging.CSV | ||
default: | ||
format = logging.CSV | ||
} | ||
|
||
return logging.Config{ | ||
Level: logging.NewLogLevelOption(level), | ||
EnableStackTrace: logging.NewEnableStackTraceOption(cfg.GetBool("stacktrace")), | ||
DisableColor: logging.NewDisableColorOption(cfg.GetBool("nocolor")), | ||
EncoderFormat: logging.NewEncoderFormatOption(format), | ||
OutputPaths: []string{cfg.GetString("output")}, | ||
EnableCaller: logging.NewEnableCallerOption(cfg.GetBool("caller")), | ||
} | ||
} |
Oops, something went wrong.