summaryrefslogtreecommitdiffstats
path: root/cmd/mattermost/commands/config.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/mattermost/commands/config.go')
-rw-r--r--cmd/mattermost/commands/config.go132
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
+}