Fix #937: Print full working configuration at startup
Only when using debug mode Co-authored-by: Hector Sanjuan <code@hector.link>
This commit is contained in:
parent
c80e8fe010
commit
ae8e74453b
|
@ -333,3 +333,13 @@ func (cfg *Config) toJSONConfig() (jcfg *jsonConfig, err error) {
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *Config) ToDisplayJSON() ([]byte, error) {
|
||||||
|
jcfg, err := cfg.toJSONConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.DisplayJSON(jcfg)
|
||||||
|
}
|
||||||
|
|
|
@ -147,9 +147,9 @@ type jsonConfig struct {
|
||||||
|
|
||||||
Libp2pListenMultiaddress ipfsconfig.Strings `json:"libp2p_listen_multiaddress,omitempty"`
|
Libp2pListenMultiaddress ipfsconfig.Strings `json:"libp2p_listen_multiaddress,omitempty"`
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
PrivateKey string `json:"private_key,omitempty"`
|
PrivateKey string `json:"private_key,omitempty" hidden:"true"`
|
||||||
|
|
||||||
BasicAuthCredentials map[string]string `json:"basic_auth_credentials"`
|
BasicAuthCredentials map[string]string `json:"basic_auth_credentials" hidden:"true"`
|
||||||
HTTPLogFile string `json:"http_log_file"`
|
HTTPLogFile string `json:"http_log_file"`
|
||||||
Headers map[string][]string `json:"headers"`
|
Headers map[string][]string `json:"headers"`
|
||||||
|
|
||||||
|
@ -503,6 +503,16 @@ func (cfg *Config) corsOptions() *cors.Options {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *Config) ToDisplayJSON() ([]byte, error) {
|
||||||
|
jcfg, err := cfg.toJSONConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.DisplayJSON(jcfg)
|
||||||
|
}
|
||||||
|
|
||||||
func newTLSConfig(certFile, keyFile string) (*tls.Config, error) {
|
func newTLSConfig(certFile, keyFile string) (*tls.Config, error) {
|
||||||
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -162,8 +162,8 @@ type Config struct {
|
||||||
type configJSON struct {
|
type configJSON struct {
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Peername string `json:"peername"`
|
Peername string `json:"peername"`
|
||||||
PrivateKey string `json:"private_key,omitempty"`
|
PrivateKey string `json:"private_key,omitempty" hidden:"true"`
|
||||||
Secret string `json:"secret"`
|
Secret string `json:"secret" hidden:"true"`
|
||||||
LeaveOnShutdown bool `json:"leave_on_shutdown"`
|
LeaveOnShutdown bool `json:"leave_on_shutdown"`
|
||||||
ListenMultiaddress ipfsconfig.Strings `json:"listen_multiaddress"`
|
ListenMultiaddress ipfsconfig.Strings `json:"listen_multiaddress"`
|
||||||
EnableRelayHop bool `json:"enable_relay_hop"`
|
EnableRelayHop bool `json:"enable_relay_hop"`
|
||||||
|
@ -526,6 +526,15 @@ func (cfg *Config) GetPeerstorePath() string {
|
||||||
return filepath.Join(cfg.BaseDir, filename)
|
return filepath.Join(cfg.BaseDir, filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *Config) ToDisplayJSON() ([]byte, error) {
|
||||||
|
jcfg, err := cfg.toConfigJSON()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return config.DisplayJSON(jcfg)
|
||||||
|
}
|
||||||
|
|
||||||
// DecodeClusterSecret parses a hex-encoded string, checks that it is exactly
|
// DecodeClusterSecret parses a hex-encoded string, checks that it is exactly
|
||||||
// 32 bytes long and returns its value as a byte-slice.x
|
// 32 bytes long and returns its value as a byte-slice.x
|
||||||
func DecodeClusterSecret(hexSecret string) ([]byte, error) {
|
func DecodeClusterSecret(hexSecret string) ([]byte, error) {
|
||||||
|
|
|
@ -121,8 +121,11 @@ func createCluster(
|
||||||
|
|
||||||
cfgs := cfgHelper.Configs()
|
cfgs := cfgHelper.Configs()
|
||||||
cfgMgr := cfgHelper.Manager()
|
cfgMgr := cfgHelper.Manager()
|
||||||
|
cfgBytes, err := cfgMgr.ToDisplayJSON()
|
||||||
|
checkErr("getting configuration string", err)
|
||||||
|
logger.Debugf("Configuration:\n%s\n", cfgBytes)
|
||||||
|
|
||||||
ctx, err := tag.New(ctx, tag.Upsert(observations.HostKey, host.ID().Pretty()))
|
ctx, err = tag.New(ctx, tag.Upsert(observations.HostKey, host.ID().Pretty()))
|
||||||
checkErr("tag context with host id", err)
|
checkErr("tag context with host id", err)
|
||||||
|
|
||||||
var apis []ipfscluster.API
|
var apis []ipfscluster.API
|
||||||
|
|
|
@ -58,6 +58,8 @@ type ComponentConfig interface {
|
||||||
// Provides a channel to signal the Manager that the configuration
|
// Provides a channel to signal the Manager that the configuration
|
||||||
// should be persisted.
|
// should be persisted.
|
||||||
SaveCh() <-chan struct{}
|
SaveCh() <-chan struct{}
|
||||||
|
// ToDisplayJSON returns a string representing the config excluding hidden fields.
|
||||||
|
ToDisplayJSON() ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are the component configuration types
|
// These are the component configuration types
|
||||||
|
@ -512,7 +514,6 @@ func (cfg *Manager) ToJSON() ([]byte, error) {
|
||||||
if cfg.clusterConfig != nil {
|
if cfg.clusterConfig != nil {
|
||||||
cfg.clusterConfig.SetBaseDir(dir)
|
cfg.clusterConfig.SetBaseDir(dir)
|
||||||
raw, err := cfg.clusterConfig.ToJSON()
|
raw, err := cfg.clusterConfig.ToJSON()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -541,6 +542,52 @@ func (cfg *Manager) ToJSON() ([]byte, error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = cfg.applyUpdateJSONConfigs(jcfg, updateJSONConfigs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefaultJSONMarshal(jcfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns a printable cluster configuration.
|
||||||
|
func (cfg *Manager) ToDisplayJSON() ([]byte, error) {
|
||||||
|
jcfg := &jsonConfig{}
|
||||||
|
|
||||||
|
if cfg.clusterConfig != nil {
|
||||||
|
raw, err := cfg.clusterConfig.ToDisplayJSON()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
jcfg.Cluster = new(json.RawMessage)
|
||||||
|
*jcfg.Cluster = raw
|
||||||
|
}
|
||||||
|
|
||||||
|
updateJSONConfigs := func(section Section, dest *jsonSection) error {
|
||||||
|
for k, v := range section {
|
||||||
|
j, err := v.ToDisplayJSON()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if *dest == nil {
|
||||||
|
*dest = make(jsonSection)
|
||||||
|
}
|
||||||
|
jsonSection := *dest
|
||||||
|
jsonSection[k] = new(json.RawMessage)
|
||||||
|
*jsonSection[k] = j
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := cfg.applyUpdateJSONConfigs(jcfg, updateJSONConfigs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefaultJSONMarshal(jcfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *Manager) applyUpdateJSONConfigs(jcfg *jsonConfig, updateJSONConfigs func(section Section, dest *jsonSection) error) error {
|
||||||
for _, t := range SectionTypes() {
|
for _, t := range SectionTypes() {
|
||||||
if t == Cluster {
|
if t == Cluster {
|
||||||
continue
|
continue
|
||||||
|
@ -548,11 +595,11 @@ func (cfg *Manager) ToJSON() ([]byte, error) {
|
||||||
jsection := jcfg.getSection(t)
|
jsection := jcfg.getSection(t)
|
||||||
err := updateJSONConfigs(cfg.sections[t], jsection)
|
err := updateJSONConfigs(cfg.sections[t], jsection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefaultJSONMarshal(jcfg)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsLoadedFromJSON tells whether the given component belonging to
|
// IsLoadedFromJSON tells whether the given component belonging to
|
||||||
|
|
|
@ -92,6 +92,14 @@ func (m *mockCfg) Validate() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *mockCfg) ToDisplayJSON() ([]byte, error) {
|
||||||
|
return []byte(`
|
||||||
|
{
|
||||||
|
"a":"b"
|
||||||
|
}
|
||||||
|
`), nil
|
||||||
|
}
|
||||||
|
|
||||||
func setupConfigManager() *Manager {
|
func setupConfigManager() *Manager {
|
||||||
cfg := NewManager()
|
cfg := NewManager()
|
||||||
mockCfg := &mockCfg{}
|
mockCfg := &mockCfg{}
|
||||||
|
@ -176,3 +184,29 @@ func TestSaveWithSource(t *testing.T) {
|
||||||
t.Error("should have generated a source-only json")
|
t.Error("should have generated a source-only json")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDefaultJSONMarshalWithoutHiddenFields(t *testing.T) {
|
||||||
|
type s struct {
|
||||||
|
A string `json:"a_key"`
|
||||||
|
B string `json:"b_key" hidden:"true"`
|
||||||
|
}
|
||||||
|
cfg := s{
|
||||||
|
A: "hi",
|
||||||
|
B: "there",
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := `{
|
||||||
|
"a_key": "hi",
|
||||||
|
"b_key": "XXX_hidden_XXX"
|
||||||
|
}`
|
||||||
|
|
||||||
|
res, err := DisplayJSON(&cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(res) != expected {
|
||||||
|
t.Error("result does not match expected")
|
||||||
|
t.Error(string(res))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package config
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -114,3 +116,64 @@ func ParseDurations(component string, args ...*DurationOpt) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type hiddenField struct{}
|
||||||
|
|
||||||
|
func (hf hiddenField) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(`"XXX_hidden_XXX"`), nil
|
||||||
|
}
|
||||||
|
func (hf hiddenField) UnmarshalJSON(b []byte) error { return nil }
|
||||||
|
|
||||||
|
// DisplayJSON takes pointer to a JSON-friendly configuration struct and
|
||||||
|
// returns the JSON-encoded representation of it filtering out any struct
|
||||||
|
// fields marked with the tag `hidden:"true"`, but keeping fields marked
|
||||||
|
// with `"json:omitempty"`.
|
||||||
|
func DisplayJSON(cfg interface{}) ([]byte, error) {
|
||||||
|
cfg = reflect.Indirect(reflect.ValueOf(cfg)).Interface()
|
||||||
|
origStructT := reflect.TypeOf(cfg)
|
||||||
|
if origStructT.Kind() != reflect.Struct {
|
||||||
|
panic("the given argument should be a struct")
|
||||||
|
}
|
||||||
|
|
||||||
|
hiddenFieldT := reflect.TypeOf(hiddenField{})
|
||||||
|
|
||||||
|
// create a new struct type with same fields
|
||||||
|
// but setting hidden fields as hidden.
|
||||||
|
finalStructFields := []reflect.StructField{}
|
||||||
|
for i := 0; i < origStructT.NumField(); i++ {
|
||||||
|
f := origStructT.Field(i)
|
||||||
|
hidden := f.Tag.Get("hidden") == "true"
|
||||||
|
if f.PkgPath != "" { // skip unexported
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if hidden {
|
||||||
|
f.Type = hiddenFieldT
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove omitempty from tag, ignore other tags except json
|
||||||
|
var jsonTags []string
|
||||||
|
for _, s := range strings.Split(f.Tag.Get("json"), ",") {
|
||||||
|
if s != "omitempty" {
|
||||||
|
jsonTags = append(jsonTags, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.Tag = reflect.StructTag(fmt.Sprintf("json:\"%s\"", strings.Join(jsonTags, ",")))
|
||||||
|
|
||||||
|
finalStructFields = append(finalStructFields, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the original JSON into the new
|
||||||
|
// struct and re-convert it to JSON.
|
||||||
|
finalStructT := reflect.StructOf(finalStructFields)
|
||||||
|
finalValue := reflect.New(finalStructT)
|
||||||
|
data := finalValue.Interface()
|
||||||
|
origJSON, err := json.Marshal(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(origJSON, data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return DefaultJSONMarshal(data)
|
||||||
|
}
|
||||||
|
|
|
@ -191,3 +191,8 @@ func (cfg *Config) ApplyEnvVars() error {
|
||||||
|
|
||||||
return cfg.applyJSONConfig(jcfg)
|
return cfg.applyJSONConfig(jcfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *Config) ToDisplayJSON() ([]byte, error) {
|
||||||
|
return config.DisplayJSON(cfg.toJSONConfig())
|
||||||
|
}
|
||||||
|
|
|
@ -313,3 +313,8 @@ func (cfg *Config) GetDataFolder() string {
|
||||||
}
|
}
|
||||||
return cfg.DataFolder
|
return cfg.DataFolder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *Config) ToDisplayJSON() ([]byte, error) {
|
||||||
|
return config.DisplayJSON(cfg.toJSONConfig())
|
||||||
|
}
|
||||||
|
|
|
@ -234,3 +234,8 @@ func (cfg *Config) GetFolder() string {
|
||||||
|
|
||||||
return filepath.Join(cfg.BaseDir, cfg.Folder)
|
return filepath.Join(cfg.BaseDir, cfg.Folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *Config) ToDisplayJSON() ([]byte, error) {
|
||||||
|
return config.DisplayJSON(cfg.toJSONConfig())
|
||||||
|
}
|
||||||
|
|
|
@ -127,3 +127,8 @@ func (cfg *Config) toJSONConfig() *jsonConfig {
|
||||||
MetricType: cfg.MetricType.String(),
|
MetricType: cfg.MetricType.String(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *Config) ToDisplayJSON() ([]byte, error) {
|
||||||
|
return config.DisplayJSON(cfg.toJSONConfig())
|
||||||
|
}
|
||||||
|
|
|
@ -95,3 +95,8 @@ func (cfg *Config) toJSONConfig() *jsonConfig {
|
||||||
MetricTTL: cfg.MetricTTL.String(),
|
MetricTTL: cfg.MetricTTL.String(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *Config) ToDisplayJSON() ([]byte, error) {
|
||||||
|
return config.DisplayJSON(cfg.toJSONConfig())
|
||||||
|
}
|
||||||
|
|
|
@ -205,3 +205,13 @@ func (cfg *Config) toJSONConfig() (jcfg *jsonConfig, err error) {
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *Config) ToDisplayJSON() ([]byte, error) {
|
||||||
|
jcfg, err := cfg.toJSONConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.DisplayJSON(jcfg)
|
||||||
|
}
|
||||||
|
|
|
@ -111,3 +111,8 @@ func (cfg *Config) toJSONConfig() *jsonConfig {
|
||||||
FailureThreshold: &cfg.FailureThreshold,
|
FailureThreshold: &cfg.FailureThreshold,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *Config) ToDisplayJSON() ([]byte, error) {
|
||||||
|
return config.DisplayJSON(cfg.toJSONConfig())
|
||||||
|
}
|
||||||
|
|
|
@ -144,6 +144,11 @@ func (cfg *MetricsConfig) toJSONConfig() *jsonMetricsConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *MetricsConfig) ToDisplayJSON() ([]byte, error) {
|
||||||
|
return config.DisplayJSON(cfg.toJSONConfig())
|
||||||
|
}
|
||||||
|
|
||||||
// TracingConfig configures tracing.
|
// TracingConfig configures tracing.
|
||||||
type TracingConfig struct {
|
type TracingConfig struct {
|
||||||
config.Saver
|
config.Saver
|
||||||
|
@ -257,3 +262,8 @@ func (cfg *TracingConfig) toJSONConfig() *jsonTracingConfig {
|
||||||
ServiceName: cfg.ServiceName,
|
ServiceName: cfg.ServiceName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *TracingConfig) ToDisplayJSON() ([]byte, error) {
|
||||||
|
return config.DisplayJSON(cfg.toJSONConfig())
|
||||||
|
}
|
||||||
|
|
|
@ -112,3 +112,8 @@ func (cfg *Config) toJSONConfig() *jsonConfig {
|
||||||
|
|
||||||
return jCfg
|
return jCfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDisplayJSON returns JSON config as a string.
|
||||||
|
func (cfg *Config) ToDisplayJSON() ([]byte, error) {
|
||||||
|
return config.DisplayJSON(cfg.toJSONConfig())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user