diff options
Diffstat (limited to 'cmd/mattermost/commands/config.go')
-rw-r--r-- | cmd/mattermost/commands/config.go | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/cmd/mattermost/commands/config.go b/cmd/mattermost/commands/config.go index b8630b82f..47dd61458 100644 --- a/cmd/mattermost/commands/config.go +++ b/cmd/mattermost/commands/config.go @@ -4,12 +4,17 @@ package commands import ( + "bytes" "encoding/json" + "fmt" "os" + "reflect" + "strings" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/mattermost/mattermost-server/mlog" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/utils" ) @@ -36,12 +41,22 @@ var ConfigSubpathCmd = &cobra.Command{ RunE: configSubpathCmdF, } +var ConfigGetCmd = &cobra.Command{ + Use: "get", + Short: "Get config setting", + Long: "Gets the value of a config setting by its name in dot notation.", + Example: `config get SqlSettings.DriverName`, + Args: cobra.ExactArgs(1), + RunE: configGetCmdF, +} + func init() { ConfigSubpathCmd.Flags().String("path", "", "Optional subpath; defaults to value in SiteURL") ConfigCmd.AddCommand( ValidateConfigCmd, ConfigSubpathCmd, + ConfigGetCmd, ) RootCmd.AddCommand(ConfigCmd) } @@ -102,3 +117,120 @@ func configSubpathCmdF(command *cobra.Command, args []string) error { return nil } + +func configGetCmdF(command *cobra.Command, args []string) error { + app, err := InitDBCommandContextCobra(command) + if err != nil { + return err + } + defer app.Shutdown() + + // create the model for config + // Note: app.Config() returns a pointer, make appropriate changes + config := app.Config() + + // get the print config setting and any error if there is + out, err := printConfigValues(configToMap(*config), strings.Split(args[0], "."), args[0]) + if err != nil { + return err + } + + fmt.Printf("%s", out) + + return nil +} + +// printConfigValues function prints out the value of the configSettings working recursively or +// gives an error if config setting is not in the file. +func printConfigValues(configMap map[string]interface{}, configSetting []string, name string) (string, error) { + + res, ok := configMap[configSetting[0]] + if !ok { + return "", fmt.Errorf("%s configuration setting is not in the file", name) + } + value := reflect.ValueOf(res) + switch value.Kind() { + case reflect.Map: + if len(configSetting) == 1 { + return printMap(value, 0), nil + } + return printConfigValues(res.(map[string]interface{}), configSetting[1:], name) + default: + if len(configSetting) == 1 { + return fmt.Sprintf("%s: \"%v\"\n", name, res), nil + } + return "", fmt.Errorf("%s configuration setting is not in the file", name) + } +} + +// printMap takes a reflect.Value and return a string, recursively if its a map with the given tab settings. +func printMap(value reflect.Value, tabVal int) string { + + // our output buffer + out := &bytes.Buffer{} + + for _, key := range value.MapKeys() { + val := value.MapIndex(key) + if newVal, ok := val.Interface().(map[string]interface{}); !ok { + fmt.Fprintf(out, "%s", strings.Repeat("\t", tabVal)) + fmt.Fprintf(out, "%v: \"%v\"\n", key.Interface(), val.Interface()) + } else { + fmt.Fprintf(out, "%s", strings.Repeat("\t", tabVal)) + fmt.Fprintf(out, "%v:\n", key.Interface()) + // going one level in, increase the tab + tabVal++ + fmt.Fprintf(out, "%s", printMap(reflect.ValueOf(newVal), tabVal)) + // coming back one level, decrease the tab + tabVal-- + } + } + + return out.String() + +} + +// configToMap converts our config into a map +func configToMap(s interface{}) map[string]interface{} { + return structToMap(s) +} + +// structToMap converts a struct into a map +func structToMap(t interface{}) map[string]interface{} { + defer func() { + if r := recover(); r != nil { + mlog.Error(fmt.Sprintf("Panicked in structToMap. This should never happen. %v", r)) + } + }() + + val := reflect.ValueOf(t) + + if val.Kind() != reflect.Struct { + return nil + } + + out := map[string]interface{}{} + + for i := 0; i < val.NumField(); i++ { + field := val.Field(i) + + var value interface{} + + switch field.Kind() { + case reflect.Struct: + value = structToMap(field.Interface()) + case reflect.Ptr: + indirectType := field.Elem() + + if indirectType.Kind() == reflect.Struct { + value = structToMap(indirectType.Interface()) + } else { + value = indirectType.Interface() + } + default: + value = field.Interface() + } + + out[val.Type().Field(i).Name] = value + } + return out +} |